Skip to content

Commit e2ec8ac

Browse files
committed
claude 3 api support (#642)
1 parent 381cea3 commit e2ec8ac

File tree

3 files changed

+41
-30
lines changed

3 files changed

+41
-30
lines changed

src/config/index.mjs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,14 @@ export const chatgptApiModelKeys = [
4848
]
4949
export const customApiModelKeys = ['customModel']
5050
export const azureOpenAiApiModelKeys = ['azureOpenAi']
51-
export const claudeApiModelKeys = ['claude2Api']
51+
export const claudeApiModelKeys = [
52+
'claude12Api',
53+
'claude2Api',
54+
'claude21Api',
55+
'claude3HaikuApi',
56+
'claude3SonnetApi',
57+
'claude3OpusApi',
58+
]
5259
export const chatglmApiModelKeys = ['chatglmTurbo']
5360
export const githubThirdPartyApiModelKeys = ['waylaidwandererApi']
5461
export const poeWebModelKeys = [
@@ -101,7 +108,15 @@ export const Models = {
101108
},
102109

103110
claude2WebFree: { value: '', desc: 'Claude.ai (Web)' },
104-
claude2Api: { value: '', desc: 'Claude.ai (API, Claude 2)' },
111+
claude12Api: { value: 'claude-instant-1.2', desc: 'Claude.ai (API, Claude Instant 1.2)' },
112+
claude2Api: { value: 'claude-2.0', desc: 'Claude.ai (API, Claude 2)' },
113+
claude21Api: { value: 'claude-2.1', desc: 'Claude.ai (API, Claude 2.1)' },
114+
claude3HaikuApi: {
115+
value: 'claude-3-haiku-20240307',
116+
desc: 'Claude.ai (API, Claude 3 Haiku)',
117+
},
118+
claude3SonnetApi: { value: 'claude-3-sonnet-20240229', desc: 'Claude.ai (API, Claude 3 Sonnet)' },
119+
claude3OpusApi: { value: 'claude-3-opus-20240229', desc: 'Claude.ai (API, Claude 3 Opus)' },
105120

106121
bingFree4: { value: '', desc: 'Bing (Web, GPT-4)' },
107122
bingFreeSydney: { value: '', desc: 'Bing (Web, GPT-4, Sydney)' },
@@ -343,7 +358,7 @@ export function isUsingAzureOpenAi(configOrSession) {
343358
return azureOpenAiApiModelKeys.includes(configOrSession.modelName)
344359
}
345360

346-
export function isUsingClaude2Api(configOrSession) {
361+
export function isUsingClaudeApi(configOrSession) {
347362
return claudeApiModelKeys.includes(configOrSession.modelName)
348363
}
349364

src/popup/sections/GeneralPart.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
isUsingOpenAiApiKey,
66
isUsingAzureOpenAi,
77
isUsingChatGLMApi,
8-
isUsingClaude2Api,
8+
isUsingClaudeApi,
99
isUsingCustomModel,
1010
isUsingCustomNameOnlyModel,
1111
isUsingGithubThirdPartyApi,
@@ -145,7 +145,7 @@ export function GeneralPart({ config, updateConfig }) {
145145
isUsingMultiModeModel(config) ||
146146
isUsingCustomModel(config) ||
147147
isUsingAzureOpenAi(config) ||
148-
isUsingClaude2Api(config) ||
148+
isUsingClaudeApi(config) ||
149149
isUsingCustomNameOnlyModel(config) ||
150150
isUsingMoonshotApi(config)
151151
? 'width: 50%;'
@@ -264,7 +264,7 @@ export function GeneralPart({ config, updateConfig }) {
264264
}}
265265
/>
266266
)}
267-
{isUsingClaude2Api(config) && (
267+
{isUsingClaudeApi(config) && (
268268
<input
269269
type="password"
270270
style="width: 50%;"

src/services/apis/claude-api.mjs

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { getUserConfig } from '../../config/index.mjs'
1+
import { getUserConfig, Models } from '../../config/index.mjs'
22
import { pushRecord, setAbortController } from './shared.mjs'
33
import { fetchSSE } from '../../utils/fetch-sse.mjs'
44
import { isEmpty } from 'lodash-es'
5+
import { getConversationPairs } from '../../utils/get-conversation-pairs.mjs'
56

67
/**
78
* @param {Runtime.Port} port
@@ -11,28 +12,28 @@ import { isEmpty } from 'lodash-es'
1112
export async function generateAnswersWithClaudeApi(port, question, session) {
1213
const { controller, messageListener, disconnectListener } = setAbortController(port)
1314
const config = await getUserConfig()
15+
const modelName = session.modelName
1416

15-
let prompt = ''
16-
for (const record of session.conversationRecords.slice(-config.maxConversationContextLength)) {
17-
prompt += '\n\nHuman: ' + record.question + '\n\nAssistant: ' + record.answer
18-
}
19-
prompt += `\n\nHuman: ${question}\n\nAssistant:`
17+
const prompt = getConversationPairs(
18+
session.conversationRecords.slice(-config.maxConversationContextLength),
19+
false,
20+
)
21+
prompt.push({ role: 'user', content: question })
2022

2123
let answer = ''
22-
await fetchSSE(`https://api.anthropic.com/v1/complete`, {
24+
await fetchSSE(`https://api.anthropic.com/v1/messages`, {
2325
method: 'POST',
2426
signal: controller.signal,
2527
headers: {
2628
'Content-Type': 'application/json',
27-
accept: 'application/json',
2829
'anthropic-version': '2023-06-01',
2930
'x-api-key': config.claudeApiKey,
3031
},
3132
body: JSON.stringify({
32-
model: 'claude-2',
33-
prompt: prompt,
33+
model: Models[modelName].value,
34+
messages: prompt,
3435
stream: true,
35-
max_tokens_to_sample: config.maxResponseTokenLength,
36+
max_tokens: config.maxResponseTokenLength,
3637
temperature: config.temperature,
3738
}),
3839
onMessage(message) {
@@ -45,22 +46,17 @@ export async function generateAnswersWithClaudeApi(port, question, session) {
4546
console.debug('json error', error)
4647
return
4748
}
48-
49-
// The Claude v2 API may send metadata fields, handle them here
50-
if (data.conversationId) session.conversationId = data.conversationId
51-
if (data.parentMessageId) session.parentMessageId = data.parentMessageId
52-
53-
// In Claude's case, the "completion" key holds the text
54-
if (data.completion) {
55-
answer += data.completion
56-
port.postMessage({ answer: answer, done: false, session: null })
57-
}
58-
59-
// Check if the message indicates that Claude is done
60-
if (data.stop_reason === 'stop_sequence') {
49+
if (data?.type === 'message_stop') {
6150
pushRecord(session, question, answer)
6251
console.debug('conversation history', { content: session.conversationRecords })
6352
port.postMessage({ answer: null, done: true, session: session })
53+
return
54+
}
55+
56+
const delta = data?.delta?.text
57+
if (delta) {
58+
answer += delta
59+
port.postMessage({ answer: answer, done: false, session: null })
6460
}
6561
},
6662
async onStart() {},

0 commit comments

Comments
 (0)