Repository navigation
[EPIC-D][LOU-D22] Tools carry their own inputSchema and execute; defineTool no longer wraps ai.tool() - #79
Merged
Merged
Conversation
…o longer wraps ai.tool()
ToolDescriptor gains optional canonical `inputSchema` (zod) and `execute`
fields. defineTool() sets both and builds the legacy ai v4 `.tool` object
({ description, parameters, execute }) by hand instead of calling ai's
tool(). Runtime reads of a tool's schema and execute go through
getToolInputSchema()/getToolExecute() (src/tools/toolContract.ts), which
prefer the canonical fields and fall back to tool.parameters/tool.execute:
argument validation, the provider ToolDefinition builder, the sandbox
guard, tool lookup, approval resume and the MCP server export.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bY29ibQgv3MDdjAbUT4YR
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.
What
ToolDescriptor(src/types/tool.ts) gains optionalinputSchema?: z.ZodTypeAnyandexecute?(args, ctx). They are documented as the canonical fields..tool(theaiv4Tool) is documented as legacy and kept for compatibility this release.defineTool()setsinputSchema(same schema asinput) andexecuteitself. It no longer importstoolfromai: it builds the legacy.toolobject{ description, parameters, execute }by hand, using the sameexecutefunction.DefinedTooltypesinputSchema: Sandexecute(args: z.output<S>, ctx): Promise<O>.src/tools/toolContract.ts:getToolInputSchema(desc)andgetToolExecute(desc)prefer the canonical fields and fall back totool.parameters/tool.execute. Every runtime read now goes through them:toolArgsValidation.ts: argument validationgenerateStep.tsbuildTools(): the providerToolDefinitionbuilder (one-line swap; the read lives only there)sandboxGuard.ts: executiontoolCallExecution.tsfindExecutableTool()resume.ts: the "tool not found" guard on approval resume (one-line swap; the read lives only there)tools/mcp/server/buildServer.ts: the MCP server exportAgentExecutor.tsis unchanged.[Unreleased] -> Addedentry. docs/api-overview.md: the tools section now describes the canonical fields, and argument validation now saysinputSchemainstead ofparameters.llms-full.txtregenerated.src/toolsfiles that still import fromaiafter this change (non-test):src/tools/defineTool.ts: type-onlyToolExecutionOptions, which D23 replacessrc/tools/built-in/currentDate.ts,dayName.ts,email.ts,http.ts,slack.ts,src/tools/mcp/McpToolLoader.ts: D24src/tools/built-in/github.ts,jira.ts: D25Why
aiv5+ renamedparameterstoinputSchema. Because the SDK readtool.parametersdirectly, every user tool and the SDK itself were tied toaiv4. With the SDK's own types as the source of truth, D23-D27 can swap theaiadapter without touching tool authors.Acceptance criteria
ToolDescriptorhas optionalinputSchema(zod 3) andexecuteat descriptor level. Both are documented as canonical, and.toolis documented as legacy.DefinedToolsetsinputSchemaandexecute, does not importtoolfromai, and still produces a v4-shaped.tool({ description, parameters, execute }).ToolRegistry, Agent Forge and existing callers are unchanged.DefineToolOptions.inputis kept. TheinputSchemaoption alias was not added: keeping inference typed forinput|inputSchemaand the validation messages correct costs more than ~10 lines.getToolInputSchema(). Execute reads go throughgetToolExecute(), including sandboxGuard..test-d.tspasses. A new case checks thatdefineTool(...).inputSchemais the input zod type and thatexecute's argument, context and return types are inferred.defineTooltool runs end-to-end withmockModel, withai.toolspied and asserted not calledai.tool()descriptor still validates and runssrc/toolsfiles that still importai(above).How verified
npx tsc --noEmit: no errorsnpm run lint:✖ 433 problems (0 errors, 433 warnings), the same warning count as mainnpm run test:types:Tests 20 passed (20),Type Errors no errorsnpx vitest run:Tests 2023 passed | 1 failed | 3 skipped (2027). The one failure differed between runs, was in unrelated code that depends on timing, and passed when re-run on its own:guardrails.test.tschild-process timeout (re-run: 23/23 passed)cloudflare.test.tswrangler dev(re-run: 15/15 passed)npm run test:coverage:Test Files 138 passed (138),Tests 2024 passed | 3 skipped (2027)npm run build && npm run build --workspace=packages/create-loushy-agent: both succeedednpm run docs:verify-snippets -- --skip-build:all 91 snippet(s) type-check against src/; 6 also run cleanlynpm run docs:llms:check: passednpm run fallow:✓ No issues found. The only duplication reported is an existing 15-line clone between AnthropicProvider and OpenAIProvider.Note for D24/D25:
github.ts(it disables out-of-scope tools by reassigningdescriptor.tool.execute) andsandboxFetch.tsrouteFetchThroughSandbox(it readsdescriptor.tool.execute) still work on.tool.execute. When those built-ins move todefineTool, they must override or read the canonicalexecuteinstead, or the disablement would be bypassed.🤖 Generated with Claude Code
https://claude.ai/code/session_016bY29ibQgv3MDdjAbUT4YR
Generated by Claude Code