Skip to content

Commander Bots

Per-Commander Telegram Bot Responder + Conversation Memory

source: documentation/activities/commander-bots-responder.md

9 Commander bots registered in the CT106 poller (/opt/scripts/hinata-bot-poller.py COMMANDER_MAP), each replying in its Commander's voice via Anthropic API (claude-haiku-4-5-20251001) using the Commander's context.md as system prompt. Per-bot BotFather tokens live as files in the Itachi credential directory on CT106 — never printed here.

  BotCommanderbot-id

    bulmaBulma (finance)8912480615
    ging-encyclopediaGing (reading)8880398293
    zukoZuko (career)8885744749
    brookBrook (entertainment)8905587154
    sanjiSanji (nutrition)8924288755
    simbaSimba (shelter — product folded into Zepile home tab; bot still registered)id in CT106 token file
    squidwardSquidward (music)id in CT106 token file
    melfiMelfi (psychology)id in CT106 token file
    kakashiKakashi (VMO2 work)id in CT106 token file
    hashiramaHashirama (investment) — **PENDING**: BotFather token awaited from Michael; COMMANDER_MAP entry + token file wire on receipt; context = federation/colonel_sung-jinwoo-synthesis_hashirama-investment_context.mdpending

Architecture

hinata-bot-poller.py runs always-on on CT106 (Z2 systemd; the former Mac LaunchAgent placement is retired per runtime-vs-BAU law). Per-turn flow:

  1. Poll Telegram getUpdates every 30s

  2. Redact credential shapes from message body

  3. Write inbox file (frontmatter + body, redacted)

  4. Load Commander context.md (cached at startup)

  5. Build system prompt: identity wrapper + Commander context

  6. Load conversation history (last 10 turns, 24h freshness window, JSONL at ~/Sandpit/hinata/data/bot-memory/{bot}.jsonl)

  7. POST to Anthropic API

  8. Send reply via Telegram sendMessage (split at 4000 chars)

  9. Append both turns to history

Smart features

  • /start gives static ack — no LLM call

  • Redacted messages: reply skipped (don't echo back leaked credentials)

  • Conversation memory auto-rotates when JSONL > 80 lines (keeps last 20)

  • Out-of-domain: Commander instructed to redirect to right Commander

Known gap

bot-reply-vault-receipt — replies don't visibly prove vault-connection. Needs /whoami Telegram command + probe detection. Catalogued in projects/hinata-architecture/bot-reply-vault-receipt.md.

Cost: ~$0.0001 per reply at haiku-4-5 rates.

Verification: Live-tested 2026-05-26 ~10:42 — sanji replied + brook replied. Memory layer verified at 10:49 restart.

Wave 4 — Bot Context Injection + Tool-Call Protocol

source: documentation/activities/wave4-bot-tool-call.md

Closes the paper-Commander gap. Bulma bot now runs deterministic queries before LLM synthesis, and injects results into context.

Wave 4a — Event injection

* `load_recent_events()` fetches last 5 events from api.michael-engineer.dev/events via x-hinata-key auth

* Injected into Commander system prompt under "## Recent Hinata system events"

Wave 4b — Routing-rule matcher

  * Inline BOT_RULES table — 7 rules: Bulma (spend, fees, mtd, savings, merchant-top, income, upcoming-debits)

  * match_bot_rule(bot_name, msg) — first-match-wins, bot-scoped

Wave 4c — Tool-call invocation

    * invoke_tool(cli_args) — subprocess with 15s timeout, JSON parse, never raises

    * Injected into system prompt under "## Tool result for THIS turn (read first)"

    * System prompt rule: "If a 'Tool result' block is present, use it as source of truth. Never contradict it; never claim 'no data' when JSON is present."

Wave 4d — 4-turn log shape

When tool_match fires: bot-memory.jsonl gains 4 entries per turn (user, tool_call, tool_result, assistant) instead of 2. tool_result truncated to 4000 chars.

Smoke test results

  QueryMatched ruleCLI invoked

    "How much did I spend weekly on ganja in April"bulma-spend-questionbulma-q.py spend --category ganja --period 2026-04 --bucket week
    "When do bills go out this week"bulma-upcoming-debitsbulma-q.py upcoming-debits --days 14
    "Fees this month"bulma-fees-questionbulma-q.py fees
    "Random unrelated question"(none)LLM-only path

Architecture invariant

Bots never query raw producer data directly. They invoke CLI tools that read through the categoriser + period parser. The CLI is the boundary; the LLM synthesises natural language over deterministic output.

What is deferred

      * Dynamic routing.md parser (#840082) — bot still uses inline Python rule table

      * Proper ChatGPT-style tool_call/tool_result API roles in Anthropic messages payload

      * Other Commanders (Brook, Sanji, Squidward, Zuko, Ging) have no rules yet

◆ hinata · commander-bots · folded from documentation/activities/ phase-19