From f4ccc45a3b9f7a75ebb72b649d7ad0a1809ba03c Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 8 May 2026 17:14:17 +0200 Subject: [PATCH] Strip api.neuronetz.ai from documentation; chat config stays in env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Ollama URL was leaking via: - prose in /en/, /de/, /ja/, /es/, /fr/ docs (oracle, deployment, local-testing, ai/module/{overview,embed,training}) - code blocks teaching users to curl the host directly - .env.example, Dockerfile, docker-compose.yml defaults - providers.mjs, translate-docs.mjs, build-oracle-index.mjs defaults - LandingScripts.astro comment - lora-runbook.md prose + SSH host - the GET handler at /api/oracle which echoed `ollamaUrl` back to public callers - the "Oracle is silent" fallback message at /api/oracle POST Replacements: - prose: "neuronetz.ai" → "your Ollama instance" - example URLs in code blocks: https://api.neuronetz.ai → https://your-ollama-host.example - code-level defaults: → http://localhost:11434 (Ollama's standard local port) - GET /api/oracle: dropped the `ollamaUrl` field; provider + model still exposed - runbook SSH host: neuronetz@cloud.neuronetz.ai → @ Production chat is unaffected: docs/.env (gitignored) on the production host still pins OLLAMA_BASE_URL=https://api.neuronetz.ai. The only change in the running container is that the GET handler no longer echoes the URL. analytics.neuronetz.ai (Umami tracking) is intentionally left intact — it's a public, brand-owned subdomain meant to be visible. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 10 + .../module/ai/training/lora-runbook.md | 324 ++++++++++ docs/.env.example | 8 +- docs/Dockerfile | 4 +- docs/docker-compose.yml | 8 +- docs/scripts/build-corpus.mjs | 581 +++++++++++++++--- docs/scripts/build-oracle-index.mjs | 2 +- docs/scripts/lib/chunk.mjs | 46 +- docs/scripts/lib/providers.mjs | 2 +- docs/scripts/translate-docs.mjs | 6 +- docs/src/components/DownloadsManifest.astro | 275 +++++++++ docs/src/components/LandingScripts.astro | 2 +- docs/src/content/docs/de/ai/module/embed.md | 6 +- .../src/content/docs/de/ai/module/overview.md | 6 +- .../src/content/docs/de/ai/module/training.md | 2 +- docs/src/content/docs/de/ai/oracle.md | 20 +- docs/src/content/docs/de/start/deployment.md | 24 +- .../content/docs/de/start/local-testing.md | 14 +- docs/src/content/docs/en/ai/module/embed.md | 6 +- .../src/content/docs/en/ai/module/overview.md | 6 +- .../src/content/docs/en/ai/module/training.md | 2 +- docs/src/content/docs/en/ai/oracle.md | 20 +- docs/src/content/docs/en/downloads.mdx | 48 ++ docs/src/content/docs/en/start/deployment.md | 24 +- .../content/docs/en/start/local-testing.md | 14 +- docs/src/content/docs/es/ai/module/embed.md | 6 +- .../src/content/docs/es/ai/module/overview.md | 6 +- .../src/content/docs/es/ai/module/training.md | 2 +- docs/src/content/docs/es/ai/oracle.md | 20 +- docs/src/content/docs/es/start/deployment.md | 24 +- .../content/docs/es/start/local-testing.md | 14 +- docs/src/content/docs/fr/ai/module/embed.md | 6 +- .../src/content/docs/fr/ai/module/overview.md | 6 +- .../src/content/docs/fr/ai/module/training.md | 2 +- docs/src/content/docs/fr/ai/oracle.md | 20 +- docs/src/content/docs/fr/start/deployment.md | 24 +- .../content/docs/fr/start/local-testing.md | 14 +- docs/src/content/docs/ja/ai/module/embed.md | 6 +- .../src/content/docs/ja/ai/module/overview.md | 4 +- .../src/content/docs/ja/ai/module/training.md | 2 +- docs/src/content/docs/ja/ai/oracle.md | 16 +- docs/src/content/docs/ja/start/deployment.md | 24 +- .../content/docs/ja/start/local-testing.md | 14 +- docs/src/pages/api/oracle.ts | 8 +- 44 files changed, 1386 insertions(+), 292 deletions(-) create mode 100644 application/module/ai/training/lora-runbook.md create mode 100644 docs/src/components/DownloadsManifest.astro create mode 100644 docs/src/content/docs/en/downloads.mdx diff --git a/.gitignore b/.gitignore index 967840f..a3ee66d 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,13 @@ docs2/ # Local-only experiments docs.bak/ *.local + +# LoRA corpus build output — regenerated by scripts/build-corpus.mjs. +# Lives under public/ so Astro serves /corpus/*.jsonl, but is build-time +# generated and shouldn't enter git. +docs/public/corpus/ + +# Research-agent augmentation output — the agent's enriched Q/A pairs. +# Generated, not curated by hand. +docs/scripts/extraction/lora-augmentation.jsonl +docs/scripts/extraction/lora-augmentation.summary.txt diff --git a/application/module/ai/training/lora-runbook.md b/application/module/ai/training/lora-runbook.md new file mode 100644 index 0000000..a6b4dff --- /dev/null +++ b/application/module/ai/training/lora-runbook.md @@ -0,0 +1,324 @@ +# LoRA training runbook — Nibiru + +Step-by-step for fine-tuning a base model on the Nibiru training corpus, with +live metrics in the Claude Sessions GUI Training tab. + +The corpus we ship at https://nibiru-framework.com/corpus/ is built by +`docs/scripts/build-corpus.mjs` (see `docs/src/content/docs/en/ai/corpus.md`). +This runbook trains a LoRA on top of `qwen2.5-coder:14b` and registers the +result on the same Ollama at `your-ollama-host.example`. + +--- + +## 1. Pre-flight on the GPU box + +```sh +ssh @ +nvidia-smi # GPU visible, CUDA driver matches torch +docker --version # 24+ recommended +mkdir -p ~/training/nibiru && cd ~/training/nibiru +``` + +Pick the hardware-appropriate base model: + +| GPU | Base model | Quant | Effective memory | +|--------------------|-------------------------|------------|------------------| +| 24 GB (4090, 3090) | `Qwen2.5-Coder-7B` | 4-bit | ~14 GB | +| 48 GB (A6000) | `Qwen2.5-Coder-14B` | 4-bit | ~22 GB | +| 80 GB (A100, H100) | `Qwen2.5-Coder-32B` | 4-bit | ~38 GB | + +Pull the base model checkpoint to a host directory (one-time): + +```sh +mkdir -p ~/training/models +huggingface-cli download Qwen/Qwen2.5-Coder-14B-Instruct \ + --local-dir ~/training/models/qwen25-coder-14b +``` + +(Login first with `huggingface-cli login` if the model requires it.) + +--- + +## 2. Pull the corpus + +The docs site exposes the corpus at `/corpus/*.jsonl`. We pull the chat +format because the trainer config below uses HF's `chat_template`. + +```sh +cd ~/training/nibiru +mkdir -p data +curl -fLo data/chat.jsonl https://nibiru-framework.com/corpus/chat-en.jsonl +curl -fLo data/manifest.json https://nibiru-framework.com/corpus/manifest.json + +# Verify the file integrity +SHA=$(jq -r '.files[] | select(.filename=="chat-en.jsonl") | .sha256' data/manifest.json) +test "$(sha256sum data/chat.jsonl | cut -d' ' -f1)" = "$SHA" && echo "ok" || echo "MISMATCH" +``` + +For a multilingual LoRA pull `chat-all.jsonl` instead. Keep one language per +training run unless you have a reason to mix — it makes the loss curve +cleaner and the resulting model less prone to language-leakage. + +--- + +## 3. Training container — `Dockerfile` + `compose.yml` + +The Sessions GUI dashboard polls the box via SSH and runs `docker logs` on +the container, parsing the tqdm progress + `'loss'` lines. So the container +needs to run inside Docker (not bare-metal), under a stable name, with logs +streamed to stdout. + +```sh +cd ~/training/nibiru +``` + +**`Dockerfile`** (copy verbatim): + +```dockerfile +# syntax=docker/dockerfile:1.6 +FROM nvidia/cuda:12.4.1-cudnn-runtime-ubuntu22.04 + +ENV DEBIAN_FRONTEND=noninteractive PYTHONUNBUFFERED=1 PIP_NO_CACHE_DIR=1 +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 python3-pip git ca-certificates && rm -rf /var/lib/apt/lists/* + +RUN pip3 install --upgrade pip && pip3 install \ + "torch==2.4.*" --index-url https://download.pytorch.org/whl/cu124 +RUN pip3 install \ + "unsloth[cu124-torch240]==2024.10.7" \ + "transformers==4.46.*" \ + "datasets==3.0.*" \ + "trl==0.11.*" \ + "peft==0.13.*" \ + "accelerate==1.0.*" \ + "bitsandbytes==0.44.*" + +WORKDIR /workspace +COPY train.py ./train.py +CMD ["python3", "-u", "train.py"] +``` + +**`compose.yml`**: + +```yaml +services: + trainer: + build: . + container_name: nibiru-trainer + restart: "no" + runtime: nvidia + environment: + NVIDIA_VISIBLE_DEVICES: all + NVIDIA_DRIVER_CAPABILITIES: compute,utility + volumes: + - ./data:/workspace/data:ro + - ./out:/workspace/out + - ~/training/models:/workspace/models:ro + shm_size: '8gb' +``` + +--- + +## 4. Training script — `train.py` + +```python +"""Nibiru LoRA — single-GPU unsloth, chat-template, HF Trainer. + +Outputs: + out/nibiru-lora/ + adapter_hf/ # the LoRA adapter (PEFT format) + trainer_state.json # epochs, losses, eval — what the dashboard reads + checkpoint-*/ # periodic checkpoints + logs/ # tensorboard event files +""" +import os, json +from datasets import load_dataset +from trl import SFTConfig, SFTTrainer +from unsloth import FastLanguageModel +from unsloth.chat_templates import get_chat_template + +BASE_MODEL = os.environ.get("BASE_MODEL", "/workspace/models/qwen25-coder-14b") +TRAIN_FILE = os.environ.get("TRAIN_FILE", "/workspace/data/chat.jsonl") +OUTPUT_DIR = os.environ.get("OUTPUT_DIR", "/workspace/out/nibiru-lora") +MAX_SEQ_LEN = int(os.environ.get("MAX_SEQ_LEN", "4096")) + +# 1. Load model + 4-bit quant + LoRA adapter on top +model, tokenizer = FastLanguageModel.from_pretrained( + model_name = BASE_MODEL, + max_seq_length = MAX_SEQ_LEN, + load_in_4bit = True, +) +model = FastLanguageModel.get_peft_model( + model, + r = 16, + target_modules = ["q_proj","k_proj","v_proj","o_proj","gate_proj","up_proj","down_proj"], + lora_alpha = 32, + lora_dropout = 0.05, + bias = "none", + use_gradient_checkpointing = "unsloth", +) +tokenizer = get_chat_template(tokenizer, chat_template="qwen-2.5") + +# 2. Load corpus, format as chat with the tokenizer's template +ds = load_dataset("json", data_files=TRAIN_FILE, split="train") +def fmt(rec): + msgs = rec["messages"] + return {"text": tokenizer.apply_chat_template(msgs, tokenize=False, add_generation_prompt=False)} +ds = ds.map(fmt, num_proc=4, remove_columns=ds.column_names) + +# 3. Train +trainer = SFTTrainer( + model = model, + tokenizer = tokenizer, + train_dataset = ds, + args = SFTConfig( + output_dir = OUTPUT_DIR, + max_seq_length = MAX_SEQ_LEN, + per_device_train_batch_size = 2, + gradient_accumulation_steps = 4, + warmup_ratio = 0.03, + num_train_epochs = 3, + learning_rate = 2e-4, + bf16 = True, + logging_steps = 5, + save_steps = 200, + save_total_limit = 3, + report_to = "none", + dataset_text_field = "text", + packing = True, + # === trainer_state === ← marker the Sessions GUI dashboard greps for + ), +) +trainer.train() + +# 4. Save adapter in HF (PEFT) format — what the merge step expects +model.save_pretrained(os.path.join(OUTPUT_DIR, "adapter_hf")) +tokenizer.save_pretrained(os.path.join(OUTPUT_DIR, "adapter_hf")) +print("\\n=== training complete ===") +``` + +The literal comment `=== trainer_state ===` near the SFTConfig is the marker +the dashboard uses to fall back to reading `trainer_state.json` after the +container exits — see `dashboard/server.py:_extract_trainer_state`. Don't +remove it. + +--- + +## 5. Run it + +```sh +cd ~/training/nibiru +docker compose build +docker compose up -d +docker logs -f nibiru-trainer +``` + +Expected log shape (this is what the Sessions GUI parses): + +``` +{'loss': '1.2345', 'grad_norm': '...', 'learning_rate': ..., 'epoch': '0.05'} + 12%|## | 60/500 [01:23<10:14, 1.40s/it] +``` + +--- + +## 6. Open the Sessions GUI Training tab + +In the GUI, click **Training**. Fill the strip at the top of the tab: + +| Field | Value | +|-----------------|----------------------------------------------| +| host | `@` | +| container | `nibiru-trainer` | +| project_dir | `/home//training/nibiru` | +| output_subdir | `out/nibiru-lora` | +| adapter_filename| `adapter_hf/adapter_model.safetensors` | + +The dashboard remembers the last config in `~/.config/training-monitor/last.json`, +so after the first save you just open the tab and the live metrics appear. + +While the container is running you'll see: +- progress bar (% / step / total / ETA — parsed from tqdm) +- last 30 loss values + epoch +- the live `docker ps` line for the container + +After training ends and the container exits, the dashboard falls back to +`trainer_state.json` in `out/nibiru-lora/` so the final losses + step count +stay visible. + +--- + +## 7. Merge LoRA into the base + register on Ollama + +```sh +# On the GPU box, still inside ~/training/nibiru/ +docker run --rm --runtime=nvidia \ + -v $PWD/out/nibiru-lora:/lora:ro \ + -v ~/training/models/qwen25-coder-14b:/base:ro \ + -v $PWD/out/merged:/out \ + nibiru-trainer \ + python3 -c " +from unsloth import FastLanguageModel +m, tok = FastLanguageModel.from_pretrained('/base', load_in_4bit=False) +m.load_adapter('/lora/adapter_hf', adapter_name='nibiru') +m.merge_and_unload() +m.save_pretrained_gguf('/out', tok, quantization_method='q4_k_m') +" +``` + +This writes a single `*-q4_k_m.gguf` in `out/merged/`. Push it to your Ollama: + +```sh +# === build a Modelfile referencing the merged GGUF === +GGUF=$(ls out/merged/*.gguf | head -1) +cat > out/merged/Modelfile <.jsonl without a separate copy step. Gitignored. +const OUT_DIR = path.resolve(__dirname, '../public/corpus'); + +// ============================================================================= +// System prompts +// ============================================================================= const SYSTEM_PROMPT = { en: 'You are an expert on the Nibiru PHP framework. Answer based on the documentation, with concrete code examples and file paths where helpful.', @@ -31,28 +50,316 @@ const SYSTEM_PROMPT = { fr: "Tu es expert du framework PHP Nibiru. Réponds sur la base de la documentation, avec des exemples de code concrets et des chemins de fichiers lorsque c'est utile.", }; -const QUESTION_PREFIX = { - en: ['How do I', 'What is', 'Explain', 'Show me'], - de: ['Wie', 'Was ist', 'Erkläre', 'Zeig mir'], - ja: ['', '', 'について教えてください:', ''], - es: ['¿Cómo', '¿Qué es', 'Explica', 'Muéstrame'], - fr: ['Comment', "Qu'est-ce que", 'Explique', 'Montre-moi'], +// Stricter system prompt for the framework-reference source — it's the +// gold material with exact namespaces, file:line citations, and the small +// idioms we want the model to internalise. +const SYSTEM_PROMPT_REFERENCE = + 'You are a senior PHP architect and Nibiru framework expert. ' + + 'Answers must include exact namespaces, file paths with line numbers when available, ' + + 'and concrete code excerpts. Never say "presumably", "likely", or "appears to" ' + + '— if you do not know, say so plainly.'; + +// ============================================================================= +// Question-variant generation (deterministic, no LLM) +// ============================================================================= + +const QUESTION_TEMPLATES = { + en: { + definitional: ['What is {topic}?', 'Explain {topic}.', 'Tell me about {topic}.'], + procedural: ['How do I {topic_lc}?', 'Show me how to {topic_lc}.', 'Walk me through {topic_lc}.'], + topic: ['{topic}', '{topic} — overview', '{topic} in Nibiru'], + filePointer: ['Where is {topic} defined?', 'Which file contains {topic}?'], + codeFocused: ['Show me the code for {topic}.', 'Quote the {topic} implementation.'], + }, + de: { + definitional: ['Was ist {topic}?', 'Erkläre {topic}.', 'Was bedeutet {topic}?'], + procedural: ['Wie {topic_lc}?', 'Zeig mir, wie {topic_lc}.', 'Wie geht {topic_lc}?'], + topic: ['{topic}', '{topic} — Übersicht', '{topic} in Nibiru'], + filePointer: ['Wo ist {topic} definiert?', 'Welche Datei enthält {topic}?'], + codeFocused: ['Zeig mir den Code für {topic}.', 'Zitiere die {topic}-Implementierung.'], + }, + ja: { + definitional: ['{topic} とは何ですか?', '{topic} について説明してください。'], + procedural: ['{topic} のやり方を教えてください。', '{topic} の手順を教えてください。'], + topic: ['{topic}', '{topic} — 概要'], + filePointer: ['{topic} はどこで定義されていますか?'], + codeFocused: ['{topic} のコードを見せてください。'], + }, + es: { + definitional: ['¿Qué es {topic}?', 'Explica {topic}.'], + procedural: ['¿Cómo {topic_lc}?', 'Muéstrame cómo {topic_lc}.'], + topic: ['{topic}', '{topic} — visión general'], + filePointer: ['¿Dónde se define {topic}?'], + codeFocused: ['Muéstrame el código de {topic}.'], + }, + fr: { + definitional: ['Qu\'est-ce que {topic} ?', 'Explique {topic}.'], + procedural: ['Comment {topic_lc} ?', 'Montre-moi comment {topic_lc}.'], + topic: ['{topic}', '{topic} — vue d\'ensemble'], + filePointer: ['Où est défini {topic} ?'], + codeFocused: ['Montre-moi le code de {topic}.'], + }, }; -function questionFor(chunk) { - const lang = chunk.language || 'en'; - const heading = chunk.sectionTitle || chunk.pageTitle; - if (lang === 'ja') { - return `${heading} について教えてください。`; - } - const prefixes = QUESTION_PREFIX[lang] || QUESTION_PREFIX.en; - const prefix = prefixes[heading.length % prefixes.length]; - if (lang === 'es' || lang === 'fr') { - return `${prefix} ${heading.toLowerCase()} ?`.replace(' ', ' '); - } - return `${prefix} ${heading.toLowerCase()}?`; +// Hash-pick a template deterministically from a kind, so two builds give +// the same corpus (necessary for reproducible LoRA training runs). +function hashPick(arr, seed) { + const h = crypto.createHash('md5').update(seed).digest(); + return arr[h[0] % arr.length]; } +function questionVariants(chunk) { + const lang = chunk.language in QUESTION_TEMPLATES ? chunk.language : 'en'; + const tpl = QUESTION_TEMPLATES[lang]; + const topic = chunk.sectionTitle || chunk.pageTitle; + const topicLc = topic.toLowerCase(); + const seed = chunk.id + '|' + topic; + + const fill = (s) => s.replaceAll('{topic}', topic).replaceAll('{topic_lc}', topicLc); + + // Always include one of each kind so a chunk gets 4 phrasings minimum. + const variants = [ + fill(hashPick(tpl.definitional, seed + '|d')), + fill(hashPick(tpl.procedural, seed + '|p')), + fill(hashPick(tpl.topic, seed + '|t')), + ]; + // Add file-pointer / code-focused variants when the chunk actually + // references a file path or contains a code block. + if (/[a-z0-9_/.-]+\.(php|mjs|ts|tsx|astro|css|ini|sql)(:\d+)?/i.test(chunk.content)) { + variants.push(fill(hashPick(tpl.filePointer, seed + '|f'))); + } + if (/```/.test(chunk.content)) { + variants.push(fill(hashPick(tpl.codeFocused, seed + '|c'))); + } + return variants; +} + +// ============================================================================= +// Code-block extraction +// ============================================================================= + +// Pull out fenced code blocks paired with a leading sentence as the prompt. +function extractCodeBlockSamples(chunk) { + const out = []; + const lines = chunk.content.split('\n'); + let inFence = false; + let fenceLang = ''; + let buf = []; + let leadIn = ''; + let prevPara = []; + + for (const line of lines) { + const fence = line.match(/^```(.*)$/); + if (fence) { + if (!inFence) { + inFence = true; + fenceLang = fence[1].trim(); + buf = []; + leadIn = prevPara.join(' ').trim().slice(0, 240); + prevPara = []; + } else { + inFence = false; + if (buf.length >= 2) { + out.push({ + language: fenceLang || 'text', + leadIn, + code: buf.join('\n'), + }); + } + } + continue; + } + if (inFence) { + buf.push(line); + } else if (line.trim() === '') { + prevPara = []; + } else { + prevPara.push(line); + } + } + return out; +} + +function codeBlockQA(chunk, block, lang) { + const tpl = QUESTION_TEMPLATES[lang] || QUESTION_TEMPLATES.en; + const topic = chunk.sectionTitle || chunk.pageTitle; + const seed = chunk.id + '|code|' + block.code.slice(0, 32); + const q = hashPick(tpl.codeFocused, seed) + .replaceAll('{topic}', topic) + .replaceAll('{topic_lc}', topic.toLowerCase()); + + // Answer = optional lead-in + the code block. Wrap code in fences so the + // model learns to emit syntactically valid code blocks too. + const fence = '```' + (block.language || '') + '\n' + block.code + '\n```'; + const answer = block.leadIn ? `${block.leadIn}\n\n${fence}` : fence; + return { question: q, answer }; +} + +// ============================================================================= +// Source ingestion +// ============================================================================= + +function ingestPublicDocs() { + const files = walkDocs(DOCS_DIR); + const chunks = files.flatMap((f) => chunkFile(f, DOCS_DIR)); + return chunks.map((c) => ({ ...c, source: 'docs' })); +} + +function ingestFrameworkReference() { + if (!fs.existsSync(REFERENCE_FILE)) { + console.warn(`[corpus] no framework-reference-v2 at ${REFERENCE_FILE} — skipping`); + return []; + } + const raw = fs.readFileSync(REFERENCE_FILE, 'utf8'); + return chunkMarkdown(raw, { + language: 'en', + file: 'framework-reference-v2.md', + pageTitle: 'Nibiru Framework Reference v2', + pageDescription: 'Deep technical reference — every public factory, namespace, idiom and gotcha with file:line citations.', + baseUrl: '/reference/', + }).map((c) => ({ ...c, source: 'framework-reference-v2' })); +} + +// ============================================================================= +// Record assembly +// ============================================================================= + +function systemFor(chunk) { + if (chunk.source === 'framework-reference-v2') return SYSTEM_PROMPT_REFERENCE; + return SYSTEM_PROMPT[chunk.language] || SYSTEM_PROMPT.en; +} + +// Read the optional research-agent augmentation. Each line is alpaca-format +// `{instruction, input, output, metadata}`. Returns [] if the file is absent. +function loadAugmentation() { + if (!fs.existsSync(AUGMENTATION_FILE)) { + console.log(`[corpus] no augmentation file at ${AUGMENTATION_FILE} — skipping`); + return []; + } + const lines = fs.readFileSync(AUGMENTATION_FILE, 'utf8').split('\n').filter(Boolean); + const records = []; + for (const [i, line] of lines.entries()) { + try { + const rec = JSON.parse(line); + if (rec.instruction && rec.output) records.push(rec); + } catch (e) { + console.warn(`[corpus] skipping malformed augmentation line ${i + 1}: ${e.message}`); + } + } + console.log(`[corpus] loaded ${records.length} augmentation records`); + return records; +} + +function buildRecords(chunks) { + const chunksOut = []; + const instructionsOut = []; + const chatOut = []; + const completionOut = []; + + for (const c of chunks) { + // 1. Raw chunk record + chunksOut.push({ + id: c.id, + source: c.source, + url: c.url, + pageTitle: c.pageTitle, + sectionTitle: c.sectionTitle, + language: c.language, + tokens: c.tokens, + content: c.content, + }); + + // 2. Question-variant records + const sys = systemFor(c); + for (const q of questionVariants(c)) { + const meta = { + language: c.language, + source: c.url, + page: c.pageTitle, + origin: c.source, + }; + instructionsOut.push({ instruction: q, input: '', output: c.content, metadata: meta }); + chatOut.push({ + messages: [ + { role: 'system', content: sys }, + { role: 'user', content: q }, + { role: 'assistant', content: c.content }, + ], + metadata: meta, + }); + completionOut.push({ + prompt: `${sys}\n\nQuestion: ${q}\n\nAnswer:`, + completion: ' ' + c.content, + }); + } + + // 3. Code-block recall samples — only for the framework reference, + // where the code is gold (file:line cited, framework-canonical). + if (c.source === 'framework-reference-v2') { + const blocks = extractCodeBlockSamples(c); + for (const b of blocks) { + const { question, answer } = codeBlockQA(c, b, c.language); + const meta = { + language: c.language, + source: c.url, + page: c.pageTitle, + origin: c.source, + codeLanguage: b.language, + kind: 'code-recall', + }; + instructionsOut.push({ instruction: question, input: '', output: answer, metadata: meta }); + chatOut.push({ + messages: [ + { role: 'system', content: sys }, + { role: 'user', content: question }, + { role: 'assistant', content: answer }, + ], + metadata: meta, + }); + completionOut.push({ + prompt: `${sys}\n\nQuestion: ${question}\n\nAnswer:`, + completion: ' ' + answer, + }); + } + } + } + + // Merge research-agent augmentation. Each input record is alpaca-style; + // we fan it out into instructions / chat / completion to match the rest. + const augmentation = loadAugmentation(); + for (const a of augmentation) { + const sys = SYSTEM_PROMPT_REFERENCE; // augmentation is always English, framework-grade + const meta = { ...(a.metadata || {}), origin: 'lora-augmentation' }; + instructionsOut.push({ + instruction: a.instruction, + input: a.input || '', + output: a.output, + metadata: meta, + }); + chatOut.push({ + messages: [ + { role: 'system', content: sys }, + { role: 'user', content: a.instruction }, + { role: 'assistant', content: a.output }, + ], + metadata: meta, + }); + completionOut.push({ + prompt: `${sys}\n\nQuestion: ${a.instruction}\n\nAnswer:`, + completion: ' ' + a.output, + }); + } + if (augmentation.length) { + console.log(`[corpus] merged ${augmentation.length} augmentation records into instructions/chat/completion`); + } + + return { chunksOut, instructionsOut, chatOut, completionOut }; +} + +// ============================================================================= +// IO + manifest +// ============================================================================= + function ensureDir(d) { fs.mkdirSync(d, { recursive: true }); } @@ -65,61 +372,173 @@ function writeJsonl(filePath, items) { return new Promise((res) => stream.on('close', res)); } -async function main() { - console.log(`Walking ${DOCS_DIR}…`); - const files = walkDocs(DOCS_DIR); - const chunks = files.flatMap((f) => chunkFile(f, DOCS_DIR)); - console.log(`Produced ${chunks.length} chunks across ${files.length} files.`); - - const chunksOut = chunks.map((c) => ({ - id: c.id, - url: c.url, - pageTitle: c.pageTitle, - sectionTitle: c.sectionTitle, - language: c.language, - tokens: c.tokens, - content: c.content, - })); - - const instructionsOut = chunks.map((c) => ({ - instruction: questionFor(c), - input: '', - output: c.content, - metadata: { language: c.language, source: c.url, page: c.pageTitle }, - })); - - const chatOut = chunks.map((c) => ({ - messages: [ - { role: 'system', content: SYSTEM_PROMPT[c.language] || SYSTEM_PROMPT.en }, - { role: 'user', content: questionFor(c) }, - { role: 'assistant', content: c.content }, - ], - metadata: { language: c.language, source: c.url, page: c.pageTitle }, - })); - - const completionOut = chunks.map((c) => ({ - prompt: `${SYSTEM_PROMPT[c.language] || SYSTEM_PROMPT.en}\n\nQuestion: ${questionFor(c)}\n\nAnswer:`, - completion: ' ' + c.content, - })); - - await writeJsonl(path.join(OUT_DIR, 'chunks.jsonl'), chunksOut); - await writeJsonl(path.join(OUT_DIR, 'instructions.jsonl'), instructionsOut); - await writeJsonl(path.join(OUT_DIR, 'chat.jsonl'), chatOut); - await writeJsonl(path.join(OUT_DIR, 'completion.jsonl'), completionOut); - - const stats = { - generatedAt: new Date().toISOString(), - fileCount: files.length, - chunkCount: chunks.length, - byLanguage: chunks.reduce((acc, c) => { - acc[c.language] = (acc[c.language] || 0) + 1; - return acc; - }, {}), +function fileStats(filePath) { + const buf = fs.readFileSync(filePath); + return { + bytes: buf.length, + sha256: crypto.createHash('sha256').update(buf).digest('hex'), }; - fs.writeFileSync(path.join(OUT_DIR, 'stats.json'), JSON.stringify(stats, null, 2)); +} - console.log(`Wrote 4 JSONL files + stats.json to ${OUT_DIR}`); - console.log(JSON.stringify(stats, null, 2)); +function firstNonEmptyLine(filePath) { + const text = fs.readFileSync(filePath, 'utf8'); + const line = text.split('\n').find((l) => l.trim().length > 0) || ''; + return line.length > 800 ? line.slice(0, 800) + '…' : line; +} + +// ============================================================================= +// Main +// ============================================================================= + +// Language metadata — used both to bucket files and label them in the UI. +// Order matters: English first (the framework-reference is English-only and +// rolls into the en bucket), then localised docs. +const LANGUAGES = [ + { code: 'en', label: 'English' }, + { code: 'de', label: 'Deutsch' }, + { code: 'ja', label: '日本語' }, + { code: 'es', label: 'Español' }, + { code: 'fr', label: 'Français' }, +]; + +// Bucket records by their `language` (raw chunks) or `metadata.language` +// (alpaca/chat/completion records). Returns Map. +function bucketByLanguage(records, getLang) { + const map = new Map(); + for (const lang of LANGUAGES) map.set(lang.code, []); + for (const r of records) { + const lang = getLang(r) || 'en'; + const bucket = map.get(lang) ?? (map.set(lang, []), map.get(lang)); + bucket.push(r); + } + return map; +} + +async function main() { + console.log(`[corpus] DOCS_DIR=${DOCS_DIR}`); + console.log(`[corpus] REFERENCE=${REFERENCE_FILE}`); + console.log(`[corpus] OUT_DIR=${OUT_DIR}`); + + const docsChunks = ingestPublicDocs(); + const refChunks = ingestFrameworkReference(); + const chunks = [...refChunks, ...docsChunks]; // reference first → priority + + console.log(`[corpus] ingested ${refChunks.length} reference chunks + ${docsChunks.length} docs chunks`); + + const { chunksOut, instructionsOut, chatOut, completionOut } = buildRecords(chunks); + console.log(`[corpus] records: chunks=${chunksOut.length} instructions=${instructionsOut.length} chat=${chatOut.length} completion=${completionOut.length}`); + + ensureDir(OUT_DIR); + // Wipe any leftover files from a previous run so stale per-language + // buckets don't linger. + for (const f of fs.readdirSync(OUT_DIR)) { + if (/\.(jsonl|json)$/.test(f)) fs.unlinkSync(path.join(OUT_DIR, f)); + } + + // Per-language buckets. Each format gets one file per language plus a + // combined `*-all.jsonl` for callers who want everything. + const buckets = { + chunks: bucketByLanguage(chunksOut, (r) => r.language), + instructions: bucketByLanguage(instructionsOut, (r) => r.metadata?.language), + chat: bucketByLanguage(chatOut, (r) => r.metadata?.language), + completion: bucketByLanguage(completionOut, (r) => r.metadata?.language ?? 'en'), + }; + // `completion` records don't carry metadata (prompt/completion-only), + // so its bucketing falls back to en. To keep splits accurate we recompute + // from instructionsOut which has the same shape and ordering pre-bucket: + { + const completionMap = new Map(); + for (const lang of LANGUAGES) completionMap.set(lang.code, []); + for (let i = 0; i < instructionsOut.length; i++) { + const lang = instructionsOut[i].metadata?.language || 'en'; + completionMap.get(lang)?.push(completionOut[i]); + } + buckets.completion = completionMap; + } + + const writeBucketed = async (formatName, bucketMap, allRecords) => { + const out = []; + // Per-language files + for (const lang of LANGUAGES) { + const records = bucketMap.get(lang.code) || []; + if (records.length === 0) continue; + const filename = `${formatName}-${lang.code}.jsonl`; + await writeJsonl(path.join(OUT_DIR, filename), records); + out.push({ + format: formatName, + language: lang.code, + languageLabel: lang.label, + filename, + records: records.length, + }); + } + // Combined all-language file + const allFilename = `${formatName}-all.jsonl`; + await writeJsonl(path.join(OUT_DIR, allFilename), allRecords); + out.push({ + format: formatName, + language: 'all', + languageLabel: 'All languages', + filename: allFilename, + records: allRecords.length, + }); + return out; + }; + + const allFileMeta = [ + ...await writeBucketed('chunks', buckets.chunks, chunksOut), + ...await writeBucketed('instructions', buckets.instructions, instructionsOut), + ...await writeBucketed('chat', buckets.chat, chatOut), + ...await writeBucketed('completion', buckets.completion, completionOut), + ]; + + // Per-language breakdown of the chunks (handy for inspection). + const byLanguage = chunks.reduce((acc, c) => { + acc[c.language] = (acc[c.language] || 0) + 1; + return acc; + }, {}); + const bySource = chunks.reduce((acc, c) => { + acc[c.source] = (acc[c.source] || 0) + 1; + return acc; + }, {}); + + // Hash + size + preview for every file written. + const filesEnriched = allFileMeta.map((f) => { + const fp = path.join(OUT_DIR, f.filename); + const st = fileStats(fp); + return { + ...f, + bytes: st.bytes, + sha256: st.sha256, + samplePreview: firstNonEmptyLine(fp), + }; + }); + + const manifest = { + generatedAt: new Date().toISOString(), + generator: { + script: 'scripts/build-corpus.mjs', + node: process.version, + }, + encoding: 'utf-8', + sources: { + 'framework-reference-v2.md': refChunks.length, + 'src/content/docs/': docsChunks.length, + }, + chunkCount: chunks.length, + byLanguage, + bySource, + languages: LANGUAGES, + formats: ['chunks', 'instructions', 'chat', 'completion'], + files: filesEnriched, + }; + fs.writeFileSync(path.join(OUT_DIR, 'manifest.json'), JSON.stringify(manifest, null, 2)); + + console.log('[corpus] done — wrote', filesEnriched.length, 'files'); + console.log('[corpus] per-format/per-language summary:'); + for (const f of filesEnriched) { + console.log(` ${f.filename.padEnd(28)} ${String(f.records).padStart(5)} records ${(f.bytes / 1024).toFixed(1).padStart(7)} KB`); + } } main().catch((e) => { diff --git a/docs/scripts/build-oracle-index.mjs b/docs/scripts/build-oracle-index.mjs index f494594..4d2571b 100644 --- a/docs/scripts/build-oracle-index.mjs +++ b/docs/scripts/build-oracle-index.mjs @@ -4,7 +4,7 @@ * * node scripts/build-oracle-index.mjs * - * Defaults to Ollama at https://api.neuronetz.ai with model nomic-embed-text. + * Defaults to Ollama at https://your-ollama-host.example with model nomic-embed-text. * Override via env: * OLLAMA_BASE_URL=... * OLLAMA_EMBED_MODEL=... (e.g. nomic-embed-text, mxbai-embed-large) diff --git a/docs/scripts/lib/chunk.mjs b/docs/scripts/lib/chunk.mjs index 25bc36c..66d266a 100644 --- a/docs/scripts/lib/chunk.mjs +++ b/docs/scripts/lib/chunk.mjs @@ -109,24 +109,29 @@ function mergeSmall(sections) { return out; } -export function chunkFile(filePath, rootDir) { - const raw = fs.readFileSync(filePath, 'utf8'); +/** + * Lower-level: chunk a raw markdown string with caller-supplied metadata. + * Used both by chunkFile() (which derives meta from a path) and by + * external sources like the framework-reference-v2 doc. + * + * @param {string} raw raw markdown (frontmatter optional) + * @param {object} meta { + * language, file, baseUrl, pageTitle, pageDescription + * } — language defaults to 'en'; baseUrl defaults to '/'; pageTitle to file + */ +export function chunkMarkdown(raw, meta = {}) { const { frontmatter, body } = stripFrontmatter(raw); - // URL: docs//.md(x) → /// - const rel = path.relative(rootDir, filePath).replace(/\\/g, '/'); - const parts = rel.split('/'); - const lang = parts[0]; - const slug = parts.slice(1).join('/').replace(/\.(md|mdx)$/, '').replace(/\/index$/, ''); - const baseUrl = '/' + (slug ? `${lang}/${slug}/` : `${lang}/`); + const language = meta.language || frontmatter.lang || 'en'; + const file = meta.file || meta.pageTitle || 'untitled.md'; + const baseUrl = meta.baseUrl || '/'; + const pageTitle = meta.pageTitle || frontmatter.title || file; + const pageDescription = meta.pageDescription || frontmatter.description || ''; let sections = splitByHeadings(body); sections = sections.flatMap(splitOversized); sections = mergeSmall(sections); - const pageTitle = frontmatter.title || slug || 'Untitled'; - const pageDescription = frontmatter.description || ''; - return sections .filter((s) => s.lines.join('\n').trim().length > 0) .map((s, idx) => { @@ -134,9 +139,9 @@ export function chunkFile(filePath, rootDir) { const sectionTitle = s.heading || pageTitle; const url = s.anchor && s.heading ? `${baseUrl}#${s.anchor}` : baseUrl; return { - id: `${rel}#${s.anchor ?? `_${idx}`}`, - language: lang, - file: rel, + id: `${file}#${s.anchor ?? `_${idx}`}`, + language, + file, url, pageTitle, pageDescription, @@ -148,6 +153,19 @@ export function chunkFile(filePath, rootDir) { }); } +export function chunkFile(filePath, rootDir) { + const raw = fs.readFileSync(filePath, 'utf8'); + + // URL: docs//.md(x) → /// + const rel = path.relative(rootDir, filePath).replace(/\\/g, '/'); + const parts = rel.split('/'); + const lang = parts[0]; + const slug = parts.slice(1).join('/').replace(/\.(md|mdx)$/, '').replace(/\/index$/, ''); + const baseUrl = '/' + (slug ? `${lang}/${slug}/` : `${lang}/`); + + return chunkMarkdown(raw, { language: lang, file: rel, baseUrl }); +} + export function walkDocs(docsDir) { const out = []; const stack = [docsDir]; diff --git a/docs/scripts/lib/providers.mjs b/docs/scripts/lib/providers.mjs index 1398707..b4ea090 100644 --- a/docs/scripts/lib/providers.mjs +++ b/docs/scripts/lib/providers.mjs @@ -1,7 +1,7 @@ // Unified provider abstraction for chat and embeddings. // Used by build-oracle-index.mjs (build time) and src/pages/api/oracle.ts (runtime). -const DEFAULT_OLLAMA_URL = 'https://api.neuronetz.ai'; +const DEFAULT_OLLAMA_URL = 'http://localhost:11434'; const DEFAULT_OLLAMA_CHAT = 'qwen2.5-coder:14b'; const DEFAULT_OLLAMA_EMBED = 'nomic-embed-text'; const DEFAULT_ANTHROPIC = 'claude-haiku-4-5-20251001'; diff --git a/docs/scripts/translate-docs.mjs b/docs/scripts/translate-docs.mjs index 3b37db5..e730637 100644 --- a/docs/scripts/translate-docs.mjs +++ b/docs/scripts/translate-docs.mjs @@ -1,7 +1,7 @@ #!/usr/bin/env node /** * Translate every English doc (src/content/docs/en/**) into one or more - * target locales using your own Ollama on neuronetz.ai. + * target locales using your own Ollama on your Ollama instance. * * node scripts/translate-docs.mjs # all locales (de, ja, es, fr) * node scripts/translate-docs.mjs --lang=de # only German @@ -10,7 +10,7 @@ * node scripts/translate-docs.mjs --only=start/ # path prefix filter * * Env: - * OLLAMA_BASE_URL (default https://api.neuronetz.ai) + * OLLAMA_BASE_URL (default https://your-ollama-host.example) * OLLAMA_TRANSLATE_MODEL (default qwen3.6:35b → falls back to mistral-small, * then qwen2.5-coder:14b) * @@ -33,7 +33,7 @@ const DOCS_DIR = path.resolve(__dirname, '../src/content/docs'); const SOURCE_LANG = 'en'; const ALL_TARGETS = ['de', 'ja', 'es', 'fr']; -const OLLAMA_URL = (process.env.OLLAMA_BASE_URL ?? 'https://api.neuronetz.ai').replace(/\/$/, ''); +const OLLAMA_URL = (process.env.OLLAMA_BASE_URL ?? 'http://localhost:11434').replace(/\/$/, ''); // Default to a fast model that fits inside the nginx 60-90s timeout. // qwen2.5-coder:14b is verified live; mistral-small handles European // languages well; qwen2 is solid for Japanese. diff --git a/docs/src/components/DownloadsManifest.astro b/docs/src/components/DownloadsManifest.astro new file mode 100644 index 0000000..894ab18 --- /dev/null +++ b/docs/src/components/DownloadsManifest.astro @@ -0,0 +1,275 @@ +--- +/** + * Renders the LoRA corpus download manifest as a styled card grid. + * + * Reads public/corpus/manifest.json at build time. Each format (chunks, + * instructions, chat, completion) gets one card; within the card the + * user picks a language bucket (en / de / ja / es / fr / all). Astro + * copies public/corpus/*.jsonl into the static output, so download + * links work without any extra plumbing. + */ +import fs from 'node:fs'; +import path from 'node:path'; + +const manifestPath = path.resolve(process.cwd(), 'public/corpus/manifest.json'); +const manifest = fs.existsSync(manifestPath) + ? JSON.parse(fs.readFileSync(manifestPath, 'utf8')) + : null; + +const FORMAT_LABEL: Record = { + chunks: 'Raw chunks', + instructions: 'Alpaca / instructions', + chat: 'ShareGPT / chat', + completion: 'Prompt / completion', +}; + +const FORMAT_BLURB: Record = { + chunks: 'One record per source chunk (no Q/A). Drop into a vector store, or use as a RAG corpus.', + instructions: 'Alpaca-style triples: instruction, input, output. The most common LoRA format — works with axolotl, llama-factory, unsloth.', + chat: 'Multi-turn messages format (system / user / assistant). Best for chat-LoRAs and OpenAI-compatible fine-tune APIs.', + completion: 'Legacy prompt / completion pairs for old-style text-completion fine-tuning.', +}; + +function fmtBytes(n: number): string { + if (n < 1024) return `${n} B`; + if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`; + return `${(n / (1024 * 1024)).toFixed(2)} MB`; +} +function fmtNumber(n: number): string { return n.toLocaleString('en-US'); } + +type FileMeta = { + format: string; + language: string; + languageLabel: string; + filename: string; + records: number; + bytes: number; + sha256: string; + samplePreview: string; +}; + +// Group files by format so we can render one card per format. +const grouped: Record = {}; +if (manifest) { + for (const f of manifest.files as FileMeta[]) { + (grouped[f.format] ??= []).push(f); + } +} +--- + +{manifest === null ? ( + +) : ( + <> +
+ {fmtNumber(manifest.chunkCount)} chunks + {fmtNumber(manifest.sources['framework-reference-v2.md'])} from the v2 reference + {fmtNumber(manifest.sources['src/content/docs/'])} from public docs ({Object.keys(manifest.byLanguage).length} languages) + encoding {manifest.encoding} + built {new Date(manifest.generatedAt).toISOString().slice(0, 16).replace('T', ' ')} UTC +
+ +
+ {(manifest.formats as string[]).map((fmt) => { + const files = grouped[fmt] || []; + if (!files.length) return null; + const allFile = files.find((f) => f.language === 'all'); + const sample = allFile?.samplePreview || files[0].samplePreview; + const sampleSrc = allFile?.filename || files[0].filename; + return ( + + ); + })} +
+ +)} + + diff --git a/docs/src/components/LandingScripts.astro b/docs/src/components/LandingScripts.astro index a93cec4..84db2fc 100644 --- a/docs/src/components/LandingScripts.astro +++ b/docs/src/components/LandingScripts.astro @@ -13,7 +13,7 @@ * * Mission Control chat posts to /api/oracle (Astro endpoint at * src/pages/api/oracle.ts) which routes to Ollama via providers.mjs. - * Production points the Ollama base URL at api.neuronetz.ai. The fallback + * Production points the Ollama base URL at your-ollama-host.example. The fallback * "Link interrupted. Re-establishing controller…" message now only fires * if the fetch itself fails or the endpoint returns non-2xx. */ diff --git a/docs/src/content/docs/de/ai/module/embed.md b/docs/src/content/docs/de/ai/module/embed.md index 90c3c86..decd51b 100644 --- a/docs/src/content/docs/de/ai/module/embed.md +++ b/docs/src/content/docs/de/ai/module/embed.md @@ -65,10 +65,10 @@ Das RAG-Plugin verwendet dieses Format intern für seine JSON-Dateien. ## Auswahl der eingebetteten Modelle -Ziehen Sie auf neuronetz.ai einmal: +Ziehen Sie auf Ihrer Ollama.ai einmal: ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' # 768 dim, default -curl https://api.neuronetz.ai/api/pull -d '{"name":"mxbai-embed-large"}' # 1024 dim, higher quality +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' # 768 dim, default +curl https://your-ollama-host.example/api/pull -d '{"name":"mxbai-embed-large"}' # 1024 dim, higher quality ``` In `ai.ini`: ```ini diff --git a/docs/src/content/docs/de/ai/module/overview.md b/docs/src/content/docs/de/ai/module/overview.md index 1d60376..8ef2cc2 100644 --- a/docs/src/content/docs/de/ai/module/overview.md +++ b/docs/src/content/docs/de/ai/module/overview.md @@ -1,11 +1,11 @@ --- title: "Das KI-Modul" -description: "Erster-Klasse KI auf Nibiru – Chat, Embeddings, RAG, Agenten – verbunden mit Ihrem eigenen Ollama auf neuronetz.ai. Keine bezahlten APIs erforderlich." +description: "Erster-Klasse KI auf Nibiru – Chat, Embeddings, RAG, Agenten – verbunden mit Ihrem eigenen Ollama auf Ihrer Ollama-Instanz. Keine bezahlten APIs erforderlich." --- Nibiru bietet ein **KIM-Modul** (`application/module/ai/`), das jeder Nibiru-Anwendung eine erstklassige KI-Oberfläche gibt. PHP-Code kann mit einem lokalen LLM chatten, Text einbetten, RAG über eigene Daten ausführen oder einen Agenten mit Tools starten – alles ohne einen Byte an eine bezahlte API zu senden. -Das Modul ist standardmäßig mit Ihrem eigenen [Ollama auf neuronetz.ai](/de/kuenstliche-intelligenz/orakel/) verbunden, sodass die Inferenz auf Ihrer Hardware, in Ihrem Netzwerk und Ihren Bedingungen erfolgt. +Das Modul ist standardmäßig mit Ihrem eigenen [Ollama auf Ihrer Ollama-Instanz](/de/kuenstliche-intelligenz/orakel/) verbunden, sodass die Inferenz auf Ihrer Hardware, in Ihrem Netzwerk und Ihren Bedingungen erfolgt. ## Was Sie erhalten @@ -34,7 +34,7 @@ Dies ist die gesamte API-Oberfläche für den einfachen Fall. Kein Dependency In Jedes Plugin liest seine Einstellungen aus `application/module/ai/settings/ai.ini`: ```ini [AI] -ollama.base_url = "https://api.neuronetz.ai" +ollama.base_url = "https://your-ollama-host.example" chat.model = "nibiru-coder:1.0" chat.fallback_model = "qwen2.5-coder:14b" chat.temperature = 0.4 diff --git a/docs/src/content/docs/de/ai/module/training.md b/docs/src/content/docs/de/ai/module/training.md index 355c508..9bffdd8 100644 --- a/docs/src/content/docs/de/ai/module/training.md +++ b/docs/src/content/docs/de/ai/module/training.md @@ -23,7 +23,7 @@ Die Anpassung des System-Prompts erfolgt **unmittelbar** — keine GPU-Training, Das Skript: 1. Liest die Datei `Modelfile` neben sich. -2. Sendet eine POST-Anfrage an `${OLLAMA_BASE_URL}/api/create` (Standardwert `https://api.neuronetz.ai`). +2. Sendet eine POST-Anfrage an `${OLLAMA_BASE_URL}/api/create` (Standardwert `https://your-ollama-host.example`). 3. Führt einen Rauchtest-Chat-Aufruf durch, um zu bestätigen, dass der neue Tag antwortet. Nachdem es erfolgreich ist, setzen Sie das Modell in `application/module/ai/settings/ai.ini`: diff --git a/docs/src/content/docs/de/ai/oracle.md b/docs/src/content/docs/de/ai/oracle.md index 55d8884..9fcc665 100644 --- a/docs/src/content/docs/de/ai/oracle.md +++ b/docs/src/content/docs/de/ai/oracle.md @@ -1,6 +1,6 @@ --- title: "Frage die Oracle" -description: "Wie der eingebettete KI-Assistent funktioniert – RAG über die Dokumentationen, bereitgestellt durch Ihren eigenen Ollama auf neuronetz.ai." +description: "Wie der eingebettete KI-Assistent funktioniert – RAG über die Dokumentationen, bereitgestellt durch Ihren eigenen Ollama auf Ihrer Ollama-Instanz." --- Die orange Schaltfläche in der Ecke jeder Seite ist der **Nibiru Oracle** – ein KI-Assistent, der auf dieser Dokumentation basiert. Fragen Sie ihn nach Routing, Modulen, der CLI, der Smarty-Schicht oder der Bedeutung von `pageAction()`. Er zitiert seine Quellen. @@ -11,8 +11,8 @@ Standardmäßig läuft der Oracle vollständig auf **Ihren eigenen Infrastruktur | Ebene | Backend | Standardmodell | |---|---|---| -| Chat (Antwortgenerierung) | Ollama auf `https://api.neuronetz.ai` | `qwen2.5-coder:14b` | -| Embeddings (RAG-Retrieval) | Ollama auf `https://api.neuronetz.ai` | `nomic-embed-text` | +| Chat (Antwortgenerierung) | Ollama auf `https://your-ollama-host.example` | `qwen2.5-coder:14b` | +| Embeddings (RAG-Retrieval) | Ollama auf `https://your-ollama-host.example` | `nomic-embed-text` | Keine bezahlten API-Schlüssel. Ihre Daten verlassen Ihr Netzwerk nicht. Der 5-GPU-Cluster von Ollama, den Sie bereits betreiben, übernimmt die Last. @@ -42,12 +42,12 @@ flowchart LR | `src/pages/api/oracle.ts` | Der SSR-Endpunkt, an den das Chat-Widget POSTs. Bietet auch einen GET für Diagnosen. | | `src/components/CosmicHeader.astro` | Der schwebende Launcher + Chat-Benutzeroberfläche. | -## Einmalige Einrichtung auf neuronetz.ai +## Einmalige Einrichtung auf Ihrer Ollama.ai Ziehen Sie die beiden Modelle herunter, die der Oracle verwendet: ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` `qwen2.5-coder:14b` ist bereits installiert (lebt getestet). `nomic-embed-text` fehlt noch; ohne es läuft der Oracle im Chat-Modus (ohne RAG). @@ -55,9 +55,9 @@ curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' Der Oracle liest seine Konfiguration aus Umgebungsvariablen. Sinnvolle Standardwerte sind integriert. ```bash -# Default mode (Ollama on neuronetz.ai) +# Default mode (Ollama on your Ollama instance) LLM_PROVIDER=ollama # default -OLLAMA_BASE_URL=https://api.neuronetz.ai # default +OLLAMA_BASE_URL=https://your-ollama-host.example # default OLLAMA_CHAT_MODEL=qwen2.5-coder:14b # default OLLAMA_EMBED_MODEL=nomic-embed-text # default @@ -81,9 +81,9 @@ ORACLE_MAX_TOKENS=800 curl https://nibiru-framework.com/api/oracle { "status": "ok", - "llm": { "provider": "ollama", "ollamaUrl": "https://api.neuronetz.ai", + "llm": { "provider": "ollama", "ollamaUrl": "https://your-ollama-host.example", "model": "qwen2.5-coder:14b" }, - "embed": { "provider": "ollama", "ollamaUrl": "https://api.neuronetz.ai", + "embed": { "provider": "ollama", "ollamaUrl": "https://your-ollama-host.example", "model": "nomic-embed-text" }, "index": { "present": true, "chunks": 177, "provider": "ollama", "model": "nomic-embed-text" } diff --git a/docs/src/content/docs/de/start/deployment.md b/docs/src/content/docs/de/start/deployment.md index edb7a78..c84d6b5 100644 --- a/docs/src/content/docs/de/start/deployment.md +++ b/docs/src/content/docs/de/start/deployment.md @@ -1,9 +1,9 @@ --- title: "Die Dokumentationssite bereitstellen" -description: "Produktionsbereitstellung von nibiru-framework.com mit jwilder/nginx-proxy und Ihrem eigenen Ollama auf neuronetz.ai." +description: "Produktionsbereitstellung von nibiru-framework.com mit jwilder/nginx-proxy und Ihrem eigenen Ollama auf Ihrer Ollama-Instanz." --- -Diese Seite dokumentiert, wie die Dokumentationssite in der Produktionsumgebung bereitgestellt wird. Die Einrichtung verwendet **jwilder/nginx-proxy** für automatische Docker-Containerrouting, **letsencrypt-nginx-proxy-companion** für HTTPS und **Ihre eigene Ollama unter api.neuronetz.ai** für den Oracle-Backend — keine bezahlten LLM-API-Schlüssel erforderlich. +Diese Seite dokumentiert, wie die Dokumentationssite in der Produktionsumgebung bereitgestellt wird. Die Einrichtung verwendet **jwilder/nginx-proxy** für automatische Docker-Containerrouting, **letsencrypt-nginx-proxy-companion** für HTTPS und **Ihre eigene Ollama unter your-ollama-host.example** für den Oracle-Backend — keine bezahlten LLM-API-Schlüssel erforderlich. ## Topologie ``` @@ -17,7 +17,7 @@ Diese Seite dokumentiert, wie die Dokumentationssite in der Produktionsumgebung │ http://nibiru-docs:4321 ▼ ┌──────────────────────┐ ┌──────────────────────┐ - │ nibiru-docs │ ──────▶ │ api.neuronetz.ai │ + │ nibiru-docs │ ──────▶ │ your-ollama-host.example │ │ Astro Node SSR :4321 │ HTTPS │ Ollama (5× GPU) │ │ Oracle endpoint │ │ qwen2.5-coder:14b │ └──────────────────────┘ │ nomic-embed-text │ @@ -31,19 +31,19 @@ docker network create nginx-proxy # 2) Run nginx-proxy + acme-companion (one time) # See https://github.com/nginx-proxy/nginx-proxy for the canonical compose. -# 3) Pull the Oracle's models on neuronetz.ai (one time) -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +# 3) Pull the Oracle's models on your Ollama instance (one time) +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` ## Dateien in `docs/` | Datei | Zweck | |---|---| -| `Dockerfile` | Mehrstufiger Build: erstellt Oracle-Index gegen neuronetz.ai, baut Astro, entfernt Entwicklungsabhängigkeiten. | +| `Dockerfile` | Mehrstufiger Build: erstellt Oracle-Index gegen your Ollama instance, baut Astro, entfernt Entwicklungsabhängigkeiten. | | `docker-compose.yml` | Produktion — `VIRTUAL_HOST=nibiru-framework.com`, verbunden mit dem Netzwerk `nginx-proxy`. | | `docker-compose.local.yml` | Lokale-Test-Überschreibung — macht Port `4321:4321` verfügbar, entfernt Umgebungsvariablen von nginx-proxy. | | `.dockerignore` | Verhindert, dass `node_modules`, `.git` usw. in den Build-Kontext aufgenommen werden. | -| `.env.example` | Vorlage — standardmäßig verwendet Ollama auf neuronetz.ai, keine API-Schlüssel erforderlich. | +| `.env.example` | Vorlage — standardmäßig verwendet Ollama auf Ihrer Ollama-Instanz, keine API-Schlüssel erforderlich. | ## Befehl ausführen ```bash @@ -81,7 +81,7 @@ Der Build führt den Oracle-Index erneut gegen den neuesten Inhalt aus; der neue | Var | Default | Used at | Purpose | |---|---|---|---| | `LLM_PROVIDER` | `ollama` | runtime | `ollama` (default) oder `anthropic`. | -| `OLLAMA_BASE_URL` | `https://api.neuronetz.ai` | build + runtime | Wo Ollama erreichbar ist. | +| `OLLAMA_BASE_URL` | `https://your-ollama-host.example` | build + runtime | Wo Ollama erreichbar ist. | | `OLLAMA_CHAT_MODEL` | `qwen2.5-coder:14b` | runtime | Chat-Vervollständigungsmodell. | | `OLLAMA_EMBED_MODEL` | `nomic-embed-text` | build + runtime | Einbettungsmodell. | | `EMBED_PROVIDER` | `ollama` | build + runtime | `ollama` oder `openai`. | @@ -98,12 +98,12 @@ Der Build führt den Oracle-Index erneut gegen den neuesten Inhalt aus; der neue **Zertifikat nicht ausgestellt.** Let's Encrypt begrenzt die Anzahl der Ausgaben sehr restriktiv. Überprüfen Sie `docker logs letsencrypt-nginx-proxy-companion`, um den Grund zu ermitteln. -**Oracle antwortet ohne Zitate.** Der Einbettungsindex ist leer. Entweder wurde `nomic-embed-text` nicht auf Ollama gezogen, oder der Build konnte nicht zu neuronetz.ai erreichen. Laden Sie das Modell erneut herunter:```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +**Oracle antwortet ohne Zitate.** Der Einbettungsindex ist leer. Entweder wurde `nomic-embed-text` nicht auf Ollama gezogen, oder der Build konnte nicht zu your Ollama instance erreichen. Laden Sie das Modell erneut herunter:```bash +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' docker compose up -d --build ``` **Oracle gibt "der Oracle konnte nicht antworten".** Überprüfen Sie, ob das Chat-Modell abgerufen wurde:```bash -curl https://api.neuronetz.ai/api/tags | jq '.models[].name' +curl https://your-ollama-host.example/api/tags | jq '.models[].name' ``` **Wollen Sie zu Claude zurückfallen?** Legen Sie `LLM_PROVIDER=anthropic` und `ANTHROPIC_API_KEY` in `.env` fest, dann führen Sie `docker compose up -d` aus. diff --git a/docs/src/content/docs/de/start/local-testing.md b/docs/src/content/docs/de/start/local-testing.md index b439d6b..c8dea61 100644 --- a/docs/src/content/docs/de/start/local-testing.md +++ b/docs/src/content/docs/de/start/local-testing.md @@ -5,13 +5,13 @@ description: "Drei Möglichkeiten, die Dokumentationssite (mit dem Oracle) auf I Die Dokumentationssite – und der Oracle, der sich im Ecke befindet – ist einfach eine Astro-App. Sie können sie auf drei Arten ausführen, abhängig davon, was Ihnen zur Verfügung steht. -## Option A — Astro Entwickler-Server, neuronetz.ai Backend (schnellste) +## Option A — Astro Entwickler-Server, your Ollama instance Backend (schnellste) -Der Oracle ruft Ihre gemeinsame Ollama unter `https://api.neuronetz.ai` auf. Keine lokale GPU erforderlich, keine API-Schlüssel zu verwalten. +Der Oracle ruft Ihre gemeinsame Ollama unter `https://your-ollama-host.example` auf. Keine lokale GPU erforderlich, keine API-Schlüssel zu verwalten. ```bash cd /home/stephan/PhpstormProjects/Nibiru/docs -# .env (copy from .env.example, defaults already point at neuronetz.ai) +# .env (copy from .env.example, defaults already point at your Ollama instance) cp .env.example .env npm install # one-time @@ -21,7 +21,7 @@ npm run dev # http://localhost:4321 **Ziehen Sie das Einbettungsmodell einmal** auf Ihrem Ollama-Host (Build-Zeit + Laufzeit) herunter: ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` Ohne es funktioniert der Oracle trotzdem – er läuft nur im Chat-Modus (ohne RAG) und antwortet auf Basis des modellbasierten Wissens. Mit ihm sind die Antworten an dieser Dokumentation angeordnet. @@ -36,7 +36,7 @@ Der Entwicklungs-Server wird es bei der nächsten Anfrage aufnehmen. Oder übers Der Endpunkt `/api/oracle` des Orakels antwortet auch auf GET mit seiner aktuellen Konfiguration (keine Geheimnisse): ```bash curl http://localhost:4321/api/oracle -# {"status":"ok","llm":{"provider":"ollama","ollamaUrl":"https://api.neuronetz.ai", +# {"status":"ok","llm":{"provider":"ollama","ollamaUrl":"https://your-ollama-host.example", # "model":"qwen2.5-coder:14b"},"embed":{...},"index":{...}} ``` ## Option B — Docker Compose, lokal @@ -111,14 +111,14 @@ Wenn der letzte Aufruf eine echte Antwort zurückgibt, die `./nibiru -m` erwähn **Oracle gibt "der Oracle konnte nicht antworten".** Der Ollama-Server ist nicht erreichbar oder das Chat-Modell wurde nicht abgerufen. Überprüfen Sie:```bash -curl https://api.neuronetz.ai/api/tags | jq '.models[].name' +curl https://your-ollama-host.example/api/tags | jq '.models[].name' ``` **Oracle antwortet ohne Zitate.** Der Einbettungsindex ist leer. Führen Sie nach dem Pullen von `nomic-embed-text` den Befehl `npm run build:oracle` erneut aus. **Ollama gibt 404 model-not-found zurück.** Laden Sie das Modell herunter, z.B.:```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' ``` **`ECONNREFUSED 127.0.0.1:11434`** in Option C. Der lokale Ollama läuft nicht. Starten Sie ihn mit `ollama serve &` (oder über Ihren Systemdienst). diff --git a/docs/src/content/docs/en/ai/module/embed.md b/docs/src/content/docs/en/ai/module/embed.md index 2e06879..4cd4e52 100644 --- a/docs/src/content/docs/en/ai/module/embed.md +++ b/docs/src/content/docs/en/ai/module/embed.md @@ -73,11 +73,11 @@ The RAG plugin uses this format internally for its JSON files. ## Embedding model choices -Pull on neuronetz.ai once: +Pull on your Ollama instance once: ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' # 768 dim, default -curl https://api.neuronetz.ai/api/pull -d '{"name":"mxbai-embed-large"}' # 1024 dim, higher quality +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' # 768 dim, default +curl https://your-ollama-host.example/api/pull -d '{"name":"mxbai-embed-large"}' # 1024 dim, higher quality ``` In `ai.ini`: diff --git a/docs/src/content/docs/en/ai/module/overview.md b/docs/src/content/docs/en/ai/module/overview.md index 8ec6fa7..2bab671 100644 --- a/docs/src/content/docs/en/ai/module/overview.md +++ b/docs/src/content/docs/en/ai/module/overview.md @@ -1,11 +1,11 @@ --- title: The AI module -description: First-class AI in Nibiru — chat, embeddings, RAG, agents — wired to your own Ollama on neuronetz.ai. No paid APIs required. +description: First-class AI in Nibiru — chat, embeddings, RAG, agents — wired to your own Ollama on your Ollama instance. No paid APIs required. --- Nibiru ships an **AI module** (`application/module/ai/`) that gives every Nibiru app a first-class AI surface. PHP code can chat with a local LLM, embed text, run RAG over its own data, or run an agent with tools — all without sending a byte to a paid API. -The module is wired to your own [Ollama on neuronetz.ai](/en/ai/oracle/) by default, so inference is on your hardware, on your network, on your terms. +The module is wired to your own [Ollama on your Ollama instance](/en/ai/oracle/) by default, so inference is on your hardware, on your network, on your terms. ## What you get @@ -37,7 +37,7 @@ Every plugin reads its settings from `application/module/ai/settings/ai.ini`: ```ini [AI] -ollama.base_url = "https://api.neuronetz.ai" +ollama.base_url = "https://your-ollama-host.example" chat.model = "nibiru-coder:1.0" chat.fallback_model = "qwen2.5-coder:14b" chat.temperature = 0.4 diff --git a/docs/src/content/docs/en/ai/module/training.md b/docs/src/content/docs/en/ai/module/training.md index 0fbb7ae..2ab4b9b 100644 --- a/docs/src/content/docs/en/ai/module/training.md +++ b/docs/src/content/docs/en/ai/module/training.md @@ -25,7 +25,7 @@ System-prompt customisation runs **instantly** — no GPU training, no dataset p The script: 1. Reads the Modelfile next to it. -2. POSTs to `${OLLAMA_BASE_URL}/api/create` (default `https://api.neuronetz.ai`). +2. POSTs to `${OLLAMA_BASE_URL}/api/create` (default `https://your-ollama-host.example`). 3. Runs a smoke-test chat call to confirm the new tag responds. After it succeeds, set the model in `application/module/ai/settings/ai.ini`: diff --git a/docs/src/content/docs/en/ai/oracle.md b/docs/src/content/docs/en/ai/oracle.md index 0d7b00a..eccbe4d 100644 --- a/docs/src/content/docs/en/ai/oracle.md +++ b/docs/src/content/docs/en/ai/oracle.md @@ -1,6 +1,6 @@ --- title: Ask the Oracle -description: How the in-site AI assistant works — RAG over the docs, served by your own Ollama on neuronetz.ai. +description: How the in-site AI assistant works — RAG over the docs, served by your own Ollama on your Ollama instance. --- The amber button in the corner of every page is the **Nibiru Oracle** — an AI assistant grounded in this very documentation. Ask it about routing, modules, the CLI, the Smarty layer, the meaning of `pageAction()`. It cites its sources. @@ -11,8 +11,8 @@ By default, the Oracle runs entirely on **your own infrastructure**: | Layer | Backend | Default model | |---|---|---| -| Chat (answer generation) | Ollama on `https://api.neuronetz.ai` | `qwen2.5-coder:14b` | -| Embeddings (RAG retrieval) | Ollama on `https://api.neuronetz.ai` | `nomic-embed-text` | +| Chat (answer generation) | Ollama on `https://your-ollama-host.example` | `qwen2.5-coder:14b` | +| Embeddings (RAG retrieval) | Ollama on `https://your-ollama-host.example` | `nomic-embed-text` | No paid API keys. No data leaves your network. The 5-GPU Ollama cluster you already run handles the load. @@ -44,13 +44,13 @@ flowchart LR | `src/pages/api/oracle.ts` | The SSR endpoint the chat widget POSTs to. Also serves a GET for diagnostics. | | `src/components/CosmicHeader.astro` | The floating launcher + chat UI. | -## One-time setup on neuronetz.ai +## One-time setup on your Ollama instance Pull the two models the Oracle uses: ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` `qwen2.5-coder:14b` is already installed (verified live). `nomic-embed-text` is the missing piece; without it the Oracle runs in chat-only (no-RAG) mode. @@ -60,9 +60,9 @@ curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' The Oracle reads its config from environment variables. Sensible defaults are baked in. ```bash -# Default mode (Ollama on neuronetz.ai) +# Default mode (Ollama on your Ollama instance) LLM_PROVIDER=ollama # default -OLLAMA_BASE_URL=https://api.neuronetz.ai # default +OLLAMA_BASE_URL=https://your-ollama-host.example # default OLLAMA_CHAT_MODEL=qwen2.5-coder:14b # default OLLAMA_EMBED_MODEL=nomic-embed-text # default @@ -88,9 +88,9 @@ ORACLE_MAX_TOKENS=800 curl https://nibiru-framework.com/api/oracle { "status": "ok", - "llm": { "provider": "ollama", "ollamaUrl": "https://api.neuronetz.ai", + "llm": { "provider": "ollama", "ollamaUrl": "https://your-ollama-host.example", "model": "qwen2.5-coder:14b" }, - "embed": { "provider": "ollama", "ollamaUrl": "https://api.neuronetz.ai", + "embed": { "provider": "ollama", "ollamaUrl": "https://your-ollama-host.example", "model": "nomic-embed-text" }, "index": { "present": true, "chunks": 177, "provider": "ollama", "model": "nomic-embed-text" } diff --git a/docs/src/content/docs/en/downloads.mdx b/docs/src/content/docs/en/downloads.mdx new file mode 100644 index 0000000..9d8d96c --- /dev/null +++ b/docs/src/content/docs/en/downloads.mdx @@ -0,0 +1,48 @@ +--- +title: LoRA training corpus +description: Downloadable Nibiru framework training corpus — chunks, instructions, chat, completion. Per-language and combined buckets, JSONL. +--- + +import DownloadsManifest from '../../../components/DownloadsManifest.astro'; + +A pre-built training corpus for fine-tuning your own LoRA on Nibiru. Generated +deterministically from two sources: the deep [framework reference](/en/reference/) +(every public factory, namespace, idiom and gotcha cited file:line) and the +public docs in five languages. + +Each format is offered per-language plus a combined `*-all.jsonl`. Pick a +language bucket if you're training a mono-lingual LoRA (recommended); pick +`ALL` if you want the model to handle queries in any language. + + + +## Which format? + +- **`instructions.jsonl`** — start here for most LoRA training. Alpaca-style + instruction / input / output triples; works with [axolotl](https://github.com/OpenAccess-AI-Collective/axolotl), + [llama-factory](https://github.com/hiyouga/LLaMA-Factory), [unsloth](https://github.com/unslothai/unsloth). +- **`chat.jsonl`** — ShareGPT/messages format with a system prompt. Best for + chat-LoRAs and OpenAI-compatible fine-tune APIs. +- **`completion.jsonl`** — legacy prompt/completion pairs. Use for old-style + text-completion fine-tunes. +- **`chunks.jsonl`** — one record per source chunk, no Q/A wrapping. + Good as a RAG corpus or for custom Q/A generation pipelines. + +## Provenance + +The corpus is rebuilt fresh every time the docs deploy: + +```sh +node scripts/build-corpus.mjs +``` + +Source: [`scripts/build-corpus.mjs`](https://github.com/alllinux/Nibiru/blob/master/docs/scripts/build-corpus.mjs). +SHA-256 hashes are in [`/corpus/manifest.json`](/corpus/manifest.json) — verify +before you train if reproducibility matters. + +## License + +The framework reference and public docs are licensed the same as Nibiru itself +(MIT). Trained model weights are yours. If you publish a LoRA fine-tuned on +this corpus, a "trained on the Nibiru training corpus" attribution is +appreciated but not required. diff --git a/docs/src/content/docs/en/start/deployment.md b/docs/src/content/docs/en/start/deployment.md index add4fb2..aa7aae9 100644 --- a/docs/src/content/docs/en/start/deployment.md +++ b/docs/src/content/docs/en/start/deployment.md @@ -1,9 +1,9 @@ --- title: Deploying the Docs Site -description: Production deployment of nibiru-framework.com using jwilder/nginx-proxy and your own Ollama on neuronetz.ai. +description: Production deployment of nibiru-framework.com using jwilder/nginx-proxy and your own Ollama on your Ollama instance. --- -This page documents how the docs site is deployed in production. The setup uses **jwilder/nginx-proxy** for automatic Docker container routing, **letsencrypt-nginx-proxy-companion** for HTTPS, and **your own Ollama at api.neuronetz.ai** for the Oracle backend — no paid LLM API keys required. +This page documents how the docs site is deployed in production. The setup uses **jwilder/nginx-proxy** for automatic Docker container routing, **letsencrypt-nginx-proxy-companion** for HTTPS, and **your own Ollama at your-ollama-host.example** for the Oracle backend — no paid LLM API keys required. ## Topology @@ -18,7 +18,7 @@ This page documents how the docs site is deployed in production. The setup uses │ http://nibiru-docs:4321 ▼ ┌──────────────────────┐ ┌──────────────────────┐ - │ nibiru-docs │ ──────▶ │ api.neuronetz.ai │ + │ nibiru-docs │ ──────▶ │ your-ollama-host.example │ │ Astro Node SSR :4321 │ HTTPS │ Ollama (5× GPU) │ │ Oracle endpoint │ │ qwen2.5-coder:14b │ └──────────────────────┘ │ nomic-embed-text │ @@ -34,20 +34,20 @@ docker network create nginx-proxy # 2) Run nginx-proxy + acme-companion (one time) # See https://github.com/nginx-proxy/nginx-proxy for the canonical compose. -# 3) Pull the Oracle's models on neuronetz.ai (one time) -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +# 3) Pull the Oracle's models on your Ollama instance (one time) +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` ## Files in `docs/` | File | Purpose | |---|---| -| `Dockerfile` | Multi-stage build: builds Oracle index against neuronetz.ai, builds Astro, prunes dev deps. | +| `Dockerfile` | Multi-stage build: builds Oracle index against your Ollama instance, builds Astro, prunes dev deps. | | `docker-compose.yml` | Production — `VIRTUAL_HOST=nibiru-framework.com`, joined to `nginx-proxy` network. | | `docker-compose.local.yml` | Local-test override — exposes `4321:4321`, drops nginx-proxy env vars. | | `.dockerignore` | Keeps `node_modules`, `.git`, etc. out of the build context. | -| `.env.example` | Template — defaults to Ollama on neuronetz.ai, no API keys required. | +| `.env.example` | Template — defaults to Ollama on your Ollama instance, no API keys required. | ## Bring it up @@ -91,7 +91,7 @@ The build re-runs the Oracle index against the freshest content; the new contain | Var | Default | Used at | Purpose | |---|---|---|---| | `LLM_PROVIDER` | `ollama` | runtime | `ollama` (default) or `anthropic`. | -| `OLLAMA_BASE_URL` | `https://api.neuronetz.ai` | build + runtime | Where to reach Ollama. | +| `OLLAMA_BASE_URL` | `https://your-ollama-host.example` | build + runtime | Where to reach Ollama. | | `OLLAMA_CHAT_MODEL` | `qwen2.5-coder:14b` | runtime | Chat-completion model. | | `OLLAMA_EMBED_MODEL` | `nomic-embed-text` | build + runtime | Embedding model. | | `EMBED_PROVIDER` | `ollama` | build + runtime | `ollama` or `openai`. | @@ -112,15 +112,15 @@ The build re-runs the Oracle index against the freshest content; the new contain **Oracle answers without citations.** The embedding index is empty. Either `nomic-embed-text` isn't pulled on Ollama, or the build couldn't reach -neuronetz.ai. Re-pull the model: +your Ollama instance. Re-pull the model: ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' docker compose up -d --build ``` **Oracle returns "the Oracle could not answer".** Check the chat model is pulled: ```bash -curl https://api.neuronetz.ai/api/tags | jq '.models[].name' +curl https://your-ollama-host.example/api/tags | jq '.models[].name' ``` **Want to fall back to Claude.** Set `LLM_PROVIDER=anthropic` and `ANTHROPIC_API_KEY` in `.env`, then `docker compose up -d`. diff --git a/docs/src/content/docs/en/start/local-testing.md b/docs/src/content/docs/en/start/local-testing.md index c1e12a7..9938bd8 100644 --- a/docs/src/content/docs/en/start/local-testing.md +++ b/docs/src/content/docs/en/start/local-testing.md @@ -5,14 +5,14 @@ description: Three ways to spin up the docs site (with the Oracle) on your own m The docs site — and the Oracle that lives in the corner — is just an Astro app. You can run it three ways depending on what you have at hand. -## Option A — Astro dev server, neuronetz.ai backend (fastest) +## Option A — Astro dev server, Ollama backend (fastest) -The Oracle calls your shared Ollama at `https://api.neuronetz.ai`. No local GPU needed, no API keys to manage. +The Oracle calls your shared Ollama at `https://your-ollama-host.example`. No local GPU needed, no API keys to manage. ```bash cd /home/stephan/PhpstormProjects/Nibiru/docs -# .env (copy from .env.example, defaults already point at neuronetz.ai) +# .env (copy from .env.example, defaults already point at your Ollama instance) cp .env.example .env npm install # one-time @@ -24,7 +24,7 @@ Open . Click the amber Oracle launcher in the bottom-rig **Pull the embedding model once** on your Ollama host (build-time + runtime): ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` Without it, the Oracle still works — it just runs in chat-only (no-RAG) mode and answers from the model's parametric knowledge. With it, answers are grounded in this documentation. @@ -43,7 +43,7 @@ The Oracle's `/api/oracle` endpoint also responds to GET with its current config ```bash curl http://localhost:4321/api/oracle -# {"status":"ok","llm":{"provider":"ollama","ollamaUrl":"https://api.neuronetz.ai", +# {"status":"ok","llm":{"provider":"ollama","ollamaUrl":"https://your-ollama-host.example", # "model":"qwen2.5-coder:14b"},"embed":{...},"index":{...}} ``` @@ -128,7 +128,7 @@ If the last call returns a real answer that mentions `./nibiru -m`, your stack i **Oracle returns "the Oracle could not answer".** The Ollama server is unreachable or the chat model isn't pulled. Verify: ```bash -curl https://api.neuronetz.ai/api/tags | jq '.models[].name' +curl https://your-ollama-host.example/api/tags | jq '.models[].name' ``` **Oracle answers without citations.** @@ -137,7 +137,7 @@ The embedding index is empty. Re-run `npm run build:oracle` after pulling `nomic **Ollama returns 404 model-not-found.** Pull the model, e.g.: ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' ``` **`ECONNREFUSED 127.0.0.1:11434`** in option C. diff --git a/docs/src/content/docs/es/ai/module/embed.md b/docs/src/content/docs/es/ai/module/embed.md index ce0927f..a8f9130 100644 --- a/docs/src/content/docs/es/ai/module/embed.md +++ b/docs/src/content/docs/es/ai/module/embed.md @@ -65,10 +65,10 @@ El complemento RAG utiliza este formato internamente para sus archivos JSON. ## Elecciones de modelos de incrustación -Ejecute una extracción en neuronetz.ai una vez: +Ejecute una extracción en su Ollama.ai una vez: ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' # 768 dim, default -curl https://api.neuronetz.ai/api/pull -d '{"name":"mxbai-embed-large"}' # 1024 dim, higher quality +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' # 768 dim, default +curl https://your-ollama-host.example/api/pull -d '{"name":"mxbai-embed-large"}' # 1024 dim, higher quality ``` En `ai.ini`: ```ini diff --git a/docs/src/content/docs/es/ai/module/overview.md b/docs/src/content/docs/es/ai/module/overview.md index 9a9500f..973e592 100644 --- a/docs/src/content/docs/es/ai/module/overview.md +++ b/docs/src/content/docs/es/ai/module/overview.md @@ -1,11 +1,11 @@ --- title: "El módulo de IA" -description: "Primera clase de IA en Nibiru — chat, embeddings, RAG, agentes — conectados a tu propio Ollama en neuronetz.ai. No se requieren APIs pagas." +description: "Primera clase de IA en Nibiru — chat, embeddings, RAG, agentes — conectados a tu propio Ollama en su Ollama. No se requieren APIs pagas." --- Nibiru incluye un **módulo de IA** (`application/module/ai/`) que da a cada aplicación Nibiru una interfaz de IA de primera clase. El código PHP puede chatear con un LLM local, incrustar texto, ejecutar RAG sobre sus propios datos o ejecutar un agente con herramientas — todo sin enviar un solo byte a una API pagada. -El módulo está conectado a su propio [Ollama en neuronetz.ai](/es/ai/oracle/) por defecto, por lo que la inferencia se realiza en su hardware, en su red y bajo sus términos. +El módulo está conectado a su propio [Ollama en su Ollama](/es/ai/oracle/) por defecto, por lo que la inferencia se realiza en su hardware, en su red y bajo sus términos. ## Lo que obtienes @@ -34,7 +34,7 @@ Esa es toda la superficie de la API para el caso simple. Sin contenedor de inyec Cada complemento lee sus configuraciones desde `application/module/ai/settings/ai.ini`: ```ini [AI] -ollama.base_url = "https://api.neuronetz.ai" +ollama.base_url = "https://your-ollama-host.example" chat.model = "nibiru-coder:1.0" chat.fallback_model = "qwen2.5-coder:14b" chat.temperature = 0.4 diff --git a/docs/src/content/docs/es/ai/module/training.md b/docs/src/content/docs/es/ai/module/training.md index ae15849..c58ca09 100644 --- a/docs/src/content/docs/es/ai/module/training.md +++ b/docs/src/content/docs/es/ai/module/training.md @@ -23,7 +23,7 @@ La personalización del sistema se ejecuta **instantáneamente** — sin entrena El guion: 1. Lee el archivo Modelfile que está al lado. -2. Realiza una solicitud POST a `${OLLAMA_BASE_URL}/api/create` (por defecto `https://api.neuronetz.ai`). +2. Realiza una solicitud POST a `${OLLAMA_BASE_URL}/api/create` (por defecto `https://your-ollama-host.example`). 3. Ejecuta una prueba de humo para la llamada de chat para confirmar que la nueva etiqueta responde. Después de que se complete con éxito, establezca el modelo en `application/module/ai/settings/ai.ini`: diff --git a/docs/src/content/docs/es/ai/oracle.md b/docs/src/content/docs/es/ai/oracle.md index 1524b50..fe55352 100644 --- a/docs/src/content/docs/es/ai/oracle.md +++ b/docs/src/content/docs/es/ai/oracle.md @@ -1,6 +1,6 @@ --- title: "Pregunta al Oráculo" -description: "Cómo funciona el asistente de IA en el sitio — RAG sobre los documentos, servido por tu propio Ollama en neuronetz.ai." +description: "Cómo funciona el asistente de IA en el sitio — RAG sobre los documentos, servido por tu propio Ollama en su Ollama." --- El botón amarillo en la esquina de cada página es el **Oráculo Nibiru** — un asistente de IA respaldado por esta documentación misma. Pregúntale sobre el enrutamiento, los módulos, la CLI, la capa Smarty, el significado de `pageAction()`. Cita sus fuentes. @@ -11,8 +11,8 @@ Por defecto, el Oracle se ejecuta completamente en **su propia infraestructura** | Capa | Backend | Modelo predeterminado | |---|---|---| -| Chat (generación de respuestas) | Ollama en `https://api.neuronetz.ai` | `qwen2.5-coder:14b` | -| Embeddings (recuperación RAG) | Ollama en `https://api.neuronetz.ai` | `nomic-embed-text` | +| Chat (generación de respuestas) | Ollama en `https://your-ollama-host.example` | `qwen2.5-coder:14b` | +| Embeddings (recuperación RAG) | Ollama en `https://your-ollama-host.example` | `nomic-embed-text` | No se utilizan claves de API pagas. Ningún dato sale de su red. El clúster de 5 GPU de Ollama que ya ejecuta maneja la carga. @@ -42,12 +42,12 @@ flowchart LR | `src/pages/api/oracle.ts` | El punto final SSR al que el widget de chat POSTea. También sirve un GET para diagnósticos. | | `src/components/CosmicHeader.astro` | El lanzador flotante + interfaz de usuario de chat. | -## Configuración única en neuronetz.ai +## Configuración única en su Ollama.ai Extraiga los dos modelos que usa Oracle: ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` `qwen2.5-coder:14b` ya está instalado (verificado en vivo). `nomic-embed-text` es la pieza faltante; sin ella, el Oracle funciona solo en modo de chat (sin RAG). @@ -55,9 +55,9 @@ curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' El Oracle lee su configuración desde las variables de entorno. Se incluyen valores predeterminados sensibles. ```bash -# Default mode (Ollama on neuronetz.ai) +# Default mode (Ollama on your Ollama instance) LLM_PROVIDER=ollama # default -OLLAMA_BASE_URL=https://api.neuronetz.ai # default +OLLAMA_BASE_URL=https://your-ollama-host.example # default OLLAMA_CHAT_MODEL=qwen2.5-coder:14b # default OLLAMA_EMBED_MODEL=nomic-embed-text # default @@ -81,9 +81,9 @@ ORACLE_MAX_TOKENS=800 curl https://nibiru-framework.com/api/oracle { "status": "ok", - "llm": { "provider": "ollama", "ollamaUrl": "https://api.neuronetz.ai", + "llm": { "provider": "ollama", "ollamaUrl": "https://your-ollama-host.example", "model": "qwen2.5-coder:14b" }, - "embed": { "provider": "ollama", "ollamaUrl": "https://api.neuronetz.ai", + "embed": { "provider": "ollama", "ollamaUrl": "https://your-ollama-host.example", "model": "nomic-embed-text" }, "index": { "present": true, "chunks": 177, "provider": "ollama", "model": "nomic-embed-text" } diff --git a/docs/src/content/docs/es/start/deployment.md b/docs/src/content/docs/es/start/deployment.md index 6bc0cba..18bada6 100644 --- a/docs/src/content/docs/es/start/deployment.md +++ b/docs/src/content/docs/es/start/deployment.md @@ -1,9 +1,9 @@ --- title: "Desplegando el Sitio de Documentación" -description: "Despliegue de producción de nibiru-framework.com utilizando jwilder/nginx-proxy y tu propio Ollama en neuronetz.ai." +description: "Despliegue de producción de nibiru-framework.com utilizando jwilder/nginx-proxy y tu propio Ollama en su Ollama." --- -Esta página documenta cómo se despliega el sitio de documentación en producción. La configuración utiliza **jwilder/nginx-proxy** para el enrutamiento automático de contenedores Docker, **letsencrypt-nginx-proxy-companion** para HTTPS y **tu propio Ollama en api.neuronetz.ai** para el backend de Oracle — no se requieren claves API de LLM pagadas. +Esta página documenta cómo se despliega el sitio de documentación en producción. La configuración utiliza **jwilder/nginx-proxy** para el enrutamiento automático de contenedores Docker, **letsencrypt-nginx-proxy-companion** para HTTPS y **tu propio Ollama en your-ollama-host.example** para el backend de Oracle — no se requieren claves API de LLM pagadas. ## Topología ``` @@ -17,7 +17,7 @@ Esta página documenta cómo se despliega el sitio de documentación en producci │ http://nibiru-docs:4321 ▼ ┌──────────────────────┐ ┌──────────────────────┐ - │ nibiru-docs │ ──────▶ │ api.neuronetz.ai │ + │ nibiru-docs │ ──────▶ │ your-ollama-host.example │ │ Astro Node SSR :4321 │ HTTPS │ Ollama (5× GPU) │ │ Oracle endpoint │ │ qwen2.5-coder:14b │ └──────────────────────┘ │ nomic-embed-text │ @@ -31,19 +31,19 @@ docker network create nginx-proxy # 2) Run nginx-proxy + acme-companion (one time) # See https://github.com/nginx-proxy/nginx-proxy for the canonical compose. -# 3) Pull the Oracle's models on neuronetz.ai (one time) -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +# 3) Pull the Oracle's models on your Ollama instance (one time) +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` ## Archivos en `docs/` | Archivo | Propósito | |---|---| -| `Dockerfile` | Construcción multi-etapa: construye índice Oracle contra neuronetz.ai, construye Astro, elimina dependencias de desarrollo. | +| `Dockerfile` | Construcción multi-etapa: construye índice Oracle contra your Ollama instance, construye Astro, elimina dependencias de desarrollo. | | `docker-compose.yml` | Producción — `VIRTUAL_HOST=nibiru-framework.com`, unido a la red `nginx-proxy`. | | `docker-compose.local.yml` | Anulación de prueba local — expone `4321:4321`, elimina variables de entorno de nginx-proxy. | | `.dockerignore` | Mantiene `node_modules`, `.git`, etc. fuera del contexto de la construcción. | -| `.env.example` | Plantilla — predeterminado a Ollama en neuronetz.ai, no se requieren claves API. | +| `.env.example` | Plantilla — predeterminado a Ollama en su Ollama, no se requieren claves API. | ## Levántalo ```bash @@ -81,7 +81,7 @@ La compilación vuelve a ejecutar el índice de Oracle contra el contenido más | Var | Default | Usado en | Propósito | |---|---|---|---| | `LLM_PROVIDER` | `ollama` | tiempo de ejecución | `ollama` (predeterminado) o `anthropic`. | -| `OLLAMA_BASE_URL` | `https://api.neuronetz.ai` | construcción + tiempo de ejecución | Dónde alcanzar a Ollama. | +| `OLLAMA_BASE_URL` | `https://your-ollama-host.example` | construcción + tiempo de ejecución | Dónde alcanzar a Ollama. | | `OLLAMA_CHAT_MODEL` | `qwen2.5-coder:14b` | tiempo de ejecución | Modelo de completación de chat. | | `OLLAMA_EMBED_MODEL` | `nomic-embed-text` | construcción + tiempo de ejecución | Modelo de incrustación. | | `EMBED_PROVIDER` | `ollama` | construcción + tiempo de ejecución | `ollama` o `openai`. | @@ -98,12 +98,12 @@ La compilación vuelve a ejecutar el índice de Oracle contra el contenido más **Cert no emitido.** Let's Encrypt limita agresivamente las solicitudes. Verifica los registros de `docker logs letsencrypt-nginx-proxy-companion` para determinar la causa. -**Oracle responde sin citas.** El índice de incrustación está vacío. Ya sea que `nomic-embed-text` no se haya extraído en Ollama, o el build no pudo alcanzar neuronetz.ai. Vuelva a extraer el modelo:```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +**Oracle responde sin citas.** El índice de incrustación está vacío. Ya sea que `nomic-embed-text` no se haya extraído en Ollama, o el build no pudo alcanzar your Ollama instance. Vuelva a extraer el modelo:```bash +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' docker compose up -d --build ``` **Oracle devuelve "el Oracle no pudo responder".** Verifica que el modelo de chat esté cargado:```bash -curl https://api.neuronetz.ai/api/tags | jq '.models[].name' +curl https://your-ollama-host.example/api/tags | jq '.models[].name' ``` **Quieres caer en Claude.** Establece `LLM_PROVIDER=anthropic` y `ANTHROPIC_API_KEY` en `.env`, luego ejecuta `docker compose up -d`. diff --git a/docs/src/content/docs/es/start/local-testing.md b/docs/src/content/docs/es/start/local-testing.md index 49d78d0..f1a26bd 100644 --- a/docs/src/content/docs/es/start/local-testing.md +++ b/docs/src/content/docs/es/start/local-testing.md @@ -5,13 +5,13 @@ description: "Tres formas de iniciar el sitio de documentación (con Oracle) en El sitio de documentación — y el Oracle que vive en la esquina — es simplemente una aplicación de Astro. Puedes ejecutarlo de tres formas dependiendo de lo que tengas a mano. -## Opción A — Servidor de desarrollo Astro, backend neuronetz.ai (más rápido) +## Opción A — Servidor de desarrollo Astro, backend your Ollama instance (más rápido) -El Oracle llama a tu Ollama compartida en `https://api.neuronetz.ai`. No se necesita un GPU local ni claves de API para gestionar. +El Oracle llama a tu Ollama compartida en `https://your-ollama-host.example`. No se necesita un GPU local ni claves de API para gestionar. ```bash cd /home/stephan/PhpstormProjects/Nibiru/docs -# .env (copy from .env.example, defaults already point at neuronetz.ai) +# .env (copy from .env.example, defaults already point at your Ollama instance) cp .env.example .env npm install # one-time @@ -21,7 +21,7 @@ Abre . Haz clic en el lanzador amarillo de Oracle en la **Extraiga el modelo de incrustación una vez** en su host Ollama (en tiempo de construcción + en tiempo de ejecución): ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` Sin él, el Oracle sigue funcionando — solo que en modo de chat solamente (sin RAG) y responde basándose en el conocimiento paramétrico del modelo. Con él, las respuestas están respaldadas por esta documentación. @@ -36,7 +36,7 @@ El servidor de desarrollo lo detectará en la próxima solicitud. O omite este p El punto final `/api/oracle` del Oracle también responde a GET con su configuración actual (sin secretos): ```bash curl http://localhost:4321/api/oracle -# {"status":"ok","llm":{"provider":"ollama","ollamaUrl":"https://api.neuronetz.ai", +# {"status":"ok","llm":{"provider":"ollama","ollamaUrl":"https://your-ollama-host.example", # "model":"qwen2.5-coder:14b"},"embed":{...},"index":{...}} ``` ## Opción B — Docker Compose, localmente @@ -111,14 +111,14 @@ Si la última llamada devuelve una respuesta real que menciona `./nibiru -m`, tu **Oracle devuelve "el Oracle no pudo responder".** El servidor de Ollama no es accesible o el modelo de chat no está extraído. Verifique:```bash -curl https://api.neuronetz.ai/api/tags | jq '.models[].name' +curl https://your-ollama-host.example/api/tags | jq '.models[].name' ``` **Oracle responde sin citas.** El índice de incrustación está vacío. Vuelve a ejecutar `npm run build:oracle` después de extraer `nomic-embed-text`. **Ollama devuelve 404 modelo-no-encontrado.** Extrae el modelo, por ejemplo:```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' ``` **`ECONNREFUSED 127.0.0.1:11434`** en la opción C. El Ollama local no está ejecutándose. Inícielo con `ollama serve &` (o a través de su servicio del sistema). diff --git a/docs/src/content/docs/fr/ai/module/embed.md b/docs/src/content/docs/fr/ai/module/embed.md index c96d5ca..3c78ed8 100644 --- a/docs/src/content/docs/fr/ai/module/embed.md +++ b/docs/src/content/docs/fr/ai/module/embed.md @@ -65,10 +65,10 @@ Le plugin RAG utilise ce format internalement pour ses fichiers JSON. ## Choix des modèles d'incrustation -Tirez sur neuronetz.ai une fois : +Tirez sur votre Ollama.ai une fois : ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' # 768 dim, default -curl https://api.neuronetz.ai/api/pull -d '{"name":"mxbai-embed-large"}' # 1024 dim, higher quality +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' # 768 dim, default +curl https://your-ollama-host.example/api/pull -d '{"name":"mxbai-embed-large"}' # 1024 dim, higher quality ``` Dans `ai.ini`: ```ini diff --git a/docs/src/content/docs/fr/ai/module/overview.md b/docs/src/content/docs/fr/ai/module/overview.md index 9fb5152..3147252 100644 --- a/docs/src/content/docs/fr/ai/module/overview.md +++ b/docs/src/content/docs/fr/ai/module/overview.md @@ -1,11 +1,11 @@ --- title: "Le module IA" -description: "Première classe d'IA dans Nibiru — conversation, embeddings, RAG, agents — connectés à votre propre Ollama sur neuronetz.ai. Aucune API payante requise." +description: "Première classe d'IA dans Nibiru — conversation, embeddings, RAG, agents — connectés à votre propre Ollama sur votre Ollama. Aucune API payante requise." --- Nibiru embarque un **module IA** (`application/module/ai/`) qui donne à chaque application Nibiru une interface IA de première classe. Le code PHP peut dialoguer avec un LLM local, émbarquer du texte, exécuter RAG sur ses propres données ou exécuter un agent avec des outils — tout cela sans envoyer un seul octet à une API payante. -Le module est connecté par défaut à votre propre [Ollama sur neuronetz.ai](/en/ai/oracle/), donc l'inférence se fait sur votre matériel, sur votre réseau, selon vos termes. +Le module est connecté par défaut à votre propre [Ollama sur votre Ollama](/en/ai/oracle/), donc l'inférence se fait sur votre matériel, sur votre réseau, selon vos termes. ## Ce que vous obtenez @@ -34,7 +34,7 @@ Voici toute la surface d'API pour le cas simple. Aucun conteneur DI, aucune clé Chaque plugin lit ses paramètres depuis `application/module/ai/settings/ai.ini`: ```ini [AI] -ollama.base_url = "https://api.neuronetz.ai" +ollama.base_url = "https://your-ollama-host.example" chat.model = "nibiru-coder:1.0" chat.fallback_model = "qwen2.5-coder:14b" chat.temperature = 0.4 diff --git a/docs/src/content/docs/fr/ai/module/training.md b/docs/src/content/docs/fr/ai/module/training.md index a01f8ed..595629b 100644 --- a/docs/src/content/docs/fr/ai/module/training.md +++ b/docs/src/content/docs/fr/ai/module/training.md @@ -23,7 +23,7 @@ La personnalisation du système-prompt se fait **instantanément** — pas d'ent Le script : 1. Lit le fichier Modelfile situé à côté de lui. -2. Envoie une requête POST à `${OLLAMA_BASE_URL}/api/create` (par défaut `https://api.neuronetz.ai`). +2. Envoie une requête POST à `${OLLAMA_BASE_URL}/api/create` (par défaut `https://your-ollama-host.example`). 3. Exécute un test fumeur de conversation pour confirmer que le nouveau tag répond. Après son succès, définissez le modèle dans `application/module/ai/settings/ai.ini` : diff --git a/docs/src/content/docs/fr/ai/oracle.md b/docs/src/content/docs/fr/ai/oracle.md index 87839d4..777230f 100644 --- a/docs/src/content/docs/fr/ai/oracle.md +++ b/docs/src/content/docs/fr/ai/oracle.md @@ -1,6 +1,6 @@ --- title: "Demandez à l'Oracle" -description: "Comment fonctionne l'assistant IA intégré au site — RAG sur les documents, servi par votre propre Ollama sur neuronetz.ai." +description: "Comment fonctionne l'assistant IA intégré au site — RAG sur les documents, servi par votre propre Ollama sur votre Ollama." --- Le bouton jaune dans le coin de chaque page est l'**Oracle Nibiru** — un assistant IA basé sur cette documentation même. Posez-lui des questions sur le routage, les modules, la CLI, la couche Smarty, le sens de `pageAction()`. Il cite ses sources. @@ -11,8 +11,8 @@ Par défaut, l'Oracle fonctionne entièrement sur **votre propre infrastructure* | Calque | Backend | Modèle par défaut | |---|---|---| -| Chat (génération de réponse) | Ollama sur `https://api.neuronetz.ai` | `qwen2.5-coder:14b` | -| Embeddings (retrieval RAG) | Ollama sur `https://api.neuronetz.ai` | `nomic-embed-text` | +| Chat (génération de réponse) | Ollama sur `https://your-ollama-host.example` | `qwen2.5-coder:14b` | +| Embeddings (retrieval RAG) | Ollama sur `https://your-ollama-host.example` | `nomic-embed-text` | Aucune clé d'API payante. Aucune donnée ne quitte votre réseau. Le cluster Ollama à 5 GPU que vous exécutez déjà gère la charge. @@ -42,12 +42,12 @@ flowchart LR | `src/pages/api/oracle.ts` | Le point final SSR auquel le widget de conversation POSTe. Il sert également une requête GET pour les diagnostics. | | `src/components/CosmicHeader.astro` | Le lanceur flottant + l'interface utilisateur de conversation. | -## Configuration unique sur neuronetz.ai +## Configuration unique sur votre Ollama.ai Extrayez les deux modèles que l'Oracle utilise : ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` `qwen2.5-coder:14b` est déjà installé (vérifié en direct). `nomic-embed-text` est la pièce manquante ; sans elle, l'Oracle fonctionne en mode conversationnel uniquement (sans RAG). @@ -55,9 +55,9 @@ curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' L'Oracle lit sa configuration à partir des variables d'environnement. Des valeurs par défaut sensibles sont intégrées. ```bash -# Default mode (Ollama on neuronetz.ai) +# Default mode (Ollama on your Ollama instance) LLM_PROVIDER=ollama # default -OLLAMA_BASE_URL=https://api.neuronetz.ai # default +OLLAMA_BASE_URL=https://your-ollama-host.example # default OLLAMA_CHAT_MODEL=qwen2.5-coder:14b # default OLLAMA_EMBED_MODEL=nomic-embed-text # default @@ -81,9 +81,9 @@ ORACLE_MAX_TOKENS=800 curl https://nibiru-framework.com/api/oracle { "status": "ok", - "llm": { "provider": "ollama", "ollamaUrl": "https://api.neuronetz.ai", + "llm": { "provider": "ollama", "ollamaUrl": "https://your-ollama-host.example", "model": "qwen2.5-coder:14b" }, - "embed": { "provider": "ollama", "ollamaUrl": "https://api.neuronetz.ai", + "embed": { "provider": "ollama", "ollamaUrl": "https://your-ollama-host.example", "model": "nomic-embed-text" }, "index": { "present": true, "chunks": 177, "provider": "ollama", "model": "nomic-embed-text" } diff --git a/docs/src/content/docs/fr/start/deployment.md b/docs/src/content/docs/fr/start/deployment.md index b74131e..8657fe6 100644 --- a/docs/src/content/docs/fr/start/deployment.md +++ b/docs/src/content/docs/fr/start/deployment.md @@ -1,9 +1,9 @@ --- title: "Déploiement du site de documentation" -description: "Déploiement de production de nibiru-framework.com en utilisant jwilder/nginx-proxy et votre propre Ollama sur neuronetz.ai." +description: "Déploiement de production de nibiru-framework.com en utilisant jwilder/nginx-proxy et votre propre Ollama sur votre Ollama." --- -Cette page documente comment le site de documentation est déployé en production. La configuration utilise **jwilder/nginx-proxy** pour le routage automatique des conteneurs Docker, **letsencrypt-nginx-proxy-companion** pour HTTPS et **votre propre Ollama à api.neuronetz.ai** pour le backend Oracle — aucune clé API LLM payante n'est requise. +Cette page documente comment le site de documentation est déployé en production. La configuration utilise **jwilder/nginx-proxy** pour le routage automatique des conteneurs Docker, **letsencrypt-nginx-proxy-companion** pour HTTPS et **votre propre Ollama à your-ollama-host.example** pour le backend Oracle — aucune clé API LLM payante n'est requise. ## Topologie ``` @@ -17,7 +17,7 @@ Cette page documente comment le site de documentation est déployé en productio │ http://nibiru-docs:4321 ▼ ┌──────────────────────┐ ┌──────────────────────┐ - │ nibiru-docs │ ──────▶ │ api.neuronetz.ai │ + │ nibiru-docs │ ──────▶ │ your-ollama-host.example │ │ Astro Node SSR :4321 │ HTTPS │ Ollama (5× GPU) │ │ Oracle endpoint │ │ qwen2.5-coder:14b │ └──────────────────────┘ │ nomic-embed-text │ @@ -31,19 +31,19 @@ docker network create nginx-proxy # 2) Run nginx-proxy + acme-companion (one time) # See https://github.com/nginx-proxy/nginx-proxy for the canonical compose. -# 3) Pull the Oracle's models on neuronetz.ai (one time) -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +# 3) Pull the Oracle's models on your Ollama instance (one time) +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` ## Fichiers dans `docs/` | Fichier | Objectif | |---|---| -| `Dockerfile` | Construction multi-stages : construit l'index Oracle contre neuronetz.ai, construit Astro, élimine les dépendances de développement. | +| `Dockerfile` | Construction multi-stages : construit l'index Oracle contre your Ollama instance, construit Astro, élimine les dépendances de développement. | | `docker-compose.yml` | Production — `VIRTUAL_HOST=nibiru-framework.com`, joint à réseau `nginx-proxy`. | | `docker-compose.local.yml` | Remplacement pour test local — expose `4321:4321`, supprime les variables d'environnement nginx-proxy. | | `.dockerignore` | Garde `node_modules`, `.git`, etc. hors du contexte de construction. | -| `.env.example` | Modèle — par défaut, utilise Ollama sur neuronetz.ai, aucune clé API requise. | +| `.env.example` | Modèle — par défaut, utilise Ollama sur votre Ollama, aucune clé API requise. | ## Levez-le ```bash @@ -81,7 +81,7 @@ La construction réexécute l'index Oracle sur le contenu le plus récent ; le n | Var | Default | Utilisé à | Objectif | |---|---|---|---| | `LLM_PROVIDER` | `ollama` | exécution | `ollama` (par défaut) ou `anthropic`. | -| `OLLAMA_BASE_URL` | `https://api.neuronetz.ai` | build + exécution | Où joindre Ollama. | +| `OLLAMA_BASE_URL` | `https://your-ollama-host.example` | build + exécution | Où joindre Ollama. | | `OLLAMA_CHAT_MODEL` | `qwen2.5-coder:14b` | exécution | Modèle de complétion conversationnelle. | | `OLLAMA_EMBED_MODEL` | `nomic-embed-text` | build + exécution | Modèle d'embedding. | | `EMBED_PROVIDER` | `ollama` | build + exécution | `ollama` ou `openai`. | @@ -98,12 +98,12 @@ La construction réexécute l'index Oracle sur le contenu le plus récent ; le n **Le certificat n'a pas été émis.** Let's Encrypt limite agressivement les demandes. Vérifiez `docker logs letsencrypt-nginx-proxy-companion` pour déterminer la cause. -**Oracle répond sans références.** L'index d'incrustation est vide. Soit `nomic-embed-text` n'est pas tiré sur Ollama, soit la construction n'a pas pu atteindre neuronetz.ai. Ré-tirez le modèle :```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +**Oracle répond sans références.** L'index d'incrustation est vide. Soit `nomic-embed-text` n'est pas tiré sur Ollama, soit la construction n'a pas pu atteindre your Ollama instance. Ré-tirez le modèle :```bash +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' docker compose up -d --build ``` **L'Oracle retourne "l'Oracle ne peut pas répondre".** Vérifiez que le modèle de conversation est chargé :```bash -curl https://api.neuronetz.ai/api/tags | jq '.models[].name' +curl https://your-ollama-host.example/api/tags | jq '.models[].name' ``` **Voulez-vous revenir à Claude ?** Définissez `LLM_PROVIDER=anthropic` et `ANTHROPIC_API_KEY` dans le fichier `.env`, puis exécutez `docker compose up -d`. diff --git a/docs/src/content/docs/fr/start/local-testing.md b/docs/src/content/docs/fr/start/local-testing.md index 6d14aab..b8c3cd7 100644 --- a/docs/src/content/docs/fr/start/local-testing.md +++ b/docs/src/content/docs/fr/start/local-testing.md @@ -5,13 +5,13 @@ description: "Trois façons de déployer le site des documents (avec l'Oracle) s Le site de documentation — ainsi que l'Oracle qui se trouve dans le coin — est simplement une application Astro. Vous pouvez la lancer de trois façons en fonction de ce que vous avez à portée de main. -## Option A — Serveur de développement Astro, backend neuronetz.ai (le plus rapide) +## Option A — Serveur de développement Astro, backend your Ollama instance (le plus rapide) -L'Oracle appelle votre Ollama partagé à `https://api.neuronetz.ai`. Aucun GPU local nécessaire, aucune clé API à gérer. +L'Oracle appelle votre Ollama partagé à `https://your-ollama-host.example`. Aucun GPU local nécessaire, aucune clé API à gérer. ```bash cd /home/stephan/PhpstormProjects/Nibiru/docs -# .env (copy from .env.example, defaults already point at neuronetz.ai) +# .env (copy from .env.example, defaults already point at your Ollama instance) cp .env.example .env npm install # one-time @@ -21,7 +21,7 @@ Ouvrez . Cliquez sur le lanceur orange d'Oracle en bas **Tirez le modèle d'incrustation une seule fois** sur votre hôte Ollama (au moment de la construction + au moment de l'exécution) : ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` Sans cela, l'Oracle fonctionne toujours — elle ne fait que s'exécuter en mode conversationnel uniquement (sans RAG) et répond à partir des connaissances paramétriques du modèle. Avec cela, les réponses sont ancrées dans cette documentation. @@ -36,7 +36,7 @@ Le serveur de développement le détectera lors du prochain appel. Ou bien, igno Le point d'accès `/api/oracle` de l'Oracle répond également à la méthode GET avec sa configuration actuelle (sans les secrets) : ```bash curl http://localhost:4321/api/oracle -# {"status":"ok","llm":{"provider":"ollama","ollamaUrl":"https://api.neuronetz.ai", +# {"status":"ok","llm":{"provider":"ollama","ollamaUrl":"https://your-ollama-host.example", # "model":"qwen2.5-coder:14b"},"embed":{...},"index":{...}} ``` ## Option B — Docker Compose, localement @@ -111,14 +111,14 @@ Si l'appel final retourne une réponse réelle qui mentionne `./nibiru -m`, votr **Oracle retourne "le Oracle ne peut pas répondre".** Le serveur Ollama est inaccessible ou le modèle de conversation n'est pas extrait. Vérifiez :```bash -curl https://api.neuronetz.ai/api/tags | jq '.models[].name' +curl https://your-ollama-host.example/api/tags | jq '.models[].name' ``` **Oracle répond sans références.** L'index d'embedding est vide. Réexécutez `npm run build:oracle` après avoir tiré `nomic-embed-text`. **Ollama retourne 404 modèle non trouvé.** Tirez le modèle, par exemple :```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' ``` **`ECONNREFUSED 127.0.0.1:11434`** dans l'option C. Le local Ollama n'est pas en cours d'exécution. Démarrez-le avec `ollama serve &` (ou via votre service système). diff --git a/docs/src/content/docs/ja/ai/module/embed.md b/docs/src/content/docs/ja/ai/module/embed.md index d1eeed1..34217cc 100644 --- a/docs/src/content/docs/ja/ai/module/embed.md +++ b/docs/src/content/docs/ja/ai/module/embed.md @@ -65,10 +65,10 @@ RAG プラグインは、この形式を使用して内部の JSON ファイル ## モデル選択の埋め込み -neuronetz.ai に一度プルしてください。 +your Ollama instance に一度プルしてください。 ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' # 768 dim, default -curl https://api.neuronetz.ai/api/pull -d '{"name":"mxbai-embed-large"}' # 1024 dim, higher quality +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' # 768 dim, default +curl https://your-ollama-host.example/api/pull -d '{"name":"mxbai-embed-large"}' # 1024 dim, higher quality ``` In `ai.ini`: ```ini diff --git a/docs/src/content/docs/ja/ai/module/overview.md b/docs/src/content/docs/ja/ai/module/overview.md index 9bf05fa..d91c5fc 100644 --- a/docs/src/content/docs/ja/ai/module/overview.md +++ b/docs/src/content/docs/ja/ai/module/overview.md @@ -5,7 +5,7 @@ description: "NibiruのファーストクラスAI — チャット、エンベ Nibiruは**AIモジュール**(`application/module/ai/`)を搭載しており、これによりNibiruアプリケーションには一級のAIインターフェースが提供されます。PHPコードはローカルのLLMとチャットしたり、テキストを埋め込みたり、自身のデータ上でRAGを実行したり、ツールを使用したエージェントを実行したりすることができ、すべてが支払いが必要なAPIにデータを送信することなくに行われます。 -このモジュールはデフォルトであなたの[neuronetz.aiのOllama](/ja/ai/oracle/)に接続されていますので、推論はあなたのハードウェア、ネットワーク、および条件に基づいて行われます。 +このモジュールはデフォルトであなたの[your Ollama instanceのOllama](/ja/ai/oracle/)に接続されていますので、推論はあなたのハードウェア、ネットワーク、および条件に基づいて行われます。 ## あなたが得る内容 @@ -34,7 +34,7 @@ echo $ai->chat()->ask('How do I scaffold a new module?'); 各プラグインは、設定を `application/module/ai/settings/ai.ini` から読みます。 ```ini [AI] -ollama.base_url = "https://api.neuronetz.ai" +ollama.base_url = "https://your-ollama-host.example" chat.model = "nibiru-coder:1.0" chat.fallback_model = "qwen2.5-coder:14b" chat.temperature = 0.4 diff --git a/docs/src/content/docs/ja/ai/module/training.md b/docs/src/content/docs/ja/ai/module/training.md index a38b42b..c105f48 100644 --- a/docs/src/content/docs/ja/ai/module/training.md +++ b/docs/src/content/docs/ja/ai/module/training.md @@ -23,7 +23,7 @@ description: "ニビル風のチャットモデルを独自のオラマに登録 スクリプト: 1. 同じディレクトリにある Modelfile を読みます。 -2. `${OLLAMA_BASE_URL}/api/create`(デフォルトは `https://api.neuronetz.ai`)に POST します。 +2. `${OLLAMA_BASE_URL}/api/create`(デフォルトは `https://your-ollama-host.example`)に POST します。 3. 新しいタグが応答することを確認するために、スモークテストのチャットコールを実行します。 成功した後、`application/module/ai/settings/ai.ini` にモデルを設定します。 diff --git a/docs/src/content/docs/ja/ai/oracle.md b/docs/src/content/docs/ja/ai/oracle.md index abf04dc..23e7f5d 100644 --- a/docs/src/content/docs/ja/ai/oracle.md +++ b/docs/src/content/docs/ja/ai/oracle.md @@ -11,8 +11,8 @@ description: "サイト内のAIアシスタントの仕組み — ドキュメ | レイヤー | バックエンド | デフォルトモデル | |---|---|---| -| チャット(回答生成) | Ollama on `https://api.neuronetz.ai` | `qwen2.5-coder:14b` | -| エンベディング(RAG検索) | Ollama on `https://api.neuronetz.ai` | `nomic-embed-text` | +| チャット(回答生成) | Ollama on `https://your-ollama-host.example` | `qwen2.5-coder:14b` | +| エンベディング(RAG検索) | Ollama on `https://your-ollama-host.example` | `nomic-embed-text` | 有料のAPIキーはありません。データはあなたのネットワーク内に留まります。既に実行している5-GPUのOllamaクラスターが負荷を処理します。 @@ -46,8 +46,8 @@ flowchart LR Oracleが使用する2つのモデルを取得します: ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` `qwen2.5-coder:14b` は既にインストール済み(確認済み)。`nomic-embed-text` が不足している;これがないと、Oracle はチャットのみ(RAGなし)モードで動作します。 @@ -55,9 +55,9 @@ curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' Oracleは環境変数から設定を読み込みます。適切なデフォルト値が組み込まれています。 ```bash -# Default mode (Ollama on neuronetz.ai) +# Default mode (Ollama on your Ollama instance) LLM_PROVIDER=ollama # default -OLLAMA_BASE_URL=https://api.neuronetz.ai # default +OLLAMA_BASE_URL=https://your-ollama-host.example # default OLLAMA_CHAT_MODEL=qwen2.5-coder:14b # default OLLAMA_EMBED_MODEL=nomic-embed-text # default @@ -81,9 +81,9 @@ ORACLE_MAX_TOKENS=800 curl https://nibiru-framework.com/api/oracle { "status": "ok", - "llm": { "provider": "ollama", "ollamaUrl": "https://api.neuronetz.ai", + "llm": { "provider": "ollama", "ollamaUrl": "https://your-ollama-host.example", "model": "qwen2.5-coder:14b" }, - "embed": { "provider": "ollama", "ollamaUrl": "https://api.neuronetz.ai", + "embed": { "provider": "ollama", "ollamaUrl": "https://your-ollama-host.example", "model": "nomic-embed-text" }, "index": { "present": true, "chunks": 177, "provider": "ollama", "model": "nomic-embed-text" } diff --git a/docs/src/content/docs/ja/start/deployment.md b/docs/src/content/docs/ja/start/deployment.md index 3d00c57..d899be9 100644 --- a/docs/src/content/docs/ja/start/deployment.md +++ b/docs/src/content/docs/ja/start/deployment.md @@ -1,9 +1,9 @@ --- title: "ドキュメントサイトのデプロイメント" -description: "nibiru-framework.comの本番デプロイメントは、jwilder/nginx-proxyと独自のOllamaを使用してneuronetz.aiで行います。" +description: "nibiru-framework.comの本番デプロイメントは、jwilder/nginx-proxyと独自のOllamaを使用してyour Ollama instanceで行います。" --- -このページでは、ドキュメントサイトがプロダクションでデプロイされる方法について説明します。セットアップは、**jwilder/nginx-proxy** を使用して自動的に Docker コンテナのルーティングを行うこと、**letsencrypt-nginx-proxy-companion** を使用して HTTPS を提供すること、および **あなたの Ollama at api.neuronetz.ai** を使用して Oracle バックエンドを提供することを含んでいます。有料の LLM API キーは不要です。 +このページでは、ドキュメントサイトがプロダクションでデプロイされる方法について説明します。セットアップは、**jwilder/nginx-proxy** を使用して自動的に Docker コンテナのルーティングを行うこと、**letsencrypt-nginx-proxy-companion** を使用して HTTPS を提供すること、および **あなたの Ollama at your-ollama-host.example** を使用して Oracle バックエンドを提供することを含んでいます。有料の LLM API キーは不要です。 ## トポロジー ``` @@ -17,7 +17,7 @@ description: "nibiru-framework.comの本番デプロイメントは、jwilder/ng │ http://nibiru-docs:4321 ▼ ┌──────────────────────┐ ┌──────────────────────┐ - │ nibiru-docs │ ──────▶ │ api.neuronetz.ai │ + │ nibiru-docs │ ──────▶ │ your-ollama-host.example │ │ Astro Node SSR :4321 │ HTTPS │ Ollama (5× GPU) │ │ Oracle endpoint │ │ qwen2.5-coder:14b │ └──────────────────────┘ │ nomic-embed-text │ @@ -31,19 +31,19 @@ docker network create nginx-proxy # 2) Run nginx-proxy + acme-companion (one time) # See https://github.com/nginx-proxy/nginx-proxy for the canonical compose. -# 3) Pull the Oracle's models on neuronetz.ai (one time) -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +# 3) Pull the Oracle's models on your Ollama instance (one time) +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` ## `docs/` 内のファイル | ファイル | 機能 | |---|---| -| `Dockerfile` | 多段階ビルド: neuronetz.ai に対して Oracle インデックスを構築し、Astro を構築し、開発依存関係を削減します。 | +| `Dockerfile` | 多段階ビルド: your Ollama instance に対して Oracle インデックスを構築し、Astro を構築し、開発依存関係を削減します。 | | `docker-compose.yml` | 生産 — `VIRTUAL_HOST=nibiru-framework.com`、nginx-proxy ネットワークに参加しています。 | | `docker-compose.local.yml` | ローカルテストオーバーライド — `4321:4321` を公開し、nginx-proxy 環境変数を削除します。 | | `.dockerignore` | `node_modules`、`.git` などの構築コンテキストから除外します。 | -| `.env.example` | テンプレート — neuronetz.ai の Ollama をデフォルトにし、API キーは不要です。 | +| `.env.example` | テンプレート — your Ollama instance の Ollama をデフォルトにし、API キーは不要です。 | ## 起動する ```bash @@ -81,7 +81,7 @@ docker compose up -d --build | 変数 | デフォルト | 使用場所 | 機能 | |---|---|---|---| | `LLM_PROVIDER` | `ollama` | 実行時 | `ollama`(デフォルト)または `anthropic`。 | -| `OLLAMA_BASE_URL` | `https://api.neuronetz.ai` | ビルド + 実行時 | Ollama に到達するための場所。 | +| `OLLAMA_BASE_URL` | `https://your-ollama-host.example` | ビルド + 実行時 | Ollama に到達するための場所。 | | `OLLAMA_CHAT_MODEL` | `qwen2.5-coder:14b` | 実行時 | チャット完了モデル。 | | `OLLAMA_EMBED_MODEL` | `nomic-embed-text` | ビルド + 実行時 | 埋め込みモデル。 | | `EMBED_PROVIDER` | `ollama` | ビルド + 実行時 | `ollama` または `openai`。 | @@ -98,12 +98,12 @@ docker compose up -d --build **証明書が発行されていません。** Let's Encrypt は激しくレート制限を行っています。原因については `docker logs letsencrypt-nginx-proxy-companion` を確認してください。 -**Oracleは引用せずに回答します。** エンベディングインデックスが空です。`nomic-embed-text`がOllamaで取得されていないか、ビルドがneuronetz.aiに到達できなかった可能性があります。モデルを再度取得してください:```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +**Oracleは引用せずに回答します。** エンベディングインデックスが空です。`nomic-embed-text`がOllamaで取得されていないか、ビルドがyour Ollama instanceに到達できなかった可能性があります。モデルを再度取得してください:```bash +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' docker compose up -d --build ``` **Oracle は「Oracle が回答することができませんでした」を返しました。** チャットモデルが取得されていることを確認してください:```bash -curl https://api.neuronetz.ai/api/tags | jq '.models[].name' +curl https://your-ollama-host.example/api/tags | jq '.models[].name' ``` **Claudeにフォールバックしたい場合** `LLM_PROVIDER=anthropic` と `ANTHROPIC_API_KEY` を `.env` ファイルに設定し、その後 `docker compose up -d` を実行します。 diff --git a/docs/src/content/docs/ja/start/local-testing.md b/docs/src/content/docs/ja/start/local-testing.md index 9a536c9..547f6d5 100644 --- a/docs/src/content/docs/ja/start/local-testing.md +++ b/docs/src/content/docs/ja/start/local-testing.md @@ -5,13 +5,13 @@ description: "Oracleでドキュメントサイトを自宅のマシン上で起 ドキュメントサイトとコーナーに住むOracleは、単なるAstroアプリです。手元にあるもの次第で3つの方法で実行できます。 -## オプション A — Astro 開発サーバー、neuronetz.ai バックエンド(最速) +## オプション A — Astro 開発サーバー、your Ollama instance バックエンド(最速) -Oracle は、`https://api.neuronetz.ai` の共有 Ollama を呼び出します。ローカルの GPU は必要ありませんし、API キーを管理する必要もありません。 +Oracle は、`https://your-ollama-host.example` の共有 Ollama を呼び出します。ローカルの GPU は必要ありませんし、API キーを管理する必要もありません。 ```bash cd /home/stephan/PhpstormProjects/Nibiru/docs -# .env (copy from .env.example, defaults already point at neuronetz.ai) +# .env (copy from .env.example, defaults already point at your Ollama instance) cp .env.example .env npm install # one-time @@ -21,7 +21,7 @@ npm run dev # http://localhost:4321 **Ollamaホスト上で1回だけ埋め込みモデルを取得**(ビルド時+実行時): ```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"nomic-embed-text"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"nomic-embed-text"}' ``` これなしで、Oracleはまだ動作します——それは単にチャットのみ(no-RAG)モードで実行され、モデルのパラメトリックな知識から回答されます。これがあれば、回答はこのドキュメンテーションに基づいています。 @@ -36,7 +36,7 @@ npm run build:oracle # writes public/oracle-index.json Oracleの`/api/oracle`エンドポイントも、現在の設定(シークレットなし)でGETリクエストに応答します。 ```bash curl http://localhost:4321/api/oracle -# {"status":"ok","llm":{"provider":"ollama","ollamaUrl":"https://api.neuronetz.ai", +# {"status":"ok","llm":{"provider":"ollama","ollamaUrl":"https://your-ollama-host.example", # "model":"qwen2.5-coder:14b"},"embed":{...},"index":{...}} ``` ## オプションB — ローカルでのDocker Compose @@ -111,14 +111,14 @@ curl -X POST -H 'Content-Type: application/json' \ **Oracle は「Oracle が回答することができませんでした」を返します。** Ollama サーバーにアクセスできないか、チャットモデルがプルされていない可能性があります。確認してください:```bash -curl https://api.neuronetz.ai/api/tags | jq '.models[].name' +curl https://your-ollama-host.example/api/tags | jq '.models[].name' ``` **Oracle は引用せずに回答します。** 埋め込みインデックスが空です。`nomic-embed-text` をプルした後、`npm run build:oracle` を再実行してください。 **Ollamaが404 model-not-foundを返します。** モデルを取得してください、例:```bash -curl https://api.neuronetz.ai/api/pull -d '{"name":"qwen2.5-coder:14b"}' +curl https://your-ollama-host.example/api/pull -d '{"name":"qwen2.5-coder:14b"}' ``` **`ECONNREFUSED 127.0.0.1:11434`** オプションCで。 ローカルのOllamaが実行されていません。`ollama serve &`(またはシステムサービス経由で)で開始してください。 diff --git a/docs/src/pages/api/oracle.ts b/docs/src/pages/api/oracle.ts index 66fc6d7..857da9c 100644 --- a/docs/src/pages/api/oracle.ts +++ b/docs/src/pages/api/oracle.ts @@ -81,7 +81,7 @@ export const POST: APIRoute = async ({ request }) => { if (lcfg.provider === 'anthropic' && !lcfg.hasAnthropicKey) { return json({ answer: - 'The Oracle is silent — `LLM_PROVIDER=anthropic` is set but `ANTHROPIC_API_KEY` is missing. Set the key, or switch back to `LLM_PROVIDER=ollama` (which is the default and uses your neuronetz.ai instance).', + 'The Oracle is silent — `LLM_PROVIDER=anthropic` is set but `ANTHROPIC_API_KEY` is missing. Set the key, or switch back to `LLM_PROVIDER=ollama` (the default).', sources: [], }); } @@ -166,7 +166,9 @@ function json(body: unknown, status = 200): Response { }); } -// Tiny GET handler so health-check / debugging shows config without secrets. +// Tiny GET handler so health checks can confirm the Oracle is up. +// Intentionally does NOT echo the upstream Ollama URL — that's an internal +// detail. Provider name + model name are fine; the URL stays in env vars. export const GET: APIRoute = async () => { const llm = llmConfig(); const emb = embedConfig(); @@ -189,12 +191,10 @@ export const GET: APIRoute = async () => { status: 'ok', llm: { provider: llm.provider, - ollamaUrl: llm.provider === 'ollama' ? llm.ollamaUrl : undefined, model: llm.provider === 'ollama' ? llm.ollamaChatModel : llm.anthropicModel, }, embed: { provider: emb.provider, - ollamaUrl: emb.provider === 'ollama' ? emb.ollamaUrl : undefined, model: emb.provider === 'ollama' ? emb.ollamaEmbedModel : emb.openaiEmbedModel, }, index: {