ta
TanStack
OSS
ta
Pipelines
Nx runs
Insights
Compare tasks
Analytics
Sign in
Toggle Sidebar
ai
ai
Pipelines
feat(ai): check tool input after approval edits and middleware, just before it runs (#1750) * feat(ai): check tool input at the last moment, after approval edits and middleware * test(ai): fix the boundary client tool tests * test(ai): the subagent tool input is checked after middleware * test(ai): subagent schema errors also show the received arguments * fix(ai): keep returned client results and run tool hooks once at boundaries - A client result that comes back is kept as is. Checking the raw model input again dropped the real result when middleware had repaired it. - An afterTools boundary reuses the tool phase result, so onBeforeToolCall and the tool results do not run twice. - The boundary drains executeToolCalls through drainToolCallGenerator and passes the resume state; the hooks and resume state come from shared helpers. - The validation error shows the model's own arguments in the tool result only, so middleware-injected values do not reach the model or tracing. - Changeset, middleware docs, and args JSDoc corrected. * feat(ai): check JSON Schema and MCP tool input with @cfworker/json-schema (#1751) * feat(ai): validate JSON Schema tool input with @cfworker/json-schema * chore: keep one @google/genai copy for ai-vertex and ai-gemini * test(ai): the JSON Schema of a subagent tool checks background * fix(ai): keep the page URL out of a JSON Schema tool error A failed $ref included the validator base URI. In a browser that URI is the page, query included. * fix(ai): JSON Schema tool check accepts OpenAPI 3.0 and keeps data intact - Strip `format` only from schema positions, so a `format` key inside `const` or `enum` data still matches. - Convert boolean `exclusiveMinimum`/`exclusiveMaximum` per schema, so they work under any `$schema` and numeric bounds elsewhere still apply. - Support OpenAPI 3.0 `nullable: true`: null joins `type`/`enum`, and a nullable `$ref`/`allOf`/`anyOf`/`oneOf`/`not` schema is wrapped as `if: null, else: schema`. Local `$ref`s into a wrapped schema move with it. - Check an input with no JSON form as null, list at most 10 errors, and drop more wrapper errors (`if`, `$recursiveRef`, `additionalItems`, `unevaluatedItems`). - Read the first error line with `split('\n', 1)`, which type-checks under `noUncheckedIndexedAccess`. * feat(ai): repair common model mistakes in tool input, with chat({ repairToolInput }) (#1752) * feat(ai): repair common model mistakes in tool input before the final check * fix(ai): type the repair order list * test(ai): use an input the repair cannot fix in the subagent schema test * feat(ai): chat({ repairToolInput }) to turn off or replace the input repair false turns the built-in tool input repair off. A function replaces it: it gets { tool, toolCall, input, error } for an input that failed the check, and returns the input to check again, or undefined to send the validation error to the model. * feat(ai, adapters): keep the raw tool argument string for replay (#1753) * feat(ai, adapters): keep the raw tool argument string for replay * refactor(ai): one tool-argument reconcile helper, args sent once finishToolCallArguments replaces the three reconcile copies in ToolCallManager, TextEngine and StreamProcessor. TOOL_CALL_END now sends its arguments once, as metadata.tanstack.args reconciled to the input; in-process input is parsed back from it. Drops jsonInput and isToolInputJsonLossless. A null input no longer replaces the raw args. * fix(ai-bedrock, ai-gemini): replay malformed tool arguments as {} Malformed arguments now stay in the history next to their tool error. The Bedrock and Gemini Interactions history converters send them as {} instead of failing the request. * fix(ai-gemini): send the args snapshot only when no deltas stream The initial step.arguments snapshot went out as a TOOL_CALL_ARGS delta before the streamed deltas, so the deltas did not add up to the final arguments on the client. * refactor(adapters): always send args on TOOL_CALL_END Drop the redundant rawArgs guards and hasArguments flags. Core treats empty args the same as missing args. * test(ai): keep the JSON Schema check tests off the repair path The OpenAPI 3.0 and $ref tests from feat/json-schema-tool-input send inputs the repair now fixes (a null optional field, "3" for an integer). They check the schema alone, with repairToolInput: false. Adds a test that the repair walks a nullable schema, and restores the subagent 'yes' input. --------- Co-authored-by: Tom Beckenham <34339192+tombeckenham@users.noreply.github.com> * fix(ai): give held calls a result and keep child interrupts at boundaries - When the only call that waits for approval fails its input check, the calls that the batch gating held back now run, so each call has a result. - An approved client tool is sent to the client while another call waits for approval, as a plain client tool already was. - The validation error tells the model when an approval edit or middleware changed its arguments, so it does not retry the same valid call. - An afterTools boundary interrupt keeps the subagent interrupts of the tool phase. - Changeset and server tools docs: a bad approval edit is rejected when the run resumes. --------- Co-authored-by: Tom Beckenham <34339192+tombeckenham@users.noreply.github.com>
nx run-many --targets=build --exclude=examples/**,testing/**
⌘K
feat(ai): check tool input after approval edits and middleware, just before it runs (#1750)
Succeeded
in
2m 28s
Started
Linux
4 CPU cores
read-write
access token used
Copy command
nx run-many --targets=build --exclude=examples/**,testing/**
1786
a740f90
GitHub
Open on GitHub
Tasks
Resource Usage
ta
TanStack
OSS