Skip to content

Carry additionalProperties through the Anthropic tool input_schema so it matches functool strict validation - #724

Open
PratikDhanave (PratikDhanave) wants to merge 4 commits into
microsoft:mainfrom
PratikDhanaveFork:carry-additionalproperties-anthropic-schema
Open

Carry additionalProperties through the Anthropic tool input_schema so it matches functool strict validation#724
PratikDhanave (PratikDhanave) wants to merge 4 commits into
microsoft:mainfrom
PratikDhanaveFork:carry-additionalproperties-anthropic-schema

Conversation

@PratikDhanave

Copy link
Copy Markdown
Contributor

What

The Anthropic provider builds anthropic.ToolInputSchemaParam from a func tool's schema by copying only the properties and required keywords and discarding everything else. In particular it drops additionalProperties:false, which functool's strict schema always emits.

This change copies the remaining schema keywords into ToolInputSchemaParam.ExtraFields (which the anthropic-sdk-go marshals via MarshalWithExtras), so the model-facing schema stays in sync with the Go-side validation.

Why

funcTool.Call runs handler -> inputFormat.Unmarshal -> applySchema -> validate -> resolved.Validate, and the resolved schema rejects extra properties. Because the Anthropic path told the model nothing about additionalProperties, a hallucinated extra argument would pass the model but then fail functool validation on the Go side — an asymmetry that only affected Anthropic.

This restores cross-SDK parity: the OpenAI provider forwards the whole schema map (schemaToMap returns the full map) and the Gemini provider sets decl.ParametersJsonSchema = schema. Only Anthropic was stripping keywords. Matching the other providers keeps behavior aligned with the .NET/Python semantics where the declared tool schema and the validated schema are the same.

How it is tested

Added TestToolInputSchemaCarriesAdditionalProperties in agent_test.go. It builds a tool via functool.MustNew over a struct argument, runs the agent through the existing fake-transport harness, captures the request body, and asserts tools[0].input_schema.additionalProperties == false. The test fails before the fix (keyword omitted) and passes after.

Copilot AI review requested due to automatic review settings July 24, 2026 03:19
@PratikDhanave
PratikDhanave (PratikDhanave) requested a review from a team as a code owner July 24, 2026 03:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Anthropic provider’s tool schema construction to preserve full JSON Schema semantics (notably additionalProperties: false) so the schema sent to the model matches the stricter Go-side functool validation behavior, aligning Anthropic with the existing OpenAI/Gemini providers.

Changes:

  • Forward non-properties/required JSON Schema keywords into anthropic.ToolInputSchemaParam.ExtraFields so they are included in the serialized input_schema.
  • Add a regression test that captures the outbound Anthropic request and asserts tools[0].input_schema.additionalProperties == false.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
provider/anthropicprovider/agent.go Preserves additional JSON Schema keywords by copying them into ToolInputSchemaParam.ExtraFields when building Anthropic tool params.
provider/anthropicprovider/agent_test.go Adds a request-capture test asserting additionalProperties: false is present in the tool input_schema.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions github-actions Bot added the parity-approved Go API consistency review found no parity issues label Jul 24, 2026
@github-actions

This comment has been minimized.

The Anthropic provider built ToolInputSchemaParam from only the schema's
properties and required keywords, discarding additionalProperties:false that
functool's strict schema emits. funcTool.Call validates decoded arguments
against the resolved schema, so a hallucinated extra argument passed the model
but was rejected Go-side. Carry the remaining schema keywords through
ExtraFields so the model-facing schema matches functool validation, mirroring
the OpenAI and Gemini providers which forward the full schema.
@PratikDhanave
PratikDhanave (PratikDhanave) force-pushed the carry-additionalproperties-anthropic-schema branch from af493ea to f118b3d Compare July 24, 2026 09:30
@github-actions

This comment has been minimized.

# Conflicts:
#	provider/anthropicprovider/agent_test.go
@github-actions

This comment has been minimized.

# Conflicts:
#	provider/anthropicprovider/agent_test.go
@github-actions github-actions Bot added area:provider Changes files in the provider area area:provider/anthropic Changes files in the provider / anthropic area size:medium At most 100 changed lines across at most 5 files pending-auto-risk Automatic risk classification is in progress labels Aug 20, 2026
@github-actions

This comment has been minimized.

@github-actions github-actions Bot added failed-auto-risk Automatic risk classification was inconclusive or failed and removed pending-auto-risk Automatic risk classification is in progress labels Aug 20, 2026
# Conflicts:
#	provider/anthropicprovider/agent_test.go
@github-actions github-actions Bot added pending-auto-risk Automatic risk classification is in progress and removed failed-auto-risk Automatic risk classification was inconclusive or failed labels Aug 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Parity Review — No Issues Found

This PR is a bug fix to the Anthropic provider's tool schema serialization (buildMessageParams). It carries remaining JSON Schema keywords (e.g. additionalProperties: false) through ExtraFields so the model-facing schema matches the schema that functool.Call validates against.

Public API impact: No exported symbols were added, changed, or removed. The change is confined to internal implementation inside buildMessageParams.

Cross-SDK parity: The fix restores parity rather than diverging from it. Upstream .NET and Python semantics require that the declared tool schema and the server-side validated schema are the same object. The OpenAI and Gemini Go providers already forward the full schema map; this PR brings Anthropic into alignment. No equivalent gap was identified in the upstream .NET (Microsoft.Agents.AI.Anthropic) or Python Anthropic provider.

public-api-change label is not warranted. parity-approved label is appropriate and already present.

Generated by Go API Consistency Review Agent · sonnet46 · 21 AIC · ⌖ 4.99 AIC · ⊞ 6K ·

@github-actions github-actions Bot added risk:medium Contained production impact requiring normal review depth and removed pending-auto-risk Automatic risk classification is in progress labels Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:provider/anthropic Changes files in the provider / anthropic area area:provider Changes files in the provider area parity-approved Go API consistency review found no parity issues risk:medium Contained production impact requiring normal review depth size:medium At most 100 changed lines across at most 5 files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants