same tool, three provider shapes canonical tool (your code) Tool(name="get_weather", description="...", input_schema={...}, strict=True) one source of truth; translators emit provider-specific envelopes. OpenAI tools: [{ type: "function", function: { name, description, parameters: schema, strict: true } }] Anthropic tools: [{ name, description, input_schema: schema }] schema is the contract; no `strict` flag. Gemini tools: [{ functionDeclarations: [{ name, description, parameters: openapi }] }] OpenAPI 3.0 subset OpenAI response msg.tool_calls: [{ id: "call_abc123", type: "function", function: { name, arguments: "{json}" } }] Anthropic response content: [{ type: "tool_use", id: "toolu_xyz789", name, input: {...} // obj }] input is already parsed. Gemini response parts: [{ functionCall: { id: uuid, name, args: {...} } }] unique id in Gemini 3+ name/args semantics are identical across the three; envelope and id scheme differ.