fix(desktop): keep clarify prompts answerable - #47544
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for identifying a real blocked-input path. Current main still suppresses tool.start and tool.complete when tool progress is off (tui_gateway/server.py:3606, 3664), while Desktop needs a tool-call part to render ClarifyTool (apps/desktop/src/components/assistant-ui/thread/message-parts.tsx:35-37).
Problems
- The Desktop file changed by this PR was moved to
apps/desktop/src/app/session/hooks/use-message-stream/gateway-event.tsby51a710e57e; the change needs to be ported there. - The synthetic row is keyed with
requestId, but_block()creates that ID independently (tui_gateway/server.py:2034-2040) from the lifecycle callback’stool_call_id(tui_gateway/server.py:3594,3621). It cannot merge with the later real completion as the comment claims, so the synthetic pending row can remain alongside a separate settled row.
Suggested changes
- Preserve the narrow gateway lifecycle exception, but rework missed-start recovery to use an ID shared with the later completion (or carry that tool-call ID in
clarify.request), and cover that sequence in Desktop tests.
Automated hermes-sweeper review.
| // while the inline UI normally mounts from the earlier `tool.start` | ||
| // row. If that row was missed (stream reconnect / hydration race) the | ||
| // sidebar still shows "needs input" but there is nowhere to render | ||
| // choices. Upsert a stable pending clarify tool row from the request |
There was a problem hiding this comment.
requestId is generated independently by _block() (tui_gateway/server.py:2034-2040), while the actual tool.start/tool.complete use the agent's tool_call_id. These IDs cannot merge in upsertToolPart; after completion this synthetic pending row can remain beside a separate completed row. Use a shared lifecycle ID or carry the tool-call ID in clarify.request.
Attribution mapping for the salvaged #47544 commit.
|
Superseded by #69795 — salvaged with your commits (the Python half cherry-picked verbatim; the TS half re-authored onto the post-split |
…ol-progress off (#69795) * fix(desktop): keep clarify lifecycle when tool progress is off * fix(desktop): render clarify prompt from the request event Re-authored onto the current use-message-stream/gateway-event.ts (the original patched the pre-split use-message-stream.ts). When the tool.start row that normally mounts the inline clarify UI is missed (stream reconnect / hydration race), upsert a stable pending clarify tool row from clarify.request itself so the prompt stays answerable; a real tool.start/complete with the same request id merges rather than duplicates. Co-authored-by: 정수환 <centerid@naver.com> * chore(contributors): map centerid@naver.com -> lidises Attribution mapping for the salvaged #47544 commit. * fix(desktop): correlate clarify rows by question so hydration can't duplicate The hydrated row (from clarify.request's request_id) and the real tool.start row (the model's tool_call_id) have different ids, so id-only matching appended a second clarify card in the normal path (caught by the BLOCKING_CLARIFY e2e: 'question' resolved to 2 elements). Add 'question' to the tool match-value keys so a clarify upsert merges into the existing pending clarify row regardless of id (same request<->args correlation ClarifyToolPending already uses); when no row exists yet (reconnect/hydration) it still creates one. --------- Co-authored-by: 정수환 <centerid@naver.com>
…ol-progress off (NousResearch#69795) * fix(desktop): keep clarify lifecycle when tool progress is off * fix(desktop): render clarify prompt from the request event Re-authored onto the current use-message-stream/gateway-event.ts (the original patched the pre-split use-message-stream.ts). When the tool.start row that normally mounts the inline clarify UI is missed (stream reconnect / hydration race), upsert a stable pending clarify tool row from clarify.request itself so the prompt stays answerable; a real tool.start/complete with the same request id merges rather than duplicates. Co-authored-by: 정수환 <centerid@naver.com> * chore(contributors): map centerid@naver.com -> lidises Attribution mapping for the salvaged NousResearch#47544 commit. * fix(desktop): correlate clarify rows by question so hydration can't duplicate The hydrated row (from clarify.request's request_id) and the real tool.start row (the model's tool_call_id) have different ids, so id-only matching appended a second clarify card in the normal path (caught by the BLOCKING_CLARIFY e2e: 'question' resolved to 2 elements). Add 'question' to the tool match-value keys so a clarify upsert merges into the existing pending clarify row regardless of id (same request<->args correlation ClarifyToolPending already uses); when no row exists yet (reconnect/hydration) it still creates one. --------- Co-authored-by: 정수환 <centerid@naver.com>
Summary
clarifytool lifecycle events visible to Desktop even when tool progress is set tooff, so the interactive prompt can still render and resolve.clarify.requestwhen the earliertool.startrow was missed during reconnect/hydration.Why
Desktop can otherwise show that a session needs input while providing no answerable clarify prompt, leaving the backend blocked on
clarify.respond.Test plan
./.venv/bin/python -m pytest tests/test_tui_gateway_server.py::test_tui_clarify_lifecycle_events_emit_when_tool_progress_off tests/test_tui_gateway_server.py::test_tui_non_interactive_tool_lifecycle_stays_hidden_when_tool_progress_off -o 'addopts=' -qcd apps/desktop && npm run typecheck