1
1
var lang = require ( "./lang.js" ) ;
2
+ var ChatGPTModels = [
3
+ "gpt-3.5-turbo" ,
4
+ "gpt-3.5-turbo-0301" ,
5
+ "gpt-4" ,
6
+ "gpt-4-0314" ,
7
+ "gpt-4-32k" ,
8
+ "gpt-4-32k-0314" ,
9
+ ] ;
2
10
3
11
function supportLanguages ( ) {
4
12
return lang . supportLanguages . map ( ( [ standardLang ] ) => standardLang ) ;
5
13
}
6
14
7
- function translate ( query , completion ) {
8
- const ChatGPTModels = [
9
- "gpt-3.5-turbo" ,
10
- "gpt-3.5-turbo-0301" ,
11
- "gpt-4" ,
12
- "gpt-4-0314" ,
13
- "gpt-4-32k" ,
14
- "gpt-4-32k-0314" ,
15
- ] ;
15
+ function buildHeader ( isAzureServiceProvider , apiKey ) {
16
+ return {
17
+ "Content-Type" : "application/json" ,
18
+ [ isAzureServiceProvider ? "api-key" : "Authorization" ] : isAzureServiceProvider ? apiKey : `Bearer ${ apiKey } `
19
+ } ;
20
+ }
16
21
17
- const { model, apiKeys, apiUrl, deploymentName } = $option ;
22
+ function generatePrompts ( query ) {
23
+ let systemPrompt = "You are a translation engine that can only translate text and cannot interpret it." ;
24
+ let userPrompt = `translate from ${ lang . langMap . get ( query . detectFrom ) || query . detectFrom } to ${ lang . langMap . get ( query . detectTo ) || query . detectTo } ` ;
18
25
19
- const apiKeySelection = apiKeys . split ( "," ) . map ( key => key . trim ( ) ) ;
20
- const apiKey = apiKeySelection [ Math . floor ( Math . random ( ) * apiKeySelection . length ) ] ;
21
-
22
- const isChatGPTModel = ChatGPTModels . includes ( model ) ;
23
- const isAzureServiceProvider = apiUrl . includes ( "openai.azure.com" ) ;
24
- let apiUrlPath = isChatGPTModel ? "/v1/chat/completions" : "/v1/completions" ;
25
-
26
- if ( isAzureServiceProvider ) {
27
- if ( deploymentName ) {
28
- apiUrlPath = `/openai/deployments/${ deploymentName } ` ;
29
- apiUrlPath += isChatGPTModel ? '/chat/completions?api-version=2023-03-15-preview' : '/completions?api-version=2022-12-01' ;
30
- } else {
31
- completion ( {
32
- error : {
33
- type : "param" ,
34
- message : `配置错误 - 未填写 Deployment Name` ,
35
- addition : "The name of your model deployment. You're required to first deploy a model before you can make calls" ,
36
- } ,
37
- } ) ;
38
- }
39
- }
40
-
41
- let systemPrompt =
42
- "You are a translation engine that can only translate text and cannot interpret it." ;
43
- let userPrompt = `translate from ${ lang . langMap . get ( query . detectFrom ) || query . detectFrom
44
- } to ${ lang . langMap . get ( query . detectTo ) || query . detectTo } `;
45
26
if ( query . detectTo === "wyw" || query . detectTo === "yue" ) {
46
27
userPrompt = `翻译成${ lang . langMap . get ( query . detectTo ) || query . detectTo } ` ;
47
28
}
@@ -68,95 +49,139 @@ function translate(query, completion) {
68
49
userPrompt = "polish this sentence" ;
69
50
}
70
51
}
71
-
72
- const header = {
73
- "Content-Type" : "application/json" ,
74
- } ;
75
- const body = {
76
- model : $option . model ,
52
+
53
+ userPrompt = `${ userPrompt }
54
+ Text:
55
+ """
56
+ ${ query . text }
57
+ """
58
+ `
59
+
60
+ return { systemPrompt, userPrompt } ;
61
+ }
62
+
63
+ function buildRequestBody ( model , isChatGPTModel , query ) {
64
+ const { systemPrompt, userPrompt } = generatePrompts ( query ) ;
65
+ const standardBody = {
66
+ model,
77
67
temperature : 0 ,
78
68
max_tokens : 1000 ,
79
69
top_p : 1 ,
80
70
frequency_penalty : 1 ,
81
71
presence_penalty : 1 ,
82
72
} ;
83
- userPrompt = `${ userPrompt } :\n\n"${ query . text } " =>` ;
84
-
85
- if ( isAzureServiceProvider ) {
86
- header [ "api-key" ] = `${ apiKey } `
87
- } else {
88
- header [ "Authorization" ] = `Bearer ${ apiKey } `
89
- }
90
73
if ( isChatGPTModel ) {
91
- body [ "messages" ] = [
92
- {
93
- role : "system" ,
94
- content : systemPrompt ,
74
+ return {
75
+ ...standardBody ,
76
+ messages : [
77
+ {
78
+ role : "system" ,
79
+ content : systemPrompt ,
80
+ } ,
81
+ {
82
+ role : "user" ,
83
+ content : userPrompt ,
84
+ } ,
85
+ ] ,
86
+ } ;
87
+ }
88
+ return {
89
+ ...standardBody ,
90
+ prompt : userPrompt ,
91
+ } ;
92
+ }
93
+
94
+ function handleError ( completion , result ) {
95
+ const { statusCode } = result . response ;
96
+ const reason = ( statusCode >= 400 && statusCode < 500 ) ? "param" : "api" ;
97
+ completion ( {
98
+ error : {
99
+ type : reason ,
100
+ message : `接口响应错误 - ${ result . data . error . message } ` ,
101
+ addition : JSON . stringify ( result ) ,
102
+ } ,
103
+ } ) ;
104
+ }
105
+
106
+ function handleResponse ( completion , isChatGPTModel , query , result ) {
107
+ const { choices } = result . data ;
108
+
109
+ if ( ! choices || choices . length === 0 ) {
110
+ completion ( {
111
+ error : {
112
+ type : "api" ,
113
+ message : "接口未返回结果" ,
95
114
} ,
96
- {
97
- role : "user" ,
98
- content : userPrompt ,
115
+ } ) ;
116
+ return ;
117
+ }
118
+
119
+ let targetText = ( isChatGPTModel ? choices [ 0 ] . message . content : choices [ 0 ] . text ) . trim ( ) ;
120
+
121
+ if ( targetText . startsWith ( '"' ) || targetText . startsWith ( "「" ) ) {
122
+ targetText = targetText . slice ( 1 ) ;
123
+ }
124
+ if ( targetText . endsWith ( '"' ) || targetText . endsWith ( "」" ) ) {
125
+ targetText = targetText . slice ( 0 , - 1 ) ;
126
+ }
127
+
128
+ completion ( {
129
+ result : {
130
+ from : query . detectFrom ,
131
+ to : query . detectTo ,
132
+ toParagraphs : targetText . split ( "\n" ) ,
133
+ } ,
134
+ } ) ;
135
+ }
136
+
137
+ function translate ( query , completion ) {
138
+ if ( ! lang . langMap . get ( query . detectTo ) ) {
139
+ completion ( {
140
+ error : {
141
+ type : "unsupportLanguage" ,
142
+ message : "不支持该语种" ,
99
143
} ,
100
- { role : "user" , content : `"${ query . text } "` } ,
101
- ] ;
102
- } else {
103
- body [ "prompt" ] = userPrompt ;
144
+ } ) ;
104
145
}
105
146
147
+ const { model, apiKeys, apiUrl, deploymentName } = $option ;
148
+
149
+ const apiKeySelection = apiKeys . split ( "," ) . map ( key => key . trim ( ) ) ;
150
+ const apiKey = apiKeySelection [ Math . floor ( Math . random ( ) * apiKeySelection . length ) ] ;
151
+
152
+ const isChatGPTModel = ChatGPTModels . includes ( model ) ;
153
+ const isAzureServiceProvider = apiUrl . includes ( "openai.azure.com" ) ;
154
+ let apiUrlPath = isChatGPTModel ? "/v1/chat/completions" : "/v1/completions" ;
155
+
156
+ if ( isAzureServiceProvider ) {
157
+ if ( deploymentName ) {
158
+ apiUrlPath = `/openai/deployments/${ deploymentName } ` ;
159
+ apiUrlPath += isChatGPTModel ? '/chat/completions?api-version=2023-03-15-preview' : '/completions?api-version=2022-12-01' ;
160
+ } else {
161
+ completion ( {
162
+ error : {
163
+ type : "secretKey" ,
164
+ message : `配置错误 - 未填写 Deployment Name` ,
165
+ } ,
166
+ } ) ;
167
+ }
168
+ }
169
+
170
+ const header = buildHeader ( isAzureServiceProvider , apiKey ) ;
171
+ const body = buildRequestBody ( model , isChatGPTModel , query ) ;
172
+
106
173
( async ( ) => {
107
- const resp = await $http . request ( {
174
+ const result = await $http . request ( {
108
175
method : "POST" ,
109
176
url : apiUrl + apiUrlPath ,
110
177
header,
111
178
body,
112
179
} ) ;
113
180
114
- if ( resp . error ) {
115
- const { statusCode } = resp . response ;
116
- let reason ;
117
- if ( statusCode >= 400 && statusCode < 500 ) {
118
- reason = "param" ;
119
- } else {
120
- reason = "api" ;
121
- }
122
- completion ( {
123
- error : {
124
- type : reason ,
125
- message : `接口响应错误 - ${ resp . data . error . message } ` ,
126
- addition : JSON . stringify ( resp ) ,
127
- } ,
128
- } ) ;
181
+ if ( result . error ) {
182
+ handleError ( result ) ;
129
183
} else {
130
- const { choices } = resp . data ;
131
- if ( ! choices || choices . length === 0 ) {
132
- completion ( {
133
- error : {
134
- type : "api" ,
135
- message : "接口未返回结果" ,
136
- } ,
137
- } ) ;
138
- return ;
139
- }
140
- if ( isChatGPTModel ) {
141
- targetTxt = choices [ 0 ] . message . content . trim ( ) ;
142
- } else {
143
- targetTxt = choices [ 0 ] . text . trim ( ) ;
144
- }
145
-
146
- if ( targetTxt . startsWith ( '"' ) || targetTxt . startsWith ( "「" ) ) {
147
- targetTxt = targetTxt . slice ( 1 ) ;
148
- }
149
- if ( targetTxt . endsWith ( '"' ) || targetTxt . endsWith ( "」" ) ) {
150
- targetTxt = targetTxt . slice ( 0 , - 1 ) ;
151
- }
152
-
153
- completion ( {
154
- result : {
155
- from : query . detectFrom ,
156
- to : query . detectTo ,
157
- toParagraphs : targetTxt . split ( "\n" ) ,
158
- } ,
159
- } ) ;
184
+ handleResponse ( completion , isChatGPTModel , query , result ) ;
160
185
}
161
186
} ) ( ) . catch ( ( err ) => {
162
187
completion ( {
0 commit comments