From 994749e4b82f2a00e624a0ced5d4c6e517fda79d Mon Sep 17 00:00:00 2001 From: Rodrigo Ipince Date: Mon, 10 Nov 2025 19:09:22 -0500 Subject: [PATCH 1/2] [aisdk] Allow passing of provider metadata in tool definitions --- aisdk/ai/api/llm_tool.go | 7 ++++++- .../provider/openai/internal/codec/encode_tools.go | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/aisdk/ai/api/llm_tool.go b/aisdk/ai/api/llm_tool.go index c2252ac3..e767fb50 100644 --- a/aisdk/ai/api/llm_tool.go +++ b/aisdk/ai/api/llm_tool.go @@ -30,7 +30,7 @@ type ToolDefinition interface { } // For the equivalent of ToolDefinition in MCP, see the Tool struct in: -// https://github.com/modelcontextprotocol/go-sdk/blob/main/mcp/protocol.go#L854 +// https://github.com/modelcontextprotocol/go-sdk/blob/main/mcp/protocol.go#L901 // FunctionTool represents a tool that has a name, description, and set of input arguments. // Note: this is not the user-facing tool definition. The AI SDK methods will @@ -47,6 +47,11 @@ type FunctionTool struct { // the tool's input requirements and provide matching suggestions. // InputSchema should be defined using a JSON schema. InputSchema *jsonschema.Schema `json:"input_schema,omitzero"` + + // ProviderMetadata contains additional provider-specific metadata. + // They are passed through to the provider from the AI SDK and enable + // provider-specific functionality that can be fully encapsulated in the provider. + ProviderMetadata *ProviderMetadata `json:"provider_metadata,omitzero"` } var _ ToolDefinition = &FunctionTool{} diff --git a/aisdk/ai/provider/openai/internal/codec/encode_tools.go b/aisdk/ai/provider/openai/internal/codec/encode_tools.go index 24a7d3e4..d747ef87 100644 --- a/aisdk/ai/provider/openai/internal/codec/encode_tools.go +++ b/aisdk/ai/provider/openai/internal/codec/encode_tools.go @@ -93,11 +93,21 @@ func encodeFunctionTool(tool api.FunctionTool) (*responses.ToolUnionParam, []api return nil, nil, fmt.Errorf("failed to convert tool parameters: %w", err) } + strict := true // Default to true + if tool.ProviderMetadata != nil { + fmt.Println("provider metadata: ", tool.ProviderMetadata) + if metadata, ok := tool.ProviderMetadata.Get(ProviderName); ok { + metadata := metadata.(Metadata) + if metadata.StrictSchemas != nil { + strict = *metadata.StrictSchemas + } + } + } + result := responses.ToolParamOfFunction( name, props, - // TODO: allow passing the strict flag to the function - true, // strict mode enabled + strict, ) // Add description if provided From fa61e3e023b9865c2c0b91760e26b31f14e613d5 Mon Sep 17 00:00:00 2001 From: Rodrigo Ipince Date: Thu, 13 Nov 2025 15:51:40 -0500 Subject: [PATCH 2/2] use GetMetadata func --- aisdk/ai/api/llm_tool.go | 3 +++ .../ai/provider/openai/internal/codec/encode_tools.go | 11 +++-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/aisdk/ai/api/llm_tool.go b/aisdk/ai/api/llm_tool.go index e767fb50..04fd4929 100644 --- a/aisdk/ai/api/llm_tool.go +++ b/aisdk/ai/api/llm_tool.go @@ -62,6 +62,9 @@ func (t *FunctionTool) Type() string { return "function" } // isToolDefinition is a marker method to satisfy the ToolDefinition interface func (t *FunctionTool) isToolDefinition() bool { return true } +// GetProviderMetadata returns the provider-specific metadata for the function tool +func (t FunctionTool) GetProviderMetadata() *ProviderMetadata { return t.ProviderMetadata } + // FunctionTool JSON marshaling - automatically includes "type" field func (t *FunctionTool) MarshalJSON() ([]byte, error) { type Alias FunctionTool diff --git a/aisdk/ai/provider/openai/internal/codec/encode_tools.go b/aisdk/ai/provider/openai/internal/codec/encode_tools.go index d747ef87..5fcf1684 100644 --- a/aisdk/ai/provider/openai/internal/codec/encode_tools.go +++ b/aisdk/ai/provider/openai/internal/codec/encode_tools.go @@ -94,14 +94,9 @@ func encodeFunctionTool(tool api.FunctionTool) (*responses.ToolUnionParam, []api } strict := true // Default to true - if tool.ProviderMetadata != nil { - fmt.Println("provider metadata: ", tool.ProviderMetadata) - if metadata, ok := tool.ProviderMetadata.Get(ProviderName); ok { - metadata := metadata.(Metadata) - if metadata.StrictSchemas != nil { - strict = *metadata.StrictSchemas - } - } + md := GetMetadata(tool) + if md != nil && md.StrictSchemas != nil { + strict = *md.StrictSchemas } result := responses.ToolParamOfFunction(