llm-chat/MODULE.md
flemming-it 84a23e6b14
Some checks failed
CI / Linux x86_64 (Forgejo) (push) Failing after 1s
docs: add MODULE.md + MODULE.de.md inline docs
Explains the 'why this module instead of inline HTTP' answer
operators ask when they see llm.chat for the first time:
audit, permission posture, endpoint portability.

Signed-off-by: flemming-it <sf@flemming.it>
2026-05-25 14:06:04 +02:00

104 lines
3.7 KiB
Markdown

# llm.chat
Generic Ollama-compatible LLM chat adapter. The building-block
module any flow uses when it needs a one-shot LLM completion —
classify, extract-fields, rewrite, decide — instead of rolling
its own HTTP client.
## Capability
- `llm.chat@0.1.0`
## Inputs
| Name | Type | Description |
| ---------------- | ---- | --------------------------------------------------------------- |
| `prompt` | text | The user-facing prompt. |
| `endpoint` | text | Ollama-shaped `/api/chat` URL (e.g. `http://localhost:11434/api/chat`). |
| `model` | text | Model identifier (e.g. `qwen2.5:14b`, `llama3.1:8b`). |
| `api_key` | text | Optional bearer token for cloud-hosted endpoints. |
| `system_prompt` | text | Optional system message. Empty = use the model's default. |
## Outputs
| Name | Type | Description |
| ---------------- | ---- | ------------------------------------------------------------------- |
| `response` | text | The assistant's plain-text reply. |
| `model_endpoint` | text | The endpoint the response was generated against. |
| `model_name` | text | The model identifier as supplied to the LLM API. |
| `model_digest` | text | SHA-256 digest of the served Ollama model. Empty for cloud APIs. |
Together the three `model_*` outputs answer the audit
question: "which exact model produced this response?" — that
audit trail is the reason flows use this module rather than
spawning their own HTTP calls.
## Permissions
```yaml
permissions:
- "net: localhost"
- "net: 127.0.0.1"
- "net: api.openai.com"
- "net: api.anthropic.com"
```
Loopback (local Ollama) by default. Cloud endpoints require an
operator-policy override in `~/.fai/config.yaml#security.max_permissions`.
## Why this module instead of inline HTTP
Three reasons:
1. **Audit.** Every LLM call surfaces `model_endpoint`,
`model_name`, `model_digest` as separate outputs that land
in the hash-chained audit log alongside the response. A
regulator-facing reproducibility check just compares the
digest field to the model snapshot.
2. **Permission posture.** The operator sees `llm.chat` in
the installed modules + its declared `net:` list. A
home-grown HTTP module would either hide its endpoints
or be a fresh review surface every time.
3. **Endpoint portability.** The endpoint + model are flow
inputs, not compile-time constants. The same flow runs
against `localhost:11434` in dev and a production
inference cluster in prod just by swapping the input.
## Limits in v0.1.0
- No streaming. The whole reply is buffered before the output
step fires.
- No tool-call / function-call surface. A flow needing tool
use composes multiple `llm.chat` steps with prompt
engineering, or uses MCP via the bridge.
- Cloud-provider adapters for OpenAI and Anthropic are
deferred until a flow actually needs them. Today the
Ollama wire-format is the only target.
## Example flow
```yaml
name: classify-incoming
inputs:
text: text
steps:
- id: classify
use: llm.chat@^0
with:
prompt: $inputs.text
system_prompt: |
Classify the text as one of: question, complaint,
feedback, spam. Answer with the label only.
endpoint: "http://localhost:11434/api/chat"
model: "qwen2.5:14b"
outputs:
category: $classify.response
audit_model: $classify.model_digest
```
## Build
```bash
cargo build --release --target wasm32-wasip2
# Output: target/wasm32-wasip2/release/llm_chat.wasm
```