Files
Linux_post_install/AgentsReport/builder/2026-08-27_telegram-ai-prefix.md
T
Your Name 06a05f0567
gates / consistency-and-conventions (push) Successful in 1m24s
ai continue ...
2026-09-04 11:09:21 -04:00

98 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Builder Report — Configurable AI-Bridge Trigger Word for the Telegram Listener
**Date:** 2026-08-27
**Status:** COMPLETE — implemented, verified, committed (`e6fa0a4`), pushed
---
## TL;DR
- **Request:** make the Telegram listener's `ai ` → Gemini bridge prefix configurable ("like communication telegram-listener prefix").
- **Change:** new `TELEGRAM_AI_PREFIX` config (default `ai`) + new `prefix` verb on the listener; live (per-message) reload like the command map; also editable via `pos config telegram`.
- **Files:** `bin/pos-communication-telegram-listener` 566→623, `bin/pos-communication-telegram-sender` (config-scope field), `completions/pos.bash` (regen), `DOC/AGENT_Context_Project.md` (regen filetable row), `DOC/POS.md`, `DOC/howto/ai.md`, `AGENT_TODO.md`.
- **Verification:** function-level routing harness (green), CLI verb tests, dispatch smoke via `pos`, `pos config telegram` render, gates `0 FAIL, 0 WARN`.
- **Commit:** `e6fa0a4` — pushed (`4306a53..e6fa0a4`).
[DONE]
---
## 1. Design
- **Config seam:** `TELEGRAM_AI_PREFIX` in `telegram.env` (shared by sender + listener). The listener already had a generic `load_config`; the key needs no code to load. Added to the `telegram` `# POS_CONFIG:` scope (in the sender's header, which owns that scope) so `pos config telegram` renders/edits it — registry-driven, no config-ui code.
- **CLI verb:** `pos communication telegram listener prefix` → shows current word; `prefix <word>` → validates `[A-Za-z0-9][A-Za-z0-9_-]*` (one word, no spaces/pattern metachars, no leading `-` to avoid flag ambiguity), writes `TELEGRAM_AI_PREFIX=` to `telegram.env` (chmod 600, mktemp+mv, `grep -vE` old line). Registered via `# POS_SUBCMDS: prefix` → completions regenerate.
- **Hot reload:** like the command map (re-read per message), a new `ai_bridge_prefix()` reads `telegram.env` per message. Precedence: file > env var from `load_config` (daemon start) > default `ai`. No daemon restart needed after `prefix <word>`.
- **Matching:** literal, case-insensitive prefix followed by whitespace. `case` patterns cannot express "literal word + one space + case-insensitive", so the handler uses a scoped `shopt -s nocasematch` + quoted-literal `=~`: `^"$prefix"[[:space:]](.*)$` (quoted variable = literal; nocasematch covers `AI`/`Ai`/custom `BoT`…). Unset immediately to keep the rest of the handler case-sensitive.
- **Preserved behavior:** bare `ai` (no trailing space) never matched the original `^[Aa][Ii][[:space:]]` regex → still falls through to "Unknown command". `ai /reset` (or `<prefix> /reset`) clears the session. Usage/`Unknown command`/log lines now interpolate the actual prefix.
[DONE]
---
## 2. Files Changed
| File | Change |
|------|--------|
| `bin/pos-communication-telegram-listener` | `prefix_cmd()` (show/set/validate/write), `ai_bridge_prefix()` (hot-reload resolver), `handle_message` uses `$prefix` with scoped nocasematch + literal `=~`, `--status` shows `ai prefix:`, usage() documents `prefix`, `# POS_SUBCMDS: prefix`, updated header comments |
| `bin/pos-communication-telegram-sender` | `# POS_CONFIG:` telegram scope + `TELEGRAM_AI_PREFIX=:AI-bridge trigger word in the telegram listener (default ai)::ai` |
| `completions/pos.bash` | regen: `_pos_subcmds[communication-telegram-listener]="prefix"` |
| `DOC/AGENT_Context_Project.md` | regen filetable: listener row 566→623 |
| `DOC/POS.md` | listener table: two `prefix` rows; paragraph now says `<prefix>` (default `ai `) configurable via verb/config; corrected stale claim that AI errors reply "plus a `pos config ai` hint" — code replies `AI error: …` only |
| `DOC/howto/ai.md` | Telegram section: trigger word configurable, `<prefix> /reset`, reply-context wording; troubleshooting points at `prefix` verb |
| `AGENT_TODO.md` | dated Done entry |
[DONE]
---
## 3. Tests Performed
### Routing harness — `/tmp/ai_prefix_routing_test.sh`
Extracts the listener's real functions (`handle_message` + deps) via `sed`, routes messages through them with a PATH-stub `pos` (fixed: `timeout pos …` runs a child process, so a bash-function stub is invisible) and a stub `reply`.
| Case | Result |
|------|--------|
| `ai hello` → gemini ask (`--session telegram-123 --system … hello`), answer replied | ✅ |
| `AI Hello` → routed, prompt kept (case-insensitive) | ✅ |
| `ai` (no space) → **Unknown command** (preserved edge), no ask | ✅ |
| `ai ` (trailing space) → Usage reply | ✅ |
| `ai /reset``pos ai gemini sessions reset telegram-123`, "Memory cleared." | ✅ |
| `hello` → Unknown command (not ai-routed) | ✅ |
| `TELEGRAM_AI_PREFIX=bot`: `bot hi` → routed; `BOT Hi` → routed; `ai hi` → Unknown command | ✅ |
| `bot /reset` → sessions reset | ✅ |
| var removed → `ai back` routed again (hot-reload fallback) | ✅ |
### CLI verb — real script, temp CONFIG_DIR
| Test | Result |
|------|--------|
| `prefix` (no arg) → `AI bridge prefix: ai` + usage hint | ✅ |
| `prefix bot` → writes `TELEGRAM_AI_PREFIX=bot` to telegram.env, rc 0 | ✅ |
| `prefix` after set → `AI bridge prefix: bot` | ✅ |
| `prefix 'a b'` and `prefix 'a.b'` → rc 1, validation error | ✅ |
| `prefix 1ok` → accepted (leading digit allowed) | ✅ |
| `--status``ai prefix: <current>` | ✅ |
| `prefix ai` → back to default | ✅ |
### Dispatch + config UI
- `pos communication telegram listener prefix` and flat `pos communication telegram-listener prefix` both show the current prefix (repo `bin/pos` on PATH). ✅
- `pos config telegram` (temp dir) renders `TELEGRAM_AI_PREFIX` with its description. ✅
### Gates
`bash -n` ×2 · `make gen` idempotent · `make check` OK · `make lint` 0 FAIL / 0 WARN. ✅
[DONE]
---
## 4. Notes / Remaining Risks
- **Matrix listener untouched** — it has its own hard-coded `ai …` bridge (session `matrix-<room>`); the same treatment is a possible follow-up if wanted.
- The daemon still loads `TELEGRAM_BOT_TOKEN`/`TELEGRAM_CHAT_ID` once at start (unchanged); only the prefix hot-reloads.
- A prefix change applies to ALL chats the listener serves (there is one owner chat by design).
- Literal prefix matching means a prefix containing regex metacharacters would be matched literally (quoted), but validation restricts to word chars for predictability.
[DONE]
---
**Status: COMPLETE.** The `ai ` trigger is now `TELEGRAM_AI_PREFIX` (default `ai`), configurable via `pos communication telegram listener prefix <word>` or `pos config telegram`, applied live.