From 2c1c7d5aace09086d61a55a45c537539602e6bc4 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Mon, 4 Nov 2024 15:00:31 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20feat:=20Claude=203.5=20Haiku?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 2 +- api/app/clients/AnthropicClient.js | 7 ++++--- api/models/tx.js | 4 ++++ api/models/tx.spec.js | 16 ++++++++++++++++ api/utils/tokens.js | 2 ++ packages/data-provider/src/config.ts | 1 + 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index f77bb75af27..ff9edb2fc58 100644 --- a/.env.example +++ b/.env.example @@ -82,7 +82,7 @@ PROXY= #============# ANTHROPIC_API_KEY=user_provided -# ANTHROPIC_MODELS=claude-3-5-sonnet-20241022,claude-3-5-sonnet-latest,claude-3-5-sonnet-20240620,claude-3-opus-20240229,claude-3-sonnet-20240229,claude-3-haiku-20240307,claude-2.1,claude-2,claude-1.2,claude-1,claude-1-100k,claude-instant-1,claude-instant-1-100k +# ANTHROPIC_MODELS=claude-3-5-haiku-20241022,claude-3-5-sonnet-20241022,claude-3-5-sonnet-latest,claude-3-5-sonnet-20240620,claude-3-opus-20240229,claude-3-sonnet-20240229,claude-3-haiku-20240307,claude-2.1,claude-2,claude-1.2,claude-1,claude-1-100k,claude-instant-1,claude-instant-1-100k # ANTHROPIC_REVERSE_PROXY= #============# diff --git a/api/app/clients/AnthropicClient.js b/api/app/clients/AnthropicClient.js index ff0dc4de5b7..6e9d4accc20 100644 --- a/api/app/clients/AnthropicClient.js +++ b/api/app/clients/AnthropicClient.js @@ -98,8 +98,8 @@ class AnthropicClient extends BaseClient { ); const modelMatch = matchModelName(this.modelOptions.model, EModelEndpoint.anthropic); - this.isClaude3 = modelMatch.startsWith('claude-3'); - this.isLegacyOutput = !modelMatch.startsWith('claude-3-5-sonnet'); + this.isClaude3 = modelMatch.includes('claude-3'); + this.isLegacyOutput = !modelMatch.includes('claude-3-5-sonnet'); this.supportsCacheControl = this.options.promptCache && this.checkPromptCacheSupport(modelMatch); @@ -634,7 +634,7 @@ class AnthropicClient extends BaseClient { ); }; - if (this.modelOptions.model.startsWith('claude-3')) { + if (this.modelOptions.model.includes('claude-3')) { await buildMessagesPayload(); processTokens(); return { @@ -687,6 +687,7 @@ class AnthropicClient extends BaseClient { } if ( modelMatch === 'claude-3-5-sonnet' || + modelMatch === 'claude-3-5-haiku' || modelMatch === 'claude-3-haiku' || modelMatch === 'claude-3-opus' ) { diff --git a/api/models/tx.js b/api/models/tx.js index 1b1501bd282..c9a88b6d9db 100644 --- a/api/models/tx.js +++ b/api/models/tx.js @@ -56,6 +56,8 @@ const tokenValues = Object.assign( 'claude-3-sonnet': { prompt: 3, completion: 15 }, 'claude-3-5-sonnet': { prompt: 3, completion: 15 }, 'claude-3.5-sonnet': { prompt: 3, completion: 15 }, + 'claude-3-5-haiku': { prompt: 1, completion: 5 }, + 'claude-3.5-haiku': { prompt: 1, completion: 5 }, 'claude-3-haiku': { prompt: 0.25, completion: 1.25 }, 'claude-2.1': { prompt: 8, completion: 24 }, 'claude-2': { prompt: 8, completion: 24 }, @@ -81,6 +83,8 @@ const tokenValues = Object.assign( const cacheTokenValues = { 'claude-3.5-sonnet': { write: 3.75, read: 0.3 }, 'claude-3-5-sonnet': { write: 3.75, read: 0.3 }, + 'claude-3.5-haiku': { write: 1.25, read: 0.1 }, + 'claude-3-5-haiku': { write: 1.25, read: 0.1 }, 'claude-3-haiku': { write: 0.3, read: 0.03 }, }; diff --git a/api/models/tx.spec.js b/api/models/tx.spec.js index 730c33a05d7..d9ffafcb1e0 100644 --- a/api/models/tx.spec.js +++ b/api/models/tx.spec.js @@ -92,6 +92,20 @@ describe('getValueKey', () => { expect(getValueKey('claude-3.5-sonnet-turbo')).toBe('claude-3.5-sonnet'); expect(getValueKey('claude-3.5-sonnet-0125')).toBe('claude-3.5-sonnet'); }); + + it('should return "claude-3-5-haiku" for model type of "claude-3-5-haiku-"', () => { + expect(getValueKey('claude-3-5-haiku-20240620')).toBe('claude-3-5-haiku'); + expect(getValueKey('anthropic/claude-3-5-haiku')).toBe('claude-3-5-haiku'); + expect(getValueKey('claude-3-5-haiku-turbo')).toBe('claude-3-5-haiku'); + expect(getValueKey('claude-3-5-haiku-0125')).toBe('claude-3-5-haiku'); + }); + + it('should return "claude-3.5-haiku" for model type of "claude-3.5-haiku-"', () => { + expect(getValueKey('claude-3.5-haiku-20240620')).toBe('claude-3.5-haiku'); + expect(getValueKey('anthropic/claude-3.5-haiku')).toBe('claude-3.5-haiku'); + expect(getValueKey('claude-3.5-haiku-turbo')).toBe('claude-3.5-haiku'); + expect(getValueKey('claude-3.5-haiku-0125')).toBe('claude-3.5-haiku'); + }); }); describe('getMultiplier', () => { @@ -248,6 +262,8 @@ describe('getCacheMultiplier', () => { it('should return the correct cache multiplier for a given valueKey and cacheType', () => { expect(getCacheMultiplier({ valueKey: 'claude-3-5-sonnet', cacheType: 'write' })).toBe(3.75); expect(getCacheMultiplier({ valueKey: 'claude-3-5-sonnet', cacheType: 'read' })).toBe(0.3); + expect(getCacheMultiplier({ valueKey: 'claude-3-5-haiku', cacheType: 'write' })).toBe(1.25); + expect(getCacheMultiplier({ valueKey: 'claude-3-5-haiku', cacheType: 'read' })).toBe(0.1); expect(getCacheMultiplier({ valueKey: 'claude-3-haiku', cacheType: 'write' })).toBe(0.3); expect(getCacheMultiplier({ valueKey: 'claude-3-haiku', cacheType: 'read' })).toBe(0.03); }); diff --git a/api/utils/tokens.js b/api/utils/tokens.js index 92833035af6..4bf66508f87 100644 --- a/api/utils/tokens.js +++ b/api/utils/tokens.js @@ -70,6 +70,8 @@ const anthropicModels = { 'claude-3-haiku': 200000, 'claude-3-sonnet': 200000, 'claude-3-opus': 200000, + 'claude-3.5-haiku': 200000, + 'claude-3-5-haiku': 200000, 'claude-3-5-sonnet': 200000, 'claude-3.5-sonnet': 200000, 'claude-3-5-sonnet-latest': 200000, diff --git a/packages/data-provider/src/config.ts b/packages/data-provider/src/config.ts index 81ff5eca418..5f503203313 100644 --- a/packages/data-provider/src/config.ts +++ b/packages/data-provider/src/config.ts @@ -608,6 +608,7 @@ const sharedOpenAIModels = [ ]; const sharedAnthropicModels = [ + 'claude-3-5-haiku-20241022', 'claude-3-5-sonnet-20241022', 'claude-3-5-sonnet-20240620', 'claude-3-5-sonnet-latest',