feat(assistant): surface confirmed tool results via a host renderer (fix lost API key)#179
Conversation
…fix lost API key A confirmed create_api_key returns its one-time secret in output.key, but the client dropped it: describeOutcome read only the prefix and told the user to "copy it from the API Keys page" — impossible, since a key's secret is shown only once at creation. Retain a confirmed tool's output on the resolving status message and render it prominently via a new host `renderConfirmedResult` slot (threaded through AssistantDock/Panel/transcript, mirroring toolRenderers), so a host can show a one-time reveal card. Correct the create_api_key status text. The secret lives only in the in-memory transcript (never cached, never sent back to the model), so it is shown once and gone on reload — matching the dedicated create-key page. Unlike toolRenderers' collapsed detail, the result card is expanded so a one-time secret is visible without a click.
This comment has been minimized.
This comment has been minimized.
renderConfirmedResult returns null for a tool the host doesn't render a card for; the transcript still wrapped that null in `<div class="mt-3">`, leaving an empty spacer under every other confirmed tool's status line. Compute the node first and only wrap when it is non-null.
🤖 AI Code Review (ensemble)SummaryThe PR successfully threads confirmed tool outputs (like one-time API keys) through the assistant transcript via a host-supplied renderer, keeping the visible status text free of secrets. The implementation is solid and well-tested, but there is a minor rendering contract bug where valid falsy React nodes are dropped due to truthiness checks. Issues Found1 total — 0 P1 (blocking) · 1 P2 (should fix) · 0 P3 (nice to have)
|
Problem
When the platform assistant creates an API key, the user never gets the secret. The server returns it once in the confirm response's
output.key, but the client dropped it: on confirm,describeOutcome("create_api_key")read only theprefix, discardedoutput.key, and told the user to "copy it from the API Keys page" — impossible, since a key's secret is shown only once at creation and is never re-displayed there.useAssistantChat.confirm()also discarded the wholeoutput.Solution
Add a generic seam for rendering a confirmed tool's result, then let the host draw it:
useAssistantChat.confirm()retains a clean-success tool'soutputon the resolvingstatusmessage as a newConfirmedResult { name, output, args }.adaptTranscriptsurfaces it (keyed by the system message id) andAssistantTranscriptrenders it through a new host proprenderConfirmedResult, threadedAssistantDock → AssistantPanel → transcriptexactly liketoolRenderers.toolRenderers(collapsed tool-chip detail), the confirmed-result card renders expanded, so a one-time secret is visible without a click.create_api_keystatus line — no more "copy it from the API Keys page".The package stays domain-agnostic about the result UI: the host (platform-web) owns the actual reveal card.
Security
The retained
outputmay carry a one-time secret. It lives only in the in-memory transcript: the transcript is deliberately never cached (persistence.tsstores onlythreadId/model), reload rehydrates only user/assistant text, and a chat request (ChatRequest) carries only the new message — so the secret is never persisted and never sent back to the model. Shown once, gone on reload, matching the dedicated create-key page. A confirmed result never becomes atool-role message fed to the model.Tests
New/updated unit tests: corrected
describeOutcometext (no "API Keys page", secret never in the status line);confirm()retainsoutputon the resolved message while keeping the secret out of every message's text;adaptTranscriptsurfaces the result;AssistantTranscriptrenders the host card end-to-end and degrades to just the status line when no renderer is supplied. Full assistant suite: 254/254 green.Consumer
products/platform/web(tangle-network/agent-dev-container) consumesrenderConfirmedResultto show the one-time API-key reveal card, resolving agent-dev-container#3352. That consumer PR must pin the version this releases as.