3.9 KiB
Agent Note: Web skill tool row
Status: implemented
English | 中文
Problem
The Web transcript renders skill calls through the generic fallback row, so a loaded instruction set looks like an unknown tool call even though Skill is a first-class product concept. The generic row also exposes the JSON argument envelope beside the result, adding noise around the one identity users need: the loaded skill name.
Decision
ui-skill registers a component under the existing conversation.chat.toolview keyed slot with key skill. The component owns its row chrome from the public ToolRowProps contract, matching the independent registrant posture used by the Bash sample instead of importing conversation-private components.
The collapsed row uses a 16-pixel document-and-sparkle glyph and the Bash row's neutral hierarchy: tertiary glyph, secondary Skill title, caption separator, and tertiary skill name. Running, failed, and interrupted calls retain the transcript's shimmer, error dot and first-line summary, and warning dot semantics. A settled call expands through the whole summary row into a 260-pixel bounded Instructions card containing the exact durable result text; the existing trajectory Inspect handoff remains available below the card.
The row derives every visible value from the logged call/result slice. It reads the skill name from the recorded name argument and the instructions from durable result content, and never joins the current skill catalog for descriptions or provider metadata. Because a history page can contain a tool/result after its tool/call fell outside the window, the generic HistoryEntry envelope now carries the paired call's name, exact arguments JSON, and event time on result entries. The Host derives this transient annotation and the result render intent from the complete log; the runtime prefers an in-window call and otherwise materializes the same ToolResultNode.call and callTime from the annotation. An orphan result still has call: null, and a call-side render intent remains unavailable when its event is outside the page. The existing ACP skill-load recording is seeded through the real Web persistence and composition path for a keyless interaction and accessibility snapshot.
Alternatives considered
- Keep the generic tool row and add only a
skillcolor selector inui-conversation. This leaves the redundant input envelope and generic expanded body in place, and makes the conversation package own a domain-specific visual rule. - Add a new
skillvalue to the host tool render-intent union. The keyed client slot already identifies this tool; the cross-page fix belongs to the generic history pairing envelope used by every tool rather than a skill-specific presentation value. - Export the conversation package's private
ToolRowcomponent for reuse. Client packages intentionally expose contracts rather than cross-package components; exporting it would couple independent feature packages to conversation implementation details.
Consequences
ui-skill now depends on the public conversation toolview contract, locale and primitive packages, and React in addition to its reference-source dependencies. It owns a small copy of the disclosure-row chrome, so future global interaction changes must update this registrant alongside the Bash sample and conversation rows.
Cold replay stays deterministic across pagination and when the installed skill catalog changes, and the transcript remains compact until instructions are explicitly expanded. The generic pairing annotation also prevents other keyed tool rows and result presenters from changing identity at a page boundary without persisting duplicate data. The dedicated card intentionally shows the tool's complete framed output rather than extracting only <skill_instructions>, preserving exactly what reached the model and avoiding a second parser for the skill result format.