FEATURE: add Claude 3 Haiku bot support (#552)

it is close in performance to GPT 4 at a fraction of the cost,
nice to add it to the mix.

Also improves a test case to simulate streaming, I am hunting for
the "calls" word that is jumping into function calls and can't quite
find it.
This commit is contained in:
Sam 2024-04-03 16:06:27 +11:00 committed by GitHub
parent 08b53e851c
commit 6f5f34184b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 28 additions and 5 deletions

View File

@ -164,7 +164,7 @@ en:
#### Group-Specific Access to AI Personas #### Group-Specific Access to AI Personas
Moreover, you can set it up so that certain user groups have access to specific personas. This means you can have different AI behaviors for different sections of your forum, further enhancing the diversity and richness of your community's interactions. Moreover, you can set it up so that certain user groups have access to specific personas. This means you can have different AI behaviors for different sections of your forum, further enhancing the diversity and richness of your community's interactions.
uploads: uploads:
title: "Uploads" title: "Uploads"
description: "Your AI persona will be able to search and reference the content of included files. Uploaded files must be formatted as plaintext (.txt)" description: "Your AI persona will be able to search and reference the content of included files. Uploaded files must be formatted as plaintext (.txt)"
@ -265,6 +265,7 @@ en:
fake: "Fake Test Bot" fake: "Fake Test Bot"
claude-3-opus: "Claude 3 Opus" claude-3-opus: "Claude 3 Opus"
claude-3-sonnet: "Claude 3 Sonnet" claude-3-sonnet: "Claude 3 Sonnet"
claude-3-haiku: "Claude 3 Haiku"
gpt-4: "GPT-4" gpt-4: "GPT-4"
gpt-4-turbo: "GPT-4 Turbo" gpt-4-turbo: "GPT-4 Turbo"
gpt-3: gpt-3:

View File

@ -334,6 +334,7 @@ discourse_ai:
- mixtral-8x7B-Instruct-V0.1 - mixtral-8x7B-Instruct-V0.1
- claude-3-opus - claude-3-opus
- claude-3-sonnet - claude-3-sonnet
- claude-3-haiku
ai_bot_add_to_header: ai_bot_add_to_header:
default: true default: true
client: true client: true

View File

@ -188,6 +188,12 @@ module DiscourseAi
else else
"anthropic:claude-3-sonnet" "anthropic:claude-3-sonnet"
end end
when DiscourseAi::AiBot::EntryPoint::CLAUDE_3_HAIKU_ID
if DiscourseAi::Completions::Endpoints::AwsBedrock.correctly_configured?("claude-3-haiku")
"aws_bedrock:claude-3-haiku"
else
"anthropic:claude-3-haiku"
end
else else
nil nil
end end

View File

@ -16,6 +16,7 @@ module DiscourseAi
FAKE_ID = -116 # only used for dev and test FAKE_ID = -116 # only used for dev and test
CLAUDE_3_OPUS_ID = -117 CLAUDE_3_OPUS_ID = -117
CLAUDE_3_SONNET_ID = -118 CLAUDE_3_SONNET_ID = -118
CLAUDE_3_HAIKU_ID = -119
BOTS = [ BOTS = [
[GPT4_ID, "gpt4_bot", "gpt-4"], [GPT4_ID, "gpt4_bot", "gpt-4"],
@ -27,6 +28,7 @@ module DiscourseAi
[FAKE_ID, "fake_bot", "fake"], [FAKE_ID, "fake_bot", "fake"],
[CLAUDE_3_OPUS_ID, "claude_3_opus_bot", "claude-3-opus"], [CLAUDE_3_OPUS_ID, "claude_3_opus_bot", "claude-3-opus"],
[CLAUDE_3_SONNET_ID, "claude_3_sonnet_bot", "claude-3-sonnet"], [CLAUDE_3_SONNET_ID, "claude_3_sonnet_bot", "claude-3-sonnet"],
[CLAUDE_3_HAIKU_ID, "claude_3_haiku_bot", "claude-3-haiku"],
] ]
BOT_USER_IDS = BOTS.map(&:first) BOT_USER_IDS = BOTS.map(&:first)
@ -63,6 +65,8 @@ module DiscourseAi
CLAUDE_3_OPUS_ID CLAUDE_3_OPUS_ID
in "claude-3-sonnet" in "claude-3-sonnet"
CLAUDE_3_SONNET_ID CLAUDE_3_SONNET_ID
in "claude-3-haiku"
CLAUDE_3_HAIKU_ID
else else
nil nil
end end

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative "endpoint_compliance"
RSpec.describe DiscourseAi::Completions::Endpoints::Anthropic do RSpec.describe DiscourseAi::Completions::Endpoints::Anthropic do
let(:llm) { DiscourseAi::Completions::Llm.proxy("anthropic:claude-3-opus") } let(:llm) { DiscourseAi::Completions::Llm.proxy("anthropic:claude-3-opus") }
@ -196,11 +197,17 @@ RSpec.describe DiscourseAi::Completions::Endpoints::Anthropic do
data: {"type":"message_stop"} data: {"type":"message_stop"}
STRING STRING
stub_request(:post, "https://api.anthropic.com/v1/messages").to_return(status: 200, body: body)
result = +"" result = +""
llm.generate(prompt_with_google_tool, user: Discourse.system_user) do |partial| body = body.scan(/.*\n/)
result << partial EndpointMock.with_chunk_array_support do
stub_request(:post, "https://api.anthropic.com/v1/messages").to_return(
status: 200,
body: body,
)
llm.generate(prompt_with_google_tool, user: Discourse.system_user) do |partial|
result << partial
end
end end
expected = (<<~TEXT).strip expected = (<<~TEXT).strip

View File

@ -108,6 +108,10 @@ class EndpointMock
::FinalDestination.send(:const_set, :HTTP, @original_net_http) ::FinalDestination.send(:const_set, :HTTP, @original_net_http)
end end
def self.with_chunk_array_support(&blk)
self.new(nil).with_chunk_array_support(&blk)
end
protected protected
# Copied from https://github.com/bblimke/webmock/issues/629 # Copied from https://github.com/bblimke/webmock/issues/629