Module: Anthropic::Helpers::Messages
- Defined in:
- lib/anthropic/helpers/messages.rb
Class Method Summary collapse
-
.distill_input_schema_models!(data, strict:, is_beta: false) ⇒ Hash{String=>Class}
private
Extract tool models from the request and convert them to JSON Schema Returns a hash mapping tool name to Ruby model.
- .parse_input_schemas!(raw, tools:, models:) ⇒ Hash{Symbol=>Object} private
-
.tool_api_name(tool) ⇒ String
private
The
namea runnable tool is serialized under intools[].
Class Method Details
.distill_input_schema_models!(data, strict:, is_beta: false) ⇒ Hash{String=>Class}
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Extract tool models from the request and convert them to JSON Schema Returns a hash mapping tool name to Ruby model.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/anthropic/helpers/messages.rb', line 19 def distill_input_schema_models!(data, strict:, is_beta: false) tools = {} models = {} # Check for invalid output_config type before pattern matching if data.key?(:output_config) && !data[:output_config].is_a?(Hash) raise ArgumentError, "output_config must be a Hash, got #{data[:output_config].class}" end # Check for conflicting output_format and output_config[:format] before pattern matching if data.key?(:output_format) && data.dig(:output_config, :format) raise ArgumentError, "Both output_format and output_config[:format] were provided. " \ "Please use only output_config[:format] (output_format is deprecated)." end case data in {tools: Array => tool_array} # rubocop:disable Metrics/BlockLength mapped = tool_array.map do |tool| case tool # Runnable tool instance (an `Anthropic::BaseTool` subclass, hand-written or helper-built): in Anthropic::Helpers::Tools::BaseTool name = tool_api_name(tool) # Helper-built tools (e.g. MCP) declare an explicit `tool_name` and only send the # description they were given; hand-written tools fall back to their name. description = tool.class.doc_string description ||= name unless tool.class.tool_name tools.store(name, tool) input_schema = Anthropic::Helpers::InputSchema::JsonSchemaConverter.to_json_schema(tool) # On a clash the derived keys win, so nothing in `tool_options` can shadow them. definition = {name:, description:, input_schema:} .merge(tool.class.) { |_key, derived, _option| derived } .compact definition.tap { _1.update(strict:) if strict } # Input schema class used directly as a tool: in Anthropic::Helpers::InputSchema::JsonSchemaConverter name = model_name(tool.name) description = case tool in Class if tool <= Anthropic::Helpers::InputSchema::BaseModel tool.doc_string || name else name end tools.store(name, tool) input_schema = Anthropic::Helpers::InputSchema::JsonSchemaConverter.to_json_schema(tool) {name:, description:, input_schema:}.tap { _1.update(strict:) if strict } # Tool with explicit name/description and BaseModel as input_schema: in {name: String => name, input_schema: Anthropic::Helpers::InputSchema::JsonSchemaConverter => tool, **rest} tools.store(name, tool) input_schema = Anthropic::Helpers::InputSchema::JsonSchemaConverter.to_json_schema(tool) rest.merge(name:, input_schema:).tap { _1.update(strict:) if strict } else # Any other format (pass through unchanged) # This includes raw JSON schemas and any other tool definitions. tool end end # rubocop:enable Metrics/BlockLength tool_array.replace(mapped) else end # Matched separately from `tools:` so a request can carry both tools and a structured output format. case data # GA: output_config with BaseModel class as format in {output_config: {format: Anthropic::Helpers::InputSchema::JsonSchemaConverter => model} => output_config} name = model_name(model.name) models.store(name, model) schema = model.to_json_schema Anthropic::Helpers::InputSchema::SupportedSchemas.transform_schema!(schema) output_config.update(format: {type: :json_schema, schema:}) inject_structured_output_beta_header!(data) if is_beta # GA: output_config.format.schema as BaseModel class in {output_config: {format: {schema: Anthropic::Helpers::InputSchema::JsonSchemaConverter => model} => format_} => _output_config} name = model_name(model.name) models.store(name, model) schema = model.to_json_schema Anthropic::Helpers::InputSchema::SupportedSchemas.transform_schema!(schema) format_.update(type: :json_schema, schema:) inject_structured_output_beta_header!(data) if is_beta # Beta: output_format as BaseModel class (deprecated) in {output_format: Anthropic::Helpers::InputSchema::JsonSchemaConverter => model} transform_output_format_to_output_config!(data, model:, models:, is_beta:) # rubocop:disable Lint/DuplicateBranch in {output_format: {schema: Anthropic::Helpers::InputSchema::JsonSchemaConverter => model}} # This branch handles output_format: {schema: Model} vs output_format: Model above transform_output_format_to_output_config!(data, model:, models:, is_beta:) # rubocop:enable Lint/DuplicateBranch in {output_config: {format: Anthropic::Helpers::InputSchema::JsonSchemaConverter => model}} # New API: output_config.format with model class name = model_name(model.name) models.store(name, model) schema = model.to_json_schema Anthropic::Helpers::InputSchema::SupportedSchemas.transform_schema!(schema) data.update(output_format: {type: :json_schema, schema: schema}) # Beta: output_format.schema as BaseModel class (deprecated) in {output_format: {schema: Anthropic::Helpers::InputSchema::JsonSchemaConverter => model} => output_format} name = model_name(model.name) models.store(name, model) schema = model.to_json_schema Anthropic::Helpers::InputSchema::SupportedSchemas.transform_schema!(schema) output_format.update(type: :json_schema, schema:) else end [tools, models] end |
.parse_input_schemas!(raw, tools:, models:) ⇒ Hash{Symbol=>Object}
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/anthropic/helpers/messages.rb', line 144 def parse_input_schemas!(raw, tools:, models:) raw[:content]&.each do |content| case content in {type: "tool_use", name:, input:} if (tool = tools[name]) begin coerced = Anthropic::Internal::Type::Converter.coerce(tool, input) content.store(:parsed, coerced) rescue StandardError => e content.store(:parsed, {error: e.}) end in {type: "text", text:} if (model = models.first&.last) begin json = JSON.parse(text, symbolize_names: true) coerced = Anthropic::Internal::Type::Converter.coerce(model, json) content.store(:parsed, coerced) rescue StandardError => e content.store(:parsed, {error: e.}) end else end end raw end |
.tool_api_name(tool) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The name a runnable tool is serialized under in tools[].
222 |
# File 'lib/anthropic/helpers/messages.rb', line 222 def tool_api_name(tool) = tool.class.tool_name || model_name(tool.class.name) |