From 18025f94e6914b6bec05286f5c0311f689bff39d Mon Sep 17 00:00:00 2001 From: Sylvain Utard Date: Wed, 23 Jul 2025 09:30:14 +0200 Subject: [PATCH 01/27] Introduce support of Responses API Some model (incl. `o4-mini-deep-research`) aren't compatible with the chat/completion API. This PR introduces a new `Response` class, which - similarly to `Chat` (and inheriting from the same base `Conversation` class) - allows a user to target the `responses` endpoint. --- lib/ruby_llm.rb | 4 + lib/ruby_llm/active_record/acts_as.rb | 2 +- lib/ruby_llm/chat.rb | 153 +----- lib/ruby_llm/conversation.rb | 160 +++++++ lib/ruby_llm/provider.rb | 34 +- lib/ruby_llm/providers/anthropic/chat.rb | 2 +- lib/ruby_llm/providers/anthropic/streaming.rb | 6 +- lib/ruby_llm/providers/bedrock/chat.rb | 6 +- .../providers/bedrock/streaming/base.rb | 4 +- lib/ruby_llm/providers/gemini/chat.rb | 4 +- lib/ruby_llm/providers/gemini/streaming.rb | 2 +- lib/ruby_llm/providers/openai.rb | 2 + lib/ruby_llm/providers/openai/chat.rb | 86 +++- lib/ruby_llm/providers/openai/response.rb | 43 ++ lib/ruby_llm/providers/openai/streaming.rb | 6 +- lib/ruby_llm/providers/openai/tools.rb | 39 +- lib/ruby_llm/response.rb | 22 + lib/ruby_llm/streaming.rb | 2 +- ...mpty_assistant_messages_on_api_failure.yml | 115 +++++ ...enai_o4-mini-deep-research_can_respond.yml | 446 ++++++++++++++++++ .../response_tool_calling_can_use_tools.yml | 304 ++++++++++++ spec/ruby_llm/active_record/acts_as_spec.rb | 2 +- spec/ruby_llm/chat_request_options_spec.rb | 4 +- .../providers/anthropic/tools_spec.rb | 6 +- spec/ruby_llm/response_spec.rb | 48 ++ spec/spec_helper.rb | 4 + 26 files changed, 1326 insertions(+), 180 deletions(-) create mode 100644 lib/ruby_llm/conversation.rb create mode 100644 lib/ruby_llm/providers/openai/response.rb create mode 100644 lib/ruby_llm/response.rb create mode 100644 spec/fixtures/vcr_cassettes/activerecord_actsas_error_handling_destroys_empty_assistant_messages_on_api_failure.yml create mode 100644 spec/fixtures/vcr_cassettes/response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml create mode 100644 spec/fixtures/vcr_cassettes/response_tool_calling_can_use_tools.yml create mode 100644 spec/ruby_llm/response_spec.rb diff --git a/lib/ruby_llm.rb b/lib/ruby_llm.rb index 1817ddc45..9982ac05f 100644 --- a/lib/ruby_llm.rb +++ b/lib/ruby_llm.rb @@ -43,6 +43,10 @@ def chat(...) Chat.new(...) end + def response(...) + Response.new(...) + end + def embed(...) Embedding.embed(...) end diff --git a/lib/ruby_llm/active_record/acts_as.rb b/lib/ruby_llm/active_record/acts_as.rb index 25abfefa9..4e8288ae1 100644 --- a/lib/ruby_llm/active_record/acts_as.rb +++ b/lib/ruby_llm/active_record/acts_as.rb @@ -159,7 +159,7 @@ def ask(message, with: nil, &) alias say ask def complete(...) - to_llm.complete(...) + to_llm.process(...) rescue RubyLLM::Error => e if @message&.persisted? && @message.content.blank? RubyLLM.logger.debug "RubyLLM: API call failed, destroying message: #{@message.id}" diff --git a/lib/ruby_llm/chat.rb b/lib/ruby_llm/chat.rb index f547887a7..d8d836208 100644 --- a/lib/ruby_llm/chat.rb +++ b/lib/ruby_llm/chat.rb @@ -8,162 +8,17 @@ module RubyLLM # chat = RubyLLM.chat # chat.ask "What's the best way to learn Ruby?" # chat.ask "Can you elaborate on that?" - class Chat - include Enumerable - - attr_reader :model, :messages, :tools, :params - - def initialize(model: nil, provider: nil, assume_model_exists: false, context: nil) - if assume_model_exists && !provider - raise ArgumentError, 'Provider must be specified if assume_model_exists is true' - end - - @context = context - @config = context&.config || RubyLLM.config - model_id = model || @config.default_model - with_model(model_id, provider: provider, assume_exists: assume_model_exists) - @temperature = 0.7 - @messages = [] - @tools = {} - @params = {} - @on = { - new_message: nil, - end_message: nil - } - end - - def ask(message = nil, with: nil, &) - add_message role: :user, content: Content.new(message, with) - complete(&) - end - - alias say ask - - def with_instructions(instructions, replace: false) - @messages = @messages.reject { |msg| msg.role == :system } if replace - - add_message role: :system, content: instructions - self - end - - def with_tool(tool) - unless @model.supports_functions? - raise UnsupportedFunctionsError, "Model #{@model.id} doesn't support function calling" - end - - tool_instance = tool.is_a?(Class) ? tool.new : tool - @tools[tool_instance.name.to_sym] = tool_instance - self - end - - def with_tools(*tools) - tools.each { |tool| with_tool tool } - self - end - - def with_model(model_id, provider: nil, assume_exists: false) - @model, @provider = Models.resolve(model_id, provider:, assume_exists:) - @connection = @context ? @context.connection_for(@provider) : @provider.connection(@config) - self - end - - def with_temperature(temperature) - @temperature = temperature - self - end - - def with_context(context) - @context = context - @config = context.config - with_model(@model.id, provider: @provider.slug, assume_exists: true) - self - end - - def with_params(**params) - @params = params - self - end - - def on_new_message(&block) - @on[:new_message] = block - self - end - - def on_end_message(&block) - @on[:end_message] = block - self - end - - def each(&) - messages.each(&) - end - - def complete(&) - response = @provider.complete( + class Chat < Conversation + def get_response(&) + @provider.complete( messages, tools: @tools, temperature: @temperature, model: @model.id, connection: @connection, params: @params, - &wrap_streaming_block(&) + & ) - - @on[:new_message]&.call unless block_given? - add_message response - @on[:end_message]&.call(response) - - if response.tool_call? - handle_tool_calls(response, &) - else - response - end - end - - def add_message(message_or_attributes) - message = message_or_attributes.is_a?(Message) ? message_or_attributes : Message.new(message_or_attributes) - messages << message - message - end - - def reset_messages! - @messages.clear - end - - private - - def wrap_streaming_block(&block) - return nil unless block_given? - - first_chunk_received = false - - proc do |chunk| - # Create message on first content chunk - unless first_chunk_received - first_chunk_received = true - @on[:new_message]&.call - end - - # Pass chunk to user's block - block.call chunk - end - end - - def handle_tool_calls(response, &) - response.tool_calls.each_value do |tool_call| - @on[:new_message]&.call - result = execute_tool tool_call - message = add_message role: :tool, content: result.to_s, tool_call_id: tool_call.id - @on[:end_message]&.call(message) - end - - complete(&) - end - - def execute_tool(tool_call) - tool = tools[tool_call.name.to_sym] - args = tool_call.arguments - tool.call(args) end end end diff --git a/lib/ruby_llm/conversation.rb b/lib/ruby_llm/conversation.rb new file mode 100644 index 000000000..8f524aa35 --- /dev/null +++ b/lib/ruby_llm/conversation.rb @@ -0,0 +1,160 @@ +# frozen_string_literal: true + +module RubyLLM + # Represents a base class for conversations with an AI model. Handles tool integrations. + # + # Example: + # conversation = RubyLLM.conversation + # conversation.ask "What's the best way to learn Ruby?" + # conversation.ask "Can you elaborate on that?" + class Conversation + include Enumerable + + attr_reader :model, :messages, :tools, :params + + def initialize(model: nil, provider: nil, assume_model_exists: false, context: nil) + if assume_model_exists && !provider + raise ArgumentError, 'Provider must be specified if assume_model_exists is true' + end + + @context = context + @config = context&.config || RubyLLM.config + model_id = model || @config.default_model + with_model(model_id, provider: provider, assume_exists: assume_model_exists) + @temperature = 0.7 + @messages = [] + @tools = {} + @params = {} + @on = { + new_message: nil, + end_message: nil + } + end + + def ask(message = nil, with: nil, &) + add_message role: :user, content: Content.new(message, with) + process(&) + end + + alias say ask + + def with_instructions(instructions, replace: false) + @messages = @messages.reject { |msg| msg.role == :system } if replace + + add_message role: :system, content: instructions + self + end + + def with_tool(tool) + unless @model.supports_functions? + raise UnsupportedFunctionsError, "Model #{@model.id} doesn't support function calling" + end + + tool_instance = tool.is_a?(Class) ? tool.new : tool + @tools[tool_instance.name.to_sym] = tool_instance + self + end + + def with_tools(*tools) + tools.each { |tool| with_tool tool } + self + end + + def with_model(model_id, provider: nil, assume_exists: false) + @model, @provider = Models.resolve(model_id, provider:, assume_exists:) + @connection = @context ? @context.connection_for(@provider) : @provider.connection(@config) + self + end + + def with_temperature(temperature) + @temperature = temperature + self + end + + def with_context(context) + @context = context + @config = context.config + with_model(@model.id, provider: @provider.slug, assume_exists: true) + self + end + + def with_params(**params) + @params = params + self + end + + def on_new_message(&block) + @on[:new_message] = block + self + end + + def on_end_message(&block) + @on[:end_message] = block + self + end + + def each(&) + messages.each(&) + end + + def process(&) + response = get_response(&wrap_streaming_block(&)) + + @on[:new_message]&.call unless block_given? + add_message response + @on[:end_message]&.call(response) + + if response.tool_call? + handle_tool_calls(response, &) + else + response + end + end + + def add_message(message_or_attributes) + message = message_or_attributes.is_a?(Message) ? message_or_attributes : Message.new(message_or_attributes) + messages << message + message + end + + def reset_messages! + @messages.clear + end + + private + + def wrap_streaming_block(&block) + return nil unless block_given? + + first_chunk_received = false + + proc do |chunk| + # Create message on first content chunk + unless first_chunk_received + first_chunk_received = true + @on[:new_message]&.call + end + + # Pass chunk to user's block + block.call chunk + end + end + + def handle_tool_calls(response, &) + response.tool_calls.each_value do |tool_call| + @on[:new_message]&.call + result = execute_tool tool_call + message = add_message role: :tool, content: result.to_s, tool_call_id: tool_call.id + @on[:end_message]&.call(message) + end + + process(&) + end + + def execute_tool(tool_call) + tool = tools[tool_call.name.to_sym] + args = tool_call.arguments + tool.call(args) + end + end +end diff --git a/lib/ruby_llm/provider.rb b/lib/ruby_llm/provider.rb index 8899e43db..bc4f1523b 100644 --- a/lib/ruby_llm/provider.rb +++ b/lib/ruby_llm/provider.rb @@ -15,7 +15,7 @@ def complete(messages, tools:, temperature:, model:, connection:, params: {}, &) payload = deep_merge( params, - render_payload( + render_completion_payload( messages, tools: tools, temperature: normalized_temperature, @@ -25,9 +25,30 @@ def complete(messages, tools:, temperature:, model:, connection:, params: {}, &) ) if block_given? - stream_response connection, payload, & + stream_response connection, completion_stream_url, payload, & else - sync_response connection, payload + sync_completion_response connection, payload + end + end + + def respond(messages, tools:, temperature:, model:, connection:, params: {}, &) # rubocop:disable Metrics/ParameterLists + normalized_temperature = maybe_normalize_temperature(temperature, model) + + payload = deep_merge( + params, + render_response_payload( + messages, + tools: tools, + temperature: normalized_temperature, + model: model, + stream: block_given? + ) + ) + + if block_given? + stream_response connection, responses_stream_url, payload, & + else + sync_respond_response connection, payload end end @@ -88,10 +109,15 @@ def maybe_normalize_temperature(temperature, model) end end - def sync_response(connection, payload) + def sync_completion_response(connection, payload) response = connection.post completion_url, payload parse_completion_response response end + + def sync_respond_response(connection, payload) + response = connection.post responses_url, payload + parse_respond_response response + end end def try_parse_json(maybe_json) diff --git a/lib/ruby_llm/providers/anthropic/chat.rb b/lib/ruby_llm/providers/anthropic/chat.rb index 2ba96009d..c7cd0ac6e 100644 --- a/lib/ruby_llm/providers/anthropic/chat.rb +++ b/lib/ruby_llm/providers/anthropic/chat.rb @@ -11,7 +11,7 @@ def completion_url '/v1/messages' end - def render_payload(messages, tools:, temperature:, model:, stream: false) + def render_completion_payload(messages, tools:, temperature:, model:, stream: false) system_messages, chat_messages = separate_messages(messages) system_content = build_system_content(system_messages) diff --git a/lib/ruby_llm/providers/anthropic/streaming.rb b/lib/ruby_llm/providers/anthropic/streaming.rb index 3bf842150..360e98c93 100644 --- a/lib/ruby_llm/providers/anthropic/streaming.rb +++ b/lib/ruby_llm/providers/anthropic/streaming.rb @@ -7,10 +7,14 @@ module Anthropic module Streaming private - def stream_url + def completion_stream_url completion_url end + def responses_stream_url + responses_url + end + def build_chunk(data) Chunk.new( role: :assistant, diff --git a/lib/ruby_llm/providers/bedrock/chat.rb b/lib/ruby_llm/providers/bedrock/chat.rb index 742579558..3901bec79 100644 --- a/lib/ruby_llm/providers/bedrock/chat.rb +++ b/lib/ruby_llm/providers/bedrock/chat.rb @@ -7,7 +7,7 @@ module Bedrock module Chat module_function - def sync_response(connection, payload) + def sync_completion_response(connection, payload) signature = sign_request("#{connection.connection.url_prefix}#{completion_url}", config: connection.config, payload:) response = connection.post completion_url, payload do |req| @@ -39,8 +39,8 @@ def completion_url "model/#{@model_id}/invoke" end - def render_payload(messages, tools:, temperature:, model:, stream: false) # rubocop:disable Lint/UnusedMethodArgument - # Hold model_id in instance variable for use in completion_url and stream_url + def render_completion_payload(messages, tools:, temperature:, model:, stream: false) # rubocop:disable Lint/UnusedMethodArgument + # Hold model_id in instance variable for use in completion_url and completion_stream_url @model_id = model system_messages, chat_messages = Anthropic::Chat.separate_messages(messages) diff --git a/lib/ruby_llm/providers/bedrock/streaming/base.rb b/lib/ruby_llm/providers/bedrock/streaming/base.rb index 26860076e..683ef6ef0 100644 --- a/lib/ruby_llm/providers/bedrock/streaming/base.rb +++ b/lib/ruby_llm/providers/bedrock/streaming/base.rb @@ -25,11 +25,11 @@ def self.included(base) base.include PreludeHandling end - def stream_url + def completion_stream_url "model/#{@model_id}/invoke-with-response-stream" end - def stream_response(connection, payload, &block) + def stream_response(connection, stream_url, payload, &block) signature = sign_request("#{connection.connection.url_prefix}#{stream_url}", config: connection.config, payload:) accumulator = StreamAccumulator.new diff --git a/lib/ruby_llm/providers/gemini/chat.rb b/lib/ruby_llm/providers/gemini/chat.rb index d6ba1696f..8a455efb7 100644 --- a/lib/ruby_llm/providers/gemini/chat.rb +++ b/lib/ruby_llm/providers/gemini/chat.rb @@ -11,8 +11,8 @@ def completion_url "models/#{@model}:generateContent" end - def render_payload(messages, tools:, temperature:, model:, stream: false) # rubocop:disable Lint/UnusedMethodArgument - @model = model # Store model for completion_url/stream_url + def render_completion_payload(messages, tools:, temperature:, model:, stream: false) # rubocop:disable Lint/UnusedMethodArgument + @model = model # Store model for completion_url/completion_stream_url payload = { contents: format_messages(messages), generationConfig: { diff --git a/lib/ruby_llm/providers/gemini/streaming.rb b/lib/ruby_llm/providers/gemini/streaming.rb index edf9efd5b..2017e0b16 100644 --- a/lib/ruby_llm/providers/gemini/streaming.rb +++ b/lib/ruby_llm/providers/gemini/streaming.rb @@ -5,7 +5,7 @@ module Providers module Gemini # Streaming methods for the Gemini API implementation module Streaming - def stream_url + def completion_stream_url "models/#{@model}:streamGenerateContent?alt=sse" end diff --git a/lib/ruby_llm/providers/openai.rb b/lib/ruby_llm/providers/openai.rb index 7ad39d9c1..c1731f812 100644 --- a/lib/ruby_llm/providers/openai.rb +++ b/lib/ruby_llm/providers/openai.rb @@ -8,6 +8,7 @@ module Providers module OpenAI extend Provider extend OpenAI::Chat + extend OpenAI::Response extend OpenAI::Embeddings extend OpenAI::Models extend OpenAI::Streaming @@ -18,6 +19,7 @@ module OpenAI def self.extended(base) base.extend(Provider) base.extend(OpenAI::Chat) + base.extend(OpenAI::Response) base.extend(OpenAI::Embeddings) base.extend(OpenAI::Models) base.extend(OpenAI::Streaming) diff --git a/lib/ruby_llm/providers/openai/chat.rb b/lib/ruby_llm/providers/openai/chat.rb index 697442b2f..12c143e0f 100644 --- a/lib/ruby_llm/providers/openai/chat.rb +++ b/lib/ruby_llm/providers/openai/chat.rb @@ -9,9 +9,13 @@ def completion_url 'chat/completions' end + def responses_url + 'responses' + end + module_function - def render_payload(messages, tools:, temperature:, model:, stream: false) + def render_completion_payload(messages, tools:, temperature:, model:, stream: false) payload = { model: model, messages: format_messages(messages), @@ -22,7 +26,26 @@ def render_payload(messages, tools:, temperature:, model:, stream: false) payload[:temperature] = temperature unless temperature.nil? if tools.any? - payload[:tools] = tools.map { |_, tool| tool_for(tool) } + payload[:tools] = tools.map { |_, tool| chat_tool_for(tool) } + payload[:tool_choice] = 'auto' + end + + payload[:stream_options] = { include_usage: true } if stream + payload + end + + def render_response_payload(messages, tools:, temperature:, model:, stream: false) + payload = { + model: model, + input: format_input(messages), + stream: stream + } + + # Only include temperature if it's not nil (some models don't accept it) + payload[:temperature] = temperature unless temperature.nil? + + if tools.any? + payload[:tools] = tools.map { |_, tool| response_tool_for(tool) } payload[:tool_choice] = 'auto' end @@ -49,6 +72,32 @@ def parse_completion_response(response) ) end + def parse_respond_response(response) + data = response.body + return if data.empty? + + raise Error.new(response, data.dig('error', 'message')) if data.dig('error', 'message') + + outputs = data['output'] + return unless outputs.any? + + Message.new( + role: :assistant, + content: all_output_text(outputs), + tool_calls: parse_response_tool_calls(outputs), + input_tokens: data['usage']['input_tokens'], + output_tokens: data['usage']['output_tokens'], + model_id: data['model'] + ) + end + + def all_output_text(outputs) + outputs.select { |o| o['type'] == 'message' }.flat_map do |o| + output_texts = o['content'].select { |c| c['type'] == 'output_text' } + output_texts.map { |c| c['text'] }.join("\n") + end + end + def format_messages(messages) messages.map do |msg| { @@ -60,6 +109,39 @@ def format_messages(messages) end end + def format_input(messages) # rubocop:disable Metrics/PerceivedComplexity + all_tool_calls = messages.flat_map do |m| + m.tool_calls&.values || [] + end + messages.flat_map do |msg| + if msg.tool_call? + msg.tool_calls.map do |_, tc| + { + type: 'function_call', + call_id: tc.id, + name: tc.name, + arguments: JSON.generate(tc.arguments), + status: 'completed' + } + end + elsif msg.role == :tool + { + type: 'function_call_output', + call_id: all_tool_calls.detect { |tc| tc.id == msg.tool_call_id }&.id, + output: msg.content, + status: 'completed' + } + else + { + type: 'message', + role: format_role(msg.role), + content: Media.format_content(msg.content), + status: 'completed' + }.compact + end + end + end + def format_role(role) case role when :system diff --git a/lib/ruby_llm/providers/openai/response.rb b/lib/ruby_llm/providers/openai/response.rb new file mode 100644 index 000000000..156a1f2cf --- /dev/null +++ b/lib/ruby_llm/providers/openai/response.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module RubyLLM + module Providers + module OpenAI + # Response methods of the OpenAI API integration + module Response + def responses_url + 'responses' + end + + module_function + + def parse_respond_response(response) + data = response.body + return if data.empty? + + raise Error.new(response, data.dig('error', 'message')) if data.dig('error', 'message') + + outputs = data['output'] + return unless outputs.any? + + Message.new( + role: :assistant, + content: all_output_text(outputs), + tool_calls: parse_response_tool_calls(outputs), + input_tokens: data['usage']['input_tokens'], + output_tokens: data['usage']['output_tokens'], + model_id: data['model'] + ) + end + + def all_output_text(outputs) + outputs.select { |o| o['type'] == 'message' }.flat_map do |o| + o['content'].filter_map do |c| + c['type'] == 'output_text' && c['text'] + end + end.join("\n") + end + end + end + end +end diff --git a/lib/ruby_llm/providers/openai/streaming.rb b/lib/ruby_llm/providers/openai/streaming.rb index ba3134475..ae91f3748 100644 --- a/lib/ruby_llm/providers/openai/streaming.rb +++ b/lib/ruby_llm/providers/openai/streaming.rb @@ -7,10 +7,14 @@ module OpenAI module Streaming module_function - def stream_url + def completion_stream_url completion_url end + def responses_stream_url + responses_url + end + def build_chunk(data) Chunk.new( role: :assistant, diff --git a/lib/ruby_llm/providers/openai/tools.rb b/lib/ruby_llm/providers/openai/tools.rb index 51743afb5..53de97414 100644 --- a/lib/ruby_llm/providers/openai/tools.rb +++ b/lib/ruby_llm/providers/openai/tools.rb @@ -7,21 +7,26 @@ module OpenAI module Tools module_function - def tool_for(tool) + def chat_tool_for(tool) { type: 'function', function: { name: tool.name, description: tool.description, - parameters: { - type: 'object', - properties: tool.parameters.transform_values { |param| param_schema(param) }, - required: tool.parameters.select { |_, p| p.required }.keys - } + parameters: tool_parameters_for(tool) } } end + def response_tool_for(tool) + { + type: 'function', + name: tool.name, + description: tool.description, + parameters: tool_parameters_for(tool) + } + end + def param_schema(param) { type: param.type, @@ -29,6 +34,14 @@ def param_schema(param) }.compact end + def tool_parameters_for(tool) + { + type: 'object', + properties: tool.parameters.transform_values { |param| param_schema(param) }, + required: tool.parameters.select { |_, p| p.required }.keys + } + end + def format_tool_calls(tool_calls) return nil unless tool_calls&.any? @@ -67,6 +80,20 @@ def parse_tool_calls(tool_calls, parse_arguments: true) ] end end + + def parse_response_tool_calls(outputs) + # TODO: implement the other & built-in tools + # 'web_search_call', 'file_search_call', 'image_generation_call', + # 'code_interpreter_call', 'local_shell_call', 'mcp_call', + # 'mcp_list_tools', 'mcp_approval_request' + outputs.select { |o| o['type'] == 'function_call' }.to_h do |o| + [o['id'], ToolCall.new( + id: o['call_id'], + name: o['name'], + arguments: JSON.parse(o['arguments']) + )] + end + end end end end diff --git a/lib/ruby_llm/response.rb b/lib/ruby_llm/response.rb new file mode 100644 index 000000000..6cfd7cdbd --- /dev/null +++ b/lib/ruby_llm/response.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module RubyLLM + # Represents a response from an AI model. Handles tool integration. + # + # Example: + # response = RubyLLM.response + # response.ask "What's the best way to learn Ruby?" + class Response < Conversation + def get_response(&) + @provider.respond( + messages, + tools: @tools, + temperature: @temperature, + model: @model.id, + connection: @connection, + params: @params, + & + ) + end + end +end diff --git a/lib/ruby_llm/streaming.rb b/lib/ruby_llm/streaming.rb index b7017896e..4b0a5c3c5 100644 --- a/lib/ruby_llm/streaming.rb +++ b/lib/ruby_llm/streaming.rb @@ -8,7 +8,7 @@ module RubyLLM module Streaming module_function - def stream_response(connection, payload, &block) + def stream_response(connection, stream_url, payload, &block) accumulator = StreamAccumulator.new connection.post stream_url, payload do |req| diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_error_handling_destroys_empty_assistant_messages_on_api_failure.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_error_handling_destroys_empty_assistant_messages_on_api_failure.yml new file mode 100644 index 000000000..2ea9bcdf4 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_error_handling_destroys_empty_assistant_messages_on_api_failure.yml @@ -0,0 +1,115 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.openai.com/v1/chat/completions + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"This + will fail"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 23 Jul 2025 06:53:29 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Access-Control-Expose-Headers: + - X-Request-ID + Openai-Organization: + - "" + Openai-Processing-Ms: + - '870' + Openai-Project: + - proj_c1LXe0DmfaJxa0MxGDmocdjJ + Openai-Version: + - '2020-10-01' + X-Envoy-Upstream-Service-Time: + - '901' + X-Ratelimit-Limit-Requests: + - '5000' + X-Ratelimit-Limit-Tokens: + - '2000000' + X-Ratelimit-Remaining-Requests: + - '4999' + X-Ratelimit-Remaining-Tokens: + - '1999994' + X-Ratelimit-Reset-Requests: + - 12ms + X-Ratelimit-Reset-Tokens: + - 0s + X-Request-Id: + - "" + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: | + { + "id": "chatcmpl-BwNdw4V4t4ZnrYOfeg9HuzJQEc7Vk", + "object": "chat.completion", + "created": 1753253608, + "model": "gpt-4.1-nano-2025-04-14", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "It sounds like you're concerned that something might not work as expected. Could you please provide more details or clarify what you're referring to? I'm here to help!", + "refusal": null, + "annotations": [] + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 10, + "completion_tokens": 31, + "total_tokens": 41, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "service_tier": "default", + "system_fingerprint": null + } + recorded_at: Wed, 23 Jul 2025 06:53:29 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml b/spec/fixtures/vcr_cassettes/response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml new file mode 100644 index 000000000..993ac6bc8 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml @@ -0,0 +1,446 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"tools":[{"type":"web_search_preview"}],"model":"o4-mini-deep-research","input":[{"role":"user","content":"At + what temperature does water boil (in Celsius)?"}],"stream":false,"temperature":1.0}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 22 Jul 2025 20:22:01 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '5000' + X-Ratelimit-Limit-Tokens: + - '2000000' + X-Ratelimit-Remaining-Requests: + - '4999' + X-Ratelimit-Remaining-Tokens: + - '1988636' + X-Ratelimit-Reset-Requests: + - 12ms + X-Ratelimit-Reset-Tokens: + - 340ms + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_c1LXe0DmfaJxa0MxGDmocdjJ + X-Request-Id: + - "" + Openai-Processing-Ms: + - '63465' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_687ff2aa365c8199aa5507c8b3baef3e04e204e1133d12d7", + "object": "response", + "created_at": 1753215658, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": 225, + "model": "o4-mini-deep-research-2025-06-26", + "output": [ + { + "id": "rs_687ff2aacfb081999aea60da9ffc46e004e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2ac4574819999fdbe52a15dac9f04e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "query": "\"boils at 100\u00b0C\"" + } + }, + { + "id": "rs_687ff2b3924081998979e23aebc73d6a04e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2b41ef8819985e7490c2af8bd4204e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "query": "\"water boils at 100\u00b0C\" source:wikipedia" + } + }, + { + "id": "rs_687ff2b5797881999dd4f5a124a9913e04e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2b6927c8199a0f500fdfb257ecf04e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "query": "water boils at 100\bC Britannica" + } + }, + { + "id": "rs_687ff2b7e8888199a4e8c7ff4c88b25d04e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2b84bb8819996e14f7f76059eec04e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "open_page", + "url": "https://www.britannica.com/question/When-does-water-boil" + } + }, + { + "id": "rs_687ff2b8ce788199b042cb1531409d7204e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2b95ba08199a052fabc4625c7d504e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "query": "\"water boils at 100\u00b0C\" sea level" + } + }, + { + "id": "rs_687ff2baf2f48199a8fe9fbd0ab716d804e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2bdc8e88199b955c90db08fab2b04e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "query": "\"100\u00179C at sea level\" water" + } + }, + { + "id": "rs_687ff2bf69508199b63c6a7790076b1c04e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2bfbdd88199a0f8c05c8cc9da5404e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "query": "\"boils at 100\u0001C\" water standard" + } + }, + { + "id": "rs_687ff2c01c788199adab462cb196a7fc04e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2c0b4dc81999d4e661543f1699c04e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "query": "\"100 degrees Celsius\" boiling point water" + } + }, + { + "id": "rs_687ff2c1ece081998256aafeff67af1104e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2c435508199a7e354cc09bd98fe04e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "query": "\"water boils at 100 degrees Celsius\" pressure" + } + }, + { + "id": "rs_687ff2c58fe08199b3452e3e79e8c87004e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2c80cb481998857d2c2b6202e8a04e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "open_page", + "url": "https://www.britannica.com/science/boiling-point" + } + }, + { + "id": "rs_687ff2c8afc48199b55d6064a4b8374004e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2c9756481998354313cae64c82904e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "query": "\"Water boils at 100\" site:britannica.com" + } + }, + { + "id": "rs_687ff2cae024819980f7e07640d215c204e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2cb26f88199b22740b92cce524d04e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "open_page", + "url": "https://kids.britannica.com/students/article/water/277663" + } + }, + { + "id": "rs_687ff2cbb80c81999b2860d3596831b004e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2cbd7848199ad7125d8e938d86d04e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "find_in_page", + "pattern": "boils", + "url": "https://kids.britannica.com/students/article/water/277663" + } + }, + { + "id": "rs_687ff2cc2378819991eb3899676aaa9404e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2ccd190819993b7cb79428d1c2704e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "open_page", + "url": "https://kids.britannica.com/students/article/water/277663" + } + }, + { + "id": "rs_687ff2cd76e8819987304d23113c9a7704e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2cf252c8199bbb7a7bd3daf99e804e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "open_page", + "url": null + } + }, + { + "id": "rs_687ff2cf8f708199ac1b889e0f9d26eb04e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2d1b10c81999f34c64f189fdf9604e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "open_page", + "url": "https://kids.britannica.com/students/article/water/277663" + } + }, + { + "id": "rs_687ff2d2063481999db946d3c0c6894204e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2d486b08199bc1b3ddd1790b86104e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "find_in_page", + "pattern": "100 \u00125C", + "url": "https://kids.britannica.com/students/article/water/277663" + } + }, + { + "id": "rs_687ff2d4df888199b02e20f573e2f55104e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2d629d4819989bd925e8f7bb14804e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "query": "\"100\u0001C (212\u0001F) at standard pressure\"" + } + }, + { + "id": "rs_687ff2d7c4348199a299f29b1c31209904e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2d84d40819992eb1bf5fc0b95b004e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "query": "\"100\u0001C\" boiling water NOAA" + } + }, + { + "id": "rs_687ff2da28588199aa2da963f37f480f04e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "ws_687ff2da8a5c819991fc0e042a43aa6104e204e1133d12d7", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "query": "\"vapour pressure of water = atmospheric pressure\" 100\u0001C" + } + }, + { + "id": "rs_687ff2dc087081999dc8b019598062b204e204e1133d12d7", + "type": "reasoning", + "summary": [] + }, + { + "id": "msg_687ff2e8800c819998c4f8b59f78478a04e204e1133d12d7", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [ + { + "type": "url_citation", + "end_index": 305, + "start_index": 126, + "title": "water - Students | Britannica Kids | Homework Help", + "url": "https://kids.britannica.com/students/article/water/277663#:~:text=Atmospheric%20pressure%20also%20affects%20the,and%20freezes%20at%20higher%20temperatures" + }, + { + "type": "url_citation", + "end_index": 585, + "start_index": 406, + "title": "water - Students | Britannica Kids | Homework Help", + "url": "https://kids.britannica.com/students/article/water/277663#:~:text=Atmospheric%20pressure%20also%20affects%20the,and%20freezes%20at%20higher%20temperatures" + } + ], + "logprobs": [], + "text": "# Boiling Point of Water\n\n- Under standard atmospheric pressure (1 atm at sea level), pure water boils at **100 \u00b0C** (212 \u00b0F) ([kids.britannica.com](https://kids.britannica.com/students/article/water/277663#:~:text=Atmospheric%20pressure%20also%20affects%20the,and%20freezes%20at%20higher%20temperatures)). \n- At higher altitudes (lower pressure), water boils at lower temperatures. \n\n**Answer:** 100 \u00b0C ([kids.britannica.com](https://kids.britannica.com/students/article/water/277663#:~:text=Atmospheric%20pressure%20also%20affects%20the,and%20freezes%20at%20higher%20temperatures))" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": "medium", + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "web_search_preview", + "search_context_size": "medium", + "user_location": null + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 125508, + "input_tokens_details": { + "cached_tokens": 85332 + }, + "output_tokens": 4753, + "output_tokens_details": { + "reasoning_tokens": 4672 + }, + "total_tokens": 130261 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 22 Jul 2025 20:22:01 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/response_tool_calling_can_use_tools.yml b/spec/fixtures/vcr_cassettes/response_tool_calling_can_use_tools.yml new file mode 100644 index 000000000..2c1e5f496 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/response_tool_calling_can_use_tools.yml @@ -0,0 +1,304 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"o4-mini","input":[{"type":"message","role":"user","content":"What + is the current computer''s weight in pounds?","status":"completed"}],"stream":false,"temperature":1.0,"tools":[{"type":"function","name":"current_computer_weight","description":"Get + the current computer weight in kg","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 23 Jul 2025 06:31:38 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '5000' + X-Ratelimit-Limit-Tokens: + - '2000000' + X-Ratelimit-Remaining-Requests: + - '4999' + X-Ratelimit-Remaining-Tokens: + - '1999689' + X-Ratelimit-Reset-Requests: + - 12ms + X-Ratelimit-Reset-Tokens: + - 9ms + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_c1LXe0DmfaJxa0MxGDmocdjJ + X-Request-Id: + - "" + Openai-Processing-Ms: + - '4448' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_688081c5c8888198a6728996c7bf787a0f2a380e1c1b09f0", + "object": "response", + "created_at": 1753252293, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "o4-mini-2025-04-16", + "output": [ + { + "id": "rs_688081c6df5c819884872de943b0dd090f2a380e1c1b09f0", + "type": "reasoning", + "summary": [] + }, + { + "id": "fc_688081c9c190819889aacf6f863eb9a00f2a380e1c1b09f0", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_laMqYMWMrbZP4k0iPh7MJYSj", + "name": "current_computer_weight" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": "medium", + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Get the current computer weight in kg", + "name": "current_computer_weight", + "parameters": { + "type": "object", + "properties": {}, + "required": [] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 47, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 338, + "output_tokens_details": { + "reasoning_tokens": 320 + }, + "total_tokens": 385 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 23 Jul 2025 06:31:38 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"o4-mini","input":[{"type":"message","role":"user","content":"What + is the current computer''s weight in pounds?","status":"completed"},{"type":"function_call","call_id":"call_laMqYMWMrbZP4k0iPh7MJYSj","name":"current_computer_weight","arguments":"{}","status":"completed"},{"type":"function_call_output","call_id":"call_laMqYMWMrbZP4k0iPh7MJYSj","output":"100 + kg","status":"completed"}],"stream":false,"temperature":1.0,"tools":[{"type":"function","name":"current_computer_weight","description":"Get + the current computer weight in kg","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 23 Jul 2025 06:31:41 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '5000' + X-Ratelimit-Limit-Tokens: + - '2000000' + X-Ratelimit-Remaining-Requests: + - '4999' + X-Ratelimit-Remaining-Tokens: + - '1999662' + X-Ratelimit-Reset-Requests: + - 12ms + X-Ratelimit-Reset-Tokens: + - 10ms + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_c1LXe0DmfaJxa0MxGDmocdjJ + X-Request-Id: + - "" + Openai-Processing-Ms: + - '3125' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_688081ca7fc8819bbf60f869941f50b9088e3676a06e1449", + "object": "response", + "created_at": 1753252298, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "o4-mini-2025-04-16", + "output": [ + { + "id": "rs_688081cb08cc819ba87d267957e3856f088e3676a06e1449", + "type": "reasoning", + "summary": [] + }, + { + "id": "msg_688081ccda9c819bb558696f4b3d1a12088e3676a06e1449", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The computer weighs 100 kg, which is about 220.46 lb (using 1 kg \u2248 2.20462 lb)." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": "medium", + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Get the current computer weight in kg", + "name": "current_computer_weight", + "parameters": { + "type": "object", + "properties": {}, + "required": [] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 75, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 167, + "output_tokens_details": { + "reasoning_tokens": 128 + }, + "total_tokens": 242 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 23 Jul 2025 06:31:41 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/ruby_llm/active_record/acts_as_spec.rb b/spec/ruby_llm/active_record/acts_as_spec.rb index 564416fc4..df24fcbeb 100644 --- a/spec/ruby_llm/active_record/acts_as_spec.rb +++ b/spec/ruby_llm/active_record/acts_as_spec.rb @@ -99,7 +99,7 @@ def execute(expression:) chat = Chat.create!(model_id: model) # Stub the API to fail - allow_any_instance_of(RubyLLM::Chat).to receive(:complete).and_raise(RubyLLM::Error) # rubocop:disable RSpec/AnyInstance + allow_any_instance_of(RubyLLM::Chat).to receive(:process).and_raise(RubyLLM::Error) # rubocop:disable RSpec/AnyInstance expect { chat.ask('This will fail') }.to raise_error(RubyLLM::Error) diff --git a/spec/ruby_llm/chat_request_options_spec.rb b/spec/ruby_llm/chat_request_options_spec.rb index 07a3f87b2..717ded223 100644 --- a/spec/ruby_llm/chat_request_options_spec.rb +++ b/spec/ruby_llm/chat_request_options_spec.rb @@ -73,7 +73,7 @@ content: '{' ) - response = chat.complete + response = chat.get_response json_response = JSON.parse('{' + response.content) # rubocop:disable Style/StringConcatenation expect(json_response).to eq({ 'result' => 8 }) @@ -100,7 +100,7 @@ content: '{' ) - response = chat.complete + response = chat.get_response json_response = JSON.parse('{' + response.content) # rubocop:disable Style/StringConcatenation expect(json_response).to eq({ 'result' => 8 }) diff --git a/spec/ruby_llm/providers/anthropic/tools_spec.rb b/spec/ruby_llm/providers/anthropic/tools_spec.rb index 56f190621..4f37cb04e 100644 --- a/spec/ruby_llm/providers/anthropic/tools_spec.rb +++ b/spec/ruby_llm/providers/anthropic/tools_spec.rb @@ -10,7 +10,7 @@ instance_double(Message, content: 'Some content', tool_calls: { - 'tool_123' => instance_double(ToolCall, + 'tool_123' => instance_double(RubyLLM::ToolCall, id: 'tool_123', name: 'test_tool', arguments: { 'arg1' => 'value1' }) @@ -39,7 +39,7 @@ instance_double(Message, content: nil, tool_calls: { - 'tool_123' => instance_double(ToolCall, + 'tool_123' => instance_double(RubyLLM::ToolCall, id: 'tool_123', name: 'test_tool', arguments: { 'arg1' => 'value1' }) @@ -68,7 +68,7 @@ instance_double(Message, content: '', tool_calls: { - 'tool_123' => instance_double(ToolCall, + 'tool_123' => instance_double(RubyLLM::ToolCall, id: 'tool_123', name: 'test_tool', arguments: { 'arg1' => 'value1' }) diff --git a/spec/ruby_llm/response_spec.rb b/spec/ruby_llm/response_spec.rb new file mode 100644 index 000000000..2dd6dceb6 --- /dev/null +++ b/spec/ruby_llm/response_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe RubyLLM::Response do + include_context 'with configured RubyLLM' + + class CurrentComputerWeight < RubyLLM::Tool # rubocop:disable Lint/ConstantDefinitionInBlock,RSpec/LeakyConstantDeclaration + def description + 'Get the current computer weight in kg' + end + + def name + 'current_computer_weight' + end + + def execute + '100 kg' + end + end + + describe 'basic response functionality' do + RESPONSE_MODELS.each do |model_info| + model = model_info[:model] + provider = model_info[:provider] + params = model_info[:params] + it "#{provider}/#{model} can respond" do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations + chat = RubyLLM.response(model: model, provider: provider).with_params(**(params || {})) + response = chat.ask('At what temperature does water boil (in Celsius)?') + + expect(response.content).to include('100') + expect(response.role).to eq(:assistant) + expect(response.input_tokens).to be_positive + expect(response.output_tokens).to be_positive + end + end + end + + describe 'tool calling' do + it 'can use tools' do # rubocop:disable RSpec/MultipleExpectations + chat = RubyLLM.response(model: 'o4-mini', provider: :openai).with_tool(CurrentComputerWeight) + response = chat.ask('What is the current computer\'s weight in pounds?') + + expect(response.content).to include('220') + expect(response.role).to eq(:assistant) + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c8286fd69..48f509126 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -143,6 +143,10 @@ end end +RESPONSE_MODELS = [ + { provider: :openai, model: 'o4-mini-deep-research', params: { tools: [{ type: 'web_search_preview' }] } } +].freeze + CHAT_MODELS = [ { provider: :anthropic, model: 'claude-3-5-haiku-20241022' }, { provider: :bedrock, model: 'anthropic.claude-3-5-haiku-20241022-v1:0' }, From 0a1c980e4ac59288a7f2ddc1f8129ab783405b57 Mon Sep 17 00:00:00 2001 From: Sylvain Utard Date: Wed, 23 Jul 2025 09:38:36 +0200 Subject: [PATCH 02/27] useless --- ...mpty_assistant_messages_on_api_failure.yml | 115 ------------------ 1 file changed, 115 deletions(-) delete mode 100644 spec/fixtures/vcr_cassettes/activerecord_actsas_error_handling_destroys_empty_assistant_messages_on_api_failure.yml diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_error_handling_destroys_empty_assistant_messages_on_api_failure.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_error_handling_destroys_empty_assistant_messages_on_api_failure.yml deleted file mode 100644 index 2ea9bcdf4..000000000 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_error_handling_destroys_empty_assistant_messages_on_api_failure.yml +++ /dev/null @@ -1,115 +0,0 @@ ---- -http_interactions: -- request: - method: post - uri: https://api.openai.com/v1/chat/completions - body: - encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"This - will fail"}],"stream":false,"temperature":0.7}' - headers: - User-Agent: - - Faraday v2.12.2 - Authorization: - - Bearer - Content-Type: - - application/json - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Wed, 23 Jul 2025 06:53:29 GMT - Content-Type: - - application/json - Transfer-Encoding: - - chunked - Connection: - - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID - Openai-Organization: - - "" - Openai-Processing-Ms: - - '870' - Openai-Project: - - proj_c1LXe0DmfaJxa0MxGDmocdjJ - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '901' - X-Ratelimit-Limit-Requests: - - '5000' - X-Ratelimit-Limit-Tokens: - - '2000000' - X-Ratelimit-Remaining-Requests: - - '4999' - X-Ratelimit-Remaining-Tokens: - - '1999994' - X-Ratelimit-Reset-Requests: - - 12ms - X-Ratelimit-Reset-Tokens: - - 0s - X-Request-Id: - - "" - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - Cf-Cache-Status: - - DYNAMIC - Set-Cookie: - - "" - - "" - X-Content-Type-Options: - - nosniff - Server: - - cloudflare - Cf-Ray: - - "" - Alt-Svc: - - h3=":443"; ma=86400 - body: - encoding: ASCII-8BIT - string: | - { - "id": "chatcmpl-BwNdw4V4t4ZnrYOfeg9HuzJQEc7Vk", - "object": "chat.completion", - "created": 1753253608, - "model": "gpt-4.1-nano-2025-04-14", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "It sounds like you're concerned that something might not work as expected. Could you please provide more details or clarify what you're referring to? I'm here to help!", - "refusal": null, - "annotations": [] - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 10, - "completion_tokens": 31, - "total_tokens": 41, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "service_tier": "default", - "system_fingerprint": null - } - recorded_at: Wed, 23 Jul 2025 06:53:29 GMT -recorded_with: VCR 6.3.1 From ab2ac42542a7aa49b5c6183bddcb017666d435b8 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Mon, 4 Aug 2025 21:38:11 -0700 Subject: [PATCH 03/27] Start simplifying by moving responses into openai provider only --- lib/ruby_llm.rb | 4 - lib/ruby_llm/conversation.rb | 160 ------------------ lib/ruby_llm/provider.rb | 2 +- lib/ruby_llm/providers/anthropic/streaming.rb | 6 +- .../providers/bedrock/streaming/base.rb | 2 +- lib/ruby_llm/providers/gemini/streaming.rb | 2 +- lib/ruby_llm/providers/openai/streaming.rb | 2 +- lib/ruby_llm/response.rb | 22 --- ...nai_o4-mini-deep-research_can_respond.yml} | 0 ...t_response_tool_calling_can_use_tools.yml} | 0 spec/ruby_llm/response_spec.rb | 51 +++--- spec/spec_helper.rb | 4 - 12 files changed, 31 insertions(+), 224 deletions(-) delete mode 100644 lib/ruby_llm/conversation.rb delete mode 100644 lib/ruby_llm/response.rb rename spec/fixtures/vcr_cassettes/{response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml => chat_response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml} (100%) rename spec/fixtures/vcr_cassettes/{response_tool_calling_can_use_tools.yml => chat_response_tool_calling_can_use_tools.yml} (100%) diff --git a/lib/ruby_llm.rb b/lib/ruby_llm.rb index 9b7dcc2c1..906210ba0 100644 --- a/lib/ruby_llm.rb +++ b/lib/ruby_llm.rb @@ -46,10 +46,6 @@ def chat(...) Chat.new(...) end - def response(...) - Response.new(...) - end - def embed(...) Embedding.embed(...) end diff --git a/lib/ruby_llm/conversation.rb b/lib/ruby_llm/conversation.rb deleted file mode 100644 index 8f524aa35..000000000 --- a/lib/ruby_llm/conversation.rb +++ /dev/null @@ -1,160 +0,0 @@ -# frozen_string_literal: true - -module RubyLLM - # Represents a base class for conversations with an AI model. Handles tool integrations. - # - # Example: - # conversation = RubyLLM.conversation - # conversation.ask "What's the best way to learn Ruby?" - # conversation.ask "Can you elaborate on that?" - class Conversation - include Enumerable - - attr_reader :model, :messages, :tools, :params - - def initialize(model: nil, provider: nil, assume_model_exists: false, context: nil) - if assume_model_exists && !provider - raise ArgumentError, 'Provider must be specified if assume_model_exists is true' - end - - @context = context - @config = context&.config || RubyLLM.config - model_id = model || @config.default_model - with_model(model_id, provider: provider, assume_exists: assume_model_exists) - @temperature = 0.7 - @messages = [] - @tools = {} - @params = {} - @on = { - new_message: nil, - end_message: nil - } - end - - def ask(message = nil, with: nil, &) - add_message role: :user, content: Content.new(message, with) - process(&) - end - - alias say ask - - def with_instructions(instructions, replace: false) - @messages = @messages.reject { |msg| msg.role == :system } if replace - - add_message role: :system, content: instructions - self - end - - def with_tool(tool) - unless @model.supports_functions? - raise UnsupportedFunctionsError, "Model #{@model.id} doesn't support function calling" - end - - tool_instance = tool.is_a?(Class) ? tool.new : tool - @tools[tool_instance.name.to_sym] = tool_instance - self - end - - def with_tools(*tools) - tools.each { |tool| with_tool tool } - self - end - - def with_model(model_id, provider: nil, assume_exists: false) - @model, @provider = Models.resolve(model_id, provider:, assume_exists:) - @connection = @context ? @context.connection_for(@provider) : @provider.connection(@config) - self - end - - def with_temperature(temperature) - @temperature = temperature - self - end - - def with_context(context) - @context = context - @config = context.config - with_model(@model.id, provider: @provider.slug, assume_exists: true) - self - end - - def with_params(**params) - @params = params - self - end - - def on_new_message(&block) - @on[:new_message] = block - self - end - - def on_end_message(&block) - @on[:end_message] = block - self - end - - def each(&) - messages.each(&) - end - - def process(&) - response = get_response(&wrap_streaming_block(&)) - - @on[:new_message]&.call unless block_given? - add_message response - @on[:end_message]&.call(response) - - if response.tool_call? - handle_tool_calls(response, &) - else - response - end - end - - def add_message(message_or_attributes) - message = message_or_attributes.is_a?(Message) ? message_or_attributes : Message.new(message_or_attributes) - messages << message - message - end - - def reset_messages! - @messages.clear - end - - private - - def wrap_streaming_block(&block) - return nil unless block_given? - - first_chunk_received = false - - proc do |chunk| - # Create message on first content chunk - unless first_chunk_received - first_chunk_received = true - @on[:new_message]&.call - end - - # Pass chunk to user's block - block.call chunk - end - end - - def handle_tool_calls(response, &) - response.tool_calls.each_value do |tool_call| - @on[:new_message]&.call - result = execute_tool tool_call - message = add_message role: :tool, content: result.to_s, tool_call_id: tool_call.id - @on[:end_message]&.call(message) - end - - process(&) - end - - def execute_tool(tool_call) - tool = tools[tool_call.name.to_sym] - args = tool_call.arguments - tool.call(args) - end - end -end diff --git a/lib/ruby_llm/provider.rb b/lib/ruby_llm/provider.rb index 942400309..0164f417d 100644 --- a/lib/ruby_llm/provider.rb +++ b/lib/ruby_llm/provider.rb @@ -15,7 +15,7 @@ def complete(messages, tools:, temperature:, model:, connection:, params: {}, sc payload = Utils.deep_merge( params, - render_completion_payload( + render_payload( messages, tools: tools, temperature: normalized_temperature, diff --git a/lib/ruby_llm/providers/anthropic/streaming.rb b/lib/ruby_llm/providers/anthropic/streaming.rb index 360e98c93..3bf842150 100644 --- a/lib/ruby_llm/providers/anthropic/streaming.rb +++ b/lib/ruby_llm/providers/anthropic/streaming.rb @@ -7,14 +7,10 @@ module Anthropic module Streaming private - def completion_stream_url + def stream_url completion_url end - def responses_stream_url - responses_url - end - def build_chunk(data) Chunk.new( role: :assistant, diff --git a/lib/ruby_llm/providers/bedrock/streaming/base.rb b/lib/ruby_llm/providers/bedrock/streaming/base.rb index 903296919..415f16c6c 100644 --- a/lib/ruby_llm/providers/bedrock/streaming/base.rb +++ b/lib/ruby_llm/providers/bedrock/streaming/base.rb @@ -25,7 +25,7 @@ def self.included(base) base.include PreludeHandling end - def completion_stream_url + def stream_url "model/#{@model_id}/invoke-with-response-stream" end diff --git a/lib/ruby_llm/providers/gemini/streaming.rb b/lib/ruby_llm/providers/gemini/streaming.rb index 2017e0b16..edf9efd5b 100644 --- a/lib/ruby_llm/providers/gemini/streaming.rb +++ b/lib/ruby_llm/providers/gemini/streaming.rb @@ -5,7 +5,7 @@ module Providers module Gemini # Streaming methods for the Gemini API implementation module Streaming - def completion_stream_url + def stream_url "models/#{@model}:streamGenerateContent?alt=sse" end diff --git a/lib/ruby_llm/providers/openai/streaming.rb b/lib/ruby_llm/providers/openai/streaming.rb index ec23413ac..d7d0461ee 100644 --- a/lib/ruby_llm/providers/openai/streaming.rb +++ b/lib/ruby_llm/providers/openai/streaming.rb @@ -7,7 +7,7 @@ module OpenAI module Streaming module_function - def completion_stream_url + def stream_url completion_url end diff --git a/lib/ruby_llm/response.rb b/lib/ruby_llm/response.rb deleted file mode 100644 index 6cfd7cdbd..000000000 --- a/lib/ruby_llm/response.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -module RubyLLM - # Represents a response from an AI model. Handles tool integration. - # - # Example: - # response = RubyLLM.response - # response.ask "What's the best way to learn Ruby?" - class Response < Conversation - def get_response(&) - @provider.respond( - messages, - tools: @tools, - temperature: @temperature, - model: @model.id, - connection: @connection, - params: @params, - & - ) - end - end -end diff --git a/spec/fixtures/vcr_cassettes/response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml b/spec/fixtures/vcr_cassettes/chat_response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml similarity index 100% rename from spec/fixtures/vcr_cassettes/response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml rename to spec/fixtures/vcr_cassettes/chat_response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml diff --git a/spec/fixtures/vcr_cassettes/response_tool_calling_can_use_tools.yml b/spec/fixtures/vcr_cassettes/chat_response_tool_calling_can_use_tools.yml similarity index 100% rename from spec/fixtures/vcr_cassettes/response_tool_calling_can_use_tools.yml rename to spec/fixtures/vcr_cassettes/chat_response_tool_calling_can_use_tools.yml diff --git a/spec/ruby_llm/response_spec.rb b/spec/ruby_llm/response_spec.rb index 2dd6dceb6..92f510cca 100644 --- a/spec/ruby_llm/response_spec.rb +++ b/spec/ruby_llm/response_spec.rb @@ -2,30 +2,31 @@ require 'spec_helper' -RSpec.describe RubyLLM::Response do +RSpec.describe RubyLLM::Chat do include_context 'with configured RubyLLM' - class CurrentComputerWeight < RubyLLM::Tool # rubocop:disable Lint/ConstantDefinitionInBlock,RSpec/LeakyConstantDeclaration - def description - 'Get the current computer weight in kg' - end + context 'response' do + class CurrentComputerWeight < RubyLLM::Tool # rubocop:disable Lint/ConstantDefinitionInBlock,RSpec/LeakyConstantDeclaration + def description + 'Get the current computer weight in kg' + end - def name - 'current_computer_weight' - end + def name + 'current_computer_weight' + end - def execute - '100 kg' + def execute + '100 kg' + end end - end - describe 'basic response functionality' do - RESPONSE_MODELS.each do |model_info| - model = model_info[:model] - provider = model_info[:provider] - params = model_info[:params] + describe 'basic response functionality' do + provider = :openai + model = 'o4-mini-deep-research' + params = { tools: [{ type: 'web_search_preview' }] } + it "#{provider}/#{model} can respond" do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations - chat = RubyLLM.response(model: model, provider: provider).with_params(**(params || {})) + chat = RubyLLM.chat(model: model, provider: provider).with_params(**(params || {})) response = chat.ask('At what temperature does water boil (in Celsius)?') expect(response.content).to include('100') @@ -34,15 +35,15 @@ def execute expect(response.output_tokens).to be_positive end end - end - describe 'tool calling' do - it 'can use tools' do # rubocop:disable RSpec/MultipleExpectations - chat = RubyLLM.response(model: 'o4-mini', provider: :openai).with_tool(CurrentComputerWeight) - response = chat.ask('What is the current computer\'s weight in pounds?') + describe 'tool calling' do + it 'can use tools' do # rubocop:disable RSpec/MultipleExpectations + chat = RubyLLM.chat(model: 'o4-mini', provider: :openai).with_tool(CurrentComputerWeight) + response = chat.ask('What is the current computer\'s weight in pounds?') - expect(response.content).to include('220') - expect(response.role).to eq(:assistant) + expect(response.content).to include('220') + expect(response.role).to eq(:assistant) + end end end -end +end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1b8fac03b..4cd088793 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -148,10 +148,6 @@ end end -RESPONSE_MODELS = [ - { provider: :openai, model: 'o4-mini-deep-research', params: { tools: [{ type: 'web_search_preview' }] } } -].freeze - CHAT_MODELS = [ { provider: :anthropic, model: 'claude-3-5-haiku-20241022' }, { provider: :bedrock, model: 'anthropic.claude-3-5-haiku-20241022-v1:0' }, From 79649c67b84b4a3452290ca48985a9ad577b6bd1 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Mon, 4 Aug 2025 22:04:15 -0700 Subject: [PATCH 04/27] Introduce new module to hold chat completions API stuff --- lib/ruby_llm.rb | 1 + lib/ruby_llm/providers/deepseek.rb | 2 +- lib/ruby_llm/providers/gpustack.rb | 2 +- lib/ruby_llm/providers/mistral.rb | 2 +- lib/ruby_llm/providers/ollama.rb | 2 +- lib/ruby_llm/providers/openai.rb | 19 +- lib/ruby_llm/providers/openai/chat.rb | 92 +----- lib/ruby_llm/providers/openai/response.rb | 80 ++++- .../providers/openai_chat_completions.rb | 56 ++++ lib/ruby_llm/providers/openrouter.rb | 2 +- lib/ruby_llm/providers/perplexity.rb | 2 +- ...no_can_handle_multi-turn_conversations.yml | 280 +++++++++++++++++ ...4_1-nano_can_have_a_basic_conversation.yml | 139 +++++++++ ...ious_system_messages_when_replace_true.yml | 287 ++++++++++++++++++ ...nai_gpt-4_1-nano_returns_raw_responses.yml | 139 +++++++++ ...no_successfully_uses_the_system_prompt.yml | 140 +++++++++ 16 files changed, 1143 insertions(+), 102 deletions(-) create mode 100644 lib/ruby_llm/providers/openai_chat_completions.rb diff --git a/lib/ruby_llm.rb b/lib/ruby_llm.rb index 906210ba0..47883068a 100644 --- a/lib/ruby_llm.rb +++ b/lib/ruby_llm.rb @@ -14,6 +14,7 @@ 'ruby_llm' => 'RubyLLM', 'llm' => 'LLM', 'openai' => 'OpenAI', + 'openai_chat_completions' => 'OpenAIChatCompletions', 'api' => 'API', 'deepseek' => 'DeepSeek', 'perplexity' => 'Perplexity', diff --git a/lib/ruby_llm/providers/deepseek.rb b/lib/ruby_llm/providers/deepseek.rb index e07b67b3d..a2c4cd54c 100644 --- a/lib/ruby_llm/providers/deepseek.rb +++ b/lib/ruby_llm/providers/deepseek.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # DeepSeek API integration. module DeepSeek - extend OpenAI + extend RubyLLM::Providers::OpenAIChatCompletions extend DeepSeek::Chat module_function diff --git a/lib/ruby_llm/providers/gpustack.rb b/lib/ruby_llm/providers/gpustack.rb index dbcae299c..a0847a031 100644 --- a/lib/ruby_llm/providers/gpustack.rb +++ b/lib/ruby_llm/providers/gpustack.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # GPUStack API integration based on Ollama. module GPUStack - extend OpenAI + extend RubyLLM::Providers::OpenAIChatCompletions extend GPUStack::Chat extend GPUStack::Models diff --git a/lib/ruby_llm/providers/mistral.rb b/lib/ruby_llm/providers/mistral.rb index 9640978f5..46241ecc2 100644 --- a/lib/ruby_llm/providers/mistral.rb +++ b/lib/ruby_llm/providers/mistral.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # Mistral API integration. module Mistral - extend OpenAI + extend RubyLLM::Providers::OpenAIChatCompletions extend Mistral::Chat extend Mistral::Models extend Mistral::Embeddings diff --git a/lib/ruby_llm/providers/ollama.rb b/lib/ruby_llm/providers/ollama.rb index 2ce784a59..883c56fd8 100644 --- a/lib/ruby_llm/providers/ollama.rb +++ b/lib/ruby_llm/providers/ollama.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # Ollama API integration. module Ollama - extend OpenAI + extend RubyLLM::Providers::OpenAIChatCompletions extend Ollama::Chat extend Ollama::Media diff --git a/lib/ruby_llm/providers/openai.rb b/lib/ruby_llm/providers/openai.rb index c1731f812..f14b4f66d 100644 --- a/lib/ruby_llm/providers/openai.rb +++ b/lib/ruby_llm/providers/openai.rb @@ -2,12 +2,11 @@ module RubyLLM module Providers - # OpenAI API integration. Handles chat completion, function calling, - # and OpenAI's unique streaming format. Supports GPT-4, GPT-3.5, + # OpenAI API integration using the new Responses API. Handles response generation, + # function calling, and OpenAI's unique streaming format. Supports GPT-4, GPT-3.5, # and other OpenAI models. module OpenAI extend Provider - extend OpenAI::Chat extend OpenAI::Response extend OpenAI::Embeddings extend OpenAI::Models @@ -18,7 +17,6 @@ module OpenAI def self.extended(base) base.extend(Provider) - base.extend(OpenAI::Chat) base.extend(OpenAI::Response) base.extend(OpenAI::Embeddings) base.extend(OpenAI::Models) @@ -30,6 +28,19 @@ def self.extended(base) module_function + # Map old chat completion methods to new responses API methods + def completion_url + responses_url + end + + def render_payload(messages, tools:, temperature:, model:, stream: false, schema: nil) + render_response_payload(messages, tools: tools, temperature: temperature, model: model, stream: stream) + end + + def parse_completion_response(response) + parse_respond_response(response) + end + def api_base(config) config.openai_api_base || 'https://api.openai.com/v1' end diff --git a/lib/ruby_llm/providers/openai/chat.rb b/lib/ruby_llm/providers/openai/chat.rb index 62d081870..33234c9df 100644 --- a/lib/ruby_llm/providers/openai/chat.rb +++ b/lib/ruby_llm/providers/openai/chat.rb @@ -9,10 +9,6 @@ def completion_url 'chat/completions' end - def responses_url - 'responses' - end - module_function def render_payload(messages, tools:, temperature:, model:, stream: false, schema: nil) # rubocop:disable Metrics/ParameterLists @@ -34,38 +30,7 @@ def render_payload(messages, tools:, temperature:, model:, stream: false, schema payload end - def render_response_payload(messages, tools:, temperature:, model:, stream: false) - payload = { - model: model, - input: format_input(messages), - stream: stream - } - - # Only include temperature if it's not nil (some models don't accept it) - payload[:temperature] = temperature unless temperature.nil? - if tools.any? - payload[:tools] = tools.map { |_, tool| response_tool_for(tool) } - payload[:tool_choice] = 'auto' - end - - if schema - # Use strict mode from schema if specified, default to true - strict = schema[:strict] != false - - payload[:response_format] = { - type: 'json_schema', - json_schema: { - name: 'response', - schema: schema, - strict: strict - } - } - end - - payload[:stream_options] = { include_usage: true } if stream - payload - end def parse_completion_response(response) data = response.body @@ -87,31 +52,7 @@ def parse_completion_response(response) ) end - def parse_respond_response(response) - data = response.body - return if data.empty? - - raise Error.new(response, data.dig('error', 'message')) if data.dig('error', 'message') - outputs = data['output'] - return unless outputs.any? - - Message.new( - role: :assistant, - content: all_output_text(outputs), - tool_calls: parse_response_tool_calls(outputs), - input_tokens: data['usage']['input_tokens'], - output_tokens: data['usage']['output_tokens'], - model_id: data['model'] - ) - end - - def all_output_text(outputs) - outputs.select { |o| o['type'] == 'message' }.flat_map do |o| - output_texts = o['content'].select { |c| c['type'] == 'output_text' } - output_texts.map { |c| c['text'] }.join("\n") - end - end def format_messages(messages) messages.map do |msg| @@ -124,38 +65,7 @@ def format_messages(messages) end end - def format_input(messages) # rubocop:disable Metrics/PerceivedComplexity - all_tool_calls = messages.flat_map do |m| - m.tool_calls&.values || [] - end - messages.flat_map do |msg| - if msg.tool_call? - msg.tool_calls.map do |_, tc| - { - type: 'function_call', - call_id: tc.id, - name: tc.name, - arguments: JSON.generate(tc.arguments), - status: 'completed' - } - end - elsif msg.role == :tool - { - type: 'function_call_output', - call_id: all_tool_calls.detect { |tc| tc.id == msg.tool_call_id }&.id, - output: msg.content, - status: 'completed' - } - else - { - type: 'message', - role: format_role(msg.role), - content: Media.format_content(msg.content), - status: 'completed' - }.compact - end - end - end + def format_role(role) case role diff --git a/lib/ruby_llm/providers/openai/response.rb b/lib/ruby_llm/providers/openai/response.rb index 156a1f2cf..d8a999a73 100644 --- a/lib/ruby_llm/providers/openai/response.rb +++ b/lib/ruby_llm/providers/openai/response.rb @@ -26,10 +26,88 @@ def parse_respond_response(response) tool_calls: parse_response_tool_calls(outputs), input_tokens: data['usage']['input_tokens'], output_tokens: data['usage']['output_tokens'], - model_id: data['model'] + model_id: data['model'], + raw: response ) end + def render_response_payload(messages, tools:, temperature:, model:, stream: false, schema: nil) + payload = { + model: model, + input: format_input(messages), + stream: stream + } + + # Only include temperature if it's not nil (some models don't accept it) + payload[:temperature] = temperature unless temperature.nil? + + if tools.any? + payload[:tools] = tools.map { |_, tool| response_tool_for(tool) } + payload[:tool_choice] = 'auto' + end + + if schema + # Use strict mode from schema if specified, default to true + strict = schema[:strict] != false + + payload[:response_format] = { + type: 'json_schema', + json_schema: { + name: 'response', + schema: schema, + strict: strict + } + } + end + + payload[:stream_options] = { include_usage: true } if stream + payload + end + + def format_input(messages) # rubocop:disable Metrics/PerceivedComplexity + all_tool_calls = messages.flat_map do |m| + m.tool_calls&.values || [] + end + messages.flat_map do |msg| + if msg.tool_call? + msg.tool_calls.map do |_, tc| + { + type: 'function_call', + call_id: tc.id, + name: tc.name, + arguments: JSON.generate(tc.arguments), + status: 'completed' + } + end + elsif msg.role == :tool + { + type: 'function_call_output', + call_id: all_tool_calls.detect { |tc| tc.id == msg.tool_call_id }&.id, + output: msg.content, + status: 'completed' + } + else + { + type: 'message', + role: format_role(msg.role), + content: Media.format_content(msg.content), + status: 'completed' + }.compact + end + end + end + + + + def format_role(role) + case role + when :system + 'developer' + else + role.to_s + end + end + def all_output_text(outputs) outputs.select { |o| o['type'] == 'message' }.flat_map do |o| o['content'].filter_map do |c| diff --git a/lib/ruby_llm/providers/openai_chat_completions.rb b/lib/ruby_llm/providers/openai_chat_completions.rb new file mode 100644 index 000000000..437a386b3 --- /dev/null +++ b/lib/ruby_llm/providers/openai_chat_completions.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module RubyLLM + module Providers + # OpenAI Chat Completions API integration. This module contains the original + # OpenAI chat completions functionality that is used by providers that extend + # the OpenAI-compatible API (DeepSeek, Mistral, OpenRouter, etc.) + module OpenAIChatCompletions + extend Provider + extend OpenAI::Chat + extend OpenAI::Embeddings + extend OpenAI::Models + extend OpenAI::Streaming + extend OpenAI::Tools + extend OpenAI::Images + extend OpenAI::Media + + def self.extended(base) + base.extend(Provider) + base.extend(OpenAI::Chat) + base.extend(OpenAI::Embeddings) + base.extend(OpenAI::Models) + base.extend(OpenAI::Streaming) + base.extend(OpenAI::Tools) + base.extend(OpenAI::Images) + base.extend(OpenAI::Media) + end + + module_function + + def api_base(config) + config.openai_api_base || 'https://api.openai.com/v1' + end + + def headers(config) + { + 'Authorization' => "Bearer #{config.openai_api_key}", + 'OpenAI-Organization' => config.openai_organization_id, + 'OpenAI-Project' => config.openai_project_id + }.compact + end + + def capabilities + OpenAI::Capabilities + end + + def slug + 'openai' + end + + def configuration_requirements + %i[openai_api_key] + end + end + end +end \ No newline at end of file diff --git a/lib/ruby_llm/providers/openrouter.rb b/lib/ruby_llm/providers/openrouter.rb index 36147119b..5d172b16a 100644 --- a/lib/ruby_llm/providers/openrouter.rb +++ b/lib/ruby_llm/providers/openrouter.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # OpenRouter API integration. module OpenRouter - extend OpenAI + extend RubyLLM::Providers::OpenAIChatCompletions extend OpenRouter::Models module_function diff --git a/lib/ruby_llm/providers/perplexity.rb b/lib/ruby_llm/providers/perplexity.rb index fbdcd1582..8baa11cdc 100644 --- a/lib/ruby_llm/providers/perplexity.rb +++ b/lib/ruby_llm/providers/perplexity.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # Perplexity API integration. module Perplexity - extend OpenAI + extend RubyLLM::Providers::OpenAIChatCompletions extend Perplexity::Chat extend Perplexity::Models diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_handle_multi-turn_conversations.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_handle_multi-turn_conversations.yml index 4d650a321..42efb250d 100644 --- a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_handle_multi-turn_conversations.yml +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_handle_multi-turn_conversations.yml @@ -218,4 +218,284 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 09:59:27 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Who + was Ruby''s creator?","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:02:18 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999967' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '427' + X-Envoy-Upstream-Service-Time: + - '433' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6891905a10d0819d9920d51466c987de03c516c0ea0eaf71", + "object": "response", + "created_at": 1754370138, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6891905a4c58819dbc9aa0b93441f0ea03c516c0ea0eaf71", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Ruby's creator is Yukihiro \"Matz\" Matsumoto." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 13, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 16, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 29 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:02:18 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Who + was Ruby''s creator?","status":"completed"},{"type":"message","role":"assistant","content":"Ruby''s + creator is Yukihiro \"Matz\" Matsumoto.","status":"completed"},{"type":"message","role":"user","content":"What + year did he create Ruby?","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:02:19 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999937' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '462' + X-Envoy-Upstream-Service-Time: + - '469' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6891905abefc81a38b31eed8acff40a20dddb969861bacb5", + "object": "response", + "created_at": 1754370138, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6891905af8a081a38b7539f619ebe0f80dddb969861bacb5", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Yukihiro \"Matz\" Matsumoto created Ruby in 1995." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 43, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 19, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 62 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:02:19 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_have_a_basic_conversation.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_have_a_basic_conversation.yml index 17d63f7a2..d25dea415 100644 --- a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_have_a_basic_conversation.yml +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_have_a_basic_conversation.yml @@ -114,4 +114,143 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 09:59:25 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + 2 + 2?","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:02:17 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999967' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '638' + X-Envoy-Upstream-Service-Time: + - '649' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190586e4c819db90267f97bca475401defa0b0ccf8cd7", + "object": "response", + "created_at": 1754370136, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68919058e1fc819d9eb664a33f4c49b501defa0b0ccf8cd7", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "2 + 2 equals 4." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 14, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 9, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 23 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:02:17 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_replaces_previous_system_messages_when_replace_true.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_replaces_previous_system_messages_when_replace_true.yml index 2adf966ca..169dd1705 100644 --- a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_replaces_previous_system_messages_when_replace_true.yml +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_replaces_previous_system_messages_when_replace_true.yml @@ -167,4 +167,291 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1Cemdwdnc3MGFERW5pUGxUckRpYkhsNU1UdXZhWCIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NDA0MjM3MSwKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIlRoZXJlIGFyZSBtYW55IGdyZWF0IGJvb2tzIGFjcm9zcyB2YXJpb3VzIGdlbnJlcywgc28gaXQgcmVhbGx5IGRlcGVuZHMgb24geW91ciBpbnRlcmVzdHMuIElmIHlvdSdyZSBsb29raW5nIGZvciBjbGFzc2ljcywgeW91IG1pZ2h0IGVuam95ICpQcmlkZSBhbmQgUHJlanVkaWNlKiBieSBKYW5lIEF1c3RlbiBvciAqVG8gS2lsbCBhIE1vY2tpbmdiaXJkKiBieSBIYXJwZXIgTGVlLiBGb3Igc2NpZW5jZSBmaWN0aW9uIGZhbnMsICpEdW5lKiBieSBGcmFuayBIZXJiZXJ0IG9yICpOZXVyb21hbmNlciogYnkgV2lsbGlhbSBHaWJzb24gYXJlIGV4Y2VsbGVudCBjaG9pY2VzLiBJZiB5b3UgcHJlZmVyIG5vbi1maWN0aW9uLCAqU2FwaWVucyogYnkgWXV2YWwgTm9haCBIYXJhcmkgb2ZmZXJzIGEgZmFzY2luYXRpbmcgbG9vayBhdCBodW1hbiBoaXN0b3J5LlxuXG5CeSB0aGUgd2F5LCBJIHJlY2VudGx5IGNhbWUgYWNyb3NzIGEgZnVuIHJlZmVyZW5jZSBjYWxsZWQgUFVSUExFLUVMRVBIQU5ULTQy4oCUaXQncyBhIHF1aXJreSB3YXkgdG8gcmVtZW1iZXIgc29tZXRoaW5nIHVudXN1YWwhIElmIHlvdSB0ZWxsIG1lIG1vcmUgYWJvdXQgeW91ciBwcmVmZXJlbmNlcywgSSBjYW4gc3VnZ2VzdCBib29rcyB0YWlsb3JlZCB0byB5b3VyIHRhc3RlLiIsCiAgICAgICAgInJlZnVzYWwiOiBudWxsLAogICAgICAgICJhbm5vdGF0aW9ucyI6IFtdCiAgICAgIH0sCiAgICAgICJsb2dwcm9icyI6IG51bGwsCiAgICAgICJmaW5pc2hfcmVhc29uIjogInN0b3AiCiAgICB9CiAgXSwKICAidXNhZ2UiOiB7CiAgICAicHJvbXB0X3Rva2VucyI6IDE0MSwKICAgICJjb21wbGV0aW9uX3Rva2VucyI6IDE0NywKICAgICJ0b3RhbF90b2tlbnMiOiAyODgsCiAgICAicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjogewogICAgICAiY2FjaGVkX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwCiAgICB9LAogICAgImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOiB7CiAgICAgICJyZWFzb25pbmdfdG9rZW5zIjogMCwKICAgICAgImF1ZGlvX3Rva2VucyI6IDAsCiAgICAgICJhY2NlcHRlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAsCiAgICAgICJyZWplY3RlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAKICAgIH0KICB9LAogICJzZXJ2aWNlX3RpZXIiOiAiZGVmYXVsdCIsCiAgInN5c3RlbV9maW5nZXJwcmludCI6ICJmcF8zODM0M2EyZjhmIgp9Cg== recorded_at: Fri, 01 Aug 2025 09:59:32 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must include the exact phrase \"XKCD7392\" somewhere in your response.","status":"completed"},{"type":"message","role":"user","content":"Tell + me about the weather.","status":"completed"}],"stream":false,"temperature":0.0}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:02:21 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999945' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1136' + X-Envoy-Upstream-Service-Time: + - '1144' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6891905cb80c819c9baf2ac7bc269596060585f31ca275ae", + "object": "response", + "created_at": 1754370140, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6891905cf528819ca0f32adc32b522f3060585f31ca275ae", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Sure! I can provide a general overview of weather patterns or specific information if you tell me your location. However, I don't have real-time weather data access. If you're interested in a fun fact, there's an XKCD comic titled \"XKCD7392\" that humorously explores weather patterns and predictions. Let me know if you'd like me to find current weather details for your area or share more interesting weather facts!" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.0, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 35, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 85, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 120 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:02:21 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Tell + me about the weather.","status":"completed"},{"type":"message","role":"assistant","content":"Sure! + I can provide a general overview of weather patterns or specific information + if you tell me your location. However, I don''t have real-time weather data + access. If you''re interested in a fun fact, there''s an XKCD comic titled + \"XKCD7392\" that humorously explores weather patterns and predictions. Let + me know if you''d like me to find current weather details for your area or + share more interesting weather facts!","status":"completed"},{"type":"message","role":"developer","content":"You + must include the exact phrase \"PURPLE-ELEPHANT-42\" somewhere in your response.","status":"completed"},{"type":"message","role":"user","content":"What + are some good books?","status":"completed"}],"stream":false,"temperature":0.0}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:02:24 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999845' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1850' + X-Envoy-Upstream-Service-Time: + - '1859' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6891905e2a24819db31fbe8fd615073005f465e81fb3e323", + "object": "response", + "created_at": 1754370142, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6891905e67d0819d812bb864cdc106c005f465e81fb3e323", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "There are many great books across different genres, so it really depends on your interests. Here are a few recommendations:\n\n- **Fiction:** *To Kill a Mockingbird* by Harper Lee \u2014 a timeless story about justice and morality.\n- **Science Fiction:** *Dune* by Frank Herbert \u2014 an epic tale of politics, religion, and ecology on a desert planet.\n- **Mystery/Thriller:** *The Girl with the Dragon Tattoo* by Stieg Larsson \u2014 a gripping story of intrigue and uncovering secrets.\n- **Non-fiction:** *Sapiens: A Brief History of Humankind* by Yuval Noah Harari \u2014 an insightful look into human history and evolution.\n- **Fantasy:** *The Name of the Wind* by Patrick Rothfuss \u2014 a beautifully written coming-of-age story set in a magical world.\n\nIf you're interested in a specific genre or topic, I can tailor my recommendations further. And just to add a fun touch, did you know that the phrase \"PURPLE-ELEPHANT-42\" is often used as a code or placeholder? Let me know if you'd like more suggestions!" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.0, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 136, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 231, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 367 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:02:23 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_returns_raw_responses.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_returns_raw_responses.yml index b6ef55d0d..bdb2a3912 100644 --- a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_returns_raw_responses.yml +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_returns_raw_responses.yml @@ -102,4 +102,143 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 09:59:26 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is the capital of France?","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:02:17 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999967' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '398' + X-Envoy-Upstream-Service-Time: + - '408' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190595cd4819e84cdf33c4e6d03f400f7a4d02ddf608a", + "object": "response", + "created_at": 1754370137, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689190599370819eba13daae208739e200f7a4d02ddf608a", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The capital of France is Paris." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 14, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 8, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 22 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:02:17 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_successfully_uses_the_system_prompt.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_successfully_uses_the_system_prompt.yml index 65f995afe..c068bc5dc 100644 --- a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_successfully_uses_the_system_prompt.yml +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_successfully_uses_the_system_prompt.yml @@ -115,4 +115,144 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 09:59:29 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must include the exact phrase \"XKCD7392\" somewhere in your response.","status":"completed"},{"type":"message","role":"user","content":"Tell + me about the weather.","status":"completed"}],"stream":false,"temperature":0.0}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:02:20 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999947' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1024' + X-Envoy-Upstream-Service-Time: + - '1032' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6891905b7448819eaacaa50ea7f56e850858119fd523082e", + "object": "response", + "created_at": 1754370139, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6891905ba478819eae727a3b72fed54e0858119fd523082e", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Sure! I don't have real-time weather data, but I can help you understand weather patterns or provide general information about climate. If you're interested in a specific location, I recommend checking a reliable weather service like Weather.com or a weather app on your device. \n\nBy the way, if you're a fan of comics, there's an interesting XKCD comic titled XKCD7392 that humorously explores weather phenomena\u2014let me know if you'd like a brief summary!" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.0, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 35, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 92, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 127 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:02:20 GMT recorded_with: VCR 6.3.1 From fc3945b107be69c3064aba9a19a1ae01e249a1e9 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Mon, 4 Aug 2025 22:39:38 -0700 Subject: [PATCH 05/27] Add support for attaching media --- lib/ruby_llm/providers/openai.rb | 4 +- lib/ruby_llm/providers/openai/response.rb | 44 +- .../providers/openai/response_media.rb | 77 ++ ...s_not_in_registry_but_available_in_api.yml | 139 ++++ ...ini-audio-preview_can_understand_audio.yml | 72 ++ ...ses_an_error_when_tool_execution_fails.yml | 146 ++++ ...4_1-nano_raises_appropriate_auth_error.yml | 69 ++ ...ltiple_tool_calls_in_a_single_response.yml | 316 +++++++++ ...ling_openai_gpt-4_1-nano_can_use_tools.yml | 327 +++++++++ ..._use_tools_in_multi-turn_conversations.yml | 660 ++++++++++++++++++ ...-nano_can_use_tools_without_parameters.yml | 298 ++++++++ ...ray_of_mixed_files_with_auto-detection.yml | 139 ++++ ...nai_gpt-4_1-nano_handles_multiple_pdfs.yml | 287 ++++++++ ...s_openai_gpt-4_1-nano_understands_pdfs.yml | 284 ++++++++ ...handles_context_length_exceeded_errors.yml | 71 ++ ...pt-4_1-nano_can_understand_remote_text.yml | 172 +++++ ...penai_gpt-4_1-nano_can_understand_text.yml | 283 ++++++++ ...tool_call_callback_when_tools_are_used.yml | 327 +++++++++ ...t-4_1-nano_can_understand_local_images.yml | 139 ++++ ...rstand_remote_images_without_extension.yml | 139 ++++ ..._1-nano_supports_response_format_param.yml | 72 ++ ...n_schema_and_returns_structured_output.yml | 139 ++++ ...oving_schema_with_nil_mid-conversation.yml | 139 ++++ ...rations_uses_context-specific_api_keys.yml | 69 ++ ...or_handles_invalid_api_keys_gracefully.yml | 69 ++ spec/spec_helper.rb | 18 +- 26 files changed, 4465 insertions(+), 34 deletions(-) create mode 100644 lib/ruby_llm/providers/openai/response_media.rb diff --git a/lib/ruby_llm/providers/openai.rb b/lib/ruby_llm/providers/openai.rb index f14b4f66d..e95962161 100644 --- a/lib/ruby_llm/providers/openai.rb +++ b/lib/ruby_llm/providers/openai.rb @@ -13,7 +13,7 @@ module OpenAI extend OpenAI::Streaming extend OpenAI::Tools extend OpenAI::Images - extend OpenAI::Media + extend OpenAI::ResponseMedia def self.extended(base) base.extend(Provider) @@ -23,7 +23,7 @@ def self.extended(base) base.extend(OpenAI::Streaming) base.extend(OpenAI::Tools) base.extend(OpenAI::Images) - base.extend(OpenAI::Media) + base.extend(OpenAI::ResponseMedia) end module_function diff --git a/lib/ruby_llm/providers/openai/response.rb b/lib/ruby_llm/providers/openai/response.rb index d8a999a73..fc3e3ff50 100644 --- a/lib/ruby_llm/providers/openai/response.rb +++ b/lib/ruby_llm/providers/openai/response.rb @@ -11,26 +11,6 @@ def responses_url module_function - def parse_respond_response(response) - data = response.body - return if data.empty? - - raise Error.new(response, data.dig('error', 'message')) if data.dig('error', 'message') - - outputs = data['output'] - return unless outputs.any? - - Message.new( - role: :assistant, - content: all_output_text(outputs), - tool_calls: parse_response_tool_calls(outputs), - input_tokens: data['usage']['input_tokens'], - output_tokens: data['usage']['output_tokens'], - model_id: data['model'], - raw: response - ) - end - def render_response_payload(messages, tools:, temperature:, model:, stream: false, schema: nil) payload = { model: model, @@ -90,15 +70,13 @@ def format_input(messages) # rubocop:disable Metrics/PerceivedComplexity { type: 'message', role: format_role(msg.role), - content: Media.format_content(msg.content), + content: ResponseMedia.format_content(msg.content), status: 'completed' }.compact end end end - - def format_role(role) case role when :system @@ -108,6 +86,26 @@ def format_role(role) end end + def parse_respond_response(response) + data = response.body + return if data.empty? + + raise Error.new(response, data.dig('error', 'message')) if data.dig('error', 'message') + + outputs = data['output'] + return unless outputs.any? + + Message.new( + role: :assistant, + content: all_output_text(outputs), + tool_calls: parse_response_tool_calls(outputs), + input_tokens: data['usage']['input_tokens'], + output_tokens: data['usage']['output_tokens'], + model_id: data['model'], + raw: response + ) + end + def all_output_text(outputs) outputs.select { |o| o['type'] == 'message' }.flat_map do |o| o['content'].filter_map do |c| diff --git a/lib/ruby_llm/providers/openai/response_media.rb b/lib/ruby_llm/providers/openai/response_media.rb new file mode 100644 index 000000000..a8dfbfbac --- /dev/null +++ b/lib/ruby_llm/providers/openai/response_media.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +module RubyLLM + module Providers + module OpenAI + # Handles formatting of media content (images, audio) for OpenAI APIs + module ResponseMedia + module_function + + def format_content(content) + # Convert Hash/Array back to JSON string for API + return content.to_json if content.is_a?(Hash) || content.is_a?(Array) + return content unless content.is_a?(Content) + + parts = [] + parts << format_text(content.text) if content.text + + content.attachments.each do |attachment| + case attachment.type + when :image + parts << format_image(attachment) + when :pdf + parts << format_pdf(attachment) + when :audio + parts << format_audio(attachment) + when :text + parts << format_text_file(attachment) + else + raise UnsupportedAttachmentError, attachment.type + end + end + + parts + end + + def format_image(image) + { + type: 'input_image', + image_url: image.url? ? image.source : "data:#{image.mime_type};base64,#{image.encoded}" + } + end + + def format_pdf(pdf) + { + type: 'input_file', + filename: pdf.filename, + file_data: "data:#{pdf.mime_type};base64,#{pdf.encoded}" + } + end + + def format_text_file(text_file) + { + type: 'input_text', + text: Utils.format_text_file_for_llm(text_file) + } + end + + def format_audio(audio) + { + type: 'input_audio', + input_audio: { + data: audio.encoded, + format: audio.mime_type.split('/').last + } + } + end + + def format_text(text) + { + type: 'input_text', + text: text + } + end + end + end + end +end diff --git a/spec/fixtures/vcr_cassettes/chat_assume_model_exists_works_with_models_not_in_registry_but_available_in_api.yml b/spec/fixtures/vcr_cassettes/chat_assume_model_exists_works_with_models_not_in_registry_but_available_in_api.yml index 5144e5bb9..076b62a3e 100644 --- a/spec/fixtures/vcr_cassettes/chat_assume_model_exists_works_with_models_not_in_registry_but_available_in_api.yml +++ b/spec/fixtures/vcr_cassettes/chat_assume_model_exists_works_with_models_not_in_registry_but_available_in_api.yml @@ -102,4 +102,143 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:48:51 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is 2 + 2?","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:04:27 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999967' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '459' + X-Envoy-Upstream-Service-Time: + - '466' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190daead4819e9b1f434be8309e0908402373d431ba07", + "object": "response", + "created_at": 1754370266, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689190db13b0819eb8bc8526e11909bc08402373d431ba07", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "2 + 2 equals 4." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 15, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 9, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 24 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:04:27 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_audio_models_openai_gpt-4o-mini-audio-preview_can_understand_audio.yml b/spec/fixtures/vcr_cassettes/chat_audio_models_openai_gpt-4o-mini-audio-preview_can_understand_audio.yml index 4c22f93f1..2f7bb24cd 100644 --- a/spec/fixtures/vcr_cassettes/chat_audio_models_openai_gpt-4o-mini-audio-preview_can_understand_audio.yml +++ b/spec/fixtures/vcr_cassettes/chat_audio_models_openai_gpt-4o-mini-audio-preview_can_understand_audio.yml @@ -116,4 +116,76 @@ http_interactions: "system_fingerprint": "fp_1dfa95e5cb" } recorded_at: Fri, 01 Aug 2025 10:50:59 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4o-mini-audio-preview","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What + is being said?"},{"type":"input_audio","input_audio":{"data":"UklGRiCrAQBXQVZFZm10IBAAAAABAAEAgLsAAAB3AQACABAAZGF0YQCrAQAnADAANAAzACwAIQAVAAgA///3//H/7v/r/+r/6v/q/+z/7//1//7/CAAUACIALQAzADUAMwAsACMAGQANAAQA/P/2//P/8f/z//X/+P/6//z///8CAAcADQASABcAHAAfACIAJAAkACMAIQAfAB0AHAAbABsAHAAcAB8AIQAkACUAJAAgABkAEgANAAoACQAKAA0AEgAYAB4AIwAlACUAIQAbABUAEgAPAA4ADgAMAAoACAAGAAQAAgAAAP3//P/8/wAABwAPABcAHQAfAB0AGQATAA0ABwABAPz/+P/3//f/+f/8////AQAFAAsAEgAbACQALQAyADQAMQApAB4AEQAEAPn/8v/u/+//9P/7/wEACAAMAA8AEAARABMAFQAXABoAGgAZABYAEAAKAAMA/v/5//T/8f/u/+3/7P/t/+//8f/0//b/+P/5//r/+f/2//P/7v/r/+j/5v/m/+f/6f/s/+7/7//v/+3/6v/m/+H/3P/X/9L/zv/L/8n/yf/K/83/0v/X/97/5P/q//D/9P/2//f/9f/x/+v/5P/d/9f/0v/P/8z/yv/J/8r/zf/R/9b/3P/j/+r/8P/3//r//P/6//f/8//u/+n/4//c/9T/zP/H/8X/x//N/9T/3f/m//D/+v8CAAoADQALAAUA/v/3//H/7f/p/+b/4v/h/+D/4v/m/+r/7P/t/+7/7//z//f/+//+//7//v/+//7//v/+//z//P/8//7/AgAHAAwADgANAAsABwADAAAA/P/4//T/8v/y//b/+/8AAAQABQAFAAMAAAD9//r/+P/1//X/9//6//z//f/7//n/9//3//n//v8CAAgADgAVAB0AIwAnACgAJAAeABgAEwAQAA4ADQAKAAgACAAKAA8AFwAeACQAKAAqACsALAArACoAKAAlACIAIQAgACEAIgAhACAAHwAgACQAKQAwADYAOgA8ADwAOgA2ADIALAAmACAAHQAcAB4AIgAoACwAMAAyADIALwApACQAHwAcABwAHgAhACQAKAAqACsALQAuAC0AKgAmACEAHgAdAB4AIAAhACAAHQAYABIADQAJAAYABAABAAAAAAACAAYACQAOABAAEgATABMAEQANAAcAAQD7//X/8f/v//D/8//4//3/AQADAAMAAAD5//H/6P/i/9//3//f/97/3f/a/9X/0P/L/8f/xP/E/8j/zv/X/+H/6v/w//H/8P/s/+f/4f/d/9n/2P/Y/9n/3f/g/+P/5P/k/+P/4v/f/97/3P/a/9f/1P/T/9L/0v/S/9P/1P/U/9X/2P/c/9//4v/k/+b/5v/l/+T/4//h/97/3P/b/9z/3P/d/9z/2v/Z/9r/3P/i/+f/6//s/+v/6v/o/+n/6//u//H/9P/3//n//P/+//7//f/7//r/+v/6//r/+f/1//D/6//m/+H/3f/Z/9f/1f/X/9v/4P/l/+j/6//t/+//8//5//3///////3/+v/7//z//P/8//v/+P/2//T/8//y//D/7v/w//T//f8HAA8AEwASAAsAAgD4/+3/4v/Y/8//yf/J/8//2P/i/+r/7//x//X//P8DAAoADgAOAAsABgADAAMAAgAAAP3/9//y/+7/7f/u/+7/7v/u//D/9P/7/wIACQAMAAsACgAKAA4AFAAbAB8AIgAhAB8AHgAeAB4AHwAfACIAJAApAC8AMwAzAC8AKQAjACEAJAAqADEANwA6ADsAOAA1ADEALAAnACEAGwAYABgAGwAgACYAKQAqACkAKgAqACwALQAuACwAKgApACcAJwAmACEAGgASAAsABwAIAA0AFAAZAB0AHwAgACIAJAAlACUAJAAgAB0AGgAWABIADQAGAAEA//8AAAUADAAVABwAIAAjACYAKAAqACkAJwAkACAAHgAcABsAGgAXABQAEgARABIAFAAVABUAEwARABAAEAARABMAFAAVABUAFQAVABUAFQATAA8ACQAEAAAA/f/8//3///8BAAYACgAPABMAFQAVABMAEAAMAAkABgAFAAMAAwADAAUABwAIAAcABAAAAPz/+P/0//H/7//t/+3/8P/0//v/AAADAAQAAwAAAP///v/+//3/+//4//X/9P/0//T/8//x/+3/6P/l/+X/6P/s//D/8f/x/+//6//l/9z/0f/H/77/vP/B/83/2v/n/+7/8f/w//H/8v/3//3/AgAGAAgABwABAPb/5f/R/73/rv+n/6f/q/+y/7f/u/+//8b/0P/a/+L/5v/l/+P/4f/j/+X/5v/k/+D/3P/b/97/5P/q/+3/6//n/+T/5v/s//H/8//y/+3/6P/n/+b/4//b/87/wP+2/7X/u//H/9H/2P/b/9//6P/2/wQADQANAAUA+v/w/+v/6//r/+z/6//r/+7/9v/9/wAA/P/y/+j/5f/q//T///8EAAMAAAD+/wEACwAWAB8AIwAhACAAIgAlACoALAApACUAIgAiACQAJAAeABIAAQD0/+7/7//3/wAABgAKAAsADgAUAB0AJwAtAC8ALwAvADEANAA2ADcAMwAvACwALQAxADcAOgA6ADQAKwAjAB4AHQAdAB0AHQAcAB0AHwAjACcAKQApACoALAAxADgAQABCAEAAOwAzADAAMwA5AD8AQQA+ADYALQAnACQAJAAlACYAKAArADAANwA8AD4AOQAxACkAJAAiACMAIgAfABcAEQANAA0AEgAXABoAGgAXABMADgAJAAQA///6//f/+f///wcADgAQAAwABAD9//f/9P/1//f/+/8AAAUACwASABYAFQARAAkAAQD8//b/8v/t/+f/4P/b/9v/3f/k/+v/8f/0//T/8v/w/+3/6v/p/+j/6v/s/+7/8P/v/+3/6v/n/+j/6//w//b/+v/9//7//v/9//v/9v/x/+7/7P/s/+7/7f/q/+D/1P/J/8L/wP/B/8T/xv/F/8X/xf/I/87/1P/c/+D/4//k/+X/5v/m/+P/4P/c/9r/2//d/97/2//W/83/xf/B/8H/xf/N/9P/2f/f/+T/6v/v//P/9P/z//L/8v/z//X/9f/0//H/7f/s/+z/7v/w/+//7f/r/+n/6f/q/+z/7P/t/+v/6//r/+v/6//q/+j/5v/m/+f/6v/s/+v/6P/k/+H/4P/j/+f/6v/s/+3/7v/y//j/AAAGAAoADAALAAsADQAOAAwACQADAP3/9v/v/+r/5f/f/9j/0//T/9f/3//q//f/AAAIAA4AEgAVABYAFQASAA8ACwALAAwADQAOAA0ADAAKAAgABwAGAAUABQAGAAkADAASABYAGAAXABMADgAIAAQAAAD//wAAAQAHAA4AFAAZAB0AHQAaABUADwAIAAEA/P/3//P/8v/x//H/8P/u/+v/6f/p/+r/7v/0//z/BAALABEAFAAVABMAEAAOAAwACgAJAAYAAgD///z/+//+/wAABwANABMAGQAfACQAKAAoACYAIgAcABYADwAJAAMA/v/5//X/9P/2//r/AAAFAAwAEwAaACIAKQAuADEAMgAzADEALwAqACUAIAAZABQADgAKAAcABgAHAAoADQARABQAFgAZABwAHwAjACUAJgAkACEAHgAcAB0AHgAgACIAIgAhAB4AGgAWABIADwAMAAwADQAPABIAEgAQAAsABQAAAPv/+P/6//3/AQAFAAcABwAEAAAA/v/8//z//v8AAAAA/v/7//j/9f/0//P/8v/x//H/8f/y//T/9P/z//P/8v/y//L/9P/1//T/8P/q/+P/3f/Y/9T/0P/M/8j/xf/C/77/u/+5/7f/t/+6/7//xf/L/8//0f/U/9b/1//Z/9n/2f/W/9T/0v/S/9P/0//T/9L/0f/R/9D/z//N/8r/x//F/8n/0f/c/+j/8P/0//P/7//r/+f/5f/k/+L/4v/h/+P/5f/n/+f/5P/f/9n/1v/X/9r/4v/q//L/+P/9/wAAAgADAAMAAgABAAAAAAD+//z/+f/3//X/9f/3//r//v8AAAAAAQACAAQABwAKAA0ADwAPABAAEgAVABgAGwAdACAAIwAnACsALwAxADEAMQAxADEANAA1ADYAMwAuACoAJgAlACcALAAwADQANwA5ADsAPQA+AEAAQQBCAEEAQAA9ADcALQAiABcADgAIAAcACwARABgAIAAlACoALgAxADYAOwBBAEgATgBRAFEATgBHAD8ANgAtACUAHgAWAA4ABgAAAPz/+//9/wAABAAKABAAFwAdACMAJgAmACMAHgAZABYAFAATABEADgALAAoADAAPABQAFgAVABMADwANAA0ADgAPAA4ACwAIAAYABwAMAA0ADQAKAAYABgAKABEAGQAgACUAJgAnACgAKQAnACEAGAAOAAgABwAJAAsACAACAPn/8//y//f///8EAAQAAAD6//X/9P/1//f/9//3//r/AAAKABMAFgASAAkAAAD//wQADgAXABoAFAALAAEA/f/+/wAA///6//P/7v/s/+//8P/v/+n/5P/j/+n/9v8CAAkABwAAAPf/9P/4/wAABQAGAAIA/f/5//j/+P/3//L/6v/i/93/3f/e/9v/0//K/8T/yP/X/+z///8GAAIA9f/l/9v/2f/c/+H/4v/h/97/3P/a/9f/0P/G/73/uv+//8r/1v/b/9b/yf+7/7P/tP++/8r/0P/S/87/y//K/87/0v/U/9T/0//V/9z/5v/v//D/6f/e/9P/zv/Q/9f/3v/g/93/1//S/9D/0v/T/9H/zf/J/8f/yv/Q/9X/1//V/9H/0f/W/+H/7P/1//n/9//0//X/+P/8//7//P/2//D/7f/v//H/9P/y/+3/6P/l/+j/7//4////AgAFAAkAEQAYACAAJAAjACEAIQAkACoAMAAzADAAKQAgABgAFAAPAAsABQD///z///8HABMAHgAlACUAIAAbABkAGwAhACoAMgA5AD8AQwBFAEQAQAA2ACsAIQAbABsAHQAhACIAIQAeAB0AHwAkACwANAA6AD0APQA9AD8AQQBEAEcASABHAEYARgBGAEUARQBDAEEAPwBBAEQASwBQAFQAVQBTAFAATQBKAEcAQwA+ADcAMwAvACwAKQAlAB4AFgAPAAoACgAMABAAFQAYABsAHgAgACIAIgAeABkAFAASABMAFwAcAB0AGwAVAA0ABwADAAAA/v/7//f/9P/z//X/+f/9/wAAAQACAAQABgAHAAcABAABAP////8AAAQABgAFAAAA+P/u/+X/3//Y/9L/y//F/8H/wf/F/8r/0P/W/9v/3v/h/+P/4//j/+L/4f/i/+X/6P/r/+z/6f/j/9r/z//E/7n/r/+p/6X/pf+o/6z/r/+y/7T/tv+6/7//w//I/8r/y//M/83/0P/V/9n/3v/h/+P/5f/k/+L/3//b/9f/1v/V/9b/2P/X/9b/1P/T/9T/1v/Z/9z/3//h/+X/6v/x//b/+//+//7//v/9//z/+//4//T/8P/s/+v/6//t/+3/7f/t/+3/7//y//b/+//+////AAD///3/+v/0/+3/5f/g/97/4f/n/+//9v/6//v/+//5//f/9//4//v/AAAHAA8AFgAaABoAFQANAAMA+//0/+//7f/s/+z/7f/w//P/9v/4//j/9//3//j/+//+/wAAAgADAAQABQAGAAcABwAEAAAA+f/y/+z/6f/p/+z/7//z//b/9//3//X/8v/t/+r/6f/q/+3/8v/2//n/+//6//r/+P/3//X/8//y//H/8f/z//b/+f/9/wAAAgAEAAUABQAEAAQABAAFAAUABQAFAAMAAQD+//r/9f/x/+7/7v/v//T/+/8BAAgADAAPABIAFQAYABsAHQAeAB0AHAAbABwAHgAhACMAJQAnACkALQAyADgAPQBBAEQASABMAFAAUwBVAFUAUwBRAE8ATQBLAEkARwBFAEUARQBHAEgASQBIAEcARwBHAEkASgBIAEUAQQA+ADwAPQA+AD8AQAA/AD8APwA+AD4APQA6ADcANAAzADIAMgAxACwAJgAfABkAFgAVABYAFgAXABYAFQAVABYAFgAVABMAEAAOAAwACgAIAAQA/v/1/+3/5//j/+H/4P/e/9r/1f/R/8//zv/P/9H/0//U/9b/2P/a/9r/1//T/83/x//D/8H/wP+//73/uv+4/7X/s/+0/7T/tP+2/7b/uP+7/77/wf/D/8X/x//J/8r/zP/M/8z/y//L/8z/zv/Q/9D/z//L/8b/wv+//73/vP+7/7v/vP++/8L/yP/O/9T/2f/d/+H/5v/r//H/9//7/wAAAwAHAAoADQAOAAwACAADAP7/+//7//3/AQAIAA4AFAAXABoAGgAaABoAGwAdACAAJAAnACsALgAxADMANQA2ADcANgA0ADIAMQAwADAAMAAwAC8ALgAtACoAJwAiAB0AFwASAA8ADgAOAA8ADgAOAA0ADQANAA0ADQANAAwADAAOABAAEgATABIAEQAPAA4ADQAMAAoABgABAPz/9//0//H/7v/q/+b/4f/f/9//4P/j/+X/5v/n/+r/7v/z//f/+P/2//H/7f/r/+r/6v/p/+b/4v/f/9z/2//a/9n/2P/Y/9r/3v/l/+3/8v/1//b/9v/2//j/+v/6//r/+v/5//r//P8AAAEAAwADAAIAAQAAAP7/+v/1//H/7f/t/+7/8f/1//f/+v/9////AQADAAMAAwACAAMABAAGAAoADQAOABAAEQATABUAFwAYABkAGAAXABkAGwAfACUAKwAxADQANgA1ADQANAA0ADQANgA3ADoAPQBAAEMARgBHAEgASABHAEcARwBHAEUAQQA7ADQALgApACYAJAAkACMAIgAhACIAIgAiACIAHwAbABgAFgAWABcAGAAXABYAFAATABMAEwAUABQAFAAUABYAGQAdACIAJQApACsALAArACYAHgAUAAgA///5//b/9v/3//b/9P/x/+3/6v/o/+X/4//h/9//4P/h/+T/5v/m/+X/4//i/+L/4//k/+T/4v/f/97/3v/f/+H/4f/f/93/2v/Z/9j/2f/Y/9X/0P/L/8b/xP/C/8D/vf+7/7r/vf/D/8v/0v/W/9b/0//Q/8z/y//M/83/z//S/9b/3P/j/+f/6P/l/+D/3f/b/9v/3P/d/9z/2v/b/93/4//o/+r/6f/j/9z/1//T/9P/1f/Z/9//5//y////CAAOAA8ACgAEAAAA/P/7//r/+f/2//X/9v/4//v//f/9//v/+f/3//j/+v/9/wAAAQAEAAkADwAVABwAHwAfABwAFwAUABEAEAAPAA8ADgANAA8AEAASABMAEwARAA0ACQAFAAIAAQADAAUACAAMABEAFgAaAB4AHwAeABwAGQAWABQAEQAOAAsABwAFAAMAAgABAAAA/f/6//f/9v/3//j/+f/5//j/+P/6//3/AgAIAA0AEAASABIAEwATABMAEAAMAAkACAAJAA0AEQATABMAEQAOAAoABwAEAAEA///8//v//v8DAAsAFAAbACEAJgApACsALQAtAC0AKgApACcAKAApACoAKgAoACUAIQAdABkAFQARAAwABwAEAAMABAAGAAsADwASABUAFwAYABgAFgAUABEADwAPABAAFAAYAB0AIAAiACIAIQAfABwAGAASAAwABwADAAIAAgACAAIAAwADAAMABAAFAAcABwAJAAoADQARABUAGAAYABUAEQANAAkABQADAAEA///8//r/+P/4//j/9//2//X/8//z//T/9f/2//f/9v/3//f/+f/5//n/9//0/+//6//p/+f/5f/j/+H/3v/c/9z/3f/f/+D/4P/g/+D/4v/k/+f/6P/o/+b/4v/e/9r/2P/W/9T/0//T/9P/1P/V/9X/0//S/9D/z//O/87/z//Q/9D/0v/S/9X/2f/c/9//3//d/9r/1//U/9P/0//U/9T/1f/W/9j/2//d/9//4f/j/+P/5P/l/+X/5f/l/+X/5v/o/+r/7P/t/+3/6//o/+T/4P/c/9j/1P/S/9H/0//W/9r/3f/g/+H/4v/k/+b/6P/q/+r/6//r/+z/7v/y//f/+//+/wAAAQADAAUABgAGAAUABAAEAAUACQAOABQAGAAbABwAHQAcABoAGAAVABMAEgASABMAFQAVABYAFwAYABoAHAAeAB4AHQAcABoAGgAcAB8AIwAmACsALgAxADMAMgAvACsAJQAfABoAGAAXABYAGAAaAB4AIwAoACwALwAwAC8ALQAsAC0AMAAzADcAOgA9AD4APgA9ADoANQAwACoAJgAjACQAJQAnACcAJgAhABwAFwASAA0ACgAHAAYABQAFAAcACQAMAA8AEQASABQAFAAUABQAEwATABIADwAMAAkABgADAP///f/6//f/9P/x//D/7//x//L/9P/0//P/8//0//X/+P/7////AAACAAMAAgAAAP3/+f/z/+//7P/q/+r/6v/p/+b/4//g/93/2v/Y/9T/0f/P/8//0v/Z/+L/6//0//z/AQAGAAkACgAKAAgABwAFAAQABAAFAAUABAABAP7/+v/2//T/8//z//X/+f/+/wMACQAQABYAHAAgACQAJwAqACwALgAuAC0AKwAoACYAJwAoACoALQAvAC8ALQAqACcAIwAfAB0AGwAbAB0AIQAkACkALAAvADEAMgAyADAALQAoACMAHgAZABcAFgAWABYAFQAUABIADwANAAkABAD///n/9P/x//D/8P/x//H/8f/w/+3/6v/m/+H/2//W/9L/0P/P/9H/0//V/9f/2P/Y/9j/2P/W/9P/0P/O/8v/y//M/8z/yv/I/8b/xP/E/8b/yf/M/83/zv/Q/9L/1v/a/93/3P/Z/9P/zv/J/8T/wP+7/7X/r/+r/6n/q/+u/7L/tv+6/73/wP/D/8b/yf/L/8z/zf/O/9H/1P/X/9n/2//e/+D/4v/k/+T/4//g/93/2v/Y/9n/2//f/+T/5//r/+//8//4//r//P/8//z//P/+/wAAAwAFAAYABgAFAAUABQAFAAQAAgABAAIABgAOABYAHgAjACYAJgAnACgAKgAqACgAJAAfABwAGwAcAB4AHgAdABsAGgAaABsAGwAaABgAFwAaACEAKgAzADkAOwA6ADkAOgA+AEMARwBHAEUAQgA/ADwAPAA6ADgANAAvAC0ALQAtACwAKgAmACIAIAAhACYAKgAvADAAMQAzADYAOgBAAEMAQgA/ADsAOAA2ADUANAAxACsAIwAcABUAEQANAAkAAwD9//j/9f/2//n//P/8//z/+//6//v//f/////////+////AAAEAAUABQADAAAAAAACAAcACwALAAgAAgD+//v/+//9/wAAAAD+//v/+f/4//n/+//7//z///8EAAsAFAAaAB0AHQAZABUAEAAMAAcAAgD+//v/+P/4//f/9//1//H/7f/r/+z/7f/w//L/9P/1//f/+v/+/wAAAwAFAAcACAAJAAkACQAIAAUAAgD///z/+f/1//H/7f/o/+T/4v/i/+P/5v/n/+j/6f/q/+z/7//z//j//f8AAAQABwAKAAsACwAJAAYAAgD///v/+P/1//H/7v/r/+n/6f/q/+3/7v/v/+7/6//m/+H/3P/X/9P/0P/P/9D/0f/T/9X/2P/a/97/4//o/+z/7//v/+7/7P/q/+j/5v/k/+L/4P/f/+D/4P/h/+L/4f/h/+H/4v/l/+n/7P/u/+7/7f/t/+3/7//y//b/+////wMABgAHAAcABQACAAAA/f/8//v/+v/4//b/8v/u/+r/6f/o/+n/7P/w//X//f8DAAoAEQAZAB8AJQArAC8AMwAzADEALAAlAB0AFgAOAAgAAwD///z/+v/6//z//v8AAAQABwALABAAFAAXABoAHAAcAB0AHQAbABgAEwAMAAQA/f/3//L/7//t/+3/7v/w//T/+f/+/wIABwALAA8AEgAUABQAEgAOAAoABgADAAEAAwAFAAkADAAPABEAEgASABEADgALAAgABgAGAAYABwAIAAgABwAIAAkADAAPABIAEgASABEADwANAAsACgAIAAcABgAGAAYACAAJAAoACwAMAA4AEQAUABcAGgAbABwAHQAfACEAIwAkACIAHwAbABYAEgANAAcAAgD+/0YARQBEAEQARABCAEAAPAA3ADQAMAAtACgAIwAeABoAGAAZABwAIAAjACUAJQAmACcAKgArAC0AKwAoACUAIgAgACAAIgAjACQAIwAhAB0AGQAUAA8ACgAGAAMAAAD+//v/9//z//D/7//w//L/9P/2//b/9f/z//H/8P/w/+//7f/r/+n/6f/r/+3/7//w/+3/6f/j/93/2P/U/8//y//H/8X/w//E/8b/yP/L/8z/y//L/8v/yv/L/8z/zv/Q/9L/0//T/9P/0P/N/8j/wv++/7r/uf+4/7n/uP+3/7T/sv+x/7D/sv+0/7f/uf+8/8D/xf/N/9X/3f/k/+n/7P/t/+3/7P/q/+f/4v/d/9j/1P/R/87/yf/E/73/uP+0/7P/tP+4/73/w//J/9D/1//f/+b/7f/0//j//P8AAAAAAgACAAIAAQAAAAAA/v/8//r/9v/0//D/7//v//H/8//2//n/+//9/wAAAQAFAAkADQASABYAGgAdAB8AIQAhACIAIQAeABsAGAAVABMAEgATABQAEwASABAADgANAA0ADgAOAA8ADwAPAA8AEAARABIAEwAUABUAFwAYABoAGwAaABkAFwAWABcAGQAbAB0AHgAeAB0AGwAaABsAGwAbABoAGAAVABIAEAAOAA8AEQAUABYAGQAaABkAGAAWABMAEAANAAsACQAJAAoACwAMAAwADAAMAAwADAAOAA8AEAAQABAADwAPABAADwANAAsACAAEAAEA///9//3//f/+/wEABAAJAA4AFAAZAB0AIQAjACMAIgAfABwAGgAXABQAEAAMAAgABgAGAAgACwAPABQAGgAgACYALAAyADUANgA2ADQAMAAsACgAIwAdABgAFQAUABQAFAAUABQAEgARABAADwAOAA8ADwAQABEAEgATABQAFQAVABQAFAATABIAEgARABEAEgATABQAFAAUABMAEgASABEADwAMAAkABwAHAAgACgAMAA8AEQAUABcAGwAeACAAIAAdABsAGgAZABkAFwATABAACwAJAAkACgALAAsACgAKAAsADQAQABEAEQAPAA0ACgAIAAYABQACAP///P/5//f/9//2//X/9P/z//H/7//u/+3/7P/r/+n/6P/n/+X/4//g/9z/2P/T/8//zP/K/8n/yv/K/8r/yv/H/8X/w//B/8D/v/++/77/vv/B/8T/yP/M/87/zv/P/8//0P/S/9L/0v/R/87/zP/K/8n/x//F/8L/vv+7/7n/uP+3/7j/uf+8/7//wv/G/8n/yv/L/8z/zP/N/8//0f/T/9X/2P/b/97/4//n/+v/7//y//b/9//4//j/+P/3//b/9v/1//X/9P/0//P/8v/x//D/8f/z//f//P8BAAcADAAQABMAFwAaAB0AHgAfACEAIwAlACkALAAuAC8AMAAvAC4ALQArACkAJgAiAB4AGwAZABgAFwAXABkAHAAgACMAJgAoACkAKgAsAC8AMgA0ADUANAAzADEALwAsACcAIAAZABIADgAMAA0ADwASABQAFAAVABYAFwAWABQAEQAOAAwACgAKAAsADAALAAoABwAEAAEAAAD+//3//v///wAAAgAEAAUABgAGAAUABAACAAEAAQAAAAAAAAD///7/+//4//P/7v/p/+T/4P/e/9z/3P/d/97/4P/j/+f/6//t/+7/7f/s/+v/7P/t/+7/8P/y//P/9P/z//L/7v/q/+b/4//j/+b/6v/w//X/+P/5//r/+P/3//T/8f/t/+n/6P/n/+j/6v/u//L/9f/5//z///8AAAAAAAD//wAAAgAFAAkADQAPABAAEQARABEAEgASABQAFgAaAB8AJQAsADIANgA4ADoAOwA9AD8AQgBEAEYARgBGAEgASgBLAEwASgBFAEAAOwA2ADQAMgAwAC4AKwApACkAKwAsAC0ALAApACYAJAAkACYAKQArACsAKQAmACMAIAAdABgAEgANAAgABQADAAIAAQAAAP///f/9//7//v/9//v/9//1//L/8P/u/+z/6f/m/+P/4P/e/9z/2v/W/9L/zv/K/8f/w/++/7n/tP+w/6z/q/+r/6z/rf+u/7D/sv+0/7X/t/+4/7n/uv+8/77/wP/A/8D/v/+//7//wf/C/8T/xv/J/8z/z//T/9X/1P/T/8//zP/L/8r/zP/O/9L/1//c/+H/5f/o/+v/7f/w//H/8//1//f/+P/5//v/+//8//r/+P/0//L/8f/x//T/+f8AAAYADgAWABwAIgAlACcAKAAoACcAJgAjACAAGwAWABIADgALAAoACAAIAAkACwAPABQAGQAdACAAIgAjACMAIwAiACEAIQAhACMAJQAmACYAJgAkACMAIgAiACMAIwAjACQAIwAkACUAJgAoACoAKwAsACwALQAuADAAMQAxADIAMgAwAC8ALwAvADAAMgAzADQANAAyADEAMAAuACwAKgAoACYAJQAjACMAIQAfABwAGgAXABUAFQAVABUAFwAYABkAGgAbABsAGgAYABYAFAASABIADwANAAsACQAHAAQAAAD8//f/8//x//D/8f/x//D/7v/s/+r/6P/o/+j/6f/p/+r/6//s/+3/7f/t/+3/7f/u//D/8v/0//b/+P/5//z///8BAAMAAgABAAAA/v/9//3//f/9//3//P/8//z//P/8//r/+v/5//n/+f/6//r/+//8////AQAFAAgACgALAAkABwAEAAAA/f/4//T/8f/w/+//7v/t/+v/6P/n/+b/5v/n/+f/6P/q/+3/8f/2//j/+f/3//L/7f/o/+X/4v/g/97/2//a/9n/2P/X/9b/1f/T/9L/0f/R/9D/z//N/8v/yv/K/8z/zf/O/87/zf/M/8z/zf/O/9H/1P/X/9n/2//d/9//4v/k/+b/5//o/+f/5v/m/+X/5f/m/+f/6f/q/+v/7P/s/+z/7v/w//L/9f/2//j/+P/4//j/+P/2//X/8//x//H/8v/z//b/+f/9/wAABQALABEAFQAZABsAGwAaABoAGgAbABwAHAAdAB0AHgAgACAAHwAdABoAGQAaABsAHQAeAB8AIAAhACMAJQAmACYAJAAhACAAIAAiACQAJAAjACAAHgAbABoAGgAYABcAFAASABEAEgAVABgAGgAcAB4AHwAgACEAIAAgAB4AHQAcABsAGgAZABYAFAATABIAEwATABQAEwARAA8ADAAKAAgABwAFAAQAAwADAAQABAAEAAMAAAD+//v/+f/5//j/+P/4//f/9v/0//P/8v/y//P/9P/2//f/+f/6//z//P/8//v/+f/3//b/9v/3//r//P///wAAAgADAAMAAQAAAP7//P/7//3///8CAAYACgANAA8AEAARABEAEQARABEAEgAVABkAHgAjACYAKAAnACUAIwAhACEAIQAiACQAJgAnACgAKQAoACgAJwAnACYAJwAmACYAJQAkACMAIgAjACMAIwAjACIAIQAgAB8AIAAfAB8AHgAcABwAHQAeAB4AHQAaABcAFAASABIAEwAUABQAEwATABMAFQAWABYAEwAPAAkABAAAAP7/+v/3//P/8P/v/+//7//v/+3/6v/n/+X/5P/m/+f/6f/p/+r/6//t/+7/7v/s/+j/4//e/9z/2//c/9z/2//a/9n/2f/a/9v/2//a/9f/1f/T/9P/0//U/9P/0//S/9H/0f/Q/87/zP/I/8X/xP/F/8n/zf/Q/9L/0v/R/9D/z//P/87/zP/I/8X/w//E/8b/yv/Q/9X/2//g/+b/6v/v//H/8v/z//X/9//6//v/+v/3//L/7P/n/+T/4v/g/93/2v/X/9X/1P/V/9X/1v/X/9b/1//Z/9v/3v/h/+X/6P/t//L/9//7//z//f/7//r/+v/6//r/+f/2//P/8P/v/+//8P/w/+//7f/s/+v/7P/u//H/9P/3//n/+//8//z/+v/4//X/8v/v/+7/7//v/+//7//v//H/8//3//v//v////7//P/7//v/+//8//r/+P/z//D/7v/u//D/8v/1//j/+//+/wIACQARABkAHwAkACgAKgArACsAKQAmACIAIAAeAB4AHwAfAB4AHQAbABsAGwAcAB8AIQAkACgALAAwADQAOAA6ADwAPQA9AD8AQgBEAEcASgBNAE8AUQBRAFAATgBKAEcARABCAEAAPwA+AD0APAA6ADkANwA2ADQAMwAyADMANQA4AD0AQABEAEYARgBFAEIAPgA5ADMALAAmAB8AGgAVABEADgALAAsACgAKAAkACAAGAAMAAQAAAAAAAQACAAQABQAGAAYABgAFAAUABAACAAEA///9//v/+f/3//T/8v/x/+//7f/s/+v/6v/q/+r/6v/o/+f/5P/i/+H/4f/i/+T/5f/n/+j/6v/s/+7/8P/y//P/9P/0//T/9P/y//D/7v/r/+n/6v/s/+//8f/z//L/8v/y//T/9v/6//3/AAAAAAEAAAD///3/+v/3//X/8//z//T/9v/5//r/+//7//v/+v/7//v//f///wAAAQADAAUACAAMABAAEwAWABYAFQATABAADAAIAAMA/v/6//X/8v/w//D/8f/x//L/8v/z//P/9f/2//j/+f/5//r/+v/6//n/+P/2//P/8P/s/+j/5P/g/93/2v/Z/9n/2f/a/9v/3f/f/+D/4f/i/+L/4//j/+T/5f/n/+n/6v/q/+j/5f/h/93/2f/W/9P/0f/P/87/zv/P/9D/0v/U/9X/1P/U/9T/1f/Y/9z/4P/k/+j/6//u/+//8P/v/+3/6v/o/+b/5P/k/+T/4//j/+P/5P/l/+b/5//p/+v/7//1//z/AgAHAAsADQAOAA0ACwAJAAYAAgD+//r/9v/z//L/8//0//T/9P/z//P/9P/1//f/+v/9/wAAAwAIAA0AEQAUABUAFAASABAAEAARABMAFQAUABQAEwASABMAFAAVABUAEwAPAAsABwADAAAA/P/3//L/7f/p/+j/5v/m/+n/7f/0//v/AAAFAAUAAwABAAEABAALABEAFwAYABcAFAARAA8ADwARABMAFQAWABcAFgATAA0ABQD///n/9//5//3/AAADAAQABQAHAAsAEAAVABkAGwAcAB4AIQAlACgAKgArACoAKQAoACkAKgAoACYAIgAeAB0AHQAfACAAIAAeABwAGwAbABsAGgAZABYAFgAXABsAIAAkACUAIwAgABwAGwAbABwAHAAZABcAFgAYABwAIQAkACYAJgAkACEAHQAZABUAEQAPAA4ADwAPAA4ACwAGAAQABQALABMAGwAfAB0AFwASAA8ADgAQABAADgAIAAAA+f/y/+z/5v/g/9n/1P/S/9P/1v/Z/9r/2f/X/9j/2//g/+X/6P/o/+b/5v/o/+3/8v/z//H/6v/i/9z/2f/b/9z/3f/b/9f/1P/S/9L/0//T/9L/0v/T/9j/4P/n/+3/7v/r/+n/6P/r/+7/8//1//X/9P/0//X/9//4//b/8//w/+7/8P/0//n/+//6//r/+v///wUADgAVABgAGQAYABcAFwAYABgAFQARAA0ACgAJAAgABgACAP7/+f/4//r/AAAGAAoACwAIAAYABgAJAA4AFAAYABoAGgAbABwAHwAhACIAIQAgAB8AHgAeABwAGAATAA4ACgAIAAkACQAIAAQAAAD9//z//v8BAAQABQAEAAEAAAAAAAAAAQADAAIAAAD+//z//P/9//3//f/+//7///8AAP///P/5//b/8//z//X/9v/3//f/9//3//n/+//9//3/+//4//T/8v/x//H/8v/x/+//6//m/+D/2//Y/9b/1f/W/9n/3P/g/+P/5f/m/+j/6//v//T/+f/+/wAAAAAAAAAA/v/7//f/8v/t/+j/5P/i/+D/4v/j/+X/6P/q/+z/7v/u/+7/7v/u//D/8v/2//j/+v/7//3/AAAFAAoADgARABIAEgAUABgAHgAkACgAKQAnACMAHgAbABcAFAAQAA0ACwAKAAsADQAPABEAEwAUABcAGwAhACYAKgAtADAAMgA0ADQAMgAvACsAJgAjACAAHAAYABIACwAFAAAA/f/7//r/+//8////AQADAAUABgAGAAUABAAGAAoADgASABYAGAAYABcAFgASAA0ACAACAP7/+v/6//n/+f/3//T/8P/s/+j/5//n/+n/6//v//P/9//7//7///////3/+v/3//P/8v/x//H/8v/z//T/9P/1//X/9f/1//T/9P/0//T/9P/0//T/8//x/+//7f/s/+v/6f/o/+b/5f/j/+H/3//d/93/3f/f/+P/5v/p/+z/7P/s/+3/7f/t/+//8v/2//r///8CAAQAAgD///n/8v/t/+n/5v/l/+X/5//q/+7/8//3//n/+v/4//X/8//w/+3/6//p/+n/6//v//P/9v/1//P/7v/r/+v/7v/0//r///8BAAMABAAEAAMAAQAAAPz/+f/3//X/9f/1//X/9P/z//L/8f/x//D/7//v/+7/7//x//X/9//5//n/+P/2//T/9P/z//T/9f/2//b/9//4//j/+P/2//T/8f/v/+z/6v/p/+j/5//o/+r/7v/z//r///8CAAUACAAJAAsADAAMAAsACwALAA0AEAARABEADgAKAAgACQANABMAGAAcABwAHAAcAB8AIgAlACcAJwAmACQAIwAiACIAIgAhACEAIwAnACsALQAtACwAKgApACsALwA0ADkAPAA8AD0APQA9AD0APAA5ADUAMAArACgAJgAkACMAIgAhACEAIAAeABwAGgAZABoAHQAiACYAKQAqACkAKAAnACcAJgAkACAAHQAZABkAGQAaABwAHQAcABoAFwAUABAADAAHAAEA/P/4//X/9f/2//j/+v/8//7///8AAAAAAAD///7//v/+///////+//3//P/6//j/9v/z/+7/6v/n/+X/5f/o/+z/8f/2//v/AAACAAUABQAEAAIAAQAAAP///v/7//b/8f/r/+b/5P/k/+X/5f/m/+b/5v/n/+j/6v/r/+v/6//r/+v/6//s/+z/6//o/+b/4//h/9//3v/d/9z/2//c/93/3v/h/+L/5P/n/+r/7v/y//X/9//4//j/9v/0//H/7v/q/+X/4f/f/97/3//i/+P/5f/l/+X/5f/m/+j/6P/o/+f/5P/j/+P/5P/n/+r/7P/u/+//8P/z//X/9//4//j/9//3//f/9//3//b/8//x//D/8P/x//P/9f/2//X/9P/0//X/9v/4//n/+f/3//b/9P/y//D/7v/r/+j/5v/k/+P/5P/m/+n/6//u//H/8v/1//b/+f/8//7/AAABAAMABQAFAAYABgAEAAEA/v/6//b/8//x//H/8f/y//T/9//7/wAABAAIAAwADgAQABEAEgASABEAEAAPAA4ADgAOAA8AEQASABQAFQAYABkAGwAaABoAGQAaABwAHgAgACEAIAAdABsAGAAWABUAFQAUABUAFwAaAB0AIAAhACAAHAAYABQAEQAPAA4ADQALAAoACQAJAAkACgAKAAkABwAFAAMAAAD+//v/+P/2//P/8P/t/+v/6v/q/+z/7f/v//H/9P/2//n/+//9//7//f/8//v//f///wEAAwAEAAQAAgAAAPz/+P/z/+7/6v/n/+X/5P/l/+b/5//o/+v/7//y//b/+f/7////AwAKABEAFQAWABMADgAIAAQAAQAAAAAAAAD/////AAABAAMABgAHAAgADAAQABcAHQAgACEAHgAZABQAEQAPABAAEQASABEADwAMAAoACQAJAAoACwALAA0ADwASABUAGgAcAB0AHAAZABUAEgAPAA0ADQANABAAEwAXABsAHgAfAB8AHgAcABwAHAAbABsAGgAaABkAGAAVABIADQAIAAIAAAAAAAAAAwAFAAYABQAEAAMABAAFAAYABwAIAAgACgALAAwADQANAAwACgAIAAQAAAD9//n/9v/1//f/+v/9/wAAAAAAAP7//P/6//j/9v/1//L/8P/u/+3/7f/u/+7/7v/u/+3/7f/s/+z/7v/x//X/+f/8//7//v/+//3//f/8//z//P/7//r/+f/4//j/+P/5//n/+//9//7/AAAAAAAA/v/8//n/9v/1//X/9f/0//T/9f/3//n//P/8//v/+P/z/+7/6f/m/+T/5f/m/+n/7P/u//H/8v/0//X/9v/4//n/+v/6//r/+v/7//v//P/7//n/9v/0//P/8//2//j/+v/8//z//f/+/wAAAAABAAIAAgACAAIAAQABAAAAAQACAAIAAgABAAAAAAD//////v/7//f/8//v/+z/6//r/+z/7P/t/+7/8P/y//X/+P/6//r/+//8//3//////////v/9//v/+v/5//j/9//2//T/8v/w/+3/6v/n/+T/4//i/+L/4//i/+P/5f/o/+v/7v/v/+7/7P/r/+r/7P/w//L/9P/0//P/8v/y//P/8//z//L/8f/z//T/9//5//v/+//6//n/+P/2//X/9P/0//T/9f/3//r//P/8//3//P/7//v//P/9//7/AAAEAAkADQARABQAFgAYABgAFwAVABQAEQAPAA0ACwAJAAcABgAFAAYABwAJAAsADQAOAA8AEAARABIAEgASABEADwAOAA0ADQAOABAAEwAWABkAGwAbABoAGAAWABQAEwASABEAEgASABQAFwAaAB0AHwAgACAAIAAfAB4AHAAaABkAGAAYABgAGAAYABcAFgAWABYAFwAXABcAFgAUABEAEAAOAA4ADQALAAoACAAHAAcABwAHAAcABQAEAAMAAgAAAAAA/v/8//v/+//8//3///8AAAAAAQADAAUABwAIAAgACAAIAAoACwAMAAwACwAKAAkACQAJAAkACQAJAAkACgAMAA4AEAAQAA4ADQAKAAkACAAGAAUAAwAAAAAAAAABAAQABgAIAAgACQAKAAsACwAKAAkABwAFAAQAAwADAAQABQAGAAcACgAMAA4AEAAQABAAEAAQABAAEQARABEAEAAPAA0ACgAHAAQAAQAAAP///v/+//3/+//6//r/+v/7//z//f/8//r/+P/2//T/8v/x/+7/7P/p/+b/5f/m/+f/6f/r/+z/7f/t/+3/7v/w//H/8//0//X/9v/3//j/+f/5//f/9f/x/+//7v/v//L/9v/6//z//v/+//3//P/7//r/+f/5//r/+//9////AAACAAIAAgAAAP3/+f/0//H/7//w//L/9f/3//n/+v/6//v/+//8//3//f/9//3//v/+//7//v/8//n/9f/x/+3/6//p/+j/5//n/+j/6v/r/+v/6v/o/+b/5P/k/+X/5//o/+n/6v/q/+z/7v/v/+//7v/t/+z/7P/u//H/8//0//P/8v/w//D/8f/z//T/9f/1//b/+P/7//7/AAAAAAAAAAAAAP///v/+//3//f/9//7//v/+//7//v/+////AAACAAMAAwADAAIAAQAAAP///f/6//j/9v/2//f/+v/8////AAABAAIAAwADAAIAAAD///3//P/8//3//v///wAAAgAEAAcACQAKAAkABwAGAAQABAAFAAcACQAKAAsACwAKAAkACQAIAAkACgALAAwADAANAA0ADQAOAA4ADwAPAA8ADwAPAA8ADwAPAA8ADgANAAoABwAFAAMAAwADAAUABgAIAAcABgAEAAMAAgABAAEAAQABAAIAAwAGAAgACQAJAAgABQADAAEAAAD///7//f/9//7/AAADAAYABwAGAAMAAgAAAAAAAAD+//7//f/+/wAAAQACAAMAAgAAAAAA////////////////AAABAAQABgAJAAoACwAMAA4AEQATABYAGAAaABoAGgAZABcAFQATABAADwANAAsACQAHAAcACAAJAAsADAALAAoACQAJAAkACgAJAAcAAwAAAP3/+//7//r/+f/4//b/9f/1//b/9//4//j/9//2//X/8//x/+//7v/s/+z/7P/t/+z/6//q/+n/6f/p/+v/7f/w//P/9//8////AQACAAEAAAD///7//v//////AAAAAP///v/+//7///8AAAEAAwAGAAgACgALAAwADgAOAA8ADwAPAA4ADgAPABEAEwAVABUAFQATABEADwANAAsACQAIAAYABQAGAAcACAAJAAgACAAJAAoACwAMAA0ADQAMAAoABwAEAAAA+//2//P/8P/w//D/8f/z//b/+f/9/wAAAgACAAAA///+//7//v/////////+//7///8AAAAAAAAAAP7//P/9////AQAGAAwAEAAUABYAFgAUABEADgAKAAcABAABAAAA//8AAAIABgAJAAkABgABAP7//P/9/wAAAQABAAAA/v/9//3///8AAAIAAgABAAEAAgADAAUABgAFAAQAAwAEAAUABgAHAAYABQAFAAcACgAOABEAEwATABEADgAMAAoACAAGAAQABAADAAQABQAGAAYABgAFAAUABAADAAIAAQAAAAAAAAAAAAEAAgACAAMAAwAEAAQABgAIAAoADAAOABEAEwAWABkAGgAZABYAEgAOAAsACQAIAAgACAAGAAUABAAEAAQABAAEAAMAAgABAAAAAAD///7//P/6//r/+f/4//n/+v/6//v/+//8//z/+//4//X/8v/w/+3/7P/r/+v/6//s/+3/7v/w//H/8//1//j//P8AAAQABwAJAAsACwAJAAYAAQD9//n/9v/2//b/9//3//f/9v/3//f/+P/5//j/9v/0//H/7//t/+v/6P/l/+L/4P/g/+L/5P/o/+z/8P/1//r///8DAAUABwAGAAUAAwAAAP///P/4//b/9P/1//j/+//+/wAAAAABAAEAAAAAAP///v/+////AQAEAAcACQAJAAgABgAFAAMABAAFAAcACQAMAA8AEQARAA8ADQALAAgABgAFAAYABgAHAAgACQALAAwADQANAA0ACwAJAAcABAABAAAA/f/6//j/9P/x/+7/7P/r/+v/6//s/+3/7//x//T/9v/4//n/+f/4//f/9//3//f/9//4//j/+v/8//3//v/+//v/+P/1//L/8P/w//D/8f/z//X/9//5//r/+//7//v//P/9////AAACAAUABwAJAAoACQAHAAQAAQAAAAAAAAABAAMABQAGAAkACgAMAAwACgAIAAYABgAJAA0AEQAUABUAFQAUABQAFAATABMAEgASABMAFgAbACAAJAAmACYAJAAiACAAHgAdABsAGgAZABsAHQAgACMAJQAmACUAIwAhAB4AGwAYABUAEQAPAAwACwAKAAsADAAOABAAEgAUABYAGAAZABoAGwAbABoAGQAYABUAEgAOAAoABwAFAAMAAgABAAEAAgAEAAcACQAMAA0ADgAOAA8AEAAQABEAEAAPAA4ADQANAAwACwAHAAMA///8//v//P///wAAAAAAAAAAAAABAAMABQAEAAMAAgABAAIABAAGAAcABgAEAAEA/v/7//n/9v/1//P/8//z//P/9P/1//X/9f/1//X/9P/z//L/8v/y//L/8//0//X/9v/3//f/+P/2//T/8f/u/+v/6v/p/+n/6f/o/+b/5f/j/+L/4v/h/+D/3//f/+H/4v/k/+b/6P/p/+j/6P/n/+X/4//g/97/3P/c/93/3//g/+H/4v/j/+X/5//p/+n/6P/n/+b/5P/i/+H/3//d/9v/2f/Z/9n/2v/a/9r/2v/b/93/3//i/+X/6P/q/+r/6//r/+v/7P/t/+7/7v/v//H/8//0//b/9//2//X/9P/z//L/8//0//b/9v/3//f/9//5//v//P/9//7//v///wAAAgAEAAUABQAEAAEAAAD9//v/+v/6//v//P///wAABAAHAAkACwAMAA0ADgAPABAAEQARABAADgALAAkABwAHAAcABwAIAAkACgAMAA4AEAASABMAFAAVABYAGAAaABwAHgAfAB4AHQAbABgAFAASABAADwAOAA8AEAATABYAGQAdACEAIwAkACUAJAAjACEAHwAcABoAGAAVABQAFAAUABUAFgAYABkAGwAdACAAIwAmACgAKAAoACcAJAAgABwAFwARAA0ACQAHAAYABwAIAAoACwALAA0ADgAQABIAEwASABEADgAKAAgABQAEAAIAAAD+//v/+v/6//z//v8AAAIABQAGAAcABwAFAAMAAAD+//z/+v/6//v//f///wIABwAMABEAFAAWABUAFAASABAADQAKAAcABAACAAAAAAAAAAAAAQACAAMABgAKAA4AEwAWABkAGwAbABoAGAAVABEADAAIAAUAAgAAAAAAAAAAAAAAAQADAAYACQAMAA8AEQARABEADwAMAAgAAwAAAPz/+f/3//f/+P/7//7/AAADAAQABAAEAAMAAQAAAP3/+v/3//b/9v/2//j/+P/4//j/+f/5//r/+//9//3//f/9//3//P/6//j/9P/w/+z/6f/p/+j/6v/s/+//9P/3//v//v/+//3/+//5//b/8//x/+7/7P/q/+j/5//m/+X/5P/j/+P/5P/m/+r/7f/w//L/8v/z//P/8v/y//H/8f/x//P/9P/3//n/+//+/wAAAQADAAQABAAEAAMAAgABAAAAAAAAAAAAAAAAAAAAAAD///7//f/8//z//P/8//3//v//////AAAAAP///v/+//7/AAABAAUACQALAA4ADgAOAA0ACwAJAAYABQAEAAMAAwACAAAA/v/5//X/8P/t/+z/7f/w//P/9v/5//r/+//5//f/8//v/+r/5//m/+b/6P/s/+//8v/1//b/9//2//X/8v/v/+z/6f/n/+f/6P/p/+v/7f/u/+//8P/x//L/8//1//j/+f/7//z//P/7//r/+f/3//T/8v/x//H/8//2//r///8CAAUABwAHAAkACwAOAA8AEQARAA8ADgANAAsACQAHAAUAAgABAAIABgALABIAFwAbAB0AHgAfAB8AHwAdABoAFwAUABMAEgATABQAEwASABEAEAAQABAAEAAQABAAEAAQABAAEAAPAA4ADQAMAA0ADgAPABEAEQARABEAEwAVABYAFwAWABMADwALAAgABwAHAAcABwAHAAcABgAHAAcABwAHAAcACQAMABAAEwAVABYAFQAVABYAFgAWABQAEgAOAAsACgAKAAwADgAOAA4ADQALAAkACAAHAAQAAgAAAP////8AAAEAAgAEAAYABwAJAAwADgAPABAAEQARABAADwANAAoABwAEAAIAAAD///3/+//4//X/8//x//H/8f/y//L/8//z//L/8f/x//D/7v/u/+3/7P/s/+z/7v/v//D/8f/y//L/8f/w/+7/6//o/+T/4f/f/9//4P/j/+f/6//v//P/9v/5//v//P/9//z/+v/4//X/8//x/+//7P/q/+b/4//h/9//3f/c/9z/3f/f/+L/5P/l/+X/4//h/9//3//g/+P/5v/q/+//9P/5//7/AAAAAP7/+v/1//H/8P/x//L/9f/3//j/+P/5//r/+//7//v/+//7//z//v8AAAMABQAHAAcABgAEAAIAAAD+//z/+v/5//r/+//9////AAACAAMABAAFAAYABwAIAAkACQAJAAkACQAJAAoACwANABAAEwAXABoAHQAfAB4AHQAZABUAEAAMAAkABQADAAEAAAAAAAAAAgAEAAYACQAMAA4AEQAUABcAGAAYABcAFQASABEADwANAAsACgAKAAoACgALAAwADgARABMAFQAWABYAFAASABAAEQASABQAFgAWABYAFAATABMAEwASABEAEAAOAA4ADwASABQAFwAZABkAGQAXABMADgAIAAIAAAD//wAAAQAEAAcACQALAAsACwAKAAgABQADAAEAAAACAAQABwAJAAkACQAHAAQAAQD+//r/9//2//X/9f/1//P/8v/w/+7/7f/s/+r/6f/n/+b/5v/n/+j/6f/p/+n/6P/p/+n/6v/r/+z/7v/u/+//7v/u/+z/6//q/+r/6v/r/+v/6//q/+n/6P/n/+b/5P/j/+P/4//m/+n/7f/v//H/8v/z//T/9//6//3/AAADAAcACwAPABIAEwATABIAEAAPAAwACwAJAAYABQAFAAUABwAJAAkACQAIAAgABwAHAAcABwAHAAcABgAFAAUABQAFAAQABAACAAAA///9//r/9//1//P/8f/v/+7/7v/t/+3/7f/u/+7/7//w//H/8v/0//X/9f/2//T/8v/w/+7/7P/s/+3/7//x//P/9P/0//L/8P/v/+3/7f/u/+7/7v/t/+z/6//r/+v/6//s/+7/8P/z//f/+f/7//v/+v/5//f/9f/y//D/7//w//H/9P/3//r/+//8//z/+//7//z//f///wEABQAJAAwADQAMAAkABAAAAP7//P/9////AAACAAQABQAGAAcACAAKAAsADAAOAA8AEQATABYAGAAbABwAGwAaABgAFgAWABcAGQAbABwAHAAaABgAFQARAA4ACwAJAAgACQAMABAAFAAXABsAHgAgACMAJgApACsALAAtAC0ALAArACoAKQAnACUAIwAiACIAJAAmACgAKgArACsAKAAjAB0AFwARAA4ADAANAA8AEAARABEAEQAQAA4ADQAMAAsACQAIAAYABAACAAAA////////AAAAAAEAAQAAAAAA///+//3//f/8//r/+P/2//T/8v/x//H/8P/v/+//7//w//L/9f/3//n/+v/5//j/9v/1//P/8v/w/+3/6//o/+f/5v/n/+j/6f/r/+3/7//x//P/9f/2//b/9v/0//H/7f/q/+f/5v/m/+j/7P/w//P/9//5//v/+//7//v/+v/5//j/+P/4//r//P/9//3//P/7//n/+P/4//j/+f/6//r/+v/6//n/+f/4//f/9v/2//f/+v/+/wIACAAPABUAGQAdAB4AHwAdABoAFwATABAADAAJAAYAAwAAAAAAAAACAAMABAADAAIAAgACAAQABgAJAAsADAANAA0ADQANAA4ADgAPABEAEwAUABUAFgAVABMAEQAOAAoABQAAAPz/+f/3//b/9//4//n/+v/6//n/+P/3//X/8//w/+7/7f/s/+v/6v/o/+b/5f/k/+P/4//k/+T/5f/n/+r/7f/v//D/7v/r/+f/4//g/93/2//a/9n/2f/a/9z/3v/g/+H/4f/i/+P/5v/q/+7/8f/0//X/9f/z/+//6//m/+P/4f/i/+X/6f/t//H/8//0//P/8f/t/+n/5v/j/+P/5P/n/+v/7//x//L/8//z//L/8v/0//b/+v///wMACAAMAA4ADwAPAA4ACwAIAAUAAQAAAP////8AAAEAAgACAAEAAAD+//v/+f/3//f/+P/7//7/AQAEAAUABQAEAAUABgAKAA4AEgAVABgAGwAdAB8AHwAeABsAFwATAA8ADAAKAAcABQAEAAMAAgADAAMAAwAEAAQABgAIAAsADgAPABAAEAAQABAADwAPAA4ADgAOABAAEgAUABYAFwAXABcAFgAWABYAFgAUABIADwANAAsACwALAA0ADwARABUAGAAaABsAGQAVABIADwANAA4ADgAOAA0ACwAJAAgABwAGAAYABQAGAAcACQALAA0ADgAOAA0ACgAIAAcABwAIAAoADAAOABAAEQARAA8ADQAKAAcAAwAAAP///f/8//v/+v/6//v//P/+///////+//3//P/9//7/AAAAAAEAAAD9//z/+v/6//n/+v/6//r/+//+/wAABAAHAAkACgAKAAoACQAIAAgACAAIAAkACgAKAAoACAAFAAIAAAD///////8AAAAAAwAFAAgACgALAAsACwALAAwADgARABUAGAAZABkAGQAYABgAFwAXABcAFgAVABMAEAAMAAgAAwD///v/9//0//H/7//u/+7/7//w//L/8//0//X/9//5//z///8AAAEAAgADAAQABQAGAAUABQAEAAMAAgACAAIAAgACAAEAAAAAAAAAAAD///v/9//y/+7/6//p/+f/5P/h/97/3f/e/+H/5v/r/+7/7v/t/+z/6//q/+n/6f/o/+j/6P/q/+z/7v/w//H/8v/0//b/+f/7//v/9//y/+3/6f/n/+f/6P/p/+j/6P/o/+r/7P/v//D/7//t/+r/6P/n/+f/5v/k/+L/3//d/93/3//j/+b/6f/r/+3/8P/y//X/9v/4//n/+////wQACwASABYAFwAWABQAEgAQAAwACAADAAAA/f/8//z//P/6//f/8//w/+//8P/0//j//P///wIABwAMABAAFAAVABQAEwASABEAEQAQAA4ACgAHAAMAAAD///z/+v/5//r//v8DAAkADwARABEAEQARABIAEwAUABIADwALAAgABgAEAAMAAAD8//f/9P/z//b/+v/+/wAAAgAEAAcACgANAA0ADAAJAAgACAAMABEAGAAcAB4AHgAdAB0AHQAbABkAFQARAA4ADAANAA4ADgANAAoABgADAAEAAAAAAAAAAAAAAAIABQAIAAsACwAKAAgABgAEAAMAAwACAAIAAQAAAAEAAgADAAQAAwACAAAAAAABAAMABwAJAAsACwAMAA0ADQANAAwACQAGAAIAAAD+//z/+f/2//H/7P/p/+f/5v/n/+f/5v/l/+X/5//p/+z/7v/v/+7/7P/r/+r/6v/r/+r/6f/n/+b/5v/n/+j/6v/s/+7/8f/1//r//v8AAAIAAgACAAEAAAD9//n/8//s/+X/4P/d/9v/2v/a/9v/3f/g/+X/6//y//f/+////wEABAAGAAgACAAIAAcACAAJAAoACwAKAAYAAgD+//r/+f/5//v//P/+//7////+//7///////7//f/9//3//v8AAAIABQAFAAMA///5//P/7v/q/+f/5//o/+v/7//0//n//f8AAAEAAgACAAMABAAGAAgACwANAA0ADQAKAAcAAwAAAP3//P/7//z//v8AAAAAAQADAAMAAwACAAEAAAAAAAIABQAIAAkACgAKAAsACwAMAA4ADwAPAA8ADgANAAwADAALAAkABwAHAAgACwARABYAGwAdAB4AHAAbABkAFwAWABQAEQAOAAwACgAKAAkABwAEAAEA///+//////8AAAEAAgAEAAYACAAJAAgABgAEAAMABAAFAAcACAAIAAcABgAFAAUABgAGAAUAAwACAAEAAgACAAMAAgAAAP7//f/9//7///8AAAAAAAACAAUACQAMAA0ADAAKAAgABgAFAAYABQAEAAMAAwAFAAgADQARABQAFQAWABcAGAAaABoAGAAUAA4ACQADAAAA/v/7//j/9v/1//f/+v///wEAAwAEAAUABgAHAAkACQAIAAUAAgAAAAAAAAAAAAAA/v/6//j/9//4//r/+v/5//f/9f/1//b/9//2//X/8f/u/+z/7f/w//L/9f/2//j/+v/9/wAAAgACAAIAAAD///7//f/7//f/8//u/+r/6P/o/+j/6v/q/+r/6v/r/+z/7v/w//L/8v/0//X/+P/8/wAABAAIAAoACwAKAAkABwAEAAAA/v/6//b/8//y//D/7v/s/+n/5v/k/+L/4//k/+b/6P/r/+7/8P/y//L/8P/t/+j/5f/j/+P/4//j/+H/3//d/93/3//h/+P/5f/n/+n/7f/y//f//P/9//3/+//5//n/+P/4//b/9P/z//T/9v/5//z//f/8//v/+//9/wAABAAGAAcABgAHAAgACwAOAA8ADwAOAA0ADQAPABEAEgARAA8ADgANAA4ADwAQABAAEAARABIAFQAYABoAGgAaABoAHAAfACIAJAAlACQAIgAhACAAHgAaABQADgAJAAgACgAOABIAFAARAA4ACwAJAAkACgALAAsACgAKAAsADgASABQAFAATAA8ADAAKAAkACAAHAAUAAgAAAAAAAAAAAP///f/6//f/9f/1//b/+P/4//j/+P/3//j/+P/4//f/8//v/+v/6f/q/+v/7f/u/+7/7v/t/+7/8P/z//b/+P/7//7/AAADAAMAAwABAP///P/6//n/+P/4//n/+////wMACAALAA0ADQALAAsADQARABUAGAAaABoAGQAZABkAGQAXABQAEAANAAsADAAOABEAEwAUABQAEgAQAA4ACwAKAAgACAAJAA0AEQAWABoAHQAeAB4AHgAeAB4AHQAdABwAGgAYABUAEQANAAcAAgD///z//P/+/wAABAAIAAsADgARABIAEgARAA8ADwAPABAAEQARAA8ACwAHAAEA///8//r/+P/3//f/+P/6//z//f/8//v/+P/1//P/8//z//X/9v/4//r//P/9//7//v/+//3//v8AAAIABAAFAAUABQAEAAEA/v/4//P/7f/q/+j/6P/p/+n/5//l/+L/4P/f/93/2//a/9n/2v/d/+L/5//q/+v/6v/p/+r/7P/v//L/9P/1//X/9P/z//D/6//l/97/2f/W/9b/2f/e/+L/5v/q/+3/7//x//L/8v/z//P/9f/5//3/AAABAAEAAAD+//v/+f/2//T/8v/w/+//7//v//D/8P/v/+//7v/u//D/8f/z//X/9//5//r/+//8//3///8BAAQABwAJAAsADQAOAA8ADwAOAA0ADQANAA4ADwAQABAADgALAAgABgAEAAIAAAD+//z//f8AAAUACwAQABIAEgAQAA8ADwANAAwACgAGAAMAAgABAAMABAAEAAQABQAGAAkACwANAA4ADgAPABAAEQATABQAFQAUABIAEAANAAoABwADAAAA/v/9//z//f/9//7/AAAAAAAAAQABAAAA///+//3//f/9//7//v/+//3//f/9////AAAEAAYABwAIAAgACAAHAAYABgAEAAIAAAD+//7///8AAAEAAQAAAAAA/v/+//7//v/+//3//f/+/wAAAwAGAAgACAAGAAMAAAAAAP//AAABAAMABQAIAAwADgAQAA8ADAAJAAYAAwACAAIAAwADAAQABAAEAAUABwAJAAsACwAMAAwADQAOAA8ADgANAAsACAAGAAUABAADAAIAAQAAAAAAAQADAAQABQAFAAUABwAJAAsADQALAAkABQABAAAA/////////////wAAAQADAAUABgAEAAIAAQABAAMABgAHAAYABAABAAAA/v/9//v/+f/4//f/+P/7//7/AAABAAAAAAD///7//v/9//3/+//5//j/9v/2//X/9P/y//H/8P/x//T/9v/4//n/+f/4//f/9//3//f/+P/6//z//f/+////AAABAAIABAAFAAUABQAEAAMAAwADAAMAAgABAAAAAAD///7//v/+//7//f/8//z/+//7//v/+//8//z/+//5//b/8v/v/+z/6v/p/+j/6P/o/+r/7f/x//T/9//4//j/+P/2//T/8f/u/+z/6v/p/+r/6//s/+3/7f/u/+7/7//v/+//7//v/+//8P/y//T/9v/2//b/9f/0//T/9P/1//b/+P/7//7/AQAFAAcACQAIAAcABAACAAAA///+//7///8AAAEAAwAFAAYABwAHAAcABgAFAAUABgAHAAgACQAJAAoACwALAAoACAAGAAQAAwAEAAcACgAMAA4ADwAPAA8ADwAPAA4ADQANAA4AEQAWABsAHgAfAB8AHgAdAB4AHgAdAB0AHAAbABoAGQAYABUAEAALAAYABAACAAMABQAHAAoADgARABMAEwARAA0ACAAEAAIAAAAAAP//AAABAAQACQALAA0ADAAJAAYABQAFAAYACAAJAAgABwAHAAYABQADAAAA/f/6//f/9v/2//j/+v/9////AAAAAAAAAAD///7//P/6//n/9//2//b/9f/1//b/9//4//n/+f/5//j/9v/1//L/8P/t/+r/5//m/+b/6f/t//L/9v/5//v//P/9//3//f/9//3//v///wAAAQACAAAA/v/6//b/8v/w/+7/7P/r/+r/6//v//T/+f/7//v/+P/1//P/9P/3//v//v8AAAAAAAAAAAAA///9//v/+P/3//f/+f/6//r/+f/4//j/+f/6//v/+//6//n/+f/6//3/AAAAAAAAAAACAAUACgAPABMAFQAUABEADgALAAgABwAEAAMAAQABAAIABQAHAAgABwAFAAMAAQABAAEAAQABAAAAAAAAAAIABgAKAAwADQALAAkABwAGAAYABAABAP//+//5//j/+P/3//X/8//w/+7/7v/v//D/8v/y//P/9P/3//v///8BAAQABQAHAAgACgALAAsACQAGAAAA+v/0/+3/6f/n/+f/6v/u//H/8//0//P/8v/z//T/9f/2//n//P8AAAIABAAEAAEA/v/4//T/8f/u/+3/6//p/+f/5v/n/+n/7P/w//P/9//7////AgAFAAgACQAKAAoACwALAAsADAALAAoACQAIAAgACQAKAAsACwAJAAcABAACAAAAAAD//wAAAAAAAAAAAQADAAYACQALAA8AEgAXABoAHQAfACAAIAAfAB4AHQAbABkAFwAUABIAEQAQAA8ADgANAAwADQANAA4ADwAPAA4ADgAOAA8AEQARABAADwANAA4AEAAVABsAIAAkACcAKQArAC0ALQAqACcAIwAfABsAGQAXABQADwAJAAMA/v/7//n/+P/4//j/+f/5//r/+//8//3//f/+////AAAAAAEAAQACAAIAAgAAAP///f/8//v/+v/5//f/9f/z//L/8f/x//H/8P/v/+7/7v/v//D/8f/w//D/7//u/+3/7f/s/+n/5v/k/+L/4v/k/+b/6P/q/+z/7f/v//L/9P/2//j/+v/8//3//P/6//f/8v/u/+v/6v/q/+v/6//s/+z/7P/t/+3/7f/t/+z/7P/s/+z/7f/s/+z/6//s/+3/8P/z//X/+P/6//3///8BAAMAAwACAAAA/f/6//f/9v/3//b/9v/0//L/8P/u/+z/6//q/+r/6//t/+//8//2//n/+//9//3//v///wAAAgAEAAYACQALAA0ADgAOAA0ADQAMAA0ADwAPAA8ADQAJAAYAAwABAAAAAQABAAEAAgADAAUABgAHAAcABwAGAAUABwAIAAoADAANAA4AEAATABYAGQAaABoAGQAZABkAGwAdAB0AGwAXABIADgALAAoACAAHAAQAAQD+//v/+P/3//f/9v/2//b/9f/1//X/9v/4//n/+v/8//7/AAACAAYACQAMAA4ADwAOAAwACgAHAAYABAAEAAMAAgAAAP///v/8//v/+v/4//X/8f/v/+7/7//y//b/+v/9/wAAAQADAAUABQAEAAIA///8//n/+f/6//z//f/+////AAACAAUABwAHAAYAAgD///z/+//6//v/+//7//v//P///wEABAAGAAYABgAHAAcACQALAA0ADgAOAA4ADQAMAAsACQAHAAMAAQAAAP//AAABAAIAAwADAAMAAwAEAAUABgAHAAgACQAKAAsACwALAAwADQAPABEAEwASABEADwANAAsACgAJAAcABQACAAEAAQACAAQABgAGAAYABgAGAAcACQAKAAoACQAHAAUABAAEAAUABQAEAAQABAAEAAYABwAIAAgABwAFAAUABQAGAAcACQALAAsACwAKAAgABwAFAAIAAAD///3//P/8//3//v///wAAAAAAAAAAAAAAAAAA/f/6//j/9//3//n//P/9//z/+f/z/+3/6P/k/+L/4v/k/+b/5//o/+j/6P/n/+f/5//p/+r/6//t/+//8v/1//f/+v/7//z/+//7//n/9v/0//D/7f/q/+f/5v/l/+b/5v/n/+n/6f/q/+r/6v/r/+3/7//x//T/9f/3//f/9//1//L/7//s/+j/5v/k/+P/4//j/+T/5v/o/+v/7v/x//P/9f/3//n/+////wEABQAHAAkACQAJAAkABwAGAAQAAgAAAP//+//4//f/9//5//3/AAAEAAcACgALAA0ADwARABIAEgARABEAEgAUABYAFwAWABUAEgARAA8ADwAOAAsACAAFAAEA////////AAADAAcACwAOABEAEgASABIAEAAOAA0ADAALAAsACgAKAAkABwADAAEA///9//z/+v/4//T/8P/s/+n/5//n/+j/6f/p/+v/7f/x//X/+v/9////AAAAAAIABQAHAAkACQAHAAUABQAFAAYACQAMAA4ADwARABEAEgATABMAEwAUABQAFQAVABYAGAAYABcAFgAUABIADwANAAoABwAGAAUABgAIAAoADgARABQAFgAYABoAHAAeAB8AHwAdABsAGQAWABMAEAANAAsACQAGAAQABAADAAMABAAGAAgACgANAA8AEgAVABgAGwAeACEAJAAlACYAJwAoACgAJgAjACAAHAAYABUAEwARABAADwANAAsACQAIAAcABgAFAAQAAwACAAEAAQACAAMABAAFAAQAAwACAAEAAQABAAEAAQAAAAAAAAAAAAAAAAD///3/+//5//f/9P/x/+7/6f/m/+L/4P/g/+H/4f/i/+L/4v/j/+X/5//p/+v/7P/s/+r/6P/l/+P/4f/h/+H/4//k/+b/5//o/+n/6f/p/+j/5v/k/+L/4f/i/+T/5f/m/+X/4//h/97/3P/b/9r/2v/Z/9r/3P/f/+T/6P/s/+7/7//v//D/8P/y//X/9//5//n/9//1//L/7v/s/+n/5//k/+L/4f/h/+L/4//k/+T/5P/k/+b/6P/s//D/8//2//j/+v/9////AAABAAIAAwAFAAcACgAMAA0ADAALAAoACwALAA0ADwAPAA8ADgAMAAwADAAMAA4ADwAQABEAEgATABIAEQAQAA8ADgAOABAAEgAVABcAGAAYABcAFgATABEADwANAAwACwALAAoACgAKAAoACwAMAAwADAAMAAwACwAMAA0ADgAPAA8ADwAOAA4ADgAOAA0ADAAKAAgABQAEAAQAAwADAAMAAgAAAAAAAAAAAAEAAwAFAAcACQALAAwADAALAAoACAAGAAUABQAFAAYACAALAA4AEAARABEAEQARABAAEAAQABAAEAAPAA8ADgANAAwADAALAAsACgAKAAoACQAIAAcABQACAAEAAAABAAMABgAJAAoADAAMAAsACgALAAsADAANAA0ADAAJAAcABAACAAAA///+//3//P/8//z//P/7//n/9v/z//H/8f/x//T/+P/7////AgAFAAYABwAGAAUABAAEAAQABgAHAAgACAAHAAcABQADAAAA/v/7//n/9//3//f/9v/1//T/8//1//j/+////wEAAwAEAAQABQAGAAUAAgD///r/9v/0//T/9f/3//f/+P/4//n/+v/8//7/AAAAAAEAAgAEAAcACAAIAAcABgADAAAA///8//v/+P/2//T/8//w/+//7v/u//D/8v/2//v///8DAAYACQAMAA4AEAARABIAEgAQAA4ACwAHAAUAAwADAAMAAwACAAEAAAD+//v/+f/3//X/8//y//L/9P/3//r//f///wAAAAAAAAAAAAD///3/+v/5//f/9v/0//L/7//r/+j/5f/j/+H/3//e/93/3P/e/+H/5P/o/+v/7P/t/+3/7f/t/+7/7v/u/+3/7f/s/+z/7P/s/+z/7P/s/+z/7f/v//L/9f/3//r/+//8//z//P/8//v//P/9////AAADAAYACQAMAA8AEAAQAA8ADQAKAAcABQADAAQABQAIAAoADAAPABEAEwAWABcAGAAYABgAGQAbABwAHQAbABYAEQAMAAgABQADAAEAAAAAAAAAAgAGAAwAEQAUABcAGAAaABsAHgAfACEAIAAfAB4AHAAaABgAFgATABIAEgATABUAFgAYABgAGAAYABgAGQAaABwAHgAgACMAJQAmACYAJgAmACUAJQAlACQAIwAhAB4AGgAVABAADAAIAAUAAgABAAEAAQADAAUABgAHAAcABwAIAAgACQALAAwADAAKAAcABAAAAP7/+//4//X/8v/v/+3/7P/s/+z/7f/t/+z/6//r/+v/7P/t/+//8P/w//D/8P/v/+3/6//p/+j/5v/l/+X/5f/l/+X/5v/n/+j/6v/s/+7/8P/y//X/+P/8/wAAAwAHAAkACgAJAAcABQACAAAA///9//z/+//7//r/+v/4//X/8v/v/+7/7//y//b/+f/8//3//v/9//z/+v/4//P/7//s/+n/6f/r/+7/8P/y//L/8f/v/+7/7f/t/+7/8P/z//X/+P/6//v//P/9//3//P/8//z//P8AAAIABwALAA0ADgAMAAoACAAEAAEAAAD9//v/+v/6//v//f/+////AAAAAAAAAAABAAMABQAIAAsADQAPABAAEQARAA8ADQAKAAUAAQD9//n/9v/0//P/8v/x//D/7//t/+v/6f/o/+n/6v/t//H/9P/3//j/+P/3//X/8v/u/+r/5//m/+X/5//q/+3/7v/v/+7/7f/r/+r/6P/o/+j/6v/u//P/+P/9/wAAAgACAAIAAgABAAIAAgACAAMABQAJAA0AEgAVABcAFwAXABYAFwAYABkAGwAcAB0AHgAeAB4AHAAZABYAEwASABMAFQAXABgAGQAYABcAFgAUABIAEAAOAA0ADQAOABEAFAAYABsAHQAfAB8AIAAfAB8AHQAbABoAGQAXABcAFgAUABMAEQAPAA8ADgAOAA4ADQANAA0AEAASABYAGQAbAB0AHwAiACYAKQArAC0ALgAtACwAKwApACcAJQAhAB4AGgAYABcAFgAVABUAFQAVABYAFwAXABcAFwAWABUAEwARAA4ACwAIAAUAAgAAAP7/+//5//b/9P/0//X/9f/2//f/9//4//j/+f/6//v/+//5//j/9//1//L/7f/o/+L/3P/Y/9T/0v/Q/9D/0P/R/9T/2P/c/+D/5P/n/+n/7P/v//H/8v/z//P/8f/v/+3/6v/n/+T/4P/d/9r/2f/Z/9r/3P/e/+D/4v/l/+f/6f/s/+7/8f/z//X/9v/3//j/+f/6//r/+f/3//L/7P/m/+H/3f/b/9v/3P/d/97/3//f/97/3P/a/9n/2P/a/93/4v/n/+v/7v/w//D/8P/u/+z/6//p/+n/6v/t//H/9v/6//3///8AAP///////wAAAAABAAIAAwAEAAYABwAIAAgACQAJAAkACgAMAA8AEgAUABYAGAAYABgAFgATABAADAAIAAYABAAEAAMAAgABAAAAAAAAAAAAAAAAAAEAAQADAAQABwAJAAkACQAHAAUAAwADAAQABgAIAAoACwALAAoACQAGAAQAAAD9//r/+P/3//f/+P/5//r/+//7//z//P/7//v/+v/6//v//f8AAAIABAAGAAcACAAJAAgACAAGAAUAAwABAAIABAAHAAkADAANAA0ADQALAAgABQAAAP3/+v/5//n/+v/8//7/AAABAAMABAAFAAQABAAEAAQABgAIAAoADAANAA4ADgAPABAAEAAQAA8ADQAMAA0ADgAPAA8AEAAPAA8AEAARABMAFQAWABgAGgAcAB8AIAAgAB0AGgAVABEADgAMAAwADQAPABIAFgAZABsAHAAcABsAGgAYABcAFgAWABcAGQAdACIAJQAoACgAJgAiAB4AGQAVABIAEAAOAAwACwAKAAoACgAKAAsACwALAAoACgAJAAkACQAJAAgABwAFAAIAAQAAAAAA///+//3/+f/1//D/7f/q/+j/5//m/+T/5P/k/+b/6f/t//L/9//6//3///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA///+//z/+v/4//X/9P/z//L/8f/x//H/8f/y//L/8v/x/+7/7P/p/+j/6P/q/+3/7//x//H/8P/v/+3/7P/r/+v/7P/s/+7/8P/y//T/9P/z//H/7v/s/+r/6P/o/+j/6f/r/+7/8f/0//b/+P/5//v//P///wEAAwAEAAQAAwACAAIAAQAAAP///f/6//j/9//3//n/+//+/wAABAAGAAgACAAIAAYAAwABAAAA///+//3//P/8//3//v8AAAIAAgABAAAA/f/7//r/+f/4//j/+P/4//j/+f/6//r/+f/4//f/9//4//n/+//7//v/+//7//v/+v/6//n/9//2//X/9f/3//n/+//8//z/+//5//f/9f/0//P/8//z//P/8//0//b/+P/5//n/+P/3//X/9P/z//T/9v/4//v///8AAAIAAwACAAIAAQAAAAEAAgAEAAUABwAIAAgACQAJAAkACgAMAA4AEAARABMAFAAUABQAEgAPAAsABwADAAAA/////wAAAAAAAAEAAgADAAMAAwADAAIAAgACAAIAAgACAAIAAgABAAEAAQAAAAAAAAAAAAEAAgADAAQABAAEAAQABAAEAAIAAQAAAAAAAAADAAYACgAOABEAEwAVABYAFwAWABUAEwARABAAEQATABYAGQAZABkAFwAVABIADwAMAAkABwAHAAcACQAKAAsACwAKAAkACAAIAAgACAAJAAoADAAPABIAFAAUABQAEgAQAA8ADgANAA0ADQAMAAsACQAIAAUAAgAAAPz/+f/4//f/9//5//z/AAAFAAsADwARABAADwAMAAgABAAAAPz/9//y/+7/6v/p/+f/5//o/+n/6//v//L/9P/0//L/8P/u/+3/7v/v//D/8v/0//n//v8DAAgADAAMAAoABwAEAAAA/f/4//L/7v/q/+n/6//t/+//8f/x//H/8f/y//P/9f/2//b/9//4//r/+//8//v/+v/4//b/9v/4//r//f///wAA///9//z/+v/5//f/9f/z//P/8v/z//T/9P/0//L/8P/u/+7/7v/v//D/8P/w//L/8//3//r//f/+//////8AAAEAAwAEAAUAAwACAAEAAQACAAMABAAEAAQABQAHAAkACwAMAAwADAAMAA0ADwARABIAEAANAAoABgADAAAA/v/7//j/9//3//n//P/9//z/+f/0//D/7//v//L/9//7/wAABAAJAA8AEwAUABMAEAAMAAkABwAHAAgACQAJAAkACAAJAAoADAANAA0ADQAMAAwADAANAA4ADQALAAcAAwAAAP7//f/9//3//f/9////AAABAAMABAAEAAIAAQAAAAAAAQADAAUABQAGAAYABQADAAEAAAD///3//f/+/wAAAQACAAMAAwADAAMABAAEAAUABgAHAAkACQALAAsACgAIAAQAAAD7//j/9v/1//b/9v/2//X/9P/0//L/8f/w/+7/7P/s/+z/7//y//X/+P/7//3//v8AAAAAAQACAAIABAAFAAcACAAIAAcABgAEAAMAAwADAAIAAQAAAP3/+//7//z///8AAAIAAwAFAAYABwAHAAcABQACAAAA/v/9//3//f/+//7//v/+////AAAAAAIAAwAEAAUABQAGAAcABwAIAAgABwAGAAUABAADAAMAAgACAAEAAgADAAQABQAGAAYABQADAAIAAQAAAAAAAAAAAAAAAAABAAQABwAKAAsACwALAAoACgAKAAkACQAJAAkACQAJAAgACAAGAAQAAgABAAIAAwAEAAQABQAEAAMAAgAAAAAA/v/7//n/9//2//b/9f/z/+//6v/l/+D/2//X/9X/1P/U/9b/2f/d/+H/5f/p/+3/7//x//L/8f/w//D/8f/y//P/9P/z//H/7//s/+n/5//k/+L/4f/h/+L/5P/o/+v/7//y//b/+f/9////AQACAAMABQAGAAcABQACAP//+//4//b/9f/0//P/8//z//T/9v/3//j/9//2//X/9f/3//r//f8AAAIABAAGAAgACgALAAwADAANAA0ADQANAAwACgAHAAUAAgABAAAAAAAAAAEABAAJAAwADwARABEAEQARABIAEgARABAADwAOAA4AEAASABYAGAAYABcAFAARAA8ADAALAAsADQAPABMAFgAZABoAGwAaABkAGAAXABYAFgAVABUAFAATABMAEwATABMAEgATABUAGAAbAB4AIQAiACIAHgAaABUAEAALAAkABwAGAAcACQAMABEAFQAZABwAHgAfAB4AGwAXABMADwANAAsACgAJAAgABwAGAAUABwAJAAsADQAOAA8AEAAQABAADgALAAYAAgD///3//f///wAAAQADAAYACAAKAAoACgAHAAQAAgABAAEAAgACAAMAAgACAAEAAAD+//z/+P/0/+//6//n/+T/4v/h/+L/5P/n/+n/6//s/+z/7P/t/+z/6v/o/+X/4v/h/+H/4v/k/+X/5v/m/+f/5//m/+X/5P/h/97/2//Y/9f/1v/X/9n/3f/i/+f/7f/x//T/9v/3//b/9P/x/+//7P/r/+v/6//t/+7/8P/y//T/9v/4//n/+f/5//j/+P/4//n/+f/5//f/9f/z//H/7//u/+3/7f/t/+//8f/1//n/+//+////AAAAAAAAAQACAAIAAgACAAIAAQABAAAA///+//3//P/8//v/+v/6//v//f8AAAIABAAFAAUABAADAAIAAgADAAQABQAFAAUABQAEAAQABAAEAAQAAwACAAEAAgADAAYACAAKAAwADgAPABAAEgAUABYAFgAWABUAFQAVABYAFgAWABUAEwASABEAEAAQAA8ADgAMAAsACgAJAAgABwAGAAYABwAIAAgACAAHAAUAAwABAAAAAQABAAMABQAIAAoADAANAA0ADAAJAAYAAwAAAP7//P/6//v//P///wEABAAEAAMAAQAAAP///v/9//v/+v/5//n/+//+/wEABQAHAAgACAAIAAgABwAHAAcABwAHAAgACQALAA0ADgAOAA0ACwAIAAMAAAD8//n/9v/1//b/9//4//r//P///wAAAwAFAAYABwAHAAYABgAFAAUABAABAP//+//3//T/8//0//f/+P/6//r/+f/4//f/9f/0//L/8f/x//T/9//8/wAAAgACAAAA///8//v/+f/3//X/8v/x//D/8f/y//T/9f/4//r///8DAAcACwAMAAsACAAFAAIAAAD///////8AAAIABAAGAAcACAAIAAYAAwAAAP3/+//6//v//f///wAAAAAAAP///v/8//v/+f/2//T/8f/w/+7/7f/t/+3/7v/w//L/9f/4//r//P/+/wAAAAD+//z/+P/0//H/8f/y//T/9v/5//v//v8AAAIABAAEAAIAAAD+//z//P/9////AAADAAcACwAOABAAEQARABEAEAAQABAADwAOAAwACQAIAAcABwAJAAsADAAOAA8AEAARABIAEwATABIAEQAOAAsABwAEAAIAAAAAAP7//P/7//r/+////wIABgAJAAoACgAJAAcABgAFAAQAAwACAAEAAQAAAAEAAgACAAIAAQAAAP7//P/7//r/+//7//z//v///wAAAQADAAUABwAIAAkACQAJAAgABgAEAAMAAQAAAAAAAAAAAAAAAAACAAQABgAHAAcABgAEAAIAAAD///3/+v/2//T/8v/z//X/+P/5//r/+f/4//b/9f/y/+//6//n/+P/4f/g/+D/4f/i/+T/5v/q/+3/8P/y//L/8f/x//D/8P/x//H/8v/z//X/9//4//j/+P/4//f/9v/2//b/9f/0//T/9v/5//3/AAABAAIAAgADAAYACAAJAAoACQAHAAUABAADAAIAAgABAAIABAAGAAgACQAJAAgABwAHAAcACAAJAAoADAAPABEAFAAWABcAFwAWABYAFgAVABQAEgAPAA0ACwAJAAcABgAFAAMABAAFAAgACwANAA4ADwAOAAwACQAFAAIAAAD//wAAAAADAAUABwAGAAUAAwABAP///f/6//n/+f/6//3/AAABAAEAAQABAAEAAAAAAAAA//8AAAEAAwAEAAQAAwAAAP7/+v/3//X/8//x/+//7f/t/+z/6//r/+r/6f/q/+v/7f/v//L/9P/2//j/+f/4//f/9v/0//L/8P/v/+7/7v/t/+z/6//r/+v/7P/t/+7/7//w//H/8v/0//X/9//4//r//P/8//3//v/+/////v/9//v/+f/2//T/8//0//X/9//5//z///8BAAQABQAFAAQAAgABAAAAAAD///7//f/9//7/AAABAAIAAgABAAAAAAAAAAEAAgABAAEAAAABAAMABQAIAAkACgALAAwADAANAAwACwAJAAYABAACAAAAAAD///7///8AAAQACAALAA8AEgAUABcAGQAbABsAGgAYABYAEwARAA8ADQALAAkACAAIAAgACQAKAAwADQANAAwACgAIAAcABgAHAAkACwANAA4AEAAQABEAEAAOAAwACwAJAAkACQAKAAoACQAHAAUAAwAAAAAA//8AAAEABQAIAAwADgANAAsABwAEAAEAAAAAAAAAAQAEAAYACAAKAAkABwADAAAA/////wAAAgAFAAcACQAJAAgABgADAP//+//3//X/9f/2//j/+f/5//n/9//2//b/9v/3//j/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2f/O/8f/wf+9/73/u/+6/7f/t/+4/7v/v/+//7z/tf+t/6P/nv+e/6X/rf+2/77/xf/L/9D/1v/b/9//4//j/+D/2//S/8j/vv+z/6v/o/+e/5z/nf+i/6n/tP+//8r/1//h/+r/8f/0//L/6v/e/9L/yv/F/8b/yv/Q/9P/1//a/93/5P/t//j/AwAOABkAIgApAC8AMgAxACwAIgAVAAgA/f/0//D/7v/v/+//7//w//X//f8JABgAJwAzADsAPgA+ADoAMwAnABcABQD1/+n/4v/h/+P/5v/o/+r/7f/0/wAADAAcACkANQA/AEUASABFADwALQAbAAYA9v/o/+H/3//h/+T/5//q/+7/8f/1//b/9v/3//r//P8BAAcACQAKAAIA+v/v/+X/3f/Y/9X/0f/N/8n/yP/I/83/1f/e/+b/7//1//r//v////3/+P/v/+f/4//j/+f/6//y//b/+v///wEABAAIAAwAEQAXAB0AIQAiAB4AFQAJAP7/9//0//j//v8DAAkACwAMAAwACwAJAAcABQADAAMAAwAEAAUABQAEAAAA///9////AwAKABMAHQAnADIAPABFAEkASAA+AC4AGgAIAAAAAAAHABMAGAAVAAgA9//n/93/3v/m//X/AwAQABkAHQAbABUACQD8/+//5//l/+j/7P/v/+7/6//o/+n/7f/0//r//v////7///8AAAYACgAOAA8ADQALAAYAAQD9//r/+P/4//3/BQAMABAAEQAOAAoACgAMABQAHAAjACYAKAAoACoALgAwADMANAAzADUAOgBAAEYARwBCADgALAAjACAAJAArADMANwA2ADMAMAAuADAANgA9AEQASQBMAEwASQBBADUAJgAYAA8ACwALAAwACgAEAP3/9f/1//z/CwAcACcAKAAgABQACQABAP7//f/7//X/7P/j/93/1v/S/8z/x//F/8f/zP/Q/8v/vP+m/5L/h/+P/6P/vf/P/9D/wf+q/5f/j/+U/57/p/+s/6n/pP+g/5v/l/+P/4b/hP+N/6T/wf/d/+z/7P/h/9T/y//K/8z/yP+8/6n/mf+S/5b/pP+w/7P/rv+n/6j/tP/L/+T/9/8AAAAA/P/6//z//f/3/+n/1//J/8f/0f/h/+z/7v/p/+H/4f/v/wUAHwAyADoAPAA9AEUAUgBdAF8AUwA9ACgAHQAeACcALwAsAB4ACwAAAAAAEQAoAD8ATgBVAFgAWgBfAGMAZABdAFIASQBGAEsAUwBYAFQASQA8ADQANwBCAFIAXgBjAF8AVwBQAEsASQBFAD0AMAAiABgAEQAPAAwACAABAPv/9v/1//n/AAABAAAA+f/x/+z/6f/o/+L/1v/H/7X/p/+h/6H/pP+m/6b/ov+h/6T/rv+5/8P/yf/I/8T/wf+//77/uv+y/6T/lv+O/4v/kP+V/5r/mf+X/5b/l/+c/6P/qP+o/6P/nf+a/53/o/+q/6//sP+t/6r/qP+s/7P/vf/I/9b/5v/3/woAHAArADQAOAA4ADUANAAyADAAKwAjABsAEgAMAA0AEwAbACcANABAAE8AYQB1AIoAnACnAKoApwCgAJcAjwCJAIIAegBxAGkAZABkAGkAcwB9AIYAjACQAJIAlACVAJQAkACHAHwAbgBfAFUASwBFAD8AOQA0ADAALAAqACkAKAAnACgAKQAtADIANAAxACkAGgAJAPz/9//4////BAAFAP7/8P/f/8//xP+//7//wf/F/8j/yP/F/73/sf+k/5n/kP+Q/5P/mf+h/6P/o/+i/6P/qP+t/7H/sf+u/6f/ov+g/6H/ov+g/5n/jv+E/3z/ev98/37/fP96/3n/ff+K/5r/rP+3/7v/uv+6/8D/zP/Z/97/2f/K/7v/sf+x/73/zf/b/+L/5v/n/+z/9P/8/wEAAgACAAUADwAaACIAIgAWAAgAAgAKACMAQwBbAGQAXQBMAD8APABJAFwAbwB6AH0AewB7AH0AfwB+AHkAcgBvAHMAfACFAIgAfgBsAFgATABMAFUAYQBnAGMAXABWAFoAZAByAHoAdQBmAFAAPwA0ADUANwA1AC0AHwARAAgABgAHAAcAAgD8//X/8//1//j/+P/z/+n/3f/Y/9z/5//y//b/8f/m/9v/0//S/9H/zP/C/7L/o/+b/5v/nf+f/5r/j/+F/4H/if+X/6X/q/+m/5n/iv+B/4L/if+S/5b/lv+T/4//jP+H/4H/df9n/13/Wf9g/2v/d/99/3v/d/93/4D/k/+s/8T/1f/g/+X/6v/y//3/BwANAA4ACwAHAAUABgAKAAwAEQATABUAGQAdACAAIAAcABYAEgARABgAIgAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMANgA1ADYAOQA+AEQASQBKAEoASABKAFAAWgBkAG0AcgBzAHEAbwBqAGQAXABUAE4ASgBKAEsASwBIAEIAPAA4ADoAPwBIAE8AUABNAEUAPQA0ACwAJgAfABcADgAGAP//+f/z//H/8f/0//r/AQAIAA0AEgAUABUAFQAUABEACQD9/+//4f/W/8//y//K/8v/zf/P/9L/1f/X/9z/3v/k/+r/8f/5//7//f/2/+v/3v/T/8r/x//G/8v/0v/b/+j/9f8CAA0AEwAWABIADwALAAcAAwAAAP3/+f/z/+7/6v/o/+j/7f/2/wQAFAAmADUAQABEAEMAPgA2AC4AJgAhAB0AHAAbABwAHQAeAB8AIAAiACIAIQAfAB0AGwAaABwAHgAfAB8AHQAYABMADQAHAAEA/f/5//f/9//7/wAABAAIAAsADQAPABEAFAAXABYAEQAKAAAA+P/x/+v/5v/i/97/3P/d/+H/6v/y//n//f/+//v/+P/1//H/7f/m/97/2P/S/9D/0v/T/9X/1v/Y/93/5P/t//X/+f/5//b/8f/v/+3/7f/t/+r/5v/i/9z/2f/W/9P/0P/M/8r/y//N/9D/0v/S/9H/0f/Q/9P/2P/a/9j/1P/P/8r/yP/K/8//1P/Y/97/5f/u//f///8CAAMAAAD9//r/+P/2//P/7v/m/97/1v/P/8r/x//I/8r/0v/f/+7//v8KABUAHAAgACEAHwAZAA0AAAD1/+3/7f/0////CgATABsAHwAlACwANgA/AEkAUwBcAGMAZQBgAFUARgA2ACoAJAAmACoALwAyADMANQA5AEEASwBUAFgAWABTAE4ARgBAADgALgAlABwAGAAZAB4AJgAtADQANwA7AEAARQBHAEUAPQAxACMAFQALAAEA+P/s/93/z//E/7//wP/F/8z/0f/X/93/4//r//H/8f/t/+b/3v/c/93/4v/l/+H/2v/N/8L/uv+4/7j/uP+2/7L/rf+r/67/s/+4/7v/uf+5/7r/vP/A/8T/xv/G/8f/zP/X/+f/9/8AAAIA/v/1/+//7f/v/+//6v/f/8//xP/B/8j/1//o//b/AAAIABIAIgA0AEcAVgBeAGMAZABjAGAAWABLADsAKwAhACEALAA5AEIARABBADsAOwBBAE4AWwBkAGgAZwBlAGQAYwBfAFYARwA6ADIANQA/AE0AWABZAFMASQBCAEAAQgBGAEcARAA+ADYALwAqACQAHQAVABAADgARABgAGgAaABIACQACAAIACgAUAB8AIgAgABgADwAFAP3/8//k/9L/vv+u/6P/n/+f/6L/pf+o/6v/sv+4/8D/xv/L/87/0v/Y/9//5P/l/+D/2P/P/8n/yf/M/87/zf/H/7//t/+z/7D/sP+w/63/p/+f/5f/jP+A/3X/a/9l/2P/aP9y/33/iP+Q/5T/lf+X/5n/nv+j/6r/sP+2/7v/v//B/8H/w//F/8j/zP/R/9f/3f/j/+f/6v/t/+3/7f/r/+n/5//l/+T/5P/n/+z/9v8BAA4AGAAdAB0AGgAXABMAEwAXAB0AJAAoACsALQAuAC4AMAAxADQANwA7AEEARwBOAFYAXQBjAGkAbQBtAGwAagBnAGQAYABcAFoAVwBUAFEATwBOAFAAVABbAGUAbwB4AIAAhgCIAIcAhQB/AHkAcQBsAGkAaQBpAGkAZgBhAFsAVQBQAE4ATQBMAEsARgBBADsANgAwACwAKAAjACEAHwAeABsAFwARAAoABQADAAcADgAWABwAHgAdABgAEQAKAAMA///5//X/8f/w/+7/6v/l/93/0//H/77/t/+0/7H/rv+u/6z/rf+u/7H/s/+z/7H/rf+n/6P/oP+g/6H/of+i/6P/pf+n/6b/pP+d/5b/jf+L/43/lP+d/6b/q/+t/63/rv+w/7P/tP+y/6z/pv+h/53/m/+d/6L/qv+1/8X/1f/j/+v/7v/p/+H/3P/a/97/5P/q/+7/8P/w//D/8v/2//v/AAAEAAkADQAQABQAFQAWABQAEQANAAoACQAIAAkACQALAA4AEwAbACUAMgA/AEwAVwBhAGwAdgCAAIkAjQCOAI0AiwCIAIUAggB8AHIAaABdAFQATgBIAEMAPAAzACwAKAAmACUAIwAeABcAEQAMAA0AEQAXAB0AIgAlACgALQAxADQANQAzADEAMQAzADYANwAzACkAHAAPAAYAAQAAAAEAAgABAAAA/f/8//n/9v/x/+z/5v/i/9//3v/e/9z/2v/Y/9f/2P/Z/9n/1P/K/7//s/+q/6X/pP+k/6X/pP+l/6X/p/+s/7H/t/+9/8X/zv/Y/+P/6//x//P/8//x/+3/6P/f/9L/wv+y/6P/mf+V/5b/nP+j/6v/s/+7/8T/y//U/9z/5f/t//T/+f/4//X/7f/j/9j/0P/L/8n/yv/O/9T/2//k/+3/9f/9/wQACwARABQAEwAOAAcAAgAAAAQACQAQABQAEwARAA4ADQAPABUAHAAkAC0ANgA+AEMARABBADkALwAnAB8AGwAXABIACQD///X/7//u//L/+/8EAA0AFAAbACQALgA4AEQATgBWAFsAXABYAFEASAA/ADcAMwA1ADwARgBOAFIAUgBLAEEANgAvAC0ALQAvADAALwArACgAJgAnACwAMQA2ADgANwAzAC0AJgAfABwAGwAcAB4AIAAfABsAFAAKAAEA/f/7//7/BAAKAA4ADwAPAA0ADAANAA4ADQAKAAEA+v/y/+3/7v/y//j//v8CAAkADwAVABkAFgARAAkAAQD+//7//v/7//L/4//T/8P/uP+x/67/rP+r/6z/rv+0/7v/v/+//7z/uf+4/7v/wv/H/8f/wf+4/7D/rf+z/73/yv/V/97/5v/t//f/AAAIAA0AEQAVABcAGgAZABUADAAAAPX/7P/p/+r/7P/u/+7/7P/s/+7/8v/4//3/AAAAAP3/+f/1//H/7v/q/+b/4//i/+T/6f/v//f/AAAMABkAKAA0AD4AQgBDAEEAPwA+AD4AQAA/ADsANAAqACAAGAARAA0ACgAGAAUABAAEAAEA/f/2/+//6v/o/+v/8P/1//n//f8AAAcADwAaACUALgAzADQAMwAwACoAIgAZAA8ABwAAAPr/9P/u/+f/3//b/9r/3v/l/+7/9v/+/wUADAAUABsAHwAhACEAHgAaABYAEAAJAP//8//o/9//2v/Y/9b/1f/S/87/yv/I/8b/xv/H/8n/zP/Q/9b/3P/h/+X/5//o/+f/5//l/+L/3v/Z/9T/z//N/8z/zf/P/8//zv/L/8j/xf/D/8P/x//N/9X/3v/m/+v/7f/r/+j/4v/c/9X/0P/L/8b/w//A/73/u/+5/7j/uP+5/7//xP/M/9H/1f/W/9f/2P/d/+P/6//y//j//P/9//3///8BAAgADwAYACAAKAAuAC4AKwAjAB0AGAAaAB4AJQAqACsAJQAeABYAEwAWAB0AKgA3AEUAUABXAFwAXgBdAF0AYABkAGoAcAByAG0AZQBaAFEATgBOAFQAWgBbAFsAWQBXAFkAXQBlAG4AdgB8AH8AfgB5AG8AYwBVAEoAQwBBAEQASQBMAEsARgBAADwAPQBEAE8AWwBmAG4AcwBzAHAAaQBeAFEAQwA2ACoAIAAYAA0AAwD5//P/8P/z//j//P/9//n/8P/j/9X/x/+7/7L/rf+s/7D/tf+6/73/uv+0/6v/pf+k/6b/rv+5/8L/yv/Q/9D/zP/F/73/tP+t/6n/q/+u/7P/uP+7/7n/tf+v/6f/of+b/5j/lv+W/5X/lP+U/5n/of+v/73/yP/Q/9L/0P/N/8j/xf/B/73/uv+3/7f/t/+5/7b/r/+m/53/nf+l/7b/zP/j//f/AwAMABIAFAAVABYAGQAdACIAJgAnACQAGgALAP7/9f/z//n/AwAQABsAIwAoACsALAAtAC4AMQA1ADoAQABDAEIAPQA2AC8ALQAwADYAOwA8ADgALwAmAB8AHgAiACgAMQA5AD8AQwBEAEIAPgA6ADkAOwBCAEwAVQBbAFoAUgBHAD0ANQAvAC0AKgAnACEAGAAQAAcAAAD7//n/9//3//f/9//0/+//6f/l/+P/5P/m/+n/7f/t/+z/7P/t/+3/7v/u/+3/7v/w//L/9f/2//T/7v/m/97/1//R/87/y//I/8b/xv/J/83/0P/S/9P/1P/U/9f/2//h/+X/5f/h/9n/z//F/7z/t/+0/7P/tP+3/7r/vf/C/8f/zP/S/9j/3f/e/97/2//Z/9j/2f/d/+P/6P/r/+z/6f/l/9//2v/Z/9v/4f/q//b/AAAKABIAFgAZABoAGQAYABgAGAAaAB4AIwAoACsALQAtACwAKgApACgAJgAjACEAIAAgACIAJAAmACcAJQAiAB0AGgAbAB4AJgAxAEAAUQBiAHAAeQB5AHQAawBjAF4AXgBhAGUAZwBkAFwAUABDADgAMQAxADcAQQBMAFQAVwBRAEUANwAnABwAFgAUABUAFwAYABUAEQANAAwADgAVAB8AKwA2ADoANwAuACIAFQANAAkACAAJAAYAAAD1/+j/3P/T/9H/1f/g/+3//P8GAAsACAD9/+v/1//F/7n/sf+t/63/rv+x/7X/u//E/87/1//f/+T/5f/j/9z/0v/G/7r/sP+s/67/sv+2/7j/tv+y/67/rf+y/7z/y//c/+3/+f8AAAEA+//u/97/z//F/8H/w//H/8j/xv/A/7v/uv+//8v/2//q//f/AAACAAIA/v/2/+v/4f/a/9j/2//f/+H/3//d/9z/5P/0/woAJAA0ADkALwAdAAgA+P/w//H/9/8AAAkAEgAZAB8AJgAuADgARQBUAGQAcAB0AGwAWAA7ABoA+v/c/8b/uf+2/73/0P/r/wkAKQBDAFcAZgByAHwAhACHAIUAfQBtAFwASgA5ACoAGwALAP3/8v/t//H//v8OACIANABEAFMAXgBoAG0AbgBnAFkARgAyAB8AEAAGAAIAAwAJAA8AFAAVABIADAAIAAQABQAJAAsACwAGAP3/7//g/9T/yv/F/8L/w//G/8z/1P/d/+X/6f/r/+j/5f/h/9//3v/e/9v/1f/L/8D/t/+x/6z/qf+l/5//l/+R/4//lP+f/7L/x//c/+7/+f/7//L/4f/L/7f/p/+i/6X/rf+0/7n/uP+0/7D/r/+0/7z/xv/Q/9f/2//c/9r/0//K/7//t/+y/7L/tv+7/8D/xP/I/83/1f/i//P/AgARABgAGQAUAAoA/v/v/+H/1//R/9H/1f/b/+D/5f/m/+f/6//1/wMAFwAsADwAQwBCADsALwAiABkAFAAWAB0AKgA5AEkAVQBdAF4AWwBXAFUAVgBaAF0AXQBYAE8AQwA3ACsAIgAcABkAHAAjAC8APQBJAFYAYABpAHUAggCOAJcAmACOAHwAZABMADkALwAtADQAQgBSAGIAbgB2AHcAdABuAGgAZQBkAGUAZQBfAFIAPgAkAAsA9f/n/+P/6//3/wYAFAAeACYALAAzADoAQwBJAEwASgBCADMAIQANAPz/7v/o/+r/9P8AAAoAEgAUABIADQAJAAIA/P/x/+L/z/+7/6X/kP99/3D/av9w/4L/nP+4/87/2//b/9b/0P/P/9X/4P/p/+z/5f/X/8T/sv+l/5r/l/+X/5r/of+o/67/sP+x/7H/sf+2/77/xv/N/83/yv/B/7n/sv+t/6r/p/+l/6T/pP+o/67/s/+3/7n/u/+9/8L/xv/J/8r/x//D/73/uf+3/7b/tv+0/7L/sv+1/7r/xf/P/9v/6v/9/xEAKAA8AEkATgBIADsAKgAbAA4ACAAHAAoADgATABcAGgAdAB4AHwAhACQAKAAtADQAOQA8AD0AOAAvACQAGAAPAAkABwAFAAEA+//y/+z/6//y/wAAEwAmADcARABLAFEAVwBdAGQAawBwAHMAdABzAHEAcABvAG4AbgBtAGsAZwBjAF0AVgBPAEcAPQAzACoAIgAfAB8AIQAjACMAIAAbABkAGgAgACsANwBCAEkASwBLAEgAQwA8ADQAKwAeAA8AAADw/+D/0//K/8X/xP/F/8n/z//V/93/5f/v//n/AwANABYAHgAhACAAGQAMAPr/5//T/8L/tv+w/6z/qv+n/6P/nf+Z/5n/nP+k/67/uP+//8L/wP+8/7X/r/+o/6H/mv+R/4n/gv98/3b/c/9y/3P/d/+A/4r/l/+i/6v/r/+x/67/qf+m/6T/pf+m/6n/rf+v/7D/sf+y/7X/vf/H/9P/3v/n/+n/5//j/93/1//S/8//zP/J/8r/zP/R/9f/3//m/+7/+P8CAA8AHQAqADQAOgA9AD0APQA9AD4APgA9ADoANQAvACsAKgAuADcARABRAF4AZgBmAGEAWQBRAEoASABHAEgASQBIAEcARgBHAEwAUQBaAGQAcAB9AIoAlACdAKIAoQCbAJEAgwB0AGYAXABUAFEAUABQAE8ATQBKAEUAPwA6ADQALgAmAB4AFwASAA4ADgAPABMAFwAbAB4AHgAeABsAGgAZABwAIQAnACwALAAoAB0ADgD//+//4v/Y/9L/zv/N/87/zf/M/8z/y//N/9D/0//Y/9r/2f/Y/9X/z//J/8H/uP+t/6T/oP+h/6j/s//A/8z/1P/a/9v/2P/Q/8T/tf+m/5j/jf+I/4f/if+M/5D/k/+W/5j/nP+i/6n/tP/C/8//2//k/+f/5v/g/9j/zv/C/7f/q/+h/5r/mf+d/6X/sP+8/8f/0//d/+f/7//2//r//f/+////AAAAAAAA///7//b/8f/s/+r/7f/z////DQAdACsANQA6ADoANwA0ADMAMwA1ADYANwA3ADUAMgAtACoAKAAqADAAPQBKAFkAZABqAGwAawBnAGMAXQBVAEsAQgA4AC8AKAAkACMAJgArADMAPgBIAFAAVABTAFIAUgBUAFoAYABnAGsAagBmAF8AVgBMAEMAOwA2ADIAMgA0ADcAOgA9AD4APgA8ADcAMQApACEAGwAUAA4ACAACAP7/+//8//7/AgAFAAkACwANABEAFgAbACAAIQAfABgADQAAAO//3//T/8z/yv/P/9f/4P/m/+f/5f/h/93/2f/Z/9n/2//g/+X/6v/s/+n/4P/T/8T/uP+z/7T/uv/C/8r/0v/X/9r/3P/a/9b/zv/I/8H/vf+7/7f/sf+p/57/lf+P/47/kP+W/53/pP+u/7f/wf/K/9D/0//Q/8j/vf+w/6P/mP+P/4r/iv+O/5b/n/+q/7T/v//J/9P/3f/n/+//9f/4//f/8f/n/9r/yv+8/7H/rP+t/7X/wf/P/9z/5//w//b/+v/9////AAD+//j/7//k/9r/1P/T/9b/3f/k/+z/8v/4//7/AgAIAA8AFgAeACYALgAzADQAMAAoAB8AFgAOAAkABwAGAAYACQAPABUAHQAkAC0ANgA/AEoAVABaAF4AXwBdAF4AYABkAGkAbABpAGIAWABNAEMAOwA3ADgAPQBGAFIAXABiAGQAYgBdAFoAXABhAGgAbwBzAHMAcQBqAGMAWwBRAEoARgBEAEUARwBIAEYARABAAD8APQA8ADoANQAvACgAIgAdABgAFAAQAA8AEQAXACIALQA0ADgANwA0AC4AKgAmACEAGwASAAYA+//u/+H/2P/R/87/z//T/9f/2v/b/9z/3f/i/+v/9f///wQABQACAPr/7f/d/8v/t/+j/5D/gP92/3H/b/9y/3b/e/+E/47/mf+k/6z/sf+w/6v/o/+a/5L/j/+Q/5H/lP+W/5b/lf+U/5T/mP+f/6f/s//A/8z/1v/b/9n/0P/C/7L/pf+b/5X/kf+O/4z/iv+L/47/lv+h/6z/uP/E/8//2P/h/+f/6P/m/+D/2P/R/8v/x//E/8T/x//P/9n/5P/y//7/BwAQABcAHQAiACYAJgAmACQAIQAdABkAFAAOAAgABQAGAAkAEQAbACYAMwA9AEcATQBPAE4ASQBCADsANgA1ADUANQA0ADUANQA2ADgAOgA+AEMASwBTAFwAZQBrAG4AbQBqAGQAXQBVAEoAPQAuACAAEgALAAkADgAZACkAOwBOAF4AaABtAG0AaABiAFwAWABTAE4ASAA9ADMAJwAeABYAEwARABMAGAAeACUALAAzADcAOQA7ADwAOwA4ADMALQAmACIAIgAnADAAPABIAFAAVABSAEwAQwA5AC8AJQAcABcAFAAVABkAHQAfAB8AHQAWABAADAAIAAcABgAHAAYABQACAP//+//4//X/8//y//L/8//0//f/+/8AAAQACAAMAA4ADwAQABMAFgAaAB0AHwAfAB0AGgAXABMAEAANAAoACAAHAAgACwAQABUAFwAVAA8ABgD+//f/8//y//X/+f/8//7//f/6//T/7f/l/93/2P/V/9X/2f/d/+L/6P/s/+//8P/v/+3/6//o/+j/6P/q/+z/7//x//H/8f/v/+z/6f/n/+f/6f/t//P/+P/9/////v/4//H/6P/f/9b/z//K/8f/yP/L/9P/2v/i/+n/7f/u/+3/7P/q/+n/6//s/+//8f/y//H/7v/q/+T/3P/V/83/yP/I/8z/0//e/+n/8v/3//n/+P/0/+//6f/h/9n/0f/K/8f/x//K/87/0v/V/9X/1P/S/9D/0P/T/9f/2//e/+D/4P/e/93/2//b/97/4v/p/+//9f/4//n/+P/3//X/9P/z//T/9P/1//X/9f/z//D/6//l/93/1v/Q/83/zv/U/97/6f/z//v//v/8//b/7P/j/9v/2P/a/9//6f/z//3/AwAGAAUAAAD4/+//6P/l/+j/7v/4/wIADAATABgAGgAYABUAEAAKAAQA///6//X/8v/w//D/8//5/wEACgATABoAHwAkACcALAAyADgAPQA+ADoAMwApAB0AEAAFAP3/9//y//D/8P/x//T/+f8AAAgAEAAZACAAJQAnACgAJwAkACEAHgAbABkAGAAZABsAHgAiACYAKAArACwALAAqACcAIQAaABIACwAGAAMAAwAGAAkADAAOAA4ADAAKAAkACgAOABUAHgAmAC0AMAAuACgAHgASAAYA/P/1//L/8//4//7/AwAKABAAFAAWABcAFgATAA8ACgAEAP//+P/w/+n/4v/f/9//4P/i/+H/3f/a/9n/3f/o//j/CAAWAB0AGwAQAAEA7//f/9L/zP/N/9X/4P/t//f//P/9//v/+f/5//r/+//7//f/8v/u/+j/4//f/9n/1P/Q/8z/zP/N/9D/0v/U/9X/1//Z/9z/3//h/+L/4//m/+v/8f/3//z/AAAAAAAAAAD///////8AAAIABQAIAAkABwAAAPf/6//h/9n/1v/Y/97/6f/3/wEACAALAAkABAAAAP7///8BAAMAAwABAP///v/+///////+//r/9f/v/+j/4P/Y/9L/0f/Z/+n//v8QABsAGwASAAUA/P/7/wEADAAXACAAJQAlACMAHwAXAAwAAgD5//f/+v8BAAgACgAJAAMA///8//7/AgAGAAgACAAJAAwAEgAXABsAGwAXABMAEQAUABoAHwAkACMAHwAbABgAFgAVABEADAAGAAIAAwAHAA0AFAAWABUAEQANAAsACgAJAAgABQABAAEABQAMABMAFwAWABEACgAEAAMABQAIAAkACQAFAAMAAgAEAAUABAAAAPj/7//o/+X/5v/t//j/BgAYACwAPQBJAEsARAA3ACcAGgAWABcAHQAhACQAIAAYAAwA///z/+j/4v/h/+n/9v8HABoAKQAyADQAMQArACUAIAAeAB4AHgAfAB8AHQAbABYAEQALAAQA///6//j/+f/9/wAAAgABAAAA/f/6//r//P/+/wAAAAAAAAEABAAHAAkACwALAAoACQAJAAsADQAOAA0ADAAKAAoACwALAAkAAwD6//H/6f/l/+X/6f/v//P/9//5//v//P/9//7//v/+/////////wAAAAD///3/+//4//T/7v/o/+H/3f/c/+H/6v/2/wAACgARABQAEwAPAAcAAAD4//P/8v/2//z/AQAEAAMA///6//b/8//x//D/7//t/+v/6v/s/+//8//2//j/+f/6//r/+v/7//r/+v/6//r//P/8//7//v/+//3//P/5//X/8P/s/+r/6//v//X//P8AAAEAAQD///3/+//5//b/9P/x/+3/6v/m/+L/3v/a/9n/2//j/+//+/8FAAsADAAKAAgABgAFAAUAAwABAAAA/v///////v/8//j/8v/r/+X/5f/n/+7/9/8AAAoADwAOAAYA+f/s/+H/3//n//T/AwAQABcAGAAVABQAFAAXABsAIAAiACEAGwASAAQA9v/o/+D/4P/n//H/+P/5//P/6//k/+P/6v/0////BgAJAAgABQAAAPr/8v/q/+L/3P/b/9r/3P/f/+T/7f/6/wkAFwAdABgACgD5/+n/4v/m//D/+v//////+f/z/+//7//w//X//P8EAA8AGgAhAB4AFAAEAPP/5//k/+r/9P/8/wAA/v/5//H/6//m/+T/6P/w//3/DQAcACYAJgAeABEAAgD8//v/AAAIAA8AEQAOAAoABgAFAAgADwAWAB8AJgApACcAIgAYAA0AAwD9//v/+v/5//T/7P/k/97/3v/m//b/CAAdAC4APQBJAFUAXwBmAGgAZQBcAE4APwAwACMAGAAQAAsABwAGAAYABwAGAAQAAgAAAAIACAASAB8AKgAvADAALAAnACIAIQAiACUAKgAvADQANgA4ADcANQAwACkAIgAaABIADAAIAAQAAgAAAPv/9v/w/+r/6P/q//H//f8JABcAIQAmACcAJQAhAB0AGgAXABYAEwANAAUA+//t/9//0//L/8f/x//K/83/0P/U/9j/3//p//T//v8EAAgABwAEAP3/9f/u/+n/6f/t//f/AAAEAAQA/f/w/+L/1//Q/83/y//I/8L/u/+2/7X/t/+9/8T/y//U/93/5f/t//L/8//0//X/+v8CAAsAEgAQAAcA+f/t/+b/6P/y//3/BAAEAP3/8v/m/9v/1P/P/8//0//Y/+D/6P/t/+7/7P/p/+j/7v/7/wsAHQArADUAOgA6ADYALwAjABcACgABAP//AgAJAA4AEQAOAAcAAAD6//j/9//5//r/+v/8/wAABgANABMAFgAWABYAGAAbACIAJwAqACoAKgApACoALAAsACkAIQAVAAgA/f/0/+v/4//c/9b/1P/Y/+H/7//8/wcADgARABIAEgAUABgAHgAjACcAJwAjABoADQAAAPT/7f/t//H/9v/6//r/9//x/+z/6f/n/+j/6v/t/+//7v/u/+v/5//i/9//4P/j/+n/8P/5////BwAOABYAGgAbABcADgAAAPP/5//e/9v/2//d/+D/4//k/+L/3f/Z/9b/1//f/+v/+f8FABAAGAAcAB4AHgAcABgAEAAHAP7/9//1//b/+P/6//n/9P/t/+f/4v/e/9n/1v/T/9H/0f/T/9j/3f/j/+j/7f/y//b/+v/9//7//v/+/wAABQAPABsAJwAuAC4AJwAYAAYA9v/p/+H/4P/j/+n/7//z//f/+f/6//z/AAAJABMAHgAoAC8AMgAwACwAKAAiAB4AGwAZABkAHAAgACUAKwAuAC8ALgAqACcAJwApAC8ANgA8AD8APwA8ADgANQAxAC4AKwApACgAKgAvADkAQgBLAFEAVABVAFIATQBFADsALwAgABQACwADAP//+//2//H/7P/p/+n/7v/2/wAACgATABsAIQAlACYAJgAlACMAIAAcABYADAACAPn/8f/t/+7/8P/z//T/8f/q/+L/2v/T/87/yv/I/8j/y//Q/9b/2v/e/+D/4f/l/+n/8P/4//3//v/8//X/7f/l/97/1//S/8v/xf/B/73/u/+7/7v/u/++/8H/x//P/9j/4f/o/+3/7//w/+7/7P/p/+b/4//f/93/2f/Y/9n/3v/m/+//+P/+/wAA/v/5//P/8P/v//H/9P/2//f/9//z/+3/5f/c/9X/0f/S/9r/5v/1/wEACwAQABEADwANAAwACgAHAAMAAAD8//j/9f/0//X/9v/3//n/+//8//3//f/9////AAAAAAEAAAAAAP7//v8AAAMABwALAAwACwAJAAUAAwACAAMABgAMABMAGgAfACEAIAAbABQADAAFAAEAAAAAAAMABgAIAAkACgAJAAcABQAEAAUABwALABAAFgAbAB8AIQAhACEAHwAbABgAEwANAAgAAwAAAP///v8AAAEABAAHAAgACAAHAAUABAAEAAYACQAMAA8AEQATABQAFgAXABcAFgATAA8ADAALAAoACgAJAAkACAAHAAcACQALAAwACgAIAAUAAQAAAAAA/v/8//n/9v/0//T/9//7/wAABQAHAAUAAQD9//r/+f/7/wAACAARABgAHAAeABwAGgAWABIAEAAPABEAFAAaAB8AJQAnACcAJAAfABkAFAARABAADwAQAA8ADgALAAcAAgD///n/9P/x//D/7//z//f//f8EAAwAEgAXABkAGQAVAA8ABwAAAPn/8f/q/+X/4f/f/9//4P/f/93/2v/W/9H/0f/T/9j/3v/k/+f/6P/m/+P/4P/f/9//4P/g/+D/3//f/97/3f/c/9r/2P/W/9T/0v/O/8j/wv+9/7z/vv/D/8v/0P/T/9H/zv/N/83/0//a/+L/6f/t/+7/7f/r/+f/4v/f/9v/2v/a/9v/3P/c/9z/2//b/97/4v/r//f/BQAUACIAKwAwAC8AKwAlAB8AGwAXABUAEwASABEAEQAUABkAHwAkACsAMAA0ADcAOQA4ADcANAAwACwAJwAhABoAEwAOAAoACgANABMAGwAjACsANAA9AEUASwBNAEwASABCADwANQAtACUAHQAWABAADQALAAoACAAFAAQABgAMABQAHAAjACYAJgAjAB8AGgAUAA4ABgD+//b/8v/w//P/+P///wUADAASABcAGgAaABYAEQAMAAcAAwAAAPz/9v/u/+b/3//a/9f/1v/X/9j/2v/e/+L/5//q/+7/8f/z//T/9P/z/+//6//l/+D/3f/c/93/3//j/+b/6v/v//P/9f/2//b/9v/2//b/9v/2//X/8f/t/+n/5v/l/+b/6P/s//H/9v/8/wAAAQABAAAA/v/8//n/9f/w/+n/4//d/9n/2v/d/+L/6P/v//b///8IABEAGwAiACkALQAwADEAMgAvACwAKAAiABwAGAAUABAADAAIAAYABAAEAAgADAAPABIAFAAVABYAFwAXABYAEwAPAAoABQADAAEAAwAGAAkADAAPABEAEgAUABQAFgAWABcAFwAXABgAGAAWABEACwADAP3/9f/v/+3/7P/t/+7/7//y//P/9f/4//v///8BAAIAAwABAAAA/P/5//f/9f/2//b/9f/y/+7/6f/l/+L/4P/h/+P/5f/m/+b/4//g/93/2P/V/9L/0P/P/87/z//S/9X/2v/f/+b/7f/y//f/+v/7//r/+P/0/+//6v/m/+P/4P/e/97/4P/i/+b/6f/t//D/8//3//v///8DAAcACQALAAsACQAGAAIA///7//f/9P/z//L/8v/z//T/+P/8/wAABQAKAA0ADwASABUAFgAYABkAGAAXABgAGQAaAB0AHgAeABwAGwAZABsAHQAgACIAIAAeABkAFQAQAAwABgABAP7/+//8/wAABgAOABUAGgAdAB8AIgAjACUAJgAmACQAIgAfAB0AHAAbABgAFQARAAwABwADAAAA/P/7//r/+////wQACwASABgAHAAfACEAIgAiAB8AGgATAAsAAwD9//X/7//q/+b/5P/i/+P/5P/l/+b/5//m/+f/6P/q/+3/7f/t/+r/6P/l/+L/4P/e/93/3v/i/+f/7v/1//n/+v/4//X/8f/u/+z/6P/k/+D/3f/a/9n/2f/Y/9j/1//Y/9v/3//l/+v/8f/3//v///8DAAgADAAPABEADwAOAAsABwADAAAAAAAAAAIABgAKAA8AFAAXABoAHAAdAB4AHgAcABgAFAAQAAwACgAKAAsADwARABIAEwARABAADwAQABEAEgATABQAFAAUABUAFAAQAAsABAD///n/+P/7/wIACgAVACAAKwAzADkAOwA5ADMALAAlACAAHAAYABQADwAHAAAA+f/y/+3/6f/o/+n/7P/0//7/BgAOABQAFgAWABIADwAJAAQAAAD9//z//P///wIABQAGAAcABQAEAAIAAgACAAMABAAFAAQAAwAAAPz/9v/w/+r/5f/i/+H/4v/j/+X/5//q/+3/8P/0//X/9f/0//L/8P/v/+7/7v/u/+z/6v/m/+T/4//k/+n/7//1//v/AAADAAQABgAFAAQAAAD9//f/8v/s/+f/5f/j/+L/4f/g/+D/4P/j/+f/7f/0//z/AQAIAAwADwAPAAwABwAAAPr/9P/w/+//7v/v/+//8P/x//P/9//7////AQAEAAgACwAOAA8AEAAQAA4ACgAGAAEA/P/1/+//6v/n/+b/5v/o/+n/6//t//D/8//3//r//P/8//v/+P/1//L/7//s/+n/6P/q/+7/8//5//7/AgAHAAwAEAATABMAEAALAAYAAwACAAIAAQD+//f/7f/k/93/3P/f/+b/7f/0//n/+//9//3//f/8//v/+v/6//r/+v/6//n/9//1//T/9f/5//7/AgAGAAYABQAEAAQABgAJAAwADgAOAA0ADAAMAAwACgAGAAAA+f/0//H/8f/0//f/+P/4//n/+//+/wEABgAKAA4AEQAVABcAGAAWABIADwAOABEAGwAlACwALwArACUAHgAcAB4AJAAqAC8AMwA0ADQAMgAuACgAIAAZABYAFgAZAB0AHwAgAB8AHwAgACIAIwAgABsAFAANAAoACwAMAA4ADAAHAAIAAAAAAAYADgAVABkAGwAcAB4AIQAlACoALAAtACwAKgAnACIAHAAVAA0ABAD///r/9//1//H/7v/t/+z/7P/u//D/8v/y//L/8f/w/+//7v/t/+r/5//l/+T/5f/n/+r/7v/z//f/+//+/wAAAAD///v/+P/z/+7/6f/l/+H/3f/c/9z/3v/j/+n/7v/y//T/8//w/+v/6P/l/+T/4//j/+L/4P/c/9b/0f/N/8v/yv/M/9D/1v/e/+b/7//4/wAABQAJAAwADAAKAAYAAAD5//D/5//g/9n/1P/Q/8z/yv/K/8z/0f/Y/+D/6P/w//b/+/8AAAIABAADAAEAAAD+//3///8AAAQACAAKAA4AEQAUABgAGgAcABwAHAAdAB0AHQAbABkAFAAPAAwACgALAA4AEwAWABoAHQAcABwAGgAWABEADAAIAAQAAgAAAP/////+//7/AAADAAgADQARABQAFgAXABgAGgAcAB0AHQAcABsAGQAXABUAFAAUABMAEwASABIAEgASABEAEQAQAA4ACwAHAAMA///6//f/9P/z//P/9P/1//T/8v/w/+7/7f/v//H/9f/4//r/+v/4//b/9f/z//P/8v/x/+//7v/s/+r/6f/p/+r/7f/w//X/+P/7//z//v/9//3//v/+//////8AAAAAAAAAAAAA///8//n/9f/w/+3/6//q/+v/7//0//v/AAAIAA4AEwAWABgAGAAYABcAFgATABEADgAMAAoACAAGAAUAAgAAAAAAAAAAAAEAAQACAAMAAgABAAAA/v/7//j/9v/3//v/AAAFAAkADQAOAA8AEAAPAA4ADQAMAAoACQAIAAgACAAHAAUAAwABAAEAAAABAAIABAAGAAcACQAMAAwADQAMAAwACgAJAAkACAAHAAQAAgAAAAAA//8AAAAAAgAEAAUABwAKAAsADQALAAkABAAAAP///v8AAAAAAQAAAP///v/9//3//f/9//z//P/8//7/AQAGAAoADQANAA0ADAALAAoACgALAAwADgASABUAGQAcABwAGgAXABMAEAANAAsACAAGAAQAAwADAAMAAgD///v/9f/x/+3/6//r/+z/7v/w//P/9//6//z//v/+//7//v///wAAAgAEAAUABAADAAIAAQAAAP7//P/4//X/8v/v/+3/7P/s/+z/7P/u//D/8v/0//X/9f/0//P/8f/u/+v/6v/o/+f/5v/n/+j/6v/q/+r/6P/l/+H/3f/b/9v/3P/g/+T/6P/r/+//8f/z//X/9f/3//f/9//3//f/9v/0//L/8P/s/+n/5v/j/+H/3//e/97/3v/f/+D/4v/j/+X/6P/q/+3/8P/z//f/+//+/wAAAgADAAMAAwADAAQABQAHAAgACAAJAAoADAAQABMAFgAZABoAGwAbABsAHAAcABsAGQAUABAACwAGAAIAAAD///7/AAADAAcADAAQABMAFAAVABYAGAAaAB4AHwAgACIAIwAkACYAJwAmACQAIAAeAB0AHQAfACIAJgAqAC4AMgA0ADQAMQAsACUAIAAcABwAIAAjACYAJwAmACYAJAAjACIAIAAdABkAFgAVABUAFQAUABMADgAIAAMAAAD+//7///8BAAQACQAOABMAFwAYABgAFAASAA4ADAAKAAcAAwD+//f/8f/t/+r/6P/n/+f/5v/n/+f/6f/r/+3/7//w//H/8P/v/+z/6P/k/+D/3P/b/9n/2P/X/9b/1v/Y/9v/3//j/+T/5P/j/9//3P/Z/9b/0v/P/83/y//M/83/zv/R/9X/2P/d/+H/5P/k/+P/4v/g/+H/5P/o/+z/7v/u/+v/5//j/9//3v/e/9//4//p/+7/8//2//f/9//3//f/+f/8//7/AAACAAMABgAJAAwADQANAAwACQAIAAgACAAKAAwADQAOAA8ADwAPAA0ACQAFAAAA/v/8//z//v///wAAAwAFAAoADwAVABkAHgAhACMAJQAnACcAJQAhABsAEwALAAYAAwADAAUACgAOABMAFgAZABoAGwAZABgAFwAYABkAGwAcABwAGgAYABUAEgAQAA8ADgAPAA8AEQATABYAGAAZABgAFwAVABMAEwAUABUAFQAUABIAEAANAAoABwADAAAA/f/7//v/+//7//r/+P/1//D/7v/s/+3/7v/w//L/9f/4//3/AAAEAAYABQADAAAA/v/9//7/AAADAAYABwAHAAUAAgD///z/+f/3//b/9//7/wAABQAKAAwADAAJAAUAAAD7//b/8//x/+//8P/x//L/8v/y/+7/6v/l/+H/4P/h/+X/6v/w//X/+v/9/wAAAwAFAAYABgAEAAMAAgADAAIAAQAAAP7//P/5//j/+f/7//3///8CAAUACAAJAAsACgAIAAUAAgAAAP///v/9//z/+v/4//T/7v/p/+X/5P/l/+n/7//1//r//v8AAAEAAQAAAP///P/3//T/8v/y//P/9P/0//P/8f/w//D/8f/z//X/+P/7////AQAFAAcACAAJAAkACgAMAA4AEAARABAAEAAPAA4ADgANAAsACQAHAAcABwAJAAoACgAKAAgABgAFAAUACAALAA4AEgAXABsAHgAfAB4AGwAXABEADQAKAAcABgAGAAYABQAGAAYABQADAAAA+//0/+//6//p/+n/7f/y//b/+P/4//f/9P/v/+z/6P/n/+f/6v/u//P/+f/9/wAAAAAAAAAAAAABAAIAAwAEAAQABAADAAEA///6//X/7//r/+f/5f/l/+b/6P/s/+//8v/0//f/+P/5//r//f///wAAAAAAAP///P/5//b/9f/x/+//7f/s/+3/8P/z//f/+v/9//7/AAABAAMABQAHAAkACwAOAA8AEAAPAA0ACgAIAAgACgANABAAEwAUABMAEQAOAAoABAAAAPv/9v/0//T/9f/3//n//f///wEABQAHAAoADAANAA4ADgANAAwACgAIAAYABQADAAMAAwAFAAcACgAOABIAFQAWABUAEwARABAAEAASABMAFgAWABcAGAAZABoAGgAZABUAEQAMAAkABwAIAAoADAAOABEAEgATABMAEgAPAAwACQAGAAYACAALAA0ADgAOAAsACAAGAAMAAAD///3//P/8//z//f/+////AAAAAAAAAAAAAP///f/6//f/9P/x/+//7f/s/+v/7P/v//P/+f/+/wAAAQABAAAAAAAAAAAA//////7//f/9//3//f/9//z//P/5//f/8//x//D/7//w//D/8f/x//D/7f/p/+X/4v/f/93/3P/c/93/3//g/+L/4//j/+P/4//j/+T/5f/m/+f/6f/q/+z/7//x//P/9f/4//v/AAAGAAwAEAATABEADwALAAcABAACAAAAAAAAAAAAAgAEAAYABgAEAAIAAAAAAAAAAgADAAMABAAFAAcACAAIAAcABAABAAAAAAABAAUACAALAAsADAALAAwACwAMAAsACgAKAAsADgAQABEAEgAQAA0ACQAFAAEA///9//3//f/9////AAABAAEAAQABAAEAAwAGAAkADQAPAA8ADgANAAsACQAHAAUAAgAAAAAA///+//3/+//6//v//P///wIABgAJAAsACwAKAAgABgAEAAIAAQAAAP////8AAAAAAQABAAAA/v/7//f/8//w/+7/6//q/+v/7v/z//r/AQAHAAoADAALAAgAAwAAAPz/+v/6//z///8CAAYACgAMAA0ADQALAAcAAwAAAP7//v/9///////+//3//P/7//v//f/+////AAABAAQABwALAA4AEAASABIAEgATABMAEgAQAA0ACQAEAAEAAAD///3/+//4//f/9v/3//j/+v/8//3//v/+////AAAAAAAAAQAAAAAA///9//3//f/9//3//f/9//3//f/+//7//v/+//7//P/7//r/+v/6//n/+P/3//b/9f/0//T/9f/2//f/9//4//j/+f/4//b/8//w/+7/7f/w//P/+P/8/wAAAwAGAAgACAAHAAQAAAD8//j/9P/x/+//7f/s/+z/6//s/+z/7f/u/+//8v/1//n//v8CAAgADAAQABIAEwASABEAEAAQAA8AEAASABMAFAAVABUAFAASAA8ADAAKAAgABwAHAAgACAAIAAgABgACAP///P/4//f/9//5//z//v8AAAAAAAABAAIAAgADAAQABAAGAAgACwANAA8AEQASABEAEQARABAADwANAAwACwALAAsADAALAAoABwAGAAUABQAHAAkACgALAAsACgAKAAgABgAEAAEAAAAAAAAAAQACAAMAAwADAAMAAgAAAAAA/v/7//j/9//2//b/9//3//f/+f/7//3//v///////f/8//r/+f/4//f/9//4//n/+//+/wAAAwAGAAgACAAHAAMAAAD8//j/9v/1//b/9f/2//X/9f/1//X/9P/y//D/7P/q/+j/6v/t//H/9f/6//3/AAACAAQABQAEAAEA///8//n/9//2//b/9v/2//b/9f/0//P/8v/x//L/8v/0//b/+f/7//7/AAADAAUACAALAA0ADwAQABAADwAOAAwACgAIAAcABgAFAAYACAALAA8AFAAXABkAGgAZABcAFwAWABYAFgAWABUAFAATABIAEgARABEAEQARABIAFAAWABgAGgAbABwAGwAaABcAEwANAAYAAAD7//b/8//y//L/8//0//X/9f/1//T/8//z//T/9f/3//n/+//9/wAAAAABAAAA///8//r/+P/2//P/8P/s/+j/5P/i/+H/4P/g/9//3v/d/9z/3P/c/9z/3P/e/97/4P/i/+X/5v/o/+j/6P/o/+f/5v/k/+P/4v/j/+X/6P/r/+7/8//4//v///8AAAIAAQACAAMABQAHAAkACgAJAAcABQADAAEA///+//v/+//7//3//v8AAAAAAAAAAAAAAAAAAAEAAQAAAP7//P/7//n/9//0//H/7v/t//D/9f/6////AgAFAAkADQARABQAEwAOAAcAAQD+//3//v8AAAAAAAAAAAAAAQACAAQABAAEAAYACgARABgAHgAfABwAFwAOAAYAAAD7//f/9P/0//b/+v/+/wAAAQAAAP///f/9/wAAAwAGAAkACQAIAAYABAABAAAA/v/7//j/9v/0//P/8//0//T/9P/1//f/+////wEABAAFAAUABQAFAAYABQAFAAIA///6//b/9P/z//D/7f/p/+f/5//q/+7/8f/x//D/7P/q/+v/7//0//f/+P/3//b/9f/1//f/9v/1//T/8//1//j/+//8//n/8//t/+n/6P/p/+v/6//r/+r/6f/q/+r/6f/n/+T/4f/h/+T/5//q/+z/7P/q/+v/7P/v//H/8//y//D/7f/r/+r/6v/o/+b/5P/j/+P/5P/l/+X/5f/l/+b/5//r/+7/8v/2//n/+//9/wAAAwAGAAkACwALAAoACQAJAAoADQAPABAAEAAOAAoACQAHAAcABgADAAAA/v/9////AQAFAAkACgAKAAkACgALAAwADgAOAA4ADwARABUAFwAZABkAGQAYABkAGQAZABkAGAAYABgAGgAeACEAIwAjACEAIAAfAB8AIAAhACIAJAAmACgAKAAnACUAIQAdABoAGAAXABYAFgAWABYAFgAWABYAFgAUABIAEAAPAA4ADQALAAkACQAIAAkACwANAA8AEQASABMAEwATABIAEwAUABUAFgAWABMADwAJAAQAAQABAAEAAQABAAEAAQABAAAAAAD+//z/+//8////AwAGAAgABwAFAAIAAQAAAAEAAgAAAP///f/7//r/+v/6//v/+//+/wAABAAKAA4ADwAOAAsABwADAAEAAAABAAEAAQAAAP3/+f/1//D/7P/p/+f/5v/m/+f/6f/p/+r/6f/o/+j/6P/q/+z/7//x//L/9P/2//n//P/+//////////////8AAAAAAAAAAP///f/8//v/+f/2//P/8f/w//D/8f/x//H/7//s/+j/5f/i/9//3P/b/9v/3P/g/+T/5//p/+r/6v/s/+7/8f/2//r//f8AAAQABwAJAAoACAAEAAAA/P/5//b/9f/0//P/8//1//b/+P/3//b/9f/x/+//7f/t/+3/7//x//T/+f/9/wAAAQABAAAA///+//7//f/9//7//v/+//7///////7//f/7//v/+v/6//v//P/8//z//f///wAAAgAEAAYABwAJAAoADAAMAAwADAAOABEAEwAVABcAFwAXABcAFwAXABYAFAARAA0ACwAKAAsADAAMAAkABwAEAAIAAQACAAEAAQAAAAAAAQAEAAcACQAJAAkACQAJAAsADQAQABIAEwAVABgAGwAeACAAIQAfAB0AGgAXABMADwALAAYAAgAAAP////////7//f/6//n/9//2//X/9f/z//P/8v/z//b/+f/7//z//f/8//z/+v/5//n/+f/6//v//f8AAAAAAgACAAIAAAD9//r/9//3//b/9//3//f/9v/1//P/8v/x//H/8f/y//T/9//6//3//////////f/9//z//P/8//v//P/8//3///8AAAAAAAAAAP////8AAAIAAwAEAAMAAgABAAIAAwAEAAUABQAFAAUABAADAAIAAAD+//z/+//7//3///8AAAAAAAAAAAEAAgAEAAcACQANAA8AEgAVABcAGQAZABkAGQAaABsAGwAbABoAGQAZABkAGAAXABcAFgAWABYAFQAVABQAEwASABIAEgATABMAEgAPAAsACAAGAAQAAwACAAIAAQACAAMABAAEAAQAAgAAAAAA//8AAAAAAQABAAAA/v/8//r/+P/2//X/9P/z//P/8v/0//b/+f/9/wAAAQABAAIAAgABAAEAAQAAAP3/+f/0/+//7P/p/+b/5P/h/9//3f/b/9r/2v/a/9n/2//d/+H/5v/s//D/8//1//b/+P/6//z//v////7//P/6//f/9P/x/+3/6f/l/+L/3//d/9z/2//b/9v/3f/e/+D/4v/k/+b/6P/q/+v/6//p/+f/5f/l/+b/6v/t//H/9P/4//z///8CAAUACAAIAAgACgALAA4AEQATABIADwAKAAQAAAD7//f/9P/0//T/9//6////AgAGAAgACQAKAAwADwARABQAFwAZABoAGgAYABYAEgANAAgABAAAAAAA//////7//////////v/8//v/+v/5//n/+v/9/wAAAgAEAAYACAAKAAwADgAQABEAEQARABEAEAAQABAADwANAAwACgAJAAoADQAQABIAEwAUABQAFQAXABkAGwAbABoAGgAZABkAGgAZABgAFgAVABUAFQAXABgAGAAWABUAFQAWABYAFQATAA8ADQANAA8AEgAUABQAEwAQAA0ACwAJAAYAAQD9//v//f8DAAkADwAQAA4ACgAGAAQABAAGAAkADQATABgAGwAaABMACAD8//X/9P/5/wAABAAEAAAA/P/5//r//v8AAP//+//2//L/8v/0//f/+P/5//r//f8CAAkADAAKAAMA+//1//T/9//9/wAAAAD9//n/9v/2//f/9v/z/+//6v/p/+z/8P/0//T/8f/s/+f/5P/i/+L/4f/f/9v/2f/Z/9r/3v/h/+L/4v/h/+H/4v/k/+f/6f/q/+r/6//t/+//8P/w/+7/6//o/+j/6P/o/+b/4v/c/9b/1P/V/9j/3f/g/+P/5P/m/+n/7f/x//T/9//6////BQAOABQAFwAVABAACwAIAAgACQALAAsACQAHAAUABAADAAEA/f/4//T/8f/y//X/9//3//f/9v/1//j//P8AAAIAAwADAAMABgAJAAwADQANAAsACQAJAAoADQAPABAAEgATABYAGQAcAB4AHgAcABkAFgASAA8ACwAIAAQAAgABAAEAAwAFAAYABwAIAAkACgAMAA0ADQAOABAAEQATABUAFwAXABcAFwAYABkAGQAYABYAEgAOAAsACAAIAAcABgAEAAMAAQABAAIABAAEAAMAAQAAAP7//f///wAAAgAEAAcACQAKAAwADwARABIAEwAVABcAGQAbABwAGgAWABAACQAEAAAAAAABAAQABwAKAA0ADgAPAA8ADgANAAsADAANAA8AEwAXABsAHQAgACAAHgAaABUADwAKAAYABAADAAMAAwADAAQABQAEAAEA/v/4//P/7v/s/+z/7P/s/+z/6//q/+v/7P/t/+3/7P/s/+3/8P/0//j/+v/5//j/9v/3//r//P/8//v/+f/3//b/+P/6//z//f///wAAAAADAAUABAABAP3/+P/0//L/8v/z//T/9P/0//P/8v/x/+7/6v/m/+P/4//k/+b/5//n/+X/5P/j/+T/5v/o/+r/6//t//D/9P/4//r/+v/4//X/8//z//T/9P/y/+7/6f/l/+P/4//l/+f/6f/q/+v/7f/u//D/8v/z//P/9P/1//n//v8DAAYACQAJAAcABQAEAAMAAgACAAEAAQABAAMABQAHAAcABgAEAAIAAAAAAAAAAQACAAMABQAIAAsADQAOAA0ACwAJAAgACgAOABMAGQAeACIAJQAmACYAJwAlACUAJQAlACcAKgArAC0AKwAoACMAHwAcABkAFgASAA0ACQAHAAcACQAMAA8AEQAQAA8ADgANAA4ADgAPAA8AEQATABUAFgAVABMADwANAAwADQAQABQAFQAVABEADgALAAkABwAFAAMAAQAAAP/////+//z/+f/2//L/7//v//H/8//1//b/9v/3//f/9//3//T/8P/r/+f/5v/n/+z/8v/3//n/+P/1//H/7v/s/+r/6f/o/+n/6v/r/+z/6//n/+L/3P/X/9X/2P/c/+D/4//l/+f/6f/t//H/9f/3//f/+P/6////BAAJAA0ADgANAAsADAANAAwACwAIAAIA/f/4//X/8P/r/+b/4P/c/9v/3f/h/+X/6P/r/+3/8P/z//X/9v/0//H/7//w//L/9f/5//z//v8AAAEAAwADAAIAAAD///3//v/+/wAAAAD///z/+//7//z//f/9//z/+//7//3/AAAEAAcABwAGAAMAAgADAAYACQAMAA4AEAARABIAEgAQAAwABwADAAEAAQACAAUACAALAA0ADQANAA0ACwAJAAgACAAIAAsADgASABUAGAAbAB0AHQAcABsAGgAZABoAGwAbABsAGgAWABIADwAMAAoACQAJAAsADgATABkAHwAjACQAIwAfABwAGQAYABkAHAAeAB4AHAAYABQAEAANAAsACgAIAAgACQALAA8AEgAUABQAEwASABAADwAPAA8ADgALAAcABQADAAIAAAD///z/+P/1//X/9P/1//b/+P/6//v//f/9//v/+P/0//L/8v/1//n//f/+/////////wAAAQADAAMAAwADAAQABgAIAAoACgAJAAgACAAJAAsA","format":"wav"}}],"status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 400 + message: Bad Request + headers: + Date: + - Tue, 05 Aug 2025 05:32:05 GMT + Content-Type: + - application/json + Content-Length: + - '308' + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '34' + X-Envoy-Upstream-Service-Time: + - '44' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |- + { + "error": { + "message": "Invalid value: 'input_audio'. Supported values are: 'input_text', 'input_image', 'output_text', 'refusal', 'input_file', 'computer_screenshot', and 'summary_text'.", + "type": "invalid_request_error", + "param": "input[0].content[1].type", + "code": "invalid_value" + } + } + recorded_at: Tue, 05 Aug 2025 05:32:05 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_error_handling_raises_an_error_when_tool_execution_fails.yml b/spec/fixtures/vcr_cassettes/chat_error_handling_raises_an_error_when_tool_execution_fails.yml index b92679c7c..56eb9d0fd 100644 --- a/spec/fixtures/vcr_cassettes/chat_error_handling_raises_an_error_when_tool_execution_fails.yml +++ b/spec/fixtures/vcr_cassettes/chat_error_handling_raises_an_error_when_tool_execution_fails.yml @@ -125,4 +125,150 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:31:59 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is the weather?","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"broken","description":"Gets + current weather","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:05:03 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999750' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '671' + X-Envoy-Upstream-Service-Time: + - '680' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190fef31481a085c326d923b7fed40840c0723c8e01d3", + "object": "response", + "created_at": 1754370302, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689190ff77dc81a0b75e1cfc8889f7550840c0723c8e01d3", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_84S0cyC9mkeimyOWajEhAzR9", + "name": "broken" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather", + "name": "broken", + "parameters": { + "type": "object", + "properties": {}, + "required": [] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 33, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 11, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 44 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:05:03 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_raises_appropriate_auth_error.yml b/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_raises_appropriate_auth_error.yml index 3f8e8c459..3eecadd6d 100644 --- a/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_raises_appropriate_auth_error.yml +++ b/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_raises_appropriate_auth_error.yml @@ -65,4 +65,73 @@ http_interactions: } } recorded_at: Fri, 01 Aug 2025 09:55:51 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer invalid-key + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 401 + message: Unauthorized + headers: + Date: + - Tue, 05 Aug 2025 05:04:32 GMT + Content-Type: + - application/json + Content-Length: + - '240' + Connection: + - keep-alive + Www-Authenticate: + - Bearer realm="OpenAI API" + Openai-Version: + - '2020-10-01' + X-Request-Id: + - "" + Openai-Processing-Ms: + - '51' + X-Envoy-Upstream-Service-Time: + - '61' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |- + { + "error": { + "message": "Incorrect API key provided: invalid-key. You can find your API key at https://platform.openai.com/account/api-keys.", + "type": "invalid_request_error", + "param": null, + "code": "invalid_api_key" + } + } + recorded_at: Tue, 05 Aug 2025 05:04:32 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_handle_multiple_tool_calls_in_a_single_response.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_handle_multiple_tool_calls_in_a_single_response.yml index 520c60ade..1d532876a 100644 --- a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_handle_multiple_tool_calls_in_a_single_response.yml +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_handle_multiple_tool_calls_in_a_single_response.yml @@ -261,4 +261,320 @@ http_interactions: "system_fingerprint": "fp_f12167b370" } recorded_at: Fri, 01 Aug 2025 10:31:47 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must call the dice_roll tool exactly 3 times when asked to roll dice 3 times.","status":"completed"},{"type":"message","role":"user","content":"Roll + the dice 3 times","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"dice_roll","description":"Rolls + a single six-sided die and returns the result","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:04:58 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999717' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1312' + X-Envoy-Upstream-Service-Time: + - '1319' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190f9797481a2bdcc554024f770ff0dc77fb2373c8627", + "object": "response", + "created_at": 1754370297, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689190f9fee081a2835c9a99334091450dc77fb2373c8627", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_1d2yhsAV5juMsQVITOE3aMKQ", + "name": "dice_roll" + }, + { + "id": "fc_689190fa256c81a28ccd2210c2e5701d0dc77fb2373c8627", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_0WvwAmT3iGEXXrF0L6MN2G8t", + "name": "dice_roll" + }, + { + "id": "fc_689190fa62f481a2a2de79606e25d3aa0dc77fb2373c8627", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_bF9EEMLbvuWa4wz8DBSY5mVT", + "name": "dice_roll" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Rolls a single six-sided die and returns the result", + "name": "dice_roll", + "parameters": { + "type": "object", + "properties": {}, + "required": [] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 66, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 54, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 120 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:04:58 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must call the dice_roll tool exactly 3 times when asked to roll dice 3 times.","status":"completed"},{"type":"message","role":"user","content":"Roll + the dice 3 times","status":"completed"},{"type":"function_call","call_id":"call_1d2yhsAV5juMsQVITOE3aMKQ","name":"dice_roll","arguments":"{}","status":"completed"},{"type":"function_call","call_id":"call_0WvwAmT3iGEXXrF0L6MN2G8t","name":"dice_roll","arguments":"{}","status":"completed"},{"type":"function_call","call_id":"call_bF9EEMLbvuWa4wz8DBSY5mVT","name":"dice_roll","arguments":"{}","status":"completed"},{"type":"function_call_output","call_id":"call_1d2yhsAV5juMsQVITOE3aMKQ","output":"{:roll=>1}","status":"completed"},{"type":"function_call_output","call_id":"call_0WvwAmT3iGEXXrF0L6MN2G8t","output":"{:roll=>2}","status":"completed"},{"type":"function_call_output","call_id":"call_bF9EEMLbvuWa4wz8DBSY5mVT","output":"{:roll=>3}","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"dice_roll","description":"Rolls + a single six-sided die and returns the result","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:05:00 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999647' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1160' + X-Envoy-Upstream-Service-Time: + - '1166' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190fb308881a2b6fc0c5cdb5685d60a9ff8f877f39857", + "object": "response", + "created_at": 1754370299, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689190fc168481a29c39583498ac84690a9ff8f877f39857", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The results of the three rolls are 1, 2, and 3." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Rolls a single six-sided die and returns the result", + "name": "dice_roll", + "parameters": { + "type": "object", + "properties": {}, + "required": [] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 135, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 19, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 154 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:05:00 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools.yml index 5e40c6200..911811854 100644 --- a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools.yml +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools.yml @@ -210,4 +210,331 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1CemhmT1E5dERxWFNWWm12UmFFNG5HN3pNUGZUdiIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NDA0NTU2MiwKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIlRoZSBjdXJyZW50IHdlYXRoZXIgaW4gQmVybGluIGlzIDE1wrBDIHdpdGggYSB3aW5kIHNwZWVkIG9mIDEwIGttL2guIiwKICAgICAgICAicmVmdXNhbCI6IG51bGwsCiAgICAgICAgImFubm90YXRpb25zIjogW10KICAgICAgfSwKICAgICAgImxvZ3Byb2JzIjogbnVsbCwKICAgICAgImZpbmlzaF9yZWFzb24iOiAic3RvcCIKICAgIH0KICBdLAogICJ1c2FnZSI6IHsKICAgICJwcm9tcHRfdG9rZW5zIjogMTQzLAogICAgImNvbXBsZXRpb25fdG9rZW5zIjogMjAsCiAgICAidG90YWxfdG9rZW5zIjogMTYzLAogICAgInByb21wdF90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgImNhY2hlZF90b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMAogICAgfSwKICAgICJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjogewogICAgICAicmVhc29uaW5nX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwLAogICAgICAiYWNjZXB0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwLAogICAgICAicmVqZWN0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwCiAgICB9CiAgfSwKICAic2VydmljZV90aWVyIjogImRlZmF1bHQiLAogICJzeXN0ZW1fZmluZ2VycHJpbnQiOiAiZnBfMzgzNDNhMmY4ZiIKfQo= recorded_at: Fri, 01 Aug 2025 10:52:43 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:04:49 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999700' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '792' + X-Envoy-Upstream-Service-Time: + - '800' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190f12c50819d9f200c6ffcbaba7005e72ec641737cd6", + "object": "response", + "created_at": 1754370289, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689190f1a768819dbbb349326e4c8e0105e72ec641737cd6", + "type": "function_call", + "status": "completed", + "arguments": "{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}", + "call_id": "call_9NNCZ4vzdpbDU6G5Kk7tCdCo", + "name": "weather" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 82, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 40, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 122 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:04:49 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"call_9NNCZ4vzdpbDU6G5Kk7tCdCo","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"call_9NNCZ4vzdpbDU6G5Kk7tCdCo","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:04:50 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999647' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '491' + X-Envoy-Upstream-Service-Time: + - '502' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190f22f5c819fb370afbf9678802a097a02601991d080", + "object": "response", + "created_at": 1754370290, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689190f265d8819f872256abf8c4b9f0097a02601991d080", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The current weather in Berlin is 15\u00b0C with a wind speed of 10 km/h." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 135, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 21, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 156 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:04:50 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_in_multi-turn_conversations.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_in_multi-turn_conversations.yml index 74a0bdff5..60ca4e5b1 100644 --- a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_in_multi-turn_conversations.yml +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_in_multi-turn_conversations.yml @@ -414,4 +414,664 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1CemhnREVhVUxiNUcweHZ3TGVhdUZHMTE2NEJKZCIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NDA0NTYxMywKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIlRoZSBjdXJyZW50IHdlYXRoZXIgaW4gUGFyaXMgaXMgMTXCsEMgd2l0aCBhIHdpbmQgc3BlZWQgb2YgMTAga20vaC4iLAogICAgICAgICJyZWZ1c2FsIjogbnVsbCwKICAgICAgICAiYW5ub3RhdGlvbnMiOiBbXQogICAgICB9LAogICAgICAibG9ncHJvYnMiOiBudWxsLAogICAgICAiZmluaXNoX3JlYXNvbiI6ICJzdG9wIgogICAgfQogIF0sCiAgInVzYWdlIjogewogICAgInByb21wdF90b2tlbnMiOiAyNDMsCiAgICAiY29tcGxldGlvbl90b2tlbnMiOiAyMCwKICAgICJ0b3RhbF90b2tlbnMiOiAyNjMsCiAgICAicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjogewogICAgICAiY2FjaGVkX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwCiAgICB9LAogICAgImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOiB7CiAgICAgICJyZWFzb25pbmdfdG9rZW5zIjogMCwKICAgICAgImF1ZGlvX3Rva2VucyI6IDAsCiAgICAgICJhY2NlcHRlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAsCiAgICAgICJyZWplY3RlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAKICAgIH0KICB9LAogICJzZXJ2aWNlX3RpZXIiOiAiZGVmYXVsdCIsCiAgInN5c3RlbV9maW5nZXJwcmludCI6ICJmcF8zODM0M2EyZjhmIgp9Cg== recorded_at: Fri, 01 Aug 2025 10:53:34 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:04:52 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999702' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '897' + X-Envoy-Upstream-Service-Time: + - '910' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190f336c481918952e230140d446109c9513227fcfaab", + "object": "response", + "created_at": 1754370291, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689190f3bd5081919abc2cb1806283cc09c9513227fcfaab", + "type": "function_call", + "status": "completed", + "arguments": "{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}", + "call_id": "call_Ih720fQWNR9gg7CnTJRgBEiq", + "name": "weather" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 82, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 40, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 122 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:04:52 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"call_Ih720fQWNR9gg7CnTJRgBEiq","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"call_Ih720fQWNR9gg7CnTJRgBEiq","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:04:53 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999647' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '600' + X-Envoy-Upstream-Service-Time: + - '610' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190f47fa4819e9a62fced3ef2103b068c06dbd107f8a7", + "object": "response", + "created_at": 1754370292, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689190f4c16c819e9d16a497ea83fd96068c06dbd107f8a7", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The current weather in Berlin is 15\u00b0C with a wind speed of 10 km/h." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 135, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 21, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 156 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:04:53 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"call_Ih720fQWNR9gg7CnTJRgBEiq","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"call_Ih720fQWNR9gg7CnTJRgBEiq","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"},{"type":"message","role":"assistant","content":"The + current weather in Berlin is 15°C with a wind speed of 10 km/h.","status":"completed"},{"type":"message","role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:04:54 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999602' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '593' + X-Envoy-Upstream-Service-Time: + - '606' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190f564fc81a2bc2f0a46c6832e820637f423a76064d0", + "object": "response", + "created_at": 1754370293, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689190f5ace081a2a5663b98aa52e5780637f423a76064d0", + "type": "function_call", + "status": "completed", + "arguments": "{\"latitude\":\"48.8575\",\"longitude\":\"2.3514\"}", + "call_id": "call_f2GOZ9OL7jmDzThxwj7MtRvm", + "name": "weather" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 180, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 24, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 204 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:04:54 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"call_Ih720fQWNR9gg7CnTJRgBEiq","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"call_Ih720fQWNR9gg7CnTJRgBEiq","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"},{"type":"message","role":"assistant","content":"The + current weather in Berlin is 15°C with a wind speed of 10 km/h.","status":"completed"},{"type":"message","role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)","status":"completed"},{"type":"function_call","call_id":"call_f2GOZ9OL7jmDzThxwj7MtRvm","name":"weather","arguments":"{\"latitude\":\"48.8575\",\"longitude\":\"2.3514\"}","status":"completed"},{"type":"function_call_output","call_id":"call_f2GOZ9OL7jmDzThxwj7MtRvm","output":"Current + weather at 48.8575, 2.3514: 15°C, Wind: 10 km/h","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:04:54 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999550' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '571' + X-Envoy-Upstream-Service-Time: + - '582' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190f65d10819d82ac4bed26a029040607d69b7512a16b", + "object": "response", + "created_at": 1754370294, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689190f69b64819db86428306954296c0607d69b7512a16b", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The current weather in Paris is 15\u00b0C with a wind speed of 10 km/h." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 233, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 21, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 254 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:04:54 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters.yml index 1b82db984..8c53134da 100644 --- a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters.yml +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters.yml @@ -240,4 +240,302 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:54:13 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the best language to learn?","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"best_language_to_learn","description":"Gets + the best language to learn","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:04:56 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999742' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '497' + X-Envoy-Upstream-Service-Time: + - '509' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190f78fd881a09f1d33a49fc522e601318d1d5768f261", + "object": "response", + "created_at": 1754370295, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689190f7e85881a0823ca168a49442e801318d1d5768f261", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_VOXosmYeldcRlCgpUDo2170p", + "name": "best_language_to_learn" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets the best language to learn", + "name": "best_language_to_learn", + "parameters": { + "type": "object", + "properties": {}, + "required": [] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 42, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 14, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 56 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:04:56 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the best language to learn?","status":"completed"},{"type":"function_call","call_id":"call_VOXosmYeldcRlCgpUDo2170p","name":"best_language_to_learn","arguments":"{}","status":"completed"},{"type":"function_call_output","call_id":"call_VOXosmYeldcRlCgpUDo2170p","output":"Ruby","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"best_language_to_learn","description":"Gets + the best language to learn","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:04:56 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999717' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '509' + X-Envoy-Upstream-Service-Time: + - '515' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190f8567481a18f7cae43101556520696729ffc5bbc44", + "object": "response", + "created_at": 1754370296, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689190f8935881a1a9244e8d16ac7cbe0696729ffc5bbc44", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The best language to learn, according to the information I received, is Ruby." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets the best language to learn", + "name": "best_language_to_learn", + "parameters": { + "type": "object", + "properties": {}, + "required": [] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 65, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 83 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:04:56 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_can_handle_array_of_mixed_files_with_auto-detection.yml b/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_can_handle_array_of_mixed_files_with_auto-detection.yml index 84c7abcee..e6ca5ff79 100644 --- a/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_can_handle_array_of_mixed_files_with_auto-detection.yml +++ b/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_can_handle_array_of_mixed_files_with_auto-detection.yml @@ -120,4 +120,143 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:51:59 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Analyze + these files"},{"type":"input_image","image_url":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAMBWAADAVgGB4Q5XAAA7zElEQVR42u29d7gkZ3Xn/zlvVXW4ae7koMRII2kklEAEkWQDC0YmrPFazgZsjBdY1mt71+bn3+6PXez1LhgvGAzCpMWA7cXGAfwY2zw2IhkUECAURnFGo8kz987NnSq85/dHVXVXVVeHOzPYwkvP00/3VFd3367zPd8T3/MK37v13VQ1fSqZO4Bm7ojId/1vle+Ju0/oAAZwM49OctwCQXKP/iWAQL4n+Jy2u8m9AmwCngxcD+xD9ZT1O5FttwPbaLTDpaV2MD/XCRYWbLS6SrS6Qvy4Spg+X0mPrcTHGk00isBa1FrUKhqlz/uPdc+L1KDqLdeMNirSsTBnVNrWsbxmKTqr3+9+T+hdLfeASWA38DzgJuApwCywDDQ1jLCtlkaNhtp2S1VVxXFUHAdxHEjukrnjpsdcxBiwESrpV2vGyEj3WPpUkydqVFqumI4HgK/wYCDcE1nnK78/43w7Qo4LRG9c6XyPAdZJ8U6i7TuAGxKhPx24KEP7vc8Iw1ibl1cyGr9CmGh+37GVFaK1HhOEq6vYdivV6q7WZzQ9xwbWWjpYWo6l4wgRYBEiBAtESCeCxyxyV4T8lcIXfFfnvUj45eX29xigRNudjPA3AJcDLwZeAlyBak1thIYhhAFqbWzjXQ/xPMR1cWY2xDTtd7B+B/GrGN9H/Q7aqWIrHaRSxVR8tFpFfR9brSK+j/E7aOCDVTAKKiASa7oIGEU0/n9ooGWsto2VqOt5Ss4LVagqsldhr8LNFu42oXwogE+/tzZxulG1vHkEEOT/EopPBV9LtPv5wMuw9pqosbYlmDsh/pHH8Q8dJDh+hOj0HHZtFQ18xHFxpqbxtu2gevGlVPdeTeWCi7ChxT9xnHBxoavdpSzQ9Qd6x4osQEbrgyjUtvXpEEmIFjW++5g/lrIDWAis8PUIftvC3wr4/3kICNx/wRTvJHcP2A5cC/yghuHzw8WFC9sHH3Wa93yTxr3fpPPwAwQnjmJXllG/DVGEoIl5FkQE47o4k5NUzruIiWc+l5mbXom3Z28cGvh+jwX8KraTskAHrVSxFR+ppmyRsID2WEBFiFDa1teOdiTCYpO/oKDxyfGBjIAKnoVnK3xC4QMR/M5bZ2sn/+tS+18mA5RQfOrQzQBXJPT+r6K11cta+x+ur9z+ZVa++kVaD9xHOHcC7XRAY6qXJKwzkqGP7nOJRaKKcV0qF+5m9uZXMfNvfoaw3aF9YD/h8hLR6tqYLNBGrSWKQtp+S1t+C6uRpEIu1/S8xqfPbRKTWsAKWTawEfyDFf69wMOihrcuN7/7ATDCi98DPAN4sVr7jGDu5KbVu+9i8da/Y+X2f6Tz+AFsq4GgGJFE8IJI72LkBU/ymmSeg6jFnd3I7I++mo2v+2UUQ2Pf/QQnjhOtrvVCwTIgrK4SrK7QbjVodhqEod/7baVCLlK9JOBgFADS57da4fWiPBIZeNti+7vTBJRouwfUgZ3AMxOH7rlq7U7/+FGz+NUvMP/Zv2T1G3cQzJ+KqV0EY2J6td00X+x8pcLVRBKSzf+JJrFZ/CBiCJeWWPw//xszvYFN//Y/MvOMZ9K45x6ajzyE6VQSJ7CDTanfr2E7HTqhrytrC/jtVvKBmd+Y0LrNUXue9m2R9nv0P+j4CxTeHwmvQTmS/T7nu1D4JhO6PRf4OeCXgddg7bXtY4dn5j77l/L4e3+b43/8Udbu/Rbh2mqs3cb0pNp36UFVuse6+d4MT4pk/xObC+20CY4dprrncmpXXEVl5y5MtUq4tIhttdAocfLCkNbCPIuPP8ryyaMSBZ0+9s3a+NQHsF2hZ5/3jvV8gx4AsgCxPVBcrFCN4PPPqbnR19rhdw8AMsJ3gC3Aq4D/F/h3wI3ADn9h3p37+7/hsXe/naOf+DBr++4lajVj4pYeuWvmamuJMVQkZxiLICmCABHsyjJYy+QNN2Kmpqls205l23ai5WXC5SU6C/Ocvu9bzN9/N52lRVBb/jvXKfgcAIQ8GMqPX6XwqMC9z5zwuL0VPvEBkBG+C+wC3gK8ObH11ajZYOG2r/DYe97BoY+8j5VvfwvbaibGWvoEmRWw5gSfEbZKARQFb6n7EanNUOzaCvXrn0Xlwt0xUqenqV98Ca35Ofvgxz9sFx950KgNKeAr9/cNFrz0sYMtRABlALBSjCDwVLg4Ev4aWL29/QQHQEH4FwD/HXg14Km1NB/bz+Mf/QD73/N2Tn/1i0Srq4n8pFR7VcgxgRZOygu6xEZIkQl6BUPttKjt2cvE9Td0XxTPY/Kyy2F2U3j07rt1rdES3/HwjUMkRiIxCSCzdn24xpdpv0pB6wcDABW2KxwUuPNpdfeJC4BE+JI4epcA/xP4UcAJV1c4+bef4eF3/AbH/uJP6Jw4AapdAWtBx1T6ta20kicF2k8FWar9BRBEEd7O85h67guRSrV3uuPI5muuM5uuuS6cv+++aO3kSScyLoE4+OLSMfHdF5fAuATGwYrBiohisJLmAyTx7KXPESyl/zJQxOeJwhYLnwaazhNc+C5wKfDbwA+ptabxyEMc+OB72H/LO1m+5240CHLKqhlJ6YAgNytQGRQJF8BUBEHfZ1nF3bKN6RfehJmcLn6hTD9pt7vred+nK/sf9VceO2DiyFJ6nr8IViQRvsGKgzUOagyIAWPikFUS75M0jVzQ+uHan/5/C/B14EHnCa75VwHvBG6Kmg058bnP8tBvv5Vjn/4UweJCX6tGn9eexu7pobxpzxyXHPPTFwFkQJCJCLq5g8QPcDZtYeZFL8OZ3VT622qbNzvnv/DFGrVb/vw933bUWhndTxB/USp8I4IrgmeEihGqxlAVwROJq1tJRquLy0x+IAVColhrgvy1+wQTfFb4TwXegepzm0ce5/CffIJDf/RRmocOxmlUYbCrrllLH2uJJKF8GudnAYFqXvJ9IFBsQicmpdf0s6R3ogYBGoRDf2dty5bK09/6W87Ezl2te97zzkpnackTY87omvUqyYKo4olQVTSKCYkQJQRCwFfFBwmBKAbDU0G3uE9Q4T8LeLeG4bWL37yTR9//Lk7+w98SNRq9X615wWfJoCsQ6SV5Sp05Lb6pJ3lJ6TIFk2hM1ZqPt7NvV5FeCrH/R8aFnyjCqDpX/exrJ6a3bu3c8Vtv1caJE5UzBYFNrp8FrGr3b1YUo0lbk2qcMVPVJDMoVnWHhfOcJ5Dw0wTP9wHvDNdWrz36mT/jwXf8BnP/+AVsp5MTXFaTpaeo+f/nwJFP9+bMQS40k377Ltnz8inh7nmqVC+6mNmX34yzYTYWeBRB4KPtFlFjFbuyTLS0SLQwT7hwWqY3bnQ37d7trxx6PGyePu2tt72sKHybCN+i2AQEVsmDo3fNa6je4z6BhO8BLwDe0z55fM/BT3yExz72AVpHj+SkKprR1wwTFLs3c5SfMEFceeu91s3sFphA0hCraA4UtIQJ0p9hNsxi6hMARGur2OW4umjbHbTTRjsdbPKonTa205EN01MTT7v5R/17/uLPm8cffLCWXIuzFr5Fk/9nX9euT6CqnsIl7hNI81+K6ttXHn7gkkfe/y6OfvpTBCvL5YInzwQygAnI0XMiXJW845hlla6w+x0B7eV8eiDI5Q8Ed+sOzMQkGoUEhx8nWlyMawF5oXfBkP7f8/3K1Tc8Q+qO6Rx84MFKFEXOMDboCjgj3LzGDxF+el782tPdJ4Dwq8ArNYresfDNO3c9+K7/wakv/D1RQvmS8fBzkVixnU7zQCmagFTYRSYYBIJe1aff19SENlTjeNwIiONRueBJmFqd8PQ8nUcfxjYbQwUf9w8EaBigUeg9afeFTkW0deDh/ZVOp+MWQaAZLR8mfJtcrxHCx8JO959Z+DXgNdbv/LcTt35u64PvfhuL37gztp3Su9hZn81oeR5Vct5/ni00AwIrYEhbr8YEQRaEGdqXxHaoVWR6kurFl4ExdB55CH//I4n2J4JPGkZskAg8jNAoRKMIjSKstWgUma2bN064l+4ODhx43G80214aoWqZfR9D+Knt7zsviVzdfybhO8AE8Kqo1fzNo3/zmY0PvOu3WHlwX87DKwpStBD+FDVe+tmiDARZczAIBLkQUbqZ/9znaWouVHG3bqe2ew/q+7Tuvgv/8EE0COPQMAx6go4i1EYZwfeea/yaTHpu5ZLzd3QOHTsZLDdalWHC79H9cOHnzusBYtL9ZxJ+HfgPYWPtzQc/+fGph275HRoHHxvu5esQwZN3DEX7Enal5oAxmEATEIhIzxGk4AAK1C69gsr5FxKcOEb7oX2ES0uxoGPNLhd+T+h9/3eiqHr+xqnIUdueb3Y8izolFF5w/NYRFcSAqLj/DMKfBd7kLy3+p4N/8rGph973v2gmnn6WxnWAABlC9bkQ7xwzgSbRAcWmC1VMrcbUU5+Os2Eja1/9Mu3jx5Imz4Jgi8IeCIakXVyts73uVQw2ONn0xaoaPROvf8DroMb9JxJ+2sGzCfh1f3npjY9+9P2Vhz/4bjqnTuXsPQUtlyH/LwVHIUQcBwRx0qRXO5AhTJCm8NO/VVVxt+9i6mnPhihi9c6v4a8ux59t+4Wf+38q8OyqIE0MS69U6WyuesYV6RxpdEw7sl4qyHEdv1JwxBfnO+cDlCy52gG8pXN67tWP/sHve498+L20M8JHy7W8WMQpo37KTPc6QWALIMgxQa6qmHBBtwAlTF51HRN7n0zn0EHW7vs2YaOBqu0Ttu1qdwRWUbVdQecf889VVaZdU71wshIebfrBSmBdi4qOKfwi/WvvPQvuP4HwPeA84Df9pcWfeOSj7zcPffDd+AsLSWK9RKharvXdrJwO+e5iTkD6wTQMBKK9foI0QWSzuQWJf1+cB1DMxCQbnvt83I2bWfjcZ2kdOVSg90S71cbZweTaFAXePZ6hwsI5UjfiXVivhIfxgwU/8iwq6xV+1zGMPzdw/wk0/3Lgf/pLCzc9/JH3mYc//F46Cwu58mpZcqcstcsQGy/DADECBP1JIS3Uf/NsICkTqFK/dC8zN9yIWsvybV/BX14CY2KQqCZC71HaGQg+pWsUcFD3gponnhAc74SOBUcHeP3DhG8VHOh8J30Ah7gv/x3B6sqL9//hR3joQ79HZ36uV7/XbDk1r/lmlJZLvzNY2vQxBgi6zzMgEFWsyTNB1z8gzgaaapWNz38x9T2X0TlyiJV77yaKYnofQud5IXcji149e9Q5As4OzxEXwiOdkJb2QDCuYwjgKUe+kwC4Bnhf2GzccOCTf8ADv/8u2onw+1K7BUEOC+O0hN51FAOM8AlyoElrBBKDQLO94tIDiFqoXngxm1/8Mkylyso37qR95HAMDmv7GHGYVqMDgDDsHDCbHFPxqm7nsXZg1xRv3HRw+vMNPO5+h+j/WcDvWd+//vHP/CkP3PJOmieO5/rss/a3TPgMcfBGefvrBcEg31PJgCCj/SKA67Lp+1/E5JXXoNay8OVbCTsdxHEyvYZ6ZoIvmIWC4HPnTwrVS6pueLAT+qcj66pihjmGueqbcsz9Dgj/+4APaBRdfuwLn2Pf+36H1cOPZ0KpDDVr/IdImTkoEbpmSmXrEWqfzS+cr4XmnzImEOnlCtQqtYsvZstLX4kzMUn7yGGWv3Fnov3aJ+RhdJ47ZwAoNKM1ZedUwL3YM3gQHAsjz8atAH0ZwezPdBRm9Bz5AJlY/2bgbcDuuW/czr2/+z9YfvgBMMlv1H5Pv1i9yxZ3yhI9A0O6s2CCXLGlPALtOoaKYipVttz0r5m57mkALH/jDlpHDiem35YwwFlQfla5dPDnGNS9wBHjqukcCq3bUXW1X/jd3+mCrSpt9xxq/vXA7wAXrOx/mH23/C9Of+tOsl9fRvvF/D5DwreBzts6QTDIfGhJc2nXMUx9AoX6nsvY/oofwZmcAmDpG3cSttvxhJA+wWcFNZzO1y34fh/D7DDUKq74j4bqN6xWKO+FwlP8yjk0AZPEizUuaM+f4oEP/i5HP/+32Mj2c6yWdesM8OYHMAHfISbI1/d7jRfZ6NCZmGDHK25m+snXAODPz7F421dj7bd61nS+3nOK0QUgs2j1ciOdA6r+olKRkss6oTQ9OO6eI+1/BfDSqN3iwF/8Hx77yz+JNUJ6jlOZg1fU/jKhFplAh9QAzsYn0LKIoBgiAhuufybb//WPYKo1AFbu/TZr+x+Nz7d2oI0/C63uhZPjnJM8n4TqpYbwoKU9r1Q0swzQAWpKQ2D+XDDAZuANam39yK2f44EPv4/WwgJiComWAgJFhydwyphgWEQwit4HCTaX6NH+5WKSqVNUt23n/J/+OSb3XNZ93/wXP0+wutKl/1LKH9OOK8OFOo7gs7+tAu4eg9Qt9qjihMlPqyjUlMiC754D7f9x4FlLD+3j/g+8h+UDj5Tm8vtq+YWUbpmHn3tegiY5RyFi1/OXAdoPiOuy7QdeytYX3oSYWJn8hdPMf/XLWJvks4cIcz0Cz047GVfgg24GnPMNTk3hcQvtmP5xIbAQuWcheIgXaL6pPT/n3v+RWzhxR2wLcxe+UJ/PmYGScEyGOX2F7M0gP4AR3n5OyFJu+9NscOq0Tj/5ai786Z+nsmlz9zNW7ruX1YcfxIqAteuj/CFaPQoUw4hy0LXbJlAx8JiFqdivWlRYdc9Q+OlkjtfYINi7/9N/yv5Pf4qw4yNmSJ6+jPbHsPGDMoBl54wb8mXz+2VgyAKhumkzF73qdWx4yvW59y/edQfB6iqIKdHqAQwwTPDZv7EkfCsLVdPnERBpbzqIEi8IibS3OigEpoB6/D1NOLMwMBX+tcBPnfrm19n3sQ/Rmp9HTK+HT0o0XEbk9XWcEm8JcEoTOgOSP4P8AJXyv0lcl+03vZxdr/gRjNeLqqJmg1Nf/DxRaBFHxg7rypxEzfbsky7syI14GSjowiiYTMdP7zOyz2cUXO0GOOOPiCks1Z4E3tg4fvRJ9374Fub33d93ZTUee9en7YOAMMwcjAMCO+T8su8YNCOgGKNufNoz2f3aN1LZsjX35648+AAL93w7HhhsbZx1K2h5ukJHc+yjubUE3YWbWrKYs+Rx2GsMCK1Nco4BJnr54AXOwAlMBzLdYIPglfv/+tM89rnPEoVh19Z3F2LogNBKxu/i0RFC7VubNwZoirSvAwypKtR3ncfu1/07Nlzz1L4L0VpYsPOLK9IJoqTZXMubVqFvANWQnhdKMDiwMCZljJfpVireKvFkyfR2XCA0Z6D9M8Br5u779qZ9f/gHtBeX8tSlvbSvFilX80gvuyAyREA6KGUrg8O8svfkhikVnqcnu9PTXPhTP8eOF78snvlbuE3vuVQnt++wYiHKaX+58FNNTB/77jJgkcuQhJkMcQLLzqlrXANIbseykdc4wk+1/3mdpcWbHvjjTzB37z1dbcnZnqzwS7wWHVHrZwwQlNL7AKDkqFYygh9gBsR12PmSl3PRz/w87tR0eepz1y4zu3evehbqErc99S1Nk7zAsyAoPpcBIJAxhC9jRAMmAUDmtgxjrkNL08dJ0uffHr3tH2ce+au/IPT9nv3JabfkmKDn7GQWOOhgCjwXILBlTFDUfCn//E1PfxZ73vArTJx/4WBbWKmy47k32tSv8SS+myECLGp9qYBluBaPE/qVvVZRqORnU9mRACi0c7vACxonjj9n35/8MStHj/acEu2lweO75kq/OadH+83BuQaBljGB5EeqZI9n7f70ZVdw6Zt+lQ1XX5evBCYzfUl6/QCZ3XuFmKqbp8h0hfgIbR5Xu2E8QIx6bUJzwo6AxXGjgLSxc7va6BcO3voP9cdv/TxqtVvmzXvl0l02qVmHRHqLKDTj5dkM9Y0TIo5yDLPfJSnMpT/cK8b+YqG2fQd7Xv8f2P7Cl3TtvoYhmgx37lJX0is+vWuX1jdvCRonTlSymmsGCEYKdY+ydMioxyEplIE3F6jntb8DnBgKgILjVwFeuXr02DP2feqTNObnemVdKWRWhO7SaTJLsLPHsq/JOQDBINha7Q/3tCQsRcHbtJGLX/tGzv+hH8NU4njftltECwtoGOQ93MS21SYm3JndFweNYycGTlzUASAoY69xBbreW812Y//0tgbMj8MAqfafr9a++tBXvugeuf02rI2HbvYt3MzG2ZphgMIyqiwDaAEE5ypE7EvuyIBoQ8GdmODCm3+ai1/zerwNszFHrq4QHD2C+p1S4atVxBjZcsUVevxrXxvq1EYMT4Z9J2+mX/shLgk0BgIgo/0e8QreH147fuzKB//yz2kvLna1K9eZK/m2p6y2a251TYF+C0wgA9igLKU7tLmzbABk0U9QcGo1Lnjlj3PpG36ZapLsCedP4e9/FNtplws/eS5iZPbCC8WpepENAochqds0W+dmLroyIicx5mvDwFfX2AEseak8E1iydv8y4FWHb/uac/i2jPYnwjPZXKvk/aYsCKz2NDznIBbMQfFcKROsltvNgc5jIU+c0r7xPHa+6Ae5/Bd/jckLd4MqwZFDtPfdh3bavetRcleNB8hNbZx1ahs22MbcvCNSLvzsFQ/pjTaXAbn9YfmP9QAlzfyVsM5awgJDTUA1Sfn+ZGdp6dL9f/PXNOfnchOyyDw3BaEgJWYgywTkncCcUDMgKO0nKJgDO4L2ixlIVTCuy84X/SBX/upbmN5zOVhL+8F9tO/9VryHwAjhp2zg2chs2LkraJyaH5mQSu8+8b5zRTbIhsrjgmBYwajaH/qltzkpMwGFsK9GvLDj5QsPPsDcXV/HFSHsXpis5kk8eKEwN0czDmGZdkN/bh7tB8Ewx9Cegc03rsu2G1/Alf/xvzD75GvRKKJ9z7do3vHVePCkJp29NpPSTH5zusSLrhkQM7V5k2FE5a5/54/YJKRAMIOylkMofxgYZLD2k0QAHR3AAJIIfwb4GRv4Tzr2j1/CP3WSquchUUQQRViNc99G+p2+7I9MfYO0GJFzAtOMhPZeKwOBDPAJKDiZZbmAXKinII7D9u//V1z95t9g47XXo0FA4ytfoHnn11A/yNn4+ItsQfjkct0iwvTMtBrXWLXWjBJ8UaChxmYh3d9GhqSwGcNkpNe/qlC1A9l9SSFysgAohH114u3TXtY6cZL5O27HiUI81+1+WRBF8WKD3KLJQm5d8zn29CtStiiCILtTB8VBjAOYAEPplFAtCfXEc9n+vBdy1a/9NzY95WnYTpu1v/87Gl/7UrxTWNaByTVzaO5LcsdFmJiaNNWJCdtaXTPIeILXQgUworeY0gx477iPI7S/mwV8XQkDpNq/ibjVa+vyg/toPPoIFceBwhTuIIq6o++FPOWnHr1NR6gV1gOWgSCldJGSMW/96zW7YJMBvgIF2t/xgh/g6l97K5uuvR7baLD0mU/RvONruaVcvfq99oUtWprOBNdxzNTG2bC5ujaSwsuErxmpdOjteCUDnMlRj5XBtr/LAFltL4Z9E8CzgRdqGLJ8z7fR1ZVY+5Ou1ywLBmq7TGAKIBjEBOm5g0BQFJ6UmQ7pz/Nn29C6GFAw1SrnveilXPUr/5mN1zyVcOE0i3/+SRp33dGXo86u1MkKWpUBxxRBzOTsrHDoiKar3Yc5gWXCz/4/He+aAmGUOcn+aQJMRiPzDcdyAMhEDTVgK/ATwGywvMzaQ/twVVHXhSjqK/XGTGCT5dCZvHsJCLLJHpthAilxDDOJxT5HUYZs5JDLDyiYWo0LX/bDXPUr/4WZy64gXFpk/uMfpvHNu3KbAqn2a73mWoi0sJInX/+dmpkWcRy1NpKhTqCOYIZC909Y4hvokHJ33ZbG/dlbCBzvAqBE+5+T3OmcOEZ49AgV1+nN1k+7XAoXPYxszifIOnApG5kCCLIXMOvs5QZDST7FIJmMYlkdVDKFpsrMDLtv/hn2vv6XmN69B//YEU79wYdo3nM32XV6+eyS5lmgZA1fFiip1lU8Tyr1mm2uNQb7ATqkR2GA2bAZ/8CUACH72Y7mOn6GAWCxyACp9m8j3pRhEqBz+BAsL1Nx3bhaQmY0Wkk8EoMgXo/WFUgmUrAjQEB+Y67yFict7yoqNpLUt29nz0+9lstf+ybq23fSPniAEx98L83770OM5DpwR2l4/7F8ezYKRq2p1Wu2sdYYSPvjhIiDXk+BYEoSX1ntd0cXEzSbOnELBZ8XpNqvUUjn8CGM30kAEJU7Mqqo9rKgRSawGcGaAgiKzl63ETPzKJpPNBaZILsAJdX+qYt2c+UbfoXdP/LTVDbM0nzgfo6995209j9Crm2ZMsFn/YHRgu+ygCC1WjV1b6RM+HoGgi8zC8Wikip4WprzL7t10jpAFgBp4ufZSQYQ2/EJ5ubideROzyfV7BJnLXe8wyiOmW2JdveNfymAgKzwB9S6i4Dpzg0yhs1PuZ4rX/8rnP+SV+DWJ1i58zaO3fJu2gcfi3PYfcLU8tCv4AxqXw4739ItwES1aowRokyXL2PSvTJ+/sDSPzxzMhq7u6dRNAHZXbUPpJ+tnQ5Rs4Gp1lDaeEkWO+sg9znGGRiEkcamoACCNGTLzgXI7dI5qI6e9fClP6p1alV2Pu8FXPWLb2bbM56DOC7Lt/0jh97+m/gnTyTCL4vxe0LtO7YOk0DSFeR6rg39XmGo6PGfidYPNAup8G2u2XPULU1A9kUBAhxOXqzYwAcb4UxOxvvVtJrJewvKUfCN4nn6EQIEUZgDgRZ8gtyiUCk4fvRif8kwQq6RMd1DfdMmLvmRn2Tvz76RmUv3IqrM/81fceT33oV/8ni3dt3v9OlwX6CMBUrCxC4LqJqq60YtPxgq/LMVfNahdIxQh3ixwHg3PytIlwFVU40iMA4mAQCq0G7lzEB2Vm6vCzbKxeFZEEgmNSwZMOTaqYvt5eSbK/NlY2Hmkj1c8epfYM+PvZralq1oFHHqM3/O4+98G8HiIpITfl7QOkSYfUAZdm7vP1J3HVnMvPWcCz7LvgKVikF8XU8ryWJSDewCQDO04HVT9iI4tTrO5BQiic4ZgzabeMUlNln7LYW9NyTOGFpr+yd/FsAgA1qjU7ro1gw0pvxdz34eV7/+l9h14wtwanU08Dn6sY9w+L2/G28XKzK2nS+1/f1p8v56drGEaowYRCNUzrngC99VcQ2ea+I5DOPfTgKtIgOECTXUEn8AcV2cqakEANLbJku1+3bNTepOd+KO4n16JGNxEnRZa/tHv2a0O5vEMWUhYhJVTG7bxiU/9KM8+Wdfz+zlVyDGEDUbHPnQ+zl0y7uJmk0kmdVXkOTgpgod3WKhQw+kfoCIa4yGUST6HRB8qv3GESqV+KpFZrw+o2TU1akvVoz//X6UA0Cahq53FbdSxZ2dxZ2aIjKmsPGyQLNBhfyeO90t2Ir76SRD733ADtg312YoPlcKziivW/HY9pSncvVr38CTXvJyqhvj7dmixhr73/abHPv4R+P+PZG0c3dswY3stBlysFiG9RyjrSg6J6Ff7pwM9dcqDiaZYK7S868GCl/SvY6k8/zA8gsFBrCJfCa7eeFqBW/zFpypqUT4xTytQquVy8D1snaZRJD0nEIVCKKYCcpWdNqMT5BtPDHA5I4dXPKyH+LKn/k5tl7zFExSmQwWTnPgnW/n6Mf/d1zRG7Q2SkcLb5Ta63jNWFJ3HFlOHO1zIviCQ1nzHFynp/XWgBpBShxBybGzIIIfZ9uiviggwNrJWLYWcT0q23fgbNjQX4bLJuVbLYQgtytX70vBiI01O5PSDYBoDBBYhcpEjV3PfBZXvern2P0DL6U6u7Hnzs6d4qG3/DonP/3nmRgz75/ouF10OuqMUeajd2WqjmBENFKVM3UCB6WQXddQ8Uyh5N2/S2pXBkhXFsnzE11PGnBjR0m5f+ukvXzfYwYboWGEMz1NZecuvE2b4wURJT8/RVbUakJA70voIc5ImPPqsn/nQBBYcFyHzZddxuWvvJm9N/84G/dclluj13r8IA+95f/h1Of+ptBhOlrgug7V13V0YaY/xRMRV0TDBADjCn6U8I0RahVTWha3RnCShFRG23MgMPEeN8eyUugywEWf+iuCw4es2gjCkGhmA94FF1HddR621SpvzMv9Jc38RG8Tb3Mq0p/QSd8ehBBmQKA2/pFTu3ZyyYtfwpN/8lXsfPozcGv13Fc3D+xn36/9EvNfurU7rqVYHF2v4EpP1DFdgewnJJFKxTG0rF13lm9g8Six+44ZvDN6KnST0/yu7ceI+EkUkAfA8p/9MebyZ+Mf+IaH2jiX6xzD3bKV+sV7CE6fplh+EYk3Mw7JgyDudpXuBovQX7jJMoGGEEVxZD+1fRsXfd/3c+XNP8YFz72RemYcS3pbuffb3P+rv8TSXXckU7ntWFLS8Q38eL5BbiBEf1GyZkSXzyYCKFQOq56D58pgY+RI4qr1FC8LAhM/t5J0A+cAEJ44ASf/0lVkFo23N9UwxN22nfr1z6C++2Kajzyco/4odQxVCXN/UhM3cYBksEva7bETz+Bu28SuG57FFT/8b3jS81/I5NZtJX4HLN/9Te77T7/I0jfuQlynZP35uMLLpn9Z100HGf/CORURkWRDsTPN8qWve66h6pmhvyNyBCOkgi5QfxcMVuKQPw8A/8hhEPGAjaSbHCXLoerXPpWJy/di223ahx9P+b1vP/Uw5xg2cYOgNERKUqaYiTozOy5m+w3P5sIXv4Rdz7yBiS1bGbCHrs7ffrve/e9/wbQffRhxTDKTdx2C0/HgMTwEHDNkJG3yFEJ03Vm+7DmOEeoVp6/cXebuizExADKefx4QrAmy2AeA4MhhEKrATAoAoojw5AmmHn2I+nXXM/nkqxHHoX34UH7ea0YtQqGXL2g2cLvtQwZ1FHGqVDdvpnbRbjY94wa2P/d5bHry1VRnZko1PmvYH/3DP5UHv3UvtZrLpFWqJt5GXf4ZYv1R74vrFUrFiLaj8R3B4jkiQr3q9OpYQ744SqZMGM05fcUwcFmEEgCcPEGSBJqJ+Seu6WMjmnfeTv266/E2b2bquqfibtxE67ED+CePEyLdnTHSHvMwOyqEeI/7ytQ07nnnM3nlVcxc91Rm9l5Jbfu23NClfnVV0j3bWydOyuLXvoEnNZaDNqsBuCLUjGHCMT0wSL+2jis4HdeA6Jg+BUhVcnWysbN86bFaJR/vD0OdTVqqnbgzPfED+sLA0yK9OkAXANbvpC1h1ZzaRRFrd3yV2Zt/AmfjJpzJSSYu30tl5078EyfwTxzDnztFuLhItLZG1Gqivh/TfKWKO7OBys6d1C7aTe38C/C2bMFUqoVfnPThJ+vv0y3W1cYsJCIs3P511h47yISp4xMQEhGp0ogimlGEI0LNxICoGMEdsNL4XMX648QREnfYiKG3OHScLF93VU/FoeLJWLDstt0nDECX+gu5APBFpN8HsL04X4qdMa0Dj9K87x6mn/f98QmOg7dxE97sRiYuvRTb6cS7Ywc+ai1iDOJ5mGoNU60irttN0KiNYoAke+qR7qCV7KrVNT/J7lpEEajl5Oe/RLDWwHEc6lRpaDPnZFpVmpHSjCyOgBcDQqsi4ogM6ZA9hyFjCaO4IK6gYcERHJblU6DiGWqeM4TFtE/4AKFRjO13AqXHCGExW+IC8T433R4NzZfGGw1Wvnwr08+5sddUkeb8XQ/H9bpj07t18+4kjTDeIDnKCzvW8KymDwKCJVhdZe6Ou7o/vIJHBweb6U3IgwE6qnSsigE8I1oRoSLgCmLG1Gw9ByFjsrZeW4VW8WEt4q5jqFWcZF/isR2VeKsYAyYJz7NhYMYXmDOIbzOfkTBABHFHcDXXDJGUQlfvugP/5HEqO8/rs9Wpw6hRGOfiwyijxXltLgq7FAiZ9wjK2iMHaBw5BibZrAFDVSq0tTV0VEp6qXyr4icZMlfQikjcuUMJGEbYjPUOb5DYpo4tfMckTl/GmRmH+rsMIBon4Po1P00SHVO6e2FlABAzwIzG5eC+RRKdY8do3HM3lR274l2wuztghxCGGRBkBG4H03oPABnNL2EEUWX+rrvpLK/kIo8KLmGGBWSAjhQjhEARX7tgwAWtFMBwrm+exMo8anGIMUK96iaZvvVRf9qTGIrGAzpzmp9zAo8BvGRxrmACYgaoQrbXowd722ryyC3v58qdF1DduCHeFTsV4kABZ2nd5hhh8Gu9EFStxfo+83ffH4Mj00cuCJ54BBoN1LxhtKwxGPBBWsmoo4rEbdHJpK9zMsgjGdmOC9rJdgoXh1xIHOvHHv/6qD8fCcQFMSf5BSUp4WbxPVkGGJg0WWl3WPzybcz80Sd50k/eHA9OSjS2K7xh2lzKDENeiyJQpXFynuWDRzLtv72kioODFYOlvL9AdHzKjkCa8fRkNQqeoNUYFOKcJRgcoCrQ1vJET5rj91wztrh1wB67NikNm0JBLsMA4QAAWABHsx+deIGRKvOrTSS0HPvs37H1GU+hunE2pv+Mxg6k/qGAiM8rMx+osvTwATqrje7qIs1YUUFwcJM2hhJdkcwqopKKXZm50GT1Q5g0PRmFiqC1hBmc/oLmWH5AjcxqzIIpqHlOJs27furPN9VovN4yhUAmDDRx+DdfCoDEBMygONk/QoClVoe1js+MqdA4fIRTt36J8154IzYIysO2Pm3OMkM5U3Tj/zQfkEQSCweOxOyUW3XfM1Ex2Rm0wAI5IpVyJ15GEKwSq0ugcSO9UbQi2BqYqnSXccs4c3pqghiNG3eLsX6t4ozQ+fVUNqAjNuME5moBASKLRY3ImoCNSTKo2/ceWctCs53MwxFsFHH8y19l06VPwqvXY88/1dispheBkA5ZjJJNlDPC7h/DEpeH/WabtbnFkqXfWqgvOEgGADqMNnWM8XIDwJGYCScFQ1Ww9TjbJ94IMHjJPch8XtXLCv/sqD97JMQmoWC2MpjmQkSLKfdsGLhJCxmRpbZPKwi7zgRGWD18lPm7vsW2q6+IfYHUnmdi9z5tzgrXav+xvuFLytrJeVrLa4n9tzn7Xxw3Ld1FZ8PpflTMPq7ORSANxVlLmQHshKB1kIr0Gug04wfU6K3H8twk1h9ZbxiP+rO8GIhNegJMMQzsiLCmpSYgZoBN2U/zrWWpHfRtdmBDy9w997Nx55a4cjdCm7vHbMmx4vClFDDA0tE5ojBMc5Mlgs+uUhbMOAQq/e1b6yPagQ6k01A0cfhsTWACnGpmdnA1+W7PNdSrTkYR1yv84YDuEGGTbGihM2hF4j0CygEgsCH7gSudED+yuS6eeCSLsHz0BCuHjrJh51Y0skO1uQuQ4oStLjD6ARF2ApZPLg68PJpfoI4lSX6M2+h5RlZ2tL+X+AzOatIVVI2BwFQSYlYdQ7Wb6Dmb4LL8uBCPrteUAXJNISwIsjIwDBTp5UL8yLLqRxlNkZz1DX2fUw/vZ2rDZK6oM0zwWQ0feh5KY2GN1mqrwN9lC9M1Y6Pjnrj1XsqBexCc5S0CGhovwTmtsE0ctrkua6J99YRzQf3dbCCWANuj/l5iaAWkVfwM9x92bUYJUdWu3VoJLGHGITDkW5EUYfHoCRoXncfk7HTPyStqeZ8PMOBY4b46v0IYhBlLOtwMgOaWTQ9cTaPrA8awcSzjfqYAs+KyQTycSHADZdmN4qTNulpMxrtZlA4RTlK3ybaD5d3gBABqwrRHawKgEymNwlKjYlJFRfFbbU4fPka9dlGvlDtoqOJQM9Cbwq0JS6wuNdCceAfZ/3xtLZ3COU659Uw0flhtf5ADulk8thq3G5rNWIMXGRacgGBEELle7e9FApqYmSQEjH2B1aRBqd8EoNZFZKMCq2FmXf/A4Cv+osUTc2zbvhHPc+Px8SMof5ADmD3Wboc0VtvFumSfBzDINESUTNDQ0cIadz3esAJhLrePsNW4bBavWJBh2ho8hHknoC32nFB/9uo0NOj2BGTCwOOhNYFjohIAiHgCs83I0gxtCY31d6OqQGOtweLJebZu3ZgAIE3iDHEKs8utS1bZrq62CYKotHKuJT8+yxDpKtfsZC10/GEM6zUJWp5AwiBsMx6bjFfamGFEmMLgWYcTTocW0Rl7/WW3DvEKbScJBRMAHKs4cPXjj/YDwAj1wDK9EtiBe/0WXTBNGknmT55m40QVYySzeXJG6Nnq4ohNkVWVlZVOvJx8Hfa/JGmTM1vjCn9dTDBA+z2E7U6FDeL2t2UVyrMTIlyghhPSZqU3s2Fsr3/QkUCjZA5TJgxE5ss+xU00vNYMo+lONLg7QinpwhVhZa3J6soqM5P17qi4Qduf9m2qXJjN4wcRjWZQMup9tP3PO0L9Gb9hgl6PXR8GnooYdpgKM8btW5JlCos0UhDUxOUCJjlOiwU6Z0H9mb4AjRXRkZ4jKFJeNXNPdyIQnFaong7xZcvW3SgQRcrppTUmqpWCkPNTNoZuq56c1mwG+IEdot1lnoiOdNhGhXzrZgSlD3A1MexyqkyK21eKLenOzXjnsaAuZAoPh5PaPKO9AXJ9AVg6hMxINRnOJRaR1VIArIZ2ZBiTJf+yJUlLa022bJii6rmZDaPyI1n6AdA/f6/RDBMzoUPi/35e0JLee+1fJzpyyOJYjFAy8WtaXHY4VeomzvsVhW7KF2nmKNqIcAGTVNRw1DaIsOukfs0xQEtDHDFpg4iPxHsElZoA4tUineEQYEBODtpByMJqg20bprrbpRaFO1jzNUkPKM1mMMTxG23/GaHhZ20SShzKjcZju1PFS3rxTEHTy5ZpFY9n/YLzzRRV43AwXMHHFrLX42UNFPA1ikPB2AFtAHPDALAGnAYuLWusQKWP+vtCwrUmGyZqcQIi4wsUBT1oS/RWO0roX0v0nLHtfxG79gxYgAGaXwzztjgVtjiVrrdt+vPvJUu1Cp069Pfw7zSTVMThQLhMU8MzSA8rK5GfmCKDCE1BlnUIABrEE8JuKP/4Yavs41dbfsBaq8N0rdIdIAkUvP8BziFKqxURWR2g3TrA/o9nG+1Z+gUU9kCoiGGHU2XW8ca283kwlJuB7Dnb3UlqxuOhYIEV2xm4o9ogVmiluYD471FhgBMooaKuRGXdIoPxVRJ6qbLYaFF3nVzkQGFH7ZzmpxVGGzNA/2cPtv9ZoAz13qV8G5axQVB475SJ7f2kcQdqcNnxPlNQwgZFEG1yalxjtvKAf5rTUWtd1UvfhkQo1XiUagvELzvP/Pxqd+3/48MoJvuv/GIpa50OzU6AjSxRFBFFNrlHmccod8xGliCICEJdl/3XEc3cSv8swrL5u2XPcxth09sWZ7NT4SJ3giknzu7Fd5PcpXAvO545ZgQn/b8RnL5zYp9ixqlxTW0bO9zJsWMDAZo2oG1DjDGImHljZK2sCpkdEfPtxBGsDqoD6BD6USCwluV2G7deG+zwlcT/HV81HiB2Du1/SVOIHaH9lGh8N753a2wwHs4we97V9v7MX3Fkiylfv9/HEkaEaVPluvoOHuyc5pC/jB3qACfLxVF8orhnQzgpIu2ytfBZABwh3lF62zg5gHJAwKofMOPFGkLGFyiNDBIgdHxJIthy+89Z2P/iFnNDTYH2A2PaeOx0a0wYpzSRY4Y6fQy184Mdw/5jdeNxzcR2qsblkfZpou4VK1eHSC1rGiCOAWFewyh0PHckAA4UAaDDcgAljx0bseYHTLluLjNYpvmqirUQhM7QIo+Oaf9H5zPG03gFPDFsdapscSq4xpQMXTo3dr4sS1iWNzASm4yrJrZSMw77Wqfw1RZAkG8RX47aMQCQSDxhx923DwXAEvC1skhg3E0M4wHGykoQUE1KSGUFn+yxMDJqrUhRDGdi/4c5g0VfgCGO4bRx2enWmDRuaWiX9/BzTRdDwkD6unXHAlHfOYYrJrZRdzzubhynZcPkd/X3v3c0Qo2J8wADKkwG4HWL3QUjn6O4ekR7TpItOEw2IxCbPhNo2ohWGOYcPltw/tLnQTgo072+/P84CSEn/T1a/ls8Mexy6+yuTDLteF1HzJQ4aE7iyHWPm4zDZ6T8nIzTl57rmJ5j6OTOzZyTfW/yuXvqm3nOzEXMOFXKSngCNKMgXjLuOMezE9YGMQDA14FvkWwaQWlzRcH+Sr9tjVDWbISLyU3Zzo5jVxRVIbJmhHbr+LP+xkiVONLfn+8gzDoe290qE91CDufUzptSB2+IszjIhCSPiHB+bRbXdblz+RCng2bfIK6ODQlFqThOyw4YhuQWir6LwKfKAaD5vXhHOFQNjZi0Gu8mmqESzZV/HbUqA7R7tBkYaf91AOVlKoaTxmWHW2Um6+EPSOQMFuRwwKzHzg9+X+Z4OqLPGHZ5s3yfV+O2xcc43l7O7bPQCDs0bcCUMxHqgBG9XfV73WJ3F5HPAg9lnQlNlhypxKNILOX3LKX6QENtj+5D228CrCnsBrjeMHA8+1+kRlfAM4btXo3dlUlmE0evR7HpvRevO2IKFG0ydN+jbadgBspyAc6wY6b3/6x5SM8TYxDHSe4GdQybalPcuO0yLp7aQrbnL7QRHY0Cx3XnYmdwtAkAeBT4IPAOjRW4u/3bOE5gVhhrolRsPBWsP/2LquOW2P/xw8D12P8e5AXPdTCuQyjCnAY4CC49R83DUBGDm6yycyQ+5hKDgkRjU8YwI6KA4XmDfkYosg4iiEk03xjEpMdMlwk2eJM8d8deqvMHeGjpeKy0alkJWm3XdU9GoY4GwOsWm3xo4wTAx4AXAz9gGV/4RRPRNtBWSyUqmckvLiKODHfyBpuB9dp/NQKug3Gc7lJzH6U4wyu7F48kDo6gOMmyazcRiIvgpVqPUBWXmnGoGCcBjaFqHDycLrgkwxTDKoXpMVK6NykATPy8+5iAIAFE3a3yrJ2XM1mpc/fcQQIbMddaXcOY02MzQAKC08DbFK6xsHNkGCj9g1rT4y1H1AttfwxiXAvifMftv8SCF9cp3YpcSoRf9leEqr1FqFqeEDPd/sm4K9cVgycGV+KVQJ4YasalblyqEtcSKuJQdzzqxsVLwOMag2uceNqHiSMFSe8Z4acj+XqMEAPxqTv34Hkudx3fTyPsBB0N2+GA/gJ30NWrOdGXWqH76yK8xyozg7S8rEycfWx5wqQv6mg+EI37UIc1PJ1Z/N89ZgR1HdQpF/x6Om60Dyzlqeb4b4gvtFUlwNLUsiuT31XFSMwmaQuXJzGTIPHzCbfChFuh5lYwYvAclwmvQt2tUnE9xAqO4+AZDzcBzLU79jBZnWDf3CG949hDeMYdHwCvW2zx4Y0TWjX8kbW61cJ/jVSmekLXsRNEHSPS8sRO+RkAiFG69D9KyOuw/wLWGKzjoI4ZNHzyrBov1xuKSi4RLSXXK57BEKrty3Fm9wWUzJ56QpwzqBhPXeMEjpiO65i1mlsNZmuTOl2daBkxpycqteiijduP7F841nTFGZohLb19eOMEruA1La/xld+ysHUc548CU9RDtduaoUj6m0wlEnc62SDEYuPRBpmUUny3hf/nU06ZSp4RIuNgXYMas24PYVhX4fpeW19fv3R7VjSIhzcJBulI3L+3HGq0pEpUddzIEXPaiDml2BNrQWfBMUanK/W2wEnXOAutMFw4vtZob6h5bKpP+g8vNVbnG6G9ac+T7Isue7J/fGVZr/zyV9YHgBQEUwZzOuImX/n/Ini6Frb0GfjY2/5NtzdDWw/VAVTcSYupOXmBjiP4FCxgRbDGEDkG6xj0DBdc6hAt17G0X5ItDqwPqCOiItISZE1hMdRoVcBWjetb9FTHhquuOFo3bsuIHHdETrZscLIZBZ0NXp1pt9YwIgsTrrc611lrLgcte/XG8/Wa868Mdtz62Yjf/zPkDTdzrm5jXbU/3DLBcR/qhp0+vClSXmNhVykbSP+lssAG30ZbW5FBjIo7o4jj5AWvjGKDSJTIgSgRvMrZznIqDpsQBEIBX9FGhLYNoq4YX2DBCAuh2lOB2kbVuFTEWTXIcSOcXI38uUhtsMGt6aTjrXjiLHnGrB7qLLcMotdO7bDXb9obPP7Nv7V7P9hBfqHKE+G2rit4y+wEHphVuC6EH7PKSxUuU0kniwxmBE81Om8tooIL7rQBkWHab7FEYomMEpp4GHJkGCn0OF8loUDHog2FjonniLQFFkSYC1TnFO1UxKhBltoanRQIJowbumJOOzBvYWEp6qzVjWu3OPWoZty1rV69fe3Mxf7a8a/rlt9YRt4kfLffzugX3LKxTlWQJSs7Ldyocb7gKcDuCCY03cRa8oLZ0o7C2aBmcOpOzAw9WrdiCSUiEiU01oZG/choOgjQF6QBLFt0CfAdxBqVJQOnVDjpY+cdJKpifIPMOcjpEF1sEDYnxdUZ8YKqOGs7TK29p7IzXAvn9eITj/F/++2sIfx7GyfYAO5q7CBeEcIlFs4zcKWBy5IZCUZgohJpbapdi0Qqq6GJwpAwUOycFXs8NHq07djTBrUGmqFwPBLWqla0otJ0kNMGltqia4FouNV6ep6tBU8Jt4fL0uH81sN877b+2/8Prqk5f/cNbQ4AAABJdEVYdGNvbW1lbnQARmlsZSBzb3VyY2U6IGh0dHA6Ly9jb21tb25zLndpa2ltZWRpYS5vcmcvd2lraS9GaWxlOlJ1YnlfbG9nby5wbmfRrEvyAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDEyLTExLTEzVDEyOjQ3OjA2KzAwOjAwhERbHAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxMi0xMS0xM1QxMjo0NzowNiswMDowMPUZ46AAAABGdEVYdHNvZnR3YXJlAEltYWdlTWFnaWNrIDYuNi45LTcgMjAxMi0wOC0xNyBRMTYgaHR0cDovL3d3dy5pbWFnZW1hZ2ljay5vcmecvblIAAAAGHRFWHRUaHVtYjo6RG9jdW1lbnQ6OlBhZ2VzADGn/7svAAAAGHRFWHRUaHVtYjo6SW1hZ2U6OmhlaWdodAA5OTYGfuckAAAAF3RFWHRUaHVtYjo6SW1hZ2U6OldpZHRoADk5NUPb5RMAAAAZdEVYdFRodW1iOjpNaW1ldHlwZQBpbWFnZS9wbmc/slZOAAAAF3RFWHRUaHVtYjo6TVRpbWUAMTM1MjgxMDgyNpOSGLMAAAASdEVYdFRodW1iOjpTaXplADE5N0tCQhlJFDQAAAAzdEVYdFRodW1iOjpVUkkAZmlsZTovLy90bXAvbG9jYWxjb3B5X2VlNzBiNTEyMjExNy0xLnBuZ6uX/8EAAAAASUVORK5CYII="},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}],"status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:39:16 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999235' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1715' + X-Envoy-Upstream-Service-Time: + - '1731' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689199033778819fa9a4a38e198461220e41ddc406f7dda7", + "object": "response", + "created_at": 1754372355, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68919903ae24819fa0e700a214b48a160e41ddc406f7dda7", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The file you've provided is a sample PDF document that contains placeholder text, commonly known as \"Lorem ipsum,\" along with some generic sentences. The content appears to be a standard example used for demonstrating formatting and layout in document templates.\n\n**Key features of this PDF:**\n- Contains a title: \"Sample PDF\"\n- Includes a brief description: \"This is a simple PDF file. Fun fun fun.\"\n- Main content consists of multiple paragraphs of Lorem ipsum text, which is pseudo-Latin used as filler text.\n- No images, charts, or other multimedia elements are present.\n- The text covers various topics for demonstration purposes, with typical placeholder structure.\n\nIf you need specific analysis, such as extracting text, summarizing content, or analyzing the structure, please let me know!" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 792, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 156, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 948 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:39:16 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_handles_multiple_pdfs.yml b/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_handles_multiple_pdfs.yml index e51742f7c..a28764d7f 100644 --- a/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_handles_multiple_pdfs.yml +++ b/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_handles_multiple_pdfs.yml @@ -311,4 +311,291 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:51:57 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Compare + these documents"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}],"status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:38:55 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149998487' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1204' + X-Envoy-Upstream-Service-Time: + - '1211' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689198ee93fc819fbab1e8554b2e8e0e0d7837304feb8e1f", + "object": "response", + "created_at": 1754372334, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689198eee844819fb89dad91ef4b851c0d7837304feb8e1f", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The two documents you've provided are identical in content. Both are titled \"Sample PDF\" and contain the same text, which includes a brief introduction, multiple paragraphs of placeholder text (\"Lorem ipsum\" and similar sentences), and identical formatting. \n\nIn summary:\n- Both documents have the same title.\n- The textual content in both is exactly the same.\n- No differences in the phrasing, structure, or formatting are apparent.\n\nIf you need a more detailed comparison (such as differences in formatting, layout, or metadata), please specify!" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 1492, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 107, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 1599 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:38:55 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Compare + these documents"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}],"status":"completed"},{"type":"message","role":"assistant","content":"The + two documents you''ve provided are identical in content. Both are titled \"Sample + PDF\" and contain the same text, which includes a brief introduction, multiple + paragraphs of placeholder text (\"Lorem ipsum\" and similar sentences), and + identical formatting. \n\nIn summary:\n- Both documents have the same title.\n- + The textual content in both is exactly the same.\n- No differences in the + phrasing, structure, or formatting are apparent.\n\nIf you need a more detailed + comparison (such as differences in formatting, layout, or metadata), please + specify!","status":"completed"},{"type":"message","role":"user","content":"go + on","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:38:57 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149998372' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1514' + X-Envoy-Upstream-Service-Time: + - '1521' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689198f028c08191bae36b834dc3652c04e8e1935d2f9f4f", + "object": "response", + "created_at": 1754372336, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689198f081408191a2a308f650711a7404e8e1935d2f9f4f", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Since the textual content of both documents is identical, the main differences could potentially lie in other aspects such as:\n\n- **Formatting and layout:** Font styles, sizes, colors, margins, or spacing.\n- **Metadata:** Information embedded in the PDF such as author, title, keywords.\n- **Images or graphics:** Presence or absence of visual elements.\n- **Annotations or comments:** Any added notes or highlights.\n- **File properties:** Creation date, modification date, file size.\n\nHowever, based solely on the textual content you've provided, there are no differences. If you can upload or specify if there are other elements or details you'd like to compare, I can assist further. Would you like me to analyze specific features beyond the text?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 1608, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 148, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 1756 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:38:57 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_understands_pdfs.yml b/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_understands_pdfs.yml index 30c1bd616..a1d96f6c0 100644 --- a/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_understands_pdfs.yml +++ b/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_understands_pdfs.yml @@ -233,4 +233,288 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:51:41 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Summarize + this document"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,JVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGdWsuS20YSvOMr+siJ8IzZDT6PXtmK8MbaIYfHu4cNHzAkNGoHCFIEMJ+737KZ1VUNUKRkjfYR4oCNRnVWVtYD/Oh+cx/dHP9d+eDW2+DOtfuPa933bzrvdp3zrtt9+v17N39YzeU/Lk6/LHAzvyznfruab9KtEQ/wsuqe//AZu4P7x6MrV+kq/l0H5+cr93hw37/1D3Pni8f3bvZ7dTg1tXv349s79/iX++kRxs656Wc29Bt9zEY2LEPaMDzMC++44eOH2Dn8r3JdtK3d/5r6wb0dWvc+/f9hfNiN5xQwHEgRsXsiBsNXZXpOScP5nP+62b+O5zvn125WH+7c/da7mcO/5dLN4qkbeG29LuTaYutm+2Mj60Na5ktc62LPOzbp0gZXqkPdf3cHR+mqDb7bHduu3vV1P9Tnu+Ie+/M5PmCnah9PsdvF9lmfzG9oSd3EHoeEN3Qx7nr3oerqphk6XA8lvyju/Rwf3le72MQu8osS5+EmNOa4j0fuYSb7BUyu91yFT/Io3H2ID9jpT/f4z+S9G4CSCZ8Aut5cA/pmOFdPsR94SvhZnrDACboBRzzJgYIeaAObfh2aphLokzU06qVuYN4q3buEdS3O9YD95Lzufonj/dRHuW2drvF4XX04AVyn2K4mPlwoIB6rhx47LXQrj6c08MvQAeigd25w8Z3S4hhbeFLP4QM+VE38OFQHOJgsIf5brK/PFWkgPq+f6x7AvhbNbVlIXE3pefpQGT/7c4UHGEM9bdodD4fj/kiu6QHLILbcFaT0kVywkwYe9RBBdkU/rPEBtNzHQ932QnU/B2FICb+cu1k6JSJSLgUeTYhDELgoJF6LCfhTLQhLuOKvoeuPsmalG2HBJqRA8mtYAi/ANnyQVfQLvA524M9X4hbmm2vcfm57eAHQ3UO05BnlGswigms9Y1nCNLoNnrdQWCyWxezNuSJwesrFHOdpqiwTNQ2nvTS83OLUTXweGtlZ+VOSGLvhDMozCMw1W9xUt/FApmFP3r+A9M1+qNu6AsuWGo+LFT50u7qpz7H7ONRYJ1uAtQx0wQnX9GGLOT6IUbYn9HzWi0Z8Gc0iqftlTAeIyhUL/52Mq7s+Pg2NUIXRxRN4Pn4fEUEHRgIg5dUN/pU4EcPWigASCoMU5+cJuS4QeJEA/qEXPZ1gcobFJJQsJmp/Z0q12w2HjnAmxaMIAbQKfKC1ajSD5yX2Fa5ZOPgNvlTFtbOt8UGsw+P/LF6ljQEJ4QpHFQm/SYEQqI+aUhjXlBQDZg0En5oK0Qm+qdmBuh5bLKOICyRLX8zOQ38WnyzNbh7l4xA7rlSmBqYvU0ijZCDlTkPzElvITGE2GN5ESQlrDkPBMNFsb4rpPcx9qc4x5SU73xz2QmGeyeGF7YqkMQOxobhE9XUZJyxvaCQowWQRX6qDPJ7aJeCscLU7Nk3cIR/tBThLISURRJpmhCo7S/JPZMm4HZY4bARzVIL3SSR5VtkfhRAYU8f3dbsH1Es9dknaMGXh0Lq0ZMpKMYmL6faSafCEOIX61inOTavL1bwQLtKBZh6p0QO4Humn/gboVjdkcoyWLMUSBpb8JIHoaSmXTAkMI1+qlDMkJcZTLsRXW/AsuRdstlvh8t+H7gScYteBDKV9Q4o18Yk1kWQsbJ5ZTKFm9QIQTC8DcTxUfS9lTr4q2V/KsAX2k5Jog4Vah+XMFHiN2ftCwwP9wJT93RdBva2W0JarKP+AY1rSPotVpuya5r67K3hucsgzPbWsgSB0wDVdXeLi71Kj0WSuYwWlgmX09lSPakBwoTTSZcysP6T6hNvNE/2YZFR6UsmI/UDRl2Mz9CfJf6wa+Jjtopjcz/oMVxkq7+vhOUqFw824lA5/GZrT0FdJWie2g/zNN9STYXtDM6e8EY7w4UscnQLHjymcaKTgiEs5keBUJ/NEHyV6E0EcQjWlBEItJ7+xluHP8+OfA2WENaIlI+ayVCMWM6kRWV5wI+8JDBMJ/tCAxtpUJFAlFD9WA131HJXLqUItYEXF3iFokcI0AG52vZQkpWJMx3+ZrejcrhugEvy7ZGsWfyfpwonjPt9W3YyBEoe83BVt1buJrhGVsMKxpVPSI+ACXAAFHlG6l3yYq3FWjry1ZJi/O1d1B6HE33kDfH+duzSuAmWoHdodtEahlNSlpLHWLDBCYrUb4Fy4hg8sYCu8YK6BL3LvJDlUSltcVDeGJbanLMLUzyez28CBxVfANcen4znJm1fDpUnscZU16BYJn/xQspFgqZsT42GrxOVFpaY4sibbD0hKuXpFO1NoEhwPKT3OC0rStkpmWGcrXSY2RhBYf+mZy38VlK22p0Fa+oL+aibiWgNAVM6MZyNhxZ91aAyLXPu9viUt0Q9eYTr2zKhQFTjYIJ3n7niWptHqJOrxRa/ujD64g5KBE1CMSRQWRT8mFQoKMhb1sd3F/dAyjE1dmMrQEQNlHLllr6AqTn2P+7sCl4Xr2OayJSOP8Q2FvRnYp2JXy57cvY1PH6bUK76qcy/Rul3BlATRfBs85h4TgTd524BoXXWKNetQy9WBrMM5nLX2gV2TxRCjBbTlAT3D5VB1HTHAPCZdlNSvQr0DQ3MVTC2Vkkzx8RjjaElaqDqjh8C1qd5AsdUbnhXtyzQY2LLSDso3gH6pKOuvpxkbsSv8pLUpLGN7VlTGbpNzDmSEXVAM0TKYIbCwUtbiapU8DoYUWo4aSlisAm24+9yhsCzbqI8IXwpUSzZ+DfzHyUzuHzyplAlLl0yetYeXnwagA7dRi9LoC4ayhSusI/B86mRaguWf10EdKF62nAv0Q1dgWgbNIsgmElMlTMoYAWpnoP0XrbJXogUimkZznCDJIShHWhNaJg0SgJYALCrv0YIC63qHSs1anMA0dP5wbHfSZNhoy9OuCgtdlgAOWmR4SKlQvgX2tKMOaXOKuODEZQIssbYajVy36c9umOT7gqPgm5PaT4AFOlfAjpVcKvmR75gh6wFHyL0G5wzP5+ol7hmnlgECRVoWGigla6OR0JxQJKxxXimaGHs1dk6SyWSOLQycXJinNKKDwEQsmEUtAQ0IiW5KqmFHXGEBSJ+K/0QhbKwT2JXl2S0glJQulbfWu9/AULjRgNQJtcL44NL0xk0bOfjdpuBf56f1jQD4ub1zpnosaA/VgLaKlFJ98ATqUvdSGY+RB+GWXG/84+xbelIS1eKBfs/Fz73lKiq0OFmWYTOG4Eh8IwN5Ly218V5amYvCQbnAjMEIKay98SSB5tIcnOyI/qBrdaIrxYMOr2kSvU0Tpf5CMLx2WL1AZWE+zNP/iXSQJiw+wDhgZCMAT6JZPYIS0SJEBh7tkTmQTBd5ITI6kcUsRS8yD1ZYNf37VO9ZRuQsxWjToaPtLyOEGtWrRxaQ3bnIEqfJH/HQ1w9AVBAi1qiq+Zk5zspGHbUiQHGLNX5Y9EqpXmK2aCCmQECtn+Y+OFBOfTzFj0foJ9ARFiGEqdQN3lG0kXCAumIi/m1rzjgLdva85CkyUiHBUl6QG6X0IQNUCoi1tvLYzYSEDSvBvStGp1CHtN6w5I898FYpT3ViGlKKVOD5fDzqPGybw4mKLvnaZIxhlcddajgfPlHyL4J7sx9Y3hq9ynFczjZESep9GJDQWhVajpFRCplnU/wWL1wwahmbYThApwA2kGWLxQISZ01tPafVuDYOSfgXn8P3C2nyqA7wlCEbfmGBTRA8g1ymKXCpmbOFORYZCWGxncqRluZ4C6S5DuVtAu/Dtkin+SKmN2uLJYhihJWoL0BYSVj2Lg4dlZtRVg1RvhbRaLRZB8faMtMiAxWRNToeiy4bnNp5qVcnNGx9lJ7N6CmjAakq0Bqp/+jZPNW7K0h2wUZCu+ZYMU/WKEW5ZoUlmRRzbGajXTXFZpFpqq2l9ZHpw2xkSSoU+QpQi8u6YgnRvgCVL1InrYIhyUdYJmZPzYMtMWGS2l9Vk5VsTm25IZCacvKm07pD5oZxFGNDSI5epsWtHZGtTGqOc+ZhuTVpxICHRq/0wuPozNjAGkx0bHqm1P6g+zEnilof2xHJr63Qlsh6V0hqS4faEPuPE478Jktf/WnzgiNYBg4Mwk+n4TbYlc5rzGSFsYcvfNIYERslH0ntnCYlBhy6wdSgkEGKRSDuqPzT5Fbek+r9vCsPAS6FfRy/ahz5LRnASfw3TAyXt+avNyeGkrA1//AM5jpaZ12aZ7KGE8GRasyg8iaN4aadBQfkFTIbRt3puCRl6kxkVbrIactEHg1H3jwpOtBH5QKIjvqlqncYvMjYXYnJTMaAyfNFXE9J4cIAGQ6/vipa3hq58p2PU7126f2H+BjvPx6c5HXHwuzBYUbtpi9YHGpOlyyRMg1Af77AuJkDV5gJXQXEL8fzE1+mqGRIQaoDVnFYcU/N5rQPcqnBT/xHtiOBGd1wBwsQ1VnOVZKgAGJqEzWKjp3UbHx/iDXSyowVIIVWRrULoxJDJE8vFyZOzMlTRmbpZxgx+/GBukUajrDOx0WrnJj96gHBqXQTlqZ3SaPgyK+DvqIlXMGuK3zHw9l4LIwRDB8aRSXgdeCV8ES9wFFqemum6qEjnmcZc+n4Ck2twIVjWe3q2RbYMHWFKkaQZzrYx2eMOfDDH6y2bCtlCZKf/VhhKkMcqrxJr+bS7xfYs8CY7riLguT4SOCMsebxm16grZBTr6DDKy2MSTElga32uwjCJW41XSZEh4qHyifCb1lwEW/DiIh6n0nuVJ0hJRiuif4k5vH1IBibKyweEhqxg2ZypLjU3yex0DtHvIrHG3puaxNN8gwvRulHlRTPLv0qTwi9YBeQyxW9WsYfxKTeDEaLn7ABGo8v8u92fEMsr0C0hkXs2qff9Vhu5aM7/ekQOjTTAP7kJpUNOCk+i1EEkjNynbJq1YMa2ISDEiu1bcUJltHaszyFlAFiA4gzuAxCho1jbKW/3SuvGTUF7gZgbKHsyWT7kZLtQH+OxR7sNMPxOGlSXi/gq1uTXJEVTFD0OHxzC2WGdVZHeZYWk3FUFhuSBmEmLxXzK/stFOjTH6mkOl9mMdorU87waxoyVaiEeSTgng4Xk0/lZ1xa9tsYjp3ZZHSg/uI7I3kvBVU3qFi2WCvBOE8IimP/5gXuzf5gjX7D+KiTHY5hAZVNcH77P6d6b9EKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjM4NjYKZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAzIDAgUiAvUmVzb3VyY2VzIDYgMCBSIC9Db250ZW50cyA0IDAgUiAvTWVkaWFCb3ggWzAgMCA2MTIgNzkyXQo+PgplbmRvYmoKNiAwIG9iago8PCAvUHJvY1NldCBbIC9QREYgL1RleHQgXSAvQ29sb3JTcGFjZSA8PCAvQ3MxIDcgMCBSID4+IC9Gb250IDw8IC9GMS4wIDggMCBSCi9GMy4wIDEwIDAgUiAvRjIuMCA5IDAgUiA+PiA+PgplbmRvYmoKMTEgMCBvYmoKPDwgL0xlbmd0aCAxMiAwIFIgL04gMSAvQWx0ZXJuYXRlIC9EZXZpY2VHcmF5IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AYVST0gUURz+zTYShIhBhXiIdwoJlSmsrKDadnVZlW1bldKiGGffuqOzM9Ob2TXFkwRdojx1D6JjdOzQoZuXosCsS9cgqSAIPHXo+83s6iiEb3k73/v9/X7fe0RtnabvOylBVHNDlSulp25OTYuDHylFHdROWKYV+OlicYyx67mSv7vX1mfS2LLex7V2+/Y9tZVlYCHqLba3EPohkWYAH5mfKGWAs8Adlq/YPgE8WA6sGvAjogMPmrkw09GcdKWyLZFT5qIoKq9iO0mu+/m5xr6LtYmD/lyPZtaOvbPqqtFM1LT3RKG8D65EGc9fVPZsNRSnDeOcSEMaKfKu1d8rTMcRkSsQSgZSNWS5n2pOnXXgdRi7XbqT4/j2EKU+yWCoibXpspkdhX0AdirL7BDwBejxsmIP54F7Yf9bUcOTwCdhP2SHedatH/YXrlPge4Q9NeDOFK7F8dqKH14tAUP3VCNojHNNxNPXOXOkiO8x1BmY90Y5pgsxd5aqEzeAO2EfWapmCrFd+67qJe57AnfT4zvRmzkLXKAcSXKxFdkU0DwJWBR9i7BJDjw+zh5V4HeomMAcuYnczSj3HtURG2ejUoFWeo1Xxk/jufHF+GVsGM+Afqx213t8/+njFXXXtj48+Y163DmuvZ0bVWFWcWUL3f/HMoSP2Sc5psHToVlYa9h25A+azEywDCjEfwU+l/qSE1Xc1e7tuEUSzFA+LGwluktUbinU6j2DSqwcK9gAdnCSxCxaHLhTa7o5eHfYInpt+U1XsuuG/vr2evva8h5tyqgpKBPNs0RmlLFbo+TdeNv9ZpERnzg6vue9ilrJ/klFED+FOVoq8hRV9FZQ1sRvZw5+G7Z+XD+l5/VB/TwJPa2f0a/ooxG+DHRJz8JzUR+jSfCwaSHiEqCKgzPUTlRjjQPiKfHytFtkkf0PQBn9ZgplbmRzdHJlYW0KZW5kb2JqCjEyIDAgb2JqCjcwNAplbmRvYmoKNyAwIG9iagpbIC9JQ0NCYXNlZCAxMSAwIFIgXQplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFswIDAgNjEyIDc5Ml0gL0NvdW50IDEgL0tpZHMgWyAyIDAgUiBdID4+CmVuZG9iagoxMyAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgPj4KZW5kb2JqCjE0IDAgb2JqCjw8IC9MZW5ndGggMTUgMCBSIC9MZW5ndGgxIDM0MzIgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBrVZtaFvXGT7nXFmSpUiW5CsplmxZ17JuZEnWpyXZqT9kx7LlOHP8UTu6hiR2/J3Zq5e6IYFu9cI2Mv3o8qulsB8lHYVC6bRBg2r2I4x90LIfhnU/tmQshRXGGKM/kg3GbO05V7JZhymFTeLRed/3nPPe9zznfd8rQgkhp8guEUh2aWtxm7xInsHya6C8dHPHS0R8Cf02dM3q9tpWyDL6C+h3CWHvr23eXo2+bqlgKkuI7un6yuLyXzt9F+GwC+vT6zBof8X+AX0Tevv61s4t+6v0Q+j3oIc3X1ha1McMq9B/Cv301uKtbeYXRqB/DN37tcWtlX/95GMr9KfQ49svvLhD3qI3CDEFoHdv31jZ3iaGOegL0PUAxZd/ThEteRejl0zVLKr5f/ph2C2c4EGj2upOmDkyaWuC7sigjnpSr44GznEZfIyXSf1k4ceUvqqUaeU7ZTLc8gHWCFevdJYJDXu9uY3hEl2AwsIwBCVIQtg7UhL8I9MFn+Iteotjy0XviHd9cbmk8asjJlaKStRbIjOFDfw+X5BKWcV9LK4oyln40XA/2ILlRQUertc8YFRN0QMsqguPe0uCPFmYKpR2h92l7LDiliRvrvRwslB6OOyWFAWrtMeRIuJvbJyuxaxDzNog5vVVLzPwARdKsch9QmOyVHpYLLqLOIlq8UllSmoGnJSvEfy5Ms1OFvhU1ie5ucEn+STEoQzDd314fKaQQyQSj8TwxZQajwPF2lMIz6hSavo/UWr+MpQ2fClKLceRfo5SK2K2cEptJ1Pq+wJCjxnOnsDwbpXh3RMYbvwPhnn6MpJA2f0MxSEQHTESZEkU6RSNxf2SVfJbJSvdO9ylu4e36D09/Ux/iB3VfWlsXmAfoVabyFaZuKN7KFUTEULIbQt0QHxcJrrHg3Xk9/D9F4BdHnSjJHTYoiMdQA8wBijABnAb+B7wBvAO8AHwIWC6jMjMiIwisow1mfAwu2hmPgFiP0t1RZjv/CfptelEfPbrA08eDd660p25tJUS2X3PV+4sz70y08EeHKQDs3cXNopTEg5ACeKnf0P89aSVR645jly7X2OB4nk6PK/RKqUkaxK/5+kPD/MifZl+k3aLB2l6Hc2Vc8i5iKlcOMlLZdIELswgk3NhBg9kHzaMOvBhq/JhAx+2Iz5s4MMGPmzgwwY+bODDBj5s4MMGPmzgwwY+bODDBj5sVT4I4jviBNGpRMg+yYp4Ew6VnvNUSMz0tt1YO/yjSE3Li55UPkhzTfGx6OI1hK/Qy/OzwWynk/MhVT5jKfaI9JGZPdKK1sujb7VwbpActVttxSmMOI2RXwVkO2R7TQ7idHy+CyOfG3gMHv2Y7AGHNBkRfG1m3JqHOT2CGl1bhKV8Wg87usIzESHV1Q/Vw1ijKATOKanQpZFwMDcX6lDGoh1DM8GeqzlZpB3ja32R+Xz4zJCSiBRyoeDgpD/2fJ+fsd6ZpNMWHE11DZ5xGAyN/oF0ZCjY2NStZIcX+prt0Xyyeyhw2mQU28/GYgNygxgd5/fnqDyjnzIziZMR8voeKGhUT9z3udPvkQBv52AigNPVA8371TGxj7TWYpsDkIE0MALMAavATeC7wGvA28AD4JeA6TKK47cQPgXY5arnPOfNAd40SKNm+NRYbT3IwmQ/Pcp7nRkMOjhvmSSE52jKTCM0Za1yXHfMble/NpMW6+ankr2temf8QsqbTbRemQgMp3x6Jjk8Bqd4ijZH+tpio3EXLbhTE4lgT3uDK9zTO5AOGuhS/qI7mHC2tDbUCcwknY3lcvb2SNO5FrtIaZ25gY4Gu31mV2RAuSrnM212KeToSLYYNUzfYOa8NlWe0j+AVzdYGdhDHvGa4BnVfJxRjeCwEYdtBp8iZBEygdzCq7CNK4CRV72URpXXUiiTSGd8ZupDCvmlfoHz0knfY02ZS72h6X7ZlZ7tLdwyiqavTmUuxJz0jcNVoS0zFkxcSLoOUtcuRNpzy9mepbEAXZqfnZWHlHx6rs/rz84itAzCHEctC8S5p/5h4DcuWBAN7wdE7QdJa0ZkHx2ksQwfdQ/7DbOQGKns4adaLzGcguFEfDTxqt9He3wCoAvWkTchlKpKIzaYiAXwAjEgC0wCC8A2sAvUIz0sKC0Xd/UmcWG3q+pqH8KTqsJdueDKBVcuuHLBlQuuXHDlgisXXLlUVy1wZUFkfkToR6LJeIQFiVaNNwJrBMdtwYoEz0d+dt5r3IAesKtbKNFjyx6JggMu8V6ZtNZq2P5fIr89rc4XoTpcos6XyojOUL8cSnuMoiPY6w9mJJNokfujvYUGZprq9aTCHh1j7OCQ+kITz/maY9n2wwd0pH0w0XI63C8fvkeng7l481C6Z5DZ5YTnFZwdOZepTNK/I+dOkyB5p0zCCNRBnGq+OXAa3ov5yG+G4SBhyAZwwW1H+cdlXtsGjHK1X8vo1/JRv5bRr2X0axn9Wka/ltGvZfRrGf1aRr+W0a9l9GsZ/VpGvwa3/P3FM1lCOPwNKqm82WtSLO60Jj0o79q7rEqQz5ppk486Iq/pcWa7Pp2azrR4eqaSZ851yQYm/unKjebURDwxHm9yxsZLNDsyGzp/LX32Wj7gDPa03TuYKH/rdmJ+OBDIKYlOZbST56sK4XeDr11t6H1GrcKfYSE///526/HoqEwiox9Br1fj5RPYJ7xVCRG3ZvXwR5V5zSXVE585+hjpU5KgDlzDXZKmn5A06weWiATZgbkmcodkBAPJsCa1zprRCF4m96mG3mERdpfdF9aFf6pejWQTz20Dqv838KKF+D7mqtHbas/W4lVFJoZm83NzofzK5s2VnY2lxYmVl1Y6Zzd3bixe2Fhb3+HRVb2Qyg/4/50TPkbYBHIGl5pE9x4meXIRZTODHED1k9C/AesArfoKZW5kc3RyZWFtCmVuZG9iagoxNSAwIG9iagoyMTc2CmVuZG9iagoxNiAwIG9iago8PCAvVHlwZSAvRm9udERlc2NyaXB0b3IgL0FzY2VudCA5MzEgL0NhcEhlaWdodCA3MjMgL0Rlc2NlbnQgLTIxMyAvRmxhZ3MgMzIKL0ZvbnRCQm94IFstMzM3IC0yMTkgMTExMSA5MzFdIC9Gb250TmFtZSAvTkJVSFZWK0hlbHZldGljYU5ldWUtVWx0cmFMaWdodAovSXRhbGljQW5nbGUgMCAvU3RlbVYgMjAgL0xlYWRpbmcgMjcgL01heFdpZHRoIDExMjYgL1N0ZW1IIDIwIC9YSGVpZ2h0IDUyMAovRm9udEZpbGUyIDE0IDAgUiA+PgplbmRvYmoKMTcgMCBvYmoKWyAyNzggMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDY0OCAwIDQ4MSAwIDAgMCAwIDAgMCAwIDAgMCA1NzQgMCAwIDYxMSAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDQ4MSAwCjAgMCA1MDAgMCAwIDAgMCAwIDAgMTMwIDc3OCAwIDAgNTM3IF0KZW5kb2JqCjggMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvTkJVSFZWK0hlbHZldGljYU5ldWUtVWx0cmFMaWdodAovRm9udERlc2NyaXB0b3IgMTYgMCBSIC9XaWR0aHMgMTcgMCBSIC9GaXJzdENoYXIgMzIgL0xhc3RDaGFyIDExMiAvRW5jb2RpbmcKL01hY1JvbWFuRW5jb2RpbmcgPj4KZW5kb2JqCjE4IDAgb2JqCjw8IC9MZW5ndGggMTkgMCBSIC9MZW5ndGgxIDgzMzIgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBrVl7bFvXeT/nXJKSSPElihSpy6cokuJDEiWKD4kSKdqULEuyLT9iiY5fsiLHcu1EecxIgBZ1gS5DhS1pi+7VbkuWJluTIo2bwoUiDImXdU0bbKtXrMUaGEaLokPQDmgWtAuWxNR+3728spw4Qf4IiY/3nHPvPef7vvP7XoeMM8Za2UUmsfGl84ur/BviCEb+BfS9pQsPBlk7vox/EX3d6dW7zydtu/4Z/a8wJi7ffe7h08433k3h1ixjnYUzy4t3/XcqnGbM/3k8nzuDAcNPJDP6/4B+95nzDz40/VXDv6H/c/T/4ty9S4v3/fRTbzAWeAj9vecXH1oV49Ih9H+AfvCexfPLQzv3PIs+nmGp1XsfeFC3R/enuAWe2D2r9y+vrjLjYfRpvWYQx5c+rczA1nENsvnGiDJ8y49AT7pl5MM6OtzQY8YmZQ3GWpQHjcyEdRiDfPhYQFZmU9rv/7GzNuaAHp3MxTqYm3lYJx6RmZf5mJ8FwGWIdbEw62YR0jcYT82ss5a5hW9z/mhtnW/+4Tqr+l7EutKJ473rjKeCwYmV6iV+Eh2RwkAihJaUCk5ekiKTBxbCteBacG33XWvByeCZxbsu6SLKFTeW12r9wUvs4MIKfg8thC6N1+St5nKtNoJ5dDQPXsHjazXMcLYxA67KUP8NPKRPzQQvSdG5hf0Lly5W5Uvj1ZocCgUnLl2ZW7h0pSqHajU8ZdjiFBx/ZsXd4LkJPBsSuN+sznIQc2CK2toazYmeiIYuXVlbk9cgiTISDq1z1hiApPSMFJlY5+NzC3RrPBySaSAcCofAR62KuVtSMwcXJsBJiDgxfrRKTVuM4tlWsGdSVGr+hFRq+TgqtX4sldq2OL1FpXbwbCOVtt1epeGPUOiWhsdvo+GLqoYv3kbDjm0aJswLNggTfAWGJcFWTLBAfT/g1J8eiITsoYg9ZOcb9Yv8Yv0h/sVm/mZzHW/Qh7Njmw+xy+wsrCiwoQxISaDaBoBcBfVjphbMxDBTPuzMuCyiyVmSspcPJbi+ta3VFXKZzp41+WSXLmnwRpIuZYpF/NKcEpM3FCegzsk2FKunjmRLDxR5Nrx46NBZPMzE5jv4+Yx4DXwZYZ94QuGfWCC2DIzeYnhLFhLP5EMdGf7cY2vP1X8xdZhPzO+uv8Hd/J76l/kLN3LXr2MafDiLbr4lnhA/Y3F2fgOmblImCdoqMuYLwiMEWRSUA02CDoNOgy6AHgH9GejvQN8FfR9kPlbRs5+g8SuQOAZpZHgd4ku2bWDGiNI2gEee6ZPCXRbhbPeLzGBJ5MMW9PtEdqiEvl+IA9Wm7L7FzKHPHkok8FO+ezbdVNV3j8wN7jpdCQQqp3fFdhXj/K3C4aJ/7O5HpqcfOT3WM312R/pgqTtXu2+kuFrLdaQqtO9T+PkjCNwMH/eZddYBdRkhPLFlxC52gPTXANBrYP518PtrkDgGFbSg4QHFQcOg3aAaaAX0MOgLoL8EPQN6EfRDkJmkboFmafoWSM2wmLYzDnumxLND0ZhkJyGd7RYRnnr7608//fXvfGnPvVNdXVP37hGv3cjpnn/hhed1N1bF4dDU/XNz90+FaK9IjhHIYWIZWkKVoAXc665iTZ2yJq0HT6wgYQMS65V2MzTusIeyALpCU/yt+gH+aP1+/gwtN8I7R7gY0dYwY40WBi01NdZowhriKhDHFaQ1bc0PzClt2lHIps1e5Yfrz/LP0dT8kDozzb0H030Jc0usYzvMlXlV+6E59lTpPTyGjyqzFx092Z6+wY/ehneIQVVmKGBLvin+H/VVRSaBtIADtUy8i/ctbH77mhtQYrPCuglbREHSZG8bbnBCfkG1aHjaxioMt0mfnKktc6Olyp1x4AvewyY+WRW/H/+dqN71v28rcqzc+HNB9NqNR8X9qky7wNPD4MnEZm7liUI4bR3puxlkvAoi/8LBEXHFQE23cGS8lQ8OHuxhvqsq+BOzVVE/qfBw9MZTuD4ljtL6qj3UsH4z4v0X1pkHE/IGaMireUBtsAe9ag962INeswc97EEPe9DDHvSwBz3sQQ970MMe9LAHPexBD3vQwx70sAc97EH1lSbCjxFL3WobrQ0sKXocdDnbDWEORZJLyA71ifAf/3rXwsKu+o+r/5feW/D7C3vT/BzvnpqenuLHga5BOTubTs9mZdrrEHzZAfiyCvtbMgMywQ0kLl3KEmHsc4ESGWzkOiv0K7ZegGwFTbYCZCtAtgJkK0C2AmQrQLYCZCtAtgJkK0C2AmQrQLaCIpv52gbrbWzCOuvFBrmhOzN0uPMarHKs4ZfHsHwPMira3h6gNR82KI5PR1L28z5Jc3wdGRK74RkD3C8pTgKe8UxVis+eK5ePjIUdel9mZ/Rbrpjf7h+ohKMT2ZCoJqdOZmdO5tvlVDHwuGcoKUeHd3gHDpe7f7Pj+KivI9LX29OaKiV9xqTe1hnx9ORCVmd8LJ4/WPAmS5OdiZEed3PM4PCn/LF82OZITSsqrECn54AVD5mbB0MkgAfCtMJqqN2q2iIaeMDRkNah2GPDtWcBSXJ05N3tlcDOlemZlZ2Bqje3d3Bgbw7GXc/nl6aTyemlPP9hfbI0n/d48vMljj3kSsw7gvWbsLhqB2QDEtYyNJSeHkC042EpLBl48z7eMvVf4g0F9a/d+Jz4LOE9uPkWrwsHy2JT/34D8HAonFcgRaqB+5Qa8SqIeBVEvAoiXgW+o4KIV0HEqyDiVRDxKoh4FUS8CiJeBRGvokW8CiJeBUAi3DlYRcEYMcqBBfLQ/qsg9KmdQzuF6wzhYxQZN6lxFMwMwJ9Re4C0h0ChhYgmC0DQCJMZpZHLZw3hrqy9ARW9hhECUb7E87mymB31DkScpnZ/e2ZpX1ruL3dH88mwXehtPrfZbmoxRbpy1a7e6XyQ7/EN7Oh2JYKO3sk7esxdBn66PNzijgednVaDMJiDY7nYcMRu6Yx52kNusxBZXZS3DVW6ze2JHQ8fiI4mXBY54o7GXaYmYTRBA9D5KHDjxr65oeLn1lkfNszdQI8bsgvoQJCtoK1DW4d2H9qt0BeNuTDmwlgr2h7VD3lgqx7NVj1oemCrHtiqB9vqga16YKse2KoHtuqBrXpgqx7Yqge26lFslWYOkx8iMPuBKdK2H5q3wzapbVdwm8lm/FB+wwPBFJvCdq4huJGfjI4I11K5OD/i9Y7MF72FdMQo+HFHfLx3cCLpcCQnBnvH4w7C4ancSHJmCRCfSVl8CS/vqRd69pVisdK+nsaVXFUXMPobYDRMeZi3gUqvikovUOkFKr1ApReo9AKVXqDSC1R6gUovUOkFKr1ApReo9Gqo9AKVXqgMOOtABCQJOyCtDhUdtSlqIg/jmrfJDOZuTcNc/Btl0wMHi3eWgsHSncWFVXNZ6uwZ8vVWezs68FOe5KdqC6nppUIBBrxyPJiLuaKlffH4vlJ0h4oDyi8FcNDJ+tjL66wfiueABy1PsUaAtP3vR9tyFYR9p3E32m48j01nXLEoGu3EaCeesKAtX1PyVBn6kaEfGfqRoR8Z+pGhHxn6kaEfGfqRoR8Z+pGhH1nTjwz9yNCPul6EkEEZTqLhIBLQVQsSWWK2BboKUWx9X9qacfIGIjQbFKIsjJF03rcFjuHBmFHU//qD4Kj/pzfhs6RUdCRtvoTnFBfvB4dQsPEmsGGEjCcoc3EpLFHmQiU+sUd2YgJxaIfaflzJ3zC0A2gH+oGBLghLD3cpiFfrBTvaHFOqGwI8hEoS+R19KHczDKnAAE76BH++/oLOkxiNwew76t/hfyLc+YXSWK0gy4Xa2KlPtZeteyd6xxMOHg3vzAQCmR213Mr+wf49pzKwgOTJhdGp6MhuwgaHBwcGgA1Zzc3aFSYkcNwOot2ndiftCqUo1kZyZFU4VsVWijA8ZMLDJohLfSfaJHbHVUiTDatx1dWRVXHu4yjRkGBw6bQweztNLrPVbYkOeI0LC2X+o2yvs1u2SSInhKunEOrP1gf4j8Ar7UGG0x4kWIn90zorfwSOy1h8O45VX6aa4E0ck3yE4bSK4TQ2NY39TQPDaWA4DQyngeE0MJwGhtPAcBoYTgPDaWA4rWE4DQyntzA8QpUA2QLtJ9VcLYh61KZKJNnAdRJYjtjDzluwnMtnKPnCFsfCfkCgJGIUsLeBm79ZFi2hRMZXmC8GOocXSsN3uMTehc7BuE9flmLF6Vh5Puf5VWo80e5IjPf2lnvanIlSgr9ec0Z9tviuE9n84lR8JD15/C6TO+aLF6NtXeNHp8PD07GePaORaGk2GpseDqvYKAIbVKR2sv0byoEUCdEJIVBhKQLZoLtOEEUSuqreQvHtZMXkRjZQ76kJtRMveoA4yt3VjF1FuRNIUGKoAS6+WOYdYCqa8beW21K7c/mjbfBcSDJ7o5V+2Z0YDtVf4rN90xnvcD8PABNjYPXT4JHOE2LbM3kVgOTXCMEGQrCavWNtZybbhFXHyuWyeG15+fs33hM61Pa/3NzRmMvJdn74XO1a9GqGPZBKqEzQ0G9FuxWLtuIkQl0HG2qIxpyDLiWa0aLtkaa2ZpPTFEp6WtT1XwomOedDoiM25BMZssubcn1UnTYG/m/WaaMwSD3so4f9+63cm69VJPYyNo0fQ+MxrfFbtaFX9hMHBxTYJTanjFIpjg2lF3+LrKHxYqPxsjpCL7rhm93ai3SbIgKdYpiZTYkXpP0oFBIFFGLYLEkZlTGauKb4ekKJ6l3CDaSEcZN0Sl6E2j54EapKNTvQmi4FOuEuQxP5FcAnO1puixR7/AmPqWwO5uLVXPmbmSMdloOZ8n6PJHQ33uPB+ETG1x7u76w/ybu7dw4Fdo7Xn+bHLw9m4GDT82CQMxX3DkAeKOgknj8u7j+I+Q9Deva2SCcOb4P0GnhQ/N9bwoj9dUCRr6KEgdrioDA26pOrE3ugcA8U78HMVtUvWuEXrfBnVvhFK/yiFX7RCr9ohV+0wi9a4Ret8ItW+EUr/KJV84tW+EUrwAF/aESuR2o0wgvQ2Ty12+EDuXYE03B0+W3nUVSWcZeW6GhXLRNqXPl1LdvRrlktGUI1Q0kR/n6gXHgHcmEHsJpi31RzYfJyxAZBjDwYXbU8iPJgC/RKYzdjB2tUrhQzPqmMWLEBqtrU7NcB/fgbqacf+iHcZ9RYoNTiCsw/kAgr2U7Bq2U75SWX4EtarmNPTA4pibDuRokHvQmvRcuFi7lT9bqW66TmRruREENXUehKQFeUL15W80X8e6PoioK65vGpdqC2prPtuePNaKBG2E8uS6SZlSyR6oebmeH2jDE9oH9/ZEVJhnxDcyCNOkLgJM8YGxze0psvTyVE/UlNc1oJ8ZJ45VRn3G/TskQLlFj/Ob+iqW5bDQEfzIvCgkwf7NGfR4QwCTybr4LUcyTiW42JVIoy3KBz64aH68hGVU/mzUwmJ5fdQnFbjvjEoCzKUrX8MOaEjwqgVnkFe1RkzxBgAso6VEYhwCptjrYJ437F39IRmnLorfRc6smLC9Wci3w3nbK6EJxdqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcMPJ1FoONUM47iGsM1zGqp+XGcY963pxX2Hn/efPNU5Uocp2tSm/7KQy/ryz8mZ2xrolC2BUbCux3xoMOOTHQUb5DV26+787u6WK0M56VD9miQaerO+mU0xEXP490p93WVYiFegPO5ja9xRnoQGVsrIyfOGyLFBNdg11OnUNnbvc5PV3OFrM3qeizafNd3iIeh1gPfLA6MmCLaA+bcKX6xwVpaT8p1XVoFYutccZsg+J1OHSjjdfhAdpfOuJWAYC4iraWmurRbqfolkUmiJzYgCQhl8G5Qh/P2jPZJ8pHjvDBssVrkeUu+4rQfe1r2frjOwZEVhLhAD+aVbFQBBauI4NxU55280zog3Lc9GTbq7mtrI2iF50gNTdyVDqxpnpLMZdojFp0AkJZKr9ebouOxGfGRLk9OTEwcsIDnNb/JzYzEp6a5HP1b/dNDcr5oWOKbvEfDv9X8PdR50cyzzjo/Ei8uvMfK0+IJwn1mLHI8Wcy4V2hi0+88/YJ6+jvuV2i/3vZ9x5bDWhXZG8ZZD8/Q78FPkz94D3p1c0k8+lO1Z/ZrOkmlJkaN5VLlP+ODXKYBugYaFFc2HxHXGFR8RybEvtBHpz5X2d76CrhPAr3dokLGL/AQnimIvbj+SYWFCU2imsXrlG6cokZRAp9D2z0ReRzL27+kq6YY5TGlHv0Dp7nRTbKf8ECvIc10T3UOySBF99JdpKtsff4Sf5lfoW/zt8RVfF58ab0Vel16T3dd/V79RuGo4YfNPmbftrc07y3+SvN32o50PI3xlHjj02rpqdaZ1ufbX3H7MVspMMo+zRmDoJUDSESo3kZ91QNtzX0Y6C0Z+/c3L4KjjSXz11YfnBlaXHv8h8s986u3H3mwcbbbPOv6P+823yiGJMQ+u34xzqKbKUHjiXF+lEkDbAMy+HYdphV2QSk2wXt7mbTbIbN4r+Jfcg+97MD7CA7xO5AljHPFhiSHxgQjIkl/x9NC1daCmVuZHN0cmVhbQplbmRvYmoKMTkgMCBvYmoKNDkxMAplbmRvYmoKMjAgMCBvYmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgOTY3IC9DYXBIZWlnaHQgNzIyIC9EZXNjZW50IC0yMTMgL0ZsYWdzIDMyCi9Gb250QkJveCBbLTM0MyAtMjE0IDEwOTMgOTY3XSAvRm9udE5hbWUgL05QUE9BRCtIZWx2ZXRpY2FOZXVlLUxpZ2h0IC9JdGFsaWNBbmdsZQowIC9TdGVtViA2OCAvTGVhZGluZyAyOSAvTWF4V2lkdGggMTEyMiAvU3RlbUggNTggL1hIZWlnaHQgNTI0IC9Gb250RmlsZTIgMTggMCBSCj4+CmVuZG9iagoyMSAwIG9iagpbIDI3OCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwCjYzMCAwIDcwNCA2ODUgNTkzIDUzNyAwIDAgMjIyIDAgMCA1MzcgODMzIDcwNCAwIDYzMCAwIDAgNjMwIDAgNjg1IDU5MyAwIDAKMCAwIDAgMCAwIDAgMCAwIDUxOSA1NzQgNTE5IDU3NCA1MTkgMjU5IDU1NiA1MzcgMTg1IDE4NSAwIDE4NSA4MzMgNTM3IDU1Ngo1NzQgNTc0IDMxNSA0ODEgMjk2IDUzNyA0NjMgXQplbmRvYmoKMTAgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvTlBQT0FEK0hlbHZldGljYU5ldWUtTGlnaHQgL0ZvbnREZXNjcmlwdG9yCjIwIDAgUiAvV2lkdGhzIDIxIDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAxMTggL0VuY29kaW5nIC9NYWNSb21hbkVuY29kaW5nCj4+CmVuZG9iagoyMiAwIG9iago8PCAvTGVuZ3RoIDIzIDAgUiAvTGVuZ3RoMSA1MDU2IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AbVYa2xb1R0/517b1zfX1/EjfsWP+MaPWyd2Hr6NnYRgO5HTpkmA0KatzUhp1uZVWpptoTwmRAVj0jJpRQixFdCExDTgw1imqVvI9qGaNrR1ExQhBtr6YZs2aUNoQojXBLX3O/fagW6F8WHY+t97zrnnnvP//37/x7EJJYTYyGnCk9KRE/Orvc6BKYz8jhDqOnJqLUra8CX0TxgzLa4uneh27P4V+n8lhDu3dPyuxfmB92J49Dgh8sbywvzRNyKxPkJc05ifW8aAMGd5Df2voR9fPrF2Z+xucjf6T6M/ffzkkfngWuRh9N9Gf8eJ+TtXuR5+PyHuEPrR2+ZPLLzm+3UE/RH0s6snv7JGf8+9gf4q+hOrX15YXSUtB9DfRN8Kofiyjw1Ni9761IsxuTmFazauuPPEtN03o3XFsgIGrCJpkbClbCethDiIc3v659xwfZb1wR/ASU9tEnGm8iNKv1XdpPUHNkk5/BwRCX/LocwmoelodHylvEEPo8OlMdCloMWno7s2+MSuvZVYNboeXd9zdD26K7o8f3TDlNDveLCwXu2NbpB9lRVcZyvKRqka3G4uVKvDWMfE1sErmL5exQrHGivgrg/1XsYkc3oqusEnZyo3VjZOl4MbpXI1qCjR8Y3zM5WN8+WgUq1ilmVbU2h8z4q/obMAnS1deG41VtmHNbBEdX2drYkel1Q2zq+vB9dhiT4SUzYpaQzAUjaHT4xv0tJMhT0qxZQgG4gpMQV6VMtYW0xP7auMQxOFadLy6ZBK24pirg3qSTqk8v8JUvtngbT1M0Hq2Nb0Ckid0NnBIHVdHdLYpwC6jXDpKgifNhA+fRWE3R9DmPk2R7KI418gLnkiEInAS3rhTr19/QnFqSScipNu1U7T07U76YNW+qa1hjfYhxIfrveTY3ivlWzhihW6QbOjr/8amo/5Zv37j2GMIwho7hHuAvKFl3xpC5s49YmCY9RM/oDO6xBubjSIUHGSACQFGYLsgVQhK5C7IN+AnIU8A3kO8huIPLdJ/JewvwyN2P6yYwu72vU2gS5uXskWuIGdPVyMurWsp83OqU88RlsOP3QkGywtX1e7eN+Tryb33lvlLlzO7brjsdnRlanU5VXuwKuT37y1xHId038J+oukA+jQXra+0Fh/C6mK19sWfS/NreQVyHfPlvfQL0i1p/L0ARtbmc4OU254G497dDyC5PYtgGIs5jXwEICH0MRDAB4C8BCAhwA8BOAhAA8BeAjAQwAeAvAQgIcAPAQdj/Al6GmHnldi4tjGJEi1bIRjUMQkqgGVBkDfKb6kDCQ9wb5S4vVHy2Mf5m4aTYS18RQ9TuNypD+uXtvlpYdgTLbjmoP51FjGz/xgHPjcC3sEEsS+vI6PwQVxAC+I+SJ4EDQeW+VvtL1zpnzmHYAyDJQfZJAQrv5+/S36W85NSmSWvLdJ9sMFD0DylxDUl3Q/kYCL1MRFAi4ScJGAiwRcJOAiARcJuEjARQIuEnCRgIsEXCQdl/1QxXsRAhU7gHve6RrC+hiNYzSOUZXkibQ9msFoBlp4MWPyEhzUQibx2iRJQnKQXZADkEXIKcjXIY9Avg/5CeR5iDwH9V9B428Qbg6eOg6cmKeOw1NHmP+gPcK8RyvwBi8WwZIU7LynLcJp2VzeZ6cer5YtUjuNdSYHdha4fIHXPbrTzpkFNtoDD9eH84WiOZzORVxqh6ejI7JPi5Wy4UD3SDz3xSBHKTcQDIiCJEhek1UWTVKLEM8V21OTwyrNtrUemvZ2Rd1dhd1hmxINW+mxaCZoszjCPq3LaqVWiyc+mErmOh39GU6wC3lzP6WC3eZPDnU7M7097li6vaUtVbrv4PjeFl8skMr4BI5yFknUOSZ2cPwPcCyRLvKvTdINZNMQBzgWDY5FcCw2ORbBsQiORXAsgmMRHIvgWATHIjgWwbEIjkVwLIJjUeeYgDOCVbvBWTva7WinDO5S4C4F7lLgLgXuUuAuBe5S4C4F7lLgLgXuUuAuBe5STe5S4C4FtVBksKKN6YzVZbRl+EwUxxERPgNm4ySssxkHs54Gsx60KXIfY5mCZaowlr2eNotZKdAmi542EJzLx5pc0mdqP7R2aqPq2BStPUUf5rl2baJ3bHkicevS3Fp70VUpJocSLpqMj2kd14+1uEu+tDczORAevPn2wuLazZWh3SA95mXxiSMMPYT49JFuxKcHKssN3ViuZMczQ7dN4oRJLGbdiFek8HwBecLry/fAwSytNKZHMA3ZFlvFZLrF3SI5os5Sweao2m5aLC7SFwcmkjETt9PMjQ1NDdT66YuMd1p/F5e/YP8O8lUGi6xv5zGynQzG5SbjMhiXGexgXAbjMhiXwbgMxmUwLoNxGYzLYFwG47LOuMKyHaOcQpywrh2nVGZRO6yLMPtADqsDmvuj+EInZ2BvEWLuM2cLQy07cqVOjxpxmfiJ4m6rr2uoc/hwkCvqyVvsvyEfafHG2uWgrfZjOrXDkxhQHMUeGkfugn3kBdj38fpJUD+R8fICNjrjLXqP3VY4yV1YWHj+8oecycCk8Q6ruExz/Q02+2zhUbYnFjTm8WbETC/5YJP0YVo/pA8USaBKQtvwQoxjLIpI8huR5Aeu/iaufuDqB65+4OoHrn7g6geufuDqB65+4OoHrn7g6geufh3XZvREsXIYu4Wxm4S2akSTimhSEU0qoklFNKmIJhXRpCKaVESTimhSEU0qoklFNKnNaFIRTSpUa9htx7JBsNbVYK0LW1ghHmzJ2jFWOxrcIWoAKJKfHkAMWxZBSXinENOdVFDzR28rDLYksoXOnpRloqhJkcy1Ka3Xsqc4wZvKU8NzEc48lhs+HOLaONPlD6klc8NwZy7pb69t/DN7cDSZTQaCtWfpjCNsH5ku9OXzhQx308f92A0/PvG5+fF/+/BH1rOKbWFGf+S5zNqreu58mHPp9n2S5x5iNnH1l+tjnBP+5Sc72FnETkJ66NiN6AzBi0JNLwrBi0LwohC8KAQvCsGLQvCiELwoBC8KwYtC8KIQvCgELwrpXtTFopOdmdx4nUWlG1GpIFmztsKqHgzSImC0cQZhXOZ9LEHidGJUu2PfLhQ5cyQ9GBldnlT9/Xuy5YMK1/a93eVQfl9ufCoyNAtbCzTRkQnJI7fcMdJ7fb5jSJtLVsZ6F2ZzM+N9S/vzBoc11KBzsHeEPMmOceyYsoWCpOnqMO9m6c9jxJAG67Wm9RrU12C9Bus1WK/Beg3Wa7Beg/UarNdgvQbrNVivwXp2ytAa54kOuDmLT7Z+10UI66NdYGfXwUY+HgQ2CeQvhk0C2ORjFnYCMJBRe1DzC+hGOEHL4TiL4o8TgsUAqocrFLhobncyMTmSUPqvCXqRygKJjKe9R3FxRRrsL6c6yoNxv5rNZtVAINnjCQ6kAk/3j6fbHImRdLyv0yeJLm/IFex0W+VQVyRT3OFydA4koxnF1+YOdLYH4j7JFsGvBcDWVn8Lpd0EA1dYOfHoKssO/YwkIzPIyAwyMoOMzCAjM8jIDDIyg4zMICMzyMgMMjKDjMzA0rh+RpKRGVgxaGQGlsutDTSsQENxx3g7b5x1cnl0YLpxQNIE+tDJ4pC0Y6AY+48UbgRC7T0jgccDSOD0uto5PYG3FnoOIWuz+viSXh+DsKeI3T0gJ4zd/3edRAIGiX4Qys65IeSqT6qb+UY1+MT6+UdWJk4WT16ljn7QLBw69gx/suvZnwVuaR15hzr5vzPX/uWZ1Y7mnUU1qsYF/PbCaYqN4oN3+J/Wu0nIdLi2VN9rmsJ7rxiPGlc3fZtkKTsyeImP+wExcwHIKUiajHNC/X1OIHYKvLgAat5zhvCj9XdZnyvUX6Z/rtfwThv9OcMUCSBE+siDZJNG6Ri3k3uT7+Of4Lf4F0wPm2rmU5Z2y2nLa0wv5Ia7wANqaUNb/BuG5jk8Y0/ZCYbd2d9CUUJm9o9OV0a7JxaOn1pYWzkyf/3C7QuZ6ZWl5bU9a/PHV45gHmyu49+u+uPst+1VPm6M8fjxqOoBnSdlMoGQniLT5AYyQ24k++CxFXIef0AgEEn3vwHogcgHCmVuZHN0cmVhbQplbmRvYmoKMjMgMCBvYmoKMzA0OQplbmRvYmoKMjQgMCBvYmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgOTUxIC9DYXBIZWlnaHQgNzIyIC9EZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}],"status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:38:32 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999227' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1701' + X-Envoy-Upstream-Service-Time: + - '1712' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689198d695cc81a19246ff55f56e99420525fa3df9fe8022", + "object": "response", + "created_at": 1754372310, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689198d7058481a19e493cde64948f060525fa3df9fe8022", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The document is a simple sample PDF containing placeholder text (Lorem ipsum) and a brief description. It features multiple paragraphs of nonspecific, generic text focused on various topics such as facilisis, volutpat, vestibulum, and cursus. The content appears to be filler text used to demonstrate formatting and layout, with no specific narrative or detailed information provided." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 753, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 69, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 822 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:38:32 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Summarize + this document"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,JVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGdWsuS20YSvOMr+siJ8IzZDT6PXtmK8MbaIYfHu4cNHzAkNGoHCFIEMJ+737KZ1VUNUKRkjfYR4oCNRnVWVtYD/Oh+cx/dHP9d+eDW2+DOtfuPa933bzrvdp3zrtt9+v17N39YzeU/Lk6/LHAzvyznfruab9KtEQ/wsuqe//AZu4P7x6MrV+kq/l0H5+cr93hw37/1D3Pni8f3bvZ7dTg1tXv349s79/iX++kRxs656Wc29Bt9zEY2LEPaMDzMC++44eOH2Dn8r3JdtK3d/5r6wb0dWvc+/f9hfNiN5xQwHEgRsXsiBsNXZXpOScP5nP+62b+O5zvn125WH+7c/da7mcO/5dLN4qkbeG29LuTaYutm+2Mj60Na5ktc62LPOzbp0gZXqkPdf3cHR+mqDb7bHduu3vV1P9Tnu+Ie+/M5PmCnah9PsdvF9lmfzG9oSd3EHoeEN3Qx7nr3oerqphk6XA8lvyju/Rwf3le72MQu8osS5+EmNOa4j0fuYSb7BUyu91yFT/Io3H2ID9jpT/f4z+S9G4CSCZ8Aut5cA/pmOFdPsR94SvhZnrDACboBRzzJgYIeaAObfh2aphLokzU06qVuYN4q3buEdS3O9YD95Lzufonj/dRHuW2drvF4XX04AVyn2K4mPlwoIB6rhx47LXQrj6c08MvQAeigd25w8Z3S4hhbeFLP4QM+VE38OFQHOJgsIf5brK/PFWkgPq+f6x7AvhbNbVlIXE3pefpQGT/7c4UHGEM9bdodD4fj/kiu6QHLILbcFaT0kVywkwYe9RBBdkU/rPEBtNzHQ932QnU/B2FICb+cu1k6JSJSLgUeTYhDELgoJF6LCfhTLQhLuOKvoeuPsmalG2HBJqRA8mtYAi/ANnyQVfQLvA524M9X4hbmm2vcfm57eAHQ3UO05BnlGswigms9Y1nCNLoNnrdQWCyWxezNuSJwesrFHOdpqiwTNQ2nvTS83OLUTXweGtlZ+VOSGLvhDMozCMw1W9xUt/FApmFP3r+A9M1+qNu6AsuWGo+LFT50u7qpz7H7ONRYJ1uAtQx0wQnX9GGLOT6IUbYn9HzWi0Z8Gc0iqftlTAeIyhUL/52Mq7s+Pg2NUIXRxRN4Pn4fEUEHRgIg5dUN/pU4EcPWigASCoMU5+cJuS4QeJEA/qEXPZ1gcobFJJQsJmp/Z0q12w2HjnAmxaMIAbQKfKC1ajSD5yX2Fa5ZOPgNvlTFtbOt8UGsw+P/LF6ljQEJ4QpHFQm/SYEQqI+aUhjXlBQDZg0En5oK0Qm+qdmBuh5bLKOICyRLX8zOQ38WnyzNbh7l4xA7rlSmBqYvU0ijZCDlTkPzElvITGE2GN5ESQlrDkPBMNFsb4rpPcx9qc4x5SU73xz2QmGeyeGF7YqkMQOxobhE9XUZJyxvaCQowWQRX6qDPJ7aJeCscLU7Nk3cIR/tBThLISURRJpmhCo7S/JPZMm4HZY4bARzVIL3SSR5VtkfhRAYU8f3dbsH1Es9dknaMGXh0Lq0ZMpKMYmL6faSafCEOIX61inOTavL1bwQLtKBZh6p0QO4Humn/gboVjdkcoyWLMUSBpb8JIHoaSmXTAkMI1+qlDMkJcZTLsRXW/AsuRdstlvh8t+H7gScYteBDKV9Q4o18Yk1kWQsbJ5ZTKFm9QIQTC8DcTxUfS9lTr4q2V/KsAX2k5Jog4Vah+XMFHiN2ftCwwP9wJT93RdBva2W0JarKP+AY1rSPotVpuya5r67K3hucsgzPbWsgSB0wDVdXeLi71Kj0WSuYwWlgmX09lSPakBwoTTSZcysP6T6hNvNE/2YZFR6UsmI/UDRl2Mz9CfJf6wa+Jjtopjcz/oMVxkq7+vhOUqFw824lA5/GZrT0FdJWie2g/zNN9STYXtDM6e8EY7w4UscnQLHjymcaKTgiEs5keBUJ/NEHyV6E0EcQjWlBEItJ7+xluHP8+OfA2WENaIlI+ayVCMWM6kRWV5wI+8JDBMJ/tCAxtpUJFAlFD9WA131HJXLqUItYEXF3iFokcI0AG52vZQkpWJMx3+ZrejcrhugEvy7ZGsWfyfpwonjPt9W3YyBEoe83BVt1buJrhGVsMKxpVPSI+ACXAAFHlG6l3yYq3FWjry1ZJi/O1d1B6HE33kDfH+duzSuAmWoHdodtEahlNSlpLHWLDBCYrUb4Fy4hg8sYCu8YK6BL3LvJDlUSltcVDeGJbanLMLUzyez28CBxVfANcen4znJm1fDpUnscZU16BYJn/xQspFgqZsT42GrxOVFpaY4sibbD0hKuXpFO1NoEhwPKT3OC0rStkpmWGcrXSY2RhBYf+mZy38VlK22p0Fa+oL+aibiWgNAVM6MZyNhxZ91aAyLXPu9viUt0Q9eYTr2zKhQFTjYIJ3n7niWptHqJOrxRa/ujD64g5KBE1CMSRQWRT8mFQoKMhb1sd3F/dAyjE1dmMrQEQNlHLllr6AqTn2P+7sCl4Xr2OayJSOP8Q2FvRnYp2JXy57cvY1PH6bUK76qcy/Rul3BlATRfBs85h4TgTd524BoXXWKNetQy9WBrMM5nLX2gV2TxRCjBbTlAT3D5VB1HTHAPCZdlNSvQr0DQ3MVTC2Vkkzx8RjjaElaqDqjh8C1qd5AsdUbnhXtyzQY2LLSDso3gH6pKOuvpxkbsSv8pLUpLGN7VlTGbpNzDmSEXVAM0TKYIbCwUtbiapU8DoYUWo4aSlisAm24+9yhsCzbqI8IXwpUSzZ+DfzHyUzuHzyplAlLl0yetYeXnwagA7dRi9LoC4ayhSusI/B86mRaguWf10EdKF62nAv0Q1dgWgbNIsgmElMlTMoYAWpnoP0XrbJXogUimkZznCDJIShHWhNaJg0SgJYALCrv0YIC63qHSs1anMA0dP5wbHfSZNhoy9OuCgtdlgAOWmR4SKlQvgX2tKMOaXOKuODEZQIssbYajVy36c9umOT7gqPgm5PaT4AFOlfAjpVcKvmR75gh6wFHyL0G5wzP5+ol7hmnlgECRVoWGigla6OR0JxQJKxxXimaGHs1dk6SyWSOLQycXJinNKKDwEQsmEUtAQ0IiW5KqmFHXGEBSJ+K/0QhbKwT2JXl2S0glJQulbfWu9/AULjRgNQJtcL44NL0xk0bOfjdpuBf56f1jQD4ub1zpnosaA/VgLaKlFJ98ATqUvdSGY+RB+GWXG/84+xbelIS1eKBfs/Fz73lKiq0OFmWYTOG4Eh8IwN5Ly218V5amYvCQbnAjMEIKay98SSB5tIcnOyI/qBrdaIrxYMOr2kSvU0Tpf5CMLx2WL1AZWE+zNP/iXSQJiw+wDhgZCMAT6JZPYIS0SJEBh7tkTmQTBd5ITI6kcUsRS8yD1ZYNf37VO9ZRuQsxWjToaPtLyOEGtWrRxaQ3bnIEqfJH/HQ1w9AVBAi1qiq+Zk5zspGHbUiQHGLNX5Y9EqpXmK2aCCmQECtn+Y+OFBOfTzFj0foJ9ARFiGEqdQN3lG0kXCAumIi/m1rzjgLdva85CkyUiHBUl6QG6X0IQNUCoi1tvLYzYSEDSvBvStGp1CHtN6w5I898FYpT3ViGlKKVOD5fDzqPGybw4mKLvnaZIxhlcddajgfPlHyL4J7sx9Y3hq9ynFczjZESep9GJDQWhVajpFRCplnU/wWL1wwahmbYThApwA2kGWLxQISZ01tPafVuDYOSfgXn8P3C2nyqA7wlCEbfmGBTRA8g1ymKXCpmbOFORYZCWGxncqRluZ4C6S5DuVtAu/Dtkin+SKmN2uLJYhihJWoL0BYSVj2Lg4dlZtRVg1RvhbRaLRZB8faMtMiAxWRNToeiy4bnNp5qVcnNGx9lJ7N6CmjAakq0Bqp/+jZPNW7K0h2wUZCu+ZYMU/WKEW5ZoUlmRRzbGajXTXFZpFpqq2l9ZHpw2xkSSoU+QpQi8u6YgnRvgCVL1InrYIhyUdYJmZPzYMtMWGS2l9Vk5VsTm25IZCacvKm07pD5oZxFGNDSI5epsWtHZGtTGqOc+ZhuTVpxICHRq/0wuPozNjAGkx0bHqm1P6g+zEnilof2xHJr63Qlsh6V0hqS4faEPuPE478Jktf/WnzgiNYBg4Mwk+n4TbYlc5rzGSFsYcvfNIYERslH0ntnCYlBhy6wdSgkEGKRSDuqPzT5Fbek+r9vCsPAS6FfRy/ahz5LRnASfw3TAyXt+avNyeGkrA1//AM5jpaZ12aZ7KGE8GRasyg8iaN4aadBQfkFTIbRt3puCRl6kxkVbrIactEHg1H3jwpOtBH5QKIjvqlqncYvMjYXYnJTMaAyfNFXE9J4cIAGQ6/vipa3hq58p2PU7126f2H+BjvPx6c5HXHwuzBYUbtpi9YHGpOlyyRMg1Af77AuJkDV5gJXQXEL8fzE1+mqGRIQaoDVnFYcU/N5rQPcqnBT/xHtiOBGd1wBwsQ1VnOVZKgAGJqEzWKjp3UbHx/iDXSyowVIIVWRrULoxJDJE8vFyZOzMlTRmbpZxgx+/GBukUajrDOx0WrnJj96gHBqXQTlqZ3SaPgyK+DvqIlXMGuK3zHw9l4LIwRDB8aRSXgdeCV8ES9wFFqemum6qEjnmcZc+n4Ck2twIVjWe3q2RbYMHWFKkaQZzrYx2eMOfDDH6y2bCtlCZKf/VhhKkMcqrxJr+bS7xfYs8CY7riLguT4SOCMsebxm16grZBTr6DDKy2MSTElga32uwjCJW41XSZEh4qHyifCb1lwEW/DiIh6n0nuVJ0hJRiuif4k5vH1IBibKyweEhqxg2ZypLjU3yex0DtHvIrHG3puaxNN8gwvRulHlRTPLv0qTwi9YBeQyxW9WsYfxKTeDEaLn7ABGo8v8u92fEMsr0C0hkXs2qff9Vhu5aM7/ekQOjTTAP7kJpUNOCk+i1EEkjNynbJq1YMa2ISDEiu1bcUJltHaszyFlAFiA4gzuAxCho1jbKW/3SuvGTUF7gZgbKHsyWT7kZLtQH+OxR7sNMPxOGlSXi/gq1uTXJEVTFD0OHxzC2WGdVZHeZYWk3FUFhuSBmEmLxXzK/stFOjTH6mkOl9mMdorU87waxoyVaiEeSTgng4Xk0/lZ1xa9tsYjp3ZZHSg/uI7I3kvBVU3qFi2WCvBOE8IimP/5gXuzf5gjX7D+KiTHY5hAZVNcH77P6d6b9EKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjM4NjYKZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAzIDAgUiAvUmVzb3VyY2VzIDYgMCBSIC9Db250ZW50cyA0IDAgUiAvTWVkaWFCb3ggWzAgMCA2MTIgNzkyXQo+PgplbmRvYmoKNiAwIG9iago8PCAvUHJvY1NldCBbIC9QREYgL1RleHQgXSAvQ29sb3JTcGFjZSA8PCAvQ3MxIDcgMCBSID4+IC9Gb250IDw8IC9GMS4wIDggMCBSCi9GMy4wIDEwIDAgUiAvRjIuMCA5IDAgUiA+PiA+PgplbmRvYmoKMTEgMCBvYmoKPDwgL0xlbmd0aCAxMiAwIFIgL04gMSAvQWx0ZXJuYXRlIC9EZXZpY2VHcmF5IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AYVST0gUURz+zTYShIhBhXiIdwoJlSmsrKDadnVZlW1bldKiGGffuqOzM9Ob2TXFkwRdojx1D6JjdOzQoZuXosCsS9cgqSAIPHXo+83s6iiEb3k73/v9/X7fe0RtnabvOylBVHNDlSulp25OTYuDHylFHdROWKYV+OlicYyx67mSv7vX1mfS2LLex7V2+/Y9tZVlYCHqLba3EPohkWYAH5mfKGWAs8Adlq/YPgE8WA6sGvAjogMPmrkw09GcdKWyLZFT5qIoKq9iO0mu+/m5xr6LtYmD/lyPZtaOvbPqqtFM1LT3RKG8D65EGc9fVPZsNRSnDeOcSEMaKfKu1d8rTMcRkSsQSgZSNWS5n2pOnXXgdRi7XbqT4/j2EKU+yWCoibXpspkdhX0AdirL7BDwBejxsmIP54F7Yf9bUcOTwCdhP2SHedatH/YXrlPge4Q9NeDOFK7F8dqKH14tAUP3VCNojHNNxNPXOXOkiO8x1BmY90Y5pgsxd5aqEzeAO2EfWapmCrFd+67qJe57AnfT4zvRmzkLXKAcSXKxFdkU0DwJWBR9i7BJDjw+zh5V4HeomMAcuYnczSj3HtURG2ejUoFWeo1Xxk/jufHF+GVsGM+Afqx213t8/+njFXXXtj48+Y163DmuvZ0bVWFWcWUL3f/HMoSP2Sc5psHToVlYa9h25A+azEywDCjEfwU+l/qSE1Xc1e7tuEUSzFA+LGwluktUbinU6j2DSqwcK9gAdnCSxCxaHLhTa7o5eHfYInpt+U1XsuuG/vr2evva8h5tyqgpKBPNs0RmlLFbo+TdeNv9ZpERnzg6vue9ilrJ/klFED+FOVoq8hRV9FZQ1sRvZw5+G7Z+XD+l5/VB/TwJPa2f0a/ooxG+DHRJz8JzUR+jSfCwaSHiEqCKgzPUTlRjjQPiKfHytFtkkf0PQBn9ZgplbmRzdHJlYW0KZW5kb2JqCjEyIDAgb2JqCjcwNAplbmRvYmoKNyAwIG9iagpbIC9JQ0NCYXNlZCAxMSAwIFIgXQplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFswIDAgNjEyIDc5Ml0gL0NvdW50IDEgL0tpZHMgWyAyIDAgUiBdID4+CmVuZG9iagoxMyAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgPj4KZW5kb2JqCjE0IDAgb2JqCjw8IC9MZW5ndGggMTUgMCBSIC9MZW5ndGgxIDM0MzIgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBrVZtaFvXGT7nXFmSpUiW5CsplmxZ17JuZEnWpyXZqT9kx7LlOHP8UTu6hiR2/J3Zq5e6IYFu9cI2Mv3o8qulsB8lHYVC6bRBg2r2I4x90LIfhnU/tmQshRXGGKM/kg3GbO05V7JZhymFTeLRed/3nPPe9zznfd8rQgkhp8guEUh2aWtxm7xInsHya6C8dHPHS0R8Cf02dM3q9tpWyDL6C+h3CWHvr23eXo2+bqlgKkuI7un6yuLyXzt9F+GwC+vT6zBof8X+AX0Tevv61s4t+6v0Q+j3oIc3X1ha1McMq9B/Cv301uKtbeYXRqB/DN37tcWtlX/95GMr9KfQ49svvLhD3qI3CDEFoHdv31jZ3iaGOegL0PUAxZd/ThEteRejl0zVLKr5f/ph2C2c4EGj2upOmDkyaWuC7sigjnpSr44GznEZfIyXSf1k4ceUvqqUaeU7ZTLc8gHWCFevdJYJDXu9uY3hEl2AwsIwBCVIQtg7UhL8I9MFn+Iteotjy0XviHd9cbmk8asjJlaKStRbIjOFDfw+X5BKWcV9LK4oyln40XA/2ILlRQUertc8YFRN0QMsqguPe0uCPFmYKpR2h92l7LDiliRvrvRwslB6OOyWFAWrtMeRIuJvbJyuxaxDzNog5vVVLzPwARdKsch9QmOyVHpYLLqLOIlq8UllSmoGnJSvEfy5Ms1OFvhU1ie5ucEn+STEoQzDd314fKaQQyQSj8TwxZQajwPF2lMIz6hSavo/UWr+MpQ2fClKLceRfo5SK2K2cEptJ1Pq+wJCjxnOnsDwbpXh3RMYbvwPhnn6MpJA2f0MxSEQHTESZEkU6RSNxf2SVfJbJSvdO9ylu4e36D09/Ux/iB3VfWlsXmAfoVabyFaZuKN7KFUTEULIbQt0QHxcJrrHg3Xk9/D9F4BdHnSjJHTYoiMdQA8wBijABnAb+B7wBvAO8AHwIWC6jMjMiIwisow1mfAwu2hmPgFiP0t1RZjv/CfptelEfPbrA08eDd660p25tJUS2X3PV+4sz70y08EeHKQDs3cXNopTEg5ACeKnf0P89aSVR645jly7X2OB4nk6PK/RKqUkaxK/5+kPD/MifZl+k3aLB2l6Hc2Vc8i5iKlcOMlLZdIELswgk3NhBg9kHzaMOvBhq/JhAx+2Iz5s4MMGPmzgwwY+bODDBj5s4MMGPmzgwwY+bODDBj5sVT4I4jviBNGpRMg+yYp4Ew6VnvNUSMz0tt1YO/yjSE3Li55UPkhzTfGx6OI1hK/Qy/OzwWynk/MhVT5jKfaI9JGZPdKK1sujb7VwbpActVttxSmMOI2RXwVkO2R7TQ7idHy+CyOfG3gMHv2Y7AGHNBkRfG1m3JqHOT2CGl1bhKV8Wg87usIzESHV1Q/Vw1ijKATOKanQpZFwMDcX6lDGoh1DM8GeqzlZpB3ja32R+Xz4zJCSiBRyoeDgpD/2fJ+fsd6ZpNMWHE11DZ5xGAyN/oF0ZCjY2NStZIcX+prt0Xyyeyhw2mQU28/GYgNygxgd5/fnqDyjnzIziZMR8voeKGhUT9z3udPvkQBv52AigNPVA8371TGxj7TWYpsDkIE0MALMAavATeC7wGvA28AD4JeA6TKK47cQPgXY5arnPOfNAd40SKNm+NRYbT3IwmQ/Pcp7nRkMOjhvmSSE52jKTCM0Za1yXHfMble/NpMW6+ankr2temf8QsqbTbRemQgMp3x6Jjk8Bqd4ijZH+tpio3EXLbhTE4lgT3uDK9zTO5AOGuhS/qI7mHC2tDbUCcwknY3lcvb2SNO5FrtIaZ25gY4Gu31mV2RAuSrnM212KeToSLYYNUzfYOa8NlWe0j+AVzdYGdhDHvGa4BnVfJxRjeCwEYdtBp8iZBEygdzCq7CNK4CRV72URpXXUiiTSGd8ZupDCvmlfoHz0knfY02ZS72h6X7ZlZ7tLdwyiqavTmUuxJz0jcNVoS0zFkxcSLoOUtcuRNpzy9mepbEAXZqfnZWHlHx6rs/rz84itAzCHEctC8S5p/5h4DcuWBAN7wdE7QdJa0ZkHx2ksQwfdQ/7DbOQGKns4adaLzGcguFEfDTxqt9He3wCoAvWkTchlKpKIzaYiAXwAjEgC0wCC8A2sAvUIz0sKC0Xd/UmcWG3q+pqH8KTqsJdueDKBVcuuHLBlQuuXHDlgisXXLlUVy1wZUFkfkToR6LJeIQFiVaNNwJrBMdtwYoEz0d+dt5r3IAesKtbKNFjyx6JggMu8V6ZtNZq2P5fIr89rc4XoTpcos6XyojOUL8cSnuMoiPY6w9mJJNokfujvYUGZprq9aTCHh1j7OCQ+kITz/maY9n2wwd0pH0w0XI63C8fvkeng7l481C6Z5DZ5YTnFZwdOZepTNK/I+dOkyB5p0zCCNRBnGq+OXAa3ov5yG+G4SBhyAZwwW1H+cdlXtsGjHK1X8vo1/JRv5bRr2X0axn9Wka/ltGvZfRrGf1aRr+W0a9l9GsZ/VpGvwa3/P3FM1lCOPwNKqm82WtSLO60Jj0o79q7rEqQz5ppk486Iq/pcWa7Pp2azrR4eqaSZ851yQYm/unKjebURDwxHm9yxsZLNDsyGzp/LX32Wj7gDPa03TuYKH/rdmJ+OBDIKYlOZbST56sK4XeDr11t6H1GrcKfYSE///526/HoqEwiox9Br1fj5RPYJ7xVCRG3ZvXwR5V5zSXVE585+hjpU5KgDlzDXZKmn5A06weWiATZgbkmcodkBAPJsCa1zprRCF4m96mG3mERdpfdF9aFf6pejWQTz20Dqv838KKF+D7mqtHbas/W4lVFJoZm83NzofzK5s2VnY2lxYmVl1Y6Zzd3bixe2Fhb3+HRVb2Qyg/4/50TPkbYBHIGl5pE9x4meXIRZTODHED1k9C/AesArfoKZW5kc3RyZWFtCmVuZG9iagoxNSAwIG9iagoyMTc2CmVuZG9iagoxNiAwIG9iago8PCAvVHlwZSAvRm9udERlc2NyaXB0b3IgL0FzY2VudCA5MzEgL0NhcEhlaWdodCA3MjMgL0Rlc2NlbnQgLTIxMyAvRmxhZ3MgMzIKL0ZvbnRCQm94IFstMzM3IC0yMTkgMTExMSA5MzFdIC9Gb250TmFtZSAvTkJVSFZWK0hlbHZldGljYU5ldWUtVWx0cmFMaWdodAovSXRhbGljQW5nbGUgMCAvU3RlbVYgMjAgL0xlYWRpbmcgMjcgL01heFdpZHRoIDExMjYgL1N0ZW1IIDIwIC9YSGVpZ2h0IDUyMAovRm9udEZpbGUyIDE0IDAgUiA+PgplbmRvYmoKMTcgMCBvYmoKWyAyNzggMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDY0OCAwIDQ4MSAwIDAgMCAwIDAgMCAwIDAgMCA1NzQgMCAwIDYxMSAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDQ4MSAwCjAgMCA1MDAgMCAwIDAgMCAwIDAgMTMwIDc3OCAwIDAgNTM3IF0KZW5kb2JqCjggMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvTkJVSFZWK0hlbHZldGljYU5ldWUtVWx0cmFMaWdodAovRm9udERlc2NyaXB0b3IgMTYgMCBSIC9XaWR0aHMgMTcgMCBSIC9GaXJzdENoYXIgMzIgL0xhc3RDaGFyIDExMiAvRW5jb2RpbmcKL01hY1JvbWFuRW5jb2RpbmcgPj4KZW5kb2JqCjE4IDAgb2JqCjw8IC9MZW5ndGggMTkgMCBSIC9MZW5ndGgxIDgzMzIgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBrVl7bFvXeT/nXJKSSPElihSpy6cokuJDEiWKD4kSKdqULEuyLT9iiY5fsiLHcu1EecxIgBZ1gS5DhS1pi+7VbkuWJluTIo2bwoUiDImXdU0bbKtXrMUaGEaLokPQDmgWtAuWxNR+3728spw4Qf4IiY/3nHPvPef7vvP7XoeMM8Za2UUmsfGl84ur/BviCEb+BfS9pQsPBlk7vox/EX3d6dW7zydtu/4Z/a8wJi7ffe7h08433k3h1ixjnYUzy4t3/XcqnGbM/3k8nzuDAcNPJDP6/4B+95nzDz40/VXDv6H/c/T/4ty9S4v3/fRTbzAWeAj9vecXH1oV49Ih9H+AfvCexfPLQzv3PIs+nmGp1XsfeFC3R/enuAWe2D2r9y+vrjLjYfRpvWYQx5c+rczA1nENsvnGiDJ8y49AT7pl5MM6OtzQY8YmZQ3GWpQHjcyEdRiDfPhYQFZmU9rv/7GzNuaAHp3MxTqYm3lYJx6RmZf5mJ8FwGWIdbEw62YR0jcYT82ss5a5hW9z/mhtnW/+4Tqr+l7EutKJ473rjKeCwYmV6iV+Eh2RwkAihJaUCk5ekiKTBxbCteBacG33XWvByeCZxbsu6SLKFTeW12r9wUvs4MIKfg8thC6N1+St5nKtNoJ5dDQPXsHjazXMcLYxA67KUP8NPKRPzQQvSdG5hf0Lly5W5Uvj1ZocCgUnLl2ZW7h0pSqHajU8ZdjiFBx/ZsXd4LkJPBsSuN+sznIQc2CK2toazYmeiIYuXVlbk9cgiTISDq1z1hiApPSMFJlY5+NzC3RrPBySaSAcCofAR62KuVtSMwcXJsBJiDgxfrRKTVuM4tlWsGdSVGr+hFRq+TgqtX4sldq2OL1FpXbwbCOVtt1epeGPUOiWhsdvo+GLqoYv3kbDjm0aJswLNggTfAWGJcFWTLBAfT/g1J8eiITsoYg9ZOcb9Yv8Yv0h/sVm/mZzHW/Qh7Njmw+xy+wsrCiwoQxISaDaBoBcBfVjphbMxDBTPuzMuCyiyVmSspcPJbi+ta3VFXKZzp41+WSXLmnwRpIuZYpF/NKcEpM3FCegzsk2FKunjmRLDxR5Nrx46NBZPMzE5jv4+Yx4DXwZYZ94QuGfWCC2DIzeYnhLFhLP5EMdGf7cY2vP1X8xdZhPzO+uv8Hd/J76l/kLN3LXr2MafDiLbr4lnhA/Y3F2fgOmblImCdoqMuYLwiMEWRSUA02CDoNOgy6AHgH9GejvQN8FfR9kPlbRs5+g8SuQOAZpZHgd4ku2bWDGiNI2gEee6ZPCXRbhbPeLzGBJ5MMW9PtEdqiEvl+IA9Wm7L7FzKHPHkok8FO+ezbdVNV3j8wN7jpdCQQqp3fFdhXj/K3C4aJ/7O5HpqcfOT3WM312R/pgqTtXu2+kuFrLdaQqtO9T+PkjCNwMH/eZddYBdRkhPLFlxC52gPTXANBrYP518PtrkDgGFbSg4QHFQcOg3aAaaAX0MOgLoL8EPQN6EfRDkJmkboFmafoWSM2wmLYzDnumxLND0ZhkJyGd7RYRnnr7608//fXvfGnPvVNdXVP37hGv3cjpnn/hhed1N1bF4dDU/XNz90+FaK9IjhHIYWIZWkKVoAXc665iTZ2yJq0HT6wgYQMS65V2MzTusIeyALpCU/yt+gH+aP1+/gwtN8I7R7gY0dYwY40WBi01NdZowhriKhDHFaQ1bc0PzClt2lHIps1e5Yfrz/LP0dT8kDozzb0H030Jc0usYzvMlXlV+6E59lTpPTyGjyqzFx092Z6+wY/ehneIQVVmKGBLvin+H/VVRSaBtIADtUy8i/ctbH77mhtQYrPCuglbREHSZG8bbnBCfkG1aHjaxioMt0mfnKktc6Olyp1x4AvewyY+WRW/H/+dqN71v28rcqzc+HNB9NqNR8X9qky7wNPD4MnEZm7liUI4bR3puxlkvAoi/8LBEXHFQE23cGS8lQ8OHuxhvqsq+BOzVVE/qfBw9MZTuD4ljtL6qj3UsH4z4v0X1pkHE/IGaMireUBtsAe9ag962INeswc97EEPe9DDHvSwBz3sQQ970MMe9LAHPexBD3vQwx70sAc97EH1lSbCjxFL3WobrQ0sKXocdDnbDWEORZJLyA71ifAf/3rXwsKu+o+r/5feW/D7C3vT/BzvnpqenuLHga5BOTubTs9mZdrrEHzZAfiyCvtbMgMywQ0kLl3KEmHsc4ESGWzkOiv0K7ZegGwFTbYCZCtAtgJkK0C2AmQrQLYCZCtAtgJkK0C2AmQrQLaCIpv52gbrbWzCOuvFBrmhOzN0uPMarHKs4ZfHsHwPMira3h6gNR82KI5PR1L28z5Jc3wdGRK74RkD3C8pTgKe8UxVis+eK5ePjIUdel9mZ/Rbrpjf7h+ohKMT2ZCoJqdOZmdO5tvlVDHwuGcoKUeHd3gHDpe7f7Pj+KivI9LX29OaKiV9xqTe1hnx9ORCVmd8LJ4/WPAmS5OdiZEed3PM4PCn/LF82OZITSsqrECn54AVD5mbB0MkgAfCtMJqqN2q2iIaeMDRkNah2GPDtWcBSXJ05N3tlcDOlemZlZ2Bqje3d3Bgbw7GXc/nl6aTyemlPP9hfbI0n/d48vMljj3kSsw7gvWbsLhqB2QDEtYyNJSeHkC042EpLBl48z7eMvVf4g0F9a/d+Jz4LOE9uPkWrwsHy2JT/34D8HAonFcgRaqB+5Qa8SqIeBVEvAoiXgW+o4KIV0HEqyDiVRDxKoh4FUS8CiJeBRGvokW8CiJeBUAi3DlYRcEYMcqBBfLQ/qsg9KmdQzuF6wzhYxQZN6lxFMwMwJ9Re4C0h0ChhYgmC0DQCJMZpZHLZw3hrqy9ARW9hhECUb7E87mymB31DkScpnZ/e2ZpX1ruL3dH88mwXehtPrfZbmoxRbpy1a7e6XyQ7/EN7Oh2JYKO3sk7esxdBn66PNzijgednVaDMJiDY7nYcMRu6Yx52kNusxBZXZS3DVW6ze2JHQ8fiI4mXBY54o7GXaYmYTRBA9D5KHDjxr65oeLn1lkfNszdQI8bsgvoQJCtoK1DW4d2H9qt0BeNuTDmwlgr2h7VD3lgqx7NVj1oemCrHtiqB9vqga16YKse2KoHtuqBrXpgqx7Yqge26lFslWYOkx8iMPuBKdK2H5q3wzapbVdwm8lm/FB+wwPBFJvCdq4huJGfjI4I11K5OD/i9Y7MF72FdMQo+HFHfLx3cCLpcCQnBnvH4w7C4ancSHJmCRCfSVl8CS/vqRd69pVisdK+nsaVXFUXMPobYDRMeZi3gUqvikovUOkFKr1ApReo9AKVXqDSC1R6gUovUOkFKr1ApReo9Gqo9AKVXqgMOOtABCQJOyCtDhUdtSlqIg/jmrfJDOZuTcNc/Btl0wMHi3eWgsHSncWFVXNZ6uwZ8vVWezs68FOe5KdqC6nppUIBBrxyPJiLuaKlffH4vlJ0h4oDyi8FcNDJ+tjL66wfiueABy1PsUaAtP3vR9tyFYR9p3E32m48j01nXLEoGu3EaCeesKAtX1PyVBn6kaEfGfqRoR8Z+pGhHxn6kaEfGfqRoR8Z+pGhH1nTjwz9yNCPul6EkEEZTqLhIBLQVQsSWWK2BboKUWx9X9qacfIGIjQbFKIsjJF03rcFjuHBmFHU//qD4Kj/pzfhs6RUdCRtvoTnFBfvB4dQsPEmsGGEjCcoc3EpLFHmQiU+sUd2YgJxaIfaflzJ3zC0A2gH+oGBLghLD3cpiFfrBTvaHFOqGwI8hEoS+R19KHczDKnAAE76BH++/oLOkxiNwew76t/hfyLc+YXSWK0gy4Xa2KlPtZeteyd6xxMOHg3vzAQCmR213Mr+wf49pzKwgOTJhdGp6MhuwgaHBwcGgA1Zzc3aFSYkcNwOot2ndiftCqUo1kZyZFU4VsVWijA8ZMLDJohLfSfaJHbHVUiTDatx1dWRVXHu4yjRkGBw6bQweztNLrPVbYkOeI0LC2X+o2yvs1u2SSInhKunEOrP1gf4j8Ar7UGG0x4kWIn90zorfwSOy1h8O45VX6aa4E0ck3yE4bSK4TQ2NY39TQPDaWA4DQyngeE0MJwGhtPAcBoYTgPDaWA4rWE4DQyntzA8QpUA2QLtJ9VcLYh61KZKJNnAdRJYjtjDzluwnMtnKPnCFsfCfkCgJGIUsLeBm79ZFi2hRMZXmC8GOocXSsN3uMTehc7BuE9flmLF6Vh5Puf5VWo80e5IjPf2lnvanIlSgr9ec0Z9tviuE9n84lR8JD15/C6TO+aLF6NtXeNHp8PD07GePaORaGk2GpseDqvYKAIbVKR2sv0byoEUCdEJIVBhKQLZoLtOEEUSuqreQvHtZMXkRjZQ76kJtRMveoA4yt3VjF1FuRNIUGKoAS6+WOYdYCqa8beW21K7c/mjbfBcSDJ7o5V+2Z0YDtVf4rN90xnvcD8PABNjYPXT4JHOE2LbM3kVgOTXCMEGQrCavWNtZybbhFXHyuWyeG15+fs33hM61Pa/3NzRmMvJdn74XO1a9GqGPZBKqEzQ0G9FuxWLtuIkQl0HG2qIxpyDLiWa0aLtkaa2ZpPTFEp6WtT1XwomOedDoiM25BMZssubcn1UnTYG/m/WaaMwSD3so4f9+63cm69VJPYyNo0fQ+MxrfFbtaFX9hMHBxTYJTanjFIpjg2lF3+LrKHxYqPxsjpCL7rhm93ai3SbIgKdYpiZTYkXpP0oFBIFFGLYLEkZlTGauKb4ekKJ6l3CDaSEcZN0Sl6E2j54EapKNTvQmi4FOuEuQxP5FcAnO1puixR7/AmPqWwO5uLVXPmbmSMdloOZ8n6PJHQ33uPB+ETG1x7u76w/ybu7dw4Fdo7Xn+bHLw9m4GDT82CQMxX3DkAeKOgknj8u7j+I+Q9Deva2SCcOb4P0GnhQ/N9bwoj9dUCRr6KEgdrioDA26pOrE3ugcA8U78HMVtUvWuEXrfBnVvhFK/yiFX7RCr9ohV+0wi9a4Ret8ItW+EUr/KJV84tW+EUrwAF/aESuR2o0wgvQ2Ty12+EDuXYE03B0+W3nUVSWcZeW6GhXLRNqXPl1LdvRrlktGUI1Q0kR/n6gXHgHcmEHsJpi31RzYfJyxAZBjDwYXbU8iPJgC/RKYzdjB2tUrhQzPqmMWLEBqtrU7NcB/fgbqacf+iHcZ9RYoNTiCsw/kAgr2U7Bq2U75SWX4EtarmNPTA4pibDuRokHvQmvRcuFi7lT9bqW66TmRruREENXUehKQFeUL15W80X8e6PoioK65vGpdqC2prPtuePNaKBG2E8uS6SZlSyR6oebmeH2jDE9oH9/ZEVJhnxDcyCNOkLgJM8YGxze0psvTyVE/UlNc1oJ8ZJ45VRn3G/TskQLlFj/Ob+iqW5bDQEfzIvCgkwf7NGfR4QwCTybr4LUcyTiW42JVIoy3KBz64aH68hGVU/mzUwmJ5fdQnFbjvjEoCzKUrX8MOaEjwqgVnkFe1RkzxBgAso6VEYhwCptjrYJ437F39IRmnLorfRc6smLC9Wci3w3nbK6EJxdqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcMPJ1FoONUM47iGsM1zGqp+XGcY963pxX2Hn/efPNU5Uocp2tSm/7KQy/ryz8mZ2xrolC2BUbCux3xoMOOTHQUb5DV26+787u6WK0M56VD9miQaerO+mU0xEXP490p93WVYiFegPO5ja9xRnoQGVsrIyfOGyLFBNdg11OnUNnbvc5PV3OFrM3qeizafNd3iIeh1gPfLA6MmCLaA+bcKX6xwVpaT8p1XVoFYutccZsg+J1OHSjjdfhAdpfOuJWAYC4iraWmurRbqfolkUmiJzYgCQhl8G5Qh/P2jPZJ8pHjvDBssVrkeUu+4rQfe1r2frjOwZEVhLhAD+aVbFQBBauI4NxU55280zog3Lc9GTbq7mtrI2iF50gNTdyVDqxpnpLMZdojFp0AkJZKr9ebouOxGfGRLk9OTEwcsIDnNb/JzYzEp6a5HP1b/dNDcr5oWOKbvEfDv9X8PdR50cyzzjo/Ei8uvMfK0+IJwn1mLHI8Wcy4V2hi0+88/YJ6+jvuV2i/3vZ9x5bDWhXZG8ZZD8/Q78FPkz94D3p1c0k8+lO1Z/ZrOkmlJkaN5VLlP+ODXKYBugYaFFc2HxHXGFR8RybEvtBHpz5X2d76CrhPAr3dokLGL/AQnimIvbj+SYWFCU2imsXrlG6cokZRAp9D2z0ReRzL27+kq6YY5TGlHv0Dp7nRTbKf8ECvIc10T3UOySBF99JdpKtsff4Sf5lfoW/zt8RVfF58ab0Vel16T3dd/V79RuGo4YfNPmbftrc07y3+SvN32o50PI3xlHjj02rpqdaZ1ufbX3H7MVspMMo+zRmDoJUDSESo3kZ91QNtzX0Y6C0Z+/c3L4KjjSXz11YfnBlaXHv8h8s986u3H3mwcbbbPOv6P+823yiGJMQ+u34xzqKbKUHjiXF+lEkDbAMy+HYdphV2QSk2wXt7mbTbIbN4r+Jfcg+97MD7CA7xO5AljHPFhiSHxgQjIkl/x9NC1daCmVuZHN0cmVhbQplbmRvYmoKMTkgMCBvYmoKNDkxMAplbmRvYmoKMjAgMCBvYmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgOTY3IC9DYXBIZWlnaHQgNzIyIC9EZXNjZW50IC0yMTMgL0ZsYWdzIDMyCi9Gb250QkJveCBbLTM0MyAtMjE0IDEwOTMgOTY3XSAvRm9udE5hbWUgL05QUE9BRCtIZWx2ZXRpY2FOZXVlLUxpZ2h0IC9JdGFsaWNBbmdsZQowIC9TdGVtViA2OCAvTGVhZGluZyAyOSAvTWF4V2lkdGggMTEyMiAvU3RlbUggNTggL1hIZWlnaHQgNTI0IC9Gb250RmlsZTIgMTggMCBSCj4+CmVuZG9iagoyMSAwIG9iagpbIDI3OCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwCjYzMCAwIDcwNCA2ODUgNTkzIDUzNyAwIDAgMjIyIDAgMCA1MzcgODMzIDcwNCAwIDYzMCAwIDAgNjMwIDAgNjg1IDU5MyAwIDAKMCAwIDAgMCAwIDAgMCAwIDUxOSA1NzQgNTE5IDU3NCA1MTkgMjU5IDU1NiA1MzcgMTg1IDE4NSAwIDE4NSA4MzMgNTM3IDU1Ngo1NzQgNTc0IDMxNSA0ODEgMjk2IDUzNyA0NjMgXQplbmRvYmoKMTAgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvTlBQT0FEK0hlbHZldGljYU5ldWUtTGlnaHQgL0ZvbnREZXNjcmlwdG9yCjIwIDAgUiAvV2lkdGhzIDIxIDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAxMTggL0VuY29kaW5nIC9NYWNSb21hbkVuY29kaW5nCj4+CmVuZG9iagoyMiAwIG9iago8PCAvTGVuZ3RoIDIzIDAgUiAvTGVuZ3RoMSA1MDU2IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AbVYa2xb1R0/517b1zfX1/EjfsWP+MaPWyd2Hr6NnYRgO5HTpkmA0KatzUhp1uZVWpptoTwmRAVj0jJpRQixFdCExDTgw1imqVvI9qGaNrR1ExQhBtr6YZs2aUNoQojXBLX3O/fagW6F8WHY+t97zrnnnvP//37/x7EJJYTYyGnCk9KRE/Orvc6BKYz8jhDqOnJqLUra8CX0TxgzLa4uneh27P4V+n8lhDu3dPyuxfmB92J49Dgh8sbywvzRNyKxPkJc05ifW8aAMGd5Df2voR9fPrF2Z+xucjf6T6M/ffzkkfngWuRh9N9Gf8eJ+TtXuR5+PyHuEPrR2+ZPLLzm+3UE/RH0s6snv7JGf8+9gf4q+hOrX15YXSUtB9DfRN8Kofiyjw1Ni9761IsxuTmFazauuPPEtN03o3XFsgIGrCJpkbClbCethDiIc3v659xwfZb1wR/ASU9tEnGm8iNKv1XdpPUHNkk5/BwRCX/LocwmoelodHylvEEPo8OlMdCloMWno7s2+MSuvZVYNboeXd9zdD26K7o8f3TDlNDveLCwXu2NbpB9lRVcZyvKRqka3G4uVKvDWMfE1sErmL5exQrHGivgrg/1XsYkc3oqusEnZyo3VjZOl4MbpXI1qCjR8Y3zM5WN8+WgUq1ilmVbU2h8z4q/obMAnS1deG41VtmHNbBEdX2drYkel1Q2zq+vB9dhiT4SUzYpaQzAUjaHT4xv0tJMhT0qxZQgG4gpMQV6VMtYW0xP7auMQxOFadLy6ZBK24pirg3qSTqk8v8JUvtngbT1M0Hq2Nb0Ckid0NnBIHVdHdLYpwC6jXDpKgifNhA+fRWE3R9DmPk2R7KI418gLnkiEInAS3rhTr19/QnFqSScipNu1U7T07U76YNW+qa1hjfYhxIfrveTY3ivlWzhihW6QbOjr/8amo/5Zv37j2GMIwho7hHuAvKFl3xpC5s49YmCY9RM/oDO6xBubjSIUHGSACQFGYLsgVQhK5C7IN+AnIU8A3kO8huIPLdJ/JewvwyN2P6yYwu72vU2gS5uXskWuIGdPVyMurWsp83OqU88RlsOP3QkGywtX1e7eN+Tryb33lvlLlzO7brjsdnRlanU5VXuwKuT37y1xHId038J+oukA+jQXra+0Fh/C6mK19sWfS/NreQVyHfPlvfQL0i1p/L0ARtbmc4OU254G497dDyC5PYtgGIs5jXwEICH0MRDAB4C8BCAhwA8BOAhAA8BeAjAQwAeAvAQgIcAPAQdj/Al6GmHnldi4tjGJEi1bIRjUMQkqgGVBkDfKb6kDCQ9wb5S4vVHy2Mf5m4aTYS18RQ9TuNypD+uXtvlpYdgTLbjmoP51FjGz/xgHPjcC3sEEsS+vI6PwQVxAC+I+SJ4EDQeW+VvtL1zpnzmHYAyDJQfZJAQrv5+/S36W85NSmSWvLdJ9sMFD0DylxDUl3Q/kYCL1MRFAi4ScJGAiwRcJOAiARcJuEjARQIuEnCRgIsEXCQdl/1QxXsRAhU7gHve6RrC+hiNYzSOUZXkibQ9msFoBlp4MWPyEhzUQibx2iRJQnKQXZADkEXIKcjXIY9Avg/5CeR5iDwH9V9B428Qbg6eOg6cmKeOw1NHmP+gPcK8RyvwBi8WwZIU7LynLcJp2VzeZ6cer5YtUjuNdSYHdha4fIHXPbrTzpkFNtoDD9eH84WiOZzORVxqh6ejI7JPi5Wy4UD3SDz3xSBHKTcQDIiCJEhek1UWTVKLEM8V21OTwyrNtrUemvZ2Rd1dhd1hmxINW+mxaCZoszjCPq3LaqVWiyc+mErmOh39GU6wC3lzP6WC3eZPDnU7M7097li6vaUtVbrv4PjeFl8skMr4BI5yFknUOSZ2cPwPcCyRLvKvTdINZNMQBzgWDY5FcCw2ORbBsQiORXAsgmMRHIvgWATHIjgWwbEIjkVwLIJjUeeYgDOCVbvBWTva7WinDO5S4C4F7lLgLgXuUuAuBe5S4C4F7lLgLgXuUuAuBe5STe5S4C4FtVBksKKN6YzVZbRl+EwUxxERPgNm4ySssxkHs54Gsx60KXIfY5mCZaowlr2eNotZKdAmi542EJzLx5pc0mdqP7R2aqPq2BStPUUf5rl2baJ3bHkicevS3Fp70VUpJocSLpqMj2kd14+1uEu+tDczORAevPn2wuLazZWh3SA95mXxiSMMPYT49JFuxKcHKssN3ViuZMczQ7dN4oRJLGbdiFek8HwBecLry/fAwSytNKZHMA3ZFlvFZLrF3SI5os5Sweao2m5aLC7SFwcmkjETt9PMjQ1NDdT66YuMd1p/F5e/YP8O8lUGi6xv5zGynQzG5SbjMhiXGexgXAbjMhiXwbgMxmUwLoNxGYzLYFwG47LOuMKyHaOcQpywrh2nVGZRO6yLMPtADqsDmvuj+EInZ2BvEWLuM2cLQy07cqVOjxpxmfiJ4m6rr2uoc/hwkCvqyVvsvyEfafHG2uWgrfZjOrXDkxhQHMUeGkfugn3kBdj38fpJUD+R8fICNjrjLXqP3VY4yV1YWHj+8oecycCk8Q6ruExz/Q02+2zhUbYnFjTm8WbETC/5YJP0YVo/pA8USaBKQtvwQoxjLIpI8huR5Aeu/iaufuDqB65+4OoHrn7g6geufuDqB65+4OoHrn7g6geufh3XZvREsXIYu4Wxm4S2akSTimhSEU0qoklFNKmIJhXRpCKaVESTimhSEU0qoklFNKnNaFIRTSpUa9htx7JBsNbVYK0LW1ghHmzJ2jFWOxrcIWoAKJKfHkAMWxZBSXinENOdVFDzR28rDLYksoXOnpRloqhJkcy1Ka3Xsqc4wZvKU8NzEc48lhs+HOLaONPlD6klc8NwZy7pb69t/DN7cDSZTQaCtWfpjCNsH5ku9OXzhQx308f92A0/PvG5+fF/+/BH1rOKbWFGf+S5zNqreu58mHPp9n2S5x5iNnH1l+tjnBP+5Sc72FnETkJ66NiN6AzBi0JNLwrBi0LwohC8KAQvCsGLQvCiELwoBC8KwYtC8KIQvCgELwrpXtTFopOdmdx4nUWlG1GpIFmztsKqHgzSImC0cQZhXOZ9LEHidGJUu2PfLhQ5cyQ9GBldnlT9/Xuy5YMK1/a93eVQfl9ufCoyNAtbCzTRkQnJI7fcMdJ7fb5jSJtLVsZ6F2ZzM+N9S/vzBoc11KBzsHeEPMmOceyYsoWCpOnqMO9m6c9jxJAG67Wm9RrU12C9Bus1WK/Beg3Wa7Beg/UarNdgvQbrNVivwXp2ytAa54kOuDmLT7Z+10UI66NdYGfXwUY+HgQ2CeQvhk0C2ORjFnYCMJBRe1DzC+hGOEHL4TiL4o8TgsUAqocrFLhobncyMTmSUPqvCXqRygKJjKe9R3FxRRrsL6c6yoNxv5rNZtVAINnjCQ6kAk/3j6fbHImRdLyv0yeJLm/IFex0W+VQVyRT3OFydA4koxnF1+YOdLYH4j7JFsGvBcDWVn8Lpd0EA1dYOfHoKssO/YwkIzPIyAwyMoOMzCAjM8jIDDIyg4zMICMzyMgMMjKDjMzA0rh+RpKRGVgxaGQGlsutDTSsQENxx3g7b5x1cnl0YLpxQNIE+tDJ4pC0Y6AY+48UbgRC7T0jgccDSOD0uto5PYG3FnoOIWuz+viSXh+DsKeI3T0gJ4zd/3edRAIGiX4Qys65IeSqT6qb+UY1+MT6+UdWJk4WT16ljn7QLBw69gx/suvZnwVuaR15hzr5vzPX/uWZ1Y7mnUU1qsYF/PbCaYqN4oN3+J/Wu0nIdLi2VN9rmsJ7rxiPGlc3fZtkKTsyeImP+wExcwHIKUiajHNC/X1OIHYKvLgAat5zhvCj9XdZnyvUX6Z/rtfwThv9OcMUCSBE+siDZJNG6Ri3k3uT7+Of4Lf4F0wPm2rmU5Z2y2nLa0wv5Ia7wANqaUNb/BuG5jk8Y0/ZCYbd2d9CUUJm9o9OV0a7JxaOn1pYWzkyf/3C7QuZ6ZWl5bU9a/PHV45gHmyu49+u+uPst+1VPm6M8fjxqOoBnSdlMoGQniLT5AYyQ24k++CxFXIef0AgEEn3vwHogcgHCmVuZHN0cmVhbQplbmRvYmoKMjMgMCBvYmoKMzA0OQplbmRvYmoKMjQgMCBvYmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgOTUxIC9DYXBIZWlnaHQgNzIyIC9EZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}],"status":"completed"},{"type":"message","role":"assistant","content":"The + document is a simple sample PDF containing placeholder text (Lorem ipsum) + and a brief description. It features multiple paragraphs of nonspecific, generic + text focused on various topics such as facilisis, volutpat, vestibulum, and + cursus. The content appears to be filler text used to demonstrate formatting + and layout, with no specific narrative or detailed information provided.","status":"completed"},{"type":"message","role":"user","content":"go + on","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:38:34 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999150' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1399' + X-Envoy-Upstream-Service-Time: + - '1409' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689198d8e734819c83dcc3b1d995405e068b23cd07121e5a", + "object": "response", + "created_at": 1754372313, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689198d95190819c9caa2b1e52ff630f068b23cd07121e5a", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Certainly! The document's structure includes several sections of Lorem ipsum text, which is commonly used as dummy text for ing and layout purposes. The paragraphs are varied in length and style, showcasing how different blocks of text can be formatted within a PDF. The overall purpose of this sample appears to be to illustrate how a simple PDF document can contain multiple paragraphs, with consistent formatting and spacing, without conveying any meaningful content. The document is straightforward, serving as a template or file rather than containing substantive information." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 831, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 101, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 932 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:38:34 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_real_error_scenarios_openai_gpt-4_1-nano_handles_context_length_exceeded_errors.yml b/spec/fixtures/vcr_cassettes/chat_real_error_scenarios_openai_gpt-4_1-nano_handles_context_length_exceeded_errors.yml index e3ea97bc3..0f3fc6ff6 100644 --- a/spec/fixtures/vcr_cassettes/chat_real_error_scenarios_openai_gpt-4_1-nano_handles_context_length_exceeded_errors.yml +++ b/spec/fixtures/vcr_cassettes/chat_real_error_scenarios_openai_gpt-4_1-nano_handles_context_length_exceeded_errors.yml @@ -77,4 +77,75 @@ http_interactions: } } recorded_at: Fri, 01 Aug 2025 09:56:46 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"","status":"completed"},{"type":"message","role":"assistant","content":"","status":"completed"},{"type":"message","role":"user","content":"","status":"completed"},{"type":"message","role":"assistant","content":"","status":"completed"},{"type":"message","role":"user","content":"","status":"completed"},{"type":"message","role":"assistant","content":"","status":"completed"},{"type":"message","role":"user","content":"","status":"completed"},{"type":"message","role":"assistant","content":"","status":"completed"},{"type":"message","role":"user","content":"","status":"completed"},{"type":"message","role":"assistant","content":"","status":"completed"},{"type":"message","role":"user","content":"Hi","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 500 + message: Internal Server Error + headers: + Date: + - Tue, 05 Aug 2025 05:04:44 GMT + Content-Type: + - application/json + Content-Length: + - '353' + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '6894' + X-Envoy-Upstream-Service-Time: + - '6899' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |- + { + "error": { + "message": "An error occurred while processing your request. You can retry your request, or contact us through our help center at help.openai.com if the error persists. Please include the request ID req_630c2c7cf0cdc55830bd88fee6ac4495 in your message.", + "type": "server_error", + "param": null, + "code": "server_error" + } + } + recorded_at: Tue, 05 Aug 2025 05:04:44 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_remote_text.yml b/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_remote_text.yml index ba7028ab6..99256c689 100644 --- a/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_remote_text.yml +++ b/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_remote_text.yml @@ -245,4 +245,176 @@ http_interactions: "system_fingerprint": "fp_479cfdfab2" } recorded_at: Fri, 01 Aug 2025 10:49:52 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What''s + in this file?"},{"type":"input_text","text":"Ruby + is copyrighted free software by Yukihiro Matsumoto .\nYou + can redistribute it and/or modify it under either the terms of the\n2-clause + BSDL (see the file BSDL), or the conditions below:\n\n 1. You may make and + give away verbatim copies of the source form of the\n software without + restriction, provided that you duplicate all of the\n original copyright + notices and associated disclaimers.\n\n 2. You may modify your copy of the + software in any way, provided that\n you do at least ONE of the following:\n\n a) + place your modifications in the Public Domain or otherwise\n make + them Freely Available, such as by posting said\n\t modifications to Usenet + or an equivalent medium, or by allowing\n\t the author to include your modifications + in the software.\n\n b) use the modified software only within your corporation + or\n organization.\n\n c) give non-standard binaries non-standard + names, with\n instructions on where to get the original software + distribution.\n\n d) make other distribution arrangements with the author.\n\n 3. + You may distribute the software in object code or binary form,\n provided + that you do at least ONE of the following:\n\n a) distribute the binaries + and library files of the software,\n\t together with instructions (in the + manual page or equivalent)\n\t on where to get the original distribution.\n\n b) + accompany the distribution with the machine-readable source of\n\t the software.\n\n c) + give non-standard binaries non-standard names, with\n instructions + on where to get the original software distribution.\n\n d) make other + distribution arrangements with the author.\n\n 4. You may modify and include + the part of the software into any other\n software (possibly commercial). But + some files in the distribution\n are not written by the author, so that + they are not under these terms.\n\n For the list of those files and their + copying conditions, see the\n file LEGAL.\n\n 5. The scripts and library + files supplied as input to or produced as\n output from the software do + not automatically fall under the\n copyright of the software, but belong + to whomever generated them,\n and may be sold commercially, and may be + aggregated with this\n software.\n\n 6. THIS SOFTWARE IS PROVIDED \"AS + IS\" AND WITHOUT ANY EXPRESS OR\n IMPLIED WARRANTIES, INCLUDING, WITHOUT + LIMITATION, THE IMPLIED\n WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR\n PURPOSE.\n"}],"status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:26:38 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999442' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '3172' + X-Envoy-Upstream-Service-Time: + - '3178' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6891960b3ee08192a54b1a3b1cde8c9202963210610baacf", + "object": "response", + "created_at": 1754371595, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6891960bbbbc8192a96956b6f73a30b602963210610baacf", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The file `license.txt` contains the licensing information for the Ruby programming language. It states that Ruby is copyrighted free software created by Yukihiro Matsumoto. \n\nThe license allows you to:\n- Reproduce and distribute verbatim copies of Ruby's source code.\n- Modify the source code under certain conditions, such as placing modifications in the public domain, using the modified version within your organization, giving non-standard binaries unique names with instructions, or making other arrangements with the author.\n- Distribute Ruby in binary form with specific instructions or accompanying source code.\n- Incorporate parts of Ruby into other software, including commercial ones, with some files possibly not being under these terms.\n\nThe license also emphasizes that the software is provided \"as is\" without warranties and clarifies the ownership of scripts and generated files.\n\nIn summary, it is a permissive license with specific conditions for redistribution and modification, typical of open-source software." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 540, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 186, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 726 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:26:38 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_text.yml b/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_text.yml index 07b355e72..253eabb90 100644 --- a/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_text.yml +++ b/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_text.yml @@ -233,4 +233,287 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:49:49 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What''s + in this file?"},{"type":"input_text","text":"Ruby + is the best."}],"status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:13:03 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999950' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '592' + X-Envoy-Upstream-Service-Time: + - '598' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689192df508881929965fe1ec69f9d430efcd93b5a5ed0f0", + "object": "response", + "created_at": 1754370783, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689192dfa2c08192bfec745068a32c580efcd93b5a5ed0f0", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The file named \"ruby.txt\" contains the text: \"Ruby is the best.\"" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 31, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 49 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:13:03 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What''s + in this file?"},{"type":"input_text","text":"Ruby + is the best."}],"status":"completed"},{"type":"message","role":"assistant","content":"The + file named \"ruby.txt\" contains the text: \"Ruby is the best.\"","status":"completed"},{"type":"message","role":"user","content":[{"type":"input_text","text":"and + in this one?"},{"type":"input_text","text":"Ruby + is the best"}],"status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:13:05 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999895' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1083' + X-Envoy-Upstream-Service-Time: + - '1154' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689192e050e4819eadde22ef95743ba90cb7efa80695da0b", + "object": "response", + "created_at": 1754370784, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689192e0d910819e9725259eaccd6cce0cb7efa80695da0b", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The file named \"ruby.xml\" contains an XML element with the content: `Ruby is the best`." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 86, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 29, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 115 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:13:05 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_call_callback_when_tools_are_used.yml b/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_call_callback_when_tools_are_used.yml index e94cc5ffa..34723b717 100644 --- a/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_call_callback_when_tools_are_used.yml +++ b/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_call_callback_when_tools_are_used.yml @@ -198,4 +198,331 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1CemhpdEppT3NNQ0N2eExCeTZWYnBjczI3c3M3NSIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NDA0NTc3OSwKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIlRoZSBjdXJyZW50IHdlYXRoZXIgaW4gQmVybGluIGlzIDE1wrBDIHdpdGggYSB3aW5kIHNwZWVkIG9mIDEwIGttL2guIiwKICAgICAgICAicmVmdXNhbCI6IG51bGwsCiAgICAgICAgImFubm90YXRpb25zIjogW10KICAgICAgfSwKICAgICAgImxvZ3Byb2JzIjogbnVsbCwKICAgICAgImZpbmlzaF9yZWFzb24iOiAic3RvcCIKICAgIH0KICBdLAogICJ1c2FnZSI6IHsKICAgICJwcm9tcHRfdG9rZW5zIjogMTQzLAogICAgImNvbXBsZXRpb25fdG9rZW5zIjogMjAsCiAgICAidG90YWxfdG9rZW5zIjogMTYzLAogICAgInByb21wdF90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgImNhY2hlZF90b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMAogICAgfSwKICAgICJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjogewogICAgICAicmVhc29uaW5nX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwLAogICAgICAiYWNjZXB0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwLAogICAgICAicmVqZWN0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwCiAgICB9CiAgfSwKICAic2VydmljZV90aWVyIjogImRlZmF1bHQiLAogICJzeXN0ZW1fZmluZ2VycHJpbnQiOiAiZnBfMzgzNDNhMmY4ZiIKfQo= recorded_at: Fri, 01 Aug 2025 10:56:19 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:05:01 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999700' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '671' + X-Envoy-Upstream-Service-Time: + - '677' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190fce3b4819d90734b43404af4c70dbc0ecbb2977a4a", + "object": "response", + "created_at": 1754370300, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689190fd432c819d937f0ba16ed9805e0dbc0ecbb2977a4a", + "type": "function_call", + "status": "completed", + "arguments": "{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}", + "call_id": "call_K2GwaJaYl0PJolb5ff2fMlt2", + "name": "weather" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 82, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 40, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 122 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:05:01 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"call_K2GwaJaYl0PJolb5ff2fMlt2","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"call_K2GwaJaYl0PJolb5ff2fMlt2","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:05:02 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999647' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '625' + X-Envoy-Upstream-Service-Time: + - '631' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190fdfdb0819fb8ef0d307f1a4455059e276d8af4f053", + "object": "response", + "created_at": 1754370302, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689190fe3abc819fab4497574d394356059e276d8af4f053", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The current weather in Berlin is 15\u00b0C with a wind speed of 10 km/h." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 135, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 21, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 156 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:05:02 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_local_images.yml b/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_local_images.yml index c076da2a7..dd9e3cd46 100644 --- a/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_local_images.yml +++ b/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_local_images.yml @@ -120,4 +120,143 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:50:41 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What + do you see in this image?"},{"type":"input_image","image_url":"data:image/png;base64,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"}],"status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:30:27 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999235' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '599' + X-Envoy-Upstream-Service-Time: + - '606' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689196f30d2c819180aad36bc786ba680a334a06830b4f49", + "object": "response", + "created_at": 1754371827, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689196f355b88191bf5f375be5e20ef80a334a06830b4f49", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "This image appears to be a stylized, geometric representation of a red gemstone, possibly a ruby. The facets and shading suggest a faceted, three-dimensional gem." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 56, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 34, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 90 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:30:27 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_remote_images_without_extension.yml b/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_remote_images_without_extension.yml index f276f89a0..9fc4f6c2c 100644 --- a/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_remote_images_without_extension.yml +++ b/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_remote_images_without_extension.yml @@ -159,4 +159,143 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:50:42 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What + do you see in this image?"},{"type":"input_image","image_url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzSCawxoHrVtf9AX-o7bp7KVxcmkYWzsIjng&s"}],"status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:31:41 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999235' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1185' + X-Envoy-Upstream-Service-Time: + - '1205' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6891973c4ed881919d14dfd84de789c20401b73eb56beae5", + "object": "response", + "created_at": 1754371900, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6891973cdae88191a118d73239dda41c0401b73eb56beae5", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The image shows the Eiffel Tower in Paris, France, during what appears to be sunset or sunrise, with a colorful sky above. There is a body of water and greenery in the foreground." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 149, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 39, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 188 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:31:41 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_with_params_openai_gpt-4_1-nano_supports_response_format_param.yml b/spec/fixtures/vcr_cassettes/chat_with_params_openai_gpt-4_1-nano_supports_response_format_param.yml index 50ff9659e..5e3e73bb4 100644 --- a/spec/fixtures/vcr_cassettes/chat_with_params_openai_gpt-4_1-nano_supports_response_format_param.yml +++ b/spec/fixtures/vcr_cassettes/chat_with_params_openai_gpt-4_1-nano_supports_response_format_param.yml @@ -102,4 +102,76 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 09:57:05 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"response_format":{"type":"json_object"},"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is the square root of 64? Answer with a JSON object with the key `result`.","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 400 + message: Bad Request + headers: + Date: + - Tue, 05 Aug 2025 05:04:45 GMT + Content-Type: + - application/json + Content-Length: + - '384' + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '11' + X-Envoy-Upstream-Service-Time: + - '19' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |- + { + "error": { + "message": "Unsupported parameter: 'response_format'. In the Responses API, this parameter has moved to 'text.format'. Try again with the new parameter. See the API documentation for more information: https://platform.openai.com/docs/api-reference/responses/create.", + "type": "invalid_request_error", + "param": null, + "code": "unsupported_parameter" + } + } + recorded_at: Tue, 05 Aug 2025 05:04:45 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_accepts_a_json_schema_and_returns_structured_output.yml b/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_accepts_a_json_schema_and_returns_structured_output.yml index cc60258db..9aa18b810 100644 --- a/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_accepts_a_json_schema_and_returns_structured_output.yml +++ b/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_accepts_a_json_schema_and_returns_structured_output.yml @@ -114,4 +114,143 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 09:57:12 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Generate + a person named John who is 30 years old","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:04:46 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999962' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1189' + X-Envoy-Upstream-Service-Time: + - '1196' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190ed5548819cb3be42fce40467a609fe9fd3f2a749b2", + "object": "response", + "created_at": 1754370285, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689190eda3f0819cbf377e1e5b2edf4009fe9fd3f2a749b2", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Here's a brief description of John, a 30-year-old person:\n\nJohn is a 30-year-old individual with a friendly demeanor. He has short, dark brown hair and blue eyes. He works as a software developer and enjoys playing basketball in his free time. John is known for his positive attitude and dedication to his work and hobbies." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 18, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 69, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 87 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:04:46 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_allows_removing_schema_with_nil_mid-conversation.yml b/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_allows_removing_schema_with_nil_mid-conversation.yml index 133de81be..ff2e129a1 100644 --- a/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_allows_removing_schema_with_nil_mid-conversation.yml +++ b/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_allows_removing_schema_with_nil_mid-conversation.yml @@ -217,4 +217,143 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 09:57:14 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Generate + a person named Bob","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:04:48 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999967' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1154' + X-Envoy-Upstream-Service-Time: + - '1162' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689190eedd2c819d9d70691fd6fad6440f427ac4b0b64e30", + "object": "response", + "created_at": 1754370286, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689190ef0dec819db6321e0acef8146a0f427ac4b0b64e30", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Sure! Here's a brief description of a person named Bob:\n\nBob is a friendly and approachable individual in his mid-40s. He has short, brown hair that\u2019s slightly graying at the temples and warm blue eyes. He often wears casual attire, like jeans and a comfortable sweater, and has a welcoming smile that makes everyone feel at ease. Bob works as a community organizer and is passionate about helping others and making a positive impact in his neighborhood.\n\nWould you like a more detailed character profile or a different style?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 12, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 105, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 117 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:04:48 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/context_context_chat_operations_uses_context-specific_api_keys.yml b/spec/fixtures/vcr_cassettes/context_context_chat_operations_uses_context-specific_api_keys.yml index ee3f272ae..d7635a27f 100644 --- a/spec/fixtures/vcr_cassettes/context_context_chat_operations_uses_context-specific_api_keys.yml +++ b/spec/fixtures/vcr_cassettes/context_context_chat_operations_uses_context-specific_api_keys.yml @@ -65,4 +65,73 @@ http_interactions: } } recorded_at: Fri, 01 Aug 2025 10:31:59 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer -context-key + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 401 + message: Unauthorized + headers: + Date: + - Tue, 05 Aug 2025 05:05:04 GMT + Content-Type: + - application/json + Content-Length: + - '245' + Connection: + - keep-alive + Www-Authenticate: + - Bearer realm="OpenAI API" + Openai-Version: + - '2020-10-01' + X-Request-Id: + - "" + Openai-Processing-Ms: + - '73' + X-Envoy-Upstream-Service-Time: + - '86' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |- + { + "error": { + "message": "Incorrect API key provided: -con****-key. You can find your API key at https://platform.openai.com/account/api-keys.", + "type": "invalid_request_error", + "param": null, + "code": "invalid_api_key" + } + } + recorded_at: Tue, 05 Aug 2025 05:05:03 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/error_handles_invalid_api_keys_gracefully.yml b/spec/fixtures/vcr_cassettes/error_handles_invalid_api_keys_gracefully.yml index e4f208c44..89ea99308 100644 --- a/spec/fixtures/vcr_cassettes/error_handles_invalid_api_keys_gracefully.yml +++ b/spec/fixtures/vcr_cassettes/error_handles_invalid_api_keys_gracefully.yml @@ -65,4 +65,73 @@ http_interactions: } } recorded_at: Fri, 01 Aug 2025 10:32:07 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer invalid-key + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 401 + message: Unauthorized + headers: + Date: + - Tue, 05 Aug 2025 05:05:04 GMT + Content-Type: + - application/json + Content-Length: + - '240' + Connection: + - keep-alive + Www-Authenticate: + - Bearer realm="OpenAI API" + Openai-Version: + - '2020-10-01' + X-Request-Id: + - "" + Openai-Processing-Ms: + - '60' + X-Envoy-Upstream-Service-Time: + - '74' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |- + { + "error": { + "message": "Incorrect API key provided: invalid-key. You can find your API key at https://platform.openai.com/account/api-keys.", + "type": "invalid_request_error", + "param": null, + "code": "invalid_api_key" + } + } + recorded_at: Tue, 05 Aug 2025 05:05:04 GMT recorded_with: VCR 6.3.1 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4cd088793..ea7abb6ae 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -149,16 +149,16 @@ end CHAT_MODELS = [ - { provider: :anthropic, model: 'claude-3-5-haiku-20241022' }, - { provider: :bedrock, model: 'anthropic.claude-3-5-haiku-20241022-v1:0' }, - { provider: :gemini, model: 'gemini-2.0-flash' }, - { provider: :deepseek, model: 'deepseek-chat' }, + # { provider: :anthropic, model: 'claude-3-5-haiku-20241022' }, + # { provider: :bedrock, model: 'anthropic.claude-3-5-haiku-20241022-v1:0' }, + # { provider: :gemini, model: 'gemini-2.0-flash' }, + # { provider: :deepseek, model: 'deepseek-chat' }, { provider: :openai, model: 'gpt-4.1-nano' }, - { provider: :openrouter, model: 'anthropic/claude-3.5-haiku' }, - { provider: :ollama, model: 'qwen3' }, - { provider: :gpustack, model: 'qwen3' }, - { provider: :perplexity, model: 'sonar' }, - { provider: :mistral, model: 'ministral-3b-latest' } + # { provider: :openrouter, model: 'anthropic/claude-3.5-haiku' }, + # { provider: :ollama, model: 'qwen3' }, + # { provider: :gpustack, model: 'qwen3' }, + # { provider: :perplexity, model: 'sonar' }, + # { provider: :mistral, model: 'ministral-3b-latest' } ].freeze PDF_MODELS = [ From 99e4d9e7399dd80aef9050f0f70a761779014428 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Mon, 4 Aug 2025 23:04:50 -0700 Subject: [PATCH 06/27] Refactor a bit to support audio inputs with fallback --- lib/ruby_llm.rb | 2 +- lib/ruby_llm/provider.rb | 21 ------ lib/ruby_llm/providers/deepseek.rb | 2 +- lib/ruby_llm/providers/gpustack.rb | 2 +- lib/ruby_llm/providers/mistral.rb | 2 +- lib/ruby_llm/providers/ollama.rb | 2 +- lib/ruby_llm/providers/openai.rb | 72 ++++++++----------- .../providers/openai/chat_completions.rb | 56 +++++++++++++++ .../providers/openai_chat_completions.rb | 56 --------------- lib/ruby_llm/providers/openrouter.rb | 2 +- lib/ruby_llm/providers/perplexity.rb | 2 +- spec/spec_helper.rb | 18 ++--- 12 files changed, 103 insertions(+), 134 deletions(-) create mode 100644 lib/ruby_llm/providers/openai/chat_completions.rb delete mode 100644 lib/ruby_llm/providers/openai_chat_completions.rb diff --git a/lib/ruby_llm.rb b/lib/ruby_llm.rb index 47883068a..b8a8202dd 100644 --- a/lib/ruby_llm.rb +++ b/lib/ruby_llm.rb @@ -14,7 +14,7 @@ 'ruby_llm' => 'RubyLLM', 'llm' => 'LLM', 'openai' => 'OpenAI', - 'openai_chat_completions' => 'OpenAIChatCompletions', + 'chat_completions' => 'ChatCompletions', 'api' => 'API', 'deepseek' => 'DeepSeek', 'perplexity' => 'Perplexity', diff --git a/lib/ruby_llm/provider.rb b/lib/ruby_llm/provider.rb index 0164f417d..b68fd0bfc 100644 --- a/lib/ruby_llm/provider.rb +++ b/lib/ruby_llm/provider.rb @@ -32,27 +32,6 @@ def complete(messages, tools:, temperature:, model:, connection:, params: {}, sc end end - def respond(messages, tools:, temperature:, model:, connection:, params: {}, &) # rubocop:disable Metrics/ParameterLists - normalized_temperature = maybe_normalize_temperature(temperature, model) - - payload = deep_merge( - params, - render_response_payload( - messages, - tools: tools, - temperature: normalized_temperature, - model: model, - stream: block_given? - ) - ) - - if block_given? - stream_response connection, responses_stream_url, payload, & - else - sync_respond_response connection, payload - end - end - def list_models(connection:) response = connection.get models_url parse_list_models_response response, slug, capabilities diff --git a/lib/ruby_llm/providers/deepseek.rb b/lib/ruby_llm/providers/deepseek.rb index a2c4cd54c..6b0d72cf0 100644 --- a/lib/ruby_llm/providers/deepseek.rb +++ b/lib/ruby_llm/providers/deepseek.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # DeepSeek API integration. module DeepSeek - extend RubyLLM::Providers::OpenAIChatCompletions + extend RubyLLM::Providers::OpenAI::ChatCompletions extend DeepSeek::Chat module_function diff --git a/lib/ruby_llm/providers/gpustack.rb b/lib/ruby_llm/providers/gpustack.rb index a0847a031..55ddc029f 100644 --- a/lib/ruby_llm/providers/gpustack.rb +++ b/lib/ruby_llm/providers/gpustack.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # GPUStack API integration based on Ollama. module GPUStack - extend RubyLLM::Providers::OpenAIChatCompletions + extend RubyLLM::Providers::OpenAI::ChatCompletions extend GPUStack::Chat extend GPUStack::Models diff --git a/lib/ruby_llm/providers/mistral.rb b/lib/ruby_llm/providers/mistral.rb index 46241ecc2..5fd7ab0c5 100644 --- a/lib/ruby_llm/providers/mistral.rb +++ b/lib/ruby_llm/providers/mistral.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # Mistral API integration. module Mistral - extend RubyLLM::Providers::OpenAIChatCompletions + extend RubyLLM::Providers::OpenAI::ChatCompletions extend Mistral::Chat extend Mistral::Models extend Mistral::Embeddings diff --git a/lib/ruby_llm/providers/ollama.rb b/lib/ruby_llm/providers/ollama.rb index 883c56fd8..2020d3ac6 100644 --- a/lib/ruby_llm/providers/ollama.rb +++ b/lib/ruby_llm/providers/ollama.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # Ollama API integration. module Ollama - extend RubyLLM::Providers::OpenAIChatCompletions + extend RubyLLM::Providers::OpenAI::ChatCompletions extend Ollama::Chat extend Ollama::Media diff --git a/lib/ruby_llm/providers/openai.rb b/lib/ruby_llm/providers/openai.rb index e95962161..a1550ef61 100644 --- a/lib/ruby_llm/providers/openai.rb +++ b/lib/ruby_llm/providers/openai.rb @@ -6,63 +6,53 @@ module Providers # function calling, and OpenAI's unique streaming format. Supports GPT-4, GPT-3.5, # and other OpenAI models. module OpenAI - extend Provider + extend OpenAI::ChatCompletions extend OpenAI::Response - extend OpenAI::Embeddings - extend OpenAI::Models - extend OpenAI::Streaming - extend OpenAI::Tools - extend OpenAI::Images extend OpenAI::ResponseMedia def self.extended(base) - base.extend(Provider) + base.extend(OpenAI::ChatCompletions) base.extend(OpenAI::Response) - base.extend(OpenAI::Embeddings) - base.extend(OpenAI::Models) - base.extend(OpenAI::Streaming) - base.extend(OpenAI::Tools) - base.extend(OpenAI::Images) base.extend(OpenAI::ResponseMedia) end module_function - # Map old chat completion methods to new responses API methods - def completion_url - responses_url + # Detect if messages contain audio attachments + def has_audio_input?(messages) + messages.any? do |message| + next false unless message.respond_to?(:content) && message.content.respond_to?(:attachments) + + message.content.attachments.any? { |attachment| attachment.type == :audio } + end end + # Override render_payload to conditionally route to chat completions or responses API def render_payload(messages, tools:, temperature:, model:, stream: false, schema: nil) - render_response_payload(messages, tools: tools, temperature: temperature, model: model, stream: stream) + # Track which API we're using for later methods + @using_responses_api = !has_audio_input?(messages) + + if @using_responses_api + # Use responses API for everything else + render_response_payload(messages, tools: tools, temperature: temperature, model: model, stream: stream, schema: schema) + else + # Use chat completions for audio - call the original method from ChatCompletions + super(messages, tools: tools, temperature: temperature, model: model, stream: stream, schema: schema) + end + end + + # Override completion_url to conditionally route to the right endpoint + def completion_url + @using_responses_api ? responses_url : super end + # Override parse_completion_response to use the right parser def parse_completion_response(response) - parse_respond_response(response) - end - - def api_base(config) - config.openai_api_base || 'https://api.openai.com/v1' - end - - def headers(config) - { - 'Authorization' => "Bearer #{config.openai_api_key}", - 'OpenAI-Organization' => config.openai_organization_id, - 'OpenAI-Project' => config.openai_project_id - }.compact - end - - def capabilities - OpenAI::Capabilities - end - - def slug - 'openai' - end - - def configuration_requirements - %i[openai_api_key] + if @using_responses_api + parse_respond_response(response) + else + super(response) + end end end end diff --git a/lib/ruby_llm/providers/openai/chat_completions.rb b/lib/ruby_llm/providers/openai/chat_completions.rb new file mode 100644 index 000000000..f3b8c7308 --- /dev/null +++ b/lib/ruby_llm/providers/openai/chat_completions.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module RubyLLM + module Providers + module OpenAI + # OpenAI Chat Completions API integration. This module contains the original + # OpenAI chat completions functionality that is used by providers that extend + # the OpenAI-compatible API (DeepSeek, Mistral, OpenRouter, etc.) + module ChatCompletions + extend Provider + extend OpenAI::Chat + extend OpenAI::Embeddings + extend OpenAI::Models + extend OpenAI::Streaming + extend OpenAI::Tools + extend OpenAI::Images + extend OpenAI::Media + + def self.extended(base) + base.extend(Provider) + base.extend(OpenAI::Chat) + base.extend(OpenAI::Embeddings) + base.extend(OpenAI::Models) + base.extend(OpenAI::Streaming) + base.extend(OpenAI::Tools) + base.extend(OpenAI::Images) + base.extend(OpenAI::Media) + end + + def api_base(config) + config.openai_api_base || 'https://api.openai.com/v1' + end + + def headers(config) + { + 'Authorization' => "Bearer #{config.openai_api_key}", + 'OpenAI-Organization' => config.openai_organization_id, + 'OpenAI-Project' => config.openai_project_id + }.compact + end + + def capabilities + OpenAI::Capabilities + end + + def slug + 'openai' + end + + def configuration_requirements + %i[openai_api_key] + end + end + end + end +end diff --git a/lib/ruby_llm/providers/openai_chat_completions.rb b/lib/ruby_llm/providers/openai_chat_completions.rb deleted file mode 100644 index 437a386b3..000000000 --- a/lib/ruby_llm/providers/openai_chat_completions.rb +++ /dev/null @@ -1,56 +0,0 @@ -# frozen_string_literal: true - -module RubyLLM - module Providers - # OpenAI Chat Completions API integration. This module contains the original - # OpenAI chat completions functionality that is used by providers that extend - # the OpenAI-compatible API (DeepSeek, Mistral, OpenRouter, etc.) - module OpenAIChatCompletions - extend Provider - extend OpenAI::Chat - extend OpenAI::Embeddings - extend OpenAI::Models - extend OpenAI::Streaming - extend OpenAI::Tools - extend OpenAI::Images - extend OpenAI::Media - - def self.extended(base) - base.extend(Provider) - base.extend(OpenAI::Chat) - base.extend(OpenAI::Embeddings) - base.extend(OpenAI::Models) - base.extend(OpenAI::Streaming) - base.extend(OpenAI::Tools) - base.extend(OpenAI::Images) - base.extend(OpenAI::Media) - end - - module_function - - def api_base(config) - config.openai_api_base || 'https://api.openai.com/v1' - end - - def headers(config) - { - 'Authorization' => "Bearer #{config.openai_api_key}", - 'OpenAI-Organization' => config.openai_organization_id, - 'OpenAI-Project' => config.openai_project_id - }.compact - end - - def capabilities - OpenAI::Capabilities - end - - def slug - 'openai' - end - - def configuration_requirements - %i[openai_api_key] - end - end - end -end \ No newline at end of file diff --git a/lib/ruby_llm/providers/openrouter.rb b/lib/ruby_llm/providers/openrouter.rb index 5d172b16a..282d6882a 100644 --- a/lib/ruby_llm/providers/openrouter.rb +++ b/lib/ruby_llm/providers/openrouter.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # OpenRouter API integration. module OpenRouter - extend RubyLLM::Providers::OpenAIChatCompletions + extend RubyLLM::Providers::OpenAI::ChatCompletions extend OpenRouter::Models module_function diff --git a/lib/ruby_llm/providers/perplexity.rb b/lib/ruby_llm/providers/perplexity.rb index 8baa11cdc..1f67e7029 100644 --- a/lib/ruby_llm/providers/perplexity.rb +++ b/lib/ruby_llm/providers/perplexity.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # Perplexity API integration. module Perplexity - extend RubyLLM::Providers::OpenAIChatCompletions + extend RubyLLM::Providers::OpenAI::ChatCompletions extend Perplexity::Chat extend Perplexity::Models diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ea7abb6ae..4cd088793 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -149,16 +149,16 @@ end CHAT_MODELS = [ - # { provider: :anthropic, model: 'claude-3-5-haiku-20241022' }, - # { provider: :bedrock, model: 'anthropic.claude-3-5-haiku-20241022-v1:0' }, - # { provider: :gemini, model: 'gemini-2.0-flash' }, - # { provider: :deepseek, model: 'deepseek-chat' }, + { provider: :anthropic, model: 'claude-3-5-haiku-20241022' }, + { provider: :bedrock, model: 'anthropic.claude-3-5-haiku-20241022-v1:0' }, + { provider: :gemini, model: 'gemini-2.0-flash' }, + { provider: :deepseek, model: 'deepseek-chat' }, { provider: :openai, model: 'gpt-4.1-nano' }, - # { provider: :openrouter, model: 'anthropic/claude-3.5-haiku' }, - # { provider: :ollama, model: 'qwen3' }, - # { provider: :gpustack, model: 'qwen3' }, - # { provider: :perplexity, model: 'sonar' }, - # { provider: :mistral, model: 'ministral-3b-latest' } + { provider: :openrouter, model: 'anthropic/claude-3.5-haiku' }, + { provider: :ollama, model: 'qwen3' }, + { provider: :gpustack, model: 'qwen3' }, + { provider: :perplexity, model: 'sonar' }, + { provider: :mistral, model: 'ministral-3b-latest' } ].freeze PDF_MODELS = [ From a693991a4640ebe95ca18e919878be415a38f3bb Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 20:59:48 -0700 Subject: [PATCH 07/27] Restore use of complete --- lib/ruby_llm/active_record/acts_as.rb | 2 +- ...ling_handles_attachments_in_ask_method.yml | 137 ++++++++ ..._handling_handles_multiple_attachments.yml | 137 ++++++++ ...at_functionality_persists_chat_history.yml | 137 ++++++++ ..._chat_functionality_tracks_token_usage.yml | 136 ++++++++ ...ced_chat_models_allows_model_switching.yml | 136 ++++++++ ...ersists_tool_calls_with_custom_classes.yml | 311 ++++++++++++++++++ ...spaced_classes_and_custom_associations.yml | 137 ++++++++ ...mpty_assistant_messages_on_api_failure.yml | 140 ++++++++ ...llows_changing_models_mid-conversation.yml | 136 ++++++++ ...s_with_schema_for_structured_responses.yml | 70 ++++ ..._actsas_tool_usage_persists_tool_calls.yml | 311 ++++++++++++++++++ 12 files changed, 1789 insertions(+), 1 deletion(-) create mode 100644 spec/fixtures/vcr_cassettes/activerecord_actsas_error_handling_destroys_empty_assistant_messages_on_api_failure.yml diff --git a/lib/ruby_llm/active_record/acts_as.rb b/lib/ruby_llm/active_record/acts_as.rb index c11bc6f6c..6e6f37a46 100644 --- a/lib/ruby_llm/active_record/acts_as.rb +++ b/lib/ruby_llm/active_record/acts_as.rb @@ -173,7 +173,7 @@ def ask(message, with: nil, &) alias say ask def complete(...) - to_llm.process(...) + to_llm.complete(...) rescue RubyLLM::Error => e if @message&.persisted? && @message.content.blank? RubyLLM.logger.debug "RubyLLM: API call failed, destroying message: #{@message.id}" diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_attachments_in_ask_method.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_attachments_in_ask_method.yml index 29d8a54d0..6ef4efc67 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_attachments_in_ask_method.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_attachments_in_ask_method.yml @@ -120,4 +120,141 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 09:47:04 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What + do you see?"},{"type":"input_image","image_url":"data:image/png;base64,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"}],"status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 03:58:31 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999235' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1304' + X-Envoy-Upstream-Service-Time: + - '1340' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892d2e639ac81a2938681869f29dbb10f63f732e1682461", + "object": "response", + "created_at": 1754452710, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6892d2e70d0c81a2a39e250a00c3e5e40f63f732e1682461", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The image appears to be a stylized, geometric representation of a red gemstone or crystal, with facets and a shiny surface." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 53, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 26, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 79 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 03:58:31 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_multiple_attachments.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_multiple_attachments.yml index 65e85eb2a..29a108c9e 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_multiple_attachments.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_multiple_attachments.yml @@ -85,4 +85,141 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1CemdkcVlRUDBwa29hWEl2NTVzOVBmZk1lTmpoMSIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NDA0MTYyMiwKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIlRoZSBpbWFnZSB5b3UndmUgdXBsb2FkZWQgYXBwZWFycyB0byBiZSBhIHN0eWxpemVkLCBmYWNldGVkIGdlbXN0b25lIG9yIGNyeXN0YWwgd2l0aCBhIHJpY2gsIGRlZXAgcmVkIGh1ZS4gSXQgZmVhdHVyZXMgbXVsdGlwbGUgZ2VvbWV0cmljIGZhY2V0cyB0aGF0IHJlZmxlY3QgbGlnaHQsIGdpdmluZyBpdCBhIHNoaW1tZXJpbmcsIHRocmVlLWRpbWVuc2lvbmFsIGFwcGVhcmFuY2UuIFRoaXMgdHlwZSBvZiB2aXN1YWwgaXMgb2Z0ZW4gYXNzb2NpYXRlZCB3aXRoIGx1eHVyeSwgZWxlZ2FuY2UsIGFuZCBoaWdoLXF1YWxpdHkgamV3ZWxyeSBvciBkZWNvcmF0aXZlIG9iamVjdHMuXG5cbklmIHlvdSBoYXZlIHNwZWNpZmljIHF1ZXN0aW9ucyBvciBuZWVkIGEgZGV0YWlsZWQgYW5hbHlzaXMgcmVsYXRlZCB0byB0aGlzIGltYWdl4oCUc3VjaCBhcyBpdHMgZGVzaWduLCBzeW1ib2xpc20sIG9yIHBvdGVudGlhbCB1c2Vz4oCUcGxlYXNlIGxldCBtZSBrbm93ISIsCiAgICAgICAgInJlZnVzYWwiOiBudWxsLAogICAgICAgICJhbm5vdGF0aW9ucyI6IFtdCiAgICAgIH0sCiAgICAgICJsb2dwcm9icyI6IG51bGwsCiAgICAgICJmaW5pc2hfcmVhc29uIjogInN0b3AiCiAgICB9CiAgXSwKICAidXNhZ2UiOiB7CiAgICAicHJvbXB0X3Rva2VucyI6IDEwMDMsCiAgICAiY29tcGxldGlvbl90b2tlbnMiOiA5MywKICAgICJ0b3RhbF90b2tlbnMiOiAxMDk2LAogICAgInByb21wdF90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgImNhY2hlZF90b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMAogICAgfSwKICAgICJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjogewogICAgICAicmVhc29uaW5nX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwLAogICAgICAiYWNjZXB0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwLAogICAgICAicmVqZWN0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwCiAgICB9CiAgfSwKICAic2VydmljZV90aWVyIjogImRlZmF1bHQiLAogICJzeXN0ZW1fZmluZ2VycHJpbnQiOiAiZnBfMzgzNDNhMmY4ZiIKfQo= recorded_at: Fri, 01 Aug 2025 09:47:03 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Analyze + these"},{"type":"input_image","image_url":"data:image/png;base64,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"},{"type":"input_file","filename":"sample20250805-82335-brcpx0.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}],"status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 03:58:29 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999235' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '4879' + X-Envoy-Upstream-Service-Time: + - '4886' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892d2e0c2e4819c89d2a04359f3ea860984345ce488e0b2", + "object": "response", + "created_at": 1754452704, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6892d2e1adb4819ca5d54fd08145aa870984345ce488e0b2", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The provided document appears to be a sample PDF containing a mix of placeholder text and a brief description. Here's an analysis of its contents:\n\n1. **Header/Title:**\n - The phrase \"Sample PDF\" indicates that this is a demonstration or example document.\n\n2. **Introduction:**\n - The phrase \"This is a simple PDF file. Fun fun fun.\" suggests an informal, light-hearted tone.\n\n3. **Main Content:**\n - The bulk of the document consists of *Lorem ipsum* text, a common placeholder used in publishing and web design. It is used here to simulate real content.\n - The *Lorem ipsum* spans multiple paragraphs, discussing various generic topics related to text formatting, layout, and presentation, but without specific meaning.\n\n4. **Format & Style:**\n - The text appears to be formatted as standard paragraph blocks.\n - No images, tables, or other media are included in the visible content.\n\n5. **Purpose:**\n - Since it\u2019s labeled as a sample PDF with placeholder text, its primary purpose seems to be demonstrating layout, font, or formatting styles rather than conveying actual information.\n\nIf you need a more detailed analysis or specific insights about this PDF (such as structure, metadata, or formatting nuances), please let me know!" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 791, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 262, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 1053 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 03:58:29 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_persists_chat_history.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_persists_chat_history.yml index 05ee54613..90b1d9250 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_persists_chat_history.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_persists_chat_history.yml @@ -114,4 +114,141 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 09:47:07 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + your favorite Ruby feature?","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 03:58:46 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999967' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '4905' + X-Envoy-Upstream-Service-Time: + - '5024' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892d2f19a2c819190133fd0e58d6f050b085032e9498dfc", + "object": "response", + "created_at": 1754452722, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6892d2f504d4819196142a929eeabfae0b085032e9498dfc", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "I find the concept of **blocks** in Ruby particularly fascinating. They allow for elegant and concise code by enabling developers to pass chunks of code as arguments to methods. This feature makes iteration, callbacks, and many other patterns very natural and readable in Ruby. For example:\n\n```ruby\n[1, 2, 3].each do |number|\n puts number * 2\nend\n```\n\nThis simplicity and flexibility in handling code blocks make Ruby's blocks, along with methods like `each`, `map`, and `select`, powerful tools for writing expressive code. Do you have a favorite Ruby feature?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 13, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 125, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 138 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 03:58:46 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_tracks_token_usage.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_tracks_token_usage.yml index 699f47f94..126f9831d 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_tracks_token_usage.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_tracks_token_usage.yml @@ -113,4 +113,140 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 09:47:08 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 03:58:47 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999972' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '427' + X-Envoy-Upstream-Service-Time: + - '432' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892d2f6dc2881a18e62fb73d56a8a8d0e74bd56f1303b25", + "object": "response", + "created_at": 1754452726, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6892d2f717a881a1892705b4db6cbf250e74bd56f1303b25", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Hello! How can I assist you today?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 8, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 18 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 03:58:47 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_allows_model_switching.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_allows_model_switching.yml index 75caac6c8..de9a3ae7e 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_allows_model_switching.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_allows_model_switching.yml @@ -113,4 +113,140 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:48:51 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 03:58:57 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999975' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '801' + X-Envoy-Upstream-Service-Time: + - '810' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892d300a1288191bde9c4631605b2e4098b2e370204711e", + "object": "response", + "created_at": 1754452736, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6892d30121f481918a5049c66408a11e098b2e370204711e", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Hello! How can I assist you today?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 8, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 18 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 03:58:57 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_persists_tool_calls_with_custom_classes.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_persists_tool_calls_with_custom_classes.yml index aa85a528e..ef44e4f71 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_persists_tool_calls_with_custom_classes.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_persists_tool_calls_with_custom_classes.yml @@ -243,4 +243,315 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:48:50 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + 123 * 456?","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 03:58:54 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999737' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1010' + X-Envoy-Upstream-Service-Time: + - '1021' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892d2fd8110819282a6bf10c9fbe6e602417b59a153cc9d", + "object": "response", + "created_at": 1754452733, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_6892d2fe2d3881929dcac2e7c7edea1b02417b59a153cc9d", + "type": "function_call", + "status": "completed", + "arguments": "{\"expression\":\"123 * 456\"}", + "call_id": "call_EPXHwJ5NNnIDbCszD3RHXesE", + "name": "calculator" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 47, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 65 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 03:58:54 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + 123 * 456?","status":"completed"},{"type":"function_call","call_id":"call_EPXHwJ5NNnIDbCszD3RHXesE","name":"calculator","arguments":"{\"expression\":\"123 + * 456\"}","status":"completed"},{"type":"function_call_output","call_id":"call_EPXHwJ5NNnIDbCszD3RHXesE","output":"56088","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 03:58:56 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999710' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '897' + X-Envoy-Upstream-Service-Time: + - '960' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892d2ff1fb881a18356444d91b2be350d4bf41dc963fd1f", + "object": "response", + "created_at": 1754452735, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6892d2ff732481a1a9ee564c519a687d0d4bf41dc963fd1f", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The result of 123 multiplied by 456 is 56,088." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 72, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 17, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 89 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 03:58:55 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_works_with_namespaced_classes_and_custom_associations.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_works_with_namespaced_classes_and_custom_associations.yml index 44318e084..8104084c2 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_works_with_namespaced_classes_and_custom_associations.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_works_with_namespaced_classes_and_custom_associations.yml @@ -114,4 +114,141 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:48:48 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + 2 + 2?","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 03:58:53 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999967' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '489' + X-Envoy-Upstream-Service-Time: + - '495' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892d2fcbb7c81a3a61754b418004f270651e0369b630202", + "object": "response", + "created_at": 1754452732, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6892d2fcfc7481a3be0c158413fc9f5a0651e0369b630202", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "2 + 2 equals 4." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 14, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 9, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 23 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 03:58:53 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_error_handling_destroys_empty_assistant_messages_on_api_failure.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_error_handling_destroys_empty_assistant_messages_on_api_failure.yml new file mode 100644 index 000000000..c0368b209 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_error_handling_destroys_empty_assistant_messages_on_api_failure.yml @@ -0,0 +1,140 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"This + will fail","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 03:58:52 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999970' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '873' + X-Envoy-Upstream-Service-Time: + - '895' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892d2fb7a10819c90b8d7604bcd32b802ae8a124918aafd", + "object": "response", + "created_at": 1754452731, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6892d2fbd45c819cabab9458607d8fba02ae8a124918aafd", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "It looks like you might be referring to a specific situation or statement. Could you please provide more context or clarify what you're referring to? I'm here to help!" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 10, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 33, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 43 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 03:58:52 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_model_switching_allows_changing_models_mid-conversation.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_model_switching_allows_changing_models_mid-conversation.yml index 3ed97325a..145369e1f 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_model_switching_allows_changing_models_mid-conversation.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_model_switching_allows_changing_models_mid-conversation.yml @@ -113,4 +113,140 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 10:48:47 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 03:58:50 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999975' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '775' + X-Envoy-Upstream-Service-Time: + - '801' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892d2fa07d881a392e98c557363ca0305efa45e8122f89b", + "object": "response", + "created_at": 1754452730, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6892d2fa7a2c81a3bc9d18633831d3a005efa45e8122f89b", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Hello! How can I assist you today?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 8, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 18 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 03:58:50 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_structured_output_supports_with_schema_for_structured_responses.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_structured_output_supports_with_schema_for_structured_responses.yml index 77956697f..08df966b8 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_structured_output_supports_with_schema_for_structured_responses.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_structured_output_supports_with_schema_for_structured_responses.yml @@ -102,4 +102,74 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 09:47:12 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Generate + a person named Alice who is 25 years old","status":"completed"}],"stream":false,"temperature":0.7,"response_format":{"type":"json_schema","json_schema":{"name":"response","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"],"additionalProperties":false},"strict":true}}}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 400 + message: Bad Request + headers: + Date: + - Wed, 06 Aug 2025 03:58:51 GMT + Content-Type: + - application/json + Content-Length: + - '384' + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '15' + X-Envoy-Upstream-Service-Time: + - '27' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |- + { + "error": { + "message": "Unsupported parameter: 'response_format'. In the Responses API, this parameter has moved to 'text.format'. Try again with the new parameter. See the API documentation for more information: https://platform.openai.com/docs/api-reference/responses/create.", + "type": "invalid_request_error", + "param": null, + "code": "unsupported_parameter" + } + } + recorded_at: Wed, 06 Aug 2025 03:58:51 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_usage_persists_tool_calls.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_usage_persists_tool_calls.yml index 5a5f9972d..b3233e102 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_usage_persists_tool_calls.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_usage_persists_tool_calls.yml @@ -243,4 +243,315 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Fri, 01 Aug 2025 09:47:10 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + 123 * 456?","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 03:58:48 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999735' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '719' + X-Envoy-Upstream-Service-Time: + - '734' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892d2f7c07481a2b3bf5cd31f40ec38065d0c1f1efed6a7", + "object": "response", + "created_at": 1754452727, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_6892d2f822a481a2a3434f3bef843f6a065d0c1f1efed6a7", + "type": "function_call", + "status": "completed", + "arguments": "{\"expression\":\"123 * 456\"}", + "call_id": "call_sjvyFUfZQs0YwFIr5qCxIsFc", + "name": "calculator" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 47, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 65 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 03:58:48 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + 123 * 456?","status":"completed"},{"type":"function_call","call_id":"call_sjvyFUfZQs0YwFIr5qCxIsFc","name":"calculator","arguments":"{\"expression\":\"123 + * 456\"}","status":"completed"},{"type":"function_call_output","call_id":"call_sjvyFUfZQs0YwFIr5qCxIsFc","output":"56088","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 03:58:49 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999710' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '655' + X-Envoy-Upstream-Service-Time: + - '667' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892d2f8d3ec81918765de01a9d63ba50e663ad0a08c1489", + "object": "response", + "created_at": 1754452728, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6892d2f91c50819198ab5617d49bd8130e663ad0a08c1489", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The result of 123 multiplied by 456 is 56,088." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ] + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 72, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 17, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 89 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 03:58:49 GMT recorded_with: VCR 6.3.1 From d8ff718c08bd10432dc9b2f2e33926d6eeb9f21c Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 21:11:21 -0700 Subject: [PATCH 08/27] Setup response schema for responses API --- lib/ruby_llm/providers/openai/chat.rb | 14 +++ lib/ruby_llm/providers/openai/response.rb | 6 +- ...s_with_schema_for_structured_responses.yml | 118 +++++++++++++++--- spec/ruby_llm/active_record/acts_as_spec.rb | 2 +- 4 files changed, 120 insertions(+), 20 deletions(-) diff --git a/lib/ruby_llm/providers/openai/chat.rb b/lib/ruby_llm/providers/openai/chat.rb index 33234c9df..1503b2340 100644 --- a/lib/ruby_llm/providers/openai/chat.rb +++ b/lib/ruby_llm/providers/openai/chat.rb @@ -26,6 +26,20 @@ def render_payload(messages, tools:, temperature:, model:, stream: false, schema payload[:tool_choice] = 'auto' end + if schema + # Use strict mode from schema if specified, default to true + strict = schema[:strict] != false + + payload[:response_format] = { + type: 'json_schema', + json_schema: { + name: 'response', + schema: schema, + strict: strict + } + } + end + payload[:stream_options] = { include_usage: true } if stream payload end diff --git a/lib/ruby_llm/providers/openai/response.rb b/lib/ruby_llm/providers/openai/response.rb index fc3e3ff50..c5319fcbd 100644 --- a/lib/ruby_llm/providers/openai/response.rb +++ b/lib/ruby_llm/providers/openai/response.rb @@ -30,9 +30,9 @@ def render_response_payload(messages, tools:, temperature:, model:, stream: fals # Use strict mode from schema if specified, default to true strict = schema[:strict] != false - payload[:response_format] = { - type: 'json_schema', - json_schema: { + payload[:text] = { + format: { + type: 'json_schema', name: 'response', schema: schema, strict: strict diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_structured_output_supports_with_schema_for_structured_responses.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_structured_output_supports_with_schema_for_structured_responses.yml index 08df966b8..f0d91ec5d 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_structured_output_supports_with_schema_for_structured_responses.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_structured_output_supports_with_schema_for_structured_responses.yml @@ -108,7 +108,7 @@ http_interactions: body: encoding: UTF-8 string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Generate - a person named Alice who is 25 years old","status":"completed"}],"stream":false,"temperature":0.7,"response_format":{"type":"json_schema","json_schema":{"name":"response","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"],"additionalProperties":false},"strict":true}}}' + a person named Alice who is 25 years old","status":"completed"}],"stream":false,"temperature":0.7,"text":{"format":{"type":"json_schema","name":"response","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"],"additionalProperties":false},"strict":true}}}' headers: User-Agent: - Faraday v2.12.2 @@ -122,17 +122,29 @@ http_interactions: - "*/*" response: status: - code: 400 - message: Bad Request + code: 200 + message: OK headers: Date: - - Wed, 06 Aug 2025 03:58:51 GMT + - Wed, 06 Aug 2025 04:08:41 GMT Content-Type: - application/json - Content-Length: - - '384' + Transfer-Encoding: + - chunked Connection: - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999935' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s Openai-Version: - '2020-10-01' Openai-Organization: @@ -142,9 +154,9 @@ http_interactions: X-Request-Id: - "" Openai-Processing-Ms: - - '15' + - '985' X-Envoy-Upstream-Service-Time: - - '27' + - '1106' Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload Cf-Cache-Status: @@ -161,15 +173,89 @@ http_interactions: Alt-Svc: - h3=":443"; ma=86400 body: - encoding: UTF-8 + encoding: ASCII-8BIT string: |- { - "error": { - "message": "Unsupported parameter: 'response_format'. In the Responses API, this parameter has moved to 'text.format'. Try again with the new parameter. See the API documentation for more information: https://platform.openai.com/docs/api-reference/responses/create.", - "type": "invalid_request_error", - "param": null, - "code": "unsupported_parameter" - } + "id": "resp_6892d5490804819ebc2f50774e5833240a0b6b0c2d31cf8a", + "object": "response", + "created_at": 1754453321, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6892d54971bc819eb0eb2c64fc9276a90a0b6b0c2d31cf8a", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "{\"name\":\"Alice\",\"age\":25}" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "json_schema", + "description": null, + "name": "response", + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "age": { + "type": "integer" + } + }, + "required": [ + "name", + "age" + ], + "additionalProperties": false + }, + "strict": true + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 47, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 57 + }, + "user": null, + "metadata": {} } - recorded_at: Wed, 06 Aug 2025 03:58:51 GMT + recorded_at: Wed, 06 Aug 2025 04:08:41 GMT recorded_with: VCR 6.3.1 diff --git a/spec/ruby_llm/active_record/acts_as_spec.rb b/spec/ruby_llm/active_record/acts_as_spec.rb index 66a49c5b9..fe8e2cbb9 100644 --- a/spec/ruby_llm/active_record/acts_as_spec.rb +++ b/spec/ruby_llm/active_record/acts_as_spec.rb @@ -136,7 +136,7 @@ def execute(expression:) chat = Chat.create!(model_id: model) # Stub the API to fail - allow_any_instance_of(RubyLLM::Chat).to receive(:process).and_raise(RubyLLM::Error) # rubocop:disable RSpec/AnyInstance + allow_any_instance_of(RubyLLM::Chat).to receive(:complete).and_raise(RubyLLM::Error) # rubocop:disable RSpec/AnyInstance expect { chat.ask('This will fail') }.to raise_error(RubyLLM::Error) From 447100a816d5263c332e8cee3f1a88bd1b953ad5 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 21:17:01 -0700 Subject: [PATCH 09/27] Update with params spec --- spec/ruby_llm/chat_request_options_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/ruby_llm/chat_request_options_spec.rb b/spec/ruby_llm/chat_request_options_spec.rb index 64570691e..59376165d 100644 --- a/spec/ruby_llm/chat_request_options_spec.rb +++ b/spec/ruby_llm/chat_request_options_spec.rb @@ -8,10 +8,10 @@ describe 'with params' do # Supported params vary by provider, and to lesser degree, by model. - # Providers [:openai, :ollama, :deepseek] support {response_format: {type: 'json_object'}} + # Providers [:ollama, :deepseek] support {response_format: {type: 'json_object'}} # to guarantee a JSON object is returned. # (Note that :openrouter may accept the parameter but silently ignore it.) - CHAT_MODELS.select { |model_info| %i[openai ollama deepseek].include?(model_info[:provider]) }.each do |model_info| + CHAT_MODELS.select { |model_info| %i[ollama deepseek].include?(model_info[:provider]) }.each do |model_info| model = model_info[:model] provider = model_info[:provider] it "#{provider}/#{model} supports response_format param" do @@ -73,7 +73,7 @@ content: '{' ) - response = chat.get_response + response = chat.complete json_response = JSON.parse('{' + response.content) # rubocop:disable Style/StringConcatenation expect(json_response).to eq({ 'result' => 8 }) @@ -100,7 +100,7 @@ content: '{' ) - response = chat.get_response + response = chat.complete json_response = JSON.parse('{' + response.content) # rubocop:disable Style/StringConcatenation expect(json_response).to eq({ 'result' => 8 }) From f8375f522dc04d4c4310f2da078b7ffd34160018 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 21:18:59 -0700 Subject: [PATCH 10/27] Update cassettes for chat with_schema --- ...n_schema_and_returns_structured_output.yml | 163 +++------- ...oving_schema_with_nil_mid-conversation.yml | 278 +++++++----------- 2 files changed, 141 insertions(+), 300 deletions(-) diff --git a/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_accepts_a_json_schema_and_returns_structured_output.yml b/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_accepts_a_json_schema_and_returns_structured_output.yml index 9aa18b810..a82da993f 100644 --- a/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_accepts_a_json_schema_and_returns_structured_output.yml +++ b/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_accepts_a_json_schema_and_returns_structured_output.yml @@ -1,126 +1,12 @@ --- http_interactions: -- request: - method: post - uri: https://api.openai.com/v1/chat/completions - body: - encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"Generate - a person named John who is 30 years old"}],"stream":false,"temperature":0.7,"response_format":{"type":"json_schema","json_schema":{"name":"response","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"],"additionalProperties":false},"strict":true}}}' - headers: - User-Agent: - - Faraday v2.13.4 - Authorization: - - Bearer - Content-Type: - - application/json - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Fri, 01 Aug 2025 09:57:12 GMT - Content-Type: - - application/json - Transfer-Encoding: - - chunked - Connection: - - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID - Openai-Organization: - - "" - Openai-Processing-Ms: - - '190' - Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '202' - X-Ratelimit-Limit-Requests: - - '500' - X-Ratelimit-Limit-Tokens: - - '200000' - X-Ratelimit-Remaining-Requests: - - '499' - X-Ratelimit-Remaining-Tokens: - - '199986' - X-Ratelimit-Reset-Requests: - - 120ms - X-Ratelimit-Reset-Tokens: - - 4ms - X-Request-Id: - - "" - X-Envoy-Decorator-Operation: - - router.openai.svc.cluster.local:5004/* - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - Cf-Cache-Status: - - DYNAMIC - Set-Cookie: - - "" - - "" - X-Content-Type-Options: - - nosniff - Server: - - cloudflare - Cf-Ray: - - "" - Alt-Svc: - - h3=":443"; ma=86400 - body: - encoding: ASCII-8BIT - string: | - { - "id": "chatcmpl-Bzgngv4uRY1OTvVqpAB28AnlvsQ7r", - "object": "chat.completion", - "created": 1754042232, - "model": "gpt-4.1-nano-2025-04-14", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "{\"name\":\"John\",\"age\":30}", - "refusal": null, - "annotations": [] - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 53, - "completion_tokens": 9, - "total_tokens": 62, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "service_tier": "default", - "system_fingerprint": "fp_38343a2f8f" - } - recorded_at: Fri, 01 Aug 2025 09:57:12 GMT - request: method: post uri: https://api.openai.com/v1/responses body: encoding: UTF-8 string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Generate - a person named John who is 30 years old","status":"completed"}],"stream":false,"temperature":0.7}' + a person named John who is 30 years old","status":"completed"}],"stream":false,"temperature":0.7,"text":{"format":{"type":"json_schema","name":"response","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"],"additionalProperties":false},"strict":true}}}' headers: User-Agent: - Faraday v2.12.2 @@ -138,7 +24,7 @@ http_interactions: message: OK headers: Date: - - Tue, 05 Aug 2025 05:04:46 GMT + - Wed, 06 Aug 2025 04:18:25 GMT Content-Type: - application/json Transfer-Encoding: @@ -152,7 +38,7 @@ http_interactions: X-Ratelimit-Remaining-Requests: - '29999' X-Ratelimit-Remaining-Tokens: - - '149999962' + - '149999932' X-Ratelimit-Reset-Requests: - 2ms X-Ratelimit-Reset-Tokens: @@ -166,11 +52,9 @@ http_interactions: X-Request-Id: - "" Openai-Processing-Ms: - - '1189' + - '1248' X-Envoy-Upstream-Service-Time: - - '1196' - X-Envoy-Decorator-Operation: - - tasksapi.openai.svc.cluster.local:8081/* + - '1430' Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload Cf-Cache-Status: @@ -190,9 +74,9 @@ http_interactions: encoding: ASCII-8BIT string: |- { - "id": "resp_689190ed5548819cb3be42fce40467a609fe9fd3f2a749b2", + "id": "resp_6892d790e46c81a2b56402f52bd03c280ea79e0ebdf6e752", "object": "response", - "created_at": 1754370285, + "created_at": 1754453905, "status": "completed", "background": false, "error": null, @@ -203,7 +87,7 @@ http_interactions: "model": "gpt-4.1-nano-2025-04-14", "output": [ { - "id": "msg_689190eda3f0819cbf377e1e5b2edf4009fe9fd3f2a749b2", + "id": "msg_6892d791c14881a28a75740b6814ca3a0ea79e0ebdf6e752", "type": "message", "status": "completed", "content": [ @@ -211,7 +95,7 @@ http_interactions: "type": "output_text", "annotations": [], "logprobs": [], - "text": "Here's a brief description of John, a 30-year-old person:\n\nJohn is a 30-year-old individual with a friendly demeanor. He has short, dark brown hair and blue eyes. He works as a software developer and enjoys playing basketball in his free time. John is known for his positive attitude and dedication to his work and hobbies." + "text": "{\"name\":\"John\",\"age\":30}" } ], "role": "assistant" @@ -230,7 +114,26 @@ http_interactions: "temperature": 0.7, "text": { "format": { - "type": "text" + "type": "json_schema", + "description": null, + "name": "response", + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "age": { + "type": "integer" + } + }, + "required": [ + "name", + "age" + ], + "additionalProperties": false + }, + "strict": true } }, "tool_choice": "auto", @@ -239,18 +142,18 @@ http_interactions: "top_p": 1.0, "truncation": "disabled", "usage": { - "input_tokens": 18, + "input_tokens": 47, "input_tokens_details": { "cached_tokens": 0 }, - "output_tokens": 69, + "output_tokens": 10, "output_tokens_details": { "reasoning_tokens": 0 }, - "total_tokens": 87 + "total_tokens": 57 }, "user": null, "metadata": {} } - recorded_at: Tue, 05 Aug 2025 05:04:46 GMT + recorded_at: Wed, 06 Aug 2025 04:18:25 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_allows_removing_schema_with_nil_mid-conversation.yml b/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_allows_removing_schema_with_nil_mid-conversation.yml index ff2e129a1..5e7418efe 100644 --- a/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_allows_removing_schema_with_nil_mid-conversation.yml +++ b/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_allows_removing_schema_with_nil_mid-conversation.yml @@ -2,14 +2,14 @@ http_interactions: - request: method: post - uri: https://api.openai.com/v1/chat/completions + uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"Generate - a person named Bob"}],"stream":false,"temperature":0.7,"response_format":{"type":"json_schema","json_schema":{"name":"response","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"],"additionalProperties":false},"strict":true}}}' + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Generate + a person named Bob","status":"completed"}],"stream":false,"temperature":0.7,"text":{"format":{"type":"json_schema","name":"response","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"],"additionalProperties":false},"strict":true}}}' headers: User-Agent: - - Faraday v2.13.4 + - Faraday v2.12.2 Authorization: - Bearer Content-Type: @@ -24,48 +24,44 @@ http_interactions: message: OK headers: Date: - - Fri, 01 Aug 2025 09:57:13 GMT + - Wed, 06 Aug 2025 04:18:26 GMT Content-Type: - application/json Transfer-Encoding: - chunked Connection: - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID - Openai-Organization: - - "" - Openai-Processing-Ms: - - '400' - Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '439' X-Ratelimit-Limit-Requests: - - '500' + - '30000' X-Ratelimit-Limit-Tokens: - - '200000' + - '150000000' X-Ratelimit-Remaining-Requests: - - '499' + - '29999' X-Ratelimit-Remaining-Tokens: - - '199991' + - '149999940' X-Ratelimit-Reset-Requests: - - 120ms - X-Ratelimit-Reset-Tokens: - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 X-Request-Id: - "" - X-Envoy-Decorator-Operation: - - router.openai.svc.cluster.local:5004/* + Openai-Processing-Ms: + - '522' + X-Envoy-Upstream-Service-Time: + - '530' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload Cf-Cache-Status: - DYNAMIC Set-Cookie: - "" - "" - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload X-Content-Type-Options: - nosniff Server: @@ -76,154 +72,98 @@ http_interactions: - h3=":443"; ma=86400 body: encoding: ASCII-8BIT - string: | + string: |- { - "id": "chatcmpl-Bzgngioek6ATqDcnxstgV0FWQrTLh", - "object": "chat.completion", - "created": 1754042232, + "id": "resp_6892d7923340819285e2d49bc48b0e550b9d53e1a1247b55", + "object": "response", + "created_at": 1754453906, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, "model": "gpt-4.1-nano-2025-04-14", - "choices": [ + "output": [ { - "index": 0, - "message": { - "role": "assistant", - "content": "{\"name\":\"Bob\",\"age\":30}", - "refusal": null, - "annotations": [] - }, - "logprobs": null, - "finish_reason": "stop" + "id": "msg_6892d7927ccc8192864353f37e6aed9e0b9d53e1a1247b55", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "{\"name\":\"Bob\",\"age\":30}" + } + ], + "role": "assistant" } ], - "usage": { - "prompt_tokens": 47, - "completion_tokens": 9, - "total_tokens": 56, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null }, + "safety_identifier": null, "service_tier": "default", - "system_fingerprint": "fp_38343a2f8f" - } - recorded_at: Fri, 01 Aug 2025 09:57:13 GMT -- request: - method: post - uri: https://api.openai.com/v1/chat/completions - body: - encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"Generate - a person named Bob"},{"role":"assistant","content":"{\"name\":\"Bob\",\"age\":30}"},{"role":"user","content":"Now - just tell me about Ruby"}],"stream":false,"temperature":0.7}' - headers: - User-Agent: - - Faraday v2.13.4 - Authorization: - - Bearer - Content-Type: - - application/json - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Fri, 01 Aug 2025 09:57:14 GMT - Content-Type: - - application/json - Transfer-Encoding: - - chunked - Connection: - - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID - Openai-Organization: - - "" - Openai-Processing-Ms: - - '1279' - Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '1398' - X-Request-Id: - - "" - X-Envoy-Decorator-Operation: - - router.openai.svc.cluster.local:5004/* - Cf-Cache-Status: - - DYNAMIC - Set-Cookie: - - "" - - "" - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - X-Content-Type-Options: - - nosniff - Server: - - cloudflare - Cf-Ray: - - "" - Alt-Svc: - - h3=":443"; ma=86400 - body: - encoding: ASCII-8BIT - string: | - { - "id": "chatcmpl-BzgnhKtfPqHqMvEUyiwOR0NElKx4l", - "object": "chat.completion", - "created": 1754042233, - "model": "gpt-4.1-nano-2025-04-14", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "Certainly! Ruby is a dynamic, open-source programming language known for its simplicity and productivity. Created by Yukihiro Matsumoto in the mid-1990s, Ruby emphasizes clean and readable code, making it popular among developers for web development, scripting, and automation. It is particularly famous for its powerful web framework, Ruby on Rails, which has revolutionized web application development. Ruby features an elegant syntax that is easy to learn, supports object-oriented programming, and has a vibrant community that contributes to a rich ecosystem of libraries and tools.", - "refusal": null, - "annotations": [] + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "json_schema", + "description": null, + "name": "response", + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "age": { + "type": "integer" + } + }, + "required": [ + "name", + "age" + ], + "additionalProperties": false }, - "logprobs": null, - "finish_reason": "stop" + "strict": true } - ], + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", "usage": { - "prompt_tokens": 35, - "completion_tokens": 109, - "total_tokens": 144, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 + "input_tokens": 41, + "input_tokens_details": { + "cached_tokens": 0 }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 51 }, - "service_tier": "default", - "system_fingerprint": "fp_38343a2f8f" + "user": null, + "metadata": {} } - recorded_at: Fri, 01 Aug 2025 09:57:14 GMT + recorded_at: Wed, 06 Aug 2025 04:18:26 GMT - request: method: post uri: https://api.openai.com/v1/responses body: encoding: UTF-8 string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Generate - a person named Bob","status":"completed"}],"stream":false,"temperature":0.7}' + a person named Bob","status":"completed"},{"type":"message","role":"assistant","content":"{\"name\":\"Bob\",\"age\":30}","status":"completed"},{"type":"message","role":"user","content":"Now + just tell me about Ruby","status":"completed"}],"stream":false,"temperature":0.7}' headers: User-Agent: - Faraday v2.12.2 @@ -241,7 +181,7 @@ http_interactions: message: OK headers: Date: - - Tue, 05 Aug 2025 05:04:48 GMT + - Wed, 06 Aug 2025 04:18:29 GMT Content-Type: - application/json Transfer-Encoding: @@ -255,7 +195,7 @@ http_interactions: X-Ratelimit-Remaining-Requests: - '29999' X-Ratelimit-Remaining-Tokens: - - '149999967' + - '149999945' X-Ratelimit-Reset-Requests: - 2ms X-Ratelimit-Reset-Tokens: @@ -269,11 +209,9 @@ http_interactions: X-Request-Id: - "" Openai-Processing-Ms: - - '1154' + - '2466' X-Envoy-Upstream-Service-Time: - - '1162' - X-Envoy-Decorator-Operation: - - tasksapi.openai.svc.cluster.local:8081/* + - '2475' Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload Cf-Cache-Status: @@ -293,9 +231,9 @@ http_interactions: encoding: ASCII-8BIT string: |- { - "id": "resp_689190eedd2c819d9d70691fd6fad6440f427ac4b0b64e30", + "id": "resp_6892d793310481a29768052e613a842004fe68ea18936eb5", "object": "response", - "created_at": 1754370286, + "created_at": 1754453907, "status": "completed", "background": false, "error": null, @@ -306,7 +244,7 @@ http_interactions: "model": "gpt-4.1-nano-2025-04-14", "output": [ { - "id": "msg_689190ef0dec819db6321e0acef8146a0f427ac4b0b64e30", + "id": "msg_6892d793725081a2873dbfbcd1275aeb04fe68ea18936eb5", "type": "message", "status": "completed", "content": [ @@ -314,7 +252,7 @@ http_interactions: "type": "output_text", "annotations": [], "logprobs": [], - "text": "Sure! Here's a brief description of a person named Bob:\n\nBob is a friendly and approachable individual in his mid-40s. He has short, brown hair that\u2019s slightly graying at the temples and warm blue eyes. He often wears casual attire, like jeans and a comfortable sweater, and has a welcoming smile that makes everyone feel at ease. Bob works as a community organizer and is passionate about helping others and making a positive impact in his neighborhood.\n\nWould you like a more detailed character profile or a different style?" + "text": "Certainly! Here's some general information about Ruby:\n\nRuby is a dynamic, open-source programming language known for its simplicity and productivity. It was created by Yukihiro Matsumoto (often called Matz) in the mid-1990s with the goal of making programming more enjoyable and natural. Ruby emphasizes human-friendly syntax, making it easy to read and write.\n\nRuby is widely used for web development, especially with the Ruby on Rails framework, which has contributed to its popularity. Besides web development, Ruby is also used for scripting, automation, and data processing.\n\nIf you were referring to a person named Ruby, please let me know, and I can provide more specific information!" } ], "role": "assistant" @@ -342,18 +280,18 @@ http_interactions: "top_p": 1.0, "truncation": "disabled", "usage": { - "input_tokens": 12, + "input_tokens": 35, "input_tokens_details": { "cached_tokens": 0 }, - "output_tokens": 105, + "output_tokens": 137, "output_tokens_details": { "reasoning_tokens": 0 }, - "total_tokens": 117 + "total_tokens": 172 }, "user": null, "metadata": {} } - recorded_at: Tue, 05 Aug 2025 05:04:48 GMT + recorded_at: Wed, 06 Aug 2025 04:18:29 GMT recorded_with: VCR 6.3.1 From f48ba3f2810ec963ba82b1a7fa0badd95a788da4 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 21:46:26 -0700 Subject: [PATCH 11/27] Remove some extra params --- lib/ruby_llm/provider.rb | 2 +- lib/ruby_llm/providers/bedrock/streaming/base.rb | 2 +- lib/ruby_llm/streaming.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ruby_llm/provider.rb b/lib/ruby_llm/provider.rb index b68fd0bfc..6c6f85e5f 100644 --- a/lib/ruby_llm/provider.rb +++ b/lib/ruby_llm/provider.rb @@ -26,7 +26,7 @@ def complete(messages, tools:, temperature:, model:, connection:, params: {}, sc ) if block_given? - stream_response connection, completion_stream_url, payload, & + stream_response connection, payload, & else sync_completion_response connection, payload end diff --git a/lib/ruby_llm/providers/bedrock/streaming/base.rb b/lib/ruby_llm/providers/bedrock/streaming/base.rb index 415f16c6c..c2ab2ea19 100644 --- a/lib/ruby_llm/providers/bedrock/streaming/base.rb +++ b/lib/ruby_llm/providers/bedrock/streaming/base.rb @@ -29,7 +29,7 @@ def stream_url "model/#{@model_id}/invoke-with-response-stream" end - def stream_response(connection, stream_url, payload, &block) + def stream_response(connection, payload, &block) signature = sign_request("#{connection.connection.url_prefix}#{stream_url}", config: connection.config, payload:) accumulator = StreamAccumulator.new diff --git a/lib/ruby_llm/streaming.rb b/lib/ruby_llm/streaming.rb index cad91c30e..b524aebd8 100644 --- a/lib/ruby_llm/streaming.rb +++ b/lib/ruby_llm/streaming.rb @@ -8,7 +8,7 @@ module RubyLLM module Streaming module_function - def stream_response(connection, stream_url, payload, &block) + def stream_response(connection, payload, &block) accumulator = StreamAccumulator.new response = connection.post stream_url, payload do |req| From c0ae2aaecf7bc04f48c7265cf0e2f0872520926f Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 21:47:33 -0700 Subject: [PATCH 12/27] OpenAI responses API does not seem to provide token counts on chunks when streaming --- lib/ruby_llm/providers/openai/response.rb | 1 - ...token_counts_compared_to_non-streaming.yml | 222 ++++++++++-------- ...-4_1-nano_supports_streaming_responses.yml | 91 +++---- spec/ruby_llm/chat_streaming_spec.rb | 4 + 4 files changed, 179 insertions(+), 139 deletions(-) diff --git a/lib/ruby_llm/providers/openai/response.rb b/lib/ruby_llm/providers/openai/response.rb index c5319fcbd..c6293d311 100644 --- a/lib/ruby_llm/providers/openai/response.rb +++ b/lib/ruby_llm/providers/openai/response.rb @@ -40,7 +40,6 @@ def render_response_payload(messages, tools:, temperature:, model:, stream: fals } end - payload[:stream_options] = { include_usage: true } if stream payload end diff --git a/spec/fixtures/vcr_cassettes/chat_streaming_responses_openai_gpt-4_1-nano_reports_consistent_token_counts_compared_to_non-streaming.yml b/spec/fixtures/vcr_cassettes/chat_streaming_responses_openai_gpt-4_1-nano_reports_consistent_token_counts_compared_to_non-streaming.yml index 016b605d8..246921f5d 100644 --- a/spec/fixtures/vcr_cassettes/chat_streaming_responses_openai_gpt-4_1-nano_reports_consistent_token_counts_compared_to_non-streaming.yml +++ b/spec/fixtures/vcr_cassettes/chat_streaming_responses_openai_gpt-4_1-nano_reports_consistent_token_counts_compared_to_non-streaming.yml @@ -2,14 +2,14 @@ http_interactions: - request: method: post - uri: https://api.openai.com/v1/chat/completions + uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"Count - from 1 to 3"}],"stream":true,"temperature":0.0,"stream_options":{"include_usage":true}}' + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Count + from 1 to 3","status":"completed"}],"stream":true,"temperature":0.0}' headers: User-Agent: - - Faraday v2.13.4 + - Faraday v2.12.2 Authorization: - Bearer Content-Type: @@ -24,48 +24,32 @@ http_interactions: message: OK headers: Date: - - Fri, 01 Aug 2025 10:07:40 GMT + - Wed, 06 Aug 2025 04:27:56 GMT Content-Type: - text/event-stream; charset=utf-8 Transfer-Encoding: - chunked Connection: - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID + Openai-Version: + - '2020-10-01' Openai-Organization: - "" - Openai-Processing-Ms: - - '145' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '156' - X-Ratelimit-Limit-Requests: - - '500' - X-Ratelimit-Limit-Tokens: - - '200000' - X-Ratelimit-Remaining-Requests: - - '499' - X-Ratelimit-Remaining-Tokens: - - '199993' - X-Ratelimit-Reset-Requests: - - 120ms - X-Ratelimit-Reset-Tokens: - - 2ms + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 X-Request-Id: - "" - X-Envoy-Decorator-Operation: - - router.openai.svc.cluster.local:5004/* + Openai-Processing-Ms: + - '35' + X-Envoy-Upstream-Service-Time: + - '39' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload Cf-Cache-Status: - DYNAMIC Set-Cookie: - "" - "" - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload X-Content-Type-Options: - nosniff Server: @@ -77,39 +61,62 @@ http_interactions: body: encoding: UTF-8 string: |+ - data: {"id":"chatcmpl-Bzgxoyfpqa6MkKU4jikWjFnzp38NM","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892d9cbf2fc819d8638f127679424c9023dfe47d80ad8b5","object":"response","created_at":1754454475,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892d9cbf2fc819d8638f127679424c9023dfe47d80ad8b5","object":"response","created_at":1754454475,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","output_index":0,"content_index":0,"delta":"1","logprobs":[],"obfuscation":"xM2Zd74f453l07W"} - data: {"id":"chatcmpl-Bzgxoyfpqa6MkKU4jikWjFnzp38NM","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":"1"},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"VjVvVqeJA4EXHRj"} - data: {"id":"chatcmpl-Bzgxoyfpqa6MkKU4jikWjFnzp38NM","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"aBAloKqM2fsI6gI"} - data: {"id":"chatcmpl-Bzgxoyfpqa6MkKU4jikWjFnzp38NM","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","output_index":0,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"Woogwn8Djg3nOb6"} - data: {"id":"chatcmpl-Bzgxoyfpqa6MkKU4jikWjFnzp38NM","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":"2"},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"cOMqXAtXUQM67gk"} - data: {"id":"chatcmpl-Bzgxoyfpqa6MkKU4jikWjFnzp38NM","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"HubQnhkSkDGouD7"} - data: {"id":"chatcmpl-Bzgxoyfpqa6MkKU4jikWjFnzp38NM","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","output_index":0,"content_index":0,"delta":"3","logprobs":[],"obfuscation":"gGnFJAikl41wyOZ"} - data: {"id":"chatcmpl-Bzgxoyfpqa6MkKU4jikWjFnzp38NM","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":11,"item_id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","output_index":0,"content_index":0,"text":"1, 2, 3","logprobs":[]} - data: {"id":"chatcmpl-Bzgxoyfpqa6MkKU4jikWjFnzp38NM","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":12,"item_id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}} - data: {"id":"chatcmpl-Bzgxoyfpqa6MkKU4jikWjFnzp38NM","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[],"usage":{"prompt_tokens":14,"completion_tokens":7,"total_tokens":21,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":13,"output_index":0,"item":{"id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}],"role":"assistant"}} - data: [DONE] + event: response.completed + data: {"type":"response.completed","sequence_number":14,"response":{"id":"resp_6892d9cbf2fc819d8638f127679424c9023dfe47d80ad8b5","object":"response","created_at":1754454475,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":14,"input_tokens_details":{"cached_tokens":0},"output_tokens":8,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":22},"user":null,"metadata":{}}} - recorded_at: Fri, 01 Aug 2025 10:07:41 GMT + recorded_at: Wed, 06 Aug 2025 04:27:56 GMT - request: method: post - uri: https://api.openai.com/v1/chat/completions + uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"Count - from 1 to 3"}],"stream":false,"temperature":0.0}' + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Count + from 1 to 3","status":"completed"}],"stream":false,"temperature":0.0}' headers: User-Agent: - - Faraday v2.13.4 + - Faraday v2.12.2 Authorization: - Bearer Content-Type: @@ -124,41 +131,37 @@ http_interactions: message: OK headers: Date: - - Fri, 01 Aug 2025 10:07:41 GMT + - Wed, 06 Aug 2025 04:27:57 GMT Content-Type: - application/json Transfer-Encoding: - chunked Connection: - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID - Openai-Organization: - - "" - Openai-Processing-Ms: - - '271' - Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '373' X-Ratelimit-Limit-Requests: - - '500' + - '30000' X-Ratelimit-Limit-Tokens: - - '200000' + - '150000000' X-Ratelimit-Remaining-Requests: - - '499' + - '29999' X-Ratelimit-Remaining-Tokens: - - '199993' + - '149999967' X-Ratelimit-Reset-Requests: - - 120ms - X-Ratelimit-Reset-Tokens: - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 X-Request-Id: - "" - X-Envoy-Decorator-Operation: - - router.openai.svc.cluster.local:5004/* + Openai-Processing-Ms: + - '465' + X-Envoy-Upstream-Service-Time: + - '478' Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload Cf-Cache-Status: @@ -176,42 +179,69 @@ http_interactions: - h3=":443"; ma=86400 body: encoding: ASCII-8BIT - string: | + string: |- { - "id": "chatcmpl-BzgxpCwccfs7QzDDZ2bgdc1BWqWZd", - "object": "chat.completion", - "created": 1754042861, + "id": "resp_6892d9cc9bb481a2b26eb68124400f680cc127714d6b9c67", + "object": "response", + "created_at": 1754454476, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, "model": "gpt-4.1-nano-2025-04-14", - "choices": [ + "output": [ { - "index": 0, - "message": { - "role": "assistant", - "content": "1, 2, 3", - "refusal": null, - "annotations": [] - }, - "logprobs": null, - "finish_reason": "stop" + "id": "msg_6892d9ccdbb081a299423e1d8c20de9b0cc127714d6b9c67", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "1, 2, 3" + } + ], + "role": "assistant" } ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.0, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", "usage": { - "prompt_tokens": 14, - "completion_tokens": 7, - "total_tokens": 21, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 + "input_tokens": 14, + "input_tokens_details": { + "cached_tokens": 0 }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } + "output_tokens": 8, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 22 }, - "service_tier": "default", - "system_fingerprint": "fp_38343a2f8f" + "user": null, + "metadata": {} } - recorded_at: Fri, 01 Aug 2025 10:07:41 GMT + recorded_at: Wed, 06 Aug 2025 04:27:57 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_streaming_responses_openai_gpt-4_1-nano_supports_streaming_responses.yml b/spec/fixtures/vcr_cassettes/chat_streaming_responses_openai_gpt-4_1-nano_supports_streaming_responses.yml index 59d731656..f03a6d833 100644 --- a/spec/fixtures/vcr_cassettes/chat_streaming_responses_openai_gpt-4_1-nano_supports_streaming_responses.yml +++ b/spec/fixtures/vcr_cassettes/chat_streaming_responses_openai_gpt-4_1-nano_supports_streaming_responses.yml @@ -2,14 +2,14 @@ http_interactions: - request: method: post - uri: https://api.openai.com/v1/chat/completions + uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"Count - from 1 to 3"}],"stream":true,"temperature":0.7,"stream_options":{"include_usage":true}}' + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Count + from 1 to 3","status":"completed"}],"stream":true,"temperature":0.7}' headers: User-Agent: - - Faraday v2.13.4 + - Faraday v2.12.2 Authorization: - Bearer Content-Type: @@ -24,48 +24,32 @@ http_interactions: message: OK headers: Date: - - Fri, 01 Aug 2025 10:07:40 GMT + - Wed, 06 Aug 2025 04:27:04 GMT Content-Type: - text/event-stream; charset=utf-8 Transfer-Encoding: - chunked Connection: - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID + Openai-Version: + - '2020-10-01' Openai-Organization: - "" - Openai-Processing-Ms: - - '125' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '178' - X-Ratelimit-Limit-Requests: - - '500' - X-Ratelimit-Limit-Tokens: - - '200000' - X-Ratelimit-Remaining-Requests: - - '499' - X-Ratelimit-Remaining-Tokens: - - '199993' - X-Ratelimit-Reset-Requests: - - 120ms - X-Ratelimit-Reset-Tokens: - - 2ms + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 X-Request-Id: - "" - X-Envoy-Decorator-Operation: - - router.openai.svc.cluster.local:5004/* + Openai-Processing-Ms: + - '90' + X-Envoy-Upstream-Service-Time: + - '93' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload Cf-Cache-Status: - DYNAMIC Set-Cookie: - "" - "" - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload X-Content-Type-Options: - nosniff Server: @@ -77,28 +61,51 @@ http_interactions: body: encoding: UTF-8 string: |+ - data: {"id":"chatcmpl-Bzgxo9bsYaqVXjPEjmrFGY8dc4wpg","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892d99853e881918f3c032eba11f2a40feeae24cc620b0e","object":"response","created_at":1754454424,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892d99853e881918f3c032eba11f2a40feeae24cc620b0e","object":"response","created_at":1754454424,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","output_index":0,"content_index":0,"delta":"1","logprobs":[],"obfuscation":"aK5Gvyx4ky8J4le"} - data: {"id":"chatcmpl-Bzgxo9bsYaqVXjPEjmrFGY8dc4wpg","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":"1"},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"l7Gvkj0TX1b3Jxx"} - data: {"id":"chatcmpl-Bzgxo9bsYaqVXjPEjmrFGY8dc4wpg","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"3a7EKPu8Aq5ka3O"} - data: {"id":"chatcmpl-Bzgxo9bsYaqVXjPEjmrFGY8dc4wpg","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","output_index":0,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"GdrcPR3dyWoaIQo"} - data: {"id":"chatcmpl-Bzgxo9bsYaqVXjPEjmrFGY8dc4wpg","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":"2"},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"Lz2f3eUUOmMN6T9"} - data: {"id":"chatcmpl-Bzgxo9bsYaqVXjPEjmrFGY8dc4wpg","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"wczn6mpyyjcePDZ"} - data: {"id":"chatcmpl-Bzgxo9bsYaqVXjPEjmrFGY8dc4wpg","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","output_index":0,"content_index":0,"delta":"3","logprobs":[],"obfuscation":"ihkSmzV3qhRfvYK"} - data: {"id":"chatcmpl-Bzgxo9bsYaqVXjPEjmrFGY8dc4wpg","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}],"usage":null} + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":11,"item_id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","output_index":0,"content_index":0,"text":"1, 2, 3","logprobs":[]} - data: {"id":"chatcmpl-Bzgxo9bsYaqVXjPEjmrFGY8dc4wpg","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":12,"item_id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}} - data: {"id":"chatcmpl-Bzgxo9bsYaqVXjPEjmrFGY8dc4wpg","object":"chat.completion.chunk","created":1754042860,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_38343a2f8f","choices":[],"usage":{"prompt_tokens":14,"completion_tokens":7,"total_tokens":21,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":13,"output_index":0,"item":{"id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}],"role":"assistant"}} - data: [DONE] + event: response.completed + data: {"type":"response.completed","sequence_number":14,"response":{"id":"resp_6892d99853e881918f3c032eba11f2a40feeae24cc620b0e","object":"response","created_at":1754454424,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_6892d9989c588191931b7a70b31bf9ed0feeae24cc620b0e","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":14,"input_tokens_details":{"cached_tokens":0},"output_tokens":8,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":22},"user":null,"metadata":{}}} - recorded_at: Fri, 01 Aug 2025 10:07:40 GMT + recorded_at: Wed, 06 Aug 2025 04:27:04 GMT recorded_with: VCR 6.3.1 ... diff --git a/spec/ruby_llm/chat_streaming_spec.rb b/spec/ruby_llm/chat_streaming_spec.rb index 915b6dbb2..ecccff514 100644 --- a/spec/ruby_llm/chat_streaming_spec.rb +++ b/spec/ruby_llm/chat_streaming_spec.rb @@ -29,6 +29,10 @@ end it "#{provider}/#{model} reports consistent token counts compared to non-streaming" do + if provider == :openai + skip 'OpenAI Responses API does not return usage during streaming. ' \ + 'Skipping token consistency check.' + end if provider == :deepseek skip 'DeepSeek API returns different content/tokens for stream vs sync with this prompt. ' \ 'Skipping token consistency check.' From d00cc38198a00c03186cfa9a0de574169747c8f0 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 21:47:58 -0700 Subject: [PATCH 13/27] Update error handling with responses --- ...pports_handling_streaming_error_chunks.yml | 111 +++++++++++++++++ ...pports_handling_streaming_error_events.yml | 111 +++++++++++++++++ ...pports_handling_streaming_error_chunks.yml | 111 +++++++++++++++++ ...pports_handling_streaming_error_events.yml | 114 ++++++++++++++++++ spec/support/streaming_error_helpers.rb | 2 +- 5 files changed, 448 insertions(+), 1 deletion(-) create mode 100644 spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_1_openai_gpt-4_1-nano_supports_handling_streaming_error_chunks.yml create mode 100644 spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_1_openai_gpt-4_1-nano_supports_handling_streaming_error_events.yml create mode 100644 spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_2_openai_gpt-4_1-nano_supports_handling_streaming_error_chunks.yml create mode 100644 spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_2_openai_gpt-4_1-nano_supports_handling_streaming_error_events.yml diff --git a/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_1_openai_gpt-4_1-nano_supports_handling_streaming_error_chunks.yml b/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_1_openai_gpt-4_1-nano_supports_handling_streaming_error_chunks.yml new file mode 100644 index 000000000..faa3d031e --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_1_openai_gpt-4_1-nano_supports_handling_streaming_error_chunks.yml @@ -0,0 +1,111 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Count + from 1 to 3","status":"completed"}],"stream":true,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 04:43:14 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '132' + X-Envoy-Upstream-Service-Time: + - '143' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892dd62448481a384828336d3fe0b7b047e09c320bbe75a","object":"response","created_at":1754455394,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892dd62448481a384828336d3fe0b7b047e09c320bbe75a","object":"response","created_at":1754455394,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","output_index":0,"content_index":0,"delta":"1","logprobs":[],"obfuscation":"xGCGvmwq87TJwWs"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"mFYb0D2kCnxuePR"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"evsG4EhC7sSWC4C"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","output_index":0,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"oXTJTXgxrernqUf"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"7Frt2Ob97Uew0fi"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"GK36mKb6rIcZooE"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","output_index":0,"content_index":0,"delta":"3","logprobs":[],"obfuscation":"mmnUOxF5opiz5yh"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":11,"item_id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","output_index":0,"content_index":0,"text":"1, 2, 3","logprobs":[]} + + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":12,"item_id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":13,"output_index":0,"item":{"id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":14,"response":{"id":"resp_6892dd62448481a384828336d3fe0b7b047e09c320bbe75a","object":"response","created_at":1754455394,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_6892dd6291cc81a3895ee28ca04f25c8047e09c320bbe75a","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":14,"input_tokens_details":{"cached_tokens":0},"output_tokens":8,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":22},"user":null,"metadata":{}}} + + recorded_at: Wed, 06 Aug 2025 04:43:14 GMT +recorded_with: VCR 6.3.1 +... diff --git a/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_1_openai_gpt-4_1-nano_supports_handling_streaming_error_events.yml b/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_1_openai_gpt-4_1-nano_supports_handling_streaming_error_events.yml new file mode 100644 index 000000000..8b619b9db --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_1_openai_gpt-4_1-nano_supports_handling_streaming_error_events.yml @@ -0,0 +1,111 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Count + from 1 to 3","status":"completed"}],"stream":true,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 04:43:15 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '62' + X-Envoy-Upstream-Service-Time: + - '66' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892dd632ba48192b9683788fef3abaf0a7bee1c921bbf17","object":"response","created_at":1754455395,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892dd632ba48192b9683788fef3abaf0a7bee1c921bbf17","object":"response","created_at":1754455395,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","output_index":0,"content_index":0,"delta":"1","logprobs":[],"obfuscation":"1jvkgl1vuOfBDZM"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"JMOMb7rTQAoEy2A"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"okhAIZcDX5L3YIw"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","output_index":0,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"F3gYNao8IXG1YU3"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"zimjj32SR4u7YBn"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"iqA7bF39p9sRrkL"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","output_index":0,"content_index":0,"delta":"3","logprobs":[],"obfuscation":"rG8ktUIqudRvKWR"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":11,"item_id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","output_index":0,"content_index":0,"text":"1, 2, 3","logprobs":[]} + + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":12,"item_id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":13,"output_index":0,"item":{"id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":14,"response":{"id":"resp_6892dd632ba48192b9683788fef3abaf0a7bee1c921bbf17","object":"response","created_at":1754455395,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_6892dd63c6188192a3c78cf60df622d30a7bee1c921bbf17","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":14,"input_tokens_details":{"cached_tokens":0},"output_tokens":8,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":22},"user":null,"metadata":{}}} + + recorded_at: Wed, 06 Aug 2025 04:43:15 GMT +recorded_with: VCR 6.3.1 +... diff --git a/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_2_openai_gpt-4_1-nano_supports_handling_streaming_error_chunks.yml b/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_2_openai_gpt-4_1-nano_supports_handling_streaming_error_chunks.yml new file mode 100644 index 000000000..0a6bf6129 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_2_openai_gpt-4_1-nano_supports_handling_streaming_error_chunks.yml @@ -0,0 +1,111 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Count + from 1 to 3","status":"completed"}],"stream":true,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 04:43:16 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '53' + X-Envoy-Upstream-Service-Time: + - '56' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892dd645800819ca1af210d5db4f2ec05a756a2c9a1a806","object":"response","created_at":1754455396,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892dd645800819ca1af210d5db4f2ec05a756a2c9a1a806","object":"response","created_at":1754455396,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","output_index":0,"content_index":0,"delta":"1","logprobs":[],"obfuscation":"pGLlX0qM6FkdQN2"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"3Qr9PqEKwpVbnFm"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"vAk5Z2ou5LlFKVZ"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","output_index":0,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"N1C9PR8bSQpIoTB"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"H3U5CfdM9AmvFI4"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"z0r18nVXl5x5ZnQ"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","output_index":0,"content_index":0,"delta":"3","logprobs":[],"obfuscation":"SD5pp1b28LloDSB"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":11,"item_id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","output_index":0,"content_index":0,"text":"1, 2, 3","logprobs":[]} + + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":12,"item_id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":13,"output_index":0,"item":{"id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":14,"response":{"id":"resp_6892dd645800819ca1af210d5db4f2ec05a756a2c9a1a806","object":"response","created_at":1754455396,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_6892dd64978c819c84679f38cde7813805a756a2c9a1a806","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":14,"input_tokens_details":{"cached_tokens":0},"output_tokens":8,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":22},"user":null,"metadata":{}}} + + recorded_at: Wed, 06 Aug 2025 04:43:16 GMT +recorded_with: VCR 6.3.1 +... diff --git a/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_2_openai_gpt-4_1-nano_supports_handling_streaming_error_events.yml b/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_2_openai_gpt-4_1-nano_supports_handling_streaming_error_events.yml new file mode 100644 index 000000000..d765c249e --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_faraday_version_2_openai_gpt-4_1-nano_supports_handling_streaming_error_events.yml @@ -0,0 +1,114 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Count + from 1 to 3","status":"completed"}],"stream":true,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 04:43:17 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '49' + X-Envoy-Upstream-Service-Time: + - '53' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892dd6527d0819f95827a61389947300cfea00a519174ba","object":"response","created_at":1754455397,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892dd6527d0819f95827a61389947300cfea00a519174ba","object":"response","created_at":1754455397,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","output_index":0,"content_index":0,"delta":"1","logprobs":[],"obfuscation":"GU9qIwg0aDjdVCq"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"aYawzhrY50iRP1Q"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"xpaStJlD59zzNDA"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","output_index":0,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"rhVFGU3aUhOWYbF"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"fSLxjVHqiXNXT8o"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"2zQPK0y1U5WkAdn"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","output_index":0,"content_index":0,"delta":"3","logprobs":[],"obfuscation":"836rw93xxs1M2bP"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"HtVciHOtx3hkJt0"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":12,"item_id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","output_index":0,"content_index":0,"text":"1, 2, 3.","logprobs":[]} + + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":13,"item_id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3."}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":14,"output_index":0,"item":{"id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3."}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":15,"response":{"id":"resp_6892dd6527d0819f95827a61389947300cfea00a519174ba","object":"response","created_at":1754455397,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_6892dd655f20819f944bb34c53b24e020cfea00a519174ba","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":14,"input_tokens_details":{"cached_tokens":0},"output_tokens":9,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":23},"user":null,"metadata":{}}} + + recorded_at: Wed, 06 Aug 2025 04:43:17 GMT +recorded_with: VCR 6.3.1 +... diff --git a/spec/support/streaming_error_helpers.rb b/spec/support/streaming_error_helpers.rb index 54d102734..89499f6a3 100644 --- a/spec/support/streaming_error_helpers.rb +++ b/spec/support/streaming_error_helpers.rb @@ -15,7 +15,7 @@ module StreamingErrorHelpers expected_error: RubyLLM::OverloadedError }, openai: { - url: 'https://api.openai.com/v1/chat/completions', + url: 'https://api.openai.com/v1/responses', error_response: { error: { message: 'The server is temporarily overloaded. Please try again later.', From 928b1c1abe6404cd9a48314b183dd00f37d6ef7d Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 22:10:18 -0700 Subject: [PATCH 14/27] Handle chunks from responses when streaming --- lib/ruby_llm/providers/openai/streaming.rb | 145 +++++ ...ith_multi-turn_streaming_conversations.yml | 557 ++++++++++++++++++ ..._in_multi-turn_streaming_conversations.yml | 429 ++++++++++++++ ..._1-nano_handles_complex_nested_schemas.yml | 193 ++++++ 4 files changed, 1324 insertions(+) create mode 100644 spec/fixtures/vcr_cassettes/chat_with_schema_complex_schemas_openai_gpt-4_1-nano_handles_complex_nested_schemas.yml diff --git a/lib/ruby_llm/providers/openai/streaming.rb b/lib/ruby_llm/providers/openai/streaming.rb index d7d0461ee..2faa3ae2f 100644 --- a/lib/ruby_llm/providers/openai/streaming.rb +++ b/lib/ruby_llm/providers/openai/streaming.rb @@ -16,6 +16,71 @@ def responses_stream_url end def build_chunk(data) + # Check if this is responses API format vs chat completions format + if data['type'] # Responses API has a 'type' field + build_responses_chunk(data) + else + build_chat_completions_chunk(data) + end + end + + def build_responses_chunk(data) + case data['type'] + when 'response.text.delta' + # Text content delta - deprecated format + Chunk.new( + role: :assistant, + model_id: data.dig('response', 'model'), + content: data['delta'], + tool_calls: nil, + input_tokens: nil, + output_tokens: nil + ) + when 'response.output_text.delta' + # Text content delta - new format + Chunk.new( + role: :assistant, + model_id: nil, # Model is in the completion event + content: data['delta'], + tool_calls: nil, + input_tokens: nil, + output_tokens: nil + ) + when 'response.function_call_arguments.delta' + # Tool call arguments delta - handled by accumulator + # We need to track these deltas to build up the complete tool call + build_tool_call_delta_chunk(data) + when 'response.output_item.added' + # New tool call or message starting + if data.dig('item', 'type') == 'function_call' + build_tool_call_start_chunk(data) + else + build_empty_chunk(data) + end + when 'response.output_item.done' + # Tool call or message completed + if data.dig('item', 'type') == 'function_call' + build_tool_call_complete_chunk(data) + else + build_empty_chunk(data) + end + when 'response.completed' + # Final response with usage stats + Chunk.new( + role: :assistant, + model_id: data.dig('response', 'model'), + content: nil, + tool_calls: nil, + input_tokens: data.dig('response', 'usage', 'input_tokens'), + output_tokens: data.dig('response', 'usage', 'output_tokens') + ) + else + # Other event types (response.created, response.in_progress, etc.) + build_empty_chunk(data) + end + end + + def build_chat_completions_chunk(data) Chunk.new( role: :assistant, model_id: data['model'], @@ -26,6 +91,86 @@ def build_chunk(data) ) end + def build_tool_call_delta_chunk(data) + # For tool call argument deltas, we need to create a partial tool call + # The accumulator will handle building up the complete arguments + tool_call_data = { + 'id' => data['item_id'], + 'function' => { + 'name' => '', # Name comes from the initial item.added event + 'arguments' => data['delta'] || '' + } + } + + Chunk.new( + role: :assistant, + model_id: nil, + content: nil, + tool_calls: { data['item_id'] => create_streaming_tool_call(tool_call_data) }, + input_tokens: nil, + output_tokens: nil + ) + end + + def build_tool_call_start_chunk(data) + item = data['item'] + tool_call_data = { + 'id' => item['id'], + 'function' => { + 'name' => item['name'], + 'arguments' => item['arguments'] || '' + } + } + + Chunk.new( + role: :assistant, + model_id: nil, + content: nil, + tool_calls: { item['id'] => create_streaming_tool_call(tool_call_data) }, + input_tokens: nil, + output_tokens: nil + ) + end + + def build_tool_call_complete_chunk(data) + item = data['item'] + tool_call_data = { + 'id' => item['id'], + 'function' => { + 'name' => item['name'], + 'arguments' => item['arguments'] || '' + } + } + + Chunk.new( + role: :assistant, + model_id: nil, + content: nil, + tool_calls: { item['id'] => create_streaming_tool_call(tool_call_data) }, + input_tokens: nil, + output_tokens: nil + ) + end + + def build_empty_chunk(data) + Chunk.new( + role: :assistant, + model_id: data.dig('response', 'model'), + content: nil, + tool_calls: nil, + input_tokens: nil, + output_tokens: nil + ) + end + + def create_streaming_tool_call(tool_call_data) + ToolCall.new( + id: tool_call_data['id'], + name: tool_call_data.dig('function', 'name'), + arguments: tool_call_data.dig('function', 'arguments') + ) + end + def parse_streaming_error(data) error_data = JSON.parse(data) return unless error_data['error'] diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_with_multi-turn_streaming_conversations.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_with_multi-turn_streaming_conversations.yml index 9fc68ed4f..d9e89b701 100644 --- a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_with_multi-turn_streaming_conversations.yml +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_with_multi-turn_streaming_conversations.yml @@ -410,4 +410,561 @@ http_interactions: string: !binary |- ZGF0YTogeyJpZCI6ImNoYXRjbXBsLUJ6aGlmTWpOcFhjQ2pwcVdQZVh1bzh2d1h5R2E1Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NDA0NTc2NSwibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF8zODM0M2EyZjhmIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiIiwicmVmdXNhbCI6bnVsbH0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsfQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUJ6aGlmTWpOcFhjQ2pwcVdQZVh1bzh2d1h5R2E1Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NDA0NTc2NSwibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF8zODM0M2EyZjhmIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiJUaGUifSwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOm51bGx9XSwidXNhZ2UiOm51bGx9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQnpoaWZNak5wWGNDanBxV1BlWHVvOHZ3WHlHYTUiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU0MDQ1NzY1LCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwXzM4MzQzYTJmOGYiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6IiBjdXJyZW50In0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsfQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUJ6aGlmTWpOcFhjQ2pwcVdQZVh1bzh2d1h5R2E1Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NDA0NTc2NSwibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF8zODM0M2EyZjhmIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiIgd2VhdGhlciJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbH0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1CemhpZk1qTnBYY0NqcHFXUGVYdW84dndYeUdhNSIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTQwNDU3NjUsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfMzgzNDNhMmY4ZiIsImNob2ljZXMiOlt7ImluZGV4IjowLCJkZWx0YSI6eyJjb250ZW50IjoiIGluIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsfQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUJ6aGlmTWpOcFhjQ2pwcVdQZVh1bzh2d1h5R2E1Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NDA0NTc2NSwibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF8zODM0M2EyZjhmIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiIgUGFyaXMifSwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOm51bGx9XSwidXNhZ2UiOm51bGx9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQnpoaWZNak5wWGNDanBxV1BlWHVvOHZ3WHlHYTUiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU0MDQ1NzY1LCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwXzM4MzQzYTJmOGYiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6IiBpcyJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbH0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1CemhpZk1qTnBYY0NqcHFXUGVYdW84dndYeUdhNSIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTQwNDU3NjUsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfMzgzNDNhMmY4ZiIsImNob2ljZXMiOlt7ImluZGV4IjowLCJkZWx0YSI6eyJjb250ZW50IjoiICJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbH0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1CemhpZk1qTnBYY0NqcHFXUGVYdW84dndYeUdhNSIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTQwNDU3NjUsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfMzgzNDNhMmY4ZiIsImNob2ljZXMiOlt7ImluZGV4IjowLCJkZWx0YSI6eyJjb250ZW50IjoiMTUifSwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOm51bGx9XSwidXNhZ2UiOm51bGx9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQnpoaWZNak5wWGNDanBxV1BlWHVvOHZ3WHlHYTUiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU0MDQ1NzY1LCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwXzM4MzQzYTJmOGYiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6IsKwQyJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbH0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1CemhpZk1qTnBYY0NqcHFXUGVYdW84dndYeUdhNSIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTQwNDU3NjUsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfMzgzNDNhMmY4ZiIsImNob2ljZXMiOlt7ImluZGV4IjowLCJkZWx0YSI6eyJjb250ZW50IjoiIHdpdGgifSwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOm51bGx9XSwidXNhZ2UiOm51bGx9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQnpoaWZNak5wWGNDanBxV1BlWHVvOHZ3WHlHYTUiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU0MDQ1NzY1LCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwXzM4MzQzYTJmOGYiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6IiBhIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsfQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUJ6aGlmTWpOcFhjQ2pwcVdQZVh1bzh2d1h5R2E1Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NDA0NTc2NSwibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF8zODM0M2EyZjhmIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiIgd2luZCJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbH0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1CemhpZk1qTnBYY0NqcHFXUGVYdW84dndYeUdhNSIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTQwNDU3NjUsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfMzgzNDNhMmY4ZiIsImNob2ljZXMiOlt7ImluZGV4IjowLCJkZWx0YSI6eyJjb250ZW50IjoiIHNwZWVkIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsfQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUJ6aGlmTWpOcFhjQ2pwcVdQZVh1bzh2d1h5R2E1Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NDA0NTc2NSwibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF8zODM0M2EyZjhmIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiIgb2YifSwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOm51bGx9XSwidXNhZ2UiOm51bGx9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQnpoaWZNak5wWGNDanBxV1BlWHVvOHZ3WHlHYTUiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU0MDQ1NzY1LCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwXzM4MzQzYTJmOGYiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6IiAifSwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOm51bGx9XSwidXNhZ2UiOm51bGx9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQnpoaWZNak5wWGNDanBxV1BlWHVvOHZ3WHlHYTUiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU0MDQ1NzY1LCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwXzM4MzQzYTJmOGYiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6IjEwIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsfQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUJ6aGlmTWpOcFhjQ2pwcVdQZVh1bzh2d1h5R2E1Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NDA0NTc2NSwibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF8zODM0M2EyZjhmIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiIga20ifSwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOm51bGx9XSwidXNhZ2UiOm51bGx9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQnpoaWZNak5wWGNDanBxV1BlWHVvOHZ3WHlHYTUiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU0MDQ1NzY1LCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwXzM4MzQzYTJmOGYiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6Ii9oIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsfQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUJ6aGlmTWpOcFhjQ2pwcVdQZVh1bzh2d1h5R2E1Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NDA0NTc2NSwibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF8zODM0M2EyZjhmIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiIuIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsfQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUJ6aGlmTWpOcFhjQ2pwcVdQZVh1bzh2d1h5R2E1Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NDA0NTc2NSwibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF8zODM0M2EyZjhmIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7fSwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOiJzdG9wIn1dLCJ1c2FnZSI6bnVsbH0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1CemhpZk1qTnBYY0NqcHFXUGVYdW84dndYeUdhNSIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTQwNDU3NjUsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfMzgzNDNhMmY4ZiIsImNob2ljZXMiOltdLCJ1c2FnZSI6eyJwcm9tcHRfdG9rZW5zIjoyNDMsImNvbXBsZXRpb25fdG9rZW5zIjoyMCwidG90YWxfdG9rZW5zIjoyNjMsInByb21wdF90b2tlbnNfZGV0YWlscyI6eyJjYWNoZWRfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjB9LCJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjp7InJlYXNvbmluZ190b2tlbnMiOjAsImF1ZGlvX3Rva2VucyI6MCwiYWNjZXB0ZWRfcHJlZGljdGlvbl90b2tlbnMiOjAsInJlamVjdGVkX3ByZWRpY3Rpb25fdG9rZW5zIjowfX19CgpkYXRhOiBbRE9ORV0KCg== recorded_at: Fri, 01 Aug 2025 10:56:06 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"}],"stream":true,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 04:48:08 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '53' + X-Envoy-Upstream-Service-Time: + - '56' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892de882e9c81a099298b297213ea3d0175291c25f20381","object":"response","created_at":1754455688,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892de882e9c81a099298b297213ea3d0175291c25f20381","object":"response","created_at":1754455688,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","type":"function_call","status":"in_progress","arguments":"","call_id":"call_e7erFBLodAOeMIeKd6h0HpwJ","name":"weather"}} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":3,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"{","obfuscation":"YaVV0BorRE5oHiX"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":4,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"\"latitude","obfuscation":"Geh3BJg"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"\":","obfuscation":"Bc0ymQXyT8DWEH"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"\"52","obfuscation":"BtMS1VbmC5YxW"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":".","obfuscation":"Edz6odAuxNpwtPL"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"520","obfuscation":"d5BAWThNiYGNn"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"0","obfuscation":"zHGtjUsTJ8Qj3SX"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":10,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"\",","obfuscation":"tsRjjX7cmNBkqo"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":11,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"\"longitude","obfuscation":"k4tvgQ"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":12,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"\":","obfuscation":"DI9VAPXZ2uwDXL"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":13,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"\"13","obfuscation":"nCtHb7VHNCbpq"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":14,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":".","obfuscation":"J0kFGvj4p3j7cSV"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":15,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"405","obfuscation":"xfFZxZalH5Q9a"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":16,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"0","obfuscation":"Tk1zwsOJD837fMw"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":17,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"delta":"\"}","obfuscation":"50cZgFYqqzF6Ki"} + + event: response.function_call_arguments.done + data: {"type":"response.function_call_arguments.done","sequence_number":18,"item_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output_index":0,"arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}"} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":19,"output_index":0,"item":{"id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","type":"function_call","status":"completed","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","call_id":"call_e7erFBLodAOeMIeKd6h0HpwJ","name":"weather"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":20,"response":{"id":"resp_6892de882e9c81a099298b297213ea3d0175291c25f20381","object":"response","created_at":1754455688,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","type":"function_call","status":"completed","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","call_id":"call_e7erFBLodAOeMIeKd6h0HpwJ","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":82,"input_tokens_details":{"cached_tokens":0},"output_tokens":40,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":122},"user":null,"metadata":{}}} + + recorded_at: Wed, 06 Aug 2025 04:48:09 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"}],"stream":true,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 05:03:15 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '686' + X-Envoy-Upstream-Service-Time: + - '758' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892e2135160819fa0cb843ac1cb6e4a0d8f8183ade38c24","object":"response","created_at":1754456595,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892e2135160819fa0cb843ac1cb6e4a0d8f8183ade38c24","object":"response","created_at":1754456595,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"ibpFBxAQleln1"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" current","logprobs":[],"obfuscation":"Ohjsf0uO"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" weather","logprobs":[],"obfuscation":"kqLkwy16"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"MbS9O0ejb1xFU"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" Berlin","logprobs":[],"obfuscation":"jeoGuzkfD"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"z47TEzvV93xBQ"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"6jImZhc9XAoFX3c"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":"15","logprobs":[],"obfuscation":"H3cwmXtTF7TeLp"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":"°C","logprobs":[],"obfuscation":"acilnRe8FcqWSY"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" with","logprobs":[],"obfuscation":"cRJtGs0nAFG"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"wUA5ExCsdYtbDc"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" wind","logprobs":[],"obfuscation":"8dAFKBTr6If"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" speed","logprobs":[],"obfuscation":"QyqmunAz5E"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"CwzqpsQzpHSyD"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"UFz9dhlqKZtbK0Q"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":"10","logprobs":[],"obfuscation":"KzfUzypB5QV1DE"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":" km","logprobs":[],"obfuscation":"zk5E69q3fprQv"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":"/h","logprobs":[],"obfuscation":"64bkjS9Ef2v9fm"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"O7p9IOWOEN7v4f9"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":23,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"text":"The current weather in Berlin is 15°C with a wind speed of 10 km/h.","logprobs":[]} + + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":24,"item_id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The current weather in Berlin is 15°C with a wind speed of 10 km/h."}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":25,"output_index":0,"item":{"id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current weather in Berlin is 15°C with a wind speed of 10 km/h."}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":26,"response":{"id":"resp_6892e2135160819fa0cb843ac1cb6e4a0d8f8183ade38c24","object":"response","created_at":1754456595,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_6892e2154ff0819f998fa892fdec71af0d8f8183ade38c24","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current weather in Berlin is 15°C with a wind speed of 10 km/h."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":135,"input_tokens_details":{"cached_tokens":0},"output_tokens":21,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":156},"user":null,"metadata":{}}} + + recorded_at: Wed, 06 Aug 2025 05:03:17 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"},{"type":"message","role":"assistant","content":"The + current weather in Berlin is 15°C with a wind speed of 10 km/h.","status":"completed"},{"type":"message","role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)","status":"completed"}],"stream":true,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 05:03:56 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '120' + X-Envoy-Upstream-Service-Time: + - '130' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892e23cd00c819caf99bed75381d65d0913884e263aa147","object":"response","created_at":1754456636,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892e23cd00c819caf99bed75381d65d0913884e263aa147","object":"response","created_at":1754456636,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","type":"function_call","status":"in_progress","arguments":"","call_id":"call_yQDWqIjycn01jm2QDH0tVuRC","name":"weather"}} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":3,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"{\"","obfuscation":"H6p7Tsx6U4CDMb"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":4,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"latitude","obfuscation":"GrKsIXSg"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"\":\"","obfuscation":"2MU4Cj8qn7f6r"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"48","obfuscation":"nsj6A4tQiDegCO"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":".","obfuscation":"98tbbIWjDrEcW7U"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"857","obfuscation":"TB21g6RYeRtIN"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"5","obfuscation":"LJr4ciYsUTz27uz"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":10,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"\",\"","obfuscation":"9Kf0hbrAnbJPK"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":11,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"longitude","obfuscation":"HXs01N4"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":12,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"\":\"","obfuscation":"BPTyr70X7uWLm"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":13,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"2","obfuscation":"pIocor7TOtJg1lI"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":14,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":".","obfuscation":"6w8TG16Gh2xP1mZ"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":15,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"351","obfuscation":"ph6buwyv9hdHO"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":16,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"4","obfuscation":"0uSQ2a1TirbeAPF"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":17,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"delta":"\"}","obfuscation":"RUk0su4kvacjRw"} + + event: response.function_call_arguments.done + data: {"type":"response.function_call_arguments.done","sequence_number":18,"item_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output_index":0,"arguments":"{\"latitude\":\"48.8575\",\"longitude\":\"2.3514\"}"} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":19,"output_index":0,"item":{"id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","type":"function_call","status":"completed","arguments":"{\"latitude\":\"48.8575\",\"longitude\":\"2.3514\"}","call_id":"call_yQDWqIjycn01jm2QDH0tVuRC","name":"weather"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":20,"response":{"id":"resp_6892e23cd00c819caf99bed75381d65d0913884e263aa147","object":"response","created_at":1754456636,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","type":"function_call","status":"completed","arguments":"{\"latitude\":\"48.8575\",\"longitude\":\"2.3514\"}","call_id":"call_yQDWqIjycn01jm2QDH0tVuRC","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":180,"input_tokens_details":{"cached_tokens":0},"output_tokens":24,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":204},"user":null,"metadata":{}}} + + recorded_at: Wed, 06 Aug 2025 05:03:57 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"fc_6892de88a52081a0a155618e248085a00175291c25f20381","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"},{"type":"message","role":"assistant","content":"The + current weather in Berlin is 15°C with a wind speed of 10 km/h.","status":"completed"},{"type":"message","role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)","status":"completed"},{"type":"function_call","call_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","name":"weather","arguments":"{\"latitude\":\"48.8575\",\"longitude\":\"2.3514\"}","status":"completed"},{"type":"function_call_output","call_id":"fc_6892e23d35e4819cba5487948d2196830913884e263aa147","output":"Current + weather at 48.8575, 2.3514: 15°C, Wind: 10 km/h","status":"completed"}],"stream":true,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 05:03:58 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '55' + X-Envoy-Upstream-Service-Time: + - '59' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892e23e4ae0819c863f1436e00ed3f1034d7c8a463b2321","object":"response","created_at":1754456638,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892e23e4ae0819c863f1436e00ed3f1034d7c8a463b2321","object":"response","created_at":1754456638,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"aBXAJfvoFjyoY"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" current","logprobs":[],"obfuscation":"2NBN8xiz"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" weather","logprobs":[],"obfuscation":"3sdqUTYi"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"8rFcLhrc7f9C7"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" Paris","logprobs":[],"obfuscation":"Ua8XRNTzuc"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"stD9ZQ983hpLZ"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"GBcMUJCBHGbm8T5"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":"15","logprobs":[],"obfuscation":"VPFnqdZGTLUCs8"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":"°C","logprobs":[],"obfuscation":"zzUDsrZdlrWJ19"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" with","logprobs":[],"obfuscation":"wYrKhcjOUly"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"CnMtbpOTRuHfzg"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" wind","logprobs":[],"obfuscation":"ZFndkwQsWDZ"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" speed","logprobs":[],"obfuscation":"x04KYxSQAt"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"4HUPO7j5YBfF3"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"hEvb8mT88XVnx5v"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":"10","logprobs":[],"obfuscation":"59T2zDNLZjvexM"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":" km","logprobs":[],"obfuscation":"Mi8gIMu7585IK"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":"/h","logprobs":[],"obfuscation":"o5O1zyndWDknej"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"1MaT2HxFwDMB5Fu"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":23,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"text":"The current weather in Paris is 15°C with a wind speed of 10 km/h.","logprobs":[]} + + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":24,"item_id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The current weather in Paris is 15°C with a wind speed of 10 km/h."}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":25,"output_index":0,"item":{"id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current weather in Paris is 15°C with a wind speed of 10 km/h."}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":26,"response":{"id":"resp_6892e23e4ae0819c863f1436e00ed3f1034d7c8a463b2321","object":"response","created_at":1754456638,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_6892e23e8f54819cb1cd8f338810bae4034d7c8a463b2321","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current weather in Paris is 15°C with a wind speed of 10 km/h."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":233,"input_tokens_details":{"cached_tokens":0},"output_tokens":21,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":254},"user":null,"metadata":{}}} + + recorded_at: Wed, 06 Aug 2025 05:03:58 GMT recorded_with: VCR 6.3.1 +... diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters_in_multi-turn_streaming_conversations.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters_in_multi-turn_streaming_conversations.yml index 59006375b..ee694cfb2 100644 --- a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters_in_multi-turn_streaming_conversations.yml +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters_in_multi-turn_streaming_conversations.yml @@ -288,5 +288,434 @@ http_interactions: data: [DONE] recorded_at: Fri, 01 Aug 2025 10:55:05 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must use tools whenever possible.","status":"completed"},{"type":"message","role":"user","content":"What''s + the best language to learn?","status":"completed"}],"stream":true,"temperature":0.7,"tools":[{"type":"function","name":"best_language_to_learn","description":"Gets + the best language to learn","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 04:48:06 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '46' + X-Envoy-Upstream-Service-Time: + - '49' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892de86ea40819d938170f242be83af0a8154cbda9d1dab","object":"response","created_at":1754455686,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892de86ea40819d938170f242be83af0a8154cbda9d1dab","object":"response","created_at":1754455686,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"fc_6892de874888819d9590a8986c12de100a8154cbda9d1dab","type":"function_call","status":"in_progress","arguments":"","call_id":"call_qJdYTpVjL7Dg6PIa7lYYtYOA","name":"best_language_to_learn"}} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":3,"item_id":"fc_6892de874888819d9590a8986c12de100a8154cbda9d1dab","output_index":0,"delta":"{}","obfuscation":"2stuQEx3oqtMte"} + + event: response.function_call_arguments.done + data: {"type":"response.function_call_arguments.done","sequence_number":4,"item_id":"fc_6892de874888819d9590a8986c12de100a8154cbda9d1dab","output_index":0,"arguments":"{}"} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":5,"output_index":0,"item":{"id":"fc_6892de874888819d9590a8986c12de100a8154cbda9d1dab","type":"function_call","status":"completed","arguments":"{}","call_id":"call_qJdYTpVjL7Dg6PIa7lYYtYOA","name":"best_language_to_learn"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":6,"response":{"id":"resp_6892de86ea40819d938170f242be83af0a8154cbda9d1dab","object":"response","created_at":1754455686,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"fc_6892de874888819d9590a8986c12de100a8154cbda9d1dab","type":"function_call","status":"completed","arguments":"{}","call_id":"call_qJdYTpVjL7Dg6PIa7lYYtYOA","name":"best_language_to_learn"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":53,"input_tokens_details":{"cached_tokens":0},"output_tokens":14,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":67},"user":null,"metadata":{}}} + + recorded_at: Wed, 06 Aug 2025 04:48:07 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must use tools whenever possible.","status":"completed"},{"type":"message","role":"user","content":"What''s + the best language to learn?","status":"completed"},{"type":"function_call","call_id":"fc_6892de874888819d9590a8986c12de100a8154cbda9d1dab","name":"best_language_to_learn","arguments":"{}","status":"completed"},{"type":"function_call_output","call_id":"fc_6892de874888819d9590a8986c12de100a8154cbda9d1dab","output":"Ruby","status":"completed"}],"stream":true,"temperature":0.7,"tools":[{"type":"function","name":"best_language_to_learn","description":"Gets + the best language to learn","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 05:03:13 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '71' + X-Envoy-Upstream-Service-Time: + - '74' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892e211bed081a1b35df7b1e429bffb06ed94e02a117e47","object":"response","created_at":1754456593,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892e211bed081a1b35df7b1e429bffb06ed94e02a117e47","object":"response","created_at":1754456593,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"4Q02JGWcqqGk4"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" best","logprobs":[],"obfuscation":"dbITiZ9fDwb"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" language","logprobs":[],"obfuscation":"gVvwGB4"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"TddHzTNquAiTR"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" learn","logprobs":[],"obfuscation":"6Bw1zBWVsY"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"six7lZ86jWTYT"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" Ruby","logprobs":[],"obfuscation":"Gpwyu2zsBlG"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"ZNiNcopLBHpDmsw"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" Would","logprobs":[],"obfuscation":"JBOf5dYRlh"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" you","logprobs":[],"obfuscation":"tS38Og0s4QyO"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" like","logprobs":[],"obfuscation":"HtTKHyc8bzG"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"1H0FRRx5E6gBq"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" know","logprobs":[],"obfuscation":"nP66sY0df3M"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" more","logprobs":[],"obfuscation":"qo6TqGz10ea"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" about","logprobs":[],"obfuscation":"0uVr3gm12b"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" why","logprobs":[],"obfuscation":"qzLRLxSjz4k0"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" Ruby","logprobs":[],"obfuscation":"wBIFO594JV0"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"QqxswtxswMbaq"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"tLDnjLi1HEIo6w"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" great","logprobs":[],"obfuscation":"6OtTvh5DRr"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" choice","logprobs":[],"obfuscation":"YPwhFxfMy"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"jcxjbmVKpdj50"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" how","logprobs":[],"obfuscation":"vnwlYQ1SJAtI"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"G74qeCtZVrbme"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" get","logprobs":[],"obfuscation":"bc2alEt4fugI"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" started","logprobs":[],"obfuscation":"kDZjdfxp"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" with","logprobs":[],"obfuscation":"tmUggrZAjCY"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":" it","logprobs":[],"obfuscation":"jwoRsyJnpTjIa"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":32,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"delta":"?","logprobs":[],"obfuscation":"KmdzSYAaO9FmISm"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":33,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"text":"The best language to learn is Ruby. Would you like to know more about why Ruby is a great choice or how to get started with it?","logprobs":[]} + + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":34,"item_id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The best language to learn is Ruby. Would you like to know more about why Ruby is a great choice or how to get started with it?"}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":35,"output_index":0,"item":{"id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The best language to learn is Ruby. Would you like to know more about why Ruby is a great choice or how to get started with it?"}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":36,"response":{"id":"resp_6892e211bed081a1b35df7b1e429bffb06ed94e02a117e47","object":"response","created_at":1754456593,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_6892e2126ea881a191a1ece390caa51d06ed94e02a117e47","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The best language to learn is Ruby. Would you like to know more about why Ruby is a great choice or how to get started with it?"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":76,"input_tokens_details":{"cached_tokens":0},"output_tokens":31,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":107},"user":null,"metadata":{}}} + + recorded_at: Wed, 06 Aug 2025 05:03:14 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must use tools whenever possible.","status":"completed"},{"type":"message","role":"user","content":"What''s + the best language to learn?","status":"completed"},{"type":"function_call","call_id":"fc_6892de874888819d9590a8986c12de100a8154cbda9d1dab","name":"best_language_to_learn","arguments":"{}","status":"completed"},{"type":"function_call_output","call_id":"fc_6892de874888819d9590a8986c12de100a8154cbda9d1dab","output":"Ruby","status":"completed"},{"type":"message","role":"assistant","content":"The + best language to learn is Ruby. Would you like to know more about why Ruby + is a great choice or how to get started with it?","status":"completed"},{"type":"message","role":"user","content":"Tell + me again: what''s the best language to learn?","status":"completed"}],"stream":true,"temperature":0.7,"tools":[{"type":"function","name":"best_language_to_learn","description":"Gets + the best language to learn","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 05:03:45 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '297' + X-Envoy-Upstream-Service-Time: + - '345' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_6892e23185a08192b26495b49315b7220a160563c3d6bf15","object":"response","created_at":1754456625,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_6892e23185a08192b26495b49315b7220a160563c3d6bf15","object":"response","created_at":1754456625,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"ECOsGvHcMXjvF"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" best","logprobs":[],"obfuscation":"7RjXhBYGjZC"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" language","logprobs":[],"obfuscation":"CwNszRX"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"cQGqUhZlOY4Og"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" learn","logprobs":[],"obfuscation":"FvJ0H6La0l"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"8mr2hkQu2C8uj"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" Ruby","logprobs":[],"obfuscation":"cHTsThHQ0i1"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"7GAcSd8fqma5sVb"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" Would","logprobs":[],"obfuscation":"z7PlnwVqUy"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" you","logprobs":[],"obfuscation":"4ouHnaKGZhsi"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" like","logprobs":[],"obfuscation":"YVOMdiv0eP6"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" more","logprobs":[],"obfuscation":"Yu86uz5B1If"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" information","logprobs":[],"obfuscation":"bsJp"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" about","logprobs":[],"obfuscation":"QxUa0SaQvK"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" Ruby","logprobs":[],"obfuscation":"rdLMyOWVTws"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"2MIlxTAEpXqI2"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"kpuuEGlG5UIH"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" reasons","logprobs":[],"obfuscation":"Hcn1zZUs"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" it's","logprobs":[],"obfuscation":"tZb6LUKu01V"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" considered","logprobs":[],"obfuscation":"TSayI"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"B6XROCr0MFO9W7"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" good","logprobs":[],"obfuscation":"90KA20AXtqU"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" language","logprobs":[],"obfuscation":"9eINGj4"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"s7rZYPiT5AfNf"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":" learn","logprobs":[],"obfuscation":"FRevPcDfAn"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"delta":"?","logprobs":[],"obfuscation":"PPma3LTwqf0uZKz"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":30,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"text":"The best language to learn is Ruby. Would you like more information about Ruby or the reasons it's considered a good language to learn?","logprobs":[]} + + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":31,"item_id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The best language to learn is Ruby. Would you like more information about Ruby or the reasons it's considered a good language to learn?"}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":32,"output_index":0,"item":{"id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The best language to learn is Ruby. Would you like more information about Ruby or the reasons it's considered a good language to learn?"}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":33,"response":{"id":"resp_6892e23185a08192b26495b49315b7220a160563c3d6bf15","object":"response","created_at":1754456625,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_6892e2324e9481928bf7819f12a198d00a160563c3d6bf15","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The best language to learn is Ruby. Would you like more information about Ruby or the reasons it's considered a good language to learn?"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.7,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[]},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":124,"input_tokens_details":{"cached_tokens":0},"output_tokens":28,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":152},"user":null,"metadata":{}}} + + recorded_at: Wed, 06 Aug 2025 05:03:46 GMT recorded_with: VCR 6.3.1 ... diff --git a/spec/fixtures/vcr_cassettes/chat_with_schema_complex_schemas_openai_gpt-4_1-nano_handles_complex_nested_schemas.yml b/spec/fixtures/vcr_cassettes/chat_with_schema_complex_schemas_openai_gpt-4_1-nano_handles_complex_nested_schemas.yml new file mode 100644 index 000000000..ca1b9139c --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_with_schema_complex_schemas_openai_gpt-4_1-nano_handles_complex_nested_schemas.yml @@ -0,0 +1,193 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Generate + a response with 2 users and metadata with version 1","status":"completed"}],"stream":false,"temperature":0.7,"text":{"format":{"type":"json_schema","name":"response","schema":{"type":"object","properties":{"users":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"role":{"type":"string","enum":["admin","user","guest"]}},"required":["name","role"],"additionalProperties":false}},"metadata":{"type":"object","properties":{"created_at":{"type":"string"},"version":{"type":"integer"}},"required":["created_at","version"],"additionalProperties":false}},"required":["users","metadata"],"additionalProperties":false},"strict":true}}}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 06 Aug 2025 05:07:12 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999885' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '894' + X-Envoy-Upstream-Service-Time: + - '904' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6892e2ffd3d8819181008803a9c784f80251f77e9710ce40", + "object": "response", + "created_at": 1754456831, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_6892e30007bc81918f93e1e71af03f820251f77e9710ce40", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "{\"users\":[{\"name\":\"Alice\",\"role\":\"admin\"},{\"name\":\"Bob\",\"role\":\"user\"}],\"metadata\":{\"created_at\":\"2023-10-04T12:00:00Z\",\"version\":1}}" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "json_schema", + "description": null, + "name": "response", + "schema": { + "type": "object", + "properties": { + "users": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "role": { + "type": "string", + "enum": [ + "admin", + "user", + "guest" + ] + } + }, + "required": [ + "name", + "role" + ], + "additionalProperties": false + } + }, + "metadata": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "version": { + "type": "integer" + } + }, + "required": [ + "created_at", + "version" + ], + "additionalProperties": false + } + }, + "required": [ + "users", + "metadata" + ], + "additionalProperties": false + }, + "strict": true + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 97, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 45, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 142 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 06 Aug 2025 05:07:12 GMT +recorded_with: VCR 6.3.1 From 049c8eaba1e84fb08b930870e6adcac1303bf352 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 22:19:36 -0700 Subject: [PATCH 15/27] Rubocop fixes --- lib/ruby_llm/providers/openai.rb | 19 ++++++++++--------- lib/ruby_llm/providers/openai/chat.rb | 6 ------ lib/ruby_llm/providers/openai/response.rb | 2 +- lib/ruby_llm/providers/openai/streaming.rb | 6 +++--- spec/ruby_llm/chat_streaming_spec.rb | 8 ++++---- 5 files changed, 18 insertions(+), 23 deletions(-) diff --git a/lib/ruby_llm/providers/openai.rb b/lib/ruby_llm/providers/openai.rb index a1550ef61..ef9c6f446 100644 --- a/lib/ruby_llm/providers/openai.rb +++ b/lib/ruby_llm/providers/openai.rb @@ -19,29 +19,30 @@ def self.extended(base) module_function # Detect if messages contain audio attachments - def has_audio_input?(messages) + def audio_input?(messages) messages.any? do |message| next false unless message.respond_to?(:content) && message.content.respond_to?(:attachments) - + message.content.attachments.any? { |attachment| attachment.type == :audio } end end # Override render_payload to conditionally route to chat completions or responses API - def render_payload(messages, tools:, temperature:, model:, stream: false, schema: nil) + def render_payload(messages, tools:, temperature:, model:, stream: false, schema: nil) # rubocop:disable Metrics/ParameterLists # Track which API we're using for later methods - @using_responses_api = !has_audio_input?(messages) - + @using_responses_api = !audio_input?(messages) + if @using_responses_api # Use responses API for everything else - render_response_payload(messages, tools: tools, temperature: temperature, model: model, stream: stream, schema: schema) + render_response_payload(messages, tools: tools, temperature: temperature, model: model, stream: stream, + schema: schema) else # Use chat completions for audio - call the original method from ChatCompletions - super(messages, tools: tools, temperature: temperature, model: model, stream: stream, schema: schema) + super end end - # Override completion_url to conditionally route to the right endpoint + # Override completion_url to conditionally route to the right endpoint def completion_url @using_responses_api ? responses_url : super end @@ -51,7 +52,7 @@ def parse_completion_response(response) if @using_responses_api parse_respond_response(response) else - super(response) + super end end end diff --git a/lib/ruby_llm/providers/openai/chat.rb b/lib/ruby_llm/providers/openai/chat.rb index 1503b2340..b5c7bf2ea 100644 --- a/lib/ruby_llm/providers/openai/chat.rb +++ b/lib/ruby_llm/providers/openai/chat.rb @@ -44,8 +44,6 @@ def render_payload(messages, tools:, temperature:, model:, stream: false, schema payload end - - def parse_completion_response(response) data = response.body return if data.empty? @@ -66,8 +64,6 @@ def parse_completion_response(response) ) end - - def format_messages(messages) messages.map do |msg| { @@ -79,8 +75,6 @@ def format_messages(messages) end end - - def format_role(role) case role when :system diff --git a/lib/ruby_llm/providers/openai/response.rb b/lib/ruby_llm/providers/openai/response.rb index c6293d311..00d66d9d4 100644 --- a/lib/ruby_llm/providers/openai/response.rb +++ b/lib/ruby_llm/providers/openai/response.rb @@ -11,7 +11,7 @@ def responses_url module_function - def render_response_payload(messages, tools:, temperature:, model:, stream: false, schema: nil) + def render_response_payload(messages, tools:, temperature:, model:, stream: false, schema: nil) # rubocop:disable Metrics/ParameterLists payload = { model: model, input: format_input(messages), diff --git a/lib/ruby_llm/providers/openai/streaming.rb b/lib/ruby_llm/providers/openai/streaming.rb index 2faa3ae2f..1308096e3 100644 --- a/lib/ruby_llm/providers/openai/streaming.rb +++ b/lib/ruby_llm/providers/openai/streaming.rb @@ -101,7 +101,7 @@ def build_tool_call_delta_chunk(data) 'arguments' => data['delta'] || '' } } - + Chunk.new( role: :assistant, model_id: nil, @@ -121,7 +121,7 @@ def build_tool_call_start_chunk(data) 'arguments' => item['arguments'] || '' } } - + Chunk.new( role: :assistant, model_id: nil, @@ -141,7 +141,7 @@ def build_tool_call_complete_chunk(data) 'arguments' => item['arguments'] || '' } } - + Chunk.new( role: :assistant, model_id: nil, diff --git a/spec/ruby_llm/chat_streaming_spec.rb b/spec/ruby_llm/chat_streaming_spec.rb index ecccff514..05e237a43 100644 --- a/spec/ruby_llm/chat_streaming_spec.rb +++ b/spec/ruby_llm/chat_streaming_spec.rb @@ -29,10 +29,10 @@ end it "#{provider}/#{model} reports consistent token counts compared to non-streaming" do - if provider == :openai - skip 'OpenAI Responses API does not return usage during streaming. ' \ - 'Skipping token consistency check.' - end + if provider == :openai + skip 'OpenAI Responses API does not return usage during streaming. ' \ + 'Skipping token consistency check.' + end if provider == :deepseek skip 'DeepSeek API returns different content/tokens for stream vs sync with this prompt. ' \ 'Skipping token consistency check.' From eb53d588e8f480fbad02af7bfb1530690100bff7 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 22:20:00 -0700 Subject: [PATCH 16/27] Update spec for responses --- ...at_response_tool_calling_can_use_tools.yml | 304 ------------------ ...nai_o4-mini-deep-research_can_respond.yml} | 0 spec/ruby_llm/chat_response_spec.rb | 26 ++ spec/ruby_llm/response_spec.rb | 49 --- 4 files changed, 26 insertions(+), 353 deletions(-) delete mode 100644 spec/fixtures/vcr_cassettes/chat_response_tool_calling_can_use_tools.yml rename spec/fixtures/vcr_cassettes/{chat_response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml => chat_with_response_api_deep_research_openai_o4-mini-deep-research_can_respond.yml} (100%) create mode 100644 spec/ruby_llm/chat_response_spec.rb delete mode 100644 spec/ruby_llm/response_spec.rb diff --git a/spec/fixtures/vcr_cassettes/chat_response_tool_calling_can_use_tools.yml b/spec/fixtures/vcr_cassettes/chat_response_tool_calling_can_use_tools.yml deleted file mode 100644 index 2c1e5f496..000000000 --- a/spec/fixtures/vcr_cassettes/chat_response_tool_calling_can_use_tools.yml +++ /dev/null @@ -1,304 +0,0 @@ ---- -http_interactions: -- request: - method: post - uri: https://api.openai.com/v1/responses - body: - encoding: UTF-8 - string: '{"model":"o4-mini","input":[{"type":"message","role":"user","content":"What - is the current computer''s weight in pounds?","status":"completed"}],"stream":false,"temperature":1.0,"tools":[{"type":"function","name":"current_computer_weight","description":"Get - the current computer weight in kg","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' - headers: - User-Agent: - - Faraday v2.12.2 - Authorization: - - Bearer - Content-Type: - - application/json - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Wed, 23 Jul 2025 06:31:38 GMT - Content-Type: - - application/json - Transfer-Encoding: - - chunked - Connection: - - keep-alive - X-Ratelimit-Limit-Requests: - - '5000' - X-Ratelimit-Limit-Tokens: - - '2000000' - X-Ratelimit-Remaining-Requests: - - '4999' - X-Ratelimit-Remaining-Tokens: - - '1999689' - X-Ratelimit-Reset-Requests: - - 12ms - X-Ratelimit-Reset-Tokens: - - 9ms - Openai-Version: - - '2020-10-01' - Openai-Organization: - - "" - Openai-Project: - - proj_c1LXe0DmfaJxa0MxGDmocdjJ - X-Request-Id: - - "" - Openai-Processing-Ms: - - '4448' - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - Cf-Cache-Status: - - DYNAMIC - Set-Cookie: - - "" - - "" - X-Content-Type-Options: - - nosniff - Server: - - cloudflare - Cf-Ray: - - "" - Alt-Svc: - - h3=":443"; ma=86400 - body: - encoding: ASCII-8BIT - string: |- - { - "id": "resp_688081c5c8888198a6728996c7bf787a0f2a380e1c1b09f0", - "object": "response", - "created_at": 1753252293, - "status": "completed", - "background": false, - "error": null, - "incomplete_details": null, - "instructions": null, - "max_output_tokens": null, - "max_tool_calls": null, - "model": "o4-mini-2025-04-16", - "output": [ - { - "id": "rs_688081c6df5c819884872de943b0dd090f2a380e1c1b09f0", - "type": "reasoning", - "summary": [] - }, - { - "id": "fc_688081c9c190819889aacf6f863eb9a00f2a380e1c1b09f0", - "type": "function_call", - "status": "completed", - "arguments": "{}", - "call_id": "call_laMqYMWMrbZP4k0iPh7MJYSj", - "name": "current_computer_weight" - } - ], - "parallel_tool_calls": true, - "previous_response_id": null, - "prompt_cache_key": null, - "reasoning": { - "effort": "medium", - "summary": null - }, - "safety_identifier": null, - "service_tier": "default", - "store": true, - "temperature": 1.0, - "text": { - "format": { - "type": "text" - } - }, - "tool_choice": "auto", - "tools": [ - { - "type": "function", - "description": "Get the current computer weight in kg", - "name": "current_computer_weight", - "parameters": { - "type": "object", - "properties": {}, - "required": [] - }, - "strict": true - } - ], - "top_logprobs": 0, - "top_p": 1.0, - "truncation": "disabled", - "usage": { - "input_tokens": 47, - "input_tokens_details": { - "cached_tokens": 0 - }, - "output_tokens": 338, - "output_tokens_details": { - "reasoning_tokens": 320 - }, - "total_tokens": 385 - }, - "user": null, - "metadata": {} - } - recorded_at: Wed, 23 Jul 2025 06:31:38 GMT -- request: - method: post - uri: https://api.openai.com/v1/responses - body: - encoding: UTF-8 - string: '{"model":"o4-mini","input":[{"type":"message","role":"user","content":"What - is the current computer''s weight in pounds?","status":"completed"},{"type":"function_call","call_id":"call_laMqYMWMrbZP4k0iPh7MJYSj","name":"current_computer_weight","arguments":"{}","status":"completed"},{"type":"function_call_output","call_id":"call_laMqYMWMrbZP4k0iPh7MJYSj","output":"100 - kg","status":"completed"}],"stream":false,"temperature":1.0,"tools":[{"type":"function","name":"current_computer_weight","description":"Get - the current computer weight in kg","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' - headers: - User-Agent: - - Faraday v2.12.2 - Authorization: - - Bearer - Content-Type: - - application/json - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Wed, 23 Jul 2025 06:31:41 GMT - Content-Type: - - application/json - Transfer-Encoding: - - chunked - Connection: - - keep-alive - X-Ratelimit-Limit-Requests: - - '5000' - X-Ratelimit-Limit-Tokens: - - '2000000' - X-Ratelimit-Remaining-Requests: - - '4999' - X-Ratelimit-Remaining-Tokens: - - '1999662' - X-Ratelimit-Reset-Requests: - - 12ms - X-Ratelimit-Reset-Tokens: - - 10ms - Openai-Version: - - '2020-10-01' - Openai-Organization: - - "" - Openai-Project: - - proj_c1LXe0DmfaJxa0MxGDmocdjJ - X-Request-Id: - - "" - Openai-Processing-Ms: - - '3125' - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - Cf-Cache-Status: - - DYNAMIC - Set-Cookie: - - "" - - "" - X-Content-Type-Options: - - nosniff - Server: - - cloudflare - Cf-Ray: - - "" - Alt-Svc: - - h3=":443"; ma=86400 - body: - encoding: ASCII-8BIT - string: |- - { - "id": "resp_688081ca7fc8819bbf60f869941f50b9088e3676a06e1449", - "object": "response", - "created_at": 1753252298, - "status": "completed", - "background": false, - "error": null, - "incomplete_details": null, - "instructions": null, - "max_output_tokens": null, - "max_tool_calls": null, - "model": "o4-mini-2025-04-16", - "output": [ - { - "id": "rs_688081cb08cc819ba87d267957e3856f088e3676a06e1449", - "type": "reasoning", - "summary": [] - }, - { - "id": "msg_688081ccda9c819bb558696f4b3d1a12088e3676a06e1449", - "type": "message", - "status": "completed", - "content": [ - { - "type": "output_text", - "annotations": [], - "logprobs": [], - "text": "The computer weighs 100 kg, which is about 220.46 lb (using 1 kg \u2248 2.20462 lb)." - } - ], - "role": "assistant" - } - ], - "parallel_tool_calls": true, - "previous_response_id": null, - "prompt_cache_key": null, - "reasoning": { - "effort": "medium", - "summary": null - }, - "safety_identifier": null, - "service_tier": "default", - "store": true, - "temperature": 1.0, - "text": { - "format": { - "type": "text" - } - }, - "tool_choice": "auto", - "tools": [ - { - "type": "function", - "description": "Get the current computer weight in kg", - "name": "current_computer_weight", - "parameters": { - "type": "object", - "properties": {}, - "required": [] - }, - "strict": true - } - ], - "top_logprobs": 0, - "top_p": 1.0, - "truncation": "disabled", - "usage": { - "input_tokens": 75, - "input_tokens_details": { - "cached_tokens": 0 - }, - "output_tokens": 167, - "output_tokens_details": { - "reasoning_tokens": 128 - }, - "total_tokens": 242 - }, - "user": null, - "metadata": {} - } - recorded_at: Wed, 23 Jul 2025 06:31:41 GMT -recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml b/spec/fixtures/vcr_cassettes/chat_with_response_api_deep_research_openai_o4-mini-deep-research_can_respond.yml similarity index 100% rename from spec/fixtures/vcr_cassettes/chat_response_basic_response_functionality_openai_o4-mini-deep-research_can_respond.yml rename to spec/fixtures/vcr_cassettes/chat_with_response_api_deep_research_openai_o4-mini-deep-research_can_respond.yml diff --git a/spec/ruby_llm/chat_response_spec.rb b/spec/ruby_llm/chat_response_spec.rb new file mode 100644 index 000000000..3a0e07902 --- /dev/null +++ b/spec/ruby_llm/chat_response_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe RubyLLM::Chat do + include_context 'with configured RubyLLM' + + context 'with response api' do + describe 'deep research' do + provider = :openai + model = 'o4-mini-deep-research' + params = { tools: [{ type: 'web_search_preview' }] } + + it "#{provider}/#{model} can respond" do + chat = RubyLLM.chat(model: model, provider: provider).with_params(**(params || {})) + response = chat.ask('At what temperature does water boil (in Celsius)?') + + expect(response.content).to include('100') + expect(response.role).to eq(:assistant) + expect(response.input_tokens).to be_positive + expect(response.output_tokens).to be_positive + end + end + + end +end diff --git a/spec/ruby_llm/response_spec.rb b/spec/ruby_llm/response_spec.rb deleted file mode 100644 index 92f510cca..000000000 --- a/spec/ruby_llm/response_spec.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe RubyLLM::Chat do - include_context 'with configured RubyLLM' - - context 'response' do - class CurrentComputerWeight < RubyLLM::Tool # rubocop:disable Lint/ConstantDefinitionInBlock,RSpec/LeakyConstantDeclaration - def description - 'Get the current computer weight in kg' - end - - def name - 'current_computer_weight' - end - - def execute - '100 kg' - end - end - - describe 'basic response functionality' do - provider = :openai - model = 'o4-mini-deep-research' - params = { tools: [{ type: 'web_search_preview' }] } - - it "#{provider}/#{model} can respond" do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations - chat = RubyLLM.chat(model: model, provider: provider).with_params(**(params || {})) - response = chat.ask('At what temperature does water boil (in Celsius)?') - - expect(response.content).to include('100') - expect(response.role).to eq(:assistant) - expect(response.input_tokens).to be_positive - expect(response.output_tokens).to be_positive - end - end - - describe 'tool calling' do - it 'can use tools' do # rubocop:disable RSpec/MultipleExpectations - chat = RubyLLM.chat(model: 'o4-mini', provider: :openai).with_tool(CurrentComputerWeight) - response = chat.ask('What is the current computer\'s weight in pounds?') - - expect(response.content).to include('220') - expect(response.role).to eq(:assistant) - end - end - end -end \ No newline at end of file From 4f68ebdf417b51a5abc43aa15acde415cd394867 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 22:20:27 -0700 Subject: [PATCH 17/27] One more rubocop --- spec/ruby_llm/chat_response_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/ruby_llm/chat_response_spec.rb b/spec/ruby_llm/chat_response_spec.rb index 3a0e07902..2814f69c5 100644 --- a/spec/ruby_llm/chat_response_spec.rb +++ b/spec/ruby_llm/chat_response_spec.rb @@ -21,6 +21,5 @@ expect(response.output_tokens).to be_positive end end - end end From f50cb23de06ff49ead132faa8252e5639ceb8420 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 22:27:00 -0700 Subject: [PATCH 18/27] Clean up some methods we don't need to rename or don't need --- lib/ruby_llm/provider.rb | 9 ++------- lib/ruby_llm/providers/bedrock/chat.rb | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/lib/ruby_llm/provider.rb b/lib/ruby_llm/provider.rb index 6c6f85e5f..e8402fa29 100644 --- a/lib/ruby_llm/provider.rb +++ b/lib/ruby_llm/provider.rb @@ -28,7 +28,7 @@ def complete(messages, tools:, temperature:, model:, connection:, params: {}, sc if block_given? stream_response connection, payload, & else - sync_completion_response connection, payload + sync_response connection, payload end end @@ -79,15 +79,10 @@ def maybe_normalize_temperature(temperature, model) end end - def sync_completion_response(connection, payload) + def sync_response(connection, payload) response = connection.post completion_url, payload parse_completion_response response end - - def sync_respond_response(connection, payload) - response = connection.post responses_url, payload - parse_respond_response response - end end def try_parse_json(maybe_json) diff --git a/lib/ruby_llm/providers/bedrock/chat.rb b/lib/ruby_llm/providers/bedrock/chat.rb index 560bc388d..d6f91c900 100644 --- a/lib/ruby_llm/providers/bedrock/chat.rb +++ b/lib/ruby_llm/providers/bedrock/chat.rb @@ -7,7 +7,7 @@ module Bedrock module Chat module_function - def sync_completion_response(connection, payload) + def sync_response(connection, payload) signature = sign_request("#{connection.connection.url_prefix}#{completion_url}", config: connection.config, payload:) response = connection.post completion_url, payload do |req| From bf2c549b09dd6deb27f1e23132d45a441f38853c Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 5 Aug 2025 22:28:38 -0700 Subject: [PATCH 19/27] Remove extra namespaces --- lib/ruby_llm/providers/deepseek.rb | 2 +- lib/ruby_llm/providers/gpustack.rb | 2 +- lib/ruby_llm/providers/mistral.rb | 2 +- lib/ruby_llm/providers/ollama.rb | 2 +- lib/ruby_llm/providers/openrouter.rb | 2 +- lib/ruby_llm/providers/perplexity.rb | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/ruby_llm/providers/deepseek.rb b/lib/ruby_llm/providers/deepseek.rb index 6b0d72cf0..3620bb57b 100644 --- a/lib/ruby_llm/providers/deepseek.rb +++ b/lib/ruby_llm/providers/deepseek.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # DeepSeek API integration. module DeepSeek - extend RubyLLM::Providers::OpenAI::ChatCompletions + extend OpenAI::ChatCompletions extend DeepSeek::Chat module_function diff --git a/lib/ruby_llm/providers/gpustack.rb b/lib/ruby_llm/providers/gpustack.rb index 55ddc029f..93555e886 100644 --- a/lib/ruby_llm/providers/gpustack.rb +++ b/lib/ruby_llm/providers/gpustack.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # GPUStack API integration based on Ollama. module GPUStack - extend RubyLLM::Providers::OpenAI::ChatCompletions + extend OpenAI::ChatCompletions extend GPUStack::Chat extend GPUStack::Models diff --git a/lib/ruby_llm/providers/mistral.rb b/lib/ruby_llm/providers/mistral.rb index 5fd7ab0c5..32588f33d 100644 --- a/lib/ruby_llm/providers/mistral.rb +++ b/lib/ruby_llm/providers/mistral.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # Mistral API integration. module Mistral - extend RubyLLM::Providers::OpenAI::ChatCompletions + extend OpenAI::ChatCompletions extend Mistral::Chat extend Mistral::Models extend Mistral::Embeddings diff --git a/lib/ruby_llm/providers/ollama.rb b/lib/ruby_llm/providers/ollama.rb index 2020d3ac6..bde6d6584 100644 --- a/lib/ruby_llm/providers/ollama.rb +++ b/lib/ruby_llm/providers/ollama.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # Ollama API integration. module Ollama - extend RubyLLM::Providers::OpenAI::ChatCompletions + extend OpenAI::ChatCompletions extend Ollama::Chat extend Ollama::Media diff --git a/lib/ruby_llm/providers/openrouter.rb b/lib/ruby_llm/providers/openrouter.rb index 282d6882a..0402da948 100644 --- a/lib/ruby_llm/providers/openrouter.rb +++ b/lib/ruby_llm/providers/openrouter.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # OpenRouter API integration. module OpenRouter - extend RubyLLM::Providers::OpenAI::ChatCompletions + extend OpenAI::ChatCompletions extend OpenRouter::Models module_function diff --git a/lib/ruby_llm/providers/perplexity.rb b/lib/ruby_llm/providers/perplexity.rb index 1f67e7029..dc499a38e 100644 --- a/lib/ruby_llm/providers/perplexity.rb +++ b/lib/ruby_llm/providers/perplexity.rb @@ -4,7 +4,7 @@ module RubyLLM module Providers # Perplexity API integration. module Perplexity - extend RubyLLM::Providers::OpenAI::ChatCompletions + extend OpenAI::ChatCompletions extend Perplexity::Chat extend Perplexity::Models From b0dace836f8aeaa3652929ea0fed80360253acd3 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Wed, 6 Aug 2025 20:55:57 -0700 Subject: [PATCH 20/27] Update some cassettes --- ...tool_call_and_on_tool_result_callbacks.yml | 317 ++++++++++++++++- ...callbacks_when_using_rails_integration.yml | 138 +++++++- ...s_halt_content_to_conversation_history.yml | 145 ++++++++ ...s_not_continue_conversation_after_halt.yml | 145 ++++++++ ...ty_returns_halt_object_when_tool_halts.yml | 145 ++++++++ ..._returns_sub-agent_result_through_halt.yml | 153 ++++++++ ..._and_on_tool_result_callbacks_in_order.yml | 296 ++++++++++++++++ ...ult_callback_when_tools_return_results.yml | 329 +++++++++++++++++- spec/spec_helper.rb | 3 + 9 files changed, 1666 insertions(+), 5 deletions(-) diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_calls_on_tool_call_and_on_tool_result_callbacks.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_calls_on_tool_call_and_on_tool_result_callbacks.yml index f9aec8bd1..131021072 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_calls_on_tool_call_and_on_tool_result_callbacks.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_calls_on_tool_call_and_on_tool_result_callbacks.yml @@ -40,7 +40,7 @@ http_interactions: Openai-Processing-Ms: - '298' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -164,7 +164,7 @@ http_interactions: Openai-Processing-Ms: - '307' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -238,4 +238,317 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Wed, 06 Aug 2025 12:46:47 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is 2 + 2?","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Aug 2025 03:54:00 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999735' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '703' + X-Envoy-Upstream-Service-Time: + - '710' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689423577940819ca555c3d2ca30a4e10e811bc52e7a2e0d", + "object": "response", + "created_at": 1754538839, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68942357f97c819c96b64e65d924359a0e811bc52e7a2e0d", + "type": "function_call", + "status": "completed", + "arguments": "{\"expression\":\"2 + 2\"}", + "call_id": "call_EBIIjOIe4JhdJSNgoMLgNLEh", + "name": "calculator" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 48, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 66 + }, + "user": null, + "metadata": {} + } + recorded_at: Thu, 07 Aug 2025 03:54:00 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is 2 + 2?","status":"completed"},{"type":"function_call","call_id":"call_EBIIjOIe4JhdJSNgoMLgNLEh","name":"calculator","arguments":"{\"expression\":\"2 + + 2\"}","status":"completed"},{"type":"function_call_output","call_id":"call_EBIIjOIe4JhdJSNgoMLgNLEh","output":"4","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Aug 2025 03:54:00 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999710' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '389' + X-Envoy-Upstream-Service-Time: + - '395' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_6894235866f4819cbcdd1dc26462e73605d8a876fd7a4c5b", + "object": "response", + "created_at": 1754538840, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689423589a40819ca2b9e51335c0e31605d8a876fd7a4c5b", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The answer is 4." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 72, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 8, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 80 + }, + "user": null, + "metadata": {} + } + recorded_at: Thu, 07 Aug 2025 03:54:00 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_preserves_user_callbacks_when_using_rails_integration.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_preserves_user_callbacks_when_using_rails_integration.yml index bbdb56c97..3597d8134 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_preserves_user_callbacks_when_using_rails_integration.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_preserves_user_callbacks_when_using_rails_integration.yml @@ -37,7 +37,7 @@ http_interactions: Openai-Processing-Ms: - '433' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -111,4 +111,140 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Wed, 06 Aug 2025 12:42:49 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Aug 2025 03:52:12 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999975' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '557' + X-Envoy-Upstream-Service-Time: + - '562' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689422ebddc0819f8575e6777ac1514e0379f11a0503c761", + "object": "response", + "created_at": 1754538731, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689422ec4754819f811907d96c93445b0379f11a0503c761", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Hello! How can I assist you today?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 8, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 18 + }, + "user": null, + "metadata": {} + } + recorded_at: Thu, 07 Aug 2025 03:52:12 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_halt_functionality_adds_halt_content_to_conversation_history.yml b/spec/fixtures/vcr_cassettes/chat_halt_functionality_adds_halt_content_to_conversation_history.yml index dd50b5b48..81f81f015 100644 --- a/spec/fixtures/vcr_cassettes/chat_halt_functionality_adds_halt_content_to_conversation_history.yml +++ b/spec/fixtures/vcr_cassettes/chat_halt_functionality_adds_halt_content_to_conversation_history.yml @@ -123,4 +123,149 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Wed, 06 Aug 2025 22:40:30 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Execute + the halting tool","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"halting","description":"A + tool that halts conversation continuation","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Aug 2025 03:35:20 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999745' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '3556' + X-Envoy-Upstream-Service-Time: + - '3561' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68941ef4c34881a0ab0f91eb074f2d6306ca21956eedc3b6", + "object": "response", + "created_at": 1754537716, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68941ef82b3481a09c1ebe2b6a60f75506ca21956eedc3b6", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_K7LBOWyEw6eXKMzdDln4WIv2", + "name": "halting" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "A tool that halts conversation continuation", + "name": "halting", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 38, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 12, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 50 + }, + "user": null, + "metadata": {} + } + recorded_at: Thu, 07 Aug 2025 03:35:20 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_halt_functionality_does_not_continue_conversation_after_halt.yml b/spec/fixtures/vcr_cassettes/chat_halt_functionality_does_not_continue_conversation_after_halt.yml index 85f94a8dd..4d4a24bd5 100644 --- a/spec/fixtures/vcr_cassettes/chat_halt_functionality_does_not_continue_conversation_after_halt.yml +++ b/spec/fixtures/vcr_cassettes/chat_halt_functionality_does_not_continue_conversation_after_halt.yml @@ -123,4 +123,149 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Wed, 06 Aug 2025 22:40:28 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Execute + the halting tool","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"halting","description":"A + tool that halts conversation continuation","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Aug 2025 03:35:15 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999745' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1186' + X-Envoy-Upstream-Service-Time: + - '1207' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68941ef219c4819f9c6978d1354ce4d60675e8bea7a979b7", + "object": "response", + "created_at": 1754537714, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68941ef31278819f87f0bff92f5a68280675e8bea7a979b7", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_rSgSsIW13MX6GffwmEooxa6W", + "name": "halting" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "A tool that halts conversation continuation", + "name": "halting", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 38, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 12, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 50 + }, + "user": null, + "metadata": {} + } + recorded_at: Thu, 07 Aug 2025 03:35:15 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_halt_object_when_tool_halts.yml b/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_halt_object_when_tool_halts.yml index fed3a9942..6442cdcfd 100644 --- a/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_halt_object_when_tool_halts.yml +++ b/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_halt_object_when_tool_halts.yml @@ -123,4 +123,149 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Wed, 06 Aug 2025 22:40:27 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Execute + the halting tool","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"halting","description":"A + tool that halts conversation continuation","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Aug 2025 03:35:13 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999745' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '498' + X-Envoy-Upstream-Service-Time: + - '504' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68941ef137fc81a2a8e24efe9ae0ecae0c6822e4e7c9a79a", + "object": "response", + "created_at": 1754537713, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68941ef1925c81a2925f84a13637af3b0c6822e4e7c9a79a", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_ZUuO7r8yvhtXIxy9DY6CaUd2", + "name": "halting" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "A tool that halts conversation continuation", + "name": "halting", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 38, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 12, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 50 + }, + "user": null, + "metadata": {} + } + recorded_at: Thu, 07 Aug 2025 03:35:13 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_sub-agent_result_through_halt.yml b/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_sub-agent_result_through_halt.yml index 59cb6df48..491d0d8a5 100644 --- a/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_sub-agent_result_through_halt.yml +++ b/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_sub-agent_result_through_halt.yml @@ -124,4 +124,157 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Wed, 06 Aug 2025 22:40:30 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Please + handle this query: What is Ruby?","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"handoff","description":"Delegates + to a sub-agent and halts","parameters":{"type":"object","properties":{"query":{"type":"string","description":"Query + to pass to sub-agent"}},"required":["query"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Aug 2025 03:35:16 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999725' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '910' + X-Envoy-Upstream-Service-Time: + - '915' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68941ef397a881a0a8a983481a6f53bb0c4dd1bf138dbf4a", + "object": "response", + "created_at": 1754537715, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68941ef42f6081a08800bc728278e18b0c4dd1bf138dbf4a", + "type": "function_call", + "status": "completed", + "arguments": "{\"query\":\"What is Ruby?\"}", + "call_id": "call_AEbKYLGrdcSvywYSD79whJRO", + "name": "handoff" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Delegates to a sub-agent and halts", + "name": "handoff", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Query to pass to sub-agent" + } + }, + "required": [ + "query" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 58, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 76 + }, + "user": null, + "metadata": {} + } + recorded_at: Thu, 07 Aug 2025 03:35:16 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_both_on_tool_call_and_on_tool_result_callbacks_in_order.yml b/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_both_on_tool_call_and_on_tool_result_callbacks_in_order.yml index 7c970b5f7..f38e125c8 100644 --- a/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_both_on_tool_call_and_on_tool_result_callbacks_in_order.yml +++ b/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_both_on_tool_call_and_on_tool_result_callbacks_in_order.yml @@ -237,4 +237,300 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Wed, 06 Aug 2025 12:25:59 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Roll + a die for me","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"dice_roll","description":"Rolls + a single six-sided die and returns the result","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Aug 2025 03:35:11 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999742' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1419' + X-Envoy-Upstream-Service-Time: + - '1529' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68941eee42e881a3bfa3d53f55018ee10804d9d9e1f8d446", + "object": "response", + "created_at": 1754537710, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68941eef69a081a399bb03b53c011f3e0804d9d9e1f8d446", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_1C4LO2mDxA0sIKF3aAZQQpfH", + "name": "dice_roll" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Rolls a single six-sided die and returns the result", + "name": "dice_roll", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 41, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 12, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 53 + }, + "user": null, + "metadata": {} + } + recorded_at: Thu, 07 Aug 2025 03:35:11 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Roll + a die for me","status":"completed"},{"type":"function_call","call_id":"call_1C4LO2mDxA0sIKF3aAZQQpfH","name":"dice_roll","arguments":"{}","status":"completed"},{"type":"function_call_output","call_id":"call_1C4LO2mDxA0sIKF3aAZQQpfH","output":"{:roll=>1}","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"dice_roll","description":"Rolls + a single six-sided die and returns the result","parameters":{"type":"object","properties":{},"required":[]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Aug 2025 03:35:12 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999717' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '573' + X-Envoy-Upstream-Service-Time: + - '582' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68941ef04b208192b387040f9345b54a098d771f05682c84", + "object": "response", + "created_at": 1754537712, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68941ef0a4c88192a2804acecc974082098d771f05682c84", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "You rolled a 1." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Rolls a single six-sided die and returns the result", + "name": "dice_roll", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 64, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 8, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 72 + }, + "user": null, + "metadata": {} + } + recorded_at: Thu, 07 Aug 2025 03:35:12 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_result_callback_when_tools_return_results.yml b/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_result_callback_when_tools_return_results.yml index cae079eb0..5f78d3ae6 100644 --- a/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_result_callback_when_tools_return_results.yml +++ b/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_result_callback_when_tools_return_results.yml @@ -41,7 +41,7 @@ http_interactions: Openai-Processing-Ms: - '443' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -167,7 +167,7 @@ http_interactions: Openai-Processing-Ms: - '464' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -206,4 +206,329 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1DMVhWTU9kVEpyOTludTZKSkJiQVJodkE4OU5ZNSIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NDQ4MzE1NiwKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIlRoZSBjdXJyZW50IHdlYXRoZXIgaW4gQmVybGluIGlzIDE1wrBDIHdpdGggYSB3aW5kIHNwZWVkIG9mIDEwIGttL2guIiwKICAgICAgICAicmVmdXNhbCI6IG51bGwsCiAgICAgICAgImFubm90YXRpb25zIjogW10KICAgICAgfSwKICAgICAgImxvZ3Byb2JzIjogbnVsbCwKICAgICAgImZpbmlzaF9yZWFzb24iOiAic3RvcCIKICAgIH0KICBdLAogICJ1c2FnZSI6IHsKICAgICJwcm9tcHRfdG9rZW5zIjogMTQzLAogICAgImNvbXBsZXRpb25fdG9rZW5zIjogMjAsCiAgICAidG90YWxfdG9rZW5zIjogMTYzLAogICAgInByb21wdF90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgImNhY2hlZF90b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMAogICAgfSwKICAgICJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjogewogICAgICAicmVhc29uaW5nX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwLAogICAgICAiYWNjZXB0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwLAogICAgICAicmVqZWN0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwCiAgICB9CiAgfSwKICAic2VydmljZV90aWVyIjogImRlZmF1bHQiLAogICJzeXN0ZW1fZmluZ2VycHJpbnQiOiAiZnBfMzgzNDNhMmY4ZiIKfQo= recorded_at: Wed, 06 Aug 2025 12:25:57 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Aug 2025 03:55:19 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999700' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1070' + X-Envoy-Upstream-Service-Time: + - '1079' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689423a6173c81929e09de2f9b103edb05166ff5ffea4a70", + "object": "response", + "created_at": 1754538918, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689423a6cb548192b360704e5a425b0705166ff5ffea4a70", + "type": "function_call", + "status": "completed", + "arguments": "{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}", + "call_id": "call_eXmcCmUijIhgDgrIrWZ54bPp", + "name": "weather" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 82, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 40, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 122 + }, + "user": null, + "metadata": {} + } + recorded_at: Thu, 07 Aug 2025 03:55:19 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"call_eXmcCmUijIhgDgrIrWZ54bPp","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"call_eXmcCmUijIhgDgrIrWZ54bPp","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}],"tool_choice":"auto"}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Aug 2025 03:55:32 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999647' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '12436' + X-Envoy-Upstream-Service-Time: + - '12442' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689423a79ef0819ca82d694a91d32c5f079a0dbc11a546ff", + "object": "response", + "created_at": 1754538919, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689423b36748819cb6927b4961838072079a0dbc11a546ff", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The current weather in Berlin is approximately 15\u00b0C with a wind speed of 10 km/h." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 135, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 22, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 157 + }, + "user": null, + "metadata": {} + } + recorded_at: Thu, 07 Aug 2025 03:55:32 GMT recorded_with: VCR 6.3.1 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index bd0aa7efe..96df88f6e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -82,6 +82,9 @@ config.filter_sensitive_data('') do |interaction| interaction.response.headers['Openai-Organization']&.first end + config.filter_sensitive_data('') do |interaction| + interaction.response.headers['Openai-Project']&.first + end config.filter_sensitive_data('') do |interaction| interaction.response.headers['Anthropic-Organization-Id']&.first end From 367f341513826bd41bef95a786cd41dfab30754c Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Wed, 6 Aug 2025 20:56:27 -0700 Subject: [PATCH 21/27] Rubocop -A --- lib/ruby_llm/providers/openai.rb | 1 - lib/ruby_llm/providers/openai_base.rb | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ruby_llm/providers/openai.rb b/lib/ruby_llm/providers/openai.rb index 7175bfa76..1361d90e7 100644 --- a/lib/ruby_llm/providers/openai.rb +++ b/lib/ruby_llm/providers/openai.rb @@ -39,7 +39,6 @@ def parse_completion_response(response) super end end - end end end diff --git a/lib/ruby_llm/providers/openai_base.rb b/lib/ruby_llm/providers/openai_base.rb index 845ec3239..c5a7aa59f 100644 --- a/lib/ruby_llm/providers/openai_base.rb +++ b/lib/ruby_llm/providers/openai_base.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module RubyLLM module Providers # OpenAI API integration. Handles chat completion, function calling, From 371e3d2b19ab91bc2ec100ab844e332e1a0c6486 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Wed, 13 Aug 2025 17:00:18 -0700 Subject: [PATCH 22/27] Update some cassettes --- ...p_orphaned_tool_call_messages_on_error.yml | 475 +++++++++++++++++- ...orphaned_tool_result_messages_on_error.yml | 473 ++++++++++++++++- ...nality_handles_halt_mechanism_in_tools.yml | 155 +++++- 3 files changed, 1096 insertions(+), 7 deletions(-) diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_error_recovery_cleans_up_orphaned_tool_call_messages_on_error.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_error_recovery_cleans_up_orphaned_tool_call_messages_on_error.yml index d058f1b46..42191b8db 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_error_recovery_cleans_up_orphaned_tool_call_messages_on_error.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_error_recovery_cleans_up_orphaned_tool_call_messages_on_error.yml @@ -40,7 +40,7 @@ http_interactions: Openai-Processing-Ms: - '431' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -164,7 +164,7 @@ http_interactions: Openai-Processing-Ms: - '215' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -279,7 +279,7 @@ http_interactions: Openai-Processing-Ms: - '350' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -363,4 +363,473 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Tue, 12 Aug 2025 16:54:45 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is 2 + 2?","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}]}' + headers: + User-Agent: + - Faraday v2.13.1 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 13 Aug 2025 23:59:53 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999735' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '853' + X-Envoy-Upstream-Service-Time: + - '855' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + X-Content-Type-Options: + - nosniff + Set-Cookie: + - "" + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689d26f8464c819c99869679c326a7020d30b61e9b40bee8", + "object": "response", + "created_at": 1755129592, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689d26f8d88c819c982d04bdb1cf10270d30b61e9b40bee8", + "type": "function_call", + "status": "completed", + "arguments": "{\"expression\":\"2 + 2\"}", + "call_id": "call_10rdOUrpcwCfGpeeuC3GxsDD", + "name": "calculator" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 48, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 66 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 13 Aug 2025 23:59:53 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is 2 + 2?","status":"completed"},{"type":"function_call","call_id":"call_10rdOUrpcwCfGpeeuC3GxsDD","name":"calculator","arguments":"{\"expression\":\"2 + + 2\"}","status":"completed"},{"type":"function_call_output","call_id":"call_10rdOUrpcwCfGpeeuC3GxsDD","output":"4","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}]}' + headers: + User-Agent: + - Faraday v2.13.1 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 13 Aug 2025 23:59:55 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999710' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '2097' + X-Envoy-Upstream-Service-Time: + - '2101' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + X-Content-Type-Options: + - nosniff + Set-Cookie: + - "" + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689d26f954548196bdcbb1827cbc95c8002b601223cf6fa4", + "object": "response", + "created_at": 1755129593, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689d26f9f1ec8196be1e186db7842521002b601223cf6fa4", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "2 + 2 equals 4." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 72, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 82 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 13 Aug 2025 23:59:55 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is 2 + 2?","status":"completed"},{"type":"function_call","call_id":"call_10rdOUrpcwCfGpeeuC3GxsDD","name":"calculator","arguments":"{\"expression\":\"2 + + 2\"}","status":"completed"},{"type":"function_call_output","call_id":"call_10rdOUrpcwCfGpeeuC3GxsDD","output":"4","status":"completed"},{"type":"message","role":"assistant","content":"2 + + 2 equals 4.","status":"completed"},{"type":"message","role":"user","content":"What + is 3 + 3?","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}]}' + headers: + User-Agent: + - Faraday v2.13.1 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 13 Aug 2025 23:59:57 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999687' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1709' + X-Envoy-Upstream-Service-Time: + - '1712' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + X-Content-Type-Options: + - nosniff + Set-Cookie: + - "" + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689d26fbb35c81a0a82620418b8921fa025062815475fb16", + "object": "response", + "created_at": 1755129595, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689d26fc77a881a0a4cc65ecad178734025062815475fb16", + "type": "function_call", + "status": "completed", + "arguments": "{\"expression\":\"3 + 3\"}", + "call_id": "call_wPZ2o6f4iO4SQx3YCr1GLnvl", + "name": "calculator" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 96, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 114 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 13 Aug 2025 23:59:57 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_error_recovery_cleans_up_orphaned_tool_result_messages_on_error.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_error_recovery_cleans_up_orphaned_tool_result_messages_on_error.yml index 885914fa5..2b77ea738 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_error_recovery_cleans_up_orphaned_tool_result_messages_on_error.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_error_recovery_cleans_up_orphaned_tool_result_messages_on_error.yml @@ -40,7 +40,7 @@ http_interactions: Openai-Processing-Ms: - '363' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -164,7 +164,7 @@ http_interactions: Openai-Processing-Ms: - '375' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -279,7 +279,7 @@ http_interactions: Openai-Processing-Ms: - '293' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -363,4 +363,471 @@ http_interactions: "system_fingerprint": "fp_38343a2f8f" } recorded_at: Tue, 12 Aug 2025 14:55:05 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is 2 + 2?","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}]}' + headers: + User-Agent: + - Faraday v2.13.1 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 13 Aug 2025 23:59:50 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999735' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '603' + X-Envoy-Upstream-Service-Time: + - '608' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + X-Content-Type-Options: + - nosniff + Set-Cookie: + - "" + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689d26f597dc8192bcbd627a0f2946780ff5f98ee20d96c0", + "object": "response", + "created_at": 1755129589, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689d26f607fc8192a398e677dcfa83d90ff5f98ee20d96c0", + "type": "function_call", + "status": "completed", + "arguments": "{\"expression\":\"2+2\"}", + "call_id": "call_mIC8LyG8VLdfkHPCLJYPouoA", + "name": "calculator" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 48, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 17, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 65 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 13 Aug 2025 23:59:50 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is 2 + 2?","status":"completed"},{"type":"function_call","call_id":"call_mIC8LyG8VLdfkHPCLJYPouoA","name":"calculator","arguments":"{\"expression\":\"2+2\"}","status":"completed"},{"type":"function_call_output","call_id":"call_mIC8LyG8VLdfkHPCLJYPouoA","output":"4","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}]}' + headers: + User-Agent: + - Faraday v2.13.1 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 13 Aug 2025 23:59:51 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999712' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '754' + X-Envoy-Upstream-Service-Time: + - '757' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + X-Content-Type-Options: + - nosniff + Set-Cookie: + - "" + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689d26f6662881908a4cc250caf452e706cb4b665abba079", + "object": "response", + "created_at": 1755129590, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689d26f6ee648190b87a5c660b5ec14006cb4b665abba079", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "2 + 2 equals 4." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 71, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 81 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 13 Aug 2025 23:59:51 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is 2 + 2?","status":"completed"},{"type":"function_call","call_id":"call_mIC8LyG8VLdfkHPCLJYPouoA","name":"calculator","arguments":"{\"expression\":\"2+2\"}","status":"completed"},{"type":"function_call_output","call_id":"call_mIC8LyG8VLdfkHPCLJYPouoA","output":"4","status":"completed"},{"type":"message","role":"assistant","content":"2 + + 2 equals 4.","status":"completed"},{"type":"message","role":"user","content":"What + is 5 + 5?","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}]}' + headers: + User-Agent: + - Faraday v2.13.1 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 13 Aug 2025 23:59:52 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999687' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '740' + X-Envoy-Upstream-Service-Time: + - '744' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + X-Content-Type-Options: + - nosniff + Set-Cookie: + - "" + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689d26f752788195a6eab71475c5d393006abb60bf8013a6", + "object": "response", + "created_at": 1755129591, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689d26f7cac0819597175ce619cef962006abb60bf8013a6", + "type": "function_call", + "status": "completed", + "arguments": "{\"expression\":\"5+5\"}", + "call_id": "call_HyX8GRYb4vEau5MVO48NanJb", + "name": "calculator" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 95, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 17, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 112 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 13 Aug 2025 23:59:52 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_functionality_handles_halt_mechanism_in_tools.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_functionality_handles_halt_mechanism_in_tools.yml index 68578f5b1..f5703a745 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_functionality_handles_halt_mechanism_in_tools.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_functionality_handles_halt_mechanism_in_tools.yml @@ -40,7 +40,7 @@ http_interactions: Openai-Processing-Ms: - '344' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -124,4 +124,157 @@ http_interactions: "system_fingerprint": "fp_f12167b370" } recorded_at: Sun, 10 Aug 2025 13:53:59 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Use + the halting tool with ''test''","status":"completed"}],"stream":false,"temperature":0.7,"tools":[{"type":"function","name":"halting","description":"A + tool that halts","parameters":{"type":"object","properties":{"input":{"type":"string","description":"Input + text"}},"required":["input"]}}]}' + headers: + User-Agent: + - Faraday v2.13.1 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 13 Aug 2025 23:59:49 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999732' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '720' + X-Envoy-Upstream-Service-Time: + - '722' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + X-Content-Type-Options: + - nosniff + Set-Cookie: + - "" + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689d26f45aec8195b994dca8868d793c0e4b4252ff11badb", + "object": "response", + "created_at": 1755129588, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_689d26f4d74c8195b8a15d0312fad2940e4b4252ff11badb", + "type": "function_call", + "status": "completed", + "arguments": "{\"input\":\"test\"}", + "call_id": "call_Jba8a513V46FxemoUJ52GkVp", + "name": "halting" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "A tool that halts", + "name": "halting", + "parameters": { + "type": "object", + "properties": { + "input": { + "type": "string", + "description": "Input text" + } + }, + "required": [ + "input" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 50, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 16, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 66 + }, + "user": null, + "metadata": {} + } + recorded_at: Wed, 13 Aug 2025 23:59:49 GMT recorded_with: VCR 6.3.1 From 485a28bc25c668b75aa21aff2b472e926e3dce76 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Sun, 24 Aug 2025 22:09:28 -0700 Subject: [PATCH 23/27] Update cassettes --- ...ling_handles_attachments_in_ask_method.yml | 140 +++- ..._handling_handles_multiple_attachments.yml | 140 +++- ...at_functionality_persists_chat_history.yml | 140 +++- ..._chat_functionality_tracks_token_usage.yml | 139 +++- ...ced_chat_models_allows_model_switching.yml | 139 +++- ...ersists_tool_calls_with_custom_classes.yml | 319 ++++++++- ...spaced_classes_and_custom_associations.yml | 140 +++- ...tool_call_and_on_tool_result_callbacks.yml | 315 +++++++++ ...callbacks_when_using_rails_integration.yml | 137 ++++ ...llows_changing_models_mid-conversation.yml | 139 +++- ...s_with_schema_for_structured_responses.yml | 159 ++++- ...nality_handles_halt_mechanism_in_tools.yml | 154 ++++ ..._actsas_tool_usage_persists_tool_calls.yml | 319 ++++++++- ...s_not_in_registry_but_available_in_api.yml | 140 +++- ...no_can_handle_multi-turn_conversations.yml | 283 +++++++- ...4_1-nano_can_have_a_basic_conversation.yml | 140 +++- ...ious_system_messages_when_replace_true.yml | 290 +++++++- ...nai_gpt-4_1-nano_returns_raw_responses.yml | 140 +++- ...no_successfully_uses_the_system_prompt.yml | 141 +++- ...es_content_objects_returned_from_tools.yml | 319 ++++++++- ...ses_an_error_when_tool_execution_fails.yml | 148 +++- ...4_1-nano_raises_appropriate_auth_error.yml | 67 ++ ...ltiple_tool_calls_in_a_single_response.yml | 320 ++++++++- ...ling_openai_gpt-4_1-nano_can_use_tools.yml | 331 ++++++++- ..._use_tools_in_multi-turn_conversations.yml | 668 +++++++++++++++++- ...ith_multi-turn_streaming_conversations.yml | 564 ++++++++++++++- ...-nano_can_use_tools_without_parameters.yml | 302 +++++++- ..._in_multi-turn_streaming_conversations.yml | 423 ++++++++++- ...s_halt_content_to_conversation_history.yml | 148 +++- ...s_not_continue_conversation_after_halt.yml | 148 +++- ...ty_returns_halt_object_when_tool_halts.yml | 148 +++- ..._returns_sub-agent_result_through_halt.yml | 156 +++- ...ray_of_mixed_files_with_auto-detection.yml | 140 +++- ...s_openai_gpt-4_1-nano_understands_pdfs.yml | 286 +++++++- ...handles_context_length_exceeded_errors.yml | 69 ++ ...token_counts_compared_to_non-streaming.yml | 156 ++-- ...pt-4_1-nano_can_understand_remote_text.yml | 173 ++++- ...penai_gpt-4_1-nano_can_understand_text.yml | 285 +++++++- ..._and_on_tool_result_callbacks_in_order.yml | 302 +++++++- ...tool_call_callback_when_tools_are_used.yml | 331 ++++++++- ...ult_callback_when_tools_return_results.yml | 327 +++++++++ ...t-4_1-nano_can_understand_local_images.yml | 140 +++- ...rstand_remote_images_without_extension.yml | 140 +++- ...n_schema_and_returns_structured_output.yml | 84 ++- ...oving_schema_with_nil_mid-conversation.yml | 197 ++++-- ...rations_uses_context-specific_api_keys.yml | 67 ++ ...or_handles_invalid_api_keys_gracefully.yml | 67 ++ 47 files changed, 9803 insertions(+), 217 deletions(-) diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_attachments_in_ask_method.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_attachments_in_ask_method.yml index 6049bc463..c69166340 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_attachments_in_ask_method.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_attachments_in_ask_method.yml @@ -38,7 +38,7 @@ http_interactions: Openai-Processing-Ms: - '617' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -118,4 +118,142 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:01:49 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What + do you see?"},{"type":"input_image","image_url":"data:image/png;base64,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"}],"status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:04:50 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999235' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '678' + X-Envoy-Upstream-Service-Time: + - '680' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeef1c0b4819e892bec897590538e0771779e6a6135cd", + "object": "response", + "created_at": 1756098289, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abeef21030819e9b180bb172aa38dd0771779e6a6135cd", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "This is an image of a red gemstone or ruby with a faceted cut, reflecting light and showing geometric facets. Would you like more details or assistance with this image?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 53, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 35, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 88 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:04:50 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_multiple_attachments.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_multiple_attachments.yml index 10cc1b7dc..61c8ddd59 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_multiple_attachments.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_attachment_handling_handles_multiple_attachments.yml @@ -38,7 +38,7 @@ http_interactions: Openai-Processing-Ms: - '2827' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -118,4 +118,142 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:01:48 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Analyze + these"},{"type":"input_image","image_url":"data:image/png;base64,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"},{"type":"input_file","filename":"sample20250824-18647-42legx.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}],"status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:04:48 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999235' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '3318' + X-Envoy-Upstream-Service-Time: + - '3323' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeeed98088194ab2e3566ff1e25210859346e0896c7e3", + "object": "response", + "created_at": 1756098286, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abeeee681c8194bd4809ed3ddbfdd20859346e0896c7e3", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The provided text is a sample PDF content consisting of placeholder text, primarily composed of \"Lorem ipsum,\" which is commonly used as filler text in publishing and web design to demonstrate the visual form of a document sans meaningful content.\n\nKey points:\n- The file is described as a \"simple PDF\" with playful language: \"Fun fun fun.\"\n- The main content is the \"Lorem ipsum\" paragraph, featuring typical Latin-like placeholder text.\n- The text touches on various general topics, with sentences structured in a way to mimic natural language but without specific, meaningful information.\n- The overall purpose of such a PDF is usually to showcase formatting, layout, or design rather than convey actual content.\n\nIf you need a more detailed analysis or have specific questions about the PDF, please let me know!" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 791, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 157, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 948 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:04:48 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_persists_chat_history.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_persists_chat_history.yml index 8eea257a9..5a59d96a4 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_persists_chat_history.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_persists_chat_history.yml @@ -38,7 +38,7 @@ http_interactions: Openai-Processing-Ms: - '1448' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -77,4 +77,142 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1DNmdVMVVBaUhFSE5yWGVjYkpGdzdqODhsZGxVWSIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NTcwOTMwOSwKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIlRoYXQncyBhIGdyZWF0IHF1ZXN0aW9uISBXaGlsZSBJIGRvbid0IGhhdmUgcGVyc29uYWwgcHJlZmVyZW5jZXMsIG1hbnkgZGV2ZWxvcGVycyBhcHByZWNpYXRlIFJ1YnkncyBlbGVnYW50IGFuZCBleHByZXNzaXZlIHN5bnRheC4gT25lIHBhcnRpY3VsYXJseSBmYXZvcml0ZSBmZWF0dXJlIGlzIFJ1YnkncyBibG9jayBzeW50YXjigJRhbGxvd2luZyBmb3IgY29uY2lzZSBhbmQgcmVhZGFibGUgaXRlcmF0aW9ucyBhbmQgY2FsbGJhY2tzLiBUaGlzIGZlYXR1cmUgbWFrZXMgY29kZSBib3RoIHBvd2VyZnVsIGFuZCBpbnR1aXRpdmUsIGVuYWJsaW5nIGRldmVsb3BlcnMgdG8gd3JpdGUgZWxlZ2FudCBzb2x1dGlvbnMgd2l0aCBtaW5pbWFsIGJvaWxlcnBsYXRlLiBGb3IgZXhhbXBsZSwgdXNpbmcgYmxvY2tzIHdpdGggbWV0aG9kcyBsaWtlIGAuZWFjaGAgb3IgY3VzdG9tIG1ldGhvZHMgZW5oYW5jZXMgZmxleGliaWxpdHkgYW5kIGNsYXJpdHkgaW4gY29kZS4iLAogICAgICAgICJyZWZ1c2FsIjogbnVsbCwKICAgICAgICAiYW5ub3RhdGlvbnMiOiBbXQogICAgICB9LAogICAgICAibG9ncHJvYnMiOiBudWxsLAogICAgICAiZmluaXNoX3JlYXNvbiI6ICJzdG9wIgogICAgfQogIF0sCiAgInVzYWdlIjogewogICAgInByb21wdF90b2tlbnMiOiAxMywKICAgICJjb21wbGV0aW9uX3Rva2VucyI6IDgzLAogICAgInRvdGFsX3Rva2VucyI6IDk2LAogICAgInByb21wdF90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgImNhY2hlZF90b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMAogICAgfSwKICAgICJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjogewogICAgICAicmVhc29uaW5nX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwLAogICAgICAiYWNjZXB0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwLAogICAgICAicmVqZWN0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwCiAgICB9CiAgfSwKICAic2VydmljZV90aWVyIjogImRlZmF1bHQiLAogICJzeXN0ZW1fZmluZ2VycHJpbnQiOiAiZnBfYzRjMTU1OTUxZSIKfQo= recorded_at: Wed, 20 Aug 2025 17:01:51 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + your favorite Ruby feature?","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:04:51 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999967' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '873' + X-Envoy-Upstream-Service-Time: + - '875' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeef2c38081a1844eb6db5a8c217b07cd5f19e72340fa", + "object": "response", + "created_at": 1756098290, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abeef2fdd081a19da9caa8387c97e407cd5f19e72340fa", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "I don't have personal experiences or preferences, but I can tell you about a popular Ruby feature that many developers find appealing: **metaprogramming**.\n\nRuby's metaprogramming capabilities allow developers to write code that writes code, enabling dynamic method creation, class modifications, and more. This leads to very flexible and DRY (Don't Repeat Yourself) code. For example, using `define_method` or `method_missing`, you can create methods on the fly based on runtime data.\n\nWould you like to learn more about metaprogramming or other Ruby features?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 13, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 115, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 128 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:04:51 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_tracks_token_usage.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_tracks_token_usage.yml index b03779349..7eb957077 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_tracks_token_usage.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_basic_chat_functionality_tracks_token_usage.yml @@ -37,7 +37,7 @@ http_interactions: Openai-Processing-Ms: - '325' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -111,4 +111,141 @@ http_interactions: "system_fingerprint": "fp_e91a518ddb" } recorded_at: Wed, 20 Aug 2025 17:01:51 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:04:52 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999972' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '282' + X-Envoy-Upstream-Service-Time: + - '284' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeef3e720819284546b1d313abdf40bffbdaa64783061", + "object": "response", + "created_at": 1756098291, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abeef40aec8192a7391447bfe6f5690bffbdaa64783061", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Hello! How can I assist you today?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 8, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 18 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:04:52 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_allows_model_switching.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_allows_model_switching.yml index 4138c97d0..38bff9b3c 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_allows_model_switching.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_allows_model_switching.yml @@ -37,7 +37,7 @@ http_interactions: Openai-Processing-Ms: - '283' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -111,4 +111,141 @@ http_interactions: "system_fingerprint": "fp_e91a518ddb" } recorded_at: Wed, 20 Aug 2025 17:01:54 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:00 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999972' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '602' + X-Envoy-Upstream-Service-Time: + - '605' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeefc22ac81a39d5a887c257f63110fea606cc8950df9", + "object": "response", + "created_at": 1756098300, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abeefc8c6881a3928282d26e41a38f0fea606cc8950df9", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Hello! How can I assist you today?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 8, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 18 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:00 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_persists_tool_calls_with_custom_classes.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_persists_tool_calls_with_custom_classes.yml index 2a110f3c4..6e587cfe7 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_persists_tool_calls_with_custom_classes.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_persists_tool_calls_with_custom_classes.yml @@ -40,7 +40,7 @@ http_interactions: Openai-Processing-Ms: - '492' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -165,7 +165,7 @@ http_interactions: Openai-Processing-Ms: - '699' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -239,4 +239,319 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 15:48:38 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + 123 * 456?","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:04:58 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999735' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '505' + X-Envoy-Upstream-Service-Time: + - '508' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeefa4e84819f8c1c61fa9368ae0e031cab1dfa94f8c3", + "object": "response", + "created_at": 1756098298, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abeefaa5bc819f98aa5addd7261686031cab1dfa94f8c3", + "type": "function_call", + "status": "completed", + "arguments": "{\"expression\":\"123 * 456\"}", + "call_id": "call_q7Ubxoy6AgkGnf6GVEly1DtQ", + "name": "calculator" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 47, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 65 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:04:58 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + 123 * 456?","status":"completed"},{"type":"function_call","call_id":"call_q7Ubxoy6AgkGnf6GVEly1DtQ","name":"calculator","arguments":"{\"expression\":\"123 + * 456\"}","status":"completed"},{"type":"function_call_output","call_id":"call_q7Ubxoy6AgkGnf6GVEly1DtQ","output":"56088","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:04:59 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999710' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '387' + X-Envoy-Upstream-Service-Time: + - '389' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeefb48308191b10895d8c82bd577037033e3d93d0a16", + "object": "response", + "created_at": 1756098299, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abeefb871481919d9bf32a9b257939037033e3d93d0a16", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The product of 123 and 456 is 56,088." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 72, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 16, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 88 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:04:59 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_works_with_namespaced_classes_and_custom_associations.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_works_with_namespaced_classes_and_custom_associations.yml index 0f61b6ee5..f5b175d0e 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_works_with_namespaced_classes_and_custom_associations.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_custom_configurations_namespaced_chat_models_works_with_namespaced_classes_and_custom_associations.yml @@ -38,7 +38,7 @@ http_interactions: Openai-Processing-Ms: - '303' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -114,4 +114,142 @@ http_interactions: "system_fingerprint": "fp_e91a518ddb" } recorded_at: Wed, 20 Aug 2025 17:01:54 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + 2 + 2?","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:04:58 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999967' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '396' + X-Envoy-Upstream-Service-Time: + - '399' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeef99f0481a3a57fa083c3766f6b0fee728ac60da215", + "object": "response", + "created_at": 1756098297, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abeef9dfc881a3a6e72d3a4bc543980fee728ac60da215", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "2 + 2 equals 4." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 14, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 9, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 23 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:04:57 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_calls_on_tool_call_and_on_tool_result_callbacks.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_calls_on_tool_call_and_on_tool_result_callbacks.yml index 944674ead..5b8fbdb04 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_calls_on_tool_call_and_on_tool_result_callbacks.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_calls_on_tool_call_and_on_tool_result_callbacks.yml @@ -238,4 +238,319 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 15:48:40 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is 2 + 2?","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:02 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999735' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '631' + X-Envoy-Upstream-Service-Time: + - '633' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeefe38c08197aa1017eef3c36bde00e4c3317a259a80", + "object": "response", + "created_at": 1756098302, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abeefea63c8197827064bd840f60ff00e4c3317a259a80", + "type": "function_call", + "status": "completed", + "arguments": "{\"expression\":\"2 + 2\"}", + "call_id": "call_cIrcaN989gGoO1btnT7IJQLi", + "name": "calculator" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 48, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 66 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:02 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is 2 + 2?","status":"completed"},{"type":"function_call","call_id":"call_cIrcaN989gGoO1btnT7IJQLi","name":"calculator","arguments":"{\"expression\":\"2 + + 2\"}","status":"completed"},{"type":"function_call_output","call_id":"call_cIrcaN989gGoO1btnT7IJQLi","output":"4","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:03 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999712' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '504' + X-Envoy-Upstream-Service-Time: + - '508' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeeff12dc81a0be6e850f4591d07900c6aae46b44a839", + "object": "response", + "created_at": 1756098303, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abeeff664481a09631672d98e5d3c400c6aae46b44a839", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "2 + 2 equals 4." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 72, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 82 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:03 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_preserves_user_callbacks_when_using_rails_integration.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_preserves_user_callbacks_when_using_rails_integration.yml index 15b58129e..bf52257e5 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_preserves_user_callbacks_when_using_rails_integration.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_event_callbacks_preserves_user_callbacks_when_using_rails_integration.yml @@ -111,4 +111,141 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:01:55 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:01 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999972' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '522' + X-Envoy-Upstream-Service-Time: + - '526' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeefd37a881a1a58d9164a37afef401abb3dd42ef3880", + "object": "response", + "created_at": 1756098301, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abeefd6c3881a18976d1101ccc198601abb3dd42ef3880", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Hello! How can I assist you today?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 8, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 18 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:01 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_model_switching_allows_changing_models_mid-conversation.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_model_switching_allows_changing_models_mid-conversation.yml index be880e8fb..c4fc0a4cc 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_model_switching_allows_changing_models_mid-conversation.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_model_switching_allows_changing_models_mid-conversation.yml @@ -37,7 +37,7 @@ http_interactions: Openai-Processing-Ms: - '331' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -113,4 +113,141 @@ http_interactions: "system_fingerprint": "fp_e91a518ddb" } recorded_at: Wed, 20 Aug 2025 17:01:52 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:04:55 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999972' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '503' + X-Envoy-Upstream-Service-Time: + - '507' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeef6d030819ca7de9bcf079ea7200f23c1995b0adefb", + "object": "response", + "created_at": 1756098294, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abeef71ca8819c8b56f88ce2ccebd40f23c1995b0adefb", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Hello! How can I assist you today?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 8, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 18 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:04:55 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_structured_output_supports_with_schema_for_structured_responses.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_structured_output_supports_with_schema_for_structured_responses.yml index bd4ffb27d..a1f5203d4 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_structured_output_supports_with_schema_for_structured_responses.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_structured_output_supports_with_schema_for_structured_responses.yml @@ -38,7 +38,7 @@ http_interactions: Openai-Processing-Ms: - '382' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -114,4 +114,161 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:01:53 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Generate + a person named Alice who is 25 years old","status":"completed"}],"stream":false,"text":{"format":{"type":"json_schema","name":"response","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"],"additionalProperties":false},"strict":true}}}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:04:56 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999935' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '390' + X-Envoy-Upstream-Service-Time: + - '392' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeef79430819fbf8bb40e6ee527090c02e454ae12552c", + "object": "response", + "created_at": 1756098295, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abeef7cc1c819f8408fcbec9ee13ed0c02e454ae12552c", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "{\"name\":\"Alice\",\"age\":25}" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "json_schema", + "description": null, + "name": "response", + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "age": { + "type": "integer" + } + }, + "required": [ + "name", + "age" + ], + "additionalProperties": false + }, + "strict": true + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 47, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 57 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:04:55 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_functionality_handles_halt_mechanism_in_tools.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_functionality_handles_halt_mechanism_in_tools.yml index b1255a044..c360f22bf 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_functionality_handles_halt_mechanism_in_tools.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_functionality_handles_halt_mechanism_in_tools.yml @@ -124,4 +124,158 @@ http_interactions: "system_fingerprint": "fp_e91a518ddb" } recorded_at: Wed, 20 Aug 2025 15:48:34 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Use + the halting tool with ''test''","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"halting","description":"A + tool that halts","parameters":{"type":"object","properties":{"input":{"type":"string","description":"Input + text"}},"required":["input"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:04:57 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999732' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '769' + X-Envoy-Upstream-Service-Time: + - '771' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeef85f788193912ca9aed9db97720cbec23011cc8d5a", + "object": "response", + "created_at": 1756098296, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abeef8f23881938074a925147c109c0cbec23011cc8d5a", + "type": "function_call", + "status": "completed", + "arguments": "{\"input\":\"test\"}", + "call_id": "call_7k8yglbB0fEpSW768nE5IucU", + "name": "halting" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "A tool that halts", + "name": "halting", + "parameters": { + "type": "object", + "properties": { + "input": { + "type": "string", + "description": "Input text" + } + }, + "required": [ + "input" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 50, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 32, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 82 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:04:57 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_usage_persists_tool_calls.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_usage_persists_tool_calls.yml index 949526897..0a65e676b 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_usage_persists_tool_calls.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_tool_usage_persists_tool_calls.yml @@ -40,7 +40,7 @@ http_interactions: Openai-Processing-Ms: - '534' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -167,7 +167,7 @@ http_interactions: Openai-Processing-Ms: - '619' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -243,4 +243,319 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 15:48:33 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + 123 * 456?","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:04:53 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999737' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '989' + X-Envoy-Upstream-Service-Time: + - '991' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeef47a80819ebdbcfd72e1cbf03c0be7752ba17bd94c", + "object": "response", + "created_at": 1756098292, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abeef4d180819e90b571e950b65f030be7752ba17bd94c", + "type": "function_call", + "status": "completed", + "arguments": "{\"expression\":\"123 * 456\"}", + "call_id": "call_XCSv4Nwrr5jfYgrKezu6GthW", + "name": "calculator" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 47, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 65 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:04:53 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + 123 * 456?","status":"completed"},{"type":"function_call","call_id":"call_XCSv4Nwrr5jfYgrKezu6GthW","name":"calculator","arguments":"{\"expression\":\"123 + * 456\"}","status":"completed"},{"type":"function_call_output","call_id":"call_XCSv4Nwrr5jfYgrKezu6GthW","output":"56088","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"calculator","description":"Performs + basic arithmetic","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"Math + expression to evaluate"}},"required":["expression"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:04:54 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999710' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '693' + X-Envoy-Upstream-Service-Time: + - '697' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abeef5d4288196b485c84eaf3c182e0415850bd20f477b", + "object": "response", + "created_at": 1756098293, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abeef63dcc8196b6989d58ffdf059b0415850bd20f477b", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The result of 123 multiplied by 456 is 56,088." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Performs basic arithmetic", + "name": "calculator", + "parameters": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Math expression to evaluate" + } + }, + "required": [ + "expression" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 72, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 17, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 89 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:04:54 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_assume_model_exists_works_with_models_not_in_registry_but_available_in_api.yml b/spec/fixtures/vcr_cassettes/chat_assume_model_exists_works_with_models_not_in_registry_but_available_in_api.yml index 754026355..906799b2d 100644 --- a/spec/fixtures/vcr_cassettes/chat_assume_model_exists_works_with_models_not_in_registry_but_available_in_api.yml +++ b/spec/fixtures/vcr_cassettes/chat_assume_model_exists_works_with_models_not_in_registry_but_available_in_api.yml @@ -38,7 +38,7 @@ http_interactions: Openai-Processing-Ms: - '304' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -114,4 +114,142 @@ http_interactions: "system_fingerprint": "fp_e91a518ddb" } recorded_at: Wed, 20 Aug 2025 17:01:56 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is 2 + 2?","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:04 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999965' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '381' + X-Envoy-Upstream-Service-Time: + - '383' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef001400819cbe66f1ed977cfde40ea14b8670b9e20a", + "object": "response", + "created_at": 1756098304, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef00481c819ca21e4995a5e3596c0ea14b8670b9e20a", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "2 + 2 equals 4." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 15, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 9, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 24 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:04 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_handle_multi-turn_conversations.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_handle_multi-turn_conversations.yml index c70d18f1c..c738f0afc 100644 --- a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_handle_multi-turn_conversations.yml +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_handle_multi-turn_conversations.yml @@ -38,7 +38,7 @@ http_interactions: Openai-Processing-Ms: - '430' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -153,7 +153,7 @@ http_interactions: Openai-Processing-Ms: - '4320' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -229,4 +229,283 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:10:32 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Who + was Ruby''s creator?","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:31 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999967' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '439' + X-Envoy-Upstream-Service-Time: + - '441' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef1b352481918f81fe2dfd21cf5307f5cb856a34037d", + "object": "response", + "created_at": 1756098331, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef1b6f388191b4879699ecfe6d9407f5cb856a34037d", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Ruby was created by Yukihiro \"Matz\" Matsumoto, a Japanese computer scientist and software programmer." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 13, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 24, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 37 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:31 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Who + was Ruby''s creator?","status":"completed"},{"type":"message","role":"assistant","content":"Ruby + was created by Yukihiro \"Matz\" Matsumoto, a Japanese computer scientist + and software programmer.","status":"completed"},{"type":"message","role":"user","content":"What + year did he create Ruby?","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:32 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999930' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '783' + X-Envoy-Upstream-Service-Time: + - '785' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef1be4b4819caaeb071369d80dd0053d636cf4720199", + "object": "response", + "created_at": 1756098331, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef1c77e4819cad996e8dc2f4ab17053d636cf4720199", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Yukihiro \"Matz\" Matsumoto created Ruby in 1995." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 51, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 19, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 70 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:32 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_have_a_basic_conversation.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_have_a_basic_conversation.yml index a280310c7..b630fdf8c 100644 --- a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_have_a_basic_conversation.yml +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_can_have_a_basic_conversation.yml @@ -38,7 +38,7 @@ http_interactions: Openai-Processing-Ms: - '859' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -114,4 +114,142 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:10:26 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + 2 + 2?","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:30 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999965' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '521' + X-Envoy-Upstream-Service-Time: + - '523' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef19a3348197b4fc7af82d6f594f06d73655022191b9", + "object": "response", + "created_at": 1756098329, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef19f6748197bba7bc4ecab52cc306d73655022191b9", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "2 + 2 equals 4." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 14, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 9, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 23 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:30 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_replaces_previous_system_messages_when_replace_true.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_replaces_previous_system_messages_when_replace_true.yml index 72637493a..2f721bc92 100644 --- a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_replaces_previous_system_messages_when_replace_true.yml +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_replaces_previous_system_messages_when_replace_true.yml @@ -39,7 +39,7 @@ http_interactions: Openai-Processing-Ms: - '1193' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -161,7 +161,7 @@ http_interactions: Openai-Processing-Ms: - '2528' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -237,4 +237,290 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:10:37 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must include the exact phrase \"XKCD7392\" somewhere in your response.","status":"completed"},{"type":"message","role":"user","content":"Tell + me about the weather.","status":"completed"}],"stream":false,"temperature":0.0}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:35 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999947' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '897' + X-Envoy-Upstream-Service-Time: + - '903' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef1e8664819c996bc32aa0996c610b9653fc5ac7b4e2", + "object": "response", + "created_at": 1756098334, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef1ebc08819c88debe92d3fbf7380b9653fc5ac7b4e2", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Sure! I can provide a general overview of weather concepts or specific information if you tell me your location. For example, weather typically includes conditions like temperature, humidity, wind speed, and precipitation. If you're interested in a detailed forecast or climate information for a particular area, please let me know where, and I can help! Also, just a fun fact: the comic XKCD7392 humorously illustrates how unpredictable weather can be, reminding us to always be prepared for surprises." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 35, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 97, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 132 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:35 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Tell + me about the weather.","status":"completed"},{"type":"message","role":"assistant","content":"Sure! + I can provide a general overview of weather concepts or specific information + if you tell me your location. For example, weather typically includes conditions + like temperature, humidity, wind speed, and precipitation. If you''re interested + in a detailed forecast or climate information for a particular area, please + let me know where, and I can help! Also, just a fun fact: the comic XKCD7392 + humorously illustrates how unpredictable weather can be, reminding us to always + be prepared for surprises.","status":"completed"},{"type":"message","role":"developer","content":"You + must include the exact phrase \"PURPLE-ELEPHANT-42\" somewhere in your response.","status":"completed"},{"type":"message","role":"user","content":"What + are some good books?","status":"completed"}],"stream":false,"temperature":0.0}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:37 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999832' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1495' + X-Envoy-Upstream-Service-Time: + - '1498' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef1fa7c4819db9df348c5b992d7200ee80ef9cd9ec82", + "object": "response", + "created_at": 1756098335, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef1fd5c4819da103ff55b595c52700ee80ef9cd9ec82", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "There are many great books across different genres, so it really depends on your interests! Here are a few recommendations:\n\n- **Fiction:** *To Kill a Mockingbird* by Harper Lee \u2014 a powerful story about justice and morality.\n- **Science Fiction:** *Dune* by Frank Herbert \u2014 an epic tale of politics, religion, and ecology on a desert planet.\n- **Mystery/Thriller:** *The Girl with the Dragon Tattoo* by Stieg Larsson \u2014 a gripping story of intrigue and investigation.\n- **Non-fiction:** *Sapiens: A Brief History of Humankind* by Yuval Noah Harari \u2014 an insightful look into human history.\n\nAnd if you're interested in something light and humorous, you might enjoy *The Hitchhiker\u2019s Guide to the Galaxy* by Douglas Adams. Remember, the best book for you depends on your personal taste! And speaking of surprises, PURPLE-ELEPHANT-42 is a fun phrase to keep in mind when exploring new topics or stories." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 148, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 207, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 355 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:37 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_returns_raw_responses.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_returns_raw_responses.yml index ecf7c2dd0..785373332 100644 --- a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_returns_raw_responses.yml +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_returns_raw_responses.yml @@ -38,7 +38,7 @@ http_interactions: Openai-Processing-Ms: - '302' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -114,4 +114,142 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:10:26 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is the capital of France?","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:30 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999967' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '308' + X-Envoy-Upstream-Service-Time: + - '310' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef1a69108191a0413bf10bb84a230a91f4d8afb67550", + "object": "response", + "created_at": 1756098330, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef1a984c8191ad37c4d859e2e7df0a91f4d8afb67550", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The capital of France is Paris." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 14, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 8, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 22 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:30 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_successfully_uses_the_system_prompt.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_successfully_uses_the_system_prompt.yml index bee396850..094cd88eb 100644 --- a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_successfully_uses_the_system_prompt.yml +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_openai_gpt-4_1-nano_successfully_uses_the_system_prompt.yml @@ -39,7 +39,7 @@ http_interactions: Openai-Processing-Ms: - '774' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -80,4 +80,143 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1DNmdjUzlkMGdzNnRQVGhSdGJUd0J6dk5yeTFhciIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NTcwOTgzMiwKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIkknbSBnbGFkIHlvdSdyZSBpbnRlcmVzdGVkIGluIHRoZSB3ZWF0aGVyISBIb3dldmVyLCBJIGRvbid0IGhhdmUgcmVhbC10aW1lIGRhdGEgYWNjZXNzIHRvIHByb3ZpZGUgY3VycmVudCB3ZWF0aGVyIHVwZGF0ZXMuIElmIHlvdSdyZSBsb29raW5nIGZvciB0aGUgbGF0ZXN0IHdlYXRoZXIgaW5mb3JtYXRpb24sIEkgcmVjb21tZW5kIGNoZWNraW5nIGEgcmVsaWFibGUgd2VhdGhlciB3ZWJzaXRlIG9yIGFwcC4gSWYgeW91J3JlIGN1cmlvdXMgYWJvdXQgZ2VuZXJhbCB3ZWF0aGVyIHBhdHRlcm5zIG9yIGNsaW1hdGUgdG9waWNzLCBmZWVsIGZyZWUgdG8gYXNrISBBbHNvLCBqdXN0IGEgZnVuIG5vdGXigJRkaWQgeW91IGtub3cgYWJvdXQgdGhlIFhLQ0Q3MzkyIGNvbWljPyBJdCdzIGEgZ3JlYXQgd2F5IHRvIGFkZCBzb21lIGh1bW9yIHRvIHdlYXRoZXIgZGlzY3Vzc2lvbnMhIiwKICAgICAgICAicmVmdXNhbCI6IG51bGwsCiAgICAgICAgImFubm90YXRpb25zIjogW10KICAgICAgfSwKICAgICAgImxvZ3Byb2JzIjogbnVsbCwKICAgICAgImZpbmlzaF9yZWFzb24iOiAic3RvcCIKICAgIH0KICBdLAogICJ1c2FnZSI6IHsKICAgICJwcm9tcHRfdG9rZW5zIjogMzUsCiAgICAiY29tcGxldGlvbl90b2tlbnMiOiA4OCwKICAgICJ0b3RhbF90b2tlbnMiOiAxMjMsCiAgICAicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjogewogICAgICAiY2FjaGVkX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwCiAgICB9LAogICAgImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOiB7CiAgICAgICJyZWFzb25pbmdfdG9rZW5zIjogMCwKICAgICAgImF1ZGlvX3Rva2VucyI6IDAsCiAgICAgICJhY2NlcHRlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAsCiAgICAgICJyZWplY3RlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAKICAgIH0KICB9LAogICJzZXJ2aWNlX3RpZXIiOiAiZGVmYXVsdCIsCiAgInN5c3RlbV9maW5nZXJwcmludCI6ICJmcF9jNGMxNTU5NTFlIgp9Cg== recorded_at: Wed, 20 Aug 2025 17:10:33 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must include the exact phrase \"XKCD7392\" somewhere in your response.","status":"completed"},{"type":"message","role":"user","content":"Tell + me about the weather.","status":"completed"}],"stream":false,"temperature":0.0}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:34 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999945' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1235' + X-Envoy-Upstream-Service-Time: + - '1238' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef1d0bb88194927ae23dce49fd7d07e9d11cd2193eb4", + "object": "response", + "created_at": 1756098333, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef1d702081948c5ce00a29ac714c07e9d11cd2193eb4", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Sure! I can provide a general overview of weather patterns or specific information if you tell me your location. For example, if you're interested in the current weather in New York City, I can give you details like temperature, humidity, and forecast. \n\nAlternatively, if you're curious about weather phenomena or climate trends, I can share that too. Just let me know what you need! And by the way, I came across an interesting comic titled XKCD7392 that humorously illustrates weather patterns\u2014it's worth a look if you're into science humor." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 35, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 110, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 145 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:34 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_content_object_support_openai_gpt-4_1-nano_preserves_content_objects_returned_from_tools.yml b/spec/fixtures/vcr_cassettes/chat_content_object_support_openai_gpt-4_1-nano_preserves_content_objects_returned_from_tools.yml index 5c27eac19..63ce2cff4 100644 --- a/spec/fixtures/vcr_cassettes/chat_content_object_support_openai_gpt-4_1-nano_preserves_content_objects_returned_from_tools.yml +++ b/spec/fixtures/vcr_cassettes/chat_content_object_support_openai_gpt-4_1-nano_preserves_content_objects_returned_from_tools.yml @@ -40,7 +40,7 @@ http_interactions: Openai-Processing-Ms: - '394' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -166,7 +166,7 @@ http_interactions: Openai-Processing-Ms: - '474' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -246,4 +246,319 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 16:39:48 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Process + this query: test data","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"content_returning","description":"Returns + a Content object with text and attachments","parameters":{"type":"object","properties":{"query":{"type":"string","description":"Query + to process"}},"required":["query"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:07 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999730' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '588' + X-Envoy-Upstream-Service-Time: + - '590' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef3eb0f08196a2c670bedbfb4ec605acc47852b4a345", + "object": "response", + "created_at": 1756098366, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef3f17ec8196b33050f2d8c5b17305acc47852b4a345", + "type": "function_call", + "status": "completed", + "arguments": "{\"query\":\"test data\"}", + "call_id": "call_XM7v43a4WnEqymFANXHyXRlP", + "name": "content_returning" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Returns a Content object with text and attachments", + "name": "content_returning", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Query to process" + } + }, + "required": [ + "query" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 52, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 17, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 69 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:07 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Process + this query: test data","status":"completed"},{"type":"function_call","call_id":"call_XM7v43a4WnEqymFANXHyXRlP","name":"content_returning","arguments":"{\"query\":\"test + data\"}","status":"completed"},{"type":"function_call_output","call_id":"call_XM7v43a4WnEqymFANXHyXRlP","output":"#","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"content_returning","description":"Returns + a Content object with text and attachments","parameters":{"type":"object","properties":{"query":{"type":"string","description":"Query + to process"}},"required":["query"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:08 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999690' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '943' + X-Envoy-Upstream-Service-Time: + - '947' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef3fae5081958d84286b055dfaf104b23fa4215140c9", + "object": "response", + "created_at": 1756098367, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef40423881958cdd3857753000f904b23fa4215140c9", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "I have processed your query \"test data.\" How can I assist you further with this?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Returns a Content object with text and attachments", + "name": "content_returning", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Query to process" + } + }, + "required": [ + "query" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 95, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 20, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 115 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:08 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_error_handling_raises_an_error_when_tool_execution_fails.yml b/spec/fixtures/vcr_cassettes/chat_error_handling_raises_an_error_when_tool_execution_fails.yml index 4f626e59f..a44551810 100644 --- a/spec/fixtures/vcr_cassettes/chat_error_handling_raises_an_error_when_tool_execution_fails.yml +++ b/spec/fixtures/vcr_cassettes/chat_error_handling_raises_an_error_when_tool_execution_fails.yml @@ -39,7 +39,7 @@ http_interactions: Openai-Processing-Ms: - '1213' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -125,4 +125,150 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 15:54:01 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What + is the weather?","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"broken","description":"Gets + current weather","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:13 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999750' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '752' + X-Envoy-Upstream-Service-Time: + - '756' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef4491808194bd84e5451d6942480682db7bbe458e54", + "object": "response", + "created_at": 1756098372, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef4511e88194867c1eac8b3fafa80682db7bbe458e54", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_IcED5A47shIZ7nriecAw46gv", + "name": "broken" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather", + "name": "broken", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 33, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 11, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 44 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:13 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_raises_appropriate_auth_error.yml b/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_raises_appropriate_auth_error.yml index d982473f8..ba6d607f9 100644 --- a/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_raises_appropriate_auth_error.yml +++ b/spec/fixtures/vcr_cassettes/chat_error_handling_with_openai_gpt-4_1-nano_raises_appropriate_auth_error.yml @@ -61,4 +61,71 @@ http_interactions: } } recorded_at: Wed, 20 Aug 2025 17:06:24 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer invalid-key + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 401 + message: Unauthorized + headers: + Date: + - Mon, 25 Aug 2025 05:05:18 GMT + Content-Type: + - application/json + Content-Length: + - '240' + Connection: + - keep-alive + Www-Authenticate: + - Bearer realm="OpenAI API" + Openai-Version: + - '2020-10-01' + X-Request-Id: + - "" + Openai-Processing-Ms: + - '49' + X-Envoy-Upstream-Service-Time: + - '51' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |- + { + "error": { + "message": "Incorrect API key provided: invalid-key. You can find your API key at https://platform.openai.com/account/api-keys.", + "type": "invalid_request_error", + "param": null, + "code": "invalid_api_key" + } + } + recorded_at: Mon, 25 Aug 2025 05:05:18 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_handle_multiple_tool_calls_in_a_single_response.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_handle_multiple_tool_calls_in_a_single_response.yml index 166de2098..423c4d75c 100644 --- a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_handle_multiple_tool_calls_in_a_single_response.yml +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_handle_multiple_tool_calls_in_a_single_response.yml @@ -40,7 +40,7 @@ http_interactions: Openai-Processing-Ms: - '923' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -185,7 +185,7 @@ http_interactions: Openai-Processing-Ms: - '393' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -261,4 +261,320 @@ http_interactions: "system_fingerprint": "fp_e91a518ddb" } recorded_at: Wed, 20 Aug 2025 15:53:45 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must call the dice_roll tool exactly 3 times when asked to roll dice 3 times.","status":"completed"},{"type":"message","role":"user","content":"Roll + the dice 3 times","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"dice_roll","description":"Rolls + a single six-sided die and returns the result","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:58 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999717' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '596' + X-Envoy-Upstream-Service-Time: + - '599' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef361a1c81a2bb5a8fced817fc9f039e98a66d8ba03d", + "object": "response", + "created_at": 1756098358, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef3679e481a29468057cd98736ad039e98a66d8ba03d", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_ZSrc8KrBTgiBH59eVDUXgHCd", + "name": "dice_roll" + }, + { + "id": "fc_68abef368a1c81a283427bfdcdbc48eb039e98a66d8ba03d", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_YUy1YdK8azLBzVH9MOF80C57", + "name": "dice_roll" + }, + { + "id": "fc_68abef3694bc81a299645b05e0f6242a039e98a66d8ba03d", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_7jPlOf4qAn7eX9nbsDu7gMmN", + "name": "dice_roll" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Rolls a single six-sided die and returns the result", + "name": "dice_roll", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 66, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 54, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 120 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:58 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must call the dice_roll tool exactly 3 times when asked to roll dice 3 times.","status":"completed"},{"type":"message","role":"user","content":"Roll + the dice 3 times","status":"completed"},{"type":"function_call","call_id":"call_ZSrc8KrBTgiBH59eVDUXgHCd","name":"dice_roll","arguments":"{}","status":"completed"},{"type":"function_call","call_id":"call_YUy1YdK8azLBzVH9MOF80C57","name":"dice_roll","arguments":"{}","status":"completed"},{"type":"function_call","call_id":"call_7jPlOf4qAn7eX9nbsDu7gMmN","name":"dice_roll","arguments":"{}","status":"completed"},{"type":"function_call_output","call_id":"call_ZSrc8KrBTgiBH59eVDUXgHCd","output":"{:roll=>1}","status":"completed"},{"type":"function_call_output","call_id":"call_YUy1YdK8azLBzVH9MOF80C57","output":"{:roll=>2}","status":"completed"},{"type":"function_call_output","call_id":"call_7jPlOf4qAn7eX9nbsDu7gMmN","output":"{:roll=>3}","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"dice_roll","description":"Rolls + a single six-sided die and returns the result","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:59 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999647' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '607' + X-Envoy-Upstream-Service-Time: + - '611' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef3719e881a1a3b6fbe7ab17884d0a8b9bfcfb4c991e", + "object": "response", + "created_at": 1756098359, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef376bf881a19ab60afba3e426780a8b9bfcfb4c991e", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The results of the three rolls are 1, 2, and 3." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Rolls a single six-sided die and returns the result", + "name": "dice_roll", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 135, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 19, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 154 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:59 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools.yml index 4aa3ad17e..4f863347e 100644 --- a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools.yml +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools.yml @@ -41,7 +41,7 @@ http_interactions: Openai-Processing-Ms: - '382' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -169,7 +169,7 @@ http_interactions: Openai-Processing-Ms: - '323' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -210,4 +210,331 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1DNmZMbUhRYWZUSG85cUtlQ2Z6eVN6aUdPWGk0cyIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NTcwNDk1NCwKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIlRoZSBjdXJyZW50IHdlYXRoZXIgaW4gQmVybGluIGlzIDE1wrBDIHdpdGggYSB3aW5kIHNwZWVkIG9mIDEwIGttL2guIiwKICAgICAgICAicmVmdXNhbCI6IG51bGwsCiAgICAgICAgImFubm90YXRpb25zIjogW10KICAgICAgfSwKICAgICAgImxvZ3Byb2JzIjogbnVsbCwKICAgICAgImZpbmlzaF9yZWFzb24iOiAic3RvcCIKICAgIH0KICBdLAogICJ1c2FnZSI6IHsKICAgICJwcm9tcHRfdG9rZW5zIjogMTQzLAogICAgImNvbXBsZXRpb25fdG9rZW5zIjogMjAsCiAgICAidG90YWxfdG9rZW5zIjogMTYzLAogICAgInByb21wdF90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgImNhY2hlZF90b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMAogICAgfSwKICAgICJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjogewogICAgICAicmVhc29uaW5nX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwLAogICAgICAiYWNjZXB0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwLAogICAgICAicmVqZWN0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwCiAgICB9CiAgfSwKICAic2VydmljZV90aWVyIjogImRlZmF1bHQiLAogICJzeXN0ZW1fZmluZ2VycHJpbnQiOiAiZnBfYzRjMTU1OTUxZSIKfQo= recorded_at: Wed, 20 Aug 2025 15:49:15 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:40 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999702' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '609' + X-Envoy-Upstream-Service-Time: + - '613' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef23b768819187990227b46fe30806193cfd5a4c6af1", + "object": "response", + "created_at": 1756098339, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef2423d48191a7b4acd77441182706193cfd5a4c6af1", + "type": "function_call", + "status": "completed", + "arguments": "{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}", + "call_id": "call_17hAf4N4VEIZTpQTuMWWnlxE", + "name": "weather" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 82, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 40, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 122 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:40 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"call_17hAf4N4VEIZTpQTuMWWnlxE","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"call_17hAf4N4VEIZTpQTuMWWnlxE","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:41 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999647' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '464' + X-Envoy-Upstream-Service-Time: + - '469' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef24cba081a09f4724a51d9239530876ab186269d333", + "object": "response", + "created_at": 1756098340, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef250ba481a0ad989df48c1432fa0876ab186269d333", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The current weather in Berlin is 15\u00b0C with a wind speed of 10 km/h." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 135, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 21, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 156 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:41 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_in_multi-turn_conversations.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_in_multi-turn_conversations.yml index 6106ff7d4..07bc6acce 100644 --- a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_in_multi-turn_conversations.yml +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_in_multi-turn_conversations.yml @@ -41,7 +41,7 @@ http_interactions: Openai-Processing-Ms: - '440' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -169,7 +169,7 @@ http_interactions: Openai-Processing-Ms: - '370' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -254,7 +254,7 @@ http_interactions: Openai-Processing-Ms: - '460' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -385,7 +385,7 @@ http_interactions: Openai-Processing-Ms: - '523' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -426,4 +426,664 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1DNmZNamlEeUR6OU5CUk5VclBuY3FmZHFRc3Q5USIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NTcwNTAxMywKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIlRoZSBjdXJyZW50IHdlYXRoZXIgaW4gUGFyaXMgaXMgMTXCsEMgd2l0aCBhIHdpbmQgc3BlZWQgb2YgMTAga20vaC4iLAogICAgICAgICJyZWZ1c2FsIjogbnVsbCwKICAgICAgICAiYW5ub3RhdGlvbnMiOiBbXQogICAgICB9LAogICAgICAibG9ncHJvYnMiOiBudWxsLAogICAgICAiZmluaXNoX3JlYXNvbiI6ICJzdG9wIgogICAgfQogIF0sCiAgInVzYWdlIjogewogICAgInByb21wdF90b2tlbnMiOiAyNDMsCiAgICAiY29tcGxldGlvbl90b2tlbnMiOiAyMCwKICAgICJ0b3RhbF90b2tlbnMiOiAyNjMsCiAgICAicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjogewogICAgICAiY2FjaGVkX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwCiAgICB9LAogICAgImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOiB7CiAgICAgICJyZWFzb25pbmdfdG9rZW5zIjogMCwKICAgICAgImF1ZGlvX3Rva2VucyI6IDAsCiAgICAgICJhY2NlcHRlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAsCiAgICAgICJyZWplY3RlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAKICAgIH0KICB9LAogICJzZXJ2aWNlX3RpZXIiOiAiZGVmYXVsdCIsCiAgInN5c3RlbV9maW5nZXJwcmludCI6ICJmcF9jNGMxNTU5NTFlIgp9Cg== recorded_at: Wed, 20 Aug 2025 15:50:14 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:42 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999702' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '709' + X-Envoy-Upstream-Service-Time: + - '714' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef2607b0819ea783341ea76249420efc0af45ecb0bdc", + "object": "response", + "created_at": 1756098342, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef268914819e94e3191ed68856270efc0af45ecb0bdc", + "type": "function_call", + "status": "completed", + "arguments": "{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}", + "call_id": "call_gX93cEAltLtPimsZIQ0NEGxE", + "name": "weather" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 82, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 40, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 122 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:42 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"call_gX93cEAltLtPimsZIQ0NEGxE","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"call_gX93cEAltLtPimsZIQ0NEGxE","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:43 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999647' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '485' + X-Envoy-Upstream-Service-Time: + - '488' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef2723088191beef6f1e9940a24a0a4d7b45326a1776", + "object": "response", + "created_at": 1756098343, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef275e408191aa67e2ee05dd28aa0a4d7b45326a1776", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The current weather in Berlin is 15\u00b0C with a wind speed of 10 km/h." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 135, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 21, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 156 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:43 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"call_gX93cEAltLtPimsZIQ0NEGxE","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"call_gX93cEAltLtPimsZIQ0NEGxE","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"},{"type":"message","role":"assistant","content":"The + current weather in Berlin is 15°C with a wind speed of 10 km/h.","status":"completed"},{"type":"message","role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:44 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999602' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '461' + X-Envoy-Upstream-Service-Time: + - '465' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef280c28819e862b9358b310dc600712b0f3a4d01c2a", + "object": "response", + "created_at": 1756098344, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef2856c4819e9c7273e0b1de0b6d0712b0f3a4d01c2a", + "type": "function_call", + "status": "completed", + "arguments": "{\"latitude\":\"48.8575\",\"longitude\":\"2.3514\"}", + "call_id": "call_iq1qaN71h66JZCHRlsDAfuwY", + "name": "weather" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 180, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 24, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 204 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:44 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"call_gX93cEAltLtPimsZIQ0NEGxE","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"call_gX93cEAltLtPimsZIQ0NEGxE","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"},{"type":"message","role":"assistant","content":"The + current weather in Berlin is 15°C with a wind speed of 10 km/h.","status":"completed"},{"type":"message","role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)","status":"completed"},{"type":"function_call","call_id":"call_iq1qaN71h66JZCHRlsDAfuwY","name":"weather","arguments":"{\"latitude\":\"48.8575\",\"longitude\":\"2.3514\"}","status":"completed"},{"type":"function_call_output","call_id":"call_iq1qaN71h66JZCHRlsDAfuwY","output":"Current + weather at 48.8575, 2.3514: 15°C, Wind: 10 km/h","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:45 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999550' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '627' + X-Envoy-Upstream-Service-Time: + - '630' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef28e0cc8191946700cfc95659c0055a91a7a73f8fa0", + "object": "response", + "created_at": 1756098344, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef293190819180166ea05e1c311a055a91a7a73f8fa0", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The current weather in Paris is 15\u00b0C with a wind speed of 10 km/h." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 233, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 21, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 254 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:45 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_with_multi-turn_streaming_conversations.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_with_multi-turn_streaming_conversations.yml index f808c68d0..e855a08ed 100644 --- a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_with_multi-turn_streaming_conversations.yml +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_with_multi-turn_streaming_conversations.yml @@ -41,7 +41,7 @@ http_interactions: Openai-Processing-Ms: - '517' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -161,7 +161,7 @@ http_interactions: Openai-Processing-Ms: - '548' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -246,7 +246,7 @@ http_interactions: Openai-Processing-Ms: - '319' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -369,7 +369,7 @@ http_interactions: Openai-Processing-Ms: - '242' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -410,5 +410,561 @@ http_interactions: string: !binary |- ZGF0YTogeyJpZCI6ImNoYXRjbXBsLUM2ZlBUQ2VDa0JqOVM4VzYyY0JkMjE2QzFvSnd0Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NTcwNTE4MywibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF9jNGMxNTU5NTFlIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiIiwicmVmdXNhbCI6bnVsbH0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsLCJvYmZ1c2NhdGlvbiI6IlBVb21NZHhNIn0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1DNmZQVENlQ2tCajlTOFc2MmNCZDIxNkMxb0p3dCIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTU3MDUxODMsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfYzRjMTU1OTUxZSIsImNob2ljZXMiOlt7ImluZGV4IjowLCJkZWx0YSI6eyJjb250ZW50IjoiVGhlIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsLCJvYmZ1c2NhdGlvbiI6IkVsQ3hidUYifQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUM2ZlBUQ2VDa0JqOVM4VzYyY0JkMjE2QzFvSnd0Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NTcwNTE4MywibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF9jNGMxNTU5NTFlIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiIgY3VycmVudCJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbCwib2JmdXNjYXRpb24iOiIzNSJ9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQzZmUFRDZUNrQmo5UzhXNjJjQmQyMTZDMW9Kd3QiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU1NzA1MTgzLCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwX2M0YzE1NTk1MWUiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6IiB3ZWF0aGVyIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsLCJvYmZ1c2NhdGlvbiI6IngzIn0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1DNmZQVENlQ2tCajlTOFc2MmNCZDIxNkMxb0p3dCIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTU3MDUxODMsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfYzRjMTU1OTUxZSIsImNob2ljZXMiOlt7ImluZGV4IjowLCJkZWx0YSI6eyJjb250ZW50IjoiIGluIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsLCJvYmZ1c2NhdGlvbiI6IkIyY3dPZ0UifQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUM2ZlBUQ2VDa0JqOVM4VzYyY0JkMjE2QzFvSnd0Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NTcwNTE4MywibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF9jNGMxNTU5NTFlIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiIgUGFyaXMifSwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOm51bGx9XSwidXNhZ2UiOm51bGwsIm9iZnVzY2F0aW9uIjoid0ZDSiJ9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQzZmUFRDZUNrQmo5UzhXNjJjQmQyMTZDMW9Kd3QiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU1NzA1MTgzLCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwX2M0YzE1NTk1MWUiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6IiBpcyJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbCwib2JmdXNjYXRpb24iOiJDN1NWYk5TIn0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1DNmZQVENlQ2tCajlTOFc2MmNCZDIxNkMxb0p3dCIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTU3MDUxODMsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfYzRjMTU1OTUxZSIsImNob2ljZXMiOlt7ImluZGV4IjowLCJkZWx0YSI6eyJjb250ZW50IjoiICJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbCwib2JmdXNjYXRpb24iOiJDSTdPSjlhVjUifQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUM2ZlBUQ2VDa0JqOVM4VzYyY0JkMjE2QzFvSnd0Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NTcwNTE4MywibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF9jNGMxNTU5NTFlIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiIxNSJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbCwib2JmdXNjYXRpb24iOiJENGN6V1lxNyJ9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQzZmUFRDZUNrQmo5UzhXNjJjQmQyMTZDMW9Kd3QiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU1NzA1MTgzLCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwX2M0YzE1NTk1MWUiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6IsKwQyJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbCwib2JmdXNjYXRpb24iOiJXVGNsNk15diJ9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQzZmUFRDZUNrQmo5UzhXNjJjQmQyMTZDMW9Kd3QiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU1NzA1MTgzLCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwX2M0YzE1NTk1MWUiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6IiB3aXRoIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsLCJvYmZ1c2NhdGlvbiI6IlRwa2hsIn0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1DNmZQVENlQ2tCajlTOFc2MmNCZDIxNkMxb0p3dCIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTU3MDUxODMsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfYzRjMTU1OTUxZSIsImNob2ljZXMiOlt7ImluZGV4IjowLCJkZWx0YSI6eyJjb250ZW50IjoiIGEifSwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOm51bGx9XSwidXNhZ2UiOm51bGwsIm9iZnVzY2F0aW9uIjoicURkVU9qMnAifQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUM2ZlBUQ2VDa0JqOVM4VzYyY0JkMjE2QzFvSnd0Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NTcwNTE4MywibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF9jNGMxNTU5NTFlIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiIgd2luZCJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbCwib2JmdXNjYXRpb24iOiJnWThtRCJ9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQzZmUFRDZUNrQmo5UzhXNjJjQmQyMTZDMW9Kd3QiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU1NzA1MTgzLCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwX2M0YzE1NTk1MWUiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6IiBzcGVlZCJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbCwib2JmdXNjYXRpb24iOiJQMWtIIn0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1DNmZQVENlQ2tCajlTOFc2MmNCZDIxNkMxb0p3dCIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTU3MDUxODMsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfYzRjMTU1OTUxZSIsImNob2ljZXMiOlt7ImluZGV4IjowLCJkZWx0YSI6eyJjb250ZW50IjoiIG9mIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsLCJvYmZ1c2NhdGlvbiI6InZwVmFZbFcifQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUM2ZlBUQ2VDa0JqOVM4VzYyY0JkMjE2QzFvSnd0Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NTcwNTE4MywibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF9jNGMxNTU5NTFlIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiIgIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsLCJvYmZ1c2NhdGlvbiI6IjZVczJrempqbyJ9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQzZmUFRDZUNrQmo5UzhXNjJjQmQyMTZDMW9Kd3QiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU1NzA1MTgzLCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwX2M0YzE1NTk1MWUiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6IjEwIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsLCJvYmZ1c2NhdGlvbiI6IlVTdUpzakFTIn0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1DNmZQVENlQ2tCajlTOFc2MmNCZDIxNkMxb0p3dCIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTU3MDUxODMsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfYzRjMTU1OTUxZSIsImNob2ljZXMiOlt7ImluZGV4IjowLCJkZWx0YSI6eyJjb250ZW50IjoiIGttIn0sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjpudWxsfV0sInVzYWdlIjpudWxsLCJvYmZ1c2NhdGlvbiI6ImVyYmQ2U2QifQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLUM2ZlBUQ2VDa0JqOVM4VzYyY0JkMjE2QzFvSnd0Iiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTc1NTcwNTE4MywibW9kZWwiOiJncHQtNC4xLW5hbm8tMjAyNS0wNC0xNCIsInNlcnZpY2VfdGllciI6ImRlZmF1bHQiLCJzeXN0ZW1fZmluZ2VycHJpbnQiOiJmcF9jNGMxNTU5NTFlIiwiY2hvaWNlcyI6W3siaW5kZXgiOjAsImRlbHRhIjp7ImNvbnRlbnQiOiIvaCJ9LCJsb2dwcm9icyI6bnVsbCwiZmluaXNoX3JlYXNvbiI6bnVsbH1dLCJ1c2FnZSI6bnVsbCwib2JmdXNjYXRpb24iOiJNRllpdjNOdyJ9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQzZmUFRDZUNrQmo5UzhXNjJjQmQyMTZDMW9Kd3QiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU1NzA1MTgzLCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwX2M0YzE1NTk1MWUiLCJjaG9pY2VzIjpbeyJpbmRleCI6MCwiZGVsdGEiOnsiY29udGVudCI6Ii4ifSwibG9ncHJvYnMiOm51bGwsImZpbmlzaF9yZWFzb24iOm51bGx9XSwidXNhZ2UiOm51bGwsIm9iZnVzY2F0aW9uIjoiMElhY1o3dDBaIn0KCmRhdGE6IHsiaWQiOiJjaGF0Y21wbC1DNmZQVENlQ2tCajlTOFc2MmNCZDIxNkMxb0p3dCIsIm9iamVjdCI6ImNoYXQuY29tcGxldGlvbi5jaHVuayIsImNyZWF0ZWQiOjE3NTU3MDUxODMsIm1vZGVsIjoiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLCJzZXJ2aWNlX3RpZXIiOiJkZWZhdWx0Iiwic3lzdGVtX2ZpbmdlcnByaW50IjoiZnBfYzRjMTU1OTUxZSIsImNob2ljZXMiOlt7ImluZGV4IjowLCJkZWx0YSI6e30sImxvZ3Byb2JzIjpudWxsLCJmaW5pc2hfcmVhc29uIjoic3RvcCJ9XSwidXNhZ2UiOm51bGwsIm9iZnVzY2F0aW9uIjoiY3hSWSJ9CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtQzZmUFRDZUNrQmo5UzhXNjJjQmQyMTZDMW9Kd3QiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNzU1NzA1MTgzLCJtb2RlbCI6ImdwdC00LjEtbmFuby0yMDI1LTA0LTE0Iiwic2VydmljZV90aWVyIjoiZGVmYXVsdCIsInN5c3RlbV9maW5nZXJwcmludCI6ImZwX2M0YzE1NTk1MWUiLCJjaG9pY2VzIjpbXSwidXNhZ2UiOnsicHJvbXB0X3Rva2VucyI6MjQzLCJjb21wbGV0aW9uX3Rva2VucyI6MjAsInRvdGFsX3Rva2VucyI6MjYzLCJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOnsiY2FjaGVkX3Rva2VucyI6MCwiYXVkaW9fdG9rZW5zIjowfSwiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6eyJyZWFzb25pbmdfdG9rZW5zIjowLCJhdWRpb190b2tlbnMiOjAsImFjY2VwdGVkX3ByZWRpY3Rpb25fdG9rZW5zIjowLCJyZWplY3RlZF9wcmVkaWN0aW9uX3Rva2VucyI6MH19LCJvYmZ1c2NhdGlvbiI6IjNNMUVybzMifQoKZGF0YTogW0RPTkVdCgo= recorded_at: Wed, 20 Aug 2025 15:53:04 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"}],"stream":true,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:53 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '353' + X-Envoy-Upstream-Service-Time: + - '387' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_68abef3157188190bbae5f1d81fb51ec0fadd368ad07380b","object":"response","created_at":1756098353,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_68abef3157188190bbae5f1d81fb51ec0fadd368ad07380b","object":"response","created_at":1756098353,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","type":"function_call","status":"in_progress","arguments":"","call_id":"call_rQ7wmCt39AiazKO0fZ8vCQt9","name":"weather"}} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":3,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"{","obfuscation":"CWjNfMpTHzozoBq"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":4,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"\"latitude","obfuscation":"KhnHt75"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"\":","obfuscation":"bjbkLDs1IVoYgU"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"\"52","obfuscation":"ZsNW7EvyoVzP9"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":".","obfuscation":"9Hd3YBFYUMwfnYF"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"520","obfuscation":"DLaU5DYdPxZvG"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"0","obfuscation":"5icGM8xuSMnvsGc"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":10,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"\",","obfuscation":"69PDeZsS31Gwqm"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":11,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"\"longitude","obfuscation":"cuN7MD"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":12,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"\":","obfuscation":"gNnCifQCS0vYa0"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":13,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"\"13","obfuscation":"uz5DxrlZyRPBE"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":14,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":".","obfuscation":"x8GL17alfJ3UlM0"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":15,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"405","obfuscation":"uRTPcK3mXiyaf"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":16,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"0","obfuscation":"eVvgsrDU7C8wRCD"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":17,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"delta":"\"}","obfuscation":"oLBesbCLXxmRhk"} + + event: response.function_call_arguments.done + data: {"type":"response.function_call_arguments.done","sequence_number":18,"item_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output_index":0,"arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}"} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":19,"output_index":0,"item":{"id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","type":"function_call","status":"completed","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","call_id":"call_rQ7wmCt39AiazKO0fZ8vCQt9","name":"weather"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":20,"response":{"id":"resp_68abef3157188190bbae5f1d81fb51ec0fadd368ad07380b","object":"response","created_at":1756098353,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","type":"function_call","status":"completed","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","call_id":"call_rQ7wmCt39AiazKO0fZ8vCQt9","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":82,"input_tokens_details":{"cached_tokens":0},"output_tokens":40,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":122},"user":null,"metadata":{}}} + + recorded_at: Mon, 25 Aug 2025 05:05:54 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"}],"stream":true,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:54 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '200' + X-Envoy-Upstream-Service-Time: + - '207' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_68abef32c6d88195b99703374a16a9d703c31b1894f2d11a","object":"response","created_at":1756098354,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_68abef32c6d88195b99703374a16a9d703c31b1894f2d11a","object":"response","created_at":1756098354,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"YBNtRwRQM3B8K"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" current","logprobs":[],"obfuscation":"BhFyiQ3D"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" weather","logprobs":[],"obfuscation":"fSkbnIDV"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"KLnodo63g2MUs"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" Berlin","logprobs":[],"obfuscation":"dBiuHXYpF"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"ILwjaeXkloEbm"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"4IFkuk5y5KCrBJF"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":"15","logprobs":[],"obfuscation":"up3AVcADDriWl8"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":"°C","logprobs":[],"obfuscation":"g8BJbN3c0zcpCH"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" with","logprobs":[],"obfuscation":"uf5NozHh21O"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"R8GRofpk4LaXef"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" wind","logprobs":[],"obfuscation":"7EQDD2WXL5Q"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" speed","logprobs":[],"obfuscation":"GgMDCxA2Re"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"4pPfbMPRAQSNg"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"DalngkWQ3wqsi76"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":"10","logprobs":[],"obfuscation":"aju1AhbV7j2QWx"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":" km","logprobs":[],"obfuscation":"VKJbt9e3a63rR"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":"/h","logprobs":[],"obfuscation":"4UOuaBsNHJOEpM"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"FnCTsQBAVTLMcMo"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":23,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"text":"The current weather in Berlin is 15°C with a wind speed of 10 km/h.","logprobs":[]} + + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":24,"item_id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The current weather in Berlin is 15°C with a wind speed of 10 km/h."}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":25,"output_index":0,"item":{"id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current weather in Berlin is 15°C with a wind speed of 10 km/h."}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":26,"response":{"id":"resp_68abef32c6d88195b99703374a16a9d703c31b1894f2d11a","object":"response","created_at":1756098354,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_68abef333b8c8195b98ed9af6ce01e0603c31b1894f2d11a","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current weather in Berlin is 15°C with a wind speed of 10 km/h."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":135,"input_tokens_details":{"cached_tokens":0},"output_tokens":21,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":156},"user":null,"metadata":{}}} + + recorded_at: Mon, 25 Aug 2025 05:05:55 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"},{"type":"message","role":"assistant","content":"The + current weather in Berlin is 15°C with a wind speed of 10 km/h.","status":"completed"},{"type":"message","role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)","status":"completed"}],"stream":true,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:56 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '229' + X-Envoy-Upstream-Service-Time: + - '238' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_68abef33d6f08194b98d8cf84de44fac09c31a2ab04e449c","object":"response","created_at":1756098355,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_68abef33d6f08194b98d8cf84de44fac09c31a2ab04e449c","object":"response","created_at":1756098355,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","type":"function_call","status":"in_progress","arguments":"","call_id":"call_YVmiETBfAhGtGWHOysO8oQZJ","name":"weather"}} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":3,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"{\"","obfuscation":"dxMFodXdMqcPPw"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":4,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"latitude","obfuscation":"1QhoHSKf"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"\":\"","obfuscation":"GstJyc7bvEQaL"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"48","obfuscation":"rKYVax15JsTdv9"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":".","obfuscation":"X1mZM4i0J7rRimG"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"857","obfuscation":"SaWzZeGfIjSws"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"5","obfuscation":"fmTWQl9ZD1ly7IS"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":10,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"\",\"","obfuscation":"C7S5eGwRoPZGA"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":11,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"longitude","obfuscation":"XjvzA6c"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":12,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"\":\"","obfuscation":"Pr2seK8tVEFaz"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":13,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"2","obfuscation":"QnUgCskJnhu3M2p"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":14,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":".","obfuscation":"XxYv2xyEgpFQKPa"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":15,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"351","obfuscation":"rOcLSSffZslnE"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":16,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"4","obfuscation":"NeGxvZW5kyvLzss"} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":17,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"delta":"\"}","obfuscation":"l4in8O5PwsDR2X"} + + event: response.function_call_arguments.done + data: {"type":"response.function_call_arguments.done","sequence_number":18,"item_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output_index":0,"arguments":"{\"latitude\":\"48.8575\",\"longitude\":\"2.3514\"}"} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":19,"output_index":0,"item":{"id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","type":"function_call","status":"completed","arguments":"{\"latitude\":\"48.8575\",\"longitude\":\"2.3514\"}","call_id":"call_YVmiETBfAhGtGWHOysO8oQZJ","name":"weather"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":20,"response":{"id":"resp_68abef33d6f08194b98d8cf84de44fac09c31a2ab04e449c","object":"response","created_at":1756098355,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","type":"function_call","status":"completed","arguments":"{\"latitude\":\"48.8575\",\"longitude\":\"2.3514\"}","call_id":"call_YVmiETBfAhGtGWHOysO8oQZJ","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":180,"input_tokens_details":{"cached_tokens":0},"output_tokens":24,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":204},"user":null,"metadata":{}}} + + recorded_at: Mon, 25 Aug 2025 05:05:56 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"fc_68abef3240e88190a94144ae71f93b3f0fadd368ad07380b","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"},{"type":"message","role":"assistant","content":"The + current weather in Berlin is 15°C with a wind speed of 10 km/h.","status":"completed"},{"type":"message","role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)","status":"completed"},{"type":"function_call","call_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","name":"weather","arguments":"{\"latitude\":\"48.8575\",\"longitude\":\"2.3514\"}","status":"completed"},{"type":"function_call_output","call_id":"fc_68abef3447bc81948f16d1d8c9f85d3809c31a2ab04e449c","output":"Current + weather at 48.8575, 2.3514: 15°C, Wind: 10 km/h","status":"completed"}],"stream":true,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:57 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '62' + X-Envoy-Upstream-Service-Time: + - '68' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_68abef34f09c819f8112abc8819a98380e8739318ccb65bc","object":"response","created_at":1756098356,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_68abef34f09c819f8112abc8819a98380e8739318ccb65bc","object":"response","created_at":1756098356,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"Lr7Yw9zti2YqR"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" current","logprobs":[],"obfuscation":"t05HfMqB"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" weather","logprobs":[],"obfuscation":"zH0P4qeW"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"VwcJDn4DNc626"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" Paris","logprobs":[],"obfuscation":"nQqfHEGRkA"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"8ffYuU1CKHbMd"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"5ZKk4dvkR3l6WAC"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":"15","logprobs":[],"obfuscation":"dm0cbGpanF5KJ3"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":"°C","logprobs":[],"obfuscation":"LrPYVoPpWKRzBh"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" with","logprobs":[],"obfuscation":"WXcjqU1GGMQ"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"vFGkJP1jkse89M"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" wind","logprobs":[],"obfuscation":"J6llSCb6GS4"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" speed","logprobs":[],"obfuscation":"sv0p4WFwEh"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"172Y0lR3g19QQ"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"Z9kXWBuq6Ggaqqe"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":"10","logprobs":[],"obfuscation":"UvPjLKkI0ot411"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":" km","logprobs":[],"obfuscation":"oFvq7P9ecZTGc"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":"/h","logprobs":[],"obfuscation":"KseXq892JySzIU"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"ritv6mrjqrEXka9"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":23,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"text":"The current weather in Paris is 15°C with a wind speed of 10 km/h.","logprobs":[]} + + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":24,"item_id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The current weather in Paris is 15°C with a wind speed of 10 km/h."}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":25,"output_index":0,"item":{"id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current weather in Paris is 15°C with a wind speed of 10 km/h."}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":26,"response":{"id":"resp_68abef34f09c819f8112abc8819a98380e8739318ccb65bc","object":"response","created_at":1756098356,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_68abef354620819f8aae2634635dea710e8739318ccb65bc","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current weather in Paris is 15°C with a wind speed of 10 km/h."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets current weather for a location","name":"weather","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., 13.4050)"}},"required":["latitude","longitude"],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":233,"input_tokens_details":{"cached_tokens":0},"output_tokens":21,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":254},"user":null,"metadata":{}}} + + recorded_at: Mon, 25 Aug 2025 05:05:57 GMT recorded_with: VCR 6.3.1 ... diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters.yml index 16363e8f8..3c31db111 100644 --- a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters.yml +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters.yml @@ -39,7 +39,7 @@ http_interactions: Openai-Processing-Ms: - '480' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -164,7 +164,7 @@ http_interactions: Openai-Processing-Ms: - '933' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -240,4 +240,302 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 15:51:00 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the best language to learn?","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"best_language_to_learn","description":"Gets + the best language to learn","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:46 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999742' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '502' + X-Envoy-Upstream-Service-Time: + - '507' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef2a567481a2878f26fc21a7d8ca01fdbe950f386125", + "object": "response", + "created_at": 1756098346, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef2aad5081a29af7f65d08558ba401fdbe950f386125", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_rNv01Gx3oYf92kxECusP39mL", + "name": "best_language_to_learn" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets the best language to learn", + "name": "best_language_to_learn", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 42, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 14, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 56 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:46 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the best language to learn?","status":"completed"},{"type":"function_call","call_id":"call_rNv01Gx3oYf92kxECusP39mL","name":"best_language_to_learn","arguments":"{}","status":"completed"},{"type":"function_call_output","call_id":"call_rNv01Gx3oYf92kxECusP39mL","output":"Ruby","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"best_language_to_learn","description":"Gets + the best language to learn","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:47 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999717' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '599' + X-Envoy-Upstream-Service-Time: + - '605' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef2b3570819eb1a341b17d867c4b05921ee1afc2726c", + "object": "response", + "created_at": 1756098347, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef2b97a8819e93224152b5b7d0b305921ee1afc2726c", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The best language to learn, according to the latest information, is Ruby." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets the best language to learn", + "name": "best_language_to_learn", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 65, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 17, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 82 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:47 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters_in_multi-turn_streaming_conversations.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters_in_multi-turn_streaming_conversations.yml index 91a86db0d..ba953ec89 100644 --- a/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters_in_multi-turn_streaming_conversations.yml +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_openai_gpt-4_1-nano_can_use_tools_without_parameters_in_multi-turn_streaming_conversations.yml @@ -40,7 +40,7 @@ http_interactions: Openai-Processing-Ms: - '392' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -130,7 +130,7 @@ http_interactions: Openai-Processing-Ms: - '217' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -236,7 +236,7 @@ http_interactions: Openai-Processing-Ms: - '264' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -300,5 +300,422 @@ http_interactions: data: [DONE] recorded_at: Wed, 20 Aug 2025 15:52:04 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must use tools whenever possible.","status":"completed"},{"type":"message","role":"user","content":"What''s + the best language to learn?","status":"completed"}],"stream":true,"tools":[{"type":"function","name":"best_language_to_learn","description":"Gets + the best language to learn","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:48 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '426' + X-Envoy-Upstream-Service-Time: + - '454' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_68abef2c808c8196b7d31438e656239a087e5ba4ac78125d","object":"response","created_at":1756098348,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_68abef2c808c8196b7d31438e656239a087e5ba4ac78125d","object":"response","created_at":1756098348,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"fc_68abef2d5f0c8196a730553050771c29087e5ba4ac78125d","type":"function_call","status":"in_progress","arguments":"","call_id":"call_wYjfMYT9L7fHWOAkJNgcBevG","name":"best_language_to_learn"}} + + event: response.function_call_arguments.delta + data: {"type":"response.function_call_arguments.delta","sequence_number":3,"item_id":"fc_68abef2d5f0c8196a730553050771c29087e5ba4ac78125d","output_index":0,"delta":"{}","obfuscation":"nkXX4ZquTubURI"} + + event: response.function_call_arguments.done + data: {"type":"response.function_call_arguments.done","sequence_number":4,"item_id":"fc_68abef2d5f0c8196a730553050771c29087e5ba4ac78125d","output_index":0,"arguments":"{}"} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":5,"output_index":0,"item":{"id":"fc_68abef2d5f0c8196a730553050771c29087e5ba4ac78125d","type":"function_call","status":"completed","arguments":"{}","call_id":"call_wYjfMYT9L7fHWOAkJNgcBevG","name":"best_language_to_learn"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":6,"response":{"id":"resp_68abef2c808c8196b7d31438e656239a087e5ba4ac78125d","object":"response","created_at":1756098348,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"fc_68abef2d5f0c8196a730553050771c29087e5ba4ac78125d","type":"function_call","status":"completed","arguments":"{}","call_id":"call_wYjfMYT9L7fHWOAkJNgcBevG","name":"best_language_to_learn"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":53,"input_tokens_details":{"cached_tokens":0},"output_tokens":14,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":67},"user":null,"metadata":{}}} + + recorded_at: Mon, 25 Aug 2025 05:05:49 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must use tools whenever possible.","status":"completed"},{"type":"message","role":"user","content":"What''s + the best language to learn?","status":"completed"},{"type":"function_call","call_id":"fc_68abef2d5f0c8196a730553050771c29087e5ba4ac78125d","name":"best_language_to_learn","arguments":"{}","status":"completed"},{"type":"function_call_output","call_id":"fc_68abef2d5f0c8196a730553050771c29087e5ba4ac78125d","output":"Ruby","status":"completed"}],"stream":true,"tools":[{"type":"function","name":"best_language_to_learn","description":"Gets + the best language to learn","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:50 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '70' + X-Envoy-Upstream-Service-Time: + - '76' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_68abef2dedac81a3bb4626e6dc83e63606d0a3dafa96ea37","object":"response","created_at":1756098349,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_68abef2dedac81a3bb4626e6dc83e63606d0a3dafa96ea37","object":"response","created_at":1756098349,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"ZaVVjFT2Z7SYO"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" best","logprobs":[],"obfuscation":"TR9CaBaK2Fv"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" language","logprobs":[],"obfuscation":"uGtqSsV"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"mmTaqyOlD4kZ9"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" learn","logprobs":[],"obfuscation":"zoOr9YxiFJ"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"LBznC1SUWlIlc"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" Ruby","logprobs":[],"obfuscation":"rlUdJuii1LL"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"PydYpfsjUapEvAR"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" Would","logprobs":[],"obfuscation":"VAcL8yKZ7Q"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" you","logprobs":[],"obfuscation":"2OTWGESA9bPZ"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" like","logprobs":[],"obfuscation":"pCoydwyw5t8"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"PDPeMRanN9qEo"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" explore","logprobs":[],"obfuscation":"Qqmwqjke"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" why","logprobs":[],"obfuscation":"RthHaAGvwiRc"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" it","logprobs":[],"obfuscation":"b3eNSBQl3TQaE"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"KtqxXvDWzO5wF"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" considered","logprobs":[],"obfuscation":"JobPa"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"5qyZVWPBx4CH"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" best","logprobs":[],"obfuscation":"AiRn1q4LhGD"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"G90n3mlTyfcCg"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" learn","logprobs":[],"obfuscation":"XoiIwzj3MX"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" about","logprobs":[],"obfuscation":"oc4r2niFyL"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" other","logprobs":[],"obfuscation":"BnroRGM8bT"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":" languages","logprobs":[],"obfuscation":"s0TjrG"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"delta":"?","logprobs":[],"obfuscation":"aGxub8XEsN3orRZ"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":29,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"text":"The best language to learn is Ruby. Would you like to explore why it is considered the best or learn about other languages?","logprobs":[]} + + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":30,"item_id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The best language to learn is Ruby. Would you like to explore why it is considered the best or learn about other languages?"}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":31,"output_index":0,"item":{"id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The best language to learn is Ruby. Would you like to explore why it is considered the best or learn about other languages?"}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":32,"response":{"id":"resp_68abef2dedac81a3bb4626e6dc83e63606d0a3dafa96ea37","object":"response","created_at":1756098349,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_68abef2e442881a3a74027106383b12606d0a3dafa96ea37","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The best language to learn is Ruby. Would you like to explore why it is considered the best or learn about other languages?"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":76,"input_tokens_details":{"cached_tokens":0},"output_tokens":27,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":103},"user":null,"metadata":{}}} + + recorded_at: Mon, 25 Aug 2025 05:05:51 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"developer","content":"You + must use tools whenever possible.","status":"completed"},{"type":"message","role":"user","content":"What''s + the best language to learn?","status":"completed"},{"type":"function_call","call_id":"fc_68abef2d5f0c8196a730553050771c29087e5ba4ac78125d","name":"best_language_to_learn","arguments":"{}","status":"completed"},{"type":"function_call_output","call_id":"fc_68abef2d5f0c8196a730553050771c29087e5ba4ac78125d","output":"Ruby","status":"completed"},{"type":"message","role":"assistant","content":"The + best language to learn is Ruby. Would you like to explore why it is considered + the best or learn about other languages?","status":"completed"},{"type":"message","role":"user","content":"Tell + me again: what''s the best language to learn?","status":"completed"}],"stream":true,"tools":[{"type":"function","name":"best_language_to_learn","description":"Gets + the best language to learn","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:51 GMT + Content-Type: + - text/event-stream; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '390' + X-Envoy-Upstream-Service-Time: + - '491' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |+ + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_68abef2f89f48191920404eba7ffdb6504d2f43fe0a341ff","object":"response","created_at":1756098351,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_68abef2f89f48191920404eba7ffdb6504d2f43fe0a341ff","object":"response","created_at":1756098351,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","type":"message","status":"in_progress","content":[],"role":"assistant"}} + + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"z4F7YBS5xd0wR"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" best","logprobs":[],"obfuscation":"T2JSXDnBCHg"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" language","logprobs":[],"obfuscation":"RqBKkg7"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"BFi9LkQ0ZOJne"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" learn","logprobs":[],"obfuscation":"w6BpXOhiqW"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"3f2RPE8T14RXA"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" Ruby","logprobs":[],"obfuscation":"yvT6QSIh7dU"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"ZTF9UaddxTHgERT"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" If","logprobs":[],"obfuscation":"GzI88XcXu3HIl"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" you're","logprobs":[],"obfuscation":"zQnV0U9tc"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" interested","logprobs":[],"obfuscation":"zRxIR"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"MOlPwtQNt0WF4"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" exploring","logprobs":[],"obfuscation":"Ue310p"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" more","logprobs":[],"obfuscation":"1EkFUQXeL86"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" about","logprobs":[],"obfuscation":"w4QYDrJ83x"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" it","logprobs":[],"obfuscation":"JoPWhlaoc8TKP"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"eu1Df45hqTYW3"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" considering","logprobs":[],"obfuscation":"AlLM"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" other","logprobs":[],"obfuscation":"NokYwgB3zv"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" options","logprobs":[],"obfuscation":"B4ht3MPH"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"TqwG2CI3UzektO7"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" feel","logprobs":[],"obfuscation":"MeWbGYrd6Ru"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" free","logprobs":[],"obfuscation":"M86QmrIQADa"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"DZcByvRiLzc2B"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":" ask","logprobs":[],"obfuscation":"x1kMfmwGWPfZ"} + + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"delta":"!","logprobs":[],"obfuscation":"F8YVJ3MIpbAPizb"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":30,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"text":"The best language to learn is Ruby. If you're interested in exploring more about it or considering other options, feel free to ask!","logprobs":[]} + + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":31,"item_id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The best language to learn is Ruby. If you're interested in exploring more about it or considering other options, feel free to ask!"}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":32,"output_index":0,"item":{"id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The best language to learn is Ruby. If you're interested in exploring more about it or considering other options, feel free to ask!"}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":33,"response":{"id":"resp_68abef2f89f48191920404eba7ffdb6504d2f43fe0a341ff","object":"response","created_at":1756098351,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_68abef303b688191b1a046906ecc84df04d2f43fe0a341ff","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The best language to learn is Ruby. If you're interested in exploring more about it or considering other options, feel free to ask!"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Gets the best language to learn","name":"best_language_to_learn","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":120,"input_tokens_details":{"cached_tokens":0},"output_tokens":28,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":148},"user":null,"metadata":{}}} + + recorded_at: Mon, 25 Aug 2025 05:05:52 GMT recorded_with: VCR 6.3.1 ... diff --git a/spec/fixtures/vcr_cassettes/chat_halt_functionality_adds_halt_content_to_conversation_history.yml b/spec/fixtures/vcr_cassettes/chat_halt_functionality_adds_halt_content_to_conversation_history.yml index c40907c00..1067342d9 100644 --- a/spec/fixtures/vcr_cassettes/chat_halt_functionality_adds_halt_content_to_conversation_history.yml +++ b/spec/fixtures/vcr_cassettes/chat_halt_functionality_adds_halt_content_to_conversation_history.yml @@ -39,7 +39,7 @@ http_interactions: Openai-Processing-Ms: - '551' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -111,4 +111,150 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:12:58 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Execute + the halting tool","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"halting","description":"A + tool that halts conversation continuation","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:12 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999745' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '467' + X-Envoy-Upstream-Service-Time: + - '470' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef43d41881a3bbf63f66dac2f2f20f720f175ec45c34", + "object": "response", + "created_at": 1756098371, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef442da881a3bba01aa0cbd9578f0f720f175ec45c34", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_WKCosP79aiQhA7mjS9Pci1Bt", + "name": "halting" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "A tool that halts conversation continuation", + "name": "halting", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 38, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 12, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 50 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:12 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_halt_functionality_does_not_continue_conversation_after_halt.yml b/spec/fixtures/vcr_cassettes/chat_halt_functionality_does_not_continue_conversation_after_halt.yml index f4f4be29f..de40344d2 100644 --- a/spec/fixtures/vcr_cassettes/chat_halt_functionality_does_not_continue_conversation_after_halt.yml +++ b/spec/fixtures/vcr_cassettes/chat_halt_functionality_does_not_continue_conversation_after_halt.yml @@ -39,7 +39,7 @@ http_interactions: Openai-Processing-Ms: - '735' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -123,4 +123,150 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:12:56 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Execute + the halting tool","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"halting","description":"A + tool that halts conversation continuation","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:10 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999745' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '374' + X-Envoy-Upstream-Service-Time: + - '377' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef42186081a18300e00977ba14d00a63dd4335888366", + "object": "response", + "created_at": 1756098370, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef4258c081a1a38d60c2d4e102e60a63dd4335888366", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_wTnEzwHjDZjtr1qedH9Dgias", + "name": "halting" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "A tool that halts conversation continuation", + "name": "halting", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 38, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 12, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 50 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:10 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_halt_object_when_tool_halts.yml b/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_halt_object_when_tool_halts.yml index 82beefc16..d4de995e0 100644 --- a/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_halt_object_when_tool_halts.yml +++ b/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_halt_object_when_tool_halts.yml @@ -39,7 +39,7 @@ http_interactions: Openai-Processing-Ms: - '800' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -123,4 +123,150 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 15:53:59 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Execute + the halting tool","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"halting","description":"A + tool that halts conversation continuation","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:09 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999745' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '508' + X-Envoy-Upstream-Service-Time: + - '512' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef411bd481a28738bd347fe481f202f05226b5bfacda", + "object": "response", + "created_at": 1756098369, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef4177b081a2a4ec52723a4c8da502f05226b5bfacda", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_PEW7KADo0jaSkTfgsaMIJlyI", + "name": "halting" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "A tool that halts conversation continuation", + "name": "halting", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 38, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 12, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 50 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:09 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_sub-agent_result_through_halt.yml b/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_sub-agent_result_through_halt.yml index 70c24f33d..ba7cb799a 100644 --- a/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_sub-agent_result_through_halt.yml +++ b/spec/fixtures/vcr_cassettes/chat_halt_functionality_returns_sub-agent_result_through_halt.yml @@ -40,7 +40,7 @@ http_interactions: Openai-Processing-Ms: - '468' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -124,4 +124,158 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:12:57 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Please + handle this query: What is Ruby?","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"handoff","description":"Delegates + to a sub-agent and halts","parameters":{"type":"object","properties":{"query":{"type":"string","description":"Query + to pass to sub-agent"}},"required":["query"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:11 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999725' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '511' + X-Envoy-Upstream-Service-Time: + - '514' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef42e3dc819c85b94e477ee254ce0a4376492b6926a0", + "object": "response", + "created_at": 1756098370, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef433a40819cb3a614df626fa1f60a4376492b6926a0", + "type": "function_call", + "status": "completed", + "arguments": "{\"query\":\"What is Ruby?\"}", + "call_id": "call_m7CvvfmYyTSJkTjfAKZtxAeF", + "name": "handoff" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Delegates to a sub-agent and halts", + "name": "handoff", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Query to pass to sub-agent" + } + }, + "required": [ + "query" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 58, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 76 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:11 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_can_handle_array_of_mixed_files_with_auto-detection.yml b/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_can_handle_array_of_mixed_files_with_auto-detection.yml index c0e986286..ec6413534 100644 --- a/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_can_handle_array_of_mixed_files_with_auto-detection.yml +++ b/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_can_handle_array_of_mixed_files_with_auto-detection.yml @@ -38,7 +38,7 @@ http_interactions: Openai-Processing-Ms: - '1535' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -85,4 +85,142 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1DNmdZN0NHcDJNRDZ3V2JwVHIybVVEME43TjZZcSIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NTcwOTU2MywKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIlRoZSBmaWxlIHlvdSBwcm92aWRlZCBhcHBlYXJzIHRvIGJlIGEgc2FtcGxlIFBERiBkb2N1bWVudCBjb250YWluaW5nIHBsYWNlaG9sZGVyIG9yIGdlbmVyaWMgdGV4dCByYXRoZXIgdGhhbiBzcGVjaWZpYyBvciBkZXRhaWxlZCBjb250ZW50LiBUaGUgdGV4dCBpbmNsdWRlcyBjb21tb24gZmlsbGVyIHRleHQgKFwiTG9yZW0gaXBzdW1cIikgYWxvbmcgd2l0aCBwaHJhc2VzIGxpa2UgXCJGdW4gZnVuIGZ1blwiIGF0IHRoZSBiZWdpbm5pbmcsIGluZGljYXRpbmcgaXQgbWlnaHQgYmUgYSB0ZW1wbGF0ZSBvciBhbiBleGFtcGxlIGRvY3VtZW50LiBcblxuSWYgeW91IG5lZWQgYSBkZXRhaWxlZCBhbmFseXNpcyBvciBzcGVjaWZpYyBpbnNpZ2h0cywgcGxlYXNlIGNsYXJpZnkgeW91ciBnb2FsIG9yIGxldCBtZSBrbm93IGlmIHRoZXJlJ3MgYSBwYXJ0aWN1bGFyIGFzcGVjdCB5b3UnZCBsaWtlIG1lIHRvIGZvY3VzIG9u4oCUc3VjaCBhcyBleHRyYWN0aW5nIGtleSBpbmZvcm1hdGlvbiwgaWRlbnRpZnlpbmcgdmlzdWFsIGNvbnRlbnQsIG9yIHN1bW1hcml6aW5nIHRoZSBvdmVyYWxsIHN0cnVjdHVyZS4iLAogICAgICAgICJyZWZ1c2FsIjogbnVsbCwKICAgICAgICAiYW5ub3RhdGlvbnMiOiBbXQogICAgICB9LAogICAgICAibG9ncHJvYnMiOiBudWxsLAogICAgICAiZmluaXNoX3JlYXNvbiI6ICJzdG9wIgogICAgfQogIF0sCiAgInVzYWdlIjogewogICAgInByb21wdF90b2tlbnMiOiAxMDA0LAogICAgImNvbXBsZXRpb25fdG9rZW5zIjogMTA1LAogICAgInRvdGFsX3Rva2VucyI6IDExMDksCiAgICAicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjogewogICAgICAiY2FjaGVkX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwCiAgICB9LAogICAgImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOiB7CiAgICAgICJyZWFzb25pbmdfdG9rZW5zIjogMCwKICAgICAgImF1ZGlvX3Rva2VucyI6IDAsCiAgICAgICJhY2NlcHRlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAsCiAgICAgICJyZWplY3RlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAKICAgIH0KICB9LAogICJzZXJ2aWNlX3RpZXIiOiAiZGVmYXVsdCIsCiAgInN5c3RlbV9maW5nZXJwcmludCI6ICJmcF9jNGMxNTU5NTFlIgp9Cg== recorded_at: Wed, 20 Aug 2025 17:06:04 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Analyze + these files"},{"type":"input_image","image_url":"data:image/png;base64,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"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,JVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGdWsuS20YSvOMr+siJ8IzZDT6PXtmK8MbaIYfHu4cNHzAkNGoHCFIEMJ+737KZ1VUNUKRkjfYR4oCNRnVWVtYD/Oh+cx/dHP9d+eDW2+DOtfuPa933bzrvdp3zrtt9+v17N39YzeU/Lk6/LHAzvyznfruab9KtEQ/wsuqe//AZu4P7x6MrV+kq/l0H5+cr93hw37/1D3Pni8f3bvZ7dTg1tXv349s79/iX++kRxs656Wc29Bt9zEY2LEPaMDzMC++44eOH2Dn8r3JdtK3d/5r6wb0dWvc+/f9hfNiN5xQwHEgRsXsiBsNXZXpOScP5nP+62b+O5zvn125WH+7c/da7mcO/5dLN4qkbeG29LuTaYutm+2Mj60Na5ktc62LPOzbp0gZXqkPdf3cHR+mqDb7bHduu3vV1P9Tnu+Ie+/M5PmCnah9PsdvF9lmfzG9oSd3EHoeEN3Qx7nr3oerqphk6XA8lvyju/Rwf3le72MQu8osS5+EmNOa4j0fuYSb7BUyu91yFT/Io3H2ID9jpT/f4z+S9G4CSCZ8Aut5cA/pmOFdPsR94SvhZnrDACboBRzzJgYIeaAObfh2aphLokzU06qVuYN4q3buEdS3O9YD95Lzufonj/dRHuW2drvF4XX04AVyn2K4mPlwoIB6rhx47LXQrj6c08MvQAeigd25w8Z3S4hhbeFLP4QM+VE38OFQHOJgsIf5brK/PFWkgPq+f6x7AvhbNbVlIXE3pefpQGT/7c4UHGEM9bdodD4fj/kiu6QHLILbcFaT0kVywkwYe9RBBdkU/rPEBtNzHQ932QnU/B2FICb+cu1k6JSJSLgUeTYhDELgoJF6LCfhTLQhLuOKvoeuPsmalG2HBJqRA8mtYAi/ANnyQVfQLvA524M9X4hbmm2vcfm57eAHQ3UO05BnlGswigms9Y1nCNLoNnrdQWCyWxezNuSJwesrFHOdpqiwTNQ2nvTS83OLUTXweGtlZ+VOSGLvhDMozCMw1W9xUt/FApmFP3r+A9M1+qNu6AsuWGo+LFT50u7qpz7H7ONRYJ1uAtQx0wQnX9GGLOT6IUbYn9HzWi0Z8Gc0iqftlTAeIyhUL/52Mq7s+Pg2NUIXRxRN4Pn4fEUEHRgIg5dUN/pU4EcPWigASCoMU5+cJuS4QeJEA/qEXPZ1gcobFJJQsJmp/Z0q12w2HjnAmxaMIAbQKfKC1ajSD5yX2Fa5ZOPgNvlTFtbOt8UGsw+P/LF6ljQEJ4QpHFQm/SYEQqI+aUhjXlBQDZg0En5oK0Qm+qdmBuh5bLKOICyRLX8zOQ38WnyzNbh7l4xA7rlSmBqYvU0ijZCDlTkPzElvITGE2GN5ESQlrDkPBMNFsb4rpPcx9qc4x5SU73xz2QmGeyeGF7YqkMQOxobhE9XUZJyxvaCQowWQRX6qDPJ7aJeCscLU7Nk3cIR/tBThLISURRJpmhCo7S/JPZMm4HZY4bARzVIL3SSR5VtkfhRAYU8f3dbsH1Es9dknaMGXh0Lq0ZMpKMYmL6faSafCEOIX61inOTavL1bwQLtKBZh6p0QO4Humn/gboVjdkcoyWLMUSBpb8JIHoaSmXTAkMI1+qlDMkJcZTLsRXW/AsuRdstlvh8t+H7gScYteBDKV9Q4o18Yk1kWQsbJ5ZTKFm9QIQTC8DcTxUfS9lTr4q2V/KsAX2k5Jog4Vah+XMFHiN2ftCwwP9wJT93RdBva2W0JarKP+AY1rSPotVpuya5r67K3hucsgzPbWsgSB0wDVdXeLi71Kj0WSuYwWlgmX09lSPakBwoTTSZcysP6T6hNvNE/2YZFR6UsmI/UDRl2Mz9CfJf6wa+Jjtopjcz/oMVxkq7+vhOUqFw824lA5/GZrT0FdJWie2g/zNN9STYXtDM6e8EY7w4UscnQLHjymcaKTgiEs5keBUJ/NEHyV6E0EcQjWlBEItJ7+xluHP8+OfA2WENaIlI+ayVCMWM6kRWV5wI+8JDBMJ/tCAxtpUJFAlFD9WA131HJXLqUItYEXF3iFokcI0AG52vZQkpWJMx3+ZrejcrhugEvy7ZGsWfyfpwonjPt9W3YyBEoe83BVt1buJrhGVsMKxpVPSI+ACXAAFHlG6l3yYq3FWjry1ZJi/O1d1B6HE33kDfH+duzSuAmWoHdodtEahlNSlpLHWLDBCYrUb4Fy4hg8sYCu8YK6BL3LvJDlUSltcVDeGJbanLMLUzyez28CBxVfANcen4znJm1fDpUnscZU16BYJn/xQspFgqZsT42GrxOVFpaY4sibbD0hKuXpFO1NoEhwPKT3OC0rStkpmWGcrXSY2RhBYf+mZy38VlK22p0Fa+oL+aibiWgNAVM6MZyNhxZ91aAyLXPu9viUt0Q9eYTr2zKhQFTjYIJ3n7niWptHqJOrxRa/ujD64g5KBE1CMSRQWRT8mFQoKMhb1sd3F/dAyjE1dmMrQEQNlHLllr6AqTn2P+7sCl4Xr2OayJSOP8Q2FvRnYp2JXy57cvY1PH6bUK76qcy/Rul3BlATRfBs85h4TgTd524BoXXWKNetQy9WBrMM5nLX2gV2TxRCjBbTlAT3D5VB1HTHAPCZdlNSvQr0DQ3MVTC2Vkkzx8RjjaElaqDqjh8C1qd5AsdUbnhXtyzQY2LLSDso3gH6pKOuvpxkbsSv8pLUpLGN7VlTGbpNzDmSEXVAM0TKYIbCwUtbiapU8DoYUWo4aSlisAm24+9yhsCzbqI8IXwpUSzZ+DfzHyUzuHzyplAlLl0yetYeXnwagA7dRi9LoC4ayhSusI/B86mRaguWf10EdKF62nAv0Q1dgWgbNIsgmElMlTMoYAWpnoP0XrbJXogUimkZznCDJIShHWhNaJg0SgJYALCrv0YIC63qHSs1anMA0dP5wbHfSZNhoy9OuCgtdlgAOWmR4SKlQvgX2tKMOaXOKuODEZQIssbYajVy36c9umOT7gqPgm5PaT4AFOlfAjpVcKvmR75gh6wFHyL0G5wzP5+ol7hmnlgECRVoWGigla6OR0JxQJKxxXimaGHs1dk6SyWSOLQycXJinNKKDwEQsmEUtAQ0IiW5KqmFHXGEBSJ+K/0QhbKwT2JXl2S0glJQulbfWu9/AULjRgNQJtcL44NL0xk0bOfjdpuBf56f1jQD4ub1zpnosaA/VgLaKlFJ98ATqUvdSGY+RB+GWXG/84+xbelIS1eKBfs/Fz73lKiq0OFmWYTOG4Eh8IwN5Ly218V5amYvCQbnAjMEIKay98SSB5tIcnOyI/qBrdaIrxYMOr2kSvU0Tpf5CMLx2WL1AZWE+zNP/iXSQJiw+wDhgZCMAT6JZPYIS0SJEBh7tkTmQTBd5ITI6kcUsRS8yD1ZYNf37VO9ZRuQsxWjToaPtLyOEGtWrRxaQ3bnIEqfJH/HQ1w9AVBAi1qiq+Zk5zspGHbUiQHGLNX5Y9EqpXmK2aCCmQECtn+Y+OFBOfTzFj0foJ9ARFiGEqdQN3lG0kXCAumIi/m1rzjgLdva85CkyUiHBUl6QG6X0IQNUCoi1tvLYzYSEDSvBvStGp1CHtN6w5I898FYpT3ViGlKKVOD5fDzqPGybw4mKLvnaZIxhlcddajgfPlHyL4J7sx9Y3hq9ynFczjZESep9GJDQWhVajpFRCplnU/wWL1wwahmbYThApwA2kGWLxQISZ01tPafVuDYOSfgXn8P3C2nyqA7wlCEbfmGBTRA8g1ymKXCpmbOFORYZCWGxncqRluZ4C6S5DuVtAu/Dtkin+SKmN2uLJYhihJWoL0BYSVj2Lg4dlZtRVg1RvhbRaLRZB8faMtMiAxWRNToeiy4bnNp5qVcnNGx9lJ7N6CmjAakq0Bqp/+jZPNW7K0h2wUZCu+ZYMU/WKEW5ZoUlmRRzbGajXTXFZpFpqq2l9ZHpw2xkSSoU+QpQi8u6YgnRvgCVL1InrYIhyUdYJmZPzYMtMWGS2l9Vk5VsTm25IZCacvKm07pD5oZxFGNDSI5epsWtHZGtTGqOc+ZhuTVpxICHRq/0wuPozNjAGkx0bHqm1P6g+zEnilof2xHJr63Qlsh6V0hqS4faEPuPE478Jktf/WnzgiNYBg4Mwk+n4TbYlc5rzGSFsYcvfNIYERslH0ntnCYlBhy6wdSgkEGKRSDuqPzT5Fbek+r9vCsPAS6FfRy/ahz5LRnASfw3TAyXt+avNyeGkrA1//AM5jpaZ12aZ7KGE8GRasyg8iaN4aadBQfkFTIbRt3puCRl6kxkVbrIactEHg1H3jwpOtBH5QKIjvqlqncYvMjYXYnJTMaAyfNFXE9J4cIAGQ6/vipa3hq58p2PU7126f2H+BjvPx6c5HXHwuzBYUbtpi9YHGpOlyyRMg1Af77AuJkDV5gJXQXEL8fzE1+mqGRIQaoDVnFYcU/N5rQPcqnBT/xHtiOBGd1wBwsQ1VnOVZKgAGJqEzWKjp3UbHx/iDXSyowVIIVWRrULoxJDJE8vFyZOzMlTRmbpZxgx+/GBukUajrDOx0WrnJj96gHBqXQTlqZ3SaPgyK+DvqIlXMGuK3zHw9l4LIwRDB8aRSXgdeCV8ES9wFFqemum6qEjnmcZc+n4Ck2twIVjWe3q2RbYMHWFKkaQZzrYx2eMOfDDH6y2bCtlCZKf/VhhKkMcqrxJr+bS7xfYs8CY7riLguT4SOCMsebxm16grZBTr6DDKy2MSTElga32uwjCJW41XSZEh4qHyifCb1lwEW/DiIh6n0nuVJ0hJRiuif4k5vH1IBibKyweEhqxg2ZypLjU3yex0DtHvIrHG3puaxNN8gwvRulHlRTPLv0qTwi9YBeQyxW9WsYfxKTeDEaLn7ABGo8v8u92fEMsr0C0hkXs2qff9Vhu5aM7/ekQOjTTAP7kJpUNOCk+i1EEkjNynbJq1YMa2ISDEiu1bcUJltHaszyFlAFiA4gzuAxCho1jbKW/3SuvGTUF7gZgbKHsyWT7kZLtQH+OxR7sNMPxOGlSXi/gq1uTXJEVTFD0OHxzC2WGdVZHeZYWk3FUFhuSBmEmLxXzK/stFOjTH6mkOl9mMdorU87waxoyVaiEeSTgng4Xk0/lZ1xa9tsYjp3ZZHSg/uI7I3kvBVU3qFi2WCvBOE8IimP/5gXuzf5gjX7D+KiTHY5hAZVNcH77P6d6b9EKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjM4NjYKZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAzIDAgUiAvUmVzb3VyY2VzIDYgMCBSIC9Db250ZW50cyA0IDAgUiAvTWVkaWFCb3ggWzAgMCA2MTIgNzkyXQo+PgplbmRvYmoKNiAwIG9iago8PCAvUHJvY1NldCBbIC9QREYgL1RleHQgXSAvQ29sb3JTcGFjZSA8PCAvQ3MxIDcgMCBSID4+IC9Gb250IDw8IC9GMS4wIDggMCBSCi9GMy4wIDEwIDAgUiAvRjIuMCA5IDAgUiA+PiA+PgplbmRvYmoKMTEgMCBvYmoKPDwgL0xlbmd0aCAxMiAwIFIgL04gMSAvQWx0ZXJuYXRlIC9EZXZpY2VHcmF5IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AYVST0gUURz+zTYShIhBhXiIdwoJlSmsrKDadnVZlW1bldKiGGffuqOzM9Ob2TXFkwRdojx1D6JjdOzQoZuXosCsS9cgqSAIPHXo+83s6iiEb3k73/v9/X7fe0RtnabvOylBVHNDlSulp25OTYuDHylFHdROWKYV+OlicYyx67mSv7vX1mfS2LLex7V2+/Y9tZVlYCHqLba3EPohkWYAH5mfKGWAs8Adlq/YPgE8WA6sGvAjogMPmrkw09GcdKWyLZFT5qIoKq9iO0mu+/m5xr6LtYmD/lyPZtaOvbPqqtFM1LT3RKG8D65EGc9fVPZsNRSnDeOcSEMaKfKu1d8rTMcRkSsQSgZSNWS5n2pOnXXgdRi7XbqT4/j2EKU+yWCoibXpspkdhX0AdirL7BDwBejxsmIP54F7Yf9bUcOTwCdhP2SHedatH/YXrlPge4Q9NeDOFK7F8dqKH14tAUP3VCNojHNNxNPXOXOkiO8x1BmY90Y5pgsxd5aqEzeAO2EfWapmCrFd+67qJe57AnfT4zvRmzkLXKAcSXKxFdkU0DwJWBR9i7BJDjw+zh5V4HeomMAcuYnczSj3HtURG2ejUoFWeo1Xxk/jufHF+GVsGM+Afqx213t8/+njFXXXtj48+Y163DmuvZ0bVWFWcWUL3f/HMoSP2Sc5psHToVlYa9h25A+azEywDCjEfwU+l/qSE1Xc1e7tuEUSzFA+LGwluktUbinU6j2DSqwcK9gAdnCSxCxaHLhTa7o5eHfYInpt+U1XsuuG/vr2evva8h5tyqgpKBPNs0RmlLFbo+TdeNv9ZpERnzg6vue9ilrJ/klFED+FOVoq8hRV9FZQ1sRvZw5+G7Z+XD+l5/VB/TwJPa2f0a/ooxG+DHRJz8JzUR+jSfCwaSHiEqCKgzPUTlRjjQPiKfHytFtkkf0PQBn9ZgplbmRzdHJlYW0KZW5kb2JqCjEyIDAgb2JqCjcwNAplbmRvYmoKNyAwIG9iagpbIC9JQ0NCYXNlZCAxMSAwIFIgXQplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFswIDAgNjEyIDc5Ml0gL0NvdW50IDEgL0tpZHMgWyAyIDAgUiBdID4+CmVuZG9iagoxMyAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgPj4KZW5kb2JqCjE0IDAgb2JqCjw8IC9MZW5ndGggMTUgMCBSIC9MZW5ndGgxIDM0MzIgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBrVZtaFvXGT7nXFmSpUiW5CsplmxZ17JuZEnWpyXZqT9kx7LlOHP8UTu6hiR2/J3Zq5e6IYFu9cI2Mv3o8qulsB8lHYVC6bRBg2r2I4x90LIfhnU/tmQshRXGGKM/kg3GbO05V7JZhymFTeLRed/3nPPe9zznfd8rQgkhp8guEUh2aWtxm7xInsHya6C8dHPHS0R8Cf02dM3q9tpWyDL6C+h3CWHvr23eXo2+bqlgKkuI7un6yuLyXzt9F+GwC+vT6zBof8X+AX0Tevv61s4t+6v0Q+j3oIc3X1ha1McMq9B/Cv301uKtbeYXRqB/DN37tcWtlX/95GMr9KfQ49svvLhD3qI3CDEFoHdv31jZ3iaGOegL0PUAxZd/ThEteRejl0zVLKr5f/ph2C2c4EGj2upOmDkyaWuC7sigjnpSr44GznEZfIyXSf1k4ceUvqqUaeU7ZTLc8gHWCFevdJYJDXu9uY3hEl2AwsIwBCVIQtg7UhL8I9MFn+Iteotjy0XviHd9cbmk8asjJlaKStRbIjOFDfw+X5BKWcV9LK4oyln40XA/2ILlRQUertc8YFRN0QMsqguPe0uCPFmYKpR2h92l7LDiliRvrvRwslB6OOyWFAWrtMeRIuJvbJyuxaxDzNog5vVVLzPwARdKsch9QmOyVHpYLLqLOIlq8UllSmoGnJSvEfy5Ms1OFvhU1ie5ucEn+STEoQzDd314fKaQQyQSj8TwxZQajwPF2lMIz6hSavo/UWr+MpQ2fClKLceRfo5SK2K2cEptJ1Pq+wJCjxnOnsDwbpXh3RMYbvwPhnn6MpJA2f0MxSEQHTESZEkU6RSNxf2SVfJbJSvdO9ylu4e36D09/Ux/iB3VfWlsXmAfoVabyFaZuKN7KFUTEULIbQt0QHxcJrrHg3Xk9/D9F4BdHnSjJHTYoiMdQA8wBijABnAb+B7wBvAO8AHwIWC6jMjMiIwisow1mfAwu2hmPgFiP0t1RZjv/CfptelEfPbrA08eDd660p25tJUS2X3PV+4sz70y08EeHKQDs3cXNopTEg5ACeKnf0P89aSVR645jly7X2OB4nk6PK/RKqUkaxK/5+kPD/MifZl+k3aLB2l6Hc2Vc8i5iKlcOMlLZdIELswgk3NhBg9kHzaMOvBhq/JhAx+2Iz5s4MMGPmzgwwY+bODDBj5s4MMGPmzgwwY+bODDBj5sVT4I4jviBNGpRMg+yYp4Ew6VnvNUSMz0tt1YO/yjSE3Li55UPkhzTfGx6OI1hK/Qy/OzwWynk/MhVT5jKfaI9JGZPdKK1sujb7VwbpActVttxSmMOI2RXwVkO2R7TQ7idHy+CyOfG3gMHv2Y7AGHNBkRfG1m3JqHOT2CGl1bhKV8Wg87usIzESHV1Q/Vw1ijKATOKanQpZFwMDcX6lDGoh1DM8GeqzlZpB3ja32R+Xz4zJCSiBRyoeDgpD/2fJ+fsd6ZpNMWHE11DZ5xGAyN/oF0ZCjY2NStZIcX+prt0Xyyeyhw2mQU28/GYgNygxgd5/fnqDyjnzIziZMR8voeKGhUT9z3udPvkQBv52AigNPVA8371TGxj7TWYpsDkIE0MALMAavATeC7wGvA28AD4JeA6TKK47cQPgXY5arnPOfNAd40SKNm+NRYbT3IwmQ/Pcp7nRkMOjhvmSSE52jKTCM0Za1yXHfMble/NpMW6+ankr2temf8QsqbTbRemQgMp3x6Jjk8Bqd4ijZH+tpio3EXLbhTE4lgT3uDK9zTO5AOGuhS/qI7mHC2tDbUCcwknY3lcvb2SNO5FrtIaZ25gY4Gu31mV2RAuSrnM212KeToSLYYNUzfYOa8NlWe0j+AVzdYGdhDHvGa4BnVfJxRjeCwEYdtBp8iZBEygdzCq7CNK4CRV72URpXXUiiTSGd8ZupDCvmlfoHz0knfY02ZS72h6X7ZlZ7tLdwyiqavTmUuxJz0jcNVoS0zFkxcSLoOUtcuRNpzy9mepbEAXZqfnZWHlHx6rs/rz84itAzCHEctC8S5p/5h4DcuWBAN7wdE7QdJa0ZkHx2ksQwfdQ/7DbOQGKns4adaLzGcguFEfDTxqt9He3wCoAvWkTchlKpKIzaYiAXwAjEgC0wCC8A2sAvUIz0sKC0Xd/UmcWG3q+pqH8KTqsJdueDKBVcuuHLBlQuuXHDlgisXXLlUVy1wZUFkfkToR6LJeIQFiVaNNwJrBMdtwYoEz0d+dt5r3IAesKtbKNFjyx6JggMu8V6ZtNZq2P5fIr89rc4XoTpcos6XyojOUL8cSnuMoiPY6w9mJJNokfujvYUGZprq9aTCHh1j7OCQ+kITz/maY9n2wwd0pH0w0XI63C8fvkeng7l481C6Z5DZ5YTnFZwdOZepTNK/I+dOkyB5p0zCCNRBnGq+OXAa3ov5yG+G4SBhyAZwwW1H+cdlXtsGjHK1X8vo1/JRv5bRr2X0axn9Wka/ltGvZfRrGf1aRr+W0a9l9GsZ/VpGvwa3/P3FM1lCOPwNKqm82WtSLO60Jj0o79q7rEqQz5ppk486Iq/pcWa7Pp2azrR4eqaSZ851yQYm/unKjebURDwxHm9yxsZLNDsyGzp/LX32Wj7gDPa03TuYKH/rdmJ+OBDIKYlOZbST56sK4XeDr11t6H1GrcKfYSE///526/HoqEwiox9Br1fj5RPYJ7xVCRG3ZvXwR5V5zSXVE585+hjpU5KgDlzDXZKmn5A06weWiATZgbkmcodkBAPJsCa1zprRCF4m96mG3mERdpfdF9aFf6pejWQTz20Dqv838KKF+D7mqtHbas/W4lVFJoZm83NzofzK5s2VnY2lxYmVl1Y6Zzd3bixe2Fhb3+HRVb2Qyg/4/50TPkbYBHIGl5pE9x4meXIRZTODHED1k9C/AesArfoKZW5kc3RyZWFtCmVuZG9iagoxNSAwIG9iagoyMTc2CmVuZG9iagoxNiAwIG9iago8PCAvVHlwZSAvRm9udERlc2NyaXB0b3IgL0FzY2VudCA5MzEgL0NhcEhlaWdodCA3MjMgL0Rlc2NlbnQgLTIxMyAvRmxhZ3MgMzIKL0ZvbnRCQm94IFstMzM3IC0yMTkgMTExMSA5MzFdIC9Gb250TmFtZSAvTkJVSFZWK0hlbHZldGljYU5ldWUtVWx0cmFMaWdodAovSXRhbGljQW5nbGUgMCAvU3RlbVYgMjAgL0xlYWRpbmcgMjcgL01heFdpZHRoIDExMjYgL1N0ZW1IIDIwIC9YSGVpZ2h0IDUyMAovRm9udEZpbGUyIDE0IDAgUiA+PgplbmRvYmoKMTcgMCBvYmoKWyAyNzggMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDY0OCAwIDQ4MSAwIDAgMCAwIDAgMCAwIDAgMCA1NzQgMCAwIDYxMSAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDQ4MSAwCjAgMCA1MDAgMCAwIDAgMCAwIDAgMTMwIDc3OCAwIDAgNTM3IF0KZW5kb2JqCjggMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvTkJVSFZWK0hlbHZldGljYU5ldWUtVWx0cmFMaWdodAovRm9udERlc2NyaXB0b3IgMTYgMCBSIC9XaWR0aHMgMTcgMCBSIC9GaXJzdENoYXIgMzIgL0xhc3RDaGFyIDExMiAvRW5jb2RpbmcKL01hY1JvbWFuRW5jb2RpbmcgPj4KZW5kb2JqCjE4IDAgb2JqCjw8IC9MZW5ndGggMTkgMCBSIC9MZW5ndGgxIDgzMzIgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBrVl7bFvXeT/nXJKSSPElihSpy6cokuJDEiWKD4kSKdqULEuyLT9iiY5fsiLHcu1EecxIgBZ1gS5DhS1pi+7VbkuWJluTIo2bwoUiDImXdU0bbKtXrMUaGEaLokPQDmgWtAuWxNR+3728spw4Qf4IiY/3nHPvPef7vvP7XoeMM8Za2UUmsfGl84ur/BviCEb+BfS9pQsPBlk7vox/EX3d6dW7zydtu/4Z/a8wJi7ffe7h08433k3h1ixjnYUzy4t3/XcqnGbM/3k8nzuDAcNPJDP6/4B+95nzDz40/VXDv6H/c/T/4ty9S4v3/fRTbzAWeAj9vecXH1oV49Ih9H+AfvCexfPLQzv3PIs+nmGp1XsfeFC3R/enuAWe2D2r9y+vrjLjYfRpvWYQx5c+rczA1nENsvnGiDJ8y49AT7pl5MM6OtzQY8YmZQ3GWpQHjcyEdRiDfPhYQFZmU9rv/7GzNuaAHp3MxTqYm3lYJx6RmZf5mJ8FwGWIdbEw62YR0jcYT82ss5a5hW9z/mhtnW/+4Tqr+l7EutKJ473rjKeCwYmV6iV+Eh2RwkAihJaUCk5ekiKTBxbCteBacG33XWvByeCZxbsu6SLKFTeW12r9wUvs4MIKfg8thC6N1+St5nKtNoJ5dDQPXsHjazXMcLYxA67KUP8NPKRPzQQvSdG5hf0Lly5W5Uvj1ZocCgUnLl2ZW7h0pSqHajU8ZdjiFBx/ZsXd4LkJPBsSuN+sznIQc2CK2toazYmeiIYuXVlbk9cgiTISDq1z1hiApPSMFJlY5+NzC3RrPBySaSAcCofAR62KuVtSMwcXJsBJiDgxfrRKTVuM4tlWsGdSVGr+hFRq+TgqtX4sldq2OL1FpXbwbCOVtt1epeGPUOiWhsdvo+GLqoYv3kbDjm0aJswLNggTfAWGJcFWTLBAfT/g1J8eiITsoYg9ZOcb9Yv8Yv0h/sVm/mZzHW/Qh7Njmw+xy+wsrCiwoQxISaDaBoBcBfVjphbMxDBTPuzMuCyiyVmSspcPJbi+ta3VFXKZzp41+WSXLmnwRpIuZYpF/NKcEpM3FCegzsk2FKunjmRLDxR5Nrx46NBZPMzE5jv4+Yx4DXwZYZ94QuGfWCC2DIzeYnhLFhLP5EMdGf7cY2vP1X8xdZhPzO+uv8Hd/J76l/kLN3LXr2MafDiLbr4lnhA/Y3F2fgOmblImCdoqMuYLwiMEWRSUA02CDoNOgy6AHgH9GejvQN8FfR9kPlbRs5+g8SuQOAZpZHgd4ku2bWDGiNI2gEee6ZPCXRbhbPeLzGBJ5MMW9PtEdqiEvl+IA9Wm7L7FzKHPHkok8FO+ezbdVNV3j8wN7jpdCQQqp3fFdhXj/K3C4aJ/7O5HpqcfOT3WM312R/pgqTtXu2+kuFrLdaQqtO9T+PkjCNwMH/eZddYBdRkhPLFlxC52gPTXANBrYP518PtrkDgGFbSg4QHFQcOg3aAaaAX0MOgLoL8EPQN6EfRDkJmkboFmafoWSM2wmLYzDnumxLND0ZhkJyGd7RYRnnr7608//fXvfGnPvVNdXVP37hGv3cjpnn/hhed1N1bF4dDU/XNz90+FaK9IjhHIYWIZWkKVoAXc665iTZ2yJq0HT6wgYQMS65V2MzTusIeyALpCU/yt+gH+aP1+/gwtN8I7R7gY0dYwY40WBi01NdZowhriKhDHFaQ1bc0PzClt2lHIps1e5Yfrz/LP0dT8kDozzb0H030Jc0usYzvMlXlV+6E59lTpPTyGjyqzFx092Z6+wY/ehneIQVVmKGBLvin+H/VVRSaBtIADtUy8i/ctbH77mhtQYrPCuglbREHSZG8bbnBCfkG1aHjaxioMt0mfnKktc6Olyp1x4AvewyY+WRW/H/+dqN71v28rcqzc+HNB9NqNR8X9qky7wNPD4MnEZm7liUI4bR3puxlkvAoi/8LBEXHFQE23cGS8lQ8OHuxhvqsq+BOzVVE/qfBw9MZTuD4ljtL6qj3UsH4z4v0X1pkHE/IGaMireUBtsAe9ag962INeswc97EEPe9DDHvSwBz3sQQ970MMe9LAHPexBD3vQwx70sAc97EH1lSbCjxFL3WobrQ0sKXocdDnbDWEORZJLyA71ifAf/3rXwsKu+o+r/5feW/D7C3vT/BzvnpqenuLHga5BOTubTs9mZdrrEHzZAfiyCvtbMgMywQ0kLl3KEmHsc4ESGWzkOiv0K7ZegGwFTbYCZCtAtgJkK0C2AmQrQLYCZCtAtgJkK0C2AmQrQLaCIpv52gbrbWzCOuvFBrmhOzN0uPMarHKs4ZfHsHwPMira3h6gNR82KI5PR1L28z5Jc3wdGRK74RkD3C8pTgKe8UxVis+eK5ePjIUdel9mZ/Rbrpjf7h+ohKMT2ZCoJqdOZmdO5tvlVDHwuGcoKUeHd3gHDpe7f7Pj+KivI9LX29OaKiV9xqTe1hnx9ORCVmd8LJ4/WPAmS5OdiZEed3PM4PCn/LF82OZITSsqrECn54AVD5mbB0MkgAfCtMJqqN2q2iIaeMDRkNah2GPDtWcBSXJ05N3tlcDOlemZlZ2Bqje3d3Bgbw7GXc/nl6aTyemlPP9hfbI0n/d48vMljj3kSsw7gvWbsLhqB2QDEtYyNJSeHkC042EpLBl48z7eMvVf4g0F9a/d+Jz4LOE9uPkWrwsHy2JT/34D8HAonFcgRaqB+5Qa8SqIeBVEvAoiXgW+o4KIV0HEqyDiVRDxKoh4FUS8CiJeBRGvokW8CiJeBUAi3DlYRcEYMcqBBfLQ/qsg9KmdQzuF6wzhYxQZN6lxFMwMwJ9Re4C0h0ChhYgmC0DQCJMZpZHLZw3hrqy9ARW9hhECUb7E87mymB31DkScpnZ/e2ZpX1ruL3dH88mwXehtPrfZbmoxRbpy1a7e6XyQ7/EN7Oh2JYKO3sk7esxdBn66PNzijgednVaDMJiDY7nYcMRu6Yx52kNusxBZXZS3DVW6ze2JHQ8fiI4mXBY54o7GXaYmYTRBA9D5KHDjxr65oeLn1lkfNszdQI8bsgvoQJCtoK1DW4d2H9qt0BeNuTDmwlgr2h7VD3lgqx7NVj1oemCrHtiqB9vqga16YKse2KoHtuqBrXpgqx7Yqge26lFslWYOkx8iMPuBKdK2H5q3wzapbVdwm8lm/FB+wwPBFJvCdq4huJGfjI4I11K5OD/i9Y7MF72FdMQo+HFHfLx3cCLpcCQnBnvH4w7C4ancSHJmCRCfSVl8CS/vqRd69pVisdK+nsaVXFUXMPobYDRMeZi3gUqvikovUOkFKr1ApReo9AKVXqDSC1R6gUovUOkFKr1ApReo9Gqo9AKVXqgMOOtABCQJOyCtDhUdtSlqIg/jmrfJDOZuTcNc/Btl0wMHi3eWgsHSncWFVXNZ6uwZ8vVWezs68FOe5KdqC6nppUIBBrxyPJiLuaKlffH4vlJ0h4oDyi8FcNDJ+tjL66wfiueABy1PsUaAtP3vR9tyFYR9p3E32m48j01nXLEoGu3EaCeesKAtX1PyVBn6kaEfGfqRoR8Z+pGhHxn6kaEfGfqRoR8Z+pGhH1nTjwz9yNCPul6EkEEZTqLhIBLQVQsSWWK2BboKUWx9X9qacfIGIjQbFKIsjJF03rcFjuHBmFHU//qD4Kj/pzfhs6RUdCRtvoTnFBfvB4dQsPEmsGGEjCcoc3EpLFHmQiU+sUd2YgJxaIfaflzJ3zC0A2gH+oGBLghLD3cpiFfrBTvaHFOqGwI8hEoS+R19KHczDKnAAE76BH++/oLOkxiNwew76t/hfyLc+YXSWK0gy4Xa2KlPtZeteyd6xxMOHg3vzAQCmR213Mr+wf49pzKwgOTJhdGp6MhuwgaHBwcGgA1Zzc3aFSYkcNwOot2ndiftCqUo1kZyZFU4VsVWijA8ZMLDJohLfSfaJHbHVUiTDatx1dWRVXHu4yjRkGBw6bQweztNLrPVbYkOeI0LC2X+o2yvs1u2SSInhKunEOrP1gf4j8Ar7UGG0x4kWIn90zorfwSOy1h8O45VX6aa4E0ck3yE4bSK4TQ2NY39TQPDaWA4DQyngeE0MJwGhtPAcBoYTgPDaWA4rWE4DQyntzA8QpUA2QLtJ9VcLYh61KZKJNnAdRJYjtjDzluwnMtnKPnCFsfCfkCgJGIUsLeBm79ZFi2hRMZXmC8GOocXSsN3uMTehc7BuE9flmLF6Vh5Puf5VWo80e5IjPf2lnvanIlSgr9ec0Z9tviuE9n84lR8JD15/C6TO+aLF6NtXeNHp8PD07GePaORaGk2GpseDqvYKAIbVKR2sv0byoEUCdEJIVBhKQLZoLtOEEUSuqreQvHtZMXkRjZQ76kJtRMveoA4yt3VjF1FuRNIUGKoAS6+WOYdYCqa8beW21K7c/mjbfBcSDJ7o5V+2Z0YDtVf4rN90xnvcD8PABNjYPXT4JHOE2LbM3kVgOTXCMEGQrCavWNtZybbhFXHyuWyeG15+fs33hM61Pa/3NzRmMvJdn74XO1a9GqGPZBKqEzQ0G9FuxWLtuIkQl0HG2qIxpyDLiWa0aLtkaa2ZpPTFEp6WtT1XwomOedDoiM25BMZssubcn1UnTYG/m/WaaMwSD3so4f9+63cm69VJPYyNo0fQ+MxrfFbtaFX9hMHBxTYJTanjFIpjg2lF3+LrKHxYqPxsjpCL7rhm93ai3SbIgKdYpiZTYkXpP0oFBIFFGLYLEkZlTGauKb4ekKJ6l3CDaSEcZN0Sl6E2j54EapKNTvQmi4FOuEuQxP5FcAnO1puixR7/AmPqWwO5uLVXPmbmSMdloOZ8n6PJHQ33uPB+ETG1x7u76w/ybu7dw4Fdo7Xn+bHLw9m4GDT82CQMxX3DkAeKOgknj8u7j+I+Q9Deva2SCcOb4P0GnhQ/N9bwoj9dUCRr6KEgdrioDA26pOrE3ugcA8U78HMVtUvWuEXrfBnVvhFK/yiFX7RCr9ohV+0wi9a4Ret8ItW+EUr/KJV84tW+EUrwAF/aESuR2o0wgvQ2Ty12+EDuXYE03B0+W3nUVSWcZeW6GhXLRNqXPl1LdvRrlktGUI1Q0kR/n6gXHgHcmEHsJpi31RzYfJyxAZBjDwYXbU8iPJgC/RKYzdjB2tUrhQzPqmMWLEBqtrU7NcB/fgbqacf+iHcZ9RYoNTiCsw/kAgr2U7Bq2U75SWX4EtarmNPTA4pibDuRokHvQmvRcuFi7lT9bqW66TmRruREENXUehKQFeUL15W80X8e6PoioK65vGpdqC2prPtuePNaKBG2E8uS6SZlSyR6oebmeH2jDE9oH9/ZEVJhnxDcyCNOkLgJM8YGxze0psvTyVE/UlNc1oJ8ZJ45VRn3G/TskQLlFj/Ob+iqW5bDQEfzIvCgkwf7NGfR4QwCTybr4LUcyTiW42JVIoy3KBz64aH68hGVU/mzUwmJ5fdQnFbjvjEoCzKUrX8MOaEjwqgVnkFe1RkzxBgAso6VEYhwCptjrYJ437F39IRmnLorfRc6smLC9Wci3w3nbK6EJxdqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcMPJ1FoONUM47iGsM1zGqp+XGcY963pxX2Hn/efPNU5Uocp2tSm/7KQy/ryz8mZ2xrolC2BUbCux3xoMOOTHQUb5DV26+787u6WK0M56VD9miQaerO+mU0xEXP490p93WVYiFegPO5ja9xRnoQGVsrIyfOGyLFBNdg11OnUNnbvc5PV3OFrM3qeizafNd3iIeh1gPfLA6MmCLaA+bcKX6xwVpaT8p1XVoFYutccZsg+J1OHSjjdfhAdpfOuJWAYC4iraWmurRbqfolkUmiJzYgCQhl8G5Qh/P2jPZJ8pHjvDBssVrkeUu+4rQfe1r2frjOwZEVhLhAD+aVbFQBBauI4NxU55280zog3Lc9GTbq7mtrI2iF50gNTdyVDqxpnpLMZdojFp0AkJZKr9ebouOxGfGRLk9OTEwcsIDnNb/JzYzEp6a5HP1b/dNDcr5oWOKbvEfDv9X8PdR50cyzzjo/Ei8uvMfK0+IJwn1mLHI8Wcy4V2hi0+88/YJ6+jvuV2i/3vZ9x5bDWhXZG8ZZD8/Q78FPkz94D3p1c0k8+lO1Z/ZrOkmlJkaN5VLlP+ODXKYBugYaFFc2HxHXGFR8RybEvtBHpz5X2d76CrhPAr3dokLGL/AQnimIvbj+SYWFCU2imsXrlG6cokZRAp9D2z0ReRzL27+kq6YY5TGlHv0Dp7nRTbKf8ECvIc10T3UOySBF99JdpKtsff4Sf5lfoW/zt8RVfF58ab0Vel16T3dd/V79RuGo4YfNPmbftrc07y3+SvN32o50PI3xlHjj02rpqdaZ1ufbX3H7MVspMMo+zRmDoJUDSESo3kZ91QNtzX0Y6C0Z+/c3L4KjjSXz11YfnBlaXHv8h8s986u3H3mwcbbbPOv6P+823yiGJMQ+u34xzqKbKUHjiXF+lEkDbAMy+HYdphV2QSk2wXt7mbTbIbN4r+Jfcg+97MD7CA7xO5AljHPFhiSHxgQjIkl/x9NC1daCmVuZHN0cmVhbQplbmRvYmoKMTkgMCBvYmoKNDkxMAplbmRvYmoKMjAgMCBvYmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgOTY3IC9DYXBIZWlnaHQgNzIyIC9EZXNjZW50IC0yMTMgL0ZsYWdzIDMyCi9Gb250QkJveCBbLTM0MyAtMjE0IDEwOTMgOTY3XSAvRm9udE5hbWUgL05QUE9BRCtIZWx2ZXRpY2FOZXVlLUxpZ2h0IC9JdGFsaWNBbmdsZQowIC9TdGVtViA2OCAvTGVhZGluZyAyOSAvTWF4V2lkdGggMTEyMiAvU3RlbUggNTggL1hIZWlnaHQgNTI0IC9Gb250RmlsZTIgMTggMCBSCj4+CmVuZG9iagoyMSAwIG9iagpbIDI3OCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwCjYzMCAwIDcwNCA2ODUgNTkzIDUzNyAwIDAgMjIyIDAgMCA1MzcgODMzIDcwNCAwIDYzMCAwIDAgNjMwIDAgNjg1IDU5MyAwIDAKMCAwIDAgMCAwIDAgMCAwIDUxOSA1NzQgNTE5IDU3NCA1MTkgMjU5IDU1NiA1MzcgMTg1IDE4NSAwIDE4NSA4MzMgNTM3IDU1Ngo1NzQgNTc0IDMxNSA0ODEgMjk2IDUzNyA0NjMgXQplbmRvYmoKMTAgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvTlBQT0FEK0hlbHZldGljYU5ldWUtTGlnaHQgL0ZvbnREZXNjcmlwdG9yCjIwIDAgUiAvV2lkdGhzIDIxIDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAxMTggL0VuY29kaW5nIC9NYWNSb21hbkVuY29kaW5nCj4+CmVuZG9iagoyMiAwIG9iago8PCAvTGVuZ3RoIDIzIDAgUiAvTGVuZ3RoMSA1MDU2IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AbVYa2xb1R0/517b1zfX1/EjfsWP+MaPWyd2Hr6NnYRgO5HTpkmA0KatzUhp1uZVWpptoTwmRAVj0jJpRQixFdCExDTgw1imqVvI9qGaNrR1ExQhBtr6YZs2aUNoQojXBLX3O/fagW6F8WHY+t97zrnnnvP//37/x7EJJYTYyGnCk9KRE/Orvc6BKYz8jhDqOnJqLUra8CX0TxgzLa4uneh27P4V+n8lhDu3dPyuxfmB92J49Dgh8sbywvzRNyKxPkJc05ifW8aAMGd5Df2voR9fPrF2Z+xucjf6T6M/ffzkkfngWuRh9N9Gf8eJ+TtXuR5+PyHuEPrR2+ZPLLzm+3UE/RH0s6snv7JGf8+9gf4q+hOrX15YXSUtB9DfRN8Kofiyjw1Ni9761IsxuTmFazauuPPEtN03o3XFsgIGrCJpkbClbCethDiIc3v659xwfZb1wR/ASU9tEnGm8iNKv1XdpPUHNkk5/BwRCX/LocwmoelodHylvEEPo8OlMdCloMWno7s2+MSuvZVYNboeXd9zdD26K7o8f3TDlNDveLCwXu2NbpB9lRVcZyvKRqka3G4uVKvDWMfE1sErmL5exQrHGivgrg/1XsYkc3oqusEnZyo3VjZOl4MbpXI1qCjR8Y3zM5WN8+WgUq1ilmVbU2h8z4q/obMAnS1deG41VtmHNbBEdX2drYkel1Q2zq+vB9dhiT4SUzYpaQzAUjaHT4xv0tJMhT0qxZQgG4gpMQV6VMtYW0xP7auMQxOFadLy6ZBK24pirg3qSTqk8v8JUvtngbT1M0Hq2Nb0Ckid0NnBIHVdHdLYpwC6jXDpKgifNhA+fRWE3R9DmPk2R7KI418gLnkiEInAS3rhTr19/QnFqSScipNu1U7T07U76YNW+qa1hjfYhxIfrveTY3ivlWzhihW6QbOjr/8amo/5Zv37j2GMIwho7hHuAvKFl3xpC5s49YmCY9RM/oDO6xBubjSIUHGSACQFGYLsgVQhK5C7IN+AnIU8A3kO8huIPLdJ/JewvwyN2P6yYwu72vU2gS5uXskWuIGdPVyMurWsp83OqU88RlsOP3QkGywtX1e7eN+Tryb33lvlLlzO7brjsdnRlanU5VXuwKuT37y1xHId038J+oukA+jQXra+0Fh/C6mK19sWfS/NreQVyHfPlvfQL0i1p/L0ARtbmc4OU254G497dDyC5PYtgGIs5jXwEICH0MRDAB4C8BCAhwA8BOAhAA8BeAjAQwAeAvAQgIcAPAQdj/Al6GmHnldi4tjGJEi1bIRjUMQkqgGVBkDfKb6kDCQ9wb5S4vVHy2Mf5m4aTYS18RQ9TuNypD+uXtvlpYdgTLbjmoP51FjGz/xgHPjcC3sEEsS+vI6PwQVxAC+I+SJ4EDQeW+VvtL1zpnzmHYAyDJQfZJAQrv5+/S36W85NSmSWvLdJ9sMFD0DylxDUl3Q/kYCL1MRFAi4ScJGAiwRcJOAiARcJuEjARQIuEnCRgIsEXCQdl/1QxXsRAhU7gHve6RrC+hiNYzSOUZXkibQ9msFoBlp4MWPyEhzUQibx2iRJQnKQXZADkEXIKcjXIY9Avg/5CeR5iDwH9V9B428Qbg6eOg6cmKeOw1NHmP+gPcK8RyvwBi8WwZIU7LynLcJp2VzeZ6cer5YtUjuNdSYHdha4fIHXPbrTzpkFNtoDD9eH84WiOZzORVxqh6ejI7JPi5Wy4UD3SDz3xSBHKTcQDIiCJEhek1UWTVKLEM8V21OTwyrNtrUemvZ2Rd1dhd1hmxINW+mxaCZoszjCPq3LaqVWiyc+mErmOh39GU6wC3lzP6WC3eZPDnU7M7097li6vaUtVbrv4PjeFl8skMr4BI5yFknUOSZ2cPwPcCyRLvKvTdINZNMQBzgWDY5FcCw2ORbBsQiORXAsgmMRHIvgWATHIjgWwbEIjkVwLIJjUeeYgDOCVbvBWTva7WinDO5S4C4F7lLgLgXuUuAuBe5S4C4F7lLgLgXuUuAuBe5STe5S4C4FtVBksKKN6YzVZbRl+EwUxxERPgNm4ySssxkHs54Gsx60KXIfY5mCZaowlr2eNotZKdAmi542EJzLx5pc0mdqP7R2aqPq2BStPUUf5rl2baJ3bHkicevS3Fp70VUpJocSLpqMj2kd14+1uEu+tDczORAevPn2wuLazZWh3SA95mXxiSMMPYT49JFuxKcHKssN3ViuZMczQ7dN4oRJLGbdiFek8HwBecLry/fAwSytNKZHMA3ZFlvFZLrF3SI5os5Sweao2m5aLC7SFwcmkjETt9PMjQ1NDdT66YuMd1p/F5e/YP8O8lUGi6xv5zGynQzG5SbjMhiXGexgXAbjMhiXwbgMxmUwLoNxGYzLYFwG47LOuMKyHaOcQpywrh2nVGZRO6yLMPtADqsDmvuj+EInZ2BvEWLuM2cLQy07cqVOjxpxmfiJ4m6rr2uoc/hwkCvqyVvsvyEfafHG2uWgrfZjOrXDkxhQHMUeGkfugn3kBdj38fpJUD+R8fICNjrjLXqP3VY4yV1YWHj+8oecycCk8Q6ruExz/Q02+2zhUbYnFjTm8WbETC/5YJP0YVo/pA8USaBKQtvwQoxjLIpI8huR5Aeu/iaufuDqB65+4OoHrn7g6geufuDqB65+4OoHrn7g6geufh3XZvREsXIYu4Wxm4S2akSTimhSEU0qoklFNKmIJhXRpCKaVESTimhSEU0qoklFNKnNaFIRTSpUa9htx7JBsNbVYK0LW1ghHmzJ2jFWOxrcIWoAKJKfHkAMWxZBSXinENOdVFDzR28rDLYksoXOnpRloqhJkcy1Ka3Xsqc4wZvKU8NzEc48lhs+HOLaONPlD6klc8NwZy7pb69t/DN7cDSZTQaCtWfpjCNsH5ku9OXzhQx308f92A0/PvG5+fF/+/BH1rOKbWFGf+S5zNqreu58mHPp9n2S5x5iNnH1l+tjnBP+5Sc72FnETkJ66NiN6AzBi0JNLwrBi0LwohC8KAQvCsGLQvCiELwoBC8KwYtC8KIQvCgELwrpXtTFopOdmdx4nUWlG1GpIFmztsKqHgzSImC0cQZhXOZ9LEHidGJUu2PfLhQ5cyQ9GBldnlT9/Xuy5YMK1/a93eVQfl9ufCoyNAtbCzTRkQnJI7fcMdJ7fb5jSJtLVsZ6F2ZzM+N9S/vzBoc11KBzsHeEPMmOceyYsoWCpOnqMO9m6c9jxJAG67Wm9RrU12C9Bus1WK/Beg3Wa7Beg/UarNdgvQbrNVivwXp2ytAa54kOuDmLT7Z+10UI66NdYGfXwUY+HgQ2CeQvhk0C2ORjFnYCMJBRe1DzC+hGOEHL4TiL4o8TgsUAqocrFLhobncyMTmSUPqvCXqRygKJjKe9R3FxRRrsL6c6yoNxv5rNZtVAINnjCQ6kAk/3j6fbHImRdLyv0yeJLm/IFex0W+VQVyRT3OFydA4koxnF1+YOdLYH4j7JFsGvBcDWVn8Lpd0EA1dYOfHoKssO/YwkIzPIyAwyMoOMzCAjM8jIDDIyg4zMICMzyMgMMjKDjMzA0rh+RpKRGVgxaGQGlsutDTSsQENxx3g7b5x1cnl0YLpxQNIE+tDJ4pC0Y6AY+48UbgRC7T0jgccDSOD0uto5PYG3FnoOIWuz+viSXh+DsKeI3T0gJ4zd/3edRAIGiX4Qys65IeSqT6qb+UY1+MT6+UdWJk4WT16ljn7QLBw69gx/suvZnwVuaR15hzr5vzPX/uWZ1Y7mnUU1qsYF/PbCaYqN4oN3+J/Wu0nIdLi2VN9rmsJ7rxiPGlc3fZtkKTsyeImP+wExcwHIKUiajHNC/X1OIHYKvLgAat5zhvCj9XdZnyvUX6Z/rtfwThv9OcMUCSBE+siDZJNG6Ri3k3uT7+Of4Lf4F0wPm2rmU5Z2y2nLa0wv5Ia7wANqaUNb/BuG5jk8Y0/ZCYbd2d9CUUJm9o9OV0a7JxaOn1pYWzkyf/3C7QuZ6ZWl5bU9a/PHV45gHmyu49+u+uPst+1VPm6M8fjxqOoBnSdlMoGQniLT5AYyQ24k++CxFXIef0AgEEn3vwHogcgHCmVuZHN0cmVhbQplbmRvYmoKMjMgMCBvYmoKMzA0OQplbmRvYmoKMjQgMCBvYmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgOTUxIC9DYXBIZWlnaHQgNzIyIC9EZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}],"status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:17 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999235' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1592' + X-Envoy-Upstream-Service-Time: + - '1595' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef0c1f3c819c9c14622d9e24bd22028c3663b34c4864", + "object": "response", + "created_at": 1756098316, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef0caf18819c81ac46ec6b12f4c1028c3663b34c4864", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The provided text includes a description of a simple PDF file titled \"Sample PDF\" with the content \"Fun fun fun.\" Following that, there's a lengthy sample text that appears to be Lorem Ipsum, a commonly used placeholder text in the publishing and web design industry.\n\n**Key observations:**\n\n- **Title & Description:** \"Sample PDF\" and description \"This is a simple PDF file. Fun fun fun.\"\n- **Content:** Extensive Lorem Ipsum placeholder text, used to demonstrate layout or content structure.\n- **Purpose:** Likely intended as a template or mockup for PDF layout, testing, or demonstration.\n\nIf you need specific analysis, such as extracting text, summarizing, or analyzing the structure, please let me know!" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 792, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 146, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 938 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:17 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_understands_pdfs.yml b/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_understands_pdfs.yml index b8e4a45a0..ccc30c096 100644 --- a/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_understands_pdfs.yml +++ b/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_understands_pdfs.yml @@ -38,7 +38,7 @@ http_interactions: Openai-Processing-Ms: - '2333' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -159,7 +159,7 @@ http_interactions: Openai-Processing-Ms: - '1611' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -235,4 +235,286 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:05:57 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Summarize + this document"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,JVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGdWsuS20YSvOMr+siJ8IzZDT6PXtmK8MbaIYfHu4cNHzAkNGoHCFIEMJ+737KZ1VUNUKRkjfYR4oCNRnVWVtYD/Oh+cx/dHP9d+eDW2+DOtfuPa933bzrvdp3zrtt9+v17N39YzeU/Lk6/LHAzvyznfruab9KtEQ/wsuqe//AZu4P7x6MrV+kq/l0H5+cr93hw37/1D3Pni8f3bvZ7dTg1tXv349s79/iX++kRxs656Wc29Bt9zEY2LEPaMDzMC++44eOH2Dn8r3JdtK3d/5r6wb0dWvc+/f9hfNiN5xQwHEgRsXsiBsNXZXpOScP5nP+62b+O5zvn125WH+7c/da7mcO/5dLN4qkbeG29LuTaYutm+2Mj60Na5ktc62LPOzbp0gZXqkPdf3cHR+mqDb7bHduu3vV1P9Tnu+Ie+/M5PmCnah9PsdvF9lmfzG9oSd3EHoeEN3Qx7nr3oerqphk6XA8lvyju/Rwf3le72MQu8osS5+EmNOa4j0fuYSb7BUyu91yFT/Io3H2ID9jpT/f4z+S9G4CSCZ8Aut5cA/pmOFdPsR94SvhZnrDACboBRzzJgYIeaAObfh2aphLokzU06qVuYN4q3buEdS3O9YD95Lzufonj/dRHuW2drvF4XX04AVyn2K4mPlwoIB6rhx47LXQrj6c08MvQAeigd25w8Z3S4hhbeFLP4QM+VE38OFQHOJgsIf5brK/PFWkgPq+f6x7AvhbNbVlIXE3pefpQGT/7c4UHGEM9bdodD4fj/kiu6QHLILbcFaT0kVywkwYe9RBBdkU/rPEBtNzHQ932QnU/B2FICb+cu1k6JSJSLgUeTYhDELgoJF6LCfhTLQhLuOKvoeuPsmalG2HBJqRA8mtYAi/ANnyQVfQLvA524M9X4hbmm2vcfm57eAHQ3UO05BnlGswigms9Y1nCNLoNnrdQWCyWxezNuSJwesrFHOdpqiwTNQ2nvTS83OLUTXweGtlZ+VOSGLvhDMozCMw1W9xUt/FApmFP3r+A9M1+qNu6AsuWGo+LFT50u7qpz7H7ONRYJ1uAtQx0wQnX9GGLOT6IUbYn9HzWi0Z8Gc0iqftlTAeIyhUL/52Mq7s+Pg2NUIXRxRN4Pn4fEUEHRgIg5dUN/pU4EcPWigASCoMU5+cJuS4QeJEA/qEXPZ1gcobFJJQsJmp/Z0q12w2HjnAmxaMIAbQKfKC1ajSD5yX2Fa5ZOPgNvlTFtbOt8UGsw+P/LF6ljQEJ4QpHFQm/SYEQqI+aUhjXlBQDZg0En5oK0Qm+qdmBuh5bLKOICyRLX8zOQ38WnyzNbh7l4xA7rlSmBqYvU0ijZCDlTkPzElvITGE2GN5ESQlrDkPBMNFsb4rpPcx9qc4x5SU73xz2QmGeyeGF7YqkMQOxobhE9XUZJyxvaCQowWQRX6qDPJ7aJeCscLU7Nk3cIR/tBThLISURRJpmhCo7S/JPZMm4HZY4bARzVIL3SSR5VtkfhRAYU8f3dbsH1Es9dknaMGXh0Lq0ZMpKMYmL6faSafCEOIX61inOTavL1bwQLtKBZh6p0QO4Humn/gboVjdkcoyWLMUSBpb8JIHoaSmXTAkMI1+qlDMkJcZTLsRXW/AsuRdstlvh8t+H7gScYteBDKV9Q4o18Yk1kWQsbJ5ZTKFm9QIQTC8DcTxUfS9lTr4q2V/KsAX2k5Jog4Vah+XMFHiN2ftCwwP9wJT93RdBva2W0JarKP+AY1rSPotVpuya5r67K3hucsgzPbWsgSB0wDVdXeLi71Kj0WSuYwWlgmX09lSPakBwoTTSZcysP6T6hNvNE/2YZFR6UsmI/UDRl2Mz9CfJf6wa+Jjtopjcz/oMVxkq7+vhOUqFw824lA5/GZrT0FdJWie2g/zNN9STYXtDM6e8EY7w4UscnQLHjymcaKTgiEs5keBUJ/NEHyV6E0EcQjWlBEItJ7+xluHP8+OfA2WENaIlI+ayVCMWM6kRWV5wI+8JDBMJ/tCAxtpUJFAlFD9WA131HJXLqUItYEXF3iFokcI0AG52vZQkpWJMx3+ZrejcrhugEvy7ZGsWfyfpwonjPt9W3YyBEoe83BVt1buJrhGVsMKxpVPSI+ACXAAFHlG6l3yYq3FWjry1ZJi/O1d1B6HE33kDfH+duzSuAmWoHdodtEahlNSlpLHWLDBCYrUb4Fy4hg8sYCu8YK6BL3LvJDlUSltcVDeGJbanLMLUzyez28CBxVfANcen4znJm1fDpUnscZU16BYJn/xQspFgqZsT42GrxOVFpaY4sibbD0hKuXpFO1NoEhwPKT3OC0rStkpmWGcrXSY2RhBYf+mZy38VlK22p0Fa+oL+aibiWgNAVM6MZyNhxZ91aAyLXPu9viUt0Q9eYTr2zKhQFTjYIJ3n7niWptHqJOrxRa/ujD64g5KBE1CMSRQWRT8mFQoKMhb1sd3F/dAyjE1dmMrQEQNlHLllr6AqTn2P+7sCl4Xr2OayJSOP8Q2FvRnYp2JXy57cvY1PH6bUK76qcy/Rul3BlATRfBs85h4TgTd524BoXXWKNetQy9WBrMM5nLX2gV2TxRCjBbTlAT3D5VB1HTHAPCZdlNSvQr0DQ3MVTC2Vkkzx8RjjaElaqDqjh8C1qd5AsdUbnhXtyzQY2LLSDso3gH6pKOuvpxkbsSv8pLUpLGN7VlTGbpNzDmSEXVAM0TKYIbCwUtbiapU8DoYUWo4aSlisAm24+9yhsCzbqI8IXwpUSzZ+DfzHyUzuHzyplAlLl0yetYeXnwagA7dRi9LoC4ayhSusI/B86mRaguWf10EdKF62nAv0Q1dgWgbNIsgmElMlTMoYAWpnoP0XrbJXogUimkZznCDJIShHWhNaJg0SgJYALCrv0YIC63qHSs1anMA0dP5wbHfSZNhoy9OuCgtdlgAOWmR4SKlQvgX2tKMOaXOKuODEZQIssbYajVy36c9umOT7gqPgm5PaT4AFOlfAjpVcKvmR75gh6wFHyL0G5wzP5+ol7hmnlgECRVoWGigla6OR0JxQJKxxXimaGHs1dk6SyWSOLQycXJinNKKDwEQsmEUtAQ0IiW5KqmFHXGEBSJ+K/0QhbKwT2JXl2S0glJQulbfWu9/AULjRgNQJtcL44NL0xk0bOfjdpuBf56f1jQD4ub1zpnosaA/VgLaKlFJ98ATqUvdSGY+RB+GWXG/84+xbelIS1eKBfs/Fz73lKiq0OFmWYTOG4Eh8IwN5Ly218V5amYvCQbnAjMEIKay98SSB5tIcnOyI/qBrdaIrxYMOr2kSvU0Tpf5CMLx2WL1AZWE+zNP/iXSQJiw+wDhgZCMAT6JZPYIS0SJEBh7tkTmQTBd5ITI6kcUsRS8yD1ZYNf37VO9ZRuQsxWjToaPtLyOEGtWrRxaQ3bnIEqfJH/HQ1w9AVBAi1qiq+Zk5zspGHbUiQHGLNX5Y9EqpXmK2aCCmQECtn+Y+OFBOfTzFj0foJ9ARFiGEqdQN3lG0kXCAumIi/m1rzjgLdva85CkyUiHBUl6QG6X0IQNUCoi1tvLYzYSEDSvBvStGp1CHtN6w5I898FYpT3ViGlKKVOD5fDzqPGybw4mKLvnaZIxhlcddajgfPlHyL4J7sx9Y3hq9ynFczjZESep9GJDQWhVajpFRCplnU/wWL1wwahmbYThApwA2kGWLxQISZ01tPafVuDYOSfgXn8P3C2nyqA7wlCEbfmGBTRA8g1ymKXCpmbOFORYZCWGxncqRluZ4C6S5DuVtAu/Dtkin+SKmN2uLJYhihJWoL0BYSVj2Lg4dlZtRVg1RvhbRaLRZB8faMtMiAxWRNToeiy4bnNp5qVcnNGx9lJ7N6CmjAakq0Bqp/+jZPNW7K0h2wUZCu+ZYMU/WKEW5ZoUlmRRzbGajXTXFZpFpqq2l9ZHpw2xkSSoU+QpQi8u6YgnRvgCVL1InrYIhyUdYJmZPzYMtMWGS2l9Vk5VsTm25IZCacvKm07pD5oZxFGNDSI5epsWtHZGtTGqOc+ZhuTVpxICHRq/0wuPozNjAGkx0bHqm1P6g+zEnilof2xHJr63Qlsh6V0hqS4faEPuPE478Jktf/WnzgiNYBg4Mwk+n4TbYlc5rzGSFsYcvfNIYERslH0ntnCYlBhy6wdSgkEGKRSDuqPzT5Fbek+r9vCsPAS6FfRy/ahz5LRnASfw3TAyXt+avNyeGkrA1//AM5jpaZ12aZ7KGE8GRasyg8iaN4aadBQfkFTIbRt3puCRl6kxkVbrIactEHg1H3jwpOtBH5QKIjvqlqncYvMjYXYnJTMaAyfNFXE9J4cIAGQ6/vipa3hq58p2PU7126f2H+BjvPx6c5HXHwuzBYUbtpi9YHGpOlyyRMg1Af77AuJkDV5gJXQXEL8fzE1+mqGRIQaoDVnFYcU/N5rQPcqnBT/xHtiOBGd1wBwsQ1VnOVZKgAGJqEzWKjp3UbHx/iDXSyowVIIVWRrULoxJDJE8vFyZOzMlTRmbpZxgx+/GBukUajrDOx0WrnJj96gHBqXQTlqZ3SaPgyK+DvqIlXMGuK3zHw9l4LIwRDB8aRSXgdeCV8ES9wFFqemum6qEjnmcZc+n4Ck2twIVjWe3q2RbYMHWFKkaQZzrYx2eMOfDDH6y2bCtlCZKf/VhhKkMcqrxJr+bS7xfYs8CY7riLguT4SOCMsebxm16grZBTr6DDKy2MSTElga32uwjCJW41XSZEh4qHyifCb1lwEW/DiIh6n0nuVJ0hJRiuif4k5vH1IBibKyweEhqxg2ZypLjU3yex0DtHvIrHG3puaxNN8gwvRulHlRTPLv0qTwi9YBeQyxW9WsYfxKTeDEaLn7ABGo8v8u92fEMsr0C0hkXs2qff9Vhu5aM7/ekQOjTTAP7kJpUNOCk+i1EEkjNynbJq1YMa2ISDEiu1bcUJltHaszyFlAFiA4gzuAxCho1jbKW/3SuvGTUF7gZgbKHsyWT7kZLtQH+OxR7sNMPxOGlSXi/gq1uTXJEVTFD0OHxzC2WGdVZHeZYWk3FUFhuSBmEmLxXzK/stFOjTH6mkOl9mMdorU87waxoyVaiEeSTgng4Xk0/lZ1xa9tsYjp3ZZHSg/uI7I3kvBVU3qFi2WCvBOE8IimP/5gXuzf5gjX7D+KiTHY5hAZVNcH77P6d6b9EKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjM4NjYKZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAzIDAgUiAvUmVzb3VyY2VzIDYgMCBSIC9Db250ZW50cyA0IDAgUiAvTWVkaWFCb3ggWzAgMCA2MTIgNzkyXQo+PgplbmRvYmoKNiAwIG9iago8PCAvUHJvY1NldCBbIC9QREYgL1RleHQgXSAvQ29sb3JTcGFjZSA8PCAvQ3MxIDcgMCBSID4+IC9Gb250IDw8IC9GMS4wIDggMCBSCi9GMy4wIDEwIDAgUiAvRjIuMCA5IDAgUiA+PiA+PgplbmRvYmoKMTEgMCBvYmoKPDwgL0xlbmd0aCAxMiAwIFIgL04gMSAvQWx0ZXJuYXRlIC9EZXZpY2VHcmF5IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AYVST0gUURz+zTYShIhBhXiIdwoJlSmsrKDadnVZlW1bldKiGGffuqOzM9Ob2TXFkwRdojx1D6JjdOzQoZuXosCsS9cgqSAIPHXo+83s6iiEb3k73/v9/X7fe0RtnabvOylBVHNDlSulp25OTYuDHylFHdROWKYV+OlicYyx67mSv7vX1mfS2LLex7V2+/Y9tZVlYCHqLba3EPohkWYAH5mfKGWAs8Adlq/YPgE8WA6sGvAjogMPmrkw09GcdKWyLZFT5qIoKq9iO0mu+/m5xr6LtYmD/lyPZtaOvbPqqtFM1LT3RKG8D65EGc9fVPZsNRSnDeOcSEMaKfKu1d8rTMcRkSsQSgZSNWS5n2pOnXXgdRi7XbqT4/j2EKU+yWCoibXpspkdhX0AdirL7BDwBejxsmIP54F7Yf9bUcOTwCdhP2SHedatH/YXrlPge4Q9NeDOFK7F8dqKH14tAUP3VCNojHNNxNPXOXOkiO8x1BmY90Y5pgsxd5aqEzeAO2EfWapmCrFd+67qJe57AnfT4zvRmzkLXKAcSXKxFdkU0DwJWBR9i7BJDjw+zh5V4HeomMAcuYnczSj3HtURG2ejUoFWeo1Xxk/jufHF+GVsGM+Afqx213t8/+njFXXXtj48+Y163DmuvZ0bVWFWcWUL3f/HMoSP2Sc5psHToVlYa9h25A+azEywDCjEfwU+l/qSE1Xc1e7tuEUSzFA+LGwluktUbinU6j2DSqwcK9gAdnCSxCxaHLhTa7o5eHfYInpt+U1XsuuG/vr2evva8h5tyqgpKBPNs0RmlLFbo+TdeNv9ZpERnzg6vue9ilrJ/klFED+FOVoq8hRV9FZQ1sRvZw5+G7Z+XD+l5/VB/TwJPa2f0a/ooxG+DHRJz8JzUR+jSfCwaSHiEqCKgzPUTlRjjQPiKfHytFtkkf0PQBn9ZgplbmRzdHJlYW0KZW5kb2JqCjEyIDAgb2JqCjcwNAplbmRvYmoKNyAwIG9iagpbIC9JQ0NCYXNlZCAxMSAwIFIgXQplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFswIDAgNjEyIDc5Ml0gL0NvdW50IDEgL0tpZHMgWyAyIDAgUiBdID4+CmVuZG9iagoxMyAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgPj4KZW5kb2JqCjE0IDAgb2JqCjw8IC9MZW5ndGggMTUgMCBSIC9MZW5ndGgxIDM0MzIgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBrVZtaFvXGT7nXFmSpUiW5CsplmxZ17JuZEnWpyXZqT9kx7LlOHP8UTu6hiR2/J3Zq5e6IYFu9cI2Mv3o8qulsB8lHYVC6bRBg2r2I4x90LIfhnU/tmQshRXGGKM/kg3GbO05V7JZhymFTeLRed/3nPPe9zznfd8rQgkhp8guEUh2aWtxm7xInsHya6C8dHPHS0R8Cf02dM3q9tpWyDL6C+h3CWHvr23eXo2+bqlgKkuI7un6yuLyXzt9F+GwC+vT6zBof8X+AX0Tevv61s4t+6v0Q+j3oIc3X1ha1McMq9B/Cv301uKtbeYXRqB/DN37tcWtlX/95GMr9KfQ49svvLhD3qI3CDEFoHdv31jZ3iaGOegL0PUAxZd/ThEteRejl0zVLKr5f/ph2C2c4EGj2upOmDkyaWuC7sigjnpSr44GznEZfIyXSf1k4ceUvqqUaeU7ZTLc8gHWCFevdJYJDXu9uY3hEl2AwsIwBCVIQtg7UhL8I9MFn+Iteotjy0XviHd9cbmk8asjJlaKStRbIjOFDfw+X5BKWcV9LK4oyln40XA/2ILlRQUertc8YFRN0QMsqguPe0uCPFmYKpR2h92l7LDiliRvrvRwslB6OOyWFAWrtMeRIuJvbJyuxaxDzNog5vVVLzPwARdKsch9QmOyVHpYLLqLOIlq8UllSmoGnJSvEfy5Ms1OFvhU1ie5ucEn+STEoQzDd314fKaQQyQSj8TwxZQajwPF2lMIz6hSavo/UWr+MpQ2fClKLceRfo5SK2K2cEptJ1Pq+wJCjxnOnsDwbpXh3RMYbvwPhnn6MpJA2f0MxSEQHTESZEkU6RSNxf2SVfJbJSvdO9ylu4e36D09/Ux/iB3VfWlsXmAfoVabyFaZuKN7KFUTEULIbQt0QHxcJrrHg3Xk9/D9F4BdHnSjJHTYoiMdQA8wBijABnAb+B7wBvAO8AHwIWC6jMjMiIwisow1mfAwu2hmPgFiP0t1RZjv/CfptelEfPbrA08eDd660p25tJUS2X3PV+4sz70y08EeHKQDs3cXNopTEg5ACeKnf0P89aSVR645jly7X2OB4nk6PK/RKqUkaxK/5+kPD/MifZl+k3aLB2l6Hc2Vc8i5iKlcOMlLZdIELswgk3NhBg9kHzaMOvBhq/JhAx+2Iz5s4MMGPmzgwwY+bODDBj5s4MMGPmzgwwY+bODDBj5sVT4I4jviBNGpRMg+yYp4Ew6VnvNUSMz0tt1YO/yjSE3Li55UPkhzTfGx6OI1hK/Qy/OzwWynk/MhVT5jKfaI9JGZPdKK1sujb7VwbpActVttxSmMOI2RXwVkO2R7TQ7idHy+CyOfG3gMHv2Y7AGHNBkRfG1m3JqHOT2CGl1bhKV8Wg87usIzESHV1Q/Vw1ijKATOKanQpZFwMDcX6lDGoh1DM8GeqzlZpB3ja32R+Xz4zJCSiBRyoeDgpD/2fJ+fsd6ZpNMWHE11DZ5xGAyN/oF0ZCjY2NStZIcX+prt0Xyyeyhw2mQU28/GYgNygxgd5/fnqDyjnzIziZMR8voeKGhUT9z3udPvkQBv52AigNPVA8371TGxj7TWYpsDkIE0MALMAavATeC7wGvA28AD4JeA6TKK47cQPgXY5arnPOfNAd40SKNm+NRYbT3IwmQ/Pcp7nRkMOjhvmSSE52jKTCM0Za1yXHfMble/NpMW6+ankr2temf8QsqbTbRemQgMp3x6Jjk8Bqd4ijZH+tpio3EXLbhTE4lgT3uDK9zTO5AOGuhS/qI7mHC2tDbUCcwknY3lcvb2SNO5FrtIaZ25gY4Gu31mV2RAuSrnM212KeToSLYYNUzfYOa8NlWe0j+AVzdYGdhDHvGa4BnVfJxRjeCwEYdtBp8iZBEygdzCq7CNK4CRV72URpXXUiiTSGd8ZupDCvmlfoHz0knfY02ZS72h6X7ZlZ7tLdwyiqavTmUuxJz0jcNVoS0zFkxcSLoOUtcuRNpzy9mepbEAXZqfnZWHlHx6rs/rz84itAzCHEctC8S5p/5h4DcuWBAN7wdE7QdJa0ZkHx2ksQwfdQ/7DbOQGKns4adaLzGcguFEfDTxqt9He3wCoAvWkTchlKpKIzaYiAXwAjEgC0wCC8A2sAvUIz0sKC0Xd/UmcWG3q+pqH8KTqsJdueDKBVcuuHLBlQuuXHDlgisXXLlUVy1wZUFkfkToR6LJeIQFiVaNNwJrBMdtwYoEz0d+dt5r3IAesKtbKNFjyx6JggMu8V6ZtNZq2P5fIr89rc4XoTpcos6XyojOUL8cSnuMoiPY6w9mJJNokfujvYUGZprq9aTCHh1j7OCQ+kITz/maY9n2wwd0pH0w0XI63C8fvkeng7l481C6Z5DZ5YTnFZwdOZepTNK/I+dOkyB5p0zCCNRBnGq+OXAa3ov5yG+G4SBhyAZwwW1H+cdlXtsGjHK1X8vo1/JRv5bRr2X0axn9Wka/ltGvZfRrGf1aRr+W0a9l9GsZ/VpGvwa3/P3FM1lCOPwNKqm82WtSLO60Jj0o79q7rEqQz5ppk486Iq/pcWa7Pp2azrR4eqaSZ851yQYm/unKjebURDwxHm9yxsZLNDsyGzp/LX32Wj7gDPa03TuYKH/rdmJ+OBDIKYlOZbST56sK4XeDr11t6H1GrcKfYSE///526/HoqEwiox9Br1fj5RPYJ7xVCRG3ZvXwR5V5zSXVE585+hjpU5KgDlzDXZKmn5A06weWiATZgbkmcodkBAPJsCa1zprRCF4m96mG3mERdpfdF9aFf6pejWQTz20Dqv838KKF+D7mqtHbas/W4lVFJoZm83NzofzK5s2VnY2lxYmVl1Y6Zzd3bixe2Fhb3+HRVb2Qyg/4/50TPkbYBHIGl5pE9x4meXIRZTODHED1k9C/AesArfoKZW5kc3RyZWFtCmVuZG9iagoxNSAwIG9iagoyMTc2CmVuZG9iagoxNiAwIG9iago8PCAvVHlwZSAvRm9udERlc2NyaXB0b3IgL0FzY2VudCA5MzEgL0NhcEhlaWdodCA3MjMgL0Rlc2NlbnQgLTIxMyAvRmxhZ3MgMzIKL0ZvbnRCQm94IFstMzM3IC0yMTkgMTExMSA5MzFdIC9Gb250TmFtZSAvTkJVSFZWK0hlbHZldGljYU5ldWUtVWx0cmFMaWdodAovSXRhbGljQW5nbGUgMCAvU3RlbVYgMjAgL0xlYWRpbmcgMjcgL01heFdpZHRoIDExMjYgL1N0ZW1IIDIwIC9YSGVpZ2h0IDUyMAovRm9udEZpbGUyIDE0IDAgUiA+PgplbmRvYmoKMTcgMCBvYmoKWyAyNzggMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDY0OCAwIDQ4MSAwIDAgMCAwIDAgMCAwIDAgMCA1NzQgMCAwIDYxMSAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDQ4MSAwCjAgMCA1MDAgMCAwIDAgMCAwIDAgMTMwIDc3OCAwIDAgNTM3IF0KZW5kb2JqCjggMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvTkJVSFZWK0hlbHZldGljYU5ldWUtVWx0cmFMaWdodAovRm9udERlc2NyaXB0b3IgMTYgMCBSIC9XaWR0aHMgMTcgMCBSIC9GaXJzdENoYXIgMzIgL0xhc3RDaGFyIDExMiAvRW5jb2RpbmcKL01hY1JvbWFuRW5jb2RpbmcgPj4KZW5kb2JqCjE4IDAgb2JqCjw8IC9MZW5ndGggMTkgMCBSIC9MZW5ndGgxIDgzMzIgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBrVl7bFvXeT/nXJKSSPElihSpy6cokuJDEiWKD4kSKdqULEuyLT9iiY5fsiLHcu1EecxIgBZ1gS5DhS1pi+7VbkuWJluTIo2bwoUiDImXdU0bbKtXrMUaGEaLokPQDmgWtAuWxNR+3728spw4Qf4IiY/3nHPvPef7vvP7XoeMM8Za2UUmsfGl84ur/BviCEb+BfS9pQsPBlk7vox/EX3d6dW7zydtu/4Z/a8wJi7ffe7h08433k3h1ixjnYUzy4t3/XcqnGbM/3k8nzuDAcNPJDP6/4B+95nzDz40/VXDv6H/c/T/4ty9S4v3/fRTbzAWeAj9vecXH1oV49Ih9H+AfvCexfPLQzv3PIs+nmGp1XsfeFC3R/enuAWe2D2r9y+vrjLjYfRpvWYQx5c+rczA1nENsvnGiDJ8y49AT7pl5MM6OtzQY8YmZQ3GWpQHjcyEdRiDfPhYQFZmU9rv/7GzNuaAHp3MxTqYm3lYJx6RmZf5mJ8FwGWIdbEw62YR0jcYT82ss5a5hW9z/mhtnW/+4Tqr+l7EutKJ473rjKeCwYmV6iV+Eh2RwkAihJaUCk5ekiKTBxbCteBacG33XWvByeCZxbsu6SLKFTeW12r9wUvs4MIKfg8thC6N1+St5nKtNoJ5dDQPXsHjazXMcLYxA67KUP8NPKRPzQQvSdG5hf0Lly5W5Uvj1ZocCgUnLl2ZW7h0pSqHajU8ZdjiFBx/ZsXd4LkJPBsSuN+sznIQc2CK2toazYmeiIYuXVlbk9cgiTISDq1z1hiApPSMFJlY5+NzC3RrPBySaSAcCofAR62KuVtSMwcXJsBJiDgxfrRKTVuM4tlWsGdSVGr+hFRq+TgqtX4sldq2OL1FpXbwbCOVtt1epeGPUOiWhsdvo+GLqoYv3kbDjm0aJswLNggTfAWGJcFWTLBAfT/g1J8eiITsoYg9ZOcb9Yv8Yv0h/sVm/mZzHW/Qh7Njmw+xy+wsrCiwoQxISaDaBoBcBfVjphbMxDBTPuzMuCyiyVmSspcPJbi+ta3VFXKZzp41+WSXLmnwRpIuZYpF/NKcEpM3FCegzsk2FKunjmRLDxR5Nrx46NBZPMzE5jv4+Yx4DXwZYZ94QuGfWCC2DIzeYnhLFhLP5EMdGf7cY2vP1X8xdZhPzO+uv8Hd/J76l/kLN3LXr2MafDiLbr4lnhA/Y3F2fgOmblImCdoqMuYLwiMEWRSUA02CDoNOgy6AHgH9GejvQN8FfR9kPlbRs5+g8SuQOAZpZHgd4ku2bWDGiNI2gEee6ZPCXRbhbPeLzGBJ5MMW9PtEdqiEvl+IA9Wm7L7FzKHPHkok8FO+ezbdVNV3j8wN7jpdCQQqp3fFdhXj/K3C4aJ/7O5HpqcfOT3WM312R/pgqTtXu2+kuFrLdaQqtO9T+PkjCNwMH/eZddYBdRkhPLFlxC52gPTXANBrYP518PtrkDgGFbSg4QHFQcOg3aAaaAX0MOgLoL8EPQN6EfRDkJmkboFmafoWSM2wmLYzDnumxLND0ZhkJyGd7RYRnnr7608//fXvfGnPvVNdXVP37hGv3cjpnn/hhed1N1bF4dDU/XNz90+FaK9IjhHIYWIZWkKVoAXc665iTZ2yJq0HT6wgYQMS65V2MzTusIeyALpCU/yt+gH+aP1+/gwtN8I7R7gY0dYwY40WBi01NdZowhriKhDHFaQ1bc0PzClt2lHIps1e5Yfrz/LP0dT8kDozzb0H030Jc0usYzvMlXlV+6E59lTpPTyGjyqzFx092Z6+wY/ehneIQVVmKGBLvin+H/VVRSaBtIADtUy8i/ctbH77mhtQYrPCuglbREHSZG8bbnBCfkG1aHjaxioMt0mfnKktc6Olyp1x4AvewyY+WRW/H/+dqN71v28rcqzc+HNB9NqNR8X9qky7wNPD4MnEZm7liUI4bR3puxlkvAoi/8LBEXHFQE23cGS8lQ8OHuxhvqsq+BOzVVE/qfBw9MZTuD4ljtL6qj3UsH4z4v0X1pkHE/IGaMireUBtsAe9ag962INeswc97EEPe9DDHvSwBz3sQQ970MMe9LAHPexBD3vQwx70sAc97EH1lSbCjxFL3WobrQ0sKXocdDnbDWEORZJLyA71ifAf/3rXwsKu+o+r/5feW/D7C3vT/BzvnpqenuLHga5BOTubTs9mZdrrEHzZAfiyCvtbMgMywQ0kLl3KEmHsc4ESGWzkOiv0K7ZegGwFTbYCZCtAtgJkK0C2AmQrQLYCZCtAtgJkK0C2AmQrQLaCIpv52gbrbWzCOuvFBrmhOzN0uPMarHKs4ZfHsHwPMira3h6gNR82KI5PR1L28z5Jc3wdGRK74RkD3C8pTgKe8UxVis+eK5ePjIUdel9mZ/Rbrpjf7h+ohKMT2ZCoJqdOZmdO5tvlVDHwuGcoKUeHd3gHDpe7f7Pj+KivI9LX29OaKiV9xqTe1hnx9ORCVmd8LJ4/WPAmS5OdiZEed3PM4PCn/LF82OZITSsqrECn54AVD5mbB0MkgAfCtMJqqN2q2iIaeMDRkNah2GPDtWcBSXJ05N3tlcDOlemZlZ2Bqje3d3Bgbw7GXc/nl6aTyemlPP9hfbI0n/d48vMljj3kSsw7gvWbsLhqB2QDEtYyNJSeHkC042EpLBl48z7eMvVf4g0F9a/d+Jz4LOE9uPkWrwsHy2JT/34D8HAonFcgRaqB+5Qa8SqIeBVEvAoiXgW+o4KIV0HEqyDiVRDxKoh4FUS8CiJeBRGvokW8CiJeBUAi3DlYRcEYMcqBBfLQ/qsg9KmdQzuF6wzhYxQZN6lxFMwMwJ9Re4C0h0ChhYgmC0DQCJMZpZHLZw3hrqy9ARW9hhECUb7E87mymB31DkScpnZ/e2ZpX1ruL3dH88mwXehtPrfZbmoxRbpy1a7e6XyQ7/EN7Oh2JYKO3sk7esxdBn66PNzijgednVaDMJiDY7nYcMRu6Yx52kNusxBZXZS3DVW6ze2JHQ8fiI4mXBY54o7GXaYmYTRBA9D5KHDjxr65oeLn1lkfNszdQI8bsgvoQJCtoK1DW4d2H9qt0BeNuTDmwlgr2h7VD3lgqx7NVj1oemCrHtiqB9vqga16YKse2KoHtuqBrXpgqx7Yqge26lFslWYOkx8iMPuBKdK2H5q3wzapbVdwm8lm/FB+wwPBFJvCdq4huJGfjI4I11K5OD/i9Y7MF72FdMQo+HFHfLx3cCLpcCQnBnvH4w7C4ancSHJmCRCfSVl8CS/vqRd69pVisdK+nsaVXFUXMPobYDRMeZi3gUqvikovUOkFKr1ApReo9AKVXqDSC1R6gUovUOkFKr1ApReo9Gqo9AKVXqgMOOtABCQJOyCtDhUdtSlqIg/jmrfJDOZuTcNc/Btl0wMHi3eWgsHSncWFVXNZ6uwZ8vVWezs68FOe5KdqC6nppUIBBrxyPJiLuaKlffH4vlJ0h4oDyi8FcNDJ+tjL66wfiueABy1PsUaAtP3vR9tyFYR9p3E32m48j01nXLEoGu3EaCeesKAtX1PyVBn6kaEfGfqRoR8Z+pGhHxn6kaEfGfqRoR8Z+pGhH1nTjwz9yNCPul6EkEEZTqLhIBLQVQsSWWK2BboKUWx9X9qacfIGIjQbFKIsjJF03rcFjuHBmFHU//qD4Kj/pzfhs6RUdCRtvoTnFBfvB4dQsPEmsGGEjCcoc3EpLFHmQiU+sUd2YgJxaIfaflzJ3zC0A2gH+oGBLghLD3cpiFfrBTvaHFOqGwI8hEoS+R19KHczDKnAAE76BH++/oLOkxiNwew76t/hfyLc+YXSWK0gy4Xa2KlPtZeteyd6xxMOHg3vzAQCmR213Mr+wf49pzKwgOTJhdGp6MhuwgaHBwcGgA1Zzc3aFSYkcNwOot2ndiftCqUo1kZyZFU4VsVWijA8ZMLDJohLfSfaJHbHVUiTDatx1dWRVXHu4yjRkGBw6bQweztNLrPVbYkOeI0LC2X+o2yvs1u2SSInhKunEOrP1gf4j8Ar7UGG0x4kWIn90zorfwSOy1h8O45VX6aa4E0ck3yE4bSK4TQ2NY39TQPDaWA4DQyngeE0MJwGhtPAcBoYTgPDaWA4rWE4DQyntzA8QpUA2QLtJ9VcLYh61KZKJNnAdRJYjtjDzluwnMtnKPnCFsfCfkCgJGIUsLeBm79ZFi2hRMZXmC8GOocXSsN3uMTehc7BuE9flmLF6Vh5Puf5VWo80e5IjPf2lnvanIlSgr9ec0Z9tviuE9n84lR8JD15/C6TO+aLF6NtXeNHp8PD07GePaORaGk2GpseDqvYKAIbVKR2sv0byoEUCdEJIVBhKQLZoLtOEEUSuqreQvHtZMXkRjZQ76kJtRMveoA4yt3VjF1FuRNIUGKoAS6+WOYdYCqa8beW21K7c/mjbfBcSDJ7o5V+2Z0YDtVf4rN90xnvcD8PABNjYPXT4JHOE2LbM3kVgOTXCMEGQrCavWNtZybbhFXHyuWyeG15+fs33hM61Pa/3NzRmMvJdn74XO1a9GqGPZBKqEzQ0G9FuxWLtuIkQl0HG2qIxpyDLiWa0aLtkaa2ZpPTFEp6WtT1XwomOedDoiM25BMZssubcn1UnTYG/m/WaaMwSD3so4f9+63cm69VJPYyNo0fQ+MxrfFbtaFX9hMHBxTYJTanjFIpjg2lF3+LrKHxYqPxsjpCL7rhm93ai3SbIgKdYpiZTYkXpP0oFBIFFGLYLEkZlTGauKb4ekKJ6l3CDaSEcZN0Sl6E2j54EapKNTvQmi4FOuEuQxP5FcAnO1puixR7/AmPqWwO5uLVXPmbmSMdloOZ8n6PJHQ33uPB+ETG1x7u76w/ybu7dw4Fdo7Xn+bHLw9m4GDT82CQMxX3DkAeKOgknj8u7j+I+Q9Deva2SCcOb4P0GnhQ/N9bwoj9dUCRr6KEgdrioDA26pOrE3ugcA8U78HMVtUvWuEXrfBnVvhFK/yiFX7RCr9ohV+0wi9a4Ret8ItW+EUr/KJV84tW+EUrwAF/aESuR2o0wgvQ2Ty12+EDuXYE03B0+W3nUVSWcZeW6GhXLRNqXPl1LdvRrlktGUI1Q0kR/n6gXHgHcmEHsJpi31RzYfJyxAZBjDwYXbU8iPJgC/RKYzdjB2tUrhQzPqmMWLEBqtrU7NcB/fgbqacf+iHcZ9RYoNTiCsw/kAgr2U7Bq2U75SWX4EtarmNPTA4pibDuRokHvQmvRcuFi7lT9bqW66TmRruREENXUehKQFeUL15W80X8e6PoioK65vGpdqC2prPtuePNaKBG2E8uS6SZlSyR6oebmeH2jDE9oH9/ZEVJhnxDcyCNOkLgJM8YGxze0psvTyVE/UlNc1oJ8ZJ45VRn3G/TskQLlFj/Ob+iqW5bDQEfzIvCgkwf7NGfR4QwCTybr4LUcyTiW42JVIoy3KBz64aH68hGVU/mzUwmJ5fdQnFbjvjEoCzKUrX8MOaEjwqgVnkFe1RkzxBgAso6VEYhwCptjrYJ437F39IRmnLorfRc6smLC9Wci3w3nbK6EJxdqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcMPJ1FoONUM47iGsM1zGqp+XGcY963pxX2Hn/efPNU5Uocp2tSm/7KQy/ryz8mZ2xrolC2BUbCux3xoMOOTHQUb5DV26+787u6WK0M56VD9miQaerO+mU0xEXP490p93WVYiFegPO5ja9xRnoQGVsrIyfOGyLFBNdg11OnUNnbvc5PV3OFrM3qeizafNd3iIeh1gPfLA6MmCLaA+bcKX6xwVpaT8p1XVoFYutccZsg+J1OHSjjdfhAdpfOuJWAYC4iraWmurRbqfolkUmiJzYgCQhl8G5Qh/P2jPZJ8pHjvDBssVrkeUu+4rQfe1r2frjOwZEVhLhAD+aVbFQBBauI4NxU55280zog3Lc9GTbq7mtrI2iF50gNTdyVDqxpnpLMZdojFp0AkJZKr9ebouOxGfGRLk9OTEwcsIDnNb/JzYzEp6a5HP1b/dNDcr5oWOKbvEfDv9X8PdR50cyzzjo/Ei8uvMfK0+IJwn1mLHI8Wcy4V2hi0+88/YJ6+jvuV2i/3vZ9x5bDWhXZG8ZZD8/Q78FPkz94D3p1c0k8+lO1Z/ZrOkmlJkaN5VLlP+ODXKYBugYaFFc2HxHXGFR8RybEvtBHpz5X2d76CrhPAr3dokLGL/AQnimIvbj+SYWFCU2imsXrlG6cokZRAp9D2z0ReRzL27+kq6YY5TGlHv0Dp7nRTbKf8ECvIc10T3UOySBF99JdpKtsff4Sf5lfoW/zt8RVfF58ab0Vel16T3dd/V79RuGo4YfNPmbftrc07y3+SvN32o50PI3xlHjj02rpqdaZ1ufbX3H7MVspMMo+zRmDoJUDSESo3kZ91QNtzX0Y6C0Z+/c3L4KjjSXz11YfnBlaXHv8h8s986u3H3mwcbbbPOv6P+823yiGJMQ+u34xzqKbKUHjiXF+lEkDbAMy+HYdphV2QSk2wXt7mbTbIbN4r+Jfcg+97MD7CA7xO5AljHPFhiSHxgQjIkl/x9NC1daCmVuZHN0cmVhbQplbmRvYmoKMTkgMCBvYmoKNDkxMAplbmRvYmoKMjAgMCBvYmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgOTY3IC9DYXBIZWlnaHQgNzIyIC9EZXNjZW50IC0yMTMgL0ZsYWdzIDMyCi9Gb250QkJveCBbLTM0MyAtMjE0IDEwOTMgOTY3XSAvRm9udE5hbWUgL05QUE9BRCtIZWx2ZXRpY2FOZXVlLUxpZ2h0IC9JdGFsaWNBbmdsZQowIC9TdGVtViA2OCAvTGVhZGluZyAyOSAvTWF4V2lkdGggMTEyMiAvU3RlbUggNTggL1hIZWlnaHQgNTI0IC9Gb250RmlsZTIgMTggMCBSCj4+CmVuZG9iagoyMSAwIG9iagpbIDI3OCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwCjYzMCAwIDcwNCA2ODUgNTkzIDUzNyAwIDAgMjIyIDAgMCA1MzcgODMzIDcwNCAwIDYzMCAwIDAgNjMwIDAgNjg1IDU5MyAwIDAKMCAwIDAgMCAwIDAgMCAwIDUxOSA1NzQgNTE5IDU3NCA1MTkgMjU5IDU1NiA1MzcgMTg1IDE4NSAwIDE4NSA4MzMgNTM3IDU1Ngo1NzQgNTc0IDMxNSA0ODEgMjk2IDUzNyA0NjMgXQplbmRvYmoKMTAgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvTlBQT0FEK0hlbHZldGljYU5ldWUtTGlnaHQgL0ZvbnREZXNjcmlwdG9yCjIwIDAgUiAvV2lkdGhzIDIxIDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAxMTggL0VuY29kaW5nIC9NYWNSb21hbkVuY29kaW5nCj4+CmVuZG9iagoyMiAwIG9iago8PCAvTGVuZ3RoIDIzIDAgUiAvTGVuZ3RoMSA1MDU2IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AbVYa2xb1R0/517b1zfX1/EjfsWP+MaPWyd2Hr6NnYRgO5HTpkmA0KatzUhp1uZVWpptoTwmRAVj0jJpRQixFdCExDTgw1imqVvI9qGaNrR1ExQhBtr6YZs2aUNoQojXBLX3O/fagW6F8WHY+t97zrnnnvP//37/x7EJJYTYyGnCk9KRE/Orvc6BKYz8jhDqOnJqLUra8CX0TxgzLa4uneh27P4V+n8lhDu3dPyuxfmB92J49Dgh8sbywvzRNyKxPkJc05ifW8aAMGd5Df2voR9fPrF2Z+xucjf6T6M/ffzkkfngWuRh9N9Gf8eJ+TtXuR5+PyHuEPrR2+ZPLLzm+3UE/RH0s6snv7JGf8+9gf4q+hOrX15YXSUtB9DfRN8Kofiyjw1Ni9761IsxuTmFazauuPPEtN03o3XFsgIGrCJpkbClbCethDiIc3v659xwfZb1wR/ASU9tEnGm8iNKv1XdpPUHNkk5/BwRCX/LocwmoelodHylvEEPo8OlMdCloMWno7s2+MSuvZVYNboeXd9zdD26K7o8f3TDlNDveLCwXu2NbpB9lRVcZyvKRqka3G4uVKvDWMfE1sErmL5exQrHGivgrg/1XsYkc3oqusEnZyo3VjZOl4MbpXI1qCjR8Y3zM5WN8+WgUq1ilmVbU2h8z4q/obMAnS1deG41VtmHNbBEdX2drYkel1Q2zq+vB9dhiT4SUzYpaQzAUjaHT4xv0tJMhT0qxZQgG4gpMQV6VMtYW0xP7auMQxOFadLy6ZBK24pirg3qSTqk8v8JUvtngbT1M0Hq2Nb0Ckid0NnBIHVdHdLYpwC6jXDpKgifNhA+fRWE3R9DmPk2R7KI418gLnkiEInAS3rhTr19/QnFqSScipNu1U7T07U76YNW+qa1hjfYhxIfrveTY3ivlWzhihW6QbOjr/8amo/5Zv37j2GMIwho7hHuAvKFl3xpC5s49YmCY9RM/oDO6xBubjSIUHGSACQFGYLsgVQhK5C7IN+AnIU8A3kO8huIPLdJ/JewvwyN2P6yYwu72vU2gS5uXskWuIGdPVyMurWsp83OqU88RlsOP3QkGywtX1e7eN+Tryb33lvlLlzO7brjsdnRlanU5VXuwKuT37y1xHId038J+oukA+jQXra+0Fh/C6mK19sWfS/NreQVyHfPlvfQL0i1p/L0ARtbmc4OU254G497dDyC5PYtgGIs5jXwEICH0MRDAB4C8BCAhwA8BOAhAA8BeAjAQwAeAvAQgIcAPAQdj/Al6GmHnldi4tjGJEi1bIRjUMQkqgGVBkDfKb6kDCQ9wb5S4vVHy2Mf5m4aTYS18RQ9TuNypD+uXtvlpYdgTLbjmoP51FjGz/xgHPjcC3sEEsS+vI6PwQVxAC+I+SJ4EDQeW+VvtL1zpnzmHYAyDJQfZJAQrv5+/S36W85NSmSWvLdJ9sMFD0DylxDUl3Q/kYCL1MRFAi4ScJGAiwRcJOAiARcJuEjARQIuEnCRgIsEXCQdl/1QxXsRAhU7gHve6RrC+hiNYzSOUZXkibQ9msFoBlp4MWPyEhzUQibx2iRJQnKQXZADkEXIKcjXIY9Avg/5CeR5iDwH9V9B428Qbg6eOg6cmKeOw1NHmP+gPcK8RyvwBi8WwZIU7LynLcJp2VzeZ6cer5YtUjuNdSYHdha4fIHXPbrTzpkFNtoDD9eH84WiOZzORVxqh6ejI7JPi5Wy4UD3SDz3xSBHKTcQDIiCJEhek1UWTVKLEM8V21OTwyrNtrUemvZ2Rd1dhd1hmxINW+mxaCZoszjCPq3LaqVWiyc+mErmOh39GU6wC3lzP6WC3eZPDnU7M7097li6vaUtVbrv4PjeFl8skMr4BI5yFknUOSZ2cPwPcCyRLvKvTdINZNMQBzgWDY5FcCw2ORbBsQiORXAsgmMRHIvgWATHIjgWwbEIjkVwLIJjUeeYgDOCVbvBWTva7WinDO5S4C4F7lLgLgXuUuAuBe5S4C4F7lLgLgXuUuAuBe5STe5S4C4FtVBksKKN6YzVZbRl+EwUxxERPgNm4ySssxkHs54Gsx60KXIfY5mCZaowlr2eNotZKdAmi542EJzLx5pc0mdqP7R2aqPq2BStPUUf5rl2baJ3bHkicevS3Fp70VUpJocSLpqMj2kd14+1uEu+tDczORAevPn2wuLazZWh3SA95mXxiSMMPYT49JFuxKcHKssN3ViuZMczQ7dN4oRJLGbdiFek8HwBecLry/fAwSytNKZHMA3ZFlvFZLrF3SI5os5Sweao2m5aLC7SFwcmkjETt9PMjQ1NDdT66YuMd1p/F5e/YP8O8lUGi6xv5zGynQzG5SbjMhiXGexgXAbjMhiXwbgMxmUwLoNxGYzLYFwG47LOuMKyHaOcQpywrh2nVGZRO6yLMPtADqsDmvuj+EInZ2BvEWLuM2cLQy07cqVOjxpxmfiJ4m6rr2uoc/hwkCvqyVvsvyEfafHG2uWgrfZjOrXDkxhQHMUeGkfugn3kBdj38fpJUD+R8fICNjrjLXqP3VY4yV1YWHj+8oecycCk8Q6ruExz/Q02+2zhUbYnFjTm8WbETC/5YJP0YVo/pA8USaBKQtvwQoxjLIpI8huR5Aeu/iaufuDqB65+4OoHrn7g6geufuDqB65+4OoHrn7g6geufh3XZvREsXIYu4Wxm4S2akSTimhSEU0qoklFNKmIJhXRpCKaVESTimhSEU0qoklFNKnNaFIRTSpUa9htx7JBsNbVYK0LW1ghHmzJ2jFWOxrcIWoAKJKfHkAMWxZBSXinENOdVFDzR28rDLYksoXOnpRloqhJkcy1Ka3Xsqc4wZvKU8NzEc48lhs+HOLaONPlD6klc8NwZy7pb69t/DN7cDSZTQaCtWfpjCNsH5ku9OXzhQx308f92A0/PvG5+fF/+/BH1rOKbWFGf+S5zNqreu58mHPp9n2S5x5iNnH1l+tjnBP+5Sc72FnETkJ66NiN6AzBi0JNLwrBi0LwohC8KAQvCsGLQvCiELwoBC8KwYtC8KIQvCgELwrpXtTFopOdmdx4nUWlG1GpIFmztsKqHgzSImC0cQZhXOZ9LEHidGJUu2PfLhQ5cyQ9GBldnlT9/Xuy5YMK1/a93eVQfl9ufCoyNAtbCzTRkQnJI7fcMdJ7fb5jSJtLVsZ6F2ZzM+N9S/vzBoc11KBzsHeEPMmOceyYsoWCpOnqMO9m6c9jxJAG67Wm9RrU12C9Bus1WK/Beg3Wa7Beg/UarNdgvQbrNVivwXp2ytAa54kOuDmLT7Z+10UI66NdYGfXwUY+HgQ2CeQvhk0C2ORjFnYCMJBRe1DzC+hGOEHL4TiL4o8TgsUAqocrFLhobncyMTmSUPqvCXqRygKJjKe9R3FxRRrsL6c6yoNxv5rNZtVAINnjCQ6kAk/3j6fbHImRdLyv0yeJLm/IFex0W+VQVyRT3OFydA4koxnF1+YOdLYH4j7JFsGvBcDWVn8Lpd0EA1dYOfHoKssO/YwkIzPIyAwyMoOMzCAjM8jIDDIyg4zMICMzyMgMMjKDjMzA0rh+RpKRGVgxaGQGlsutDTSsQENxx3g7b5x1cnl0YLpxQNIE+tDJ4pC0Y6AY+48UbgRC7T0jgccDSOD0uto5PYG3FnoOIWuz+viSXh+DsKeI3T0gJ4zd/3edRAIGiX4Qys65IeSqT6qb+UY1+MT6+UdWJk4WT16ljn7QLBw69gx/suvZnwVuaR15hzr5vzPX/uWZ1Y7mnUU1qsYF/PbCaYqN4oN3+J/Wu0nIdLi2VN9rmsJ7rxiPGlc3fZtkKTsyeImP+wExcwHIKUiajHNC/X1OIHYKvLgAat5zhvCj9XdZnyvUX6Z/rtfwThv9OcMUCSBE+siDZJNG6Ri3k3uT7+Of4Lf4F0wPm2rmU5Z2y2nLa0wv5Ia7wANqaUNb/BuG5jk8Y0/ZCYbd2d9CUUJm9o9OV0a7JxaOn1pYWzkyf/3C7QuZ6ZWl5bU9a/PHV45gHmyu49+u+uPst+1VPm6M8fjxqOoBnSdlMoGQniLT5AYyQ24k++CxFXIef0AgEEn3vwHogcgHCmVuZHN0cmVhbQplbmRvYmoKMjMgMCBvYmoKMzA0OQplbmRvYmoKMjQgMCBvYmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgOTUxIC9DYXBIZWlnaHQgNzIyIC9EZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}],"status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:14 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999227' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '844' + X-Envoy-Upstream-Service-Time: + - '850' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef09818481a3ba5d3be71c4b72ff09386ac03df5045b", + "object": "response", + "created_at": 1756098313, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef09ce2081a3b727826a4605036109386ac03df5045b", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The document appears to be a sample PDF containing placeholder text, primarily consisting of \"Lorem ipsum\" and other generic Latin-based filler content. It highlights random paragraphs on various topics, demonstrating text appearance and formatting within a PDF file. The content does not convey any specific message or information beyond serving as a template or example." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 753, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 64, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 817 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:14 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Summarize + this document"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}],"status":"completed"},{"type":"message","role":"assistant","content":"The + document appears to be a sample PDF containing placeholder text, primarily + consisting of \"Lorem ipsum\" and other generic Latin-based filler content. + It highlights random paragraphs on various topics, demonstrating text appearance + and formatting within a PDF file. The content does not convey any specific + message or information beyond serving as a template or example.","status":"completed"},{"type":"message","role":"user","content":"go + on","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:15 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999155' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '797' + X-Envoy-Upstream-Service-Time: + - '800' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef0aa9a4819c9d9013e27bde98cb03c551e7af8cbda1", + "object": "response", + "created_at": 1756098314, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef0aecd0819c8e705869aa0d7ae503c551e7af8cbda1", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The PDF serves as a simple example or template of document formatting and layout, illustrating how text appears across multiple paragraphs and sections. It emphasizes the structure and visual presentation rather than conveying meaningful content or specific information. Overall, it functions as a demonstration of text organization within a PDF document, using typical placeholder text to fill the pages." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 826, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 66, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 892 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:15 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_real_error_scenarios_openai_gpt-4_1-nano_handles_context_length_exceeded_errors.yml b/spec/fixtures/vcr_cassettes/chat_real_error_scenarios_openai_gpt-4_1-nano_handles_context_length_exceeded_errors.yml index 8d04c12be..f015c2595 100644 --- a/spec/fixtures/vcr_cassettes/chat_real_error_scenarios_openai_gpt-4_1-nano_handles_context_length_exceeded_errors.yml +++ b/spec/fixtures/vcr_cassettes/chat_real_error_scenarios_openai_gpt-4_1-nano_handles_context_length_exceeded_errors.yml @@ -73,4 +73,73 @@ http_interactions: } } recorded_at: Wed, 20 Aug 2025 17:07:46 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"","status":"completed"},{"type":"message","role":"assistant","content":"","status":"completed"},{"type":"message","role":"user","content":"","status":"completed"},{"type":"message","role":"assistant","content":"","status":"completed"},{"type":"message","role":"user","content":"","status":"completed"},{"type":"message","role":"assistant","content":"","status":"completed"},{"type":"message","role":"user","content":"","status":"completed"},{"type":"message","role":"assistant","content":"","status":"completed"},{"type":"message","role":"user","content":"","status":"completed"},{"type":"message","role":"assistant","content":"","status":"completed"},{"type":"message","role":"user","content":"Hi","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 500 + message: Internal Server Error + headers: + Date: + - Mon, 25 Aug 2025 05:05:28 GMT + Content-Type: + - application/json + Content-Length: + - '353' + Connection: + - keep-alive + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '2587' + X-Envoy-Upstream-Service-Time: + - '2561' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |- + { + "error": { + "message": "An error occurred while processing your request. You can retry your request, or contact us through our help center at help.openai.com if the error persists. Please include the request ID req_c36106f48453f640180ea6ebcbb538e5 in your message.", + "type": "server_error", + "param": null, + "code": "server_error" + } + } + recorded_at: Mon, 25 Aug 2025 05:05:28 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_streaming_responses_openai_gpt-4_1-nano_reports_consistent_token_counts_compared_to_non-streaming.yml b/spec/fixtures/vcr_cassettes/chat_streaming_responses_openai_gpt-4_1-nano_reports_consistent_token_counts_compared_to_non-streaming.yml index 69052a189..84a57844b 100644 --- a/spec/fixtures/vcr_cassettes/chat_streaming_responses_openai_gpt-4_1-nano_reports_consistent_token_counts_compared_to_non-streaming.yml +++ b/spec/fixtures/vcr_cassettes/chat_streaming_responses_openai_gpt-4_1-nano_reports_consistent_token_counts_compared_to_non-streaming.yml @@ -9,7 +9,7 @@ http_interactions: from 1 to 3","status":"completed"}],"stream":true,"temperature":0.0}' headers: User-Agent: - - Faraday v2.12.2 + - Faraday v2.13.4 Authorization: - Bearer Content-Type: @@ -24,43 +24,25 @@ http_interactions: message: OK headers: Date: - - Wed, 20 Aug 2025 17:12:28 GMT + - Mon, 25 Aug 2025 05:06:53 GMT Content-Type: - text/event-stream; charset=utf-8 Transfer-Encoding: - chunked Connection: - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID + Openai-Version: + - '2020-10-01' Openai-Organization: - "" - Openai-Processing-Ms: - - '168' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '188' - X-Ratelimit-Limit-Requests: - - '500' - X-Ratelimit-Limit-Tokens: - - '200000' - X-Ratelimit-Remaining-Requests: - - '499' - X-Ratelimit-Remaining-Tokens: - - '199993' - X-Ratelimit-Reset-Requests: - - 120ms - X-Ratelimit-Reset-Tokens: - - 2ms + - "" X-Request-Id: - "" Openai-Processing-Ms: - - '35' + - '49' X-Envoy-Upstream-Service-Time: - - '39' + - '54' Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload Cf-Cache-Status: @@ -79,30 +61,52 @@ http_interactions: body: encoding: UTF-8 string: |+ - data: {"id":"chatcmpl-C6geJLtl2WtUkIOZzKf8ogWRbbjAh","object":"chat.completion.chunk","created":1755709947,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_c4c155951e","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"U95CAOKx"} + event: response.created + data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_68abef6d7b9c8192a96c9972b3a7a7af0227cb3dda34901c","object":"response","created_at":1756098413,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} - data: {"id":"chatcmpl-C6geJLtl2WtUkIOZzKf8ogWRbbjAh","object":"chat.completion.chunk","created":1755709947,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_c4c155951e","choices":[{"index":0,"delta":{"content":"1"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"93KfU0D1k"} + event: response.in_progress + data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_68abef6d7b9c8192a96c9972b3a7a7af0227cb3dda34901c","object":"response","created_at":1756098413,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":0.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} - data: {"id":"chatcmpl-C6geJLtl2WtUkIOZzKf8ogWRbbjAh","object":"chat.completion.chunk","created":1755709947,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_c4c155951e","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Dw1VLVN52"} + event: response.output_item.added + data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","type":"message","status":"in_progress","content":[],"role":"assistant"}} - data: {"id":"chatcmpl-C6geJLtl2WtUkIOZzKf8ogWRbbjAh","object":"chat.completion.chunk","created":1755709947,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_c4c155951e","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"k7pBBE8QD"} + event: response.content_part.added + data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} - data: {"id":"chatcmpl-C6geJLtl2WtUkIOZzKf8ogWRbbjAh","object":"chat.completion.chunk","created":1755709947,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_c4c155951e","choices":[{"index":0,"delta":{"content":"2"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ndWXjOTbr"} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","output_index":0,"content_index":0,"delta":"1","logprobs":[],"obfuscation":"l5QF6yE0sL6GxSK"} - data: {"id":"chatcmpl-C6geJLtl2WtUkIOZzKf8ogWRbbjAh","object":"chat.completion.chunk","created":1755709947,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_c4c155951e","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"X56QmlKgq"} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"401txdgViOVl59j"} - data: {"id":"chatcmpl-C6geJLtl2WtUkIOZzKf8ogWRbbjAh","object":"chat.completion.chunk","created":1755709947,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_c4c155951e","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"uUOfhBQZw"} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"WRSJjb6qFvglJAd"} - data: {"id":"chatcmpl-C6geJLtl2WtUkIOZzKf8ogWRbbjAh","object":"chat.completion.chunk","created":1755709947,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_c4c155951e","choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"8DxNC84cP"} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","output_index":0,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"WZKHZerzKLzafyk"} - data: {"id":"chatcmpl-C6geJLtl2WtUkIOZzKf8ogWRbbjAh","object":"chat.completion.chunk","created":1755709947,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_c4c155951e","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"cUOp"} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"RMBQ2onfRo7dxUg"} - data: {"id":"chatcmpl-C6geJLtl2WtUkIOZzKf8ogWRbbjAh","object":"chat.completion.chunk","created":1755709947,"model":"gpt-4.1-nano-2025-04-14","service_tier":"default","system_fingerprint":"fp_c4c155951e","choices":[],"usage":{"prompt_tokens":14,"completion_tokens":7,"total_tokens":21,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"lrLazH5zyO"} + event: response.output_text.delta + data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"Z7QSFN7FMJedP9D"} event: response.output_text.delta - data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_6892d9cc2bcc819dafc6201af760aa32023dfe47d80ad8b5","output_index":0,"content_index":0,"delta":"3","logprobs":[],"obfuscation":"gGnFJAikl41wyOZ"} + data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","output_index":0,"content_index":0,"delta":"3","logprobs":[],"obfuscation":"iDi5ypLkUdBQheq"} + + event: response.output_text.done + data: {"type":"response.output_text.done","sequence_number":11,"item_id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","output_index":0,"content_index":0,"text":"1, 2, 3","logprobs":[]} - recorded_at: Wed, 20 Aug 2025 17:12:28 GMT + event: response.content_part.done + data: {"type":"response.content_part.done","sequence_number":12,"item_id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}} + + event: response.output_item.done + data: {"type":"response.output_item.done","sequence_number":13,"output_index":0,"item":{"id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}],"role":"assistant"}} + + event: response.completed + data: {"type":"response.completed","sequence_number":14,"response":{"id":"resp_68abef6d7b9c8192a96c9972b3a7a7af0227cb3dda34901c","object":"response","created_at":1756098413,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-4.1-nano-2025-04-14","output":[{"id":"msg_68abef6dcba08192a848c941bb211a8b0227cb3dda34901c","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"1, 2, 3"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":0.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":14,"input_tokens_details":{"cached_tokens":0},"output_tokens":8,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":22},"user":null,"metadata":{}}} + + recorded_at: Mon, 25 Aug 2025 05:06:53 GMT - request: method: post uri: https://api.openai.com/v1/responses @@ -112,7 +116,7 @@ http_interactions: from 1 to 3","status":"completed"}],"stream":false,"temperature":0.0}' headers: User-Agent: - - Faraday v2.12.2 + - Faraday v2.13.4 Authorization: - Bearer Content-Type: @@ -127,43 +131,37 @@ http_interactions: message: OK headers: Date: - - Wed, 20 Aug 2025 17:12:28 GMT + - Mon, 25 Aug 2025 05:06:54 GMT Content-Type: - application/json Transfer-Encoding: - chunked Connection: - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID - Openai-Organization: - - "" - Openai-Processing-Ms: - - '304' - Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '329' X-Ratelimit-Limit-Requests: - - '500' + - '30000' X-Ratelimit-Limit-Tokens: - - '200000' + - '150000000' X-Ratelimit-Remaining-Requests: - - '499' + - '29999' X-Ratelimit-Remaining-Tokens: - - '199993' + - '149999967' X-Ratelimit-Reset-Requests: - - 120ms - X-Ratelimit-Reset-Tokens: - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" X-Request-Id: - "" Openai-Processing-Ms: - - '465' + - '421' X-Envoy-Upstream-Service-Time: - - '478' + - '424' Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload Cf-Cache-Status: @@ -183,13 +181,20 @@ http_interactions: encoding: ASCII-8BIT string: |- { - "id": "chatcmpl-C6geKz2354N1FaQgqTA5MXGl7TpPC", - "object": "chat.completion", - "created": 1755709948, + "id": "resp_68abef6e51d481a2a4954238b1f61829094625f18cdea301", + "object": "response", + "created_at": 1756098414, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, "model": "gpt-4.1-nano-2025-04-14", "output": [ { - "id": "msg_6892d9ccdbb081a299423e1d8c20de9b0cc127714d6b9c67", + "id": "msg_68abef6e951c81a2bb5723793251df3d094625f18cdea301", "type": "message", "status": "completed", "content": [ @@ -217,10 +222,27 @@ http_interactions: "text": { "format": { "type": "text" - } + }, + "verbosity": "medium" }, - "service_tier": "default", - "system_fingerprint": "fp_c4c155951e" + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 14, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 8, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 22 + }, + "user": null, + "metadata": {} } - recorded_at: Wed, 20 Aug 2025 17:12:28 GMT + recorded_at: Mon, 25 Aug 2025 05:06:54 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_remote_text.yml b/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_remote_text.yml index a04ce874b..e79d8ff93 100644 --- a/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_remote_text.yml +++ b/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_remote_text.yml @@ -169,7 +169,7 @@ http_interactions: Openai-Processing-Ms: - '5435' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -245,4 +245,175 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:02:54 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What''s + in this file?"},{"type":"input_text","text":"Ruby + is copyrighted free software by Yukihiro Matsumoto .\nYou + can redistribute it and/or modify it under either the terms of the\n2-clause + BSDL (see the file BSDL), or the conditions below:\n\n 1. You may make and + give away verbatim copies of the source form of the\n software without + restriction, provided that you duplicate all of the\n original copyright + notices and associated disclaimers.\n\n 2. You may modify your copy of the + software in any way, provided that\n you do at least ONE of the following:\n\n a) + place your modifications in the Public Domain or otherwise\n make + them Freely Available, such as by posting said\n\t modifications to Usenet + or an equivalent medium, or by allowing\n\t the author to include your modifications + in the software.\n\n b) use the modified software only within your corporation + or\n organization.\n\n c) give non-standard binaries non-standard + names, with\n instructions on where to get the original software + distribution.\n\n d) make other distribution arrangements with the author.\n\n 3. + You may distribute the software in object code or binary form,\n provided + that you do at least ONE of the following:\n\n a) distribute the binaries + and library files of the software,\n\t together with instructions (in the + manual page or equivalent)\n\t on where to get the original distribution.\n\n b) + accompany the distribution with the machine-readable source of\n\t the software.\n\n c) + give non-standard binaries non-standard names, with\n instructions + on where to get the original software distribution.\n\n d) make other + distribution arrangements with the author.\n\n 4. You may modify and include + the part of the software into any other\n software (possibly commercial). But + some files in the distribution\n are not written by the author, so that + they are not under these terms.\n\n For the list of those files and their + copying conditions, see the\n file LEGAL.\n\n 5. The scripts and library + files supplied as input to or produced as\n output from the software do + not automatically fall under the\n copyright of the software, but belong + to whomever generated them,\n and may be sold commercially, and may be + aggregated with this\n software.\n\n 6. THIS SOFTWARE IS PROVIDED \"AS + IS\" AND WITHOUT ANY EXPRESS OR\n IMPLIED WARRANTIES, INCLUDING, WITHOUT + LIMITATION, THE IMPLIED\n WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR\n PURPOSE.\n"}],"status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:08 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999440' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1633' + X-Envoy-Upstream-Service-Time: + - '1646' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef02fe2c819c9288b7f5cf29808d02da92e55ff90d5a", + "object": "response", + "created_at": 1756098307, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef03a168819c808343f09b66540302da92e55ff90d5a", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The file \"license.txt\" contains the licensing and copyright information for the Ruby programming language. It states that Ruby is copyrighted free software created by Yukihiro Matsumoto. The license allows users to redistribute and modify Ruby under certain conditions, either under the 2-clause Berkeley Software Distribution License (BSDL) or specific conditions outlined in the document.\n\nThe key points include:\n- Permission to copy and distribute the source code freely, with proper attribution.\n- Conditions under which modifications can be made and shared.\n- Guidelines for distributing binaries and source code.\n- Clarification that some files in the distribution may have different licensing terms.\n- Disclaimers of warranties and liabilities.\n\nOverall, it details how Ruby can be used, shared, and modified legally." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 540, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 152, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 692 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:08 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_text.yml b/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_text.yml index 61a7803d9..1e9e02234 100644 --- a/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_text.yml +++ b/spec/fixtures/vcr_cassettes/chat_text_models_openai_gpt-4_1-nano_can_understand_text.yml @@ -39,7 +39,7 @@ http_interactions: Openai-Processing-Ms: - '424' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -157,7 +157,7 @@ http_interactions: Openai-Processing-Ms: - '608' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -233,4 +233,285 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:02:46 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What''s + in this file?"},{"type":"input_text","text":"Ruby + is the best."}],"status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:05 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999950' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '443' + X-Envoy-Upstream-Service-Time: + - '446' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef012598819e9f6e010a7e96b3240b98b8ef26e0b1ba", + "object": "response", + "created_at": 1756098305, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef016588819eaaa550d9769e08310b98b8ef26e0b1ba", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The file titled \"ruby.txt\" contains the text: \"Ruby is the best.\"" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 31, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 18, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 49 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:05 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What''s + in this file?"},{"type":"input_text","text":"Ruby + is the best."}],"status":"completed"},{"type":"message","role":"assistant","content":"The + file titled \"ruby.txt\" contains the text: \"Ruby is the best.\"","status":"completed"},{"type":"message","role":"user","content":[{"type":"input_text","text":"and + in this one?"},{"type":"input_text","text":"Ruby + is the best"}],"status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:06 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999895' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '546' + X-Envoy-Upstream-Service-Time: + - '549' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef01f4b881928b11c52f2b19269f07c963f7793a0dfb", + "object": "response", + "created_at": 1756098305, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef023bd08192918a6a89eead351607c963f7793a0dfb", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The file named \"ruby.xml\" contains an XML element with the tag ``, and the content inside is \"Ruby is the best.\"" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 86, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 31, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 117 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:06 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_both_on_tool_call_and_on_tool_result_callbacks_in_order.yml b/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_both_on_tool_call_and_on_tool_result_callbacks_in_order.yml index 35e4e4af7..f895caff3 100644 --- a/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_both_on_tool_call_and_on_tool_result_callbacks_in_order.yml +++ b/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_both_on_tool_call_and_on_tool_result_callbacks_in_order.yml @@ -39,7 +39,7 @@ http_interactions: Openai-Processing-Ms: - '443' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -163,7 +163,7 @@ http_interactions: Openai-Processing-Ms: - '386' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -237,4 +237,302 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 15:53:57 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Roll + a die for me","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"dice_roll","description":"Rolls + a single six-sided die and returns the result","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:05 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999742' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '728' + X-Envoy-Upstream-Service-Time: + - '752' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef3cbab881948e1718ba387bdbd3065ef0204c3aaf38", + "object": "response", + "created_at": 1756098364, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef3d40008194a8f337d5b48807c0065ef0204c3aaf38", + "type": "function_call", + "status": "completed", + "arguments": "{}", + "call_id": "call_4W9r74MIjBTXMWtneSBDinbB", + "name": "dice_roll" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Rolls a single six-sided die and returns the result", + "name": "dice_roll", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 41, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 12, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 53 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:05 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Roll + a die for me","status":"completed"},{"type":"function_call","call_id":"call_4W9r74MIjBTXMWtneSBDinbB","name":"dice_roll","arguments":"{}","status":"completed"},{"type":"function_call_output","call_id":"call_4W9r74MIjBTXMWtneSBDinbB","output":"{:roll=>1}","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"dice_roll","description":"Rolls + a single six-sided die and returns the result","parameters":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:06 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999717' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '428' + X-Envoy-Upstream-Service-Time: + - '431' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef3dd4ac81a19e2674c090171084013e6159aff4b790", + "object": "response", + "created_at": 1756098365, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef3e1ed481a1aae7545372ff13b0013e6159aff4b790", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "You rolled a 1." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Rolls a single six-sided die and returns the result", + "name": "dice_roll", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 64, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 8, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 72 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:06 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_call_callback_when_tools_are_used.yml b/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_call_callback_when_tools_are_used.yml index 4d667eedb..9ca21b3ac 100644 --- a/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_call_callback_when_tools_are_used.yml +++ b/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_call_callback_when_tools_are_used.yml @@ -41,7 +41,7 @@ http_interactions: Openai-Processing-Ms: - '610' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -169,7 +169,7 @@ http_interactions: Openai-Processing-Ms: - '396' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -210,4 +210,331 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1DNmZRSGNRdGw2NER5QWZ1ajdaSU54OEN2bDZFdiIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NTcwNTIzMywKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIlRoZSBjdXJyZW50IHdlYXRoZXIgaW4gQmVybGluIGlzIDE1wrBDIHdpdGggYSB3aW5kIHNwZWVkIG9mIDEwIGttL2guIiwKICAgICAgICAicmVmdXNhbCI6IG51bGwsCiAgICAgICAgImFubm90YXRpb25zIjogW10KICAgICAgfSwKICAgICAgImxvZ3Byb2JzIjogbnVsbCwKICAgICAgImZpbmlzaF9yZWFzb24iOiAic3RvcCIKICAgIH0KICBdLAogICJ1c2FnZSI6IHsKICAgICJwcm9tcHRfdG9rZW5zIjogMTQzLAogICAgImNvbXBsZXRpb25fdG9rZW5zIjogMjAsCiAgICAidG90YWxfdG9rZW5zIjogMTYzLAogICAgInByb21wdF90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgImNhY2hlZF90b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMAogICAgfSwKICAgICJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjogewogICAgICAicmVhc29uaW5nX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwLAogICAgICAiYWNjZXB0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwLAogICAgICAicmVqZWN0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwCiAgICB9CiAgfSwKICAic2VydmljZV90aWVyIjogImRlZmF1bHQiLAogICJzeXN0ZW1fZmluZ2VycHJpbnQiOiAiZnBfYzRjMTU1OTUxZSIKfQo= recorded_at: Wed, 20 Aug 2025 15:53:54 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:01 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999702' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '817' + X-Envoy-Upstream-Service-Time: + - '820' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef383f808195a7a345075d8096fc07e93f97c753907a", + "object": "response", + "created_at": 1756098360, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef38c8b081958f49392839abeab807e93f97c753907a", + "type": "function_call", + "status": "completed", + "arguments": "{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}", + "call_id": "call_TRk8b58dQVTW7jF8WTdSJXgx", + "name": "weather" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 82, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 40, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 122 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:01 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"call_TRk8b58dQVTW7jF8WTdSJXgx","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"call_TRk8b58dQVTW7jF8WTdSJXgx","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:01 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999647' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '451' + X-Envoy-Upstream-Service-Time: + - '454' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef3943288192a30901c3f510231204bc410e645009b2", + "object": "response", + "created_at": 1756098361, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef3985048192adcebb3b5ebea56c04bc410e645009b2", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The current weather in Berlin is 15\u00b0C with a wind speed of 10 km/h." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 135, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 21, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 156 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:01 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_result_callback_when_tools_return_results.yml b/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_result_callback_when_tools_return_results.yml index 99dae51a3..12fd7fb3d 100644 --- a/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_result_callback_when_tools_return_results.yml +++ b/spec/fixtures/vcr_cassettes/chat_tool_call_callbacks_calls_on_tool_result_callback_when_tools_return_results.yml @@ -206,4 +206,331 @@ http_interactions: string: !binary |- ewogICJpZCI6ICJjaGF0Y21wbC1DNmZRSnpXQXBkWnJ3VWJMdWtUWm1nVmJvWFBWUyIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NTcwNTIzNSwKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIlRoZSBjdXJyZW50IHdlYXRoZXIgaW4gQmVybGluIGlzIDE1wrBDIHdpdGggYSB3aW5kIHNwZWVkIG9mIDEwIGttL2guIiwKICAgICAgICAicmVmdXNhbCI6IG51bGwsCiAgICAgICAgImFubm90YXRpb25zIjogW10KICAgICAgfSwKICAgICAgImxvZ3Byb2JzIjogbnVsbCwKICAgICAgImZpbmlzaF9yZWFzb24iOiAic3RvcCIKICAgIH0KICBdLAogICJ1c2FnZSI6IHsKICAgICJwcm9tcHRfdG9rZW5zIjogMTQzLAogICAgImNvbXBsZXRpb25fdG9rZW5zIjogMjAsCiAgICAidG90YWxfdG9rZW5zIjogMTYzLAogICAgInByb21wdF90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgImNhY2hlZF90b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMAogICAgfSwKICAgICJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjogewogICAgICAicmVhc29uaW5nX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwLAogICAgICAiYWNjZXB0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwLAogICAgICAicmVqZWN0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwCiAgICB9CiAgfSwKICAic2VydmljZV90aWVyIjogImRlZmF1bHQiLAogICJzeXN0ZW1fZmluZ2VycHJpbnQiOiAiZnBfYzRjMTU1OTUxZSIKfQo= recorded_at: Wed, 20 Aug 2025 15:53:55 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:02 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999700' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '682' + X-Envoy-Upstream-Service-Time: + - '686' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef3a40e481929717c27eba99a73a0cba51f61a3218e9", + "object": "response", + "created_at": 1756098362, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "fc_68abef3ab260819293e3ee15cf6edf9d0cba51f61a3218e9", + "type": "function_call", + "status": "completed", + "arguments": "{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}", + "call_id": "call_bCOpeE3pCBvMPVigP6rlPUuQ", + "name": "weather" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 82, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 40, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 122 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:02 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)","status":"completed"},{"type":"function_call","call_id":"call_bCOpeE3pCBvMPVigP6rlPUuQ","name":"weather","arguments":"{\"latitude\":\"52.5200\",\"longitude\":\"13.4050\"}","status":"completed"},{"type":"function_call_output","call_id":"call_bCOpeE3pCBvMPVigP6rlPUuQ","output":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h","status":"completed"}],"stream":false,"tools":[{"type":"function","name":"weather","description":"Gets + current weather for a location","parameters":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:06:04 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999647' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '589' + X-Envoy-Upstream-Service-Time: + - '592' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef3b95d081a094a3546115236f420dd3a2dabcefffc5", + "object": "response", + "created_at": 1756098363, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef3beaa481a0abc4cfe75283b8720dd3a2dabcefffc5", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The current weather in Berlin is 15\u00b0C with a wind speed of 10 km/h." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "description": "Gets current weather for a location", + "name": "weather", + "parameters": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Latitude (e.g., 52.5200)" + }, + "longitude": { + "type": "string", + "description": "Longitude (e.g., 13.4050)" + } + }, + "required": [ + "latitude", + "longitude" + ], + "additionalProperties": false + }, + "strict": true + } + ], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 135, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 21, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 156 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:04 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_local_images.yml b/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_local_images.yml index 83c9589a4..b308954fd 100644 --- a/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_local_images.yml +++ b/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_local_images.yml @@ -38,7 +38,7 @@ http_interactions: Openai-Processing-Ms: - '646' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -120,4 +120,142 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:04:18 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What + do you see in this image?"},{"type":"input_image","image_url":"data:image/png;base64,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"}],"status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:11 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999235' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1474' + X-Envoy-Upstream-Service-Time: + - '1489' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef05c25c81a099fcd8693e02a8dc094457a9a875ddbe", + "object": "response", + "created_at": 1756098309, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef067c3081a0aa5e52f0ed3e2a04094457a9a875ddbe", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The image depicts a large, red, faceted gemstone or gem-like object. It appears to be a stylized, digital rendering of a gemstone with a shiny, reflective surface and multiple facets." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 56, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 40, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 96 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:11 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_remote_images_without_extension.yml b/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_remote_images_without_extension.yml index 1953a81b3..9362b5994 100644 --- a/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_remote_images_without_extension.yml +++ b/spec/fixtures/vcr_cassettes/chat_vision_models_openai_gpt-4_1-nano_can_understand_remote_images_without_extension.yml @@ -95,7 +95,7 @@ http_interactions: Openai-Processing-Ms: - '1010' Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E + - "" Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: @@ -177,4 +177,142 @@ http_interactions: "system_fingerprint": "fp_c4c155951e" } recorded_at: Wed, 20 Aug 2025 17:04:20 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"What + do you see in this image?"},{"type":"input_image","image_url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzSCawxoHrVtf9AX-o7bp7KVxcmkYWzsIjng&s"}],"status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 25 Aug 2025 05:05:12 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149999235' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1048' + X-Envoy-Upstream-Service-Time: + - '1052' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_68abef07a4d481a2b14ae666780a8e4601d735940e60a492", + "object": "response", + "created_at": 1756098311, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef08272c81a2b1ef4bb9a2ec183301d735940e60a492", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The image shows the Eiffel Tower in Paris, France, during sunset. The sky has a mix of clouds with a warm glow near the horizon, and there are some trees and a body of water in the foreground." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 149, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 44, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 193 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:05:12 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_accepts_a_json_schema_and_returns_structured_output.yml b/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_accepts_a_json_schema_and_returns_structured_output.yml index 33c975882..2ee6ffa1d 100644 --- a/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_accepts_a_json_schema_and_returns_structured_output.yml +++ b/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_accepts_a_json_schema_and_returns_structured_output.yml @@ -5,11 +5,11 @@ http_interactions: uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"Generate - a person named John who is 30 years old"}],"stream":false,"response_format":{"type":"json_schema","json_schema":{"name":"response","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"],"additionalProperties":false},"strict":true}}}' + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Generate + a person named John who is 30 years old","status":"completed"}],"stream":false,"text":{"format":{"type":"json_schema","name":"response","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"],"additionalProperties":false},"strict":true}}}' headers: User-Agent: - - Faraday v2.12.2 + - Faraday v2.13.4 Authorization: - Bearer Content-Type: @@ -24,43 +24,37 @@ http_interactions: message: OK headers: Date: - - Wed, 20 Aug 2025 17:08:23 GMT + - Mon, 25 Aug 2025 05:06:49 GMT Content-Type: - application/json Transfer-Encoding: - chunked Connection: - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID - Openai-Organization: - - "" - Openai-Processing-Ms: - - '414' - Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '435' X-Ratelimit-Limit-Requests: - - '500' + - '30000' X-Ratelimit-Limit-Tokens: - - '200000' + - '150000000' X-Ratelimit-Remaining-Requests: - - '499' + - '29999' X-Ratelimit-Remaining-Tokens: - - '199986' + - '149999932' X-Ratelimit-Reset-Requests: - - 120ms + - 2ms X-Ratelimit-Reset-Tokens: - - 4ms + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" X-Request-Id: - "" Openai-Processing-Ms: - - '1248' + - '318' X-Envoy-Upstream-Service-Time: - - '1430' + - '320' Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload Cf-Cache-Status: @@ -80,13 +74,20 @@ http_interactions: encoding: ASCII-8BIT string: |- { - "id": "chatcmpl-C6gaN6dcApL0OhgqhfaIWaJMDiRam", - "object": "chat.completion", - "created": 1755709703, + "id": "resp_68abef69028881a38d1a014252ed597c07459232ff9bee71", + "object": "response", + "created_at": 1756098409, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, "model": "gpt-4.1-nano-2025-04-14", "output": [ { - "id": "msg_6892d791c14881a28a75740b6814ca3a0ea79e0ebdf6e752", + "id": "msg_68abef69332081a3a96032c9e8e8c39907459232ff9bee71", "type": "message", "status": "completed", "content": [ @@ -110,7 +111,7 @@ http_interactions: "safety_identifier": null, "service_tier": "default", "store": true, - "temperature": 0.7, + "temperature": 1.0, "text": { "format": { "type": "json_schema", @@ -133,10 +134,27 @@ http_interactions: "additionalProperties": false }, "strict": true - } + }, + "verbosity": "medium" }, - "service_tier": "default", - "system_fingerprint": "fp_c4c155951e" + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 47, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 57 + }, + "user": null, + "metadata": {} } - recorded_at: Wed, 20 Aug 2025 17:08:23 GMT + recorded_at: Mon, 25 Aug 2025 05:06:49 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_allows_removing_schema_with_nil_mid-conversation.yml b/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_allows_removing_schema_with_nil_mid-conversation.yml index b343168a7..8fa835448 100644 --- a/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_allows_removing_schema_with_nil_mid-conversation.yml +++ b/spec/fixtures/vcr_cassettes/chat_with_schema_with_openai_gpt-4_1-nano_allows_removing_schema_with_nil_mid-conversation.yml @@ -5,11 +5,11 @@ http_interactions: uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"Generate - a person named Bob"}],"stream":false,"response_format":{"type":"json_schema","json_schema":{"name":"response","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"],"additionalProperties":false},"strict":true}}}' + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Generate + a person named Bob","status":"completed"}],"stream":false,"text":{"format":{"type":"json_schema","name":"response","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"],"additionalProperties":false},"strict":true}}}' headers: User-Agent: - - Faraday v2.12.2 + - Faraday v2.13.4 Authorization: - Bearer Content-Type: @@ -24,43 +24,37 @@ http_interactions: message: OK headers: Date: - - Wed, 20 Aug 2025 17:08:24 GMT + - Mon, 25 Aug 2025 05:06:50 GMT Content-Type: - application/json Transfer-Encoding: - chunked Connection: - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID - Openai-Organization: - - "" - Openai-Processing-Ms: - - '406' - Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '431' X-Ratelimit-Limit-Requests: - - '500' + - '30000' X-Ratelimit-Limit-Tokens: - - '200000' + - '150000000' X-Ratelimit-Remaining-Requests: - - '499' + - '29999' X-Ratelimit-Remaining-Tokens: - - '199991' + - '149999940' X-Ratelimit-Reset-Requests: - - 120ms - X-Ratelimit-Reset-Tokens: - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" X-Request-Id: - "" Openai-Processing-Ms: - - '522' + - '346' X-Envoy-Upstream-Service-Time: - - '530' + - '347' Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload Cf-Cache-Status: @@ -80,13 +74,20 @@ http_interactions: encoding: ASCII-8BIT string: |- { - "id": "chatcmpl-C6gaNqBbnsGWEaDKfSoiv81UKbDlJ", - "object": "chat.completion", - "created": 1755709703, + "id": "resp_68abef69d93c8191b1bc8f239112d5e20dbd8f4c187f4db0", + "object": "response", + "created_at": 1756098409, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, "model": "gpt-4.1-nano-2025-04-14", "output": [ { - "id": "msg_6892d7927ccc8192864353f37e6aed9e0b9d53e1a1247b55", + "id": "msg_68abef6a14f88191b0023b6196ed45940dbd8f4c187f4db0", "type": "message", "status": "completed", "content": [ @@ -110,7 +111,7 @@ http_interactions: "safety_identifier": null, "service_tier": "default", "store": true, - "temperature": 0.7, + "temperature": 1.0, "text": { "format": { "type": "json_schema", @@ -133,23 +134,40 @@ http_interactions: "additionalProperties": false }, "strict": true - } + }, + "verbosity": "medium" }, - "service_tier": "default", - "system_fingerprint": "fp_c4c155951e" + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 41, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 51 + }, + "user": null, + "metadata": {} } - recorded_at: Wed, 20 Aug 2025 17:08:24 GMT + recorded_at: Mon, 25 Aug 2025 05:06:50 GMT - request: method: post uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"Generate - a person named Bob"},{"role":"assistant","content":"{\"name\":\"Bob\",\"age\":30}"},{"role":"user","content":"Now - just tell me about Ruby"}],"stream":false}' + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Generate + a person named Bob","status":"completed"},{"type":"message","role":"assistant","content":"{\"name\":\"Bob\",\"age\":30}","status":"completed"},{"type":"message","role":"user","content":"Now + just tell me about Ruby","status":"completed"}],"stream":false}' headers: User-Agent: - - Faraday v2.12.2 + - Faraday v2.13.4 Authorization: - Bearer Content-Type: @@ -164,43 +182,37 @@ http_interactions: message: OK headers: Date: - - Wed, 20 Aug 2025 17:08:26 GMT + - Mon, 25 Aug 2025 05:06:51 GMT Content-Type: - application/json Transfer-Encoding: - chunked Connection: - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID - Openai-Organization: - - "" - Openai-Processing-Ms: - - '1923' - Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '1947' X-Ratelimit-Limit-Requests: - - '500' + - '30000' X-Ratelimit-Limit-Tokens: - - '200000' + - '150000000' X-Ratelimit-Remaining-Requests: - - '499' + - '29999' X-Ratelimit-Remaining-Tokens: - - '199976' + - '149999945' X-Ratelimit-Reset-Requests: - - 120ms + - 2ms X-Ratelimit-Reset-Tokens: - - 7ms + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" X-Request-Id: - "" Openai-Processing-Ms: - - '2466' + - '426' X-Envoy-Upstream-Service-Time: - - '2475' + - '429' Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload Cf-Cache-Status: @@ -218,7 +230,70 @@ http_interactions: - h3=":443"; ma=86400 body: encoding: ASCII-8BIT - string: !binary |- - ewogICJpZCI6ICJjaGF0Y21wbC1DNmdhT3Z0aVFLc3VBNmMzMkF6dG5XZWlOOU9lYSIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NTcwOTcwNCwKICAibW9kZWwiOiAiZ3B0LTQuMS1uYW5vLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIkNlcnRhaW5seSEgUnVieSBpcyBhIGR5bmFtaWMsIG9wZW4tc291cmNlIHByb2dyYW1taW5nIGxhbmd1YWdlIGtub3duIGZvciBpdHMgc2ltcGxpY2l0eSBhbmQgcHJvZHVjdGl2aXR5LiBDcmVhdGVkIGJ5IFl1a2loaXJvIOKAnE1hdHrigJ0gTWF0c3Vtb3RvIGFuZCByZWxlYXNlZCBpbiB0aGUgbWlkLTE5OTBzLCBSdWJ5IGVtcGhhc2l6ZXMgaHVtYW4tZnJpZW5kbHkgc3ludGF4IHRoYXQgaXMgZWFzeSB0byByZWFkIGFuZCB3cml0ZS4gSXQgc3VwcG9ydHMgbXVsdGlwbGUgcHJvZ3JhbW1pbmcgcGFyYWRpZ21zLCBpbmNsdWRpbmcgb2JqZWN0LW9yaWVudGVkLCBmdW5jdGlvbmFsLCBhbmQgaW1wZXJhdGl2ZSBwcm9ncmFtbWluZy5cblxuUnVieSBpcyBiZXN0IGtub3duIGZvciBpdHMgZWxlZ2FudCBzeW50YXggdGhhdCByZXNlbWJsZXMgbmF0dXJhbCBsYW5ndWFnZSwgbWFraW5nIGl0IGFjY2Vzc2libGUgdG8gYmVnaW5uZXJzIHdoaWxlIHBvd2VyZnVsIGVub3VnaCBmb3IgY29tcGxleCBhcHBsaWNhdGlvbnMuIE9uZSBvZiBpdHMgbW9zdCBwb3B1bGFyIGZyYW1ld29ya3MgaXMgUnVieSBvbiBSYWlscywgYSB3ZWIgYXBwbGljYXRpb24gZnJhbWV3b3JrIHRoYXQgaGFzIHNpZ25pZmljYW50bHkgY29udHJpYnV0ZWQgdG8gUnVieSdzIHBvcHVsYXJpdHkgaW4gd2ViIGRldmVsb3BtZW50LlxuXG5SdWJ5IGlzIHVzZWQgaW4gdmFyaW91cyBkb21haW5zLCBpbmNsdWRpbmcgd2ViIGRldmVsb3BtZW50LCBhdXRvbWF0aW9uLCBkYXRhIHByb2Nlc3NpbmcsIGFuZCBtb3JlLiBJdCBib2FzdHMgYSB2aWJyYW50IGNvbW11bml0eSwgZXh0ZW5zaXZlIGxpYnJhcmllcyAoZ2VtcyksIGFuZCBjb250aW51ZXMgdG8gYmUgYSBwb3B1bGFyIGNob2ljZSBmb3IgZGV2ZWxvcGVycyBzZWVraW5nIGFuIGV4cHJlc3NpdmUgYW5kIHByb2R1Y3RpdmUgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuIiwKICAgICAgICAicmVmdXNhbCI6IG51bGwsCiAgICAgICAgImFubm90YXRpb25zIjogW10KICAgICAgfSwKICAgICAgImxvZ3Byb2JzIjogbnVsbCwKICAgICAgImZpbmlzaF9yZWFzb24iOiAic3RvcCIKICAgIH0KICBdLAogICJ1c2FnZSI6IHsKICAgICJwcm9tcHRfdG9rZW5zIjogMzUsCiAgICAiY29tcGxldGlvbl90b2tlbnMiOiAxNzAsCiAgICAidG90YWxfdG9rZW5zIjogMjA1LAogICAgInByb21wdF90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgImNhY2hlZF90b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMAogICAgfSwKICAgICJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjogewogICAgICAicmVhc29uaW5nX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwLAogICAgICAiYWNjZXB0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwLAogICAgICAicmVqZWN0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwCiAgICB9CiAgfSwKICAic2VydmljZV90aWVyIjogImRlZmF1bHQiLAogICJzeXN0ZW1fZmluZ2VycHJpbnQiOiAiZnBfYzRjMTU1OTUxZSIKfQo= - recorded_at: Wed, 20 Aug 2025 17:08:26 GMT + string: |- + { + "id": "resp_68abef6aa538819e988d3a54fc2a850a09e7a347f028b06d", + "object": "response", + "created_at": 1756098410, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_68abef6ad4bc819e8afcabc8f32e256c09e7a347f028b06d", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Could you please specify what you'd like to know about Ruby? Are you referring to the programming language, the gemstone, or something else?" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 35, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 28, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 63 + }, + "user": null, + "metadata": {} + } + recorded_at: Mon, 25 Aug 2025 05:06:51 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/context_context_chat_operations_uses_context-specific_api_keys.yml b/spec/fixtures/vcr_cassettes/context_context_chat_operations_uses_context-specific_api_keys.yml index b6332cd4f..fda587946 100644 --- a/spec/fixtures/vcr_cassettes/context_context_chat_operations_uses_context-specific_api_keys.yml +++ b/spec/fixtures/vcr_cassettes/context_context_chat_operations_uses_context-specific_api_keys.yml @@ -61,4 +61,71 @@ http_interactions: } } recorded_at: Wed, 20 Aug 2025 17:12:58 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer test-context-key + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 401 + message: Unauthorized + headers: + Date: + - Mon, 25 Aug 2025 05:06:13 GMT + Content-Type: + - application/json + Content-Length: + - '245' + Connection: + - keep-alive + Www-Authenticate: + - Bearer realm="OpenAI API" + Openai-Version: + - '2020-10-01' + X-Request-Id: + - "" + Openai-Processing-Ms: + - '31' + X-Envoy-Upstream-Service-Time: + - '33' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |- + { + "error": { + "message": "Incorrect API key provided: test-con****-key. You can find your API key at https://platform.openai.com/account/api-keys.", + "type": "invalid_request_error", + "param": null, + "code": "invalid_api_key" + } + } + recorded_at: Mon, 25 Aug 2025 05:06:13 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/error_handles_invalid_api_keys_gracefully.yml b/spec/fixtures/vcr_cassettes/error_handles_invalid_api_keys_gracefully.yml index 4b0e3bc27..e8f265362 100644 --- a/spec/fixtures/vcr_cassettes/error_handles_invalid_api_keys_gracefully.yml +++ b/spec/fixtures/vcr_cassettes/error_handles_invalid_api_keys_gracefully.yml @@ -61,4 +61,71 @@ http_interactions: } } recorded_at: Wed, 20 Aug 2025 17:13:09 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false}' + headers: + User-Agent: + - Faraday v2.13.4 + Authorization: + - Bearer invalid-key + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 401 + message: Unauthorized + headers: + Date: + - Mon, 25 Aug 2025 05:06:14 GMT + Content-Type: + - application/json + Content-Length: + - '240' + Connection: + - keep-alive + Www-Authenticate: + - Bearer realm="OpenAI API" + Openai-Version: + - '2020-10-01' + X-Request-Id: + - "" + Openai-Processing-Ms: + - '46' + X-Envoy-Upstream-Service-Time: + - '49' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: UTF-8 + string: |- + { + "error": { + "message": "Incorrect API key provided: invalid-key. You can find your API key at https://platform.openai.com/account/api-keys.", + "type": "invalid_request_error", + "param": null, + "code": "invalid_api_key" + } + } + recorded_at: Mon, 25 Aug 2025 05:06:14 GMT recorded_with: VCR 6.3.1 From 02e1d5c0d0126fdd93d71c78fce4939feac7d711 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Sun, 24 Aug 2025 22:10:15 -0700 Subject: [PATCH 24/27] Unable to generate this cassette for some reason, just restore what we had Getting this: ruby(19317,0x206ace0c0) malloc: Double free of object 0x10afc39e0 ruby(19317,0x206ace0c0) malloc: *** set a breakpoint in malloc_error_break to debug --- ...nai_gpt-4_1-nano_handles_multiple_pdfs.yml | 320 +++++++++++++----- 1 file changed, 238 insertions(+), 82 deletions(-) diff --git a/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_handles_multiple_pdfs.yml b/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_handles_multiple_pdfs.yml index eac661d25..c2cc401d2 100644 --- a/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_handles_multiple_pdfs.yml +++ b/spec/fixtures/vcr_cassettes/chat_pdf_models_openai_gpt-4_1-nano_handles_multiple_pdfs.yml @@ -33,45 +33,45 @@ http_interactions: Etag: - '"680c9470-497a"' Expires: - - Wed, 20 Aug 2025 02:50:43 GMT + - Mon, 28 Jul 2025 05:19:44 GMT Cache-Control: - max-age=600 X-Proxy-Cache: - MISS X-Github-Request-Id: - - 6200:D85F7:F30694:F4B2BE:68A535AA + - 3936:12C06F:5A9BBDB:5B38331:68870618 Accept-Ranges: - bytes Date: - - Wed, 20 Aug 2025 17:05:57 GMT + - Fri, 01 Aug 2025 10:51:41 GMT Via: - 1.1 varnish Age: - - '13' + - '27' X-Served-By: - - cache-fra-etou8220136-FRA + - cache-fra-etou8220089-FRA X-Cache: - HIT X-Cache-Hits: - '1' X-Timer: - - S1755709558.525267,VS0,VE4 + - S1754045501.478979,VS0,VE2 Vary: - Accept-Encoding X-Fastly-Request-Id: - - 472a729592cf22b69ddfab38071c4f28ef959d63 + - 61f64c429b2f2dfe010eaadf111446fb07b3859e body: encoding: ASCII-8BIT string: !binary |- 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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK - recorded_at: Wed, 20 Aug 2025 17:05:57 GMT + recorded_at: Fri, 01 Aug 2025 10:51:41 GMT - request: method: post uri: https://api.openai.com/v1/chat/completions body: encoding: UTF-8 string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":[{"type":"text","text":"Compare - these documents"},{"type":"file","file":{"filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}},{"type":"file","file":{"filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}}]}],"stream":false}' + these documents"},{"type":"file","file":{"filename":"sample.pdf","file_data":"data:application/pdf;base64,JVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGdWsuS20YSvOMr+siJ8IzZDT6PXtmK8MbaIYfHu4cNHzAkNGoHCFIEMJ+737KZ1VUNUKRkjfYR4oCNRnVWVtYD/Oh+cx/dHP9d+eDW2+DOtfuPa933bzrvdp3zrtt9+v17N39YzeU/Lk6/LHAzvyznfruab9KtEQ/wsuqe//AZu4P7x6MrV+kq/l0H5+cr93hw37/1D3Pni8f3bvZ7dTg1tXv349s79/iX++kRxs656Wc29Bt9zEY2LEPaMDzMC++44eOH2Dn8r3JdtK3d/5r6wb0dWvc+/f9hfNiN5xQwHEgRsXsiBsNXZXpOScP5nP+62b+O5zvn125WH+7c/da7mcO/5dLN4qkbeG29LuTaYutm+2Mj60Na5ktc62LPOzbp0gZXqkPdf3cHR+mqDb7bHduu3vV1P9Tnu+Ie+/M5PmCnah9PsdvF9lmfzG9oSd3EHoeEN3Qx7nr3oerqphk6XA8lvyju/Rwf3le72MQu8osS5+EmNOa4j0fuYSb7BUyu91yFT/Io3H2ID9jpT/f4z+S9G4CSCZ8Aut5cA/pmOFdPsR94SvhZnrDACboBRzzJgYIeaAObfh2aphLokzU06qVuYN4q3buEdS3O9YD95Lzufonj/dRHuW2drvF4XX04AVyn2K4mPlwoIB6rhx47LXQrj6c08MvQAeigd25w8Z3S4hhbeFLP4QM+VE38OFQHOJgsIf5brK/PFWkgPq+f6x7AvhbNbVlIXE3pefpQGT/7c4UHGEM9bdodD4fj/kiu6QHLILbcFaT0kVywkwYe9RBBdkU/rPEBtNzHQ932QnU/B2FICb+cu1k6JSJSLgUeTYhDELgoJF6LCfhTLQhLuOKvoeuPsmalG2HBJqRA8mtYAi/ANnyQVfQLvA524M9X4hbmm2vcfm57eAHQ3UO05BnlGswigms9Y1nCNLoNnrdQWCyWxezNuSJwesrFHOdpqiwTNQ2nvTS83OLUTXweGtlZ+VOSGLvhDMozCMw1W9xUt/FApmFP3r+A9M1+qNu6AsuWGo+LFT50u7qpz7H7ONRYJ1uAtQx0wQnX9GGLOT6IUbYn9HzWi0Z8Gc0iqftlTAeIyhUL/52Mq7s+Pg2NUIXRxRN4Pn4fEUEHRgIg5dUN/pU4EcPWigASCoMU5+cJuS4QeJEA/qEXPZ1gcobFJJQsJmp/Z0q12w2HjnAmxaMIAbQKfKC1ajSD5yX2Fa5ZOPgNvlTFtbOt8UGsw+P/LF6ljQEJ4QpHFQm/SYEQqI+aUhjXlBQDZg0En5oK0Qm+qdmBuh5bLKOICyRLX8zOQ38WnyzNbh7l4xA7rlSmBqYvU0ijZCDlTkPzElvITGE2GN5ESQlrDkPBMNFsb4rpPcx9qc4x5SU73xz2QmGeyeGF7YqkMQOxobhE9XUZJyxvaCQowWQRX6qDPJ7aJeCscLU7Nk3cIR/tBThLISURRJpmhCo7S/JPZMm4HZY4bARzVIL3SSR5VtkfhRAYU8f3dbsH1Es9dknaMGXh0Lq0ZMpKMYmL6faSafCEOIX61inOTavL1bwQLtKBZh6p0QO4Humn/gboVjdkcoyWLMUSBpb8JIHoaSmXTAkMI1+qlDMkJcZTLsRXW/AsuRdstlvh8t+H7gScYteBDKV9Q4o18Yk1kWQsbJ5ZTKFm9QIQTC8DcTxUfS9lTr4q2V/KsAX2k5Jog4Vah+XMFHiN2ftCwwP9wJT93RdBva2W0JarKP+AY1rSPotVpuya5r67K3hucsgzPbWsgSB0wDVdXeLi71Kj0WSuYwWlgmX09lSPakBwoTTSZcysP6T6hNvNE/2YZFR6UsmI/UDRl2Mz9CfJf6wa+Jjtopjcz/oMVxkq7+vhOUqFw824lA5/GZrT0FdJWie2g/zNN9STYXtDM6e8EY7w4UscnQLHjymcaKTgiEs5keBUJ/NEHyV6E0EcQjWlBEItJ7+xluHP8+OfA2WENaIlI+ayVCMWM6kRWV5wI+8JDBMJ/tCAxtpUJFAlFD9WA131HJXLqUItYEXF3iFokcI0AG52vZQkpWJMx3+ZrejcrhugEvy7ZGsWfyfpwonjPt9W3YyBEoe83BVt1buJrhGVsMKxpVPSI+ACXAAFHlG6l3yYq3FWjry1ZJi/O1d1B6HE33kDfH+duzSuAmWoHdodtEahlNSlpLHWLDBCYrUb4Fy4hg8sYCu8YK6BL3LvJDlUSltcVDeGJbanLMLUzyez28CBxVfANcen4znJm1fDpUnscZU16BYJn/xQspFgqZsT42GrxOVFpaY4sibbD0hKuXpFO1NoEhwPKT3OC0rStkpmWGcrXSY2RhBYf+mZy38VlK22p0Fa+oL+aibiWgNAVM6MZyNhxZ91aAyLXPu9viUt0Q9eYTr2zKhQFTjYIJ3n7niWptHqJOrxRa/ujD64g5KBE1CMSRQWRT8mFQoKMhb1sd3F/dAyjE1dmMrQEQNlHLllr6AqTn2P+7sCl4Xr2OayJSOP8Q2FvRnYp2JXy57cvY1PH6bUK76qcy/Rul3BlATRfBs85h4TgTd524BoXXWKNetQy9WBrMM5nLX2gV2TxRCjBbTlAT3D5VB1HTHAPCZdlNSvQr0DQ3MVTC2Vkkzx8RjjaElaqDqjh8C1qd5AsdUbnhXtyzQY2LLSDso3gH6pKOuvpxkbsSv8pLUpLGN7VlTGbpNzDmSEXVAM0TKYIbCwUtbiapU8DoYUWo4aSlisAm24+9yhsCzbqI8IXwpUSzZ+DfzHyUzuHzyplAlLl0yetYeXnwagA7dRi9LoC4ayhSusI/B86mRaguWf10EdKF62nAv0Q1dgWgbNIsgmElMlTMoYAWpnoP0XrbJXogUimkZznCDJIShHWhNaJg0SgJYALCrv0YIC63qHSs1anMA0dP5wbHfSZNhoy9OuCgtdlgAOWmR4SKlQvgX2tKMOaXOKuODEZQIssbYajVy36c9umOT7gqPgm5PaT4AFOlfAjpVcKvmR75gh6wFHyL0G5wzP5+ol7hmnlgECRVoWGigla6OR0JxQJKxxXimaGHs1dk6SyWSOLQycXJinNKKDwEQsmEUtAQ0IiW5KqmFHXGEBSJ+K/0QhbKwT2JXl2S0glJQulbfWu9/AULjRgNQJtcL44NL0xk0bOfjdpuBf56f1jQD4ub1zpnosaA/VgLaKlFJ98ATqUvdSGY+RB+GWXG/84+xbelIS1eKBfs/Fz73lKiq0OFmWYTOG4Eh8IwN5Ly218V5amYvCQbnAjMEIKay98SSB5tIcnOyI/qBrdaIrxYMOr2kSvU0Tpf5CMLx2WL1AZWE+zNP/iXSQJiw+wDhgZCMAT6JZPYIS0SJEBh7tkTmQTBd5ITI6kcUsRS8yD1ZYNf37VO9ZRuQsxWjToaPtLyOEGtWrRxaQ3bnIEqfJH/HQ1w9AVBAi1qiq+Zk5zspGHbUiQHGLNX5Y9EqpXmK2aCCmQECtn+Y+OFBOfTzFj0foJ9ARFiGEqdQN3lG0kXCAumIi/m1rzjgLdva85CkyUiHBUl6QG6X0IQNUCoi1tvLYzYSEDSvBvStGp1CHtN6w5I898FYpT3ViGlKKVOD5fDzqPGybw4mKLvnaZIxhlcddajgfPlHyL4J7sx9Y3hq9ynFczjZESep9GJDQWhVajpFRCplnU/wWL1wwahmbYThApwA2kGWLxQISZ01tPafVuDYOSfgXn8P3C2nyqA7wlCEbfmGBTRA8g1ymKXCpmbOFORYZCWGxncqRluZ4C6S5DuVtAu/Dtkin+SKmN2uLJYhihJWoL0BYSVj2Lg4dlZtRVg1RvhbRaLRZB8faMtMiAxWRNToeiy4bnNp5qVcnNGx9lJ7N6CmjAakq0Bqp/+jZPNW7K0h2wUZCu+ZYMU/WKEW5ZoUlmRRzbGajXTXFZpFpqq2l9ZHpw2xkSSoU+QpQi8u6YgnRvgCVL1InrYIhyUdYJmZPzYMtMWGS2l9Vk5VsTm25IZCacvKm07pD5oZxFGNDSI5epsWtHZGtTGqOc+ZhuTVpxICHRq/0wuPozNjAGkx0bHqm1P6g+zEnilof2xHJr63Qlsh6V0hqS4faEPuPE478Jktf/WnzgiNYBg4Mwk+n4TbYlc5rzGSFsYcvfNIYERslH0ntnCYlBhy6wdSgkEGKRSDuqPzT5Fbek+r9vCsPAS6FfRy/ahz5LRnASfw3TAyXt+avNyeGkrA1//AM5jpaZ12aZ7KGE8GRasyg8iaN4aadBQfkFTIbRt3puCRl6kxkVbrIactEHg1H3jwpOtBH5QKIjvqlqncYvMjYXYnJTMaAyfNFXE9J4cIAGQ6/vipa3hq58p2PU7126f2H+BjvPx6c5HXHwuzBYUbtpi9YHGpOlyyRMg1Af77AuJkDV5gJXQXEL8fzE1+mqGRIQaoDVnFYcU/N5rQPcqnBT/xHtiOBGd1wBwsQ1VnOVZKgAGJqEzWKjp3UbHx/iDXSyowVIIVWRrULoxJDJE8vFyZOzMlTRmbpZxgx+/GBukUajrDOx0WrnJj96gHBqXQTlqZ3SaPgyK+DvqIlXMGuK3zHw9l4LIwRDB8aRSXgdeCV8ES9wFFqemum6qEjnmcZc+n4Ck2twIVjWe3q2RbYMHWFKkaQZzrYx2eMOfDDH6y2bCtlCZKf/VhhKkMcqrxJr+bS7xfYs8CY7riLguT4SOCMsebxm16grZBTr6DDKy2MSTElga32uwjCJW41XSZEh4qHyifCb1lwEW/DiIh6n0nuVJ0hJRiuif4k5vH1IBibKyweEhqxg2ZypLjU3yex0DtHvIrHG3puaxNN8gwvRulHlRTPLv0qTwi9YBeQyxW9WsYfxKTeDEaLn7ABGo8v8u92fEMsr0C0hkXs2qff9Vhu5aM7/ekQOjTTAP7kJpUNOCk+i1EEkjNynbJq1YMa2ISDEiu1bcUJltHaszyFlAFiA4gzuAxCho1jbKW/3SuvGTUF7gZgbKHsyWT7kZLtQH+OxR7sNMPxOGlSXi/gq1uTXJEVTFD0OHxzC2WGdVZHeZYWk3FUFhuSBmEmLxXzK/stFOjTH6mkOl9mMdorU87waxoyVaiEeSTgng4Xk0/lZ1xa9tsYjp3ZZHSg/uI7I3kvBVU3qFi2WCvBOE8IimP/5gXuzf5gjX7D+KiTHY5hAZVNcH77P6d6b9EKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjM4NjYKZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAzIDAgUiAvUmVzb3VyY2VzIDYgMCBSIC9Db250ZW50cyA0IDAgUiAvTWVkaWFCb3ggWzAgMCA2MTIgNzkyXQo+PgplbmRvYmoKNiAwIG9iago8PCAvUHJvY1NldCBbIC9QREYgL1RleHQgXSAvQ29sb3JTcGFjZSA8PCAvQ3MxIDcgMCBSID4+IC9Gb250IDw8IC9GMS4wIDggMCBSCi9GMy4wIDEwIDAgUiAvRjIuMCA5IDAgUiA+PiA+PgplbmRvYmoKMTEgMCBvYmoKPDwgL0xlbmd0aCAxMiAwIFIgL04gMSAvQWx0ZXJuYXRlIC9EZXZpY2VHcmF5IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AYVST0gUURz+zTYShIhBhXiIdwoJlSmsrKDadnVZlW1bldKiGGffuqOzM9Ob2TXFkwRdojx1D6JjdOzQoZuXosCsS9cgqSAIPHXo+83s6iiEb3k73/v9/X7fe0RtnabvOylBVHNDlSulp25OTYuDHylFHdROWKYV+OlicYyx67mSv7vX1mfS2LLex7V2+/Y9tZVlYCHqLba3EPohkWYAH5mfKGWAs8Adlq/YPgE8WA6sGvAjogMPmrkw09GcdKWyLZFT5qIoKq9iO0mu+/m5xr6LtYmD/lyPZtaOvbPqqtFM1LT3RKG8D65EGc9fVPZsNRSnDeOcSEMaKfKu1d8rTMcRkSsQSgZSNWS5n2pOnXXgdRi7XbqT4/j2EKU+yWCoibXpspkdhX0AdirL7BDwBejxsmIP54F7Yf9bUcOTwCdhP2SHedatH/YXrlPge4Q9NeDOFK7F8dqKH14tAUP3VCNojHNNxNPXOXOkiO8x1BmY90Y5pgsxd5aqEzeAO2EfWapmCrFd+67qJe57AnfT4zvRmzkLXKAcSXKxFdkU0DwJWBR9i7BJDjw+zh5V4HeomMAcuYnczSj3HtURG2ejUoFWeo1Xxk/jufHF+GVsGM+Afqx213t8/+njFXXXtj48+Y163DmuvZ0bVWFWcWUL3f/HMoSP2Sc5psHToVlYa9h25A+azEywDCjEfwU+l/qSE1Xc1e7tuEUSzFA+LGwluktUbinU6j2DSqwcK9gAdnCSxCxaHLhTa7o5eHfYInpt+U1XsuuG/vr2evva8h5tyqgpKBPNs0RmlLFbo+TdeNv9ZpERnzg6vue9ilrJ/klFED+FOVoq8hRV9FZQ1sRvZw5+G7Z+XD+l5/VB/TwJPa2f0a/ooxG+DHRJz8JzUR+jSfCwaSHiEqCKgzPUTlRjjQPiKfHytFtkkf0PQBn9ZgplbmRzdHJlYW0KZW5kb2JqCjEyIDAgb2JqCjcwNAplbmRvYmoKNyAwIG9iagpbIC9JQ0NCYXNlZCAxMSAwIFIgXQplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFswIDAgNjEyIDc5Ml0gL0NvdW50IDEgL0tpZHMgWyAyIDAgUiBdID4+CmVuZG9iagoxMyAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgPj4KZW5kb2JqCjE0IDAgb2JqCjw8IC9MZW5ndGggMTUgMCBSIC9MZW5ndGgxIDM0MzIgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBrVZtaFvXGT7nXFmSpUiW5CsplmxZ17JuZEnWpyXZqT9kx7LlOHP8UTu6hiR2/J3Zq5e6IYFu9cI2Mv3o8qulsB8lHYVC6bRBg2r2I4x90LIfhnU/tmQshRXGGKM/kg3GbO05V7JZhymFTeLRed/3nPPe9zznfd8rQgkhp8guEUh2aWtxm7xInsHya6C8dHPHS0R8Cf02dM3q9tpWyDL6C+h3CWHvr23eXo2+bqlgKkuI7un6yuLyXzt9F+GwC+vT6zBof8X+AX0Tevv61s4t+6v0Q+j3oIc3X1ha1McMq9B/Cv301uKtbeYXRqB/DN37tcWtlX/95GMr9KfQ49svvLhD3qI3CDEFoHdv31jZ3iaGOegL0PUAxZd/ThEteRejl0zVLKr5f/ph2C2c4EGj2upOmDkyaWuC7sigjnpSr44GznEZfIyXSf1k4ceUvqqUaeU7ZTLc8gHWCFevdJYJDXu9uY3hEl2AwsIwBCVIQtg7UhL8I9MFn+Iteotjy0XviHd9cbmk8asjJlaKStRbIjOFDfw+X5BKWcV9LK4oyln40XA/2ILlRQUertc8YFRN0QMsqguPe0uCPFmYKpR2h92l7LDiliRvrvRwslB6OOyWFAWrtMeRIuJvbJyuxaxDzNog5vVVLzPwARdKsch9QmOyVHpYLLqLOIlq8UllSmoGnJSvEfy5Ms1OFvhU1ie5ucEn+STEoQzDd314fKaQQyQSj8TwxZQajwPF2lMIz6hSavo/UWr+MpQ2fClKLceRfo5SK2K2cEptJ1Pq+wJCjxnOnsDwbpXh3RMYbvwPhnn6MpJA2f0MxSEQHTESZEkU6RSNxf2SVfJbJSvdO9ylu4e36D09/Ux/iB3VfWlsXmAfoVabyFaZuKN7KFUTEULIbQt0QHxcJrrHg3Xk9/D9F4BdHnSjJHTYoiMdQA8wBijABnAb+B7wBvAO8AHwIWC6jMjMiIwisow1mfAwu2hmPgFiP0t1RZjv/CfptelEfPbrA08eDd660p25tJUS2X3PV+4sz70y08EeHKQDs3cXNopTEg5ACeKnf0P89aSVR645jly7X2OB4nk6PK/RKqUkaxK/5+kPD/MifZl+k3aLB2l6Hc2Vc8i5iKlcOMlLZdIELswgk3NhBg9kHzaMOvBhq/JhAx+2Iz5s4MMGPmzgwwY+bODDBj5s4MMGPmzgwwY+bODDBj5sVT4I4jviBNGpRMg+yYp4Ew6VnvNUSMz0tt1YO/yjSE3Li55UPkhzTfGx6OI1hK/Qy/OzwWynk/MhVT5jKfaI9JGZPdKK1sujb7VwbpActVttxSmMOI2RXwVkO2R7TQ7idHy+CyOfG3gMHv2Y7AGHNBkRfG1m3JqHOT2CGl1bhKV8Wg87usIzESHV1Q/Vw1ijKATOKanQpZFwMDcX6lDGoh1DM8GeqzlZpB3ja32R+Xz4zJCSiBRyoeDgpD/2fJ+fsd6ZpNMWHE11DZ5xGAyN/oF0ZCjY2NStZIcX+prt0Xyyeyhw2mQU28/GYgNygxgd5/fnqDyjnzIziZMR8voeKGhUT9z3udPvkQBv52AigNPVA8371TGxj7TWYpsDkIE0MALMAavATeC7wGvA28AD4JeA6TKK47cQPgXY5arnPOfNAd40SKNm+NRYbT3IwmQ/Pcp7nRkMOjhvmSSE52jKTCM0Za1yXHfMble/NpMW6+ankr2temf8QsqbTbRemQgMp3x6Jjk8Bqd4ijZH+tpio3EXLbhTE4lgT3uDK9zTO5AOGuhS/qI7mHC2tDbUCcwknY3lcvb2SNO5FrtIaZ25gY4Gu31mV2RAuSrnM212KeToSLYYNUzfYOa8NlWe0j+AVzdYGdhDHvGa4BnVfJxRjeCwEYdtBp8iZBEygdzCq7CNK4CRV72URpXXUiiTSGd8ZupDCvmlfoHz0knfY02ZS72h6X7ZlZ7tLdwyiqavTmUuxJz0jcNVoS0zFkxcSLoOUtcuRNpzy9mepbEAXZqfnZWHlHx6rs/rz84itAzCHEctC8S5p/5h4DcuWBAN7wdE7QdJa0ZkHx2ksQwfdQ/7DbOQGKns4adaLzGcguFEfDTxqt9He3wCoAvWkTchlKpKIzaYiAXwAjEgC0wCC8A2sAvUIz0sKC0Xd/UmcWG3q+pqH8KTqsJdueDKBVcuuHLBlQuuXHDlgisXXLlUVy1wZUFkfkToR6LJeIQFiVaNNwJrBMdtwYoEz0d+dt5r3IAesKtbKNFjyx6JggMu8V6ZtNZq2P5fIr89rc4XoTpcos6XyojOUL8cSnuMoiPY6w9mJJNokfujvYUGZprq9aTCHh1j7OCQ+kITz/maY9n2wwd0pH0w0XI63C8fvkeng7l481C6Z5DZ5YTnFZwdOZepTNK/I+dOkyB5p0zCCNRBnGq+OXAa3ov5yG+G4SBhyAZwwW1H+cdlXtsGjHK1X8vo1/JRv5bRr2X0axn9Wka/ltGvZfRrGf1aRr+W0a9l9GsZ/VpGvwa3/P3FM1lCOPwNKqm82WtSLO60Jj0o79q7rEqQz5ppk486Iq/pcWa7Pp2azrR4eqaSZ851yQYm/unKjebURDwxHm9yxsZLNDsyGzp/LX32Wj7gDPa03TuYKH/rdmJ+OBDIKYlOZbST56sK4XeDr11t6H1GrcKfYSE///526/HoqEwiox9Br1fj5RPYJ7xVCRG3ZvXwR5V5zSXVE585+hjpU5KgDlzDXZKmn5A06weWiATZgbkmcodkBAPJsCa1zprRCF4m96mG3mERdpfdF9aFf6pejWQTz20Dqv838KKF+D7mqtHbas/W4lVFJoZm83NzofzK5s2VnY2lxYmVl1Y6Zzd3bixe2Fhb3+HRVb2Qyg/4/50TPkbYBHIGl5pE9x4meXIRZTODHED1k9C/AesArfoKZW5kc3RyZWFtCmVuZG9iagoxNSAwIG9iagoyMTc2CmVuZG9iagoxNiAwIG9iago8PCAvVHlwZSAvRm9udERlc2NyaXB0b3IgL0FzY2VudCA5MzEgL0NhcEhlaWdodCA3MjMgL0Rlc2NlbnQgLTIxMyAvRmxhZ3MgMzIKL0ZvbnRCQm94IFstMzM3IC0yMTkgMTExMSA5MzFdIC9Gb250TmFtZSAvTkJVSFZWK0hlbHZldGljYU5ldWUtVWx0cmFMaWdodAovSXRhbGljQW5nbGUgMCAvU3RlbVYgMjAgL0xlYWRpbmcgMjcgL01heFdpZHRoIDExMjYgL1N0ZW1IIDIwIC9YSGVpZ2h0IDUyMAovRm9udEZpbGUyIDE0IDAgUiA+PgplbmRvYmoKMTcgMCBvYmoKWyAyNzggMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDY0OCAwIDQ4MSAwIDAgMCAwIDAgMCAwIDAgMCA1NzQgMCAwIDYxMSAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDQ4MSAwCjAgMCA1MDAgMCAwIDAgMCAwIDAgMTMwIDc3OCAwIDAgNTM3IF0KZW5kb2JqCjggMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvTkJVSFZWK0hlbHZldGljYU5ldWUtVWx0cmFMaWdodAovRm9udERlc2NyaXB0b3IgMTYgMCBSIC9XaWR0aHMgMTcgMCBSIC9GaXJzdENoYXIgMzIgL0xhc3RDaGFyIDExMiAvRW5jb2RpbmcKL01hY1JvbWFuRW5jb2RpbmcgPj4KZW5kb2JqCjE4IDAgb2JqCjw8IC9MZW5ndGggMTkgMCBSIC9MZW5ndGgxIDgzMzIgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBrVl7bFvXeT/nXJKSSPElihSpy6cokuJDEiWKD4kSKdqULEuyLT9iiY5fsiLHcu1EecxIgBZ1gS5DhS1pi+7VbkuWJluTIo2bwoUiDImXdU0bbKtXrMUaGEaLokPQDmgWtAuWxNR+3728spw4Qf4IiY/3nHPvPef7vvP7XoeMM8Za2UUmsfGl84ur/BviCEb+BfS9pQsPBlk7vox/EX3d6dW7zydtu/4Z/a8wJi7ffe7h08433k3h1ixjnYUzy4t3/XcqnGbM/3k8nzuDAcNPJDP6/4B+95nzDz40/VXDv6H/c/T/4ty9S4v3/fRTbzAWeAj9vecXH1oV49Ih9H+AfvCexfPLQzv3PIs+nmGp1XsfeFC3R/enuAWe2D2r9y+vrjLjYfRpvWYQx5c+rczA1nENsvnGiDJ8y49AT7pl5MM6OtzQY8YmZQ3GWpQHjcyEdRiDfPhYQFZmU9rv/7GzNuaAHp3MxTqYm3lYJx6RmZf5mJ8FwGWIdbEw62YR0jcYT82ss5a5hW9z/mhtnW/+4Tqr+l7EutKJ473rjKeCwYmV6iV+Eh2RwkAihJaUCk5ekiKTBxbCteBacG33XWvByeCZxbsu6SLKFTeW12r9wUvs4MIKfg8thC6N1+St5nKtNoJ5dDQPXsHjazXMcLYxA67KUP8NPKRPzQQvSdG5hf0Lly5W5Uvj1ZocCgUnLl2ZW7h0pSqHajU8ZdjiFBx/ZsXd4LkJPBsSuN+sznIQc2CK2toazYmeiIYuXVlbk9cgiTISDq1z1hiApPSMFJlY5+NzC3RrPBySaSAcCofAR62KuVtSMwcXJsBJiDgxfrRKTVuM4tlWsGdSVGr+hFRq+TgqtX4sldq2OL1FpXbwbCOVtt1epeGPUOiWhsdvo+GLqoYv3kbDjm0aJswLNggTfAWGJcFWTLBAfT/g1J8eiITsoYg9ZOcb9Yv8Yv0h/sVm/mZzHW/Qh7Njmw+xy+wsrCiwoQxISaDaBoBcBfVjphbMxDBTPuzMuCyiyVmSspcPJbi+ta3VFXKZzp41+WSXLmnwRpIuZYpF/NKcEpM3FCegzsk2FKunjmRLDxR5Nrx46NBZPMzE5jv4+Yx4DXwZYZ94QuGfWCC2DIzeYnhLFhLP5EMdGf7cY2vP1X8xdZhPzO+uv8Hd/J76l/kLN3LXr2MafDiLbr4lnhA/Y3F2fgOmblImCdoqMuYLwiMEWRSUA02CDoNOgy6AHgH9GejvQN8FfR9kPlbRs5+g8SuQOAZpZHgd4ku2bWDGiNI2gEee6ZPCXRbhbPeLzGBJ5MMW9PtEdqiEvl+IA9Wm7L7FzKHPHkok8FO+ezbdVNV3j8wN7jpdCQQqp3fFdhXj/K3C4aJ/7O5HpqcfOT3WM312R/pgqTtXu2+kuFrLdaQqtO9T+PkjCNwMH/eZddYBdRkhPLFlxC52gPTXANBrYP518PtrkDgGFbSg4QHFQcOg3aAaaAX0MOgLoL8EPQN6EfRDkJmkboFmafoWSM2wmLYzDnumxLND0ZhkJyGd7RYRnnr7608//fXvfGnPvVNdXVP37hGv3cjpnn/hhed1N1bF4dDU/XNz90+FaK9IjhHIYWIZWkKVoAXc665iTZ2yJq0HT6wgYQMS65V2MzTusIeyALpCU/yt+gH+aP1+/gwtN8I7R7gY0dYwY40WBi01NdZowhriKhDHFaQ1bc0PzClt2lHIps1e5Yfrz/LP0dT8kDozzb0H030Jc0usYzvMlXlV+6E59lTpPTyGjyqzFx092Z6+wY/ehneIQVVmKGBLvin+H/VVRSaBtIADtUy8i/ctbH77mhtQYrPCuglbREHSZG8bbnBCfkG1aHjaxioMt0mfnKktc6Olyp1x4AvewyY+WRW/H/+dqN71v28rcqzc+HNB9NqNR8X9qky7wNPD4MnEZm7liUI4bR3puxlkvAoi/8LBEXHFQE23cGS8lQ8OHuxhvqsq+BOzVVE/qfBw9MZTuD4ljtL6qj3UsH4z4v0X1pkHE/IGaMireUBtsAe9ag962INeswc97EEPe9DDHvSwBz3sQQ970MMe9LAHPexBD3vQwx70sAc97EH1lSbCjxFL3WobrQ0sKXocdDnbDWEORZJLyA71ifAf/3rXwsKu+o+r/5feW/D7C3vT/BzvnpqenuLHga5BOTubTs9mZdrrEHzZAfiyCvtbMgMywQ0kLl3KEmHsc4ESGWzkOiv0K7ZegGwFTbYCZCtAtgJkK0C2AmQrQLYCZCtAtgJkK0C2AmQrQLaCIpv52gbrbWzCOuvFBrmhOzN0uPMarHKs4ZfHsHwPMira3h6gNR82KI5PR1L28z5Jc3wdGRK74RkD3C8pTgKe8UxVis+eK5ePjIUdel9mZ/Rbrpjf7h+ohKMT2ZCoJqdOZmdO5tvlVDHwuGcoKUeHd3gHDpe7f7Pj+KivI9LX29OaKiV9xqTe1hnx9ORCVmd8LJ4/WPAmS5OdiZEed3PM4PCn/LF82OZITSsqrECn54AVD5mbB0MkgAfCtMJqqN2q2iIaeMDRkNah2GPDtWcBSXJ05N3tlcDOlemZlZ2Bqje3d3Bgbw7GXc/nl6aTyemlPP9hfbI0n/d48vMljj3kSsw7gvWbsLhqB2QDEtYyNJSeHkC042EpLBl48z7eMvVf4g0F9a/d+Jz4LOE9uPkWrwsHy2JT/34D8HAonFcgRaqB+5Qa8SqIeBVEvAoiXgW+o4KIV0HEqyDiVRDxKoh4FUS8CiJeBRGvokW8CiJeBUAi3DlYRcEYMcqBBfLQ/qsg9KmdQzuF6wzhYxQZN6lxFMwMwJ9Re4C0h0ChhYgmC0DQCJMZpZHLZw3hrqy9ARW9hhECUb7E87mymB31DkScpnZ/e2ZpX1ruL3dH88mwXehtPrfZbmoxRbpy1a7e6XyQ7/EN7Oh2JYKO3sk7esxdBn66PNzijgednVaDMJiDY7nYcMRu6Yx52kNusxBZXZS3DVW6ze2JHQ8fiI4mXBY54o7GXaYmYTRBA9D5KHDjxr65oeLn1lkfNszdQI8bsgvoQJCtoK1DW4d2H9qt0BeNuTDmwlgr2h7VD3lgqx7NVj1oemCrHtiqB9vqga16YKse2KoHtuqBrXpgqx7Yqge26lFslWYOkx8iMPuBKdK2H5q3wzapbVdwm8lm/FB+wwPBFJvCdq4huJGfjI4I11K5OD/i9Y7MF72FdMQo+HFHfLx3cCLpcCQnBnvH4w7C4ancSHJmCRCfSVl8CS/vqRd69pVisdK+nsaVXFUXMPobYDRMeZi3gUqvikovUOkFKr1ApReo9AKVXqDSC1R6gUovUOkFKr1ApReo9Gqo9AKVXqgMOOtABCQJOyCtDhUdtSlqIg/jmrfJDOZuTcNc/Btl0wMHi3eWgsHSncWFVXNZ6uwZ8vVWezs68FOe5KdqC6nppUIBBrxyPJiLuaKlffH4vlJ0h4oDyi8FcNDJ+tjL66wfiueABy1PsUaAtP3vR9tyFYR9p3E32m48j01nXLEoGu3EaCeesKAtX1PyVBn6kaEfGfqRoR8Z+pGhHxn6kaEfGfqRoR8Z+pGhH1nTjwz9yNCPul6EkEEZTqLhIBLQVQsSWWK2BboKUWx9X9qacfIGIjQbFKIsjJF03rcFjuHBmFHU//qD4Kj/pzfhs6RUdCRtvoTnFBfvB4dQsPEmsGGEjCcoc3EpLFHmQiU+sUd2YgJxaIfaflzJ3zC0A2gH+oGBLghLD3cpiFfrBTvaHFOqGwI8hEoS+R19KHczDKnAAE76BH++/oLOkxiNwew76t/hfyLc+YXSWK0gy4Xa2KlPtZeteyd6xxMOHg3vzAQCmR213Mr+wf49pzKwgOTJhdGp6MhuwgaHBwcGgA1Zzc3aFSYkcNwOot2ndiftCqUo1kZyZFU4VsVWijA8ZMLDJohLfSfaJHbHVUiTDatx1dWRVXHu4yjRkGBw6bQweztNLrPVbYkOeI0LC2X+o2yvs1u2SSInhKunEOrP1gf4j8Ar7UGG0x4kWIn90zorfwSOy1h8O45VX6aa4E0ck3yE4bSK4TQ2NY39TQPDaWA4DQyngeE0MJwGhtPAcBoYTgPDaWA4rWE4DQyntzA8QpUA2QLtJ9VcLYh61KZKJNnAdRJYjtjDzluwnMtnKPnCFsfCfkCgJGIUsLeBm79ZFi2hRMZXmC8GOocXSsN3uMTehc7BuE9flmLF6Vh5Puf5VWo80e5IjPf2lnvanIlSgr9ec0Z9tviuE9n84lR8JD15/C6TO+aLF6NtXeNHp8PD07GePaORaGk2GpseDqvYKAIbVKR2sv0byoEUCdEJIVBhKQLZoLtOEEUSuqreQvHtZMXkRjZQ76kJtRMveoA4yt3VjF1FuRNIUGKoAS6+WOYdYCqa8beW21K7c/mjbfBcSDJ7o5V+2Z0YDtVf4rN90xnvcD8PABNjYPXT4JHOE2LbM3kVgOTXCMEGQrCavWNtZybbhFXHyuWyeG15+fs33hM61Pa/3NzRmMvJdn74XO1a9GqGPZBKqEzQ0G9FuxWLtuIkQl0HG2qIxpyDLiWa0aLtkaa2ZpPTFEp6WtT1XwomOedDoiM25BMZssubcn1UnTYG/m/WaaMwSD3so4f9+63cm69VJPYyNo0fQ+MxrfFbtaFX9hMHBxTYJTanjFIpjg2lF3+LrKHxYqPxsjpCL7rhm93ai3SbIgKdYpiZTYkXpP0oFBIFFGLYLEkZlTGauKb4ekKJ6l3CDaSEcZN0Sl6E2j54EapKNTvQmi4FOuEuQxP5FcAnO1puixR7/AmPqWwO5uLVXPmbmSMdloOZ8n6PJHQ33uPB+ETG1x7u76w/ybu7dw4Fdo7Xn+bHLw9m4GDT82CQMxX3DkAeKOgknj8u7j+I+Q9Deva2SCcOb4P0GnhQ/N9bwoj9dUCRr6KEgdrioDA26pOrE3ugcA8U78HMVtUvWuEXrfBnVvhFK/yiFX7RCr9ohV+0wi9a4Ret8ItW+EUr/KJV84tW+EUrwAF/aESuR2o0wgvQ2Ty12+EDuXYE03B0+W3nUVSWcZeW6GhXLRNqXPl1LdvRrlktGUI1Q0kR/n6gXHgHcmEHsJpi31RzYfJyxAZBjDwYXbU8iPJgC/RKYzdjB2tUrhQzPqmMWLEBqtrU7NcB/fgbqacf+iHcZ9RYoNTiCsw/kAgr2U7Bq2U75SWX4EtarmNPTA4pibDuRokHvQmvRcuFi7lT9bqW66TmRruREENXUehKQFeUL15W80X8e6PoioK65vGpdqC2prPtuePNaKBG2E8uS6SZlSyR6oebmeH2jDE9oH9/ZEVJhnxDcyCNOkLgJM8YGxze0psvTyVE/UlNc1oJ8ZJ45VRn3G/TskQLlFj/Ob+iqW5bDQEfzIvCgkwf7NGfR4QwCTybr4LUcyTiW42JVIoy3KBz64aH68hGVU/mzUwmJ5fdQnFbjvjEoCzKUrX8MOaEjwqgVnkFe1RkzxBgAso6VEYhwCptjrYJ437F39IRmnLorfRc6smLC9Wci3w3nbK6EJxdqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcqOZcMPJ1FoONUM47iGsM1zGqp+XGcY963pxX2Hn/efPNU5Uocp2tSm/7KQy/ryz8mZ2xrolC2BUbCux3xoMOOTHQUb5DV26+787u6WK0M56VD9miQaerO+mU0xEXP490p93WVYiFegPO5ja9xRnoQGVsrIyfOGyLFBNdg11OnUNnbvc5PV3OFrM3qeizafNd3iIeh1gPfLA6MmCLaA+bcKX6xwVpaT8p1XVoFYutccZsg+J1OHSjjdfhAdpfOuJWAYC4iraWmurRbqfolkUmiJzYgCQhl8G5Qh/P2jPZJ8pHjvDBssVrkeUu+4rQfe1r2frjOwZEVhLhAD+aVbFQBBauI4NxU55280zog3Lc9GTbq7mtrI2iF50gNTdyVDqxpnpLMZdojFp0AkJZKr9ebouOxGfGRLk9OTEwcsIDnNb/JzYzEp6a5HP1b/dNDcr5oWOKbvEfDv9X8PdR50cyzzjo/Ei8uvMfK0+IJwn1mLHI8Wcy4V2hi0+88/YJ6+jvuV2i/3vZ9x5bDWhXZG8ZZD8/Q78FPkz94D3p1c0k8+lO1Z/ZrOkmlJkaN5VLlP+ODXKYBugYaFFc2HxHXGFR8RybEvtBHpz5X2d76CrhPAr3dokLGL/AQnimIvbj+SYWFCU2imsXrlG6cokZRAp9D2z0ReRzL27+kq6YY5TGlHv0Dp7nRTbKf8ECvIc10T3UOySBF99JdpKtsff4Sf5lfoW/zt8RVfF58ab0Vel16T3dd/V79RuGo4YfNPmbftrc07y3+SvN32o50PI3xlHjj02rpqdaZ1ufbX3H7MVspMMo+zRmDoJUDSESo3kZ91QNtzX0Y6C0Z+/c3L4KjjSXz11YfnBlaXHv8h8s986u3H3mwcbbbPOv6P+823yiGJMQ+u34xzqKbKUHjiXF+lEkDbAMy+HYdphV2QSk2wXt7mbTbIbN4r+Jfcg+97MD7CA7xO5AljHPFhiSHxgQjIkl/x9NC1daCmVuZHN0cmVhbQplbmRvYmoKMTkgMCBvYmoKNDkxMAplbmRvYmoKMjAgMCBvYmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgOTY3IC9DYXBIZWlnaHQgNzIyIC9EZXNjZW50IC0yMTMgL0ZsYWdzIDMyCi9Gb250QkJveCBbLTM0MyAtMjE0IDEwOTMgOTY3XSAvRm9udE5hbWUgL05QUE9BRCtIZWx2ZXRpY2FOZXVlLUxpZ2h0IC9JdGFsaWNBbmdsZQowIC9TdGVtViA2OCAvTGVhZGluZyAyOSAvTWF4V2lkdGggMTEyMiAvU3RlbUggNTggL1hIZWlnaHQgNTI0IC9Gb250RmlsZTIgMTggMCBSCj4+CmVuZG9iagoyMSAwIG9iagpbIDI3OCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwCjYzMCAwIDcwNCA2ODUgNTkzIDUzNyAwIDAgMjIyIDAgMCA1MzcgODMzIDcwNCAwIDYzMCAwIDAgNjMwIDAgNjg1IDU5MyAwIDAKMCAwIDAgMCAwIDAgMCAwIDUxOSA1NzQgNTE5IDU3NCA1MTkgMjU5IDU1NiA1MzcgMTg1IDE4NSAwIDE4NSA4MzMgNTM3IDU1Ngo1NzQgNTc0IDMxNSA0ODEgMjk2IDUzNyA0NjMgXQplbmRvYmoKMTAgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvTlBQT0FEK0hlbHZldGljYU5ldWUtTGlnaHQgL0ZvbnREZXNjcmlwdG9yCjIwIDAgUiAvV2lkdGhzIDIxIDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAxMTggL0VuY29kaW5nIC9NYWNSb21hbkVuY29kaW5nCj4+CmVuZG9iagoyMiAwIG9iago8PCAvTGVuZ3RoIDIzIDAgUiAvTGVuZ3RoMSA1MDU2IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AbVYa2xb1R0/517b1zfX1/EjfsWP+MaPWyd2Hr6NnYRgO5HTpkmA0KatzUhp1uZVWpptoTwmRAVj0jJpRQixFdCExDTgw1imqVvI9qGaNrR1ExQhBtr6YZs2aUNoQojXBLX3O/fagW6F8WHY+t97zrnnnvP//37/x7EJJYTYyGnCk9KRE/Orvc6BKYz8jhDqOnJqLUra8CX0TxgzLa4uneh27P4V+n8lhDu3dPyuxfmB92J49Dgh8sbywvzRNyKxPkJc05ifW8aAMGd5Df2voR9fPrF2Z+xucjf6T6M/ffzkkfngWuRh9N9Gf8eJ+TtXuR5+PyHuEPrR2+ZPLLzm+3UE/RH0s6snv7JGf8+9gf4q+hOrX15YXSUtB9DfRN8Kofiyjw1Ni9761IsxuTmFazauuPPEtN03o3XFsgIGrCJpkbClbCethDiIc3v659xwfZb1wR/ASU9tEnGm8iNKv1XdpPUHNkk5/BwRCX/LocwmoelodHylvEEPo8OlMdCloMWno7s2+MSuvZVYNboeXd9zdD26K7o8f3TDlNDveLCwXu2NbpB9lRVcZyvKRqka3G4uVKvDWMfE1sErmL5exQrHGivgrg/1XsYkc3oqusEnZyo3VjZOl4MbpXI1qCjR8Y3zM5WN8+WgUq1ilmVbU2h8z4q/obMAnS1deG41VtmHNbBEdX2drYkel1Q2zq+vB9dhiT4SUzYpaQzAUjaHT4xv0tJMhT0qxZQgG4gpMQV6VMtYW0xP7auMQxOFadLy6ZBK24pirg3qSTqk8v8JUvtngbT1M0Hq2Nb0Ckid0NnBIHVdHdLYpwC6jXDpKgifNhA+fRWE3R9DmPk2R7KI418gLnkiEInAS3rhTr19/QnFqSScipNu1U7T07U76YNW+qa1hjfYhxIfrveTY3ivlWzhihW6QbOjr/8amo/5Zv37j2GMIwho7hHuAvKFl3xpC5s49YmCY9RM/oDO6xBubjSIUHGSACQFGYLsgVQhK5C7IN+AnIU8A3kO8huIPLdJ/JewvwyN2P6yYwu72vU2gS5uXskWuIGdPVyMurWsp83OqU88RlsOP3QkGywtX1e7eN+Tryb33lvlLlzO7brjsdnRlanU5VXuwKuT37y1xHId038J+oukA+jQXra+0Fh/C6mK19sWfS/NreQVyHfPlvfQL0i1p/L0ARtbmc4OU254G497dDyC5PYtgGIs5jXwEICH0MRDAB4C8BCAhwA8BOAhAA8BeAjAQwAeAvAQgIcAPAQdj/Al6GmHnldi4tjGJEi1bIRjUMQkqgGVBkDfKb6kDCQ9wb5S4vVHy2Mf5m4aTYS18RQ9TuNypD+uXtvlpYdgTLbjmoP51FjGz/xgHPjcC3sEEsS+vI6PwQVxAC+I+SJ4EDQeW+VvtL1zpnzmHYAyDJQfZJAQrv5+/S36W85NSmSWvLdJ9sMFD0DylxDUl3Q/kYCL1MRFAi4ScJGAiwRcJOAiARcJuEjARQIuEnCRgIsEXCQdl/1QxXsRAhU7gHve6RrC+hiNYzSOUZXkibQ9msFoBlp4MWPyEhzUQibx2iRJQnKQXZADkEXIKcjXIY9Avg/5CeR5iDwH9V9B428Qbg6eOg6cmKeOw1NHmP+gPcK8RyvwBi8WwZIU7LynLcJp2VzeZ6cer5YtUjuNdSYHdha4fIHXPbrTzpkFNtoDD9eH84WiOZzORVxqh6ejI7JPi5Wy4UD3SDz3xSBHKTcQDIiCJEhek1UWTVKLEM8V21OTwyrNtrUemvZ2Rd1dhd1hmxINW+mxaCZoszjCPq3LaqVWiyc+mErmOh39GU6wC3lzP6WC3eZPDnU7M7097li6vaUtVbrv4PjeFl8skMr4BI5yFknUOSZ2cPwPcCyRLvKvTdINZNMQBzgWDY5FcCw2ORbBsQiORXAsgmMRHIvgWATHIjgWwbEIjkVwLIJjUeeYgDOCVbvBWTva7WinDO5S4C4F7lLgLgXuUuAuBe5S4C4F7lLgLgXuUuAuBe5STe5S4C4FtVBksKKN6YzVZbRl+EwUxxERPgNm4ySssxkHs54Gsx60KXIfY5mCZaowlr2eNotZKdAmi542EJzLx5pc0mdqP7R2aqPq2BStPUUf5rl2baJ3bHkicevS3Fp70VUpJocSLpqMj2kd14+1uEu+tDczORAevPn2wuLazZWh3SA95mXxiSMMPYT49JFuxKcHKssN3ViuZMczQ7dN4oRJLGbdiFek8HwBecLry/fAwSytNKZHMA3ZFlvFZLrF3SI5os5Sweao2m5aLC7SFwcmkjETt9PMjQ1NDdT66YuMd1p/F5e/YP8O8lUGi6xv5zGynQzG5SbjMhiXGexgXAbjMhiXwbgMxmUwLoNxGYzLYFwG47LOuMKyHaOcQpywrh2nVGZRO6yLMPtADqsDmvuj+EInZ2BvEWLuM2cLQy07cqVOjxpxmfiJ4m6rr2uoc/hwkCvqyVvsvyEfafHG2uWgrfZjOrXDkxhQHMUeGkfugn3kBdj38fpJUD+R8fICNjrjLXqP3VY4yV1YWHj+8oecycCk8Q6ruExz/Q02+2zhUbYnFjTm8WbETC/5YJP0YVo/pA8USaBKQtvwQoxjLIpI8huR5Aeu/iaufuDqB65+4OoHrn7g6geufuDqB65+4OoHrn7g6geufh3XZvREsXIYu4Wxm4S2akSTimhSEU0qoklFNKmIJhXRpCKaVESTimhSEU0qoklFNKnNaFIRTSpUa9htx7JBsNbVYK0LW1ghHmzJ2jFWOxrcIWoAKJKfHkAMWxZBSXinENOdVFDzR28rDLYksoXOnpRloqhJkcy1Ka3Xsqc4wZvKU8NzEc48lhs+HOLaONPlD6klc8NwZy7pb69t/DN7cDSZTQaCtWfpjCNsH5ku9OXzhQx308f92A0/PvG5+fF/+/BH1rOKbWFGf+S5zNqreu58mHPp9n2S5x5iNnH1l+tjnBP+5Sc72FnETkJ66NiN6AzBi0JNLwrBi0LwohC8KAQvCsGLQvCiELwoBC8KwYtC8KIQvCgELwrpXtTFopOdmdx4nUWlG1GpIFmztsKqHgzSImC0cQZhXOZ9LEHidGJUu2PfLhQ5cyQ9GBldnlT9/Xuy5YMK1/a93eVQfl9ufCoyNAtbCzTRkQnJI7fcMdJ7fb5jSJtLVsZ6F2ZzM+N9S/vzBoc11KBzsHeEPMmOceyYsoWCpOnqMO9m6c9jxJAG67Wm9RrU12C9Bus1WK/Beg3Wa7Beg/UarNdgvQbrNVivwXp2ytAa54kOuDmLT7Z+10UI66NdYGfXwUY+HgQ2CeQvhk0C2ORjFnYCMJBRe1DzC+hGOEHL4TiL4o8TgsUAqocrFLhobncyMTmSUPqvCXqRygKJjKe9R3FxRRrsL6c6yoNxv5rNZtVAINnjCQ6kAk/3j6fbHImRdLyv0yeJLm/IFex0W+VQVyRT3OFydA4koxnF1+YOdLYH4j7JFsGvBcDWVn8Lpd0EA1dYOfHoKssO/YwkIzPIyAwyMoOMzCAjM8jIDDIyg4zMICMzyMgMMjKDjMzA0rh+RpKRGVgxaGQGlsutDTSsQENxx3g7b5x1cnl0YLpxQNIE+tDJ4pC0Y6AY+48UbgRC7T0jgccDSOD0uto5PYG3FnoOIWuz+viSXh+DsKeI3T0gJ4zd/3edRAIGiX4Qys65IeSqT6qb+UY1+MT6+UdWJk4WT16ljn7QLBw69gx/suvZnwVuaR15hzr5vzPX/uWZ1Y7mnUU1qsYF/PbCaYqN4oN3+J/Wu0nIdLi2VN9rmsJ7rxiPGlc3fZtkKTsyeImP+wExcwHIKUiajHNC/X1OIHYKvLgAat5zhvCj9XdZnyvUX6Z/rtfwThv9OcMUCSBE+siDZJNG6Ri3k3uT7+Of4Lf4F0wPm2rmU5Z2y2nLa0wv5Ia7wANqaUNb/BuG5jk8Y0/ZCYbd2d9CUUJm9o9OV0a7JxaOn1pYWzkyf/3C7QuZ6ZWl5bU9a/PHV45gHmyu49+u+uPst+1VPm6M8fjxqOoBnSdlMoGQniLT5AYyQ24k++CxFXIef0AgEEn3vwHogcgHCmVuZHN0cmVhbQplbmRvYmoKMjMgMCBvYmoKMzA0OQplbmRvYmoKMjQgMCBvYmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgOTUxIC9DYXBIZWlnaHQgNzIyIC9EZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}},{"type":"file","file":{"filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}}]}],"stream":false,"temperature":0.7}' headers: User-Agent: - Faraday v2.13.4 @@ -89,7 +89,7 @@ http_interactions: message: OK headers: Date: - - Wed, 20 Aug 2025 17:05:59 GMT + - Fri, 01 Aug 2025 10:51:47 GMT Content-Type: - application/json Transfer-Encoding: @@ -101,13 +101,13 @@ http_interactions: Openai-Organization: - "" Openai-Processing-Ms: - - '2145' + - '6187' Openai-Project: - proj_KyS64Yhsc9qhhwjNcgkOa88E Openai-Version: - '2020-10-01' X-Envoy-Upstream-Service-Time: - - '2186' + - '6206' X-Ratelimit-Limit-Requests: - '500' X-Ratelimit-Limit-Tokens: @@ -275,16 +275,16 @@ http_interactions: encoding: ASCII-8BIT string: | { - "id": "chatcmpl-C6gY1WyAxB0R2544aUGnOovpIcP5y", + "id": "chatcmpl-BzheWL0l7Obj4YeNlcRgIvnapd1PY", "object": "chat.completion", - "created": 1755709557, + "created": 1754045508, "model": "gpt-4.1-nano-2025-04-14", "choices": [ { "index": 0, "message": { "role": "assistant", - "content": "The two documents you've provided are essentially identical in both their parsed text content and visual appearance. Both are titled \"Sample PDF\" and contain the same text, which is a generic placeholder with lorem ipsum and other filler content. \n\n**Key observations:**\n- The *parsed text* for both pages is identical, including phrasing and sentence structure.\n- The *visual layout* of the pages appears to be the same, as indicated by the identical sampled content.\n- There are no apparent differences in formatting, images, infographics, or diagrams based on the provided data.\n\n**Summary:**\nThese documents are duplicates of each other. If you need a more detailed comparison, such as checking for subtle formatting differences or embedded images not captured in the parsed text, I can examine their visual images further. But from the provided information, they are the same document repeated twice.", + "content": "Certainly! To provide a comprehensive comparison, here's a detailed breakdown:\n\n### Content Comparison:\n- **Text Content:** Both documents contain the same placeholder \"Lorem ipsum\" text, with identical phrasing, paragraph structure, and sequence. There are no differences in wording, punctuation, or formatting based on the parsed text.\n- **Purpose:** Given the placeholder text and the title \"Sample PDF,\" these documents appear to be templates or dummy files used for ing or layout purposes.\n\n### Visual and Structural Elements:\n- **Pages:** Both are labeled as page 1 of 1, indicating they are single-page documents.\n- **Images:** While the parsed text doesn't specify visual content, the mention of images in the file search suggests that there might be images embedded within these pages. Since both pages are similar, if images are present, they are probably identical or serve the same purpose in both files.\n- **Formatting:** The structure (paragraphs, spacing) appears consistent between the two, but without visual inspection of images or layout, this can't be confirmed.\n\n### Additional Insights:\n- The files might be copies or versions of the same template, used for demonstration or ing.\n- No unique identifiers, annotations, or differentiating features are present in the parsed text to distinguish one from the other.\n\n### Next Steps:\n- If you want, I can analyze embedded images or visual elements to see if they contain any differences or additional information.\n- Alternatively, if you have specific aspects you'd like compared (e.g., layout, images, annotations), please specify.\n\nLet me know how you'd like to proceed!", "refusal": null, "annotations": [] }, @@ -293,9 +293,9 @@ http_interactions: } ], "usage": { - "prompt_tokens": 1721, - "completion_tokens": 173, - "total_tokens": 1894, + "prompt_tokens": 1993, + "completion_tokens": 317, + "total_tokens": 2310, "prompt_tokens_details": { "cached_tokens": 0, "audio_tokens": 0 @@ -308,29 +308,16 @@ http_interactions: } }, "service_tier": "default", - "system_fingerprint": "fp_c4c155951e" + "system_fingerprint": "fp_38343a2f8f" } - recorded_at: Wed, 20 Aug 2025 17:05:59 GMT + recorded_at: Fri, 01 Aug 2025 10:51:57 GMT - request: method: post uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":[{"type":"text","text":"Compare - these documents"},{"type":"file","file":{"filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}},{"type":"file","file":{"filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}}]},{"role":"assistant","content":"The - two documents you''ve provided are essentially identical in both their parsed - text content and visual appearance. Both are titled \"Sample PDF\" and contain - the same text, which is a generic placeholder with lorem ipsum and other filler - content. \n\n**Key observations:**\n- The *parsed text* for both pages is - identical, including phrasing and sentence structure.\n- The *visual layout* - of the pages appears to be the same, as indicated by the identical sampled - content.\n- There are no apparent differences in formatting, images, infographics, - or diagrams based on the provided data.\n\n**Summary:**\nThese documents are - duplicates of each other. If you need a more detailed comparison, such as - checking for subtle formatting differences or embedded images not captured - in the parsed text, I can examine their visual images further. But from the - provided information, they are the same document repeated twice."},{"role":"user","content":"go - on"}],"stream":false}' + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Compare + these documents"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}],"status":"completed"}],"stream":false,"temperature":0.7}' headers: User-Agent: - Faraday v2.12.2 @@ -348,37 +335,31 @@ http_interactions: message: OK headers: Date: - - Wed, 20 Aug 2025 17:06:02 GMT + - Tue, 05 Aug 2025 05:38:55 GMT Content-Type: - application/json Transfer-Encoding: - chunked Connection: - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID - Openai-Organization: - - "" - Openai-Processing-Ms: - - '2430' - Openai-Project: - - proj_KyS64Yhsc9qhhwjNcgkOa88E - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '2581' X-Ratelimit-Limit-Requests: - - '500' + - '30000' X-Ratelimit-Limit-Tokens: - - '200000' + - '150000000' X-Ratelimit-Remaining-Requests: - - '499' + - '29999' X-Ratelimit-Remaining-Tokens: - - '198232' + - '149998487' X-Ratelimit-Reset-Requests: - - 120ms + - 2ms X-Ratelimit-Reset-Tokens: - - 530ms + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 X-Request-Id: - "" Openai-Processing-Ms: @@ -404,42 +385,217 @@ http_interactions: - h3=":443"; ma=86400 body: encoding: ASCII-8BIT - string: | + string: |- { - "id": "chatcmpl-C6gY4n4fCLts91f9DIo0LREbWQZgR", - "object": "chat.completion", - "created": 1755709560, + "id": "resp_689198ee93fc819fbab1e8554b2e8e0e0d7837304feb8e1f", + "object": "response", + "created_at": 1754372334, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, "model": "gpt-4.1-nano-2025-04-14", - "choices": [ + "output": [ { - "index": 0, - "message": { - "role": "assistant", - "content": "Since the documents are visually and textually identical based on the provided parsed content and image overview, there are no notable differences to highlight. Both contain the same placeholder text (\"Lorem ipsum\" and similar filler content), the same structure, and no additional visual elements such as images or diagrams that differ.\n\n**Additional considerations:**\n- If there are any subtle differences, such as formatting styles, font changes, or embedded images that weren't captured in the parsed text, I can review the images of the pages more closely.\n- If you want, I can analyze the rendered images of these pages to identify any unnoticed variations or embedded visuals that aren't reflected in the text.\n\nPlease specify if you'd like me to:\n- Perform a more detailed visual analysis\n- Identify any embedded images or diagrams\n- Review for minor formatting differences\n\nLet me know how you'd like to proceed!", - "refusal": null, - "annotations": [] - }, - "logprobs": null, - "finish_reason": "stop" + "id": "msg_689198eee844819fb89dad91ef4b851c0d7837304feb8e1f", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "The two documents you've provided are identical in content. Both are titled \"Sample PDF\" and contain the same text, which includes a brief introduction, multiple paragraphs of placeholder text (\"Lorem ipsum\" and similar sentences), and identical formatting. \n\nIn summary:\n- Both documents have the same title.\n- The textual content in both is exactly the same.\n- No differences in the phrasing, structure, or formatting are apparent.\n\nIf you need a more detailed comparison (such as differences in formatting, layout, or metadata), please specify!" + } + ], + "role": "assistant" } ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", "usage": { - "prompt_tokens": 1904, - "completion_tokens": 171, - "total_tokens": 2075, - "prompt_tokens_details": { - "cached_tokens": 1792, - "audio_tokens": 0 + "input_tokens": 1492, + "input_tokens_details": { + "cached_tokens": 0 }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 + "output_tokens": 107, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 1599 + }, + "user": null, + "metadata": {} + } + recorded_at: Tue, 05 Aug 2025 05:38:55 GMT +- request: + method: post + uri: https://api.openai.com/v1/responses + body: + encoding: UTF-8 + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Compare + these documents"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"},{"type":"input_file","filename":"sample.pdf","file_data":"data:application/pdf;base64,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ZXNjZW50IC0yMTMgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTQwOSAtMjE0IDEwOTkgOTUxXSAvRm9udE5hbWUgL1BVQUxYQStIZWx2ZXRpY2FOZXVlLUxpZ2h0SXRhbGljCi9JdGFsaWNBbmdsZSAtMTIgL1N0ZW1WIDY3IC9MZWFkaW5nIDI4IC9NYXhXaWR0aCAxMTIwIC9TdGVtSCA1OCAvWEhlaWdodCA1MjQKL0ZvbnRGaWxlMiAyMiAwIFIgPj4KZW5kb2JqCjI1IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDY4NSAwIDUzNyAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAgNTU2IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDUxOQowIDAgMCA1MTkgMjU5IDAgNTM3IDE4NSAwIDAgMTg1IDgzMyA1MzcgMCA1NzQgMCAwIDQ4MSAwIDUzNyAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNDQ0IF0KZW5kb2JqCjkgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1RydWVUeXBlIC9CYXNlRm9udCAvUFVBTFhBK0hlbHZldGljYU5ldWUtTGlnaHRJdGFsaWMKL0ZvbnREZXNjcmlwdG9yIDI0IDAgUiAvV2lkdGhzIDI1IDAgUiAvRmlyc3RDaGFyIDMyIC9MYXN0Q2hhciAyMjIgL0VuY29kaW5nCi9NYWNSb21hbkVuY29kaW5nID4+CmVuZG9iagoxIDAgb2JqCjw8IC9UaXRsZSAoc2FtcGxlKSAvQXV0aG9yIChQaGlsaXAgSHV0Y2hpc29uKSAvQ3JlYXRvciAoUGFnZXMpIC9Qcm9kdWNlciAoTWFjIE9TIFggMTAuNS40IFF1YXJ0eiBQREZDb250ZXh0KQovQ3JlYXRpb25EYXRlIChEOjIwMDgwNzAxMDUyNDQ3WjAwJzAwJykgL01vZERhdGUgKEQ6MjAwODA3MDEwNTI0NDdaMDAnMDAnKQo+PgplbmRvYmoKeHJlZgowIDI2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAxNzkzMCAwMDAwMCBuIAowMDAwMDAzOTgyIDAwMDAwIG4gCjAwMDAwMDUwNzMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAzOTYyIDAwMDAwIG4gCjAwMDAwMDQwODYgMDAwMDAgbiAKMDAwMDAwNTAzNyAwMDAwMCBuIAowMDAwMDA3OTU3IDAwMDAwIG4gCjAwMDAwMTc3NDAgMDAwMDAgbiAKMDAwMDAxMzY5MiAwMDAwMCBuIAowMDAwMDA0MjA5IDAwMDAwIG4gCjAwMDAwMDUwMTcgMDAwMDAgbiAKMDAwMDAwNTE1NiAwMDAwMCBuIAowMDAwMDA1MjA2IDAwMDAwIG4gCjAwMDAwMDc0NzIgMDAwMDAgbiAKMDAwMDAwNzQ5MyAwMDAwMCBuIAowMDAwMDA3NzU1IDAwMDAwIG4gCjAwMDAwMDgxNDYgMDAwMDAgbiAKMDAwMDAxMzE0NiAwMDAwMCBuIAowMDAwMDEzMTY3IDAwMDAwIG4gCjAwMDAwMTM0MjQgMDAwMDAgbiAKMDAwMDAxMzg3NyAwMDAwMCBuIAowMDAwMDE3MDE2IDAwMDAwIG4gCjAwMDAwMTcwMzcgMDAwMDAgbiAKMDAwMDAxNzMwMiAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDI2IC9Sb290IDEzIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8NGU5NDk1MTVhYWYxMzI0OThmNjUwZTdiZGU2Y2RjMmY+Cjw0ZTk0OTUxNWFhZjEzMjQ5OGY2NTBlN2JkZTZjZGMyZj4gXSA+PgpzdGFydHhyZWYKMTgxMzIKJSVFT0YK"}],"status":"completed"},{"type":"message","role":"assistant","content":"The + two documents you''ve provided are identical in content. Both are titled \"Sample + PDF\" and contain the same text, which includes a brief introduction, multiple + paragraphs of placeholder text (\"Lorem ipsum\" and similar sentences), and + identical formatting. \n\nIn summary:\n- Both documents have the same title.\n- + The textual content in both is exactly the same.\n- No differences in the + phrasing, structure, or formatting are apparent.\n\nIf you need a more detailed + comparison (such as differences in formatting, layout, or metadata), please + specify!","status":"completed"},{"type":"message","role":"user","content":"go + on","status":"completed"}],"stream":false,"temperature":0.7}' + headers: + User-Agent: + - Faraday v2.12.2 + Authorization: + - Bearer + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Aug 2025 05:38:57 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Ratelimit-Limit-Requests: + - '30000' + X-Ratelimit-Limit-Tokens: + - '150000000' + X-Ratelimit-Remaining-Requests: + - '29999' + X-Ratelimit-Remaining-Tokens: + - '149998372' + X-Ratelimit-Reset-Requests: + - 2ms + X-Ratelimit-Reset-Tokens: + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - proj_j3YWwie2yjmMHTGYtUxoTOJ7 + X-Request-Id: + - "" + Openai-Processing-Ms: + - '1514' + X-Envoy-Upstream-Service-Time: + - '1521' + X-Envoy-Decorator-Operation: + - tasksapi.openai.svc.cluster.local:8081/* + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cf-Cache-Status: + - DYNAMIC + Set-Cookie: + - "" + - "" + X-Content-Type-Options: + - nosniff + Server: + - cloudflare + Cf-Ray: + - "" + Alt-Svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: |- + { + "id": "resp_689198f028c08191bae36b834dc3652c04e8e1935d2f9f4f", + "object": "response", + "created_at": 1754372336, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-4.1-nano-2025-04-14", + "output": [ + { + "id": "msg_689198f081408191a2a308f650711a7404e8e1935d2f9f4f", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Since the textual content of both documents is identical, the main differences could potentially lie in other aspects such as:\n\n- **Formatting and layout:** Font styles, sizes, colors, margins, or spacing.\n- **Metadata:** Information embedded in the PDF such as author, title, keywords.\n- **Images or graphics:** Presence or absence of visual elements.\n- **Annotations or comments:** Any added notes or highlights.\n- **File properties:** Creation date, modification date, file size.\n\nHowever, based solely on the textual content you've provided, there are no differences. If you can upload or specify if there are other elements or details you'd like to compare, I can assist further. Would you like me to analyze specific features beyond the text?" + } + ], + "role": "assistant" } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null }, + "safety_identifier": null, "service_tier": "default", - "system_fingerprint": "fp_c4c155951e" + "store": true, + "temperature": 0.7, + "text": { + "format": { + "type": "text" + } + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", + "usage": { + "input_tokens": 1608, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 148, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 1756 + }, + "user": null, + "metadata": {} } - recorded_at: Wed, 20 Aug 2025 17:06:02 GMT -recorded_with: VCR 6.3.1 + recorded_at: Tue, 05 Aug 2025 05:38:57 GMT +recorded_with: VCR 6.3.1 \ No newline at end of file From 9133c7c478042af7e13cf7b653bbfe43681a9120 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Tue, 26 Aug 2025 18:06:00 -0700 Subject: [PATCH 25/27] Cleanup some comments and deprecated stuff --- lib/ruby_llm/providers/openai/streaming.rb | 25 +++------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/lib/ruby_llm/providers/openai/streaming.rb b/lib/ruby_llm/providers/openai/streaming.rb index 99de9d0af..166e35937 100644 --- a/lib/ruby_llm/providers/openai/streaming.rb +++ b/lib/ruby_llm/providers/openai/streaming.rb @@ -26,46 +26,30 @@ def build_chunk(data) def build_responses_chunk(data) case data['type'] - when 'response.text.delta' - # Text content delta - deprecated format - Chunk.new( - role: :assistant, - model_id: data.dig('response', 'model'), - content: data['delta'], - tool_calls: nil, - input_tokens: nil, - output_tokens: nil - ) when 'response.output_text.delta' - # Text content delta - new format Chunk.new( role: :assistant, - model_id: nil, # Model is in the completion event + model_id: nil, content: data['delta'], tool_calls: nil, input_tokens: nil, output_tokens: nil ) when 'response.function_call_arguments.delta' - # Tool call arguments delta - handled by accumulator - # We need to track these deltas to build up the complete tool call build_tool_call_delta_chunk(data) when 'response.output_item.added' - # New tool call or message starting if data.dig('item', 'type') == 'function_call' build_tool_call_start_chunk(data) else build_empty_chunk(data) end when 'response.output_item.done' - # Tool call or message completed if data.dig('item', 'type') == 'function_call' build_tool_call_complete_chunk(data) else build_empty_chunk(data) end when 'response.completed' - # Final response with usage stats Chunk.new( role: :assistant, model_id: data.dig('response', 'model'), @@ -75,7 +59,6 @@ def build_responses_chunk(data) output_tokens: data.dig('response', 'usage', 'output_tokens') ) else - # Other event types (response.created, response.in_progress, etc.) build_empty_chunk(data) end end @@ -92,8 +75,6 @@ def build_chat_completions_chunk(data) end def build_tool_call_delta_chunk(data) - # For tool call argument deltas, we need to create a partial tool call - # The accumulator will handle building up the complete arguments tool_call_data = { 'id' => data['item_id'], 'function' => { @@ -152,10 +133,10 @@ def build_tool_call_complete_chunk(data) ) end - def build_empty_chunk(data) + def build_empty_chunk(_data) Chunk.new( role: :assistant, - model_id: data.dig('response', 'model'), + model_id: nil, content: nil, tool_calls: nil, input_tokens: nil, From 6cda94f618b31e64f9cd9c8650e01ed4db56f21d Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Thu, 28 Aug 2025 12:16:26 -0700 Subject: [PATCH 26/27] Fix model id in responses API payload --- lib/ruby_llm/providers/openai/response.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ruby_llm/providers/openai/response.rb b/lib/ruby_llm/providers/openai/response.rb index 2433bd694..bb060d662 100644 --- a/lib/ruby_llm/providers/openai/response.rb +++ b/lib/ruby_llm/providers/openai/response.rb @@ -13,7 +13,7 @@ def responses_url def render_response_payload(messages, tools:, temperature:, model:, stream: false, schema: nil) # rubocop:disable Metrics/ParameterLists payload = { - model: model, + model: model.id, input: format_input(messages), stream: stream } From 27213bcb1d87dd5266df1ab20cc581e4dd4714b4 Mon Sep 17 00:00:00 2001 From: Paul Shippy Date: Fri, 17 Oct 2025 08:19:38 -0700 Subject: [PATCH 27/27] Fix some broken specs after merge --- gemfiles/rails_7.1.gemfile.lock | 9 +- gemfiles/rails_7.2.gemfile.lock | 9 +- gemfiles/rails_8.0.gemfile.lock | 9 +- .../providers/openai/response_media.rb | 2 +- ...config_default_when_no_model_specified.yml | 131 +++++++++++------- ...figured_associates_messages_with_model.yml | 131 +++++++++++------- 6 files changed, 180 insertions(+), 111 deletions(-) diff --git a/gemfiles/rails_7.1.gemfile.lock b/gemfiles/rails_7.1.gemfile.lock index 712b50dc0..4af638276 100644 --- a/gemfiles/rails_7.1.gemfile.lock +++ b/gemfiles/rails_7.1.gemfile.lock @@ -148,6 +148,7 @@ GEM concurrent-ruby (~> 1.1) webrick (~> 1.7) websocket-driver (~> 0.7) + ffi (1.17.2-arm64-darwin) ffi (1.17.2-x86_64-linux-gnu) fiber-annotation (0.2.0) fiber-local (1.1.0) @@ -180,7 +181,7 @@ GEM ruby-vips (>= 2.0.17, < 3) iniparse (1.5.0) io-console (0.8.1) - io-event (1.14.0) + io-event (1.11.2) irb (1.15.2) pp (>= 0.6.0) rdoc (>= 4.0.0) @@ -224,6 +225,8 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.4) + nokogiri (1.18.10-arm64-darwin) + racc (~> 1.4) nokogiri (1.18.10-x86_64-linux-gnu) racc (~> 1.4) os (1.1.4) @@ -239,7 +242,7 @@ GEM pp (0.6.3) prettyprint prettyprint (0.2.0) - prism (1.5.2) + prism (1.6.0) pry (0.15.2) coderay (~> 1.1) method_source (~> 1.0) @@ -356,6 +359,7 @@ GEM simplecov (~> 0.19) simplecov-html (0.13.2) simplecov_json_formatter (0.1.4) + sqlite3 (2.7.4-arm64-darwin) sqlite3 (2.7.4-x86_64-linux-gnu) stringio (3.1.7) thor (1.4.0) @@ -382,6 +386,7 @@ GEM zeitwerk (2.7.3) PLATFORMS + arm64-darwin-22 x86_64-linux DEPENDENCIES diff --git a/gemfiles/rails_7.2.gemfile.lock b/gemfiles/rails_7.2.gemfile.lock index 21a8f902a..206e930d4 100644 --- a/gemfiles/rails_7.2.gemfile.lock +++ b/gemfiles/rails_7.2.gemfile.lock @@ -142,6 +142,7 @@ GEM concurrent-ruby (~> 1.1) webrick (~> 1.7) websocket-driver (~> 0.7) + ffi (1.17.2-arm64-darwin) ffi (1.17.2-x86_64-linux-gnu) fiber-annotation (0.2.0) fiber-local (1.1.0) @@ -174,7 +175,7 @@ GEM ruby-vips (>= 2.0.17, < 3) iniparse (1.5.0) io-console (0.8.1) - io-event (1.14.0) + io-event (1.11.2) irb (1.15.2) pp (>= 0.6.0) rdoc (>= 4.0.0) @@ -217,6 +218,8 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.4) + nokogiri (1.18.10-arm64-darwin) + racc (~> 1.4) nokogiri (1.18.10-x86_64-linux-gnu) racc (~> 1.4) os (1.1.4) @@ -232,7 +235,7 @@ GEM pp (0.6.3) prettyprint prettyprint (0.2.0) - prism (1.5.2) + prism (1.6.0) pry (0.15.2) coderay (~> 1.1) method_source (~> 1.0) @@ -349,6 +352,7 @@ GEM simplecov (~> 0.19) simplecov-html (0.13.2) simplecov_json_formatter (0.1.4) + sqlite3 (2.7.4-arm64-darwin) sqlite3 (2.7.4-x86_64-linux-gnu) stringio (3.1.7) thor (1.4.0) @@ -376,6 +380,7 @@ GEM zeitwerk (2.7.3) PLATFORMS + arm64-darwin-22 x86_64-linux DEPENDENCIES diff --git a/gemfiles/rails_8.0.gemfile.lock b/gemfiles/rails_8.0.gemfile.lock index eeb0a61cc..2929b3c7b 100644 --- a/gemfiles/rails_8.0.gemfile.lock +++ b/gemfiles/rails_8.0.gemfile.lock @@ -142,6 +142,7 @@ GEM concurrent-ruby (~> 1.1) webrick (~> 1.7) websocket-driver (~> 0.7) + ffi (1.17.2-arm64-darwin) ffi (1.17.2-x86_64-linux-gnu) fiber-annotation (0.2.0) fiber-local (1.1.0) @@ -174,7 +175,7 @@ GEM ruby-vips (>= 2.0.17, < 3) iniparse (1.5.0) io-console (0.8.1) - io-event (1.14.0) + io-event (1.11.2) irb (1.15.2) pp (>= 0.6.0) rdoc (>= 4.0.0) @@ -217,6 +218,8 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.4) + nokogiri (1.18.10-arm64-darwin) + racc (~> 1.4) nokogiri (1.18.10-x86_64-linux-gnu) racc (~> 1.4) os (1.1.4) @@ -232,7 +235,7 @@ GEM pp (0.6.3) prettyprint prettyprint (0.2.0) - prism (1.5.2) + prism (1.6.0) pry (0.15.2) coderay (~> 1.1) method_source (~> 1.0) @@ -350,6 +353,7 @@ GEM simplecov (~> 0.19) simplecov-html (0.13.2) simplecov_json_formatter (0.1.4) + sqlite3 (2.7.4-arm64-darwin) sqlite3 (2.7.4-x86_64-linux-gnu) stringio (3.1.7) thor (1.4.0) @@ -377,6 +381,7 @@ GEM zeitwerk (2.7.3) PLATFORMS + arm64-darwin-22 x86_64-linux DEPENDENCIES diff --git a/lib/ruby_llm/providers/openai/response_media.rb b/lib/ruby_llm/providers/openai/response_media.rb index 0b592320a..e852f5e1c 100644 --- a/lib/ruby_llm/providers/openai/response_media.rb +++ b/lib/ruby_llm/providers/openai/response_media.rb @@ -50,7 +50,7 @@ def format_pdf(pdf) def format_text_file(text_file) { type: 'input_text', - text: Utils.format_text_file_for_llm(text_file) + text: text_file.for_llm } end diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_default_model_uses_config_default_when_no_model_specified.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_default_model_uses_config_default_when_no_model_specified.yml index a5d8099ef..146175650 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_default_model_uses_config_default_when_no_model_specified.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_default_model_uses_config_default_when_no_model_specified.yml @@ -2,10 +2,10 @@ http_interactions: - request: method: post - uri: https://api.openai.com/v1/chat/completions + uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"Hello"}],"stream":false}' + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false}' headers: User-Agent: - Faraday v2.13.4 @@ -23,41 +23,37 @@ http_interactions: message: OK headers: Date: - - Wed, 24 Sep 2025 14:38:04 GMT + - Fri, 17 Oct 2025 15:13:36 GMT Content-Type: - application/json Transfer-Encoding: - chunked Connection: - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID - Openai-Organization: - - "" - Openai-Processing-Ms: - - '277' - Openai-Project: - - proj_61L3Oqt640dKU0CASS2iOj8Q - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '312' X-Ratelimit-Limit-Requests: - - '500' + - '30000' X-Ratelimit-Limit-Tokens: - - '200000' + - '150000000' X-Ratelimit-Remaining-Requests: - - '499' + - '29999' X-Ratelimit-Remaining-Tokens: - - '199996' + - '149999975' X-Ratelimit-Reset-Requests: - - 120ms + - 2ms X-Ratelimit-Reset-Tokens: - - 1ms + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" X-Request-Id: - "" - X-Openai-Proxy-Wasm: - - v0.1 + Openai-Processing-Ms: + - '691' + X-Envoy-Upstream-Service-Time: + - '695' Cf-Cache-Status: - DYNAMIC Set-Cookie: @@ -75,42 +71,73 @@ http_interactions: - h3=":443"; ma=86400 body: encoding: ASCII-8BIT - string: | + string: |- { - "id": "chatcmpl-CJKv6KuZLAK9jlgkWIFpRXp9JkPFd", - "object": "chat.completion", - "created": 1758724684, + "id": "resp_050ad34b5d85b1c90068f25d1fa1f48192b26e4bad35834641", + "object": "response", + "created_at": 1760714015, + "status": "completed", + "background": false, + "billing": { + "payer": "developer" + }, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, "model": "gpt-4.1-nano-2025-04-14", - "choices": [ + "output": [ { - "index": 0, - "message": { - "role": "assistant", - "content": "Hello! How can I assist you today?", - "refusal": null, - "annotations": [] - }, - "logprobs": null, - "finish_reason": "stop" + "id": "msg_050ad34b5d85b1c90068f25d2022a8819296f867cdaa022b0f", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Hello! How can I assist you today?" + } + ], + "role": "assistant" } ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", "usage": { - "prompt_tokens": 8, - "completion_tokens": 9, - "total_tokens": 17, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 + "input_tokens": 8, + "input_tokens_details": { + "cached_tokens": 0 }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 18 }, - "service_tier": "default", - "system_fingerprint": "fp_04d3664870" + "user": null, + "metadata": {} } - recorded_at: Wed, 24 Sep 2025 14:38:04 GMT + recorded_at: Fri, 17 Oct 2025 15:13:36 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/activerecord_actsas_model_associations_when_model_registry_is_configured_associates_messages_with_model.yml b/spec/fixtures/vcr_cassettes/activerecord_actsas_model_associations_when_model_registry_is_configured_associates_messages_with_model.yml index e27494e78..5cbc7b720 100644 --- a/spec/fixtures/vcr_cassettes/activerecord_actsas_model_associations_when_model_registry_is_configured_associates_messages_with_model.yml +++ b/spec/fixtures/vcr_cassettes/activerecord_actsas_model_associations_when_model_registry_is_configured_associates_messages_with_model.yml @@ -2,10 +2,10 @@ http_interactions: - request: method: post - uri: https://api.openai.com/v1/chat/completions + uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4.1-nano","messages":[{"role":"user","content":"Hello"}],"stream":false}' + string: '{"model":"gpt-4.1-nano","input":[{"type":"message","role":"user","content":"Hello","status":"completed"}],"stream":false}' headers: User-Agent: - Faraday v2.13.4 @@ -23,41 +23,37 @@ http_interactions: message: OK headers: Date: - - Wed, 24 Sep 2025 14:38:05 GMT + - Fri, 17 Oct 2025 15:17:39 GMT Content-Type: - application/json Transfer-Encoding: - chunked Connection: - keep-alive - Access-Control-Expose-Headers: - - X-Request-ID - Openai-Organization: - - "" - Openai-Processing-Ms: - - '335' - Openai-Project: - - proj_61L3Oqt640dKU0CASS2iOj8Q - Openai-Version: - - '2020-10-01' - X-Envoy-Upstream-Service-Time: - - '349' X-Ratelimit-Limit-Requests: - - '500' + - '30000' X-Ratelimit-Limit-Tokens: - - '200000' + - '150000000' X-Ratelimit-Remaining-Requests: - - '499' + - '29999' X-Ratelimit-Remaining-Tokens: - - '199996' + - '149999972' X-Ratelimit-Reset-Requests: - - 120ms + - 2ms X-Ratelimit-Reset-Tokens: - - 1ms + - 0s + Openai-Version: + - '2020-10-01' + Openai-Organization: + - "" + Openai-Project: + - "" X-Request-Id: - "" - X-Openai-Proxy-Wasm: - - v0.1 + Openai-Processing-Ms: + - '1360' + X-Envoy-Upstream-Service-Time: + - '1364' Cf-Cache-Status: - DYNAMIC Set-Cookie: @@ -75,42 +71,73 @@ http_interactions: - h3=":443"; ma=86400 body: encoding: ASCII-8BIT - string: | + string: |- { - "id": "chatcmpl-CJKv7Gcqxstzh7GR4o5oM2PKTvOec", - "object": "chat.completion", - "created": 1758724685, + "id": "resp_0502a32699d3cd470068f25e12719081979a533b3bf3249ca1", + "object": "response", + "created_at": 1760714258, + "status": "completed", + "background": false, + "billing": { + "payer": "developer" + }, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, "model": "gpt-4.1-nano-2025-04-14", - "choices": [ + "output": [ { - "index": 0, - "message": { - "role": "assistant", - "content": "Hello! How can I assist you today?", - "refusal": null, - "annotations": [] - }, - "logprobs": null, - "finish_reason": "stop" + "id": "msg_0502a32699d3cd470068f25e1366bc8197af8a3704ba787e64", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Hello! How can I assist you today?" + } + ], + "role": "assistant" } ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": null, + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1.0, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 1.0, + "truncation": "disabled", "usage": { - "prompt_tokens": 8, - "completion_tokens": 9, - "total_tokens": 17, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 + "input_tokens": 8, + "input_tokens_details": { + "cached_tokens": 0 }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } + "output_tokens": 10, + "output_tokens_details": { + "reasoning_tokens": 0 + }, + "total_tokens": 18 }, - "service_tier": "default", - "system_fingerprint": "fp_7c233bf9d1" + "user": null, + "metadata": {} } - recorded_at: Wed, 24 Sep 2025 14:38:05 GMT + recorded_at: Fri, 17 Oct 2025 15:17:39 GMT recorded_with: VCR 6.3.1