From 4f5068e7e52a3bd1b38d2621cb63b05b23e2a395 Mon Sep 17 00:00:00 2001 From: Josh Pigford Date: Tue, 27 May 2025 05:04:58 -0500 Subject: [PATCH] feat(assistant): improve chat functionality and update tests - refactor configurable model, update OpenAI provider, enhance chat form UI, and improve test coverage (#2316) Updated model to GPT 4.1 --- app/models/assistant/configurable.rb | 9 +++------ app/models/provider/openai.rb | 2 +- app/views/messages/_chat_form.html.erb | 2 +- test/controllers/chats_controller_test.rb | 2 +- test/controllers/messages_controller_test.rb | 4 ++-- test/fixtures/messages.yml | 8 ++++---- test/models/assistant_message_test.rb | 2 +- test/models/assistant_test.rb | 14 +++++++------- test/models/chat_test.rb | 2 +- test/models/provider/openai_test.rb | 2 +- test/models/user_message_test.rb | 2 +- .../vcr_cassettes/openai/chat/basic_response.yml | 4 ++-- .../openai/chat/basic_streaming_response.yml | 8 ++++---- .../vcr_cassettes/openai/chat/function_calls.yml | 8 ++++---- .../openai/chat/streaming_function_calls.yml | 16 ++++++++-------- 15 files changed, 41 insertions(+), 44 deletions(-) diff --git a/app/models/assistant/configurable.rb b/app/models/assistant/configurable.rb index a0fb981c..b28fc523 100644 --- a/app/models/assistant/configurable.rb +++ b/app/models/assistant/configurable.rb @@ -30,8 +30,7 @@ module Assistant::Configurable ## Your purpose - You help users understand their financial data by answering questions about their accounts, - transactions, income, expenses, net worth, and more. + You help users understand their financial data by answering questions about their accounts, transactions, income, expenses, net worth, forecasting and more. ## Your rules @@ -66,11 +65,9 @@ module Assistant::Configurable ### Rules about financial advice - You are NOT a licensed financial advisor and therefore, you should not provide any specific investment advice (such as "buy this stock", "sell that bond", "invest in crypto", etc.). + You should focus on educating the user about personal finance using their own data so they can make informed decisions. - Instead, you should focus on educating the user about personal finance using their own data so they can make informed decisions. - - - Do not suggest investments or financial products + - Do not tell the user to buy or sell specific financial products or investments. - Do not make assumptions about the user's financial situation. Use the functions available to get the data you need. ### Function calling rules diff --git a/app/models/provider/openai.rb b/app/models/provider/openai.rb index 1268203a..8049f074 100644 --- a/app/models/provider/openai.rb +++ b/app/models/provider/openai.rb @@ -4,7 +4,7 @@ class Provider::Openai < Provider # Subclass so errors caught in this provider are raised as Provider::Openai::Error Error = Class.new(Provider::Error) - MODELS = %w[gpt-4o] + MODELS = %w[gpt-4.1] def initialize(access_token) @client = ::OpenAI::Client.new(access_token: access_token) diff --git a/app/views/messages/_chat_form.html.erb b/app/views/messages/_chat_form.html.erb index 0c536c94..0f7c1ce9 100644 --- a/app/views/messages/_chat_form.html.erb +++ b/app/views/messages/_chat_form.html.erb @@ -8,7 +8,7 @@ data: { chat_target: "form" } do |f| %> <%# In the future, this will be a dropdown with different AI models %> - <%= f.hidden_field :ai_model, value: "gpt-4o" %> + <%= f.hidden_field :ai_model, value: "gpt-4.1" %> <%= f.text_area :content, placeholder: "Ask anything ...", value: message_hint, class: "w-full border-0 focus:ring-0 text-sm resize-none px-1 bg-transparent", diff --git a/test/controllers/chats_controller_test.rb b/test/controllers/chats_controller_test.rb index 8f8b6eed..a3f7f58e 100644 --- a/test/controllers/chats_controller_test.rb +++ b/test/controllers/chats_controller_test.rb @@ -14,7 +14,7 @@ class ChatsControllerTest < ActionDispatch::IntegrationTest test "creates chat" do assert_difference("Chat.count") do - post chats_url, params: { chat: { content: "Hello", ai_model: "gpt-4o" } } + post chats_url, params: { chat: { content: "Hello", ai_model: "gpt-4.1" } } end assert_redirected_to chat_path(Chat.order(created_at: :desc).first, thinking: true) diff --git a/test/controllers/messages_controller_test.rb b/test/controllers/messages_controller_test.rb index c79cb174..5f6d21e5 100644 --- a/test/controllers/messages_controller_test.rb +++ b/test/controllers/messages_controller_test.rb @@ -7,7 +7,7 @@ class MessagesControllerTest < ActionDispatch::IntegrationTest end test "can create a message" do - post chat_messages_url(@chat), params: { message: { content: "Hello", ai_model: "gpt-4o" } } + post chat_messages_url(@chat), params: { message: { content: "Hello", ai_model: "gpt-4.1" } } assert_redirected_to chat_path(@chat, thinking: true) end @@ -15,7 +15,7 @@ class MessagesControllerTest < ActionDispatch::IntegrationTest test "cannot create a message if AI is disabled" do @user.update!(ai_enabled: false) - post chat_messages_url(@chat), params: { message: { content: "Hello", ai_model: "gpt-4o" } } + post chat_messages_url(@chat), params: { message: { content: "Hello", ai_model: "gpt-4.1" } } assert_response :forbidden end diff --git a/test/fixtures/messages.yml b/test/fixtures/messages.yml index 9a0e3ea5..cf3c6df8 100644 --- a/test/fixtures/messages.yml +++ b/test/fixtures/messages.yml @@ -16,20 +16,20 @@ chat1_user: type: UserMessage content: Can you help me understand my spending habits? chat: one - ai_model: gpt-4o + ai_model: gpt-4.1 created_at: 2025-03-20 12:00:01 chat2_user: type: UserMessage content: Can you help me understand my spending habits? - ai_model: gpt-4o + ai_model: gpt-4.1 chat: two created_at: 2025-03-20 12:00:01 chat1_assistant_reasoning: type: AssistantMessage content: I'm thinking... - ai_model: gpt-4o + ai_model: gpt-4.1 chat: one created_at: 2025-03-20 12:01:00 reasoning: true @@ -37,7 +37,7 @@ chat1_assistant_reasoning: chat1_assistant_response: type: AssistantMessage content: Hello! I can help you understand your spending habits. - ai_model: gpt-4o + ai_model: gpt-4.1 chat: one created_at: 2025-03-20 12:02:00 reasoning: false diff --git a/test/models/assistant_message_test.rb b/test/models/assistant_message_test.rb index 9e737d41..1e85aa21 100644 --- a/test/models/assistant_message_test.rb +++ b/test/models/assistant_message_test.rb @@ -6,7 +6,7 @@ class AssistantMessageTest < ActiveSupport::TestCase end test "broadcasts append after creation" do - message = AssistantMessage.create!(chat: @chat, content: "Hello from assistant", ai_model: "gpt-4o") + message = AssistantMessage.create!(chat: @chat, content: "Hello from assistant", ai_model: "gpt-4.1") message.update!(content: "updated") streams = capture_turbo_stream_broadcasts(@chat) diff --git a/test/models/assistant_test.rb b/test/models/assistant_test.rb index 1af4b0b7..428c3fe3 100644 --- a/test/models/assistant_test.rb +++ b/test/models/assistant_test.rb @@ -8,14 +8,14 @@ class AssistantTest < ActiveSupport::TestCase @message = @chat.messages.create!( type: "UserMessage", content: "What is my net worth?", - ai_model: "gpt-4o" + ai_model: "gpt-4.1" ) @assistant = Assistant.for_chat(@chat) @provider = mock end test "errors get added to chat" do - @assistant.expects(:get_model_provider).with("gpt-4o").returns(@provider) + @assistant.expects(:get_model_provider).with("gpt-4.1").returns(@provider) error = StandardError.new("test error") @provider.expects(:chat_response).returns(provider_error_response(error)) @@ -28,7 +28,7 @@ class AssistantTest < ActiveSupport::TestCase end test "responds to basic prompt" do - @assistant.expects(:get_model_provider).with("gpt-4o").returns(@provider) + @assistant.expects(:get_model_provider).with("gpt-4.1").returns(@provider) text_chunks = [ provider_text_chunk("I do not "), @@ -38,7 +38,7 @@ class AssistantTest < ActiveSupport::TestCase response_chunk = provider_response_chunk( id: "1", - model: "gpt-4o", + model: "gpt-4.1", messages: [ provider_message(id: "1", text: text_chunks.join) ], function_requests: [] ) @@ -63,7 +63,7 @@ class AssistantTest < ActiveSupport::TestCase end test "responds with tool function calls" do - @assistant.expects(:get_model_provider).with("gpt-4o").returns(@provider).once + @assistant.expects(:get_model_provider).with("gpt-4.1").returns(@provider).once # Only first provider call executes function Assistant::Function::GetAccounts.any_instance.stubs(:call).returns("test value").once @@ -71,7 +71,7 @@ class AssistantTest < ActiveSupport::TestCase # Call #1: Function requests call1_response_chunk = provider_response_chunk( id: "1", - model: "gpt-4o", + model: "gpt-4.1", messages: [], function_requests: [ provider_function_request(id: "1", call_id: "1", function_name: "get_accounts", function_args: "{}") @@ -88,7 +88,7 @@ class AssistantTest < ActiveSupport::TestCase call2_response_chunk = provider_response_chunk( id: "2", - model: "gpt-4o", + model: "gpt-4.1", messages: [ provider_message(id: "1", text: call2_text_chunks.join) ], function_requests: [] ) diff --git a/test/models/chat_test.rb b/test/models/chat_test.rb index 29435b5a..cb1a4448 100644 --- a/test/models/chat_test.rb +++ b/test/models/chat_test.rb @@ -22,7 +22,7 @@ class ChatTest < ActiveSupport::TestCase prompt = "Test prompt" assert_difference "@user.chats.count", 1 do - chat = @user.chats.start!(prompt, model: "gpt-4o") + chat = @user.chats.start!(prompt, model: "gpt-4.1") assert_equal 1, chat.messages.count assert_equal 1, chat.messages.where(type: "UserMessage").count diff --git a/test/models/provider/openai_test.rb b/test/models/provider/openai_test.rb index f9cf3117..bb29523f 100644 --- a/test/models/provider/openai_test.rb +++ b/test/models/provider/openai_test.rb @@ -5,7 +5,7 @@ class Provider::OpenaiTest < ActiveSupport::TestCase setup do @subject = @openai = Provider::Openai.new(ENV.fetch("OPENAI_ACCESS_TOKEN", "test-openai-token")) - @subject_model = "gpt-4o" + @subject_model = "gpt-4.1" end test "openai errors are automatically raised" do diff --git a/test/models/user_message_test.rb b/test/models/user_message_test.rb index 32aff7d4..66d9fb42 100644 --- a/test/models/user_message_test.rb +++ b/test/models/user_message_test.rb @@ -8,7 +8,7 @@ class UserMessageTest < ActiveSupport::TestCase test "requests assistant response after creation" do @chat.expects(:ask_assistant_later).once - message = UserMessage.create!(chat: @chat, content: "Hello from user", ai_model: "gpt-4o") + message = UserMessage.create!(chat: @chat, content: "Hello from user", ai_model: "gpt-4.1") message.update!(content: "updated") streams = capture_turbo_stream_broadcasts(@chat) diff --git a/test/vcr_cassettes/openai/chat/basic_response.yml b/test/vcr_cassettes/openai/chat/basic_response.yml index 5a6df1af..e70f98a4 100644 --- a/test/vcr_cassettes/openai/chat/basic_response.yml +++ b/test/vcr_cassettes/openai/chat/basic_response.yml @@ -5,7 +5,7 @@ http_interactions: uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4o","input":[{"role":"user","content":"This is a chat + string: '{"model":"gpt-4.1","input":[{"role":"user","content":"This is a chat test. If it''s working, respond with a single word: Yes"}],"instructions":null,"tools":[],"previous_response_id":null,"stream":null}' headers: Content-Type: @@ -69,7 +69,7 @@ http_interactions: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-4o-2024-08-06", + "model": "gpt-4.1-2024-08-06", "output": [ { "type": "message", diff --git a/test/vcr_cassettes/openai/chat/basic_streaming_response.yml b/test/vcr_cassettes/openai/chat/basic_streaming_response.yml index 17253361..dc620f36 100644 --- a/test/vcr_cassettes/openai/chat/basic_streaming_response.yml +++ b/test/vcr_cassettes/openai/chat/basic_streaming_response.yml @@ -5,7 +5,7 @@ http_interactions: uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4o","input":[{"role":"user","content":"This is a chat + string: '{"model":"gpt-4.1","input":[{"role":"user","content":"This is a chat test. If it''s working, respond with a single word: Yes"}],"instructions":null,"tools":[],"previous_response_id":null,"stream":true}' headers: Content-Type: @@ -61,10 +61,10 @@ http_interactions: encoding: UTF-8 string: |+ event: response.created - data: {"type":"response.created","response":{"id":"resp_67eafd5f2b90819288af54361ff81a100e51d01dbd4ed330","object":"response","created_at":1743453535,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + data: {"type":"response.created","response":{"id":"resp_67eafd5f2b90819288af54361ff81a100e51d01dbd4ed330","object":"response","created_at":1743453535,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4.1-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} event: response.in_progress - data: {"type":"response.in_progress","response":{"id":"resp_67eafd5f2b90819288af54361ff81a100e51d01dbd4ed330","object":"response","created_at":1743453535,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + data: {"type":"response.in_progress","response":{"id":"resp_67eafd5f2b90819288af54361ff81a100e51d01dbd4ed330","object":"response","created_at":1743453535,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4.1-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} event: response.output_item.added data: {"type":"response.output_item.added","output_index":0,"item":{"type":"message","id":"msg_67eafd5f7c048192a24ce545ebfd908a0e51d01dbd4ed330","status":"in_progress","role":"assistant","content":[]}} @@ -85,7 +85,7 @@ http_interactions: data: {"type":"response.output_item.done","output_index":0,"item":{"type":"message","id":"msg_67eafd5f7c048192a24ce545ebfd908a0e51d01dbd4ed330","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Yes","annotations":[]}]}} event: response.completed - data: {"type":"response.completed","response":{"id":"resp_67eafd5f2b90819288af54361ff81a100e51d01dbd4ed330","object":"response","created_at":1743453535,"status":"completed","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-2024-08-06","output":[{"type":"message","id":"msg_67eafd5f7c048192a24ce545ebfd908a0e51d01dbd4ed330","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Yes","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":25,"input_tokens_details":{"cached_tokens":0},"output_tokens":2,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":27},"user":null,"metadata":{}}} + data: {"type":"response.completed","response":{"id":"resp_67eafd5f2b90819288af54361ff81a100e51d01dbd4ed330","object":"response","created_at":1743453535,"status":"completed","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4.1-2024-08-06","output":[{"type":"message","id":"msg_67eafd5f7c048192a24ce545ebfd908a0e51d01dbd4ed330","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Yes","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":25,"input_tokens_details":{"cached_tokens":0},"output_tokens":2,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":27},"user":null,"metadata":{}}} recorded_at: Mon, 31 Mar 2025 20:38:55 GMT recorded_with: VCR 6.3.1 diff --git a/test/vcr_cassettes/openai/chat/function_calls.yml b/test/vcr_cassettes/openai/chat/function_calls.yml index bb19ee09..b51f80c4 100644 --- a/test/vcr_cassettes/openai/chat/function_calls.yml +++ b/test/vcr_cassettes/openai/chat/function_calls.yml @@ -5,7 +5,7 @@ http_interactions: uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4o","input":[{"role":"user","content":"What is my net + string: '{"model":"gpt-4.1","input":[{"role":"user","content":"What is my net worth?"}],"instructions":"Use the tools available to you to answer the user''s question.","tools":[{"type":"function","name":"get_net_worth","description":"Gets a user''s net worth","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"previous_response_id":null,"stream":null}' @@ -71,7 +71,7 @@ http_interactions: "incomplete_details": null, "instructions": "Use the tools available to you to answer the user's question.", "max_output_tokens": null, - "model": "gpt-4o-2024-08-06", + "model": "gpt-4.1-2024-08-06", "output": [ { "type": "function_call", @@ -132,7 +132,7 @@ http_interactions: uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4o","input":[{"role":"user","content":"What is my net + string: '{"model":"gpt-4.1","input":[{"role":"user","content":"What is my net worth?"},{"type":"function_call_output","call_id":"call_KrFORr53UBxdwZ9SQ6fkpU0F","output":"\"{\\\"amount\\\":10000,\\\"currency\\\":\\\"USD\\\"}\""}],"instructions":null,"tools":[],"previous_response_id":"resp_67eafd5f2d1881928f10551839e8219102a5ebf5f2a599ef","stream":null}' headers: Content-Type: @@ -196,7 +196,7 @@ http_interactions: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-4o-2024-08-06", + "model": "gpt-4.1-2024-08-06", "output": [ { "type": "message", diff --git a/test/vcr_cassettes/openai/chat/streaming_function_calls.yml b/test/vcr_cassettes/openai/chat/streaming_function_calls.yml index c4739594..41bc3971 100644 --- a/test/vcr_cassettes/openai/chat/streaming_function_calls.yml +++ b/test/vcr_cassettes/openai/chat/streaming_function_calls.yml @@ -5,7 +5,7 @@ http_interactions: uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4o","input":[{"role":"user","content":"What is my net + string: '{"model":"gpt-4.1","input":[{"role":"user","content":"What is my net worth?"}],"instructions":"Use the tools available to you to answer the user''s question.","tools":[{"type":"function","name":"get_net_worth","description":"Gets a user''s net worth","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"previous_response_id":null,"stream":true}' @@ -63,10 +63,10 @@ http_interactions: encoding: UTF-8 string: |+ event: response.created - data: {"type":"response.created","response":{"id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","object":"response","created_at":1743453535,"status":"in_progress","error":null,"incomplete_details":null,"instructions":"Use the tools available to you to answer the user's question.","max_output_tokens":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets a user's net worth","name":"get_net_worth","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + data: {"type":"response.created","response":{"id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","object":"response","created_at":1743453535,"status":"in_progress","error":null,"incomplete_details":null,"instructions":"Use the tools available to you to answer the user's question.","max_output_tokens":null,"model":"gpt-4.1-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets a user's net worth","name":"get_net_worth","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} event: response.in_progress - data: {"type":"response.in_progress","response":{"id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","object":"response","created_at":1743453535,"status":"in_progress","error":null,"incomplete_details":null,"instructions":"Use the tools available to you to answer the user's question.","max_output_tokens":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets a user's net worth","name":"get_net_worth","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + data: {"type":"response.in_progress","response":{"id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","object":"response","created_at":1743453535,"status":"in_progress","error":null,"incomplete_details":null,"instructions":"Use the tools available to you to answer the user's question.","max_output_tokens":null,"model":"gpt-4.1-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets a user's net worth","name":"get_net_worth","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} event: response.output_item.added data: {"type":"response.output_item.added","output_index":0,"item":{"type":"function_call","id":"fc_67eafd5fa714819287b2bff8c76935690aa8698ee903b906","call_id":"call_7EY6rF7mkfNyMIz3HQmrYIOq","name":"get_net_worth","arguments":"","status":"in_progress"}} @@ -81,7 +81,7 @@ http_interactions: data: {"type":"response.output_item.done","output_index":0,"item":{"type":"function_call","id":"fc_67eafd5fa714819287b2bff8c76935690aa8698ee903b906","call_id":"call_7EY6rF7mkfNyMIz3HQmrYIOq","name":"get_net_worth","arguments":"{}","status":"completed"}} event: response.completed - data: {"type":"response.completed","response":{"id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","object":"response","created_at":1743453535,"status":"completed","error":null,"incomplete_details":null,"instructions":"Use the tools available to you to answer the user's question.","max_output_tokens":null,"model":"gpt-4o-2024-08-06","output":[{"type":"function_call","id":"fc_67eafd5fa714819287b2bff8c76935690aa8698ee903b906","call_id":"call_7EY6rF7mkfNyMIz3HQmrYIOq","name":"get_net_worth","arguments":"{}","status":"completed"}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets a user's net worth","name":"get_net_worth","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":55,"input_tokens_details":{"cached_tokens":0},"output_tokens":13,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":68},"user":null,"metadata":{}}} + data: {"type":"response.completed","response":{"id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","object":"response","created_at":1743453535,"status":"completed","error":null,"incomplete_details":null,"instructions":"Use the tools available to you to answer the user's question.","max_output_tokens":null,"model":"gpt-4.1-2024-08-06","output":[{"type":"function_call","id":"fc_67eafd5fa714819287b2bff8c76935690aa8698ee903b906","call_id":"call_7EY6rF7mkfNyMIz3HQmrYIOq","name":"get_net_worth","arguments":"{}","status":"completed"}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"function","description":"Gets a user's net worth","name":"get_net_worth","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false},"strict":true}],"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":55,"input_tokens_details":{"cached_tokens":0},"output_tokens":13,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":68},"user":null,"metadata":{}}} recorded_at: Mon, 31 Mar 2025 20:38:55 GMT - request: @@ -89,7 +89,7 @@ http_interactions: uri: https://api.openai.com/v1/responses body: encoding: UTF-8 - string: '{"model":"gpt-4o","input":[{"role":"user","content":"What is my net + string: '{"model":"gpt-4.1","input":[{"role":"user","content":"What is my net worth?"},{"type":"function_call_output","call_id":"call_7EY6rF7mkfNyMIz3HQmrYIOq","output":"{\"amount\":10000,\"currency\":\"USD\"}"}],"instructions":null,"tools":[],"previous_response_id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","stream":true}' headers: Content-Type: @@ -145,10 +145,10 @@ http_interactions: encoding: UTF-8 string: |+ event: response.created - data: {"type":"response.created","response":{"id":"resp_67eafd5ff7448192af7cd9e9dde90f5e0aa8698ee903b906","object":"response","created_at":1743453536,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + data: {"type":"response.created","response":{"id":"resp_67eafd5ff7448192af7cd9e9dde90f5e0aa8698ee903b906","object":"response","created_at":1743453536,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4.1-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} event: response.in_progress - data: {"type":"response.in_progress","response":{"id":"resp_67eafd5ff7448192af7cd9e9dde90f5e0aa8698ee903b906","object":"response","created_at":1743453536,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + data: {"type":"response.in_progress","response":{"id":"resp_67eafd5ff7448192af7cd9e9dde90f5e0aa8698ee903b906","object":"response","created_at":1743453536,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4.1-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} event: response.output_item.added data: {"type":"response.output_item.added","output_index":0,"item":{"type":"message","id":"msg_67eafd6084ec81929a5132414ef713180aa8698ee903b906","status":"in_progress","role":"assistant","content":[]}} @@ -196,7 +196,7 @@ http_interactions: data: {"type":"response.output_item.done","output_index":0,"item":{"type":"message","id":"msg_67eafd6084ec81929a5132414ef713180aa8698ee903b906","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Your net worth is $10,000 USD.","annotations":[]}]}} event: response.completed - data: {"type":"response.completed","response":{"id":"resp_67eafd5ff7448192af7cd9e9dde90f5e0aa8698ee903b906","object":"response","created_at":1743453536,"status":"completed","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-2024-08-06","output":[{"type":"message","id":"msg_67eafd6084ec81929a5132414ef713180aa8698ee903b906","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Your net worth is $10,000 USD.","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":56,"input_tokens_details":{"cached_tokens":0},"output_tokens":11,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":67},"user":null,"metadata":{}}} + data: {"type":"response.completed","response":{"id":"resp_67eafd5ff7448192af7cd9e9dde90f5e0aa8698ee903b906","object":"response","created_at":1743453536,"status":"completed","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4.1-2024-08-06","output":[{"type":"message","id":"msg_67eafd6084ec81929a5132414ef713180aa8698ee903b906","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Your net worth is $10,000 USD.","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":"resp_67eafd5f2ef0819290ec6bbbc5f27c8e0aa8698ee903b906","reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":56,"input_tokens_details":{"cached_tokens":0},"output_tokens":11,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":67},"user":null,"metadata":{}}} recorded_at: Mon, 31 Mar 2025 20:38:58 GMT recorded_with: VCR 6.3.1