feat(ag-ui): tool views — render frontend components for tool calls via the views registry#600
Merged
Conversation
Design for PR-A: a chat-lib capability that renders a frontend component
for a tool call by reusing the existing `views` registry. A tool call
whose name matches a `views` key is bridged into a synthetic one-element
render spec ({ root: name, elements: { [name]: { type: name, props } } })
and rendered through the existing render-spec pipeline; matched names are
auto-excluded from the default tool card. Ships the `ag-ui/tool-views`
example (ports 4322/5322) exercising it with a weather_card tool.
PR-B (json-render + a2ui backend-spec examples) is a separate spec.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Task-by-task plan for PR-A: extract resolveMessageToolCalls shared util, add ChatToolViewsComponent (synthetic-spec bridge reusing the views registry), wire it into the chat composition, and ship the ag-ui/tool-views example (weather_card tool, ports 4322/5322) with backend, frontend, e2e fixture, and full registry/manifest wiring. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extracts the per-message tool-call scoping logic from ChatToolCallsComponent.toolCalls into a standalone resolveMessageToolCalls function so ChatToolViewsComponent (Task 2) can reuse the exact same scoping logic without duplication. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… manifest) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sageId The reducer reduced TOOL_CALL_START into the toolCalls signal but never linked the call to a Message, so the chat lib's per-message tool-call resolution (chat-tool-calls / chat-tool-views) returned nothing for AG-UI tool calls. ag-ui-langgraph emits parentMessageId on every tool call; attach the toolCallId to that assistant message (creating the slot for a tool-call-only turn). Unblocks the ag-ui/tool-views example. Also fixes two related issues found during e2e diagnosis: - MESSAGES_SNAPSHOT: bridge assistant toolCalls (AG-UI wire shape) to toolCallIds so resolveMessageToolCalls works after the snapshot replaces the streamed message list; merge snapshot-only tool calls into store. - TOOL_CALL_RESULT: parse JSON string content (ag_ui_langgraph normalises all tool results to strings) so chat-tool-views can spread result props onto the registered view component. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…nto claude/ag-ui-tool-based-genui
blove
added a commit
that referenced
this pull request
Jun 7, 2026
…t rule (#607) The chat-tool-views spec's fixture component used selector 'test-weather-card' (added in #600), which fails @angular-eslint/component-selector (must start with 'chat'/'a2ui'). Since the Library CI job lints all libs, this broke chat:lint on main and blocked every PR. Rename to 'chat-test-weather-card' (4 occurrences, test-only, zero runtime impact). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Summary
Adds AG-UI Tool Views: a chat-lib capability that renders a frontend component for a tool call by reusing the existing
viewsregistry. When a tool call'snamematches aviewskey, the chat composition bridges it into a synthetic one-element render spec ({ root: name, elements: { [name]: { type: name, props: { ...args, ...result, status } } } }) and renders it through the existing render-spec pipeline. Matched tool names are auto-excluded from the default tool card. No new public input, no change toRenderSpecComponent/RenderElementComponent.Ships a cockpit example
ag-ui/tool-views(aweather_cardtool →WeatherCardComponent) and the AG-UI adapter fix needed to make per-message tool-call resolution work.Lib capability (
@threadplane/chat)resolveMessageToolCallsshared util fromChatToolCallsComponent(behavior-identical).ChatToolViewsComponentprimitive (synthetic-spec bridge); progressive + status-aware rendering (args while running, merged result on completion,statuspassthrough).ChatComponent;excludedToolNamesunions GenUI dispatcher names + registered view names so a view tool never also renders the default card. Exported from public API.AG-UI adapter fix (
@threadplane/ag-ui) — discovered via e2eThe reducer reduced
TOOL_CALL_*into atoolCallssignal but never linked calls to aMessage, so per-message resolution returned nothing for AG-UI tool calls. Fixed three reducer paths:TOOL_CALL_STARTlinks the call to its parent assistant message viaparentMessageId(creating a slot for tool-call-only turns).MESSAGES_SNAPSHOTbridges rawtoolCalls[]→toolCallIds, drops the raw key, and merges snapshot-only calls intostore.toolCalls(deduped).TOOL_CALL_RESULTJSON-parses string content (with fallback) so result props spread cleanly.Existing
streaming(1) andinterrupts(3) AG-UI e2es confirmed non-regressed.Example
ag-ui/tool-views(ports 4322/5322)weather_cardtool returning deterministic JSON; served viaag-ui-langgraph.WeatherCardComponentregistered asviews({ weather_card: WeatherCardComponent }).cockpit/ports.mjs, capability-registry, route-resolution, cockpit-registry manifest.Test Plan
nx test chat/nx test ag-uigreen (incl. new util, primitive, and reducer specs)nx test cockpit --run cockpit-e2e-wiring route-resolution+nx test cockpit-registrygreennx build chatgreennx e2e cockpit-ag-ui-tool-views-angular— weather card renders ("San Francisco", "68")nx e2e cockpit-ag-ui-streaming-angular+cockpit-ag-ui-interrupts-angular— no regression🤖 Generated with Claude Code