---
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.
---

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.

## What you get

| Plugin | What it does | One-liner |
|---|---|---|
| `Chat` | Chat completions, single- or multi-turn | `$ai->chat()->ask('…')` |
| `Embed` | Text → vectors + cosine helpers | `$ai->embed()->one('…')` |
| `Rag` | Ingest + retrieve + grounded chat | `$ai->rag('docs')->ask('…')` |
| `Agent` | Tool-using ReAct loop | `$ai->agent()->withTools([…])->run('…')` |
| `Tool` | Base for your own custom tools | `class MyTool extends Tool { … }` |
| `Ollama` | Raw HTTP transport to any Ollama-compatible endpoint | `(new Ollama($cfg))->chat(…)` |

## Hello, AI

```php
use Nibiru\Module\Ai\Ai;

$ai = new Ai();

echo $ai->chat()->ask('How do I scaffold a new module?');
// → "Run `./nibiru -m <name>`. This creates application/module/<name>/ with…"
```

That's the whole API surface for the simple case. No DI container, no API keys, no SDK install.

## Wired by config

Every plugin reads its settings from `application/module/ai/settings/ai.ini`:

```ini
[AI]
ollama.base_url     = "https://api.neuronetz.ai"
chat.model          = "nibiru-coder:1.0"
chat.fallback_model = "qwen2.5-coder:14b"
chat.temperature    = 0.4
chat.max_tokens     = 1024
embed.model         = "nomic-embed-text"
rag.top_k           = 6
agent.max_iterations = 6
```

Per-environment override: `ai.production.ini`, `ai.staging.ini`. Nibiru's [Registry](/en/core/registry/) auto-discovers them.

## The four flagship use cases

### 1. Chat — talk to your model

```php
$ai = new \Nibiru\Module\Ai\Ai();

// One-shot
echo $ai->chat()->ask('Explain MMVC in two sentences.');

// Multi-turn
$chat = $ai->chat();
$chat->user('How do I scaffold a module?');
$chat->user('And add Graylog hooks?');   // referrs to previous turn
echo $chat->complete();

// Override per call
echo $ai->chat()
    ->system('Answer in German.')
    ->model('qwen2.5-coder:14b')
    ->temperature(0.1)
    ->ask('Was ist ein Modul?');
```

The `Chat` plugin auto-falls back to `chat.fallback_model` if the primary model isn't available — useful while you're still building `nibiru-coder`.

### 2. Embed — text into vectors

```php
$embed = $ai->embed();

$va = $embed->one('controller');
$vb = $embed->one('module');
$score = \Nibiru\Module\Ai\Plugin\Embed::cosine($va, $vb);
// → 0.78 (close concepts)
```

Compact storage:

```php
$packed = \Nibiru\Module\Ai\Plugin\Embed::pack($vec);   // base64 string, 4 bytes/dim
$vec    = \Nibiru\Module\Ai\Plugin\Embed::unpack($packed);
```

### 3. RAG — ingest, retrieve, ground

```php
$rag = $ai->rag('product-help');

// One-time ingestion
$rag->ingestDir(__DIR__ . '/help/');             // walks .md/.txt/.php
$rag->ingestText('FAQ entry…', ['source' => 'faq-12']);
$rag->ingestFile('/var/data/manual.pdf.txt');

// Then ask grounded questions
echo $rag->ask('How do I cancel my subscription?');
// → "Per the help docs, you can cancel in account → settings… [1]"
```

Storage: a single JSON file per collection at `application/module/ai/cache/rag/<name>.json`. Restartable, zero DB, fits ~10k chunks comfortably in memory.

### 4. Agent — tools that act

```php
use Nibiru\Module\Ai\Plugin\Tools;

$ai = new \Nibiru\Module\Ai\Ai();

$agent = $ai->agent()->withTools([
    new Tools\PdoQuery(),    // read-only SQL
    new Tools\HttpGet(),     // fetch URLs
    new Tools\FileRead(),    // read project files
]);

echo $agent->run('How many active users registered last week?');
// → agent decides to call pdo_query with SELECT count(*) FROM users…
//   reads observation, writes a final answer.
```

The agent uses a ReAct-style loop: read task → pick tool → execute → observe → repeat → final answer. The protocol uses a simple `\`\`\`tool {...}\`\`\`` JSON sentinel that works on every Ollama model — no model-specific tool-calling APIs required.

## Where it lives

```
application/module/ai/
├── ai.php                    # main class implementing IModule
├── interfaces/ai.php         # contract
├── traits/ai.php             # cfg() helper
├── plugins/
│   ├── ollama.php            # raw transport
│   ├── chat.php              # chat completions
│   ├── embed.php             # embeddings + cosine + pack
│   ├── rag.php               # ingest + retrieve + grounded chat
│   ├── agent.php             # ReAct tool loop
│   ├── tool.php              # abstract base for custom tools
│   └── tools/
│       ├── pdoQuery.php      # read-only SQL
│       ├── httpGet.php       # HTTP GET
│       └── fileRead.php      # project-local file read
├── settings/ai.ini           # config
├── cache/rag/                # RAG vector index files (gitignored)
└── training/
    ├── Modelfile             # the nibiru-coder system prompt
    ├── build.sh              # one-command Modelfile → registered model
    ├── smoke-test.php        # verify the whole stack
    └── README.md             # training pipeline guide
```

## Why this exists

PHP doesn't have an established "AI framework" the way Python has LangChain or JS has Vercel AI SDK. Nibiru's AI module fills that gap with the smallest, sharpest API we could write — three layers (transport → plugin → module), no DI graph, no SDK install, no per-token bill.

The design philosophy:

- **Bring your own brain.** Ollama by default, Anthropic and OpenAI as drop-ins. Swap providers via INI, never via code.
- **One JSON file per RAG collection.** No vector DB. Reboot-safe. Grep-able when you're debugging.
- **Tools are PHP classes.** Extend `Tool`, get a name + schema + execute method. The agent figures out the rest.
- **No model-specific tool-call APIs.** A single fenced-JSON convention works everywhere.

## Next

- [Chat plugin reference](/en/ai/module/chat/)
- [RAG plugin reference](/en/ai/module/rag/)
- [Agent plugin reference](/en/ai/module/agent/)
- [Training nibiru-coder](/en/ai/module/training/)
