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{Sybmol=>Object} private
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 |
# 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 # BaseTool whose class declares an explicit `tool_name` (e.g. MCP-built tools): in Anthropic::Helpers::Tools::BaseTool if tool.class.tool_name name = tool.class.tool_name description = tool.class.doc_string tools.store(name, tool) input_schema = Anthropic::Helpers::InputSchema::JsonSchemaConverter.to_json_schema(tool) extras = tool.class.tool_extra_props || {} result = {name:, input_schema:, **extras} result[:description] = description if description result[:strict] = strict if strict result # Direct tool class: in Anthropic::Helpers::InputSchema::JsonSchemaConverter classname = tool.is_a?(Anthropic::Helpers::Tools::BaseTool) ? tool.class.name : tool.name name = model_name(classname) description = case tool in Anthropic::Helpers::Tools::BaseTool tool.class.doc_string || name 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) # 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{Sybmol=>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.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/anthropic/helpers/messages.rb', line 138 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 |