Repository navigation
fix(ai): undo strict-mode nulls before an approved tool check #2110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| '@tanstack/ai': patch | ||
| '@tanstack/openai-base': patch | ||
| --- | ||
|
|
||
| Undo strict-mode `null`s on tool arguments before the input check. An approved call whose history still has those `null`s now runs when `repairToolInput` is off. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2829,6 +2829,9 @@ class TextEngine< | |
| this.params.toolExecution, | ||
| this.params.repairToolInput, | ||
| this.toolCapabilities(), | ||
| this.toolInputNormalizer( | ||
| this.resolveExecutableTools(executablePendingCalls), | ||
| ), | ||
| ) | ||
|
|
||
| // Consume the async generator, yielding custom events and collecting the return value | ||
|
|
@@ -3079,6 +3082,9 @@ class TextEngine< | |
| this.params.toolExecution, | ||
| this.params.repairToolInput, | ||
| this.toolCapabilities(), | ||
| this.toolInputNormalizer( | ||
| this.resolveExecutableTools(executableToolCalls), | ||
| ), | ||
| ) | ||
|
|
||
| // Consume the async generator, yielding custom events and collecting the return value | ||
|
|
@@ -4193,9 +4199,23 @@ class TextEngine< | |
| undefined, | ||
| this.params.repairToolInput, | ||
| this.toolCapabilities(), | ||
| this.toolInputNormalizer(tools), | ||
| ) | ||
| } | ||
|
|
||
| /** | ||
| * The adapter's undo for provider-rewritten tool arguments, closed over | ||
| * the tools of this batch. Absent when the adapter does not rewrite them. | ||
| */ | ||
| private toolInputNormalizer( | ||
| tools: ReadonlyArray<AnyTool>, | ||
| ): ((toolName: string, input: unknown) => unknown) | undefined { | ||
| const normalize = this.adapter.normalizeToolInput | ||
| if (!normalize) return undefined | ||
| const adapter = this.adapter | ||
| return (toolName, input) => normalize.call(adapter, toolName, input, tools) | ||
|
Comment on lines
+4213
to
+4216
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| } | ||
|
|
||
| /** The run's capability readers, for each server tool's context. */ | ||
| private toolCapabilities(): Pick< | ||
| ToolExecutionContext, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,6 +48,7 @@ import type { | |
| ChatCompletionMessageParam, | ||
| } from 'openai/resources/chat/completions/completions' | ||
| import type { | ||
| AnyTool, | ||
| ContentPart, | ||
| DefaultMessageMetadataByModality, | ||
| Modality, | ||
|
|
@@ -822,6 +823,17 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter< | |
| return makeStructuredOutputCompatibleWithMap(schema, originalRequired) | ||
| } | ||
|
|
||
| /** Undo strict-mode nulls before the engine checks recorded arguments. */ | ||
| normalizeToolInput( | ||
| toolName: string, | ||
| input: unknown, | ||
| tools: ReadonlyArray<AnyTool> | undefined, | ||
| ): unknown { | ||
| return createToolInputNormalizer(tools, (schema, required) => | ||
| this.makeStructuredOutputCompatibleWithMap(schema, required), | ||
| )(toolName, input) | ||
|
Comment on lines
+832
to
+834
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| } | ||
|
|
||
| /** | ||
| * Applies provider-specific transformations for structured output compatibility. | ||
| * Override `makeStructuredOutputCompatibleWithMap` when you need the inverse map | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1309,6 +1309,17 @@ export abstract class OpenAIBaseResponsesTextAdapter< | |
| return makeStructuredOutputCompatibleWithMap(schema, originalRequired) | ||
| } | ||
|
|
||
| /** Undo strict-mode nulls before the engine checks recorded arguments. */ | ||
| normalizeToolInput( | ||
| toolName: string, | ||
| input: unknown, | ||
| tools: ReadonlyArray<AnyTool> | undefined, | ||
| ): unknown { | ||
| return createToolInputNormalizer(tools, (schema, required) => | ||
| this.makeStructuredOutputCompatibleWithMap(schema, required), | ||
| )(toolName, input) | ||
|
Comment on lines
+1313
to
+1320
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| } | ||
|
|
||
| /** | ||
| * Applies provider-specific transformations for structured output compatibility. | ||
| * Override `makeStructuredOutputCompatibleWithMap` when you need the inverse map | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script executed:
Repository: TanStack/ai
Length of output: 11691
Script executed:
Repository: TanStack/ai
Length of output: 36810
Script executed:
Repository: TanStack/ai
Length of output: 42810
Script executed:
Repository: TanStack/ai
Length of output: 27901
Script executed:
Repository: TanStack/ai
Length of output: 17380
Script executed:
Repository: TanStack/ai
Length of output: 17556
Limit the resume guarantee to supported adapters.
When history contains raw strict-mode arguments, Mistral can retain an optional
nullon resume. WithrepairToolInput: false, validation rejects the input and the approved tool does not run. Qualify the guarantee to exclude adapters that do not normalize resumed input.