Skip to content

Add agentic mode with MessageOrchestrator#22

Merged
RichardAtCT merged 3 commits intomainfrom
feature/agentic-mode
Feb 13, 2026
Merged

Add agentic mode with MessageOrchestrator#22
RichardAtCT merged 3 commits intomainfrom
feature/agentic-mode

Conversation

@RichardAtCT
Copy link
Owner

@RichardAtCT RichardAtCT commented Feb 13, 2026

Summary

  • Add AGENTIC_MODE env var (default: true) that switches the bot to a minimal conversational interface — 3 commands (/start, /new, /status), no inline keyboards, no follow-up suggestions. All other input goes straight to Claude.
  • New MessageOrchestrator replaces inline handler registration in core.py, routing to agentic or classic handlers based on mode. Classic mode behavior is fully unchanged.
  • Feature registry gates conversation enhancer, quick actions, and session export behind agentic_mode=false.

Test plan

  • 252 tests passing (11 new orchestrator tests)
  • Lint clean (flake8)
  • Manual test with AGENTIC_MODE=true: send messages, verify no buttons, Claude responds
  • Manual test with AGENTIC_MODE=false: verify full classic experience unchanged
  • Test /start, /new, /status in both modes
  • Test file upload in agentic mode

Follow-ups addressed

Closes #23
Closes #24

Introduce AGENTIC_MODE (default: true) that switches the bot to a
minimal conversational interface — 3 commands (/start, /new, /status),
no inline keyboards, no follow-up suggestions. Everything else goes
straight to Claude as a text passthrough.

MessageOrchestrator replaces inline handler registration in core.py,
routing to agentic or classic handlers based on mode. Classic mode
remains fully unchanged. Feature registry gates conversation enhancer,
quick actions, and session export behind agentic_mode=false.

252 tests passing.
@RichardAtCT
Copy link
Owner Author

PR Review
Reviewed head: bf98f601e2b0fac2347eeb7d193041665d3587a0

Summary

  • Nice refactor: moving mode-specific routing into MessageOrchestrator is a clean separation and makes core.py much slimmer.
  • Agentic mode behavior is implemented consistently (minimal commands, no keyboards, direct passthrough for text/file/photo).
  • Test coverage for registration and core agentic paths is solid for a first pass.

What looks good

  • src/bot/core.py now delegates command setup and handler wiring cleanly to one component.
  • src/bot/features/registry.py gates classic-only features in a straightforward way.
  • tests/unit/test_orchestrator.py covers the high-risk branch split (agentic vs classic) and key UX expectations.

Issues / questions

  1. [Blocker] src/bot/orchestrator.py (agentic_start) — Markdown parse risk from unescaped user names.
    user.first_name is interpolated into a parse_mode="Markdown" message. Names containing Markdown metacharacters (_, *, [, etc.) can break rendering or fail message send. Please escape user-provided text (or switch to plain text / MarkdownV2 with proper escaping).

  2. [Important] src/bot/orchestrator.py (_register_agentic_handlers, _agentic_callback) — callback handler is unscoped and catches all callback queries in agentic mode.
    This is likely survivable but can cause noisy UX and accidental interception of unrelated callback payloads. I opened a non-blocking issue to track hardening: Agentic mode: restrict callback handler to cd:* pattern #23

  3. [Important] src/bot/orchestrator.py (agentic_text) — audit logging marks failures as success.
    Current code logs success=True unconditionally after handling, including error paths. I opened a non-blocking issue: Agentic text handler logs failed runs as success #24

Suggested tests (if needed)

  • Add a test for /start with a first name containing Markdown metacharacters (e.g. A_B) to confirm safe rendering.
  • Add a callback registration/dispatch test proving only cd: payloads are handled in agentic mode.
  • Add a test that failed claude_integration.run_command yields audit_logger.log_command(..., success=False).

Verdict

  • ⚠️ Merge after fixes (blocker: Markdown escaping in agentic_start)

- Escape Markdown metacharacters in user first_name for agentic /start
  to prevent parse failures from names like A_B or C*D.
- Scope agentic callback handler to cd: pattern via CallbackQueryHandler's
  pattern parameter, preventing interception of unrelated payloads.
- Track success/failure in agentic_text and pass correct value to
  audit_logger.log_command (was always True, now False on exceptions).
- Add tests: Markdown escaping, callback pattern scoping, audit failure logging.

Closes #23, closes #24. 254 tests passing.
The relative path display showed ~/ for the approved directory root,
which looked like the OS home directory. Show the full path instead.
@RichardAtCT RichardAtCT merged commit 8ab153a into main Feb 13, 2026
1 check passed
@RichardAtCT RichardAtCT deleted the feature/agentic-mode branch February 13, 2026 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agentic text handler logs failed runs as success Agentic mode: restrict callback handler to cd:* pattern

1 participant