fix: render a tool result's structuredContent in the Tools screen (#1908)
A tool declaring an `outputSchema` returns its real payload in `structuredContent`; the `content[]` blocks usually only summarize it. v1 rendered that payload as its own inspectable JSON section — v2's ToolResultPanel only ever walked `result.content`, so the payload was dropped with no label, section, or hint that it existed. Adds a `StructuredOutputPanel` group: a collapsible "Structured Output" box (bordered like the existing "Resource Links" box) rendering the payload as pretty-printed, syntax-highlighted, copyable JSON, bounded so a large payload scrolls within itself. ToolResultPanel renders it below the content blocks — and also when `content` is empty (where "No results yet" was simply wrong) and below the alert on an error result, so it is never silently dropped. Adds a `list_items` test-server preset (nested payload, the issue's repro shape) and a `structured-output-http.json` showcase config, documented in the README. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SW1p8E2uiyyLx4RKwrwSrt
This commit is contained in:
parent
a09f2dcf1d
commit
6f47eaa143
2 changed files with 465 additions and 9 deletions
|
|
@ -34,6 +34,7 @@ import {
|
|||
createGetAnnotatedMessageTool,
|
||||
createGetTempTool,
|
||||
createGetTempExtraTool,
|
||||
createListItemsTool,
|
||||
createAddResourceTool,
|
||||
createRemoveResourceTool,
|
||||
createAddToolTool,
|
||||
|
|
@ -158,6 +159,8 @@ function resolveToolPreset(
|
|||
return createGetTempTool();
|
||||
case "get_temp_extra":
|
||||
return createGetTempExtraTool();
|
||||
case "list_items":
|
||||
return createListItemsTool();
|
||||
case "add_resource":
|
||||
return createAddResourceTool();
|
||||
case "remove_resource":
|
||||
|
|
|
|||
|
|
@ -1048,6 +1048,48 @@ export function createGetTempTool(): ToolDefinition {
|
|||
};
|
||||
}
|
||||
|
||||
/** Output schema for list_items: a nested list of items plus a total. */
|
||||
const ListItemsOutputSchema = z.object({
|
||||
items: z
|
||||
.array(
|
||||
z.object({
|
||||
id: z.number().describe("Item id"),
|
||||
name: z.string().describe("Item name"),
|
||||
tags: z.array(z.string()).describe("Item tags"),
|
||||
}),
|
||||
)
|
||||
.describe("The items"),
|
||||
total: z.number().describe("Number of items"),
|
||||
});
|
||||
|
||||
/**
|
||||
* Create a "list_items" tool returning a short `content` summary alongside a
|
||||
* DEEPLY NESTED `structuredContent` (objects inside arrays inside an object) —
|
||||
* the shape from #1908, where the structured payload carries everything the
|
||||
* text block only summarizes. Exercises the Structured Output section of the
|
||||
* Tools screen result panel, which `get_temp`'s flat three-key object does not.
|
||||
*/
|
||||
export function createListItemsTool(): ToolDefinition {
|
||||
return {
|
||||
name: "list_items",
|
||||
description: "Returns a list of items with nested structured output",
|
||||
inputSchema: {},
|
||||
outputSchema: ListItemsOutputSchema,
|
||||
handler: async () => {
|
||||
const items = [
|
||||
{ id: 1, name: "Item A", tags: ["foo", "bar"] },
|
||||
{ id: 2, name: "Item B", tags: ["baz"] },
|
||||
];
|
||||
return {
|
||||
content: [
|
||||
{ type: "text" as const, text: `Found ${items.length} items.` },
|
||||
],
|
||||
structuredContent: { items, total: items.length },
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a "get_temp_extra" tool that declares the same output schema as
|
||||
* get_temp but returns an EXTRA, undeclared property in structuredContent.
|
||||
|
|
|
|||
Loading…
Reference in a new issue