From e43204031542fd908ad8bbfff28e99883a459ba4 Mon Sep 17 00:00:00 2001 From: Christoph Eicke Date: Mon, 10 Jun 2024 17:08:33 +0200 Subject: [PATCH 01/12] Dalle image generation --- app/jobs/get_next_ai_message_job.rb | 16 +++++++++ app/services/toolbox.rb | 1 + app/services/toolbox/dalle.rb | 36 +++++++++++++++++++ .../service/postgresql_service.rb | 2 +- test/services/toolbox_test.rb | 2 +- 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 app/services/toolbox/dalle.rb diff --git a/app/jobs/get_next_ai_message_job.rb b/app/jobs/get_next_ai_message_job.rb index ed72f2dbd..2ef7274ef 100644 --- a/app/jobs/get_next_ai_message_job.rb +++ b/app/jobs/get_next_ai_message_job.rb @@ -1,3 +1,5 @@ +require 'open-uri' + class GetNextAIMessageJob < ApplicationJob class ResponseCancelled < StandardError; end class WaitForPrevious < StandardError; end @@ -156,6 +158,7 @@ def call_tools_before_wrapping_up end index = @message.index + url_of_dalle_generated_image = nil msgs.each do |tool_message| # one message for each tool executed @conversation.messages.create!( assistant: @assistant, @@ -166,6 +169,13 @@ def call_tools_before_wrapping_up index: index += 1, processed_at: Time.current, ) + + content_hash = JSON.parse(tool_message[:content]) + + if content_hash.has_key?('url_of_dalle_generated_image') + url_of_dalle_generated_image = content_hash['url_of_dalle_generated_image'] + end + end assistant_reply = @conversation.messages.create!( @@ -176,6 +186,12 @@ def call_tools_before_wrapping_up index: index += 1 ) + unless url_of_dalle_generated_image.nil? + d = Document.new + d.file.attach(io: URI.open(url_of_dalle_generated_image), filename: 'image.png') + assistant_reply.documents << d + end + GetNextAIMessageJob.perform_later( @user.id, assistant_reply.id, diff --git a/app/services/toolbox.rb b/app/services/toolbox.rb index cb9786cf7..d111a82e5 100644 --- a/app/services/toolbox.rb +++ b/app/services/toolbox.rb @@ -3,6 +3,7 @@ def self.descendants [ Toolbox::HelloWorld, Toolbox::OpenMeteo, + Toolbox::Dalle ] end diff --git a/app/services/toolbox/dalle.rb b/app/services/toolbox/dalle.rb new file mode 100644 index 000000000..781de8ae8 --- /dev/null +++ b/app/services/toolbox/dalle.rb @@ -0,0 +1,36 @@ +class Toolbox::Dalle < Toolbox + + describe :generate_an_image, <<~S + Generate an image based on what the user asks you to generate. You will pass the user's prompt and will get back a URL to an image. + S + + def self.generate_an_image(image_generation_prompt_s:) + + response = client.images.generate( + parameters: { + prompt: image_generation_prompt_s, + model: "dall-e-3", + size: "1024x1792", + quality: "standard" + } + ) + + dalle_url = response.dig("data", 0, "url") + + { + prompt_given: image_generation_prompt_s, + url_of_dalle_generated_image: dalle_url, + note_to_assistant: "The image at the URL is already being shown on screen so reply with a nice message confirming the image has been generated, maybe re-describing it, but don't include the link to it." + } + end + + class << self + private + + def client + OpenAI::Client.new( + access_token: Current.user.openai_key, + ) + end + end +end \ No newline at end of file diff --git a/lib/active_storage/service/postgresql_service.rb b/lib/active_storage/service/postgresql_service.rb index e4d46646a..9be0eed1b 100644 --- a/lib/active_storage/service/postgresql_service.rb +++ b/lib/active_storage/service/postgresql_service.rb @@ -103,7 +103,7 @@ def generate_url(key, expires_in:, filename:, disposition:, content_type:) ) generated_url = url_helpers.rails_postgresql_service_url(verified_key_with_expiration, - **url_options, + only_path: true, disposition: content_disposition, content_type: content_type, filename: filename, diff --git a/test/services/toolbox_test.rb b/test/services/toolbox_test.rb index 9b8810546..292e36d37 100644 --- a/test/services/toolbox_test.rb +++ b/test/services/toolbox_test.rb @@ -2,7 +2,7 @@ class ToolboxTest < ActiveSupport::TestCase test "tools" do - assert_equal 4, Toolbox.tools.length + assert_equal 5, Toolbox.tools.length assert Toolbox::OpenMeteo.tools.first[:function].values.all? { |value| value.present? } assert Toolbox::OpenMeteo.tools.first[:function][:description].length > 100 tools = [ From 5fdd4e4debaa76eddc11d8abd3b43053e43dd333 Mon Sep 17 00:00:00 2001 From: Christoph Eicke Date: Thu, 27 Jun 2024 09:22:18 +0200 Subject: [PATCH 02/12] Update toolbox.rb Fix missing item separator. --- app/services/toolbox.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/toolbox.rb b/app/services/toolbox.rb index 0df146a14..24a6a1ac7 100644 --- a/app/services/toolbox.rb +++ b/app/services/toolbox.rb @@ -6,7 +6,7 @@ def self.descendants [ test_env && Toolbox::HelloWorld, Toolbox::OpenMeteo, - Toolbox::Dalle + Toolbox::Dalle, Toolbox::Memory, gmail_active && Toolbox::Gmail, tasks_active && Toolbox::GoogleTasks, From 5c14b120fcb88da10d7bab5a1011caef982ddced Mon Sep 17 00:00:00 2001 From: Christoph Eicke Date: Mon, 1 Jul 2024 09:20:26 +0200 Subject: [PATCH 03/12] Fix rubocop issues --- app/jobs/get_next_ai_message_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/get_next_ai_message_job.rb b/app/jobs/get_next_ai_message_job.rb index bab0c3bca..2e2c8ca5d 100644 --- a/app/jobs/get_next_ai_message_job.rb +++ b/app/jobs/get_next_ai_message_job.rb @@ -194,11 +194,11 @@ def call_tools_before_wrapping_up ) content_hash = JSON.parse(tool_message[:content]) - + if content_hash.has_key?('url_of_dalle_generated_image') url_of_dalle_generated_image = content_hash['url_of_dalle_generated_image'] end - + end assistant_reply = @conversation.messages.create!( From 08e8fe16e9ecc79ab125f88daf03cf55dc99ac55 Mon Sep 17 00:00:00 2001 From: Christoph Eicke Date: Mon, 1 Jul 2024 09:27:39 +0200 Subject: [PATCH 04/12] Fix PostgreSQL ActiveStorage tests --- test/lib/active_storage/postgresql_test.rb | 2 +- test/lib/active_storage/service/public_postgresql_test.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lib/active_storage/postgresql_test.rb b/test/lib/active_storage/postgresql_test.rb index 3b1ef2711..4cc0184c3 100644 --- a/test/lib/active_storage/postgresql_test.rb +++ b/test/lib/active_storage/postgresql_test.rb @@ -48,7 +48,7 @@ class ActiveStorage::PostgresqlTest < ActiveSupport::TestCase end test "url generation" do - assert_match(/^https:\/\/example.com\/rails\/active_storage\/postgresql\/.*\/avatar\.png\?content_type=image%2Fpng&disposition=inline/, + assert_match(/^\/rails\/active_storage\/postgresql\/.*\/avatar\.png\?content_type=image%2Fpng&disposition=inline/, @service.url(FIXTURE_KEY, expires_in: 5.minutes, disposition: :inline, filename: ActiveStorage::Filename.new("avatar.png"), content_type: "image/png")) end diff --git a/test/lib/active_storage/service/public_postgresql_test.rb b/test/lib/active_storage/service/public_postgresql_test.rb index 12e9fdb3f..1b4804957 100644 --- a/test/lib/active_storage/service/public_postgresql_test.rb +++ b/test/lib/active_storage/service/public_postgresql_test.rb @@ -8,6 +8,6 @@ class ActiveStorage::Service::PublicPostgresqlTest < ActiveSupport::TestCase test "public URL generation" do url = @service.url(@key, disposition: :inline, filename: ActiveStorage::Filename.new("avatar.png"), content_type: "image/png") - assert_match(/^https:\/\/example.com\/rails\/active_storage\/postgresql\/.*\/avatar\.png/, url) + assert_match(/^\/rails\/active_storage\/postgresql\/.*\/avatar\.png/, url) end end From bc1af9e460f40f27b62f23c4118b346252f8cf19 Mon Sep 17 00:00:00 2001 From: Christoph Eicke Date: Sun, 25 Aug 2024 12:47:16 +0200 Subject: [PATCH 05/12] Update lib/active_storage/service/postgresql_service.rb Co-authored-by: Keith Schacht --- lib/active_storage/service/postgresql_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_storage/service/postgresql_service.rb b/lib/active_storage/service/postgresql_service.rb index 9be0eed1b..7b2d98dae 100644 --- a/lib/active_storage/service/postgresql_service.rb +++ b/lib/active_storage/service/postgresql_service.rb @@ -103,7 +103,7 @@ def generate_url(key, expires_in:, filename:, disposition:, content_type:) ) generated_url = url_helpers.rails_postgresql_service_url(verified_key_with_expiration, - only_path: true, + only_path: true, # This fixes an exception with attachment URL generation from a worker: https://github.com/AllYourBot/hostedgpt/pull/398#issuecomment-2168135853 disposition: content_disposition, content_type: content_type, filename: filename, From 0564d1aca462e6d6b6f913bff0ce8edda297303c Mon Sep 17 00:00:00 2001 From: Christoph Eicke Date: Sun, 25 Aug 2024 12:47:32 +0200 Subject: [PATCH 06/12] Update app/jobs/get_next_ai_message_job.rb Co-authored-by: Keith Schacht --- app/jobs/get_next_ai_message_job.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/jobs/get_next_ai_message_job.rb b/app/jobs/get_next_ai_message_job.rb index 2e2c8ca5d..40978c751 100644 --- a/app/jobs/get_next_ai_message_job.rb +++ b/app/jobs/get_next_ai_message_job.rb @@ -193,10 +193,10 @@ def call_tools_before_wrapping_up processed_at: Time.current, ) - content_hash = JSON.parse(tool_message[:content]) + parsed = JSON.parse(tool_message[:content]) rescue nil - if content_hash.has_key?('url_of_dalle_generated_image') - url_of_dalle_generated_image = content_hash['url_of_dalle_generated_image'] + if parsed.is_a?(Hash) && parsed.has_key?("url_of_dalle_generated_image") + url_of_dalle_generated_image = parsed["url_of_dalle_generated_image"] end end From 0f20f811b8d0701a9980fd75ede880cad7f223e9 Mon Sep 17 00:00:00 2001 From: Christoph Eicke Date: Sun, 25 Aug 2024 12:49:01 +0200 Subject: [PATCH 07/12] Fixing tests --- test/models/document_test.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/test/models/document_test.rb b/test/models/document_test.rb index 49d11bdac..e0c6a9948 100644 --- a/test/models/document_test.rb +++ b/test/models/document_test.rb @@ -55,7 +55,6 @@ class DocumentTest < ActiveSupport::TestCase end test "fully_processed_url" do - assert documents(:cat_photo).fully_processed_url(:small).starts_with?('http') assert documents(:cat_photo).fully_processed_url(:small).include?('rails/active_storage/postgresql') assert documents(:cat_photo).fully_processed_url(:small).exclude?('/redirect') end From 0aea5c0bb1f02199da5fc7d870e0acc12ed2c519 Mon Sep 17 00:00:00 2001 From: Christoph Eicke Date: Sun, 25 Aug 2024 13:57:43 +0200 Subject: [PATCH 08/12] WIP: testing the image generation --- test/fixtures/conversations.yml | 6 ++ test/fixtures/messages.yml | 39 +++++++++++++ test/fixtures/users.yml | 5 ++ .../get_next_ai_message_job_openai_test.rb | 57 ++++++++++++++++++- 4 files changed, 106 insertions(+), 1 deletion(-) diff --git a/test/fixtures/conversations.yml b/test/fixtures/conversations.yml index e80dcc2e7..4accc3be8 100644 --- a/test/fixtures/conversations.yml +++ b/test/fixtures/conversations.yml @@ -76,6 +76,12 @@ weather: title: Weather last_assistant_message: weather_explained +image_generation: + user: christoph + assistant: samantha + title: Generating an image + last_assistant_message: image_generation_explained + trees: user: keith assistant: keith_gpt3 diff --git a/test/fixtures/messages.yml b/test/fixtures/messages.yml index 359cfe416..58b318156 100644 --- a/test/fixtures/messages.yml +++ b/test/fixtures/messages.yml @@ -660,6 +660,45 @@ weather_explained: version: 1 +image_generation_tool_call: + assistant: samantha + conversation: image_generation + role: assistant + tool_call_id: + content_text: + content_tool_calls: '[{"index": 0, "id": "def456", "type": "function", "function": {"name": "generate_an_image", "arguments": {"image_generation_prompt_s": "World"}}}]' + content_document: + created_at: 2024-08-25 1:01:00 + processed_at: 2024-08-25 1:01:00 + index: 1 + version: 1 + +image_generation_tool_result: + assistant: samantha + conversation: image_generation + role: tool + tool_call_id: def456 + content_text: weather is + content_tool_calls: + content_document: + created_at: 2024-08-25 1:02:00 + processed_at: 2024-08-25 1:02:00 + index: 2 + version: 1 + +image_generation_explained: + assistant: samantha + conversation: image_generation + role: assistant + tool_call_id: + content_text: The weather in Austin is + content_tool_calls: + content_document: + created_at: 2024-08-25 1:03:00 + processed_at: 2024-08-25 1:03:00 + index: 3 + version: 1 + # Next conversation trees_explained: diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index cb56107ee..c8fa13c09 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -14,3 +14,8 @@ taylor: first_name: Taylor registered_at: 2024-05-31 08:40:05 preferences: {} + +christoph: + first_name: Christoph + registered_at: 2024-08-25 08:08:08 + preferences: {} diff --git a/test/jobs/get_next_ai_message_job_openai_test.rb b/test/jobs/get_next_ai_message_job_openai_test.rb index f46411ec4..368e344dc 100644 --- a/test/jobs/get_next_ai_message_job_openai_test.rb +++ b/test/jobs/get_next_ai_message_job_openai_test.rb @@ -3,9 +3,18 @@ class GetNextAIMessageJobOpenaiTest < ActiveJob::TestCase setup do @conversation = conversations(:greeting) - @user = @conversation.user @conversation.messages.create! role: :user, content_text: "Still there?", assistant: @conversation.assistant @message = @conversation.latest_message_for_version(:latest) + + p "#########" + @image_generation = conversations(:image_generation) + p @image_generation + p @image_generation.messages.create! role: :user, content_text: "Generate an image", assistant: @image_generation.assistant + p @image_generation.messages.length + @image_generation_message = @image_generation.latest_message_for_version(:latest) + p @image_generation_message + + @user = @conversation.user @test_client = TestClient::OpenAI.new(access_token: 'abc') end @@ -56,6 +65,52 @@ class GetNextAIMessageJobOpenaiTest < ActiveJob::TestCase refute second_new_message.finished?, "This message SHOULD NOT be considered finished yet" end + test "properly handles a tool response call from the assistant when images are included" do + assert_difference "@image_generation.messages.reload.length", 2 do + TestClient::OpenAI.stub :function, "generate_an_image" do + TestClient::OpenAI.stub :arguments, { image_generation_prompt_s: "Kitten" } do + TestClient::OpenAI.stub :api_response, TestClient::OpenAI.api_function_response do + assert GetNextAIMessageJob.perform_now(@user.id, @message.id, @image_generation.assistant.id) + end + end + end + end + + p "###### Message:" + p @image_generation_message + + @image_generation_message.reload + assert @image_generation_message.content_text.blank? + assert @image_generation_message.tool_call_id.nil? + assert @image_generation_message.content_tool_calls.present?, "Assistant should have decided to call a tool" + + @new_messages = @image_generation.messages.where("id > ?", @message.id).order(:created_at) + + p "###### Image generation:" + p @image_generation + @new_messages.messages.each_with_index do |message, index| + p "######## #{index}:" + p message + end + + # first + first_new_message = @new_messages.first + assert first_new_message.tool? + # assert_equal "Hello, Keith!".to_json, first_new_message.content_text, "First new message should have the result of calling the tool" + # assert first_new_message.tool_call_id.present? + # assert first_new_message.content_tool_calls.blank? + # assert_equal @message.content_tool_calls.dig(0, :id), first_new_message.tool_call_id, "ID of tool execution should have matched decision to call the tool" + # assert first_new_message.finished?, "This message SHOULD HAVE been considered finished" + + # second + # second_new_message = @new_messages.second + # assert second_new_message.assistant?, "Second new message should be queued up for the assistant to reply" + # assert second_new_message.content_text.nil?, "The content should be nil to indicate that it hasn't even started processing" + # assert second_new_message.tool_call_id.nil? + # assert second_new_message.content_tool_calls.blank? + # refute second_new_message.finished?, "This message SHOULD NOT be considered finished yet" + end + test "returns early if the message id was invalid" do refute GetNextAIMessageJob.perform_now(@user.id, 0, @conversation.assistant.id) end From e093d7c6971acae126d99f1fef417c831861ee93 Mon Sep 17 00:00:00 2001 From: Justin Vallelonga Date: Mon, 4 Nov 2024 10:54:38 +0700 Subject: [PATCH 09/12] updates to make dalle calls work --- app/jobs/get_next_ai_message_job.rb | 4 ++-- app/services/toolbox/dalle.rb | 17 +++++++---------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/app/jobs/get_next_ai_message_job.rb b/app/jobs/get_next_ai_message_job.rb index 3c697596f..0ad348334 100644 --- a/app/jobs/get_next_ai_message_job.rb +++ b/app/jobs/get_next_ai_message_job.rb @@ -1,4 +1,4 @@ -require 'open-uri' +require "open-uri" include ActionView::RecordIdentifier require "nokogiri/xml/node" @@ -221,7 +221,7 @@ def call_tools_before_wrapping_up unless url_of_dalle_generated_image.nil? d = Document.new - d.file.attach(io: URI.open(url_of_dalle_generated_image), filename: 'image.png') + d.file.attach(io: URI.open(url_of_dalle_generated_image), filename: "image.png") assistant_reply.documents << d end diff --git a/app/services/toolbox/dalle.rb b/app/services/toolbox/dalle.rb index 781de8ae8..8cf85c3d9 100644 --- a/app/services/toolbox/dalle.rb +++ b/app/services/toolbox/dalle.rb @@ -4,8 +4,7 @@ class Toolbox::Dalle < Toolbox Generate an image based on what the user asks you to generate. You will pass the user's prompt and will get back a URL to an image. S - def self.generate_an_image(image_generation_prompt_s:) - + def generate_an_image(image_generation_prompt_s:) response = client.images.generate( parameters: { prompt: image_generation_prompt_s, @@ -24,13 +23,11 @@ def self.generate_an_image(image_generation_prompt_s:) } end - class << self - private + private - def client - OpenAI::Client.new( - access_token: Current.user.openai_key, - ) - end + def client + OpenAI::Client.new( + access_token: Current.message.assistant.api_service.effective_token + ) end -end \ No newline at end of file +end From 09cf14b695170137cd5aa9e151d59e0302665144 Mon Sep 17 00:00:00 2001 From: Justin Vallelonga Date: Tue, 5 Nov 2024 13:22:21 +0700 Subject: [PATCH 10/12] fixes most tests --- .../service/postgresql_service.rb | 2 +- .../postgresql_controller_test.rb | 1 + .../get_next_ai_message_job_openai_test.rb | 76 ++++++++++--------- test/lib/active_storage/postgresql_test.rb | 2 +- .../service/public_postgresql_test.rb | 2 +- test/models/api_service_test.rb | 4 +- test/models/message/version_test.rb | 6 +- test/services/ai_backend/anthropic_test.rb | 12 +-- 8 files changed, 57 insertions(+), 48 deletions(-) diff --git a/lib/active_storage/service/postgresql_service.rb b/lib/active_storage/service/postgresql_service.rb index 718713374..c906b0ef5 100644 --- a/lib/active_storage/service/postgresql_service.rb +++ b/lib/active_storage/service/postgresql_service.rb @@ -103,7 +103,7 @@ def generate_url(key, expires_in:, filename:, disposition:, content_type:) ) generated_url = url_helpers.rails_postgresql_service_url(verified_key_with_expiration, - only_path: true, # This fixes an exception with attachment URL generation from a worker: https://github.com/AllYourBot/hostedgpt/pull/398#issuecomment-2168135853 + **url_options, disposition: content_disposition, content_type: content_type, filename: filename, diff --git a/test/controllers/active_storage/postgresql_controller_test.rb b/test/controllers/active_storage/postgresql_controller_test.rb index 365641294..275a7150a 100644 --- a/test/controllers/active_storage/postgresql_controller_test.rb +++ b/test/controllers/active_storage/postgresql_controller_test.rb @@ -52,6 +52,7 @@ class ActiveStorage::PostgresqlControllerTest < ActionDispatch::IntegrationTest blob.delete get blob.send(url_method) + assert_response :not_found end test "showing blob with invalid key" do diff --git a/test/jobs/get_next_ai_message_job_openai_test.rb b/test/jobs/get_next_ai_message_job_openai_test.rb index 32c51bf3c..333ecf6f3 100644 --- a/test/jobs/get_next_ai_message_job_openai_test.rb +++ b/test/jobs/get_next_ai_message_job_openai_test.rb @@ -8,16 +8,6 @@ class GetNextAIMessageJobOpenaiTest < ActiveJob::TestCase @conversation.messages.create! role: :user, content_text: "Still there?", assistant: @assistant @assistant.language_model.update!(supports_tools: false) # this will change the TestClient response so we want to be selective about this @message = @conversation.latest_message_for_version(:latest) - - p "#########" - @image_generation = conversations(:image_generation) - p @image_generation - p @image_generation.messages.create! role: :user, content_text: "Generate an image", assistant: @image_generation.assistant - p @image_generation.messages.length - @image_generation_message = @image_generation.latest_message_for_version(:latest) - p @image_generation_message - - @user = @conversation.user @test_client = TestClient::OpenAI.new(access_token: "abc") end @@ -67,49 +57,63 @@ class GetNextAIMessageJobOpenaiTest < ActiveJob::TestCase end test "properly handles a tool response call from the assistant when images are included" do + @image_generation = conversations(:image_generation) + @image_generation.messages.create! role: :user, content_text: "Generate an image", assistant: @image_generation.assistant + @image_generation_message = @image_generation.latest_message_for_version(:latest) + + @image_generation.assistant.language_model.update!(supports_tools: true) + + image_generation_prompt = "Kitten" + + response = { + data: [{ + url: "https://example.com/image.jpg" + }] + } + + images_mock = Minitest::Mock.new + images_mock.expect :generate, response, parameters: { + prompt: image_generation_prompt, + model: "dall-e-3", + size: "1024x1792", + quality: "standard" + } + assert_difference "@image_generation.messages.reload.length", 2 do - TestClient::OpenAI.stub :function, "generate_an_image" do - TestClient::OpenAI.stub :arguments, { image_generation_prompt_s: "Kitten" } do - TestClient::OpenAI.stub :api_response, TestClient::OpenAI.api_function_response do - assert GetNextAIMessageJob.perform_now(@user.id, @message.id, @image_generation.assistant.id) + OpenAI::Client.stub_any_instance :images, images_mock do + TestClient::OpenAI.stub :function, "dalle_generate_an_image" do + TestClient::OpenAI.stub :arguments, { :image_generation_prompt=>image_generation_prompt } do + assert GetNextAIMessageJob.perform_now(@user.id, @image_generation_message.id, @image_generation.assistant.id) end end end end - p "###### Message:" - p @image_generation_message - @image_generation_message.reload assert @image_generation_message.content_text.blank? assert @image_generation_message.tool_call_id.nil? assert @image_generation_message.content_tool_calls.present?, "Assistant should have decided to call a tool" - @new_messages = @image_generation.messages.where("id > ?", @message.id).order(:created_at) - - p "###### Image generation:" - p @image_generation - @new_messages.messages.each_with_index do |message, index| - p "######## #{index}:" - p message - end + @new_messages = @image_generation.messages.where("id > ?", @image_generation_message.id).order(:created_at) # first first_new_message = @new_messages.first assert first_new_message.tool? - # assert_equal "Hello, Keith!".to_json, first_new_message.content_text, "First new message should have the result of calling the tool" - # assert first_new_message.tool_call_id.present? - # assert first_new_message.content_tool_calls.blank? - # assert_equal @message.content_tool_calls.dig(0, :id), first_new_message.tool_call_id, "ID of tool execution should have matched decision to call the tool" - # assert first_new_message.finished?, "This message SHOULD HAVE been considered finished" + content_text = first_new_message.content_text + json_content_text = JSON.parse(content_text) + assert_equal image_generation_prompt, json_content_text["prompt_given"], "First new message should have the result of calling the tool" + assert first_new_message.tool_call_id.present? + assert first_new_message.content_tool_calls.blank? + assert_equal @image_generation_message.content_tool_calls.dig(0, :id), first_new_message.tool_call_id, "ID of tool execution should have matched decision to call the tool" + assert first_new_message.finished?, "This message SHOULD HAVE been considered finished" # second - # second_new_message = @new_messages.second - # assert second_new_message.assistant?, "Second new message should be queued up for the assistant to reply" - # assert second_new_message.content_text.nil?, "The content should be nil to indicate that it hasn't even started processing" - # assert second_new_message.tool_call_id.nil? - # assert second_new_message.content_tool_calls.blank? - # refute second_new_message.finished?, "This message SHOULD NOT be considered finished yet" + second_new_message = @new_messages.second + assert second_new_message.assistant?, "Second new message should be queued up for the assistant to reply" + assert second_new_message.content_text.nil?, "The content should be nil to indicate that it hasn't even started processing" + assert second_new_message.tool_call_id.nil? + assert second_new_message.content_tool_calls.blank? + refute second_new_message.finished?, "This message SHOULD NOT be considered finished yet" end test "returns early if the message id was invalid" do diff --git a/test/lib/active_storage/postgresql_test.rb b/test/lib/active_storage/postgresql_test.rb index 4cc0184c3..3b1ef2711 100644 --- a/test/lib/active_storage/postgresql_test.rb +++ b/test/lib/active_storage/postgresql_test.rb @@ -48,7 +48,7 @@ class ActiveStorage::PostgresqlTest < ActiveSupport::TestCase end test "url generation" do - assert_match(/^\/rails\/active_storage\/postgresql\/.*\/avatar\.png\?content_type=image%2Fpng&disposition=inline/, + assert_match(/^https:\/\/example.com\/rails\/active_storage\/postgresql\/.*\/avatar\.png\?content_type=image%2Fpng&disposition=inline/, @service.url(FIXTURE_KEY, expires_in: 5.minutes, disposition: :inline, filename: ActiveStorage::Filename.new("avatar.png"), content_type: "image/png")) end diff --git a/test/lib/active_storage/service/public_postgresql_test.rb b/test/lib/active_storage/service/public_postgresql_test.rb index 1b4804957..12e9fdb3f 100644 --- a/test/lib/active_storage/service/public_postgresql_test.rb +++ b/test/lib/active_storage/service/public_postgresql_test.rb @@ -8,6 +8,6 @@ class ActiveStorage::Service::PublicPostgresqlTest < ActiveSupport::TestCase test "public URL generation" do url = @service.url(@key, disposition: :inline, filename: ActiveStorage::Filename.new("avatar.png"), content_type: "image/png") - assert_match(/^\/rails\/active_storage\/postgresql\/.*\/avatar\.png/, url) + assert_match(/^https:\/\/example.com\/rails\/active_storage\/postgresql\/.*\/avatar\.png/, url) end end diff --git a/test/models/api_service_test.rb b/test/models/api_service_test.rb index da2ab9198..81088cd52 100644 --- a/test/models/api_service_test.rb +++ b/test/models/api_service_test.rb @@ -57,7 +57,9 @@ class APIServiceTest < ActiveSupport::TestCase end test "can create record" do - APIService.create!(create_params) + assert_nothing_raised do + APIService.create!(create_params) + end end test "soft delete also soft deletes language_models" do diff --git a/test/models/message/version_test.rb b/test/models/message/version_test.rb index 018144269..16b31ae75 100644 --- a/test/models/message/version_test.rb +++ b/test/models/message/version_test.rb @@ -65,8 +65,10 @@ class Message::VersionTest < ActiveSupport::TestCase end test "creating a message with branched true AND branched_from_version specified SUCCEEDS" do - Current.user = users(:keith) - conversations(:versioned).messages.create!(assistant: assistants(:samantha), content_text: "What is your name?", index: 2, version: 3, branched: true, branched_from_version: 2) + assert_nothing_raised do + Current.user = users(:keith) + conversations(:versioned).messages.create!(assistant: assistants(:samantha), content_text: "What is your name?", index: 2, version: 3, branched: true, branched_from_version: 2) + end end test "creating a new messages for a SPECIFIC INDEX and SPECIFIC VERSION fails if the VERSION is SKIPPING a number" do diff --git a/test/services/ai_backend/anthropic_test.rb b/test/services/ai_backend/anthropic_test.rb index 7791ae20d..ed38a6014 100644 --- a/test/services/ai_backend/anthropic_test.rb +++ b/test/services/ai_backend/anthropic_test.rb @@ -48,11 +48,11 @@ class AIBackend::AnthropicTest < ActiveSupport::TestCase end end - test "preceding_conversation_messages only considers messages on the intended conversation version and includes the correct names" do - # TODO - end + # test "preceding_conversation_messages only considers messages on the intended conversation version and includes the correct names" do + # # TODO + # end - test "preceding_conversation_messages includes the appropriate tool details" do - # TODO - end + # test "preceding_conversation_messages includes the appropriate tool details" do + # # TODO + # end end From 78962e7f6c6f8105f68bf6fd48058dde1d84dfa6 Mon Sep 17 00:00:00 2001 From: Justin Vallelonga Date: Sun, 22 Dec 2024 11:25:44 +0700 Subject: [PATCH 11/12] removes user fixture to fix association --- test/fixtures/conversations.yml | 2 +- test/fixtures/users.yml | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/test/fixtures/conversations.yml b/test/fixtures/conversations.yml index 4a51ab95f..0f3b083a7 100644 --- a/test/fixtures/conversations.yml +++ b/test/fixtures/conversations.yml @@ -87,7 +87,7 @@ weather: last_assistant_message: weather_explained image_generation: - user: christoph + user: keith assistant: samantha title: Generating an image last_assistant_message: image_generation_explained diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index c8fa13c09..cb56107ee 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -14,8 +14,3 @@ taylor: first_name: Taylor registered_at: 2024-05-31 08:40:05 preferences: {} - -christoph: - first_name: Christoph - registered_at: 2024-08-25 08:08:08 - preferences: {} From 2d35c178f806bcb97396634948821308e650f455 Mon Sep 17 00:00:00 2001 From: Justin Vallelonga Date: Sun, 22 Dec 2024 14:53:31 +0700 Subject: [PATCH 12/12] fix test --- test/jobs/get_next_ai_message_job_openai_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jobs/get_next_ai_message_job_openai_test.rb b/test/jobs/get_next_ai_message_job_openai_test.rb index 612470baf..9d9e8f27a 100644 --- a/test/jobs/get_next_ai_message_job_openai_test.rb +++ b/test/jobs/get_next_ai_message_job_openai_test.rb @@ -103,7 +103,7 @@ class GetNextAIMessageJobOpenaiTest < ActiveJob::TestCase json_content_text = JSON.parse(content_text) assert_equal image_generation_prompt, json_content_text["prompt_given"], "First new message should have the result of calling the tool" assert first_new_message.tool_call_id.present? - assert first_new_message.content_tool_calls.blank? + assert first_new_message.content_tool_calls.present? assert_equal @image_generation_message.content_tool_calls.dig(0, :id), first_new_message.tool_call_id, "ID of tool execution should have matched decision to call the tool" assert first_new_message.finished?, "This message SHOULD HAVE been considered finished"