Tool views
A tool-view replaces or enriches the visual representation of tool calls declared by the same app. Bind it with non-empty toolNames. Core passes one toolResult prop and preserves the same mount as the state changes.
contributes:
ui:
- id: calendar-result
kind: nativeModule
surface: tool-view
slot: chat.message.inline.below
toolNames: [readCalendar]
renderBeforeOutput: true
module:
entry: dist/ui/app.js
export: CalendarResultimport type { ToolResultSurfaceProps } from '@sota/platform';
type Input = { from: string; to: string };
type Output = { events: Array<{ id: string; title: string }> };
export function CalendarResult({ toolResult }: ToolResultSurfaceProps<Input, Output>) {
if (toolResult.state === 'input-streaming') return <p>Preparing…</p>;
if (toolResult.state === 'output-pending') return <p>Waiting for an action…</p>;
if (toolResult.state === 'output-error') return <p>{toolResult.errorText}</p>;
if (toolResult.state === 'output-denied') return <p>Permission denied.</p>;
if (toolResult.state !== 'output-available') return <p>Running…</p>;
return <p>{toolResult.result?.events.length ?? 0} events</p>;
}| State | Contract |
|---|---|
input-streaming | Best-effort partial unknown input; enabled only by renderBeforeOutput. |
input-available, approval states | Completed, schema-validated input. |
output-pending | The original tool call is deferred; deferred.operationId and opaque app data may be present. |
output-available | result is the app result after Core transport metadata is removed; output retains the raw host value. |
output-error, output-denied | Render failure or denial without assuming a result. |
execution identifies the app lane that produced the call. It is diagnostic context for the payload, not a request to load that producer's historical artifact.