feat(bots): add LLM chatbot with Ollama provider (#74) #111

Merged
icub3d merged 1 commit from feature/74-chatbot into main 2026-07-11 04:16:04 +00:00
Owner

Implements #74: a reference LLM-powered bot (decentcom-chatbot) that replies to @mentions using a pluggable provider architecture, starting with Ollama.

Closes #74.

What it does

tools/bots/chatbot/ — built on the decentcom-bot SDK. On every message: skip our own messages (loop-safe), detect @{mention_name} (ASCII-case-insensitive, word-boundary; "email@chatbot.dev" and "@chatbotter" don't match), strip all mentions, send the remainder to the provider, and reply in-channel. Provider failures produce a friendly in-channel message plus a detailed log line; replies are truncated at max_reply_chars (default 4000).

Mention offsets are computed byte-wise with ASCII case folding, so stripping is safe in multibyte content (Unicode to_lowercase can shift byte offsets).

Provider architecture

Provider is enum-dispatched (no async-trait dep): a new backend is one variant, one config struct, one match arm. OllamaProvider calls the non-streaming /api/chat endpoint via reqwest with system_prompt, temperature, and optional num_predict (max_tokens), with a configurable timeout.

Config

Flattened decentcom_bot::Config (same BOT_* env overrides as every bot) plus mention_name (defaults to display_name), max_reply_chars, provider, and an [ollama] table. $CHATBOT_CONFIG selects the file; CHATBOT_OLLAMA_URL / CHATBOT_OLLAMA_MODEL / CHATBOT_MENTION_NAME override. See the crate README and chatbot.example.toml.

Dev-loop wiring

  • Procfile gains chatbot: CHATBOT_CONFIG=test-configs/chatbot.toml cargo run -q --bin chatbot, so make dev starts it.
  • test-configs/chatbot.toml uses the seeded bot-beta identity ([0x11; 32]) and points at a local Ollama.
  • sdk-seed now registers and approves bot-beta on the Open Server (previously only bot-alpha).

Verification

  • 19 new unit/integration tests (mention detection & stripping, TOML parsing/defaults, truncation, wiremock mock-Ollama: request shape, HTTP error surfacing, trailing-slash URL). cargo test --workspace, cargo clippy --workspace --all-targets -- -D warnings, cargo fmt --check all clean.
  • Live end-to-end: started the three dev servers + sdk-seed + chatbot exactly as make dev does, sent @chatbot In one short sentence, what is Rust? as alice via the SDK, and received a real completion from a local Ollama (gemma4:12b): "Rust is a high-performance programming language focused on memory safety and concurrency."

Open questions from the issue resolved as recommended: stateless per-message responses (no history), truncation for over-long replies.

🤖 Generated with Claude Code

Implements #74: a reference LLM-powered bot (`decentcom-chatbot`) that replies to `@mentions` using a pluggable provider architecture, starting with [Ollama](https://ollama.com/). Closes #74. ## What it does `tools/bots/chatbot/` — built on the `decentcom-bot` SDK. On every message: skip our own messages (loop-safe), detect `@{mention_name}` (ASCII-case-insensitive, word-boundary; "email@chatbot.dev" and "@chatbotter" don't match), strip all mentions, send the remainder to the provider, and reply in-channel. Provider failures produce a friendly in-channel message plus a detailed log line; replies are truncated at `max_reply_chars` (default 4000). Mention offsets are computed byte-wise with ASCII case folding, so stripping is safe in multibyte content (Unicode `to_lowercase` can shift byte offsets). ## Provider architecture `Provider` is enum-dispatched (no async-trait dep): a new backend is one variant, one config struct, one match arm. `OllamaProvider` calls the non-streaming `/api/chat` endpoint via reqwest with `system_prompt`, `temperature`, and optional `num_predict` (`max_tokens`), with a configurable timeout. ## Config Flattened `decentcom_bot::Config` (same `BOT_*` env overrides as every bot) plus `mention_name` (defaults to `display_name`), `max_reply_chars`, `provider`, and an `[ollama]` table. `$CHATBOT_CONFIG` selects the file; `CHATBOT_OLLAMA_URL` / `CHATBOT_OLLAMA_MODEL` / `CHATBOT_MENTION_NAME` override. See the crate README and `chatbot.example.toml`. ## Dev-loop wiring - `Procfile` gains `chatbot: CHATBOT_CONFIG=test-configs/chatbot.toml cargo run -q --bin chatbot`, so `make dev` starts it. - `test-configs/chatbot.toml` uses the seeded `bot-beta` identity (`[0x11; 32]`) and points at a local Ollama. - `sdk-seed` now registers **and approves** `bot-beta` on the Open Server (previously only `bot-alpha`). ## Verification - 19 new unit/integration tests (mention detection & stripping, TOML parsing/defaults, truncation, wiremock mock-Ollama: request shape, HTTP error surfacing, trailing-slash URL). `cargo test --workspace`, `cargo clippy --workspace --all-targets -- -D warnings`, `cargo fmt --check` all clean. - Live end-to-end: started the three dev servers + sdk-seed + chatbot exactly as `make dev` does, sent `@chatbot In one short sentence, what is Rust?` as alice via the SDK, and received a real completion from a local Ollama (`gemma4:12b`): *"Rust is a high-performance programming language focused on memory safety and concurrency."* Open questions from the issue resolved as recommended: stateless per-message responses (no history), truncation for over-long replies. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(bots): add LLM chatbot with Ollama provider (#74)
Some checks failed
Security Audit / Gitleaks (Secrets) (pull_request) Successful in 11s
Security Audit / PNPM Audit (JS SCA) (pull_request) Failing after 24s
Security Audit / Trivy (SCA & IaC) (pull_request) Failing after 25s
CI / Client — test & lint (pull_request) Successful in 43s
Security Audit / Semgrep (SAST) (pull_request) Failing after 1m14s
CI / Server — test & lint (pull_request) Successful in 3m56s
Security Audit / Cargo Audit (Rust SCA) (pull_request) Failing after 4m9s
5442b122bd
New reference bot decentcom-chatbot: replies to @mentions in any channel
it can read by sending the mention-stripped message to an LLM provider
and posting the completion back. Providers are pluggable via enum
dispatch; the initial backend is Ollama (non-streaming /api/chat).

- mention detection: ASCII-case-insensitive, word-boundary, offset-safe
  for multibyte content; all mentions stripped from the prompt
- config: flattened decentcom_bot::Config + [ollama] section (url,
  model, system_prompt, temperature, max_tokens, timeout_secs), env
  overrides CHATBOT_CONFIG / CHATBOT_OLLAMA_URL / CHATBOT_OLLAMA_MODEL
- loop-safe: ignores its own messages; provider errors are reported
  in-channel and logged; long replies truncated at max_reply_chars
- dev wiring: chatbot Procfile entry (make dev) using
  test-configs/chatbot.toml; sdk-seed now registers and approves
  bot-beta on the Open Server as the chatbot identity
- tests: mention detection, TOML parsing, truncation, and a
  wiremock-based mock-Ollama integration test

Closes #74

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
icub3d merged commit e401c324f6 into main 2026-07-11 04:16:04 +00:00
icub3d deleted branch feature/74-chatbot 2026-07-11 04:16:04 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
icub3d/decentcom!111
No description provided.