You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add Model.to_llm_tool method with multi-provider support #139
Add a convenience method to generate LLM tool/function specs directly from EasyTalk models, with support for multiple providers.
Proposed API
classGetWeatherincludeEasyTalk::Modeldefine_schemadotitle"get_weather"description"Get current weather for a location"property:location,String,description: "City and state"property:unit,String,enum: ["celsius","fahrenheit"]endend# OpenAI format (default)GetWeather.to_llm_toolGetWeather.to_llm_tool(format: :openai)# Anthropic formatGetWeather.to_llm_tool(format: :anthropic)# Future providersGetWeather.to_llm_tool(format: :gemini)GetWeather.to_llm_tool(format: :cohere)
Motivation
Currently, EasyTalk::Tools::FunctionBuilder.new(Model) only generates OpenAI-compatible specs. For Anthropic, users must manually extract and restructure the schema:
# Current (manual, error-prone)schema=Model.json_schematool={name: schema["title"],description: schema["description"],input_schema: {type: "object",properties: schema["properties"],required: schema["required"]}}
Nice API design. We handle multi-provider tool spec generation in our macOS AI agent (Fazm) and the format differences between providers are subtle but important.
Key differences to handle in the to_llm_tool method:
OpenAI format: Tool definitions wrap everything in a function object with name, description, and parameters (JSON Schema). Required fields go in a required array at the schema level.
Anthropic format: Similar structure but the top-level key is input_schema instead of parameters. Also, Claude is more sensitive to the description field on individual properties - well-described properties significantly improve tool call accuracy.
Gemini format: Uses function_declarations with yet another schema wrapper. Worth supporting if you want broad coverage.
One practical suggestion: add a strict option for OpenAI's structured output mode. When strict is true, OpenAI guarantees the output matches the schema exactly (no missing fields, correct types). This changes the schema slightly - all properties must be in required and additionalProperties: false must be set.
The Ruby DSL approach is clean. For the enum handling, consider adding validation that the enum values match the property type - we've seen subtle bugs where string enums get passed to integer properties.
Activity
m13v commentedon Mar 22, 2026
Nice API design. We handle multi-provider tool spec generation in our macOS AI agent (Fazm) and the format differences between providers are subtle but important.
Key differences to handle in the
to_llm_toolmethod:OpenAI format: Tool definitions wrap everything in a
functionobject withname,description, andparameters(JSON Schema). Required fields go in arequiredarray at the schema level.Anthropic format: Similar structure but the top-level key is
input_schemainstead ofparameters. Also, Claude is more sensitive to thedescriptionfield on individual properties - well-described properties significantly improve tool call accuracy.Gemini format: Uses
function_declarationswith yet another schema wrapper. Worth supporting if you want broad coverage.One practical suggestion: add a
strictoption for OpenAI's structured output mode. When strict is true, OpenAI guarantees the output matches the schema exactly (no missing fields, correct types). This changes the schema slightly - all properties must be inrequiredandadditionalProperties: falsemust be set.The Ruby DSL approach is clean. For the enum handling, consider adding validation that the enum values match the property type - we've seen subtle bugs where string enums get passed to integer properties.
m13v commentedon Mar 22, 2026
Our multi-provider tool spec handling is open source: https://github.com/m13v/fazm/blob/main/Desktop/Sources/Providers/ChatProvider.swift
Shows the practical differences between Claude and OpenAI tool definition formats and how we normalize them.