1
1
import { getUserConfig } from '../../config/index.mjs'
2
- import { getChatSystemPromptBase , pushRecord , setAbortController } from './shared.mjs'
3
- import { getConversationPairs } from '../../utils/get-conversation-pairs.mjs'
2
+ import { pushRecord , setAbortController } from './shared.mjs'
4
3
import { fetchSSE } from '../../utils/fetch-sse.mjs'
5
4
import { isEmpty } from 'lodash-es'
6
5
@@ -13,75 +12,69 @@ export async function generateAnswersWithClaudeApi(port, question, session) {
13
12
const { controller, messageListener, disconnectListener } = setAbortController ( port )
14
13
const config = await getUserConfig ( )
15
14
16
- const prompt = getConversationPairs (
17
- session . conversationRecords . slice ( - config . maxConversationContextLength ) ,
18
- false ,
19
- )
20
- prompt . unshift ( { role : 'Assistant' , content : await getChatSystemPromptBase ( ) } )
21
- prompt . push ( { role : 'Human' , content : question } )
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:`
22
20
23
21
let answer = ''
24
- await fetchSSE (
25
- `https://api.anthropic.com/v1/complete` ,
26
- {
27
- method : 'POST' ,
28
- signal : controller . signal ,
29
- headers : {
30
- 'Content-Type' : 'application/json' ,
31
- 'accept' : 'application/json' ,
32
- 'anthropic-version' : '2023-06-01' ,
33
- 'x-api-key' : config . claudeApiKey ,
34
- } ,
35
- body : JSON . stringify ( {
36
- model : "claude-2" ,
37
- prompt : "\n\nHuman: " + question + "\n\nAssistant:" ,
38
- stream : true ,
39
- max_tokens_to_sample : config . maxResponseTokenLength ,
40
- temperature : config . temperature ,
41
- } ) ,
42
- onMessage ( message ) {
43
- console . debug ( 'sse message' , message ) ;
44
-
45
- let data ;
46
- try {
47
- data = JSON . parse ( message ) ;
48
- } catch ( error ) {
49
- console . debug ( 'json error' , error ) ;
50
- return ;
51
- }
52
-
53
- // The Claude v2 API may send metadata fields, handle them here
54
- if ( data . conversationId ) session . conversationId = data . conversationId ;
55
- if ( data . parentMessageId ) session . parentMessageId = data . parentMessageId ;
56
-
57
- // In Claude's case, the "completion" key holds the text
58
- if ( data . completion ) {
59
- answer += data . completion ;
60
- port . postMessage ( { answer : answer , done : false , session : null } ) ;
61
- }
62
-
63
- // Check if the message indicates that Claude is done
64
- if ( data . stop_reason === 'stop_sequence' ) {
65
- pushRecord ( session , question , answer ) ;
66
- console . debug ( 'conversation history' , { content : session . conversationRecords } ) ;
67
- port . postMessage ( { answer : null , done : true , session : session } ) ;
68
- }
69
- } ,
70
- async onStart ( ) { } ,
71
- async onEnd ( ) {
72
- port . postMessage ( { done : true } )
73
- port . onMessage . removeListener ( messageListener )
74
- port . onDisconnect . removeListener ( disconnectListener )
75
- } ,
76
- async onError ( resp ) {
77
- port . onMessage . removeListener ( messageListener )
78
- port . onDisconnect . removeListener ( disconnectListener )
79
- if ( resp instanceof Error ) throw resp
80
- const error = await resp . json ( ) . catch ( ( ) => ( { } ) )
81
- throw new Error (
82
- ! isEmpty ( error ) ? JSON . stringify ( error ) : `${ resp . status } ${ resp . statusText } ` ,
83
- )
84
- } ,
22
+ await fetchSSE ( `https://api.anthropic.com/v1/complete` , {
23
+ method : 'POST' ,
24
+ signal : controller . signal ,
25
+ headers : {
26
+ 'Content-Type' : 'application/json' ,
27
+ accept : 'application/json' ,
28
+ 'anthropic-version' : '2023-06-01' ,
29
+ 'x-api-key' : config . claudeApiKey ,
85
30
} ,
86
- )
31
+ body : JSON . stringify ( {
32
+ model : 'claude-2' ,
33
+ prompt : prompt ,
34
+ stream : true ,
35
+ max_tokens_to_sample : config . maxResponseTokenLength ,
36
+ temperature : config . temperature ,
37
+ } ) ,
38
+ onMessage ( message ) {
39
+ console . debug ( 'sse message' , message )
40
+
41
+ let data
42
+ try {
43
+ data = JSON . parse ( message )
44
+ } catch ( error ) {
45
+ console . debug ( 'json error' , error )
46
+ return
47
+ }
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' ) {
61
+ pushRecord ( session , question , answer )
62
+ console . debug ( 'conversation history' , { content : session . conversationRecords } )
63
+ port . postMessage ( { answer : null , done : true , session : session } )
64
+ }
65
+ } ,
66
+ async onStart ( ) { } ,
67
+ async onEnd ( ) {
68
+ port . postMessage ( { done : true } )
69
+ port . onMessage . removeListener ( messageListener )
70
+ port . onDisconnect . removeListener ( disconnectListener )
71
+ } ,
72
+ async onError ( resp ) {
73
+ port . onMessage . removeListener ( messageListener )
74
+ port . onDisconnect . removeListener ( disconnectListener )
75
+ if ( resp instanceof Error ) throw resp
76
+ const error = await resp . json ( ) . catch ( ( ) => ( { } ) )
77
+ throw new Error ( ! isEmpty ( error ) ? JSON . stringify ( error ) : `${ resp . status } ${ resp . statusText } ` )
78
+ } ,
79
+ } )
87
80
}
0 commit comments