fix(gateway,telegram): wire clarify_callback through gateway agent and Telegram adapter#21517
Closed
Tranquil-Flow wants to merge 1 commit into
Closed
Conversation
…d Telegram adapter In the messaging gateway, AIAgent.clarify_callback was never set, so the clarify tool always returned "Clarify tool is not available in this execution context." for users on Telegram. CLI and TUI paths set this callback during agent construction; gateway/run.py was missing the equivalent wiring. Bridges the sync callback contract (question, choices) -> str into an async send_clarify_prompt coroutine on the platform adapter. The agent thread parks on a threading.Event with a 120s timeout; the inline-button click handler in the adapter resolves the event with the chosen string. The bridge degrades gracefully: adapters that don't define send_clarify_prompt / _clarify_state return "" so the agent falls back to its own judgement instead of crashing. Only the Telegram adapter gets the inline-keyboard primitives in this PR. Closes NousResearch#21032
This was referenced May 12, 2026
Contributor
Author
|
Closing — clarify in gateway/Telegram mode now works on main via a different architecture. Main has a dedicated
The protocol shape differs from this PR's ( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
After upgrade, every clarify call from the agent in gateway/Telegram mode returned
{"error": "Clarify tool is not available in this execution context."}. Inline keyboard buttons never appeared. The tool worked in CLI and TUI — gateway-only regression.Root cause:
AIAgentrequiresclarify_callbackto wire the tool to the platform. CLI (hermes_cli/main.py) and TUI (tui_gateway/server.py) both pass it during agent construction. The messaging gateway path ingateway/run.pywas never assigning it, soagent.clarify_callbackstayedNoneandtools/clarify_tool.py:57returned the not-available error. Additionally, the Telegram adapter had none of the primitives needed to actually display the choices (no_clarify_state, nosend_clarify_prompt, noclarify:callback handler).This PR:
agent.clarify_callbackon the messaging gateway path, right next to the existingagent.status_callback = _status_callback_syncline. The bridge closure (_clarify_callback_sync) posts an asyncsend_clarify_promptcoroutine on the running loop and parks on athreading.Event(120s timeout, matching CLI behaviour).send_clarify_prompt,_clarify_state, and theclarify:id:idx|skipcallback handler onTelegramAdapter._is_callback_user_authorizedhelper so unauthorized users in shared chats can't steer the waiting agent turn (security: same gate that already protects slash-confirm and update-prompt callbacks).send_clarify_prompt/_clarify_state. The bridge detects this and returns""so the clarify tool produces an empty user response on those platforms instead of crashing — same UX as before this PR for those adapters. Wiring them up is follow-up work.Related Issue
Closes #21032
Type of Change
Changes Made
gateway/run.py— added_clarify_callback_syncbridge closure (sync→async viarun_coroutine_threadsafe, 120s wait, threading.Event resolution); assignedagent.clarify_callback = _clarify_callback_syncnext to the existingagent.status_callback = _status_callback_sync.gateway/platforms/telegram.py— added_clarify_state: Dict[str, Dict[str, Any]]initializer; addedsend_clarify_prompt(...)method (inline keyboard with one button per choice + a Skip row, uses existing_metadata_thread_id/_message_thread_id_for_sendhelpers, button labels truncated to 60 chars,parse_mode=Nonefor the agent-supplied question); added theclarify:id:idx|skipbranch to_handle_callback_querywith an_is_callback_user_authorizedguard up front, before any state lookup.tests/gateway/test_telegram_clarify_buttons.py— new file. Adapter-side tests forsend_clarify_prompt(4 tests covering inline keyboard with choices, skip-only for open-ended, thread routing, not-connected guard) and the callback handler (5 tests including the authorization guard, choice resolution, skip behaviour, unknown id graceful response, invalid index rejection without resolving the event, no-clobber onea:/update_prompt:routes).tests/gateway/test_runner_clarify_callback.py— new file. End-to-end tests for the gateway closure: posts a coroutine on a real asyncio loop in a background thread, asserts blocking + resolution + cleanup; verifies graceful""return when the adapter lackssend_clarify_prompt; static guard on the wiring line ingateway/run.py.How to Test
python -m pytest tests/gateway/test_telegram_clarify_buttons.py tests/gateway/test_runner_clarify_callback.py -q→ 13 passed.python -m pytest tests/gateway/test_telegram_format.py tests/gateway/test_telegram_topic_*.py tests/gateway/test_telegram_caption*.py tests/gateway/test_telegram_approval*.py tests/gateway/test_telegram_clarify_buttons.py tests/gateway/test_runner_clarify_callback.py -q→ 161 passed.clarifytool. Without this PR, the agent receives the not-available error and proceeds without disambiguation. With this PR, an inline keyboard appears in Telegram; tapping a button resolves the agent's wait.Checklist
Code
fix(scope):,feat(scope):, etc.)send_message)Documentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/AScreenshots / Logs
Notes
send_clarify_prompt/_clarify_state. The bridge detects that and returns""for those (graceful degradation, same UX as before this PR). Wiring them up is follow-up work._is_callback_user_authorizedguard runs before any state lookup or mutation, so unauthorized users get a "not authorized" answer with no observable effect on the waiting agent turn. Pattern matches the existing slash-confirm and update-prompt callback flows.CLI_CONFIG["clarify"]["timeout"]).parse_mode=Nonefor the agent-supplied question text — agent prompts aren't trusted Markdown.