Module: Smith::Providers::OpenAI::ToolsExtensions

Defined in:
lib/smith/providers/openai/tools_extensions.rb

Overview

Tool format helpers consumed by Smith::Providers::OpenAI::Responses. Vendored from PR #770; namespace-only changes.

Constant Summary collapse

EMPTY_PARAMETERS_SCHEMA =
{
  "type" => "object",
  "properties" => {},
  "required" => [],
  "additionalProperties" => false,
  "strict" => true
}.freeze

Class Method Summary collapse

Class Method Details

.build_response_tool_choice(tool_choice) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/smith/providers/openai/tools_extensions.rb', line 92

def build_response_tool_choice(tool_choice)
  case tool_choice
  when :auto, :none, :required
    tool_choice
  else
    {
      type: "function",
      name: tool_choice
    }
  end
end

.parameters_schema_for(tool) ⇒ Object



45
46
47
48
# File 'lib/smith/providers/openai/tools_extensions.rb', line 45

def parameters_schema_for(tool)
  tool.params_schema ||
    schema_from_parameters(tool.parameters)
end

.parse_response_tool_call_arguments(output) ⇒ Object



85
86
87
88
89
90
# File 'lib/smith/providers/openai/tools_extensions.rb', line 85

def parse_response_tool_call_arguments(output)
  arguments = output["arguments"]
  return {} if arguments.nil? || arguments.empty?

  JSON.parse(arguments)
end

.parse_response_tool_calls(outputs) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/smith/providers/openai/tools_extensions.rb', line 68

def parse_response_tool_calls(outputs)
  function_calls = ::RubyLLM::Utils.to_safe_array(outputs).select { |output| output["type"] == "function_call" }
  return nil if function_calls.empty?

  function_calls.to_h do |output|
    id = output["call_id"] || output["id"]
    [
      id,
      ::RubyLLM::ToolCall.new(
        id: id,
        name: output["name"],
        arguments: parse_response_tool_call_arguments(output)
      )
    ]
  end
end

.response_tool_for(tool) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/smith/providers/openai/tools_extensions.rb', line 55

def response_tool_for(tool)
  definition = {
    type: "function",
    name: tool.name,
    description: tool.description,
    parameters: parameters_schema_for(tool)
  }

  return definition if tool.provider_params.empty?

  ::RubyLLM::Utils.deep_merge(definition, tool.provider_params)
end

.schema_from_parameters(parameters) ⇒ Object



50
51
52
53
# File 'lib/smith/providers/openai/tools_extensions.rb', line 50

def schema_from_parameters(parameters)
  schema_definition = ::RubyLLM::Tool::SchemaDefinition.from_parameters(parameters)
  schema_definition&.json_schema || EMPTY_PARAMETERS_SCHEMA
end