Telegram Bot Intent Classifier — comms-responder
Telegram Bot Intent Classifier — comms-responder
MC: #99290 Status: Live Last deploy: 2026-05-05 21:33:03 UTC Prompt SHA-256: 33fc181...b5a2
1. Overview
The comms-responder is the intent-routing brain of the ALAI Telegram bot. It receives every inbound CEO message and classifies it into one of five intent categories before generating a response. Prior to MC #99290, the bot had a task-creation bias — informal messages such as "Bok" or "Kako si?" triggered unsolicited offers to create MC tasks. The fix is prompt-only: no code was changed in comms-responder.js (802 lines, unchanged) or telegram-agent.js.
Root cause (from audit.md): The original main-system-prompt.md placed the Task Actions section (lines 20-45) before conversational rules and had an over-broad MAYBE branch — "If unsure whether it is actionable, ASK" — which caused haiku-model responses to offer task creation for purely casual messages, since 20 live MC tasks were injected unconditionally into every context window.
Fix applied 2026-05-05:
- Explicit 5-category intent classifier added at the TOP of the prompt (before context/actions).
- Task Actions section reordered to end and renamed to "ONLY for task-create intent".
- Aggressive MAYBE/ASK fallback removed.
- Conversational mode made the explicit default.
Key files:
- Prompt:
/Users/makinja/system/prompts/extracted/comms-responder/main-system-prompt.md - Bot logic:
/Users/makinja/system/tools/comms-responder.js(unchanged, 802 lines) - VM daemon:
alai-telegram-agent.serviceon Azure VM (4.223.110.181)
2. Intent Categories
Every inbound message is classified into exactly one of these five categories before a response is generated. Classification is silent (not shown to the user).
| Category | Trigger signals | Response mode | Task action? |
|---|---|---|---|
greeting | Bok, Selam, Zdravo, Hey, Ciao, opener phrases | Short friendly reply. No task mention. | Never |
chitchat | Kako si?, Šta radiš?, casual conversation | 1-2 sentences conversational. No task offer. | Never |
status-query | Da li je X gotov?, Šta ima novo?, Koji je status...? | Pull from task context, answer directly and concisely. | Never |
question | Kako radi X?, Zašto je Y?, factual or technical ask | Answer from context. No task offer unless explicitly asked. | Never |
task-create | Kreiraj task, Napravi MC za..., Dodaj task, Otvori MC — explicit verb + task directive | Create task, confirm with ID. | ONLY this category |
Default rule (prompt line 17): If category is not clearly task-create, respond conversationally. NEVER offer to create a task unprompted.
3. How It Works
The classification logic lives entirely in the system prompt file:
/Users/makinja/system/prompts/extracted/comms-responder/main-system-prompt.md
The prompt is loaded at runtime by comms-responder.js via the buildSystemPrompt() function. No intent classification code exists in the JS layer — the LLM (haiku to sonnet chain) performs STEP 1 classification silently before generating a response.
Request flow:
- CEO sends Telegram message.
alai-telegram-agent.service(VM) receives update via Telegram Bot API webhook.telegram-agent.jscallscomms-responder.js getResponse(message, history).comms-responder.jsbuilds system prompt frommain-system-prompt.md, injects scope block + task context + today's date.- LLM classifies intent (STEP 1) silently, then generates response.
- If intent =
task-create: response includesjson:actionblock.telegram-agent.js parseAndExecuteActions()extracts and runs it againstmc.js. - For all other intents: plain conversational response, no action block.
Note on MC task injection: comms-responder.js lines 191-207 load 20 open MC tasks unconditionally into every context window (to enable status-query answers). This is by design; the classifier gate prevents this context from biasing non-status responses toward task creation.
4. Adding / Tuning Intent Patterns
Edit file: /Users/makinja/system/prompts/extracted/comms-responder/main-system-prompt.md
The STEP 1 classifier table (near the top of the prompt) is the authoritative classification surface.
- Open
main-system-prompt.mdon ANVIL. - Locate the STEP 1 classifier table (lines 5-16 in current version).
- Add the new signal phrase to the Signals column of the relevant category row. Add a new row only if a genuinely new category is needed.
- If a new category should trigger a new action: also update the Task Actions section AND
parseAndExecuteActions()intelegram-agent.js(requires CodeCraft dispatch — code change). - Update the WHEN TO CREATE TASKS YES/NO examples block to include the new pattern.
- Run the test suite (Section 5) to validate no regression.
- Deploy per Section 6.
Critical constraint: Do NOT add a generic "if unsure, ASK" fallback. This was the direct cause of the original task-creation bias (audit.md, lines 42-44).
5. Testing
Test suite: /tmp/99290-evidence/test-cases.js (10 message patterns)
Dry-run (no API cost — validates prompt content only):
node /tmp/99290-evidence/test-cases.js
Live API test (costs tokens — validates actual LLM classification):
node /tmp/99290-evidence/test-cases.js --live
10 test cases:
| ID | Message | Expected Intent | Task Offer? | Description |
|---|---|---|---|---|
| TC-01 | Bok | greeting | No | Single greeting — must NOT trigger task creation offer |
| TC-02 | Selam | greeting | No | Bosnian greeting — must NOT trigger task creation offer |
| TC-03 | Šta ima novo? | status-query | No | Status query — should pull task context, NOT offer to create task |
| TC-04 | Kreiraj MC task za sintef follow-up | task-create | Yes | Explicit task-create directive — MUST trigger create_task action |
| TC-05 | Kako si? | chitchat | No | Casual chitchat — must respond conversationally, no task offer |
| TC-06 | Da li je drop deploy gotov? | status-query | No | Deploy status query — answer from context, no task offer |
| TC-07 | Napravi MC za UI bug na login stranici | task-create | Yes | Explicit task-create (Bosnian variant) — MUST trigger create_task |
| TC-08 | Kako radi auth na Bilko-u? | question | No | Technical question — answer from context, no task creation |
| TC-09 | Ciao, šta radiš? | greeting/chitchat | No | Mixed greeting+chitchat — conversational only |
| TC-10 | Otvori task za SINTEF LOI follow-up, prioritet H | task-create | Yes | Explicit task-create with priority — MUST trigger create_task |
7 prompt validation checks (dry run — all PASS after MC #99290 fix, per regression.md):
- Intent classifier table present (all 5 categories)
- Conversational default stated explicitly
- "ONLY for task-create intent" gate on Task Actions header
- Aggressive MAYBE/ASK removed (string absent from prompt)
- Greeting NO example present (Bok)
- Status-query NO example present (Šta ima novo)
- Task-create YES example present (Kreiraj task za sintef)
6. VM Deploy Procedure
Deploy target: Azure VM 4.223.110.181, service alai-telegram-agent.service
Last deploy: 2026-05-05 21:33:03 UTC
Deployed prompt SHA-256: 33fc181...b5a2
- Edit
/Users/makinja/system/prompts/extracted/comms-responder/main-system-prompt.mdon ANVIL. - Verify SHA-256 locally:
shasum -a 256 /Users/makinja/system/prompts/extracted/comms-responder/main-system-prompt.md - Copy updated prompt to VM:
scp -i ~/.ssh/azure_alai /Users/makinja/system/prompts/extracted/comms-responder/main-system-prompt.md [email protected]:/home/alai-admin/system/prompts/extracted/comms-responder/main-system-prompt.md - Restart daemon:
ssh -i ~/.ssh/azure_alai [email protected] "sudo systemctl restart alai-telegram-agent.service" - Verify daemon active:
ssh -i ~/.ssh/azure_alai [email protected] "sudo systemctl status alai-telegram-agent.service --no-pager" - Send test Telegram message (e.g., "Bok") and confirm bot replies with a greeting only — no task offer.
- Record new SHA-256 and timestamp in this runbook.
Scope: For prompt-only changes (intent tuning), only steps 1-7 are required. Code changes to comms-responder.js require a full service redeploy (not covered here).
7. Rollback
Backup artifact: /Users/makinja/system/prompts/extracted/comms-responder/main-system-prompt.md.bak-99290-20260505-213303
Created at deploy time: 2026-05-05 21:33:03 UTC. This is the pre-fix (biased) prompt.
- Locate backup on ANVIL:
ls /Users/makinja/system/prompts/extracted/comms-responder/*.bak* - Restore:
cp /Users/makinja/system/prompts/extracted/comms-responder/main-system-prompt.md.bak-99290-20260505-213303 /Users/makinja/system/prompts/extracted/comms-responder/main-system-prompt.md - Verify restored file SHA-256 differs from
33fc181...b5a2. - Re-deploy to VM (Section 6, steps 3-6).
- Open a new MC task documenting the regression cause.
Warning: Rollback restores the task-creation bias. Only roll back if the new classifier causes explicit task-create messages (TC-04, TC-07, TC-10) to fail. Verify those three test cases pass before accepting rollback as stable.
8. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Bot offers task creation for greetings or chitchat | Prompt reverted or not deployed to VM | Verify SHA-256 on VM matches 33fc181...b5a2. Re-deploy per Section 6. |
| Explicit "Kreiraj task" does NOT create a task | Classifier too tight or parseAndExecuteActions() failing | Run TC-04 live test. Check journalctl -u alai-telegram-agent.service -n 50 on VM for parse errors. |
| Daemon not running on VM | Service crash, OOM, or failed deploy | sudo systemctl status alai-telegram-agent.service then sudo systemctl restart alai-telegram-agent.service |
| Bot not responding at all | Daemon stopped, Telegram token invalid, or network issue | Check daemon status. Verify Telegram bot token in VM environment. Check VM network connectivity. |
| Wrong intent classified (e.g., question treated as status-query) | Ambiguous phrasing at classifier boundary | Add explicit example to the relevant NO/YES row in Section 2 of main-system-prompt.md. Re-test with test suite. |
| MC task created with wrong priority | No priority pattern in prompt examples | Check TC-10. Add "prioritet H/M/L" example to task-create YES examples in prompt. |
VM log access:
ssh -i ~/.ssh/azure_alai [email protected] "journalctl -u alai-telegram-agent.service -n 100 --no-pager"
Evidence files (MC #99290):
/tmp/99290-evidence/audit.md— root cause analysis/tmp/99290-evidence/test-cases.js— 10-pattern test suite/tmp/99290-evidence/regression.md— regression evidence (7/7 PASS)