@leikeduntech/leiai-js 4.0.1 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +5 -5
- package/bin/cli.js +146 -146
- package/build/index.d.ts +1 -0
- package/build/index.js +1287 -1284
- package/package.json +83 -83
package/build/index.js
CHANGED
|
@@ -1,1284 +1,1287 @@
|
|
|
1
|
-
// src/chatgpt-api.ts
|
|
2
|
-
import { Spark } from "@leikeduntech/spark-nodejs";
|
|
3
|
-
import Keyv from "keyv";
|
|
4
|
-
import pTimeout from "p-timeout";
|
|
5
|
-
import QuickLRU from "quick-lru";
|
|
6
|
-
import { v4 as uuidv4 } from "uuid";
|
|
7
|
-
|
|
8
|
-
// src/tokenizer.ts
|
|
9
|
-
import { getEncoding } from "js-tiktoken";
|
|
10
|
-
var tokenizer = getEncoding("cl100k_base");
|
|
11
|
-
function encode(input) {
|
|
12
|
-
return new Uint32Array(tokenizer.encode(input));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// src/types.ts
|
|
16
|
-
var ChatGPTError = class extends Error {
|
|
17
|
-
};
|
|
18
|
-
var openai;
|
|
19
|
-
((openai2) => {
|
|
20
|
-
})(openai || (openai = {}));
|
|
21
|
-
|
|
22
|
-
// src/fetch.ts
|
|
23
|
-
var fetch = globalThis.fetch;
|
|
24
|
-
|
|
25
|
-
// src/fetch-sse.ts
|
|
26
|
-
import { createParser } from "eventsource-parser";
|
|
27
|
-
|
|
28
|
-
// src/stream-async-iterable.ts
|
|
29
|
-
async function* streamAsyncIterable(stream) {
|
|
30
|
-
const reader = stream.getReader();
|
|
31
|
-
try {
|
|
32
|
-
while (true) {
|
|
33
|
-
const { done, value } = await reader.read();
|
|
34
|
-
if (done) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
yield value;
|
|
38
|
-
}
|
|
39
|
-
} finally {
|
|
40
|
-
reader.releaseLock();
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// src/fetch-sse.ts
|
|
45
|
-
async function fetchSSE(url, options, fetch2 = fetch, manufacturer = "OpenAI") {
|
|
46
|
-
const { onMessage, onError, ...fetchOptions } = options;
|
|
47
|
-
const res = await fetch2(url, fetchOptions);
|
|
48
|
-
if (!res.ok) {
|
|
49
|
-
let reason;
|
|
50
|
-
try {
|
|
51
|
-
reason = await res.text();
|
|
52
|
-
} catch (err) {
|
|
53
|
-
reason = res.statusText;
|
|
54
|
-
}
|
|
55
|
-
const msg = `${manufacturer} error ${res.status}: ${reason}`;
|
|
56
|
-
const error = new ChatGPTError(msg, { cause: res });
|
|
57
|
-
error.statusCode = res.status;
|
|
58
|
-
error.statusText = res.statusText;
|
|
59
|
-
throw error;
|
|
60
|
-
}
|
|
61
|
-
const parser = createParser((event) => {
|
|
62
|
-
if (event.type === "event") {
|
|
63
|
-
if (manufacturer.toLowerCase() === "zhipu") {
|
|
64
|
-
onMessage(JSON.stringify(event));
|
|
65
|
-
} else {
|
|
66
|
-
onMessage(event.data);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
const feed = (chunk) => {
|
|
71
|
-
var _a;
|
|
72
|
-
let response = null;
|
|
73
|
-
try {
|
|
74
|
-
response = JSON.parse(chunk);
|
|
75
|
-
} catch {
|
|
76
|
-
}
|
|
77
|
-
if (((_a = response == null ? void 0 : response.detail) == null ? void 0 : _a.type) === "invalid_request_error") {
|
|
78
|
-
const msg = `${manufacturer} error ${response.detail.message}: ${response.detail.code} (${response.detail.type})`;
|
|
79
|
-
const error = new ChatGPTError(msg, { cause: response });
|
|
80
|
-
error.statusCode = response.detail.code;
|
|
81
|
-
error.statusText = response.detail.message;
|
|
82
|
-
if (onError) {
|
|
83
|
-
onError(error);
|
|
84
|
-
} else {
|
|
85
|
-
console.error(error);
|
|
86
|
-
}
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
parser.feed(chunk);
|
|
90
|
-
};
|
|
91
|
-
if (!res.body.getReader) {
|
|
92
|
-
const body = res.body;
|
|
93
|
-
if (!body.on || !body.read) {
|
|
94
|
-
throw new ChatGPTError('unsupported "fetch" implementation');
|
|
95
|
-
}
|
|
96
|
-
body.on("readable", () => {
|
|
97
|
-
let chunk;
|
|
98
|
-
while (null !== (chunk = body.read())) {
|
|
99
|
-
feed(chunk.toString());
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
} else {
|
|
103
|
-
for await (const chunk of streamAsyncIterable(res.body)) {
|
|
104
|
-
const str = new TextDecoder().decode(chunk);
|
|
105
|
-
feed(str);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// src/utils.ts
|
|
111
|
-
import CryptoJS from "crypto-js";
|
|
112
|
-
var uuidv4Re = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
113
|
-
function isValidUUIDv4(str) {
|
|
114
|
-
return str && uuidv4Re.test(str);
|
|
115
|
-
}
|
|
116
|
-
function convertArrayToString(arr) {
|
|
117
|
-
let result = "[";
|
|
118
|
-
for (let i = 0; i < arr.length; i++) {
|
|
119
|
-
const obj = arr[i];
|
|
120
|
-
const keys = Object.keys(obj);
|
|
121
|
-
result += "{";
|
|
122
|
-
for (let j = 0; j < keys.length; j++) {
|
|
123
|
-
const key = keys[j];
|
|
124
|
-
const value = obj[key];
|
|
125
|
-
result += '"' + key + '":' + (typeof value === "string" ? '"' + value + '"' : value) + ",";
|
|
126
|
-
}
|
|
127
|
-
result = result.slice(0, -1);
|
|
128
|
-
result += "},";
|
|
129
|
-
}
|
|
130
|
-
result = result.slice(0, -1);
|
|
131
|
-
result += "]";
|
|
132
|
-
return result;
|
|
133
|
-
}
|
|
134
|
-
function signTencentHunyuan(bodyData, url, keyList) {
|
|
135
|
-
const sortedObj = {};
|
|
136
|
-
Object.keys(bodyData).sort().forEach((key) => {
|
|
137
|
-
sortedObj[key] = bodyData[key];
|
|
138
|
-
});
|
|
139
|
-
let signStr = "";
|
|
140
|
-
for (let key in sortedObj) {
|
|
141
|
-
if (signStr) {
|
|
142
|
-
if (typeof sortedObj[key] === "object") {
|
|
143
|
-
signStr += `&${key}=${convertArrayToString(sortedObj[key])}`;
|
|
144
|
-
} else {
|
|
145
|
-
signStr += `&${key}=${sortedObj[key]}`;
|
|
146
|
-
}
|
|
147
|
-
} else {
|
|
148
|
-
signStr += `${key}=${sortedObj[key]}`;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
signStr = `${url.replace("https://", "")}?${signStr}`;
|
|
152
|
-
const hmac = CryptoJS.HmacSHA1(signStr, keyList[2]);
|
|
153
|
-
const signBase64 = CryptoJS.enc.Base64.stringify(hmac);
|
|
154
|
-
return signBase64;
|
|
155
|
-
}
|
|
156
|
-
function isPositiveNumber(str) {
|
|
157
|
-
return /^[1-9]\d*$/.test(str);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// src/chatgpt-api.ts
|
|
161
|
-
var CHATGPT_MODEL = "gpt-3.5-turbo";
|
|
162
|
-
var USER_LABEL_DEFAULT = "User";
|
|
163
|
-
var ASSISTANT_LABEL_DEFAULT = "ChatGPT";
|
|
164
|
-
var ChatGPTAPI = class {
|
|
165
|
-
/**
|
|
166
|
-
* Creates a new client wrapper around OpenAI's chat completion API, mimicing the official ChatGPT webapp's functionality as closely as possible.
|
|
167
|
-
*
|
|
168
|
-
* @param apiKey - OpenAI API key (required).
|
|
169
|
-
* @param apiOrg - Optional OpenAI API organization (optional).
|
|
170
|
-
* @param apiBaseUrl - Optional override for the OpenAI API base URL.
|
|
171
|
-
* @param debug - Optional enables logging debugging info to stdout.
|
|
172
|
-
* @param completionParams - Param overrides to send to the [OpenAI chat completion API](https://platform.openai.com/docs/api-reference/chat/create). Options like `temperature` and `presence_penalty` can be tweaked to change the personality of the assistant.
|
|
173
|
-
* @param maxModelTokens - Optional override for the maximum number of tokens allowed by the model's context. Defaults to 4096.
|
|
174
|
-
* @param maxResponseTokens - Optional override for the minimum number of tokens allowed for the model's response. Defaults to 1000.
|
|
175
|
-
* @param messageStore - Optional [Keyv](https://github.com/jaredwray/keyv) store to persist chat messages to. If not provided, messages will be lost when the process exits.
|
|
176
|
-
* @param getMessageById - Optional function to retrieve a message by its ID. If not provided, the default implementation will be used (using an in-memory `messageStore`).
|
|
177
|
-
* @param upsertMessage - Optional function to insert or update a message. If not provided, the default implementation will be used (using an in-memory `messageStore`).
|
|
178
|
-
* @param fetch - Optional override for the `fetch` implementation to use. Defaults to the global `fetch` function.
|
|
179
|
-
*/
|
|
180
|
-
constructor(opts) {
|
|
181
|
-
const {
|
|
182
|
-
manufacturer = "OpenAI",
|
|
183
|
-
apiKey,
|
|
184
|
-
apiOrg,
|
|
185
|
-
apiBaseUrl = "https://api.openai.com/v1",
|
|
186
|
-
debug = false,
|
|
187
|
-
messageStore,
|
|
188
|
-
completionParams,
|
|
189
|
-
systemMessage,
|
|
190
|
-
maxModelTokens = 0,
|
|
191
|
-
maxResponseTokens = -1e7,
|
|
192
|
-
getMessageById,
|
|
193
|
-
upsertMessage,
|
|
194
|
-
fetch: fetch2 = fetch
|
|
195
|
-
} = opts;
|
|
196
|
-
this._manufacturer = manufacturer;
|
|
197
|
-
this._apiKey = apiKey;
|
|
198
|
-
this._apiOrg = apiOrg;
|
|
199
|
-
this._apiBaseUrl = apiBaseUrl;
|
|
200
|
-
this._debug = !!debug;
|
|
201
|
-
this._fetch = fetch2;
|
|
202
|
-
this._completionParams = {
|
|
203
|
-
model: CHATGPT_MODEL,
|
|
204
|
-
...completionParams
|
|
205
|
-
};
|
|
206
|
-
this._systemMessage = systemMessage;
|
|
207
|
-
this._maxModelTokens = maxModelTokens;
|
|
208
|
-
this._maxResponseTokens = maxResponseTokens;
|
|
209
|
-
this._getMessageById = getMessageById ?? this._defaultGetMessageById;
|
|
210
|
-
this._upsertMessage = upsertMessage ?? this._defaultUpsertMessage;
|
|
211
|
-
if (messageStore) {
|
|
212
|
-
this._messageStore = messageStore;
|
|
213
|
-
} else {
|
|
214
|
-
this._messageStore = new Keyv({
|
|
215
|
-
store: new QuickLRU({ maxSize: 1e4 })
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
if (!this._apiKey) {
|
|
219
|
-
throw new Error(`${this._manufacturer} missing required apiKey`);
|
|
220
|
-
}
|
|
221
|
-
if (!this._fetch) {
|
|
222
|
-
throw new Error("Invalid environment; fetch is not defined");
|
|
223
|
-
}
|
|
224
|
-
if (typeof this._fetch !== "function") {
|
|
225
|
-
throw new Error('Invalid "fetch" is not a function');
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
pluginListMap(pluginList) {
|
|
229
|
-
const list = {
|
|
230
|
-
"dall-e-3": {
|
|
231
|
-
name: "DallE3Fun",
|
|
232
|
-
description: "\u4F7F\u7528DALL-E3\u6A21\u578B\u6839\u636E\u7528\u6237\u63CF\u8FF0\u63D0\u793A\u521B\u4F5C\u4E00\u5F20\u65B0\u7684\u56FE\u7247"
|
|
233
|
-
},
|
|
234
|
-
"dall-e-2": {
|
|
235
|
-
name: "DallE2Fun",
|
|
236
|
-
description: "\u4F7F\u7528DALL-E2\u6A21\u578B\u628A\u7528\u6237\u63D0\u4F9B\u7684\u56FE\u7247\u548C\u6839\u636E\u63D0\u793A\u8BCD\u91CD\u65B0\u753B\u56FE\u4FEE\u6539\u56FE\u7247\u7F16\u8F91\u56FE\u7247\u66FF\u6362\u56FE\u7247\u90E8\u4EFD\u5185\u5BB9\u6362\u6539\u91CD\u753B\u56FE\u7247"
|
|
237
|
-
}
|
|
238
|
-
};
|
|
239
|
-
return list[pluginList];
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* Sends a message to the OpenAI chat completions endpoint, waits for the response
|
|
243
|
-
* to resolve, and returns the response.
|
|
244
|
-
*
|
|
245
|
-
* If you want your response to have historical context, you must provide a valid `parentMessageId`.
|
|
246
|
-
*
|
|
247
|
-
* If you want to receive a stream of partial responses, use `opts.onProgress`.
|
|
248
|
-
*
|
|
249
|
-
* Set `debug: true` in the `ChatGPTAPI` constructor to log more info on the full prompt sent to the OpenAI chat completions API. You can override the `systemMessage` in `opts` to customize the assistant's instructions.
|
|
250
|
-
*
|
|
251
|
-
* @param message - The prompt message to send
|
|
252
|
-
* @param opts.parentMessageId - Optional ID of the previous message in the conversation (defaults to `undefined`)
|
|
253
|
-
* @param opts.conversationId - Optional ID of the conversation (defaults to `undefined`)
|
|
254
|
-
* @param opts.messageId - Optional ID of the message to send (defaults to a random UUID)
|
|
255
|
-
* @param opts.systemMessage - Optional override for the chat "system message" which acts as instructions to the model (defaults to the ChatGPT system message)
|
|
256
|
-
* @param opts.timeoutMs - Optional timeout in milliseconds (defaults to no timeout)
|
|
257
|
-
* @param opts.onProgress - Optional callback which will be invoked every time the partial response is updated
|
|
258
|
-
* @param opts.abortSignal - Optional callback used to abort the underlying `fetch` call using an [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)
|
|
259
|
-
* @param completionParams - Optional overrides to send to the [OpenAI chat completion API](https://platform.openai.com/docs/api-reference/chat/create). Options like `temperature` and `presence_penalty` can be tweaked to change the personality of the assistant.
|
|
260
|
-
*
|
|
261
|
-
* @returns The response from ChatGPT
|
|
262
|
-
*/
|
|
263
|
-
async sendMessage(text, opts = {}, pluginParams) {
|
|
264
|
-
let parentMsg;
|
|
265
|
-
if (pluginParams) {
|
|
266
|
-
parentMsg = await this._getMessageById(pluginParams.assistant_res.id);
|
|
267
|
-
opts.parentMessageId = parentMsg.id;
|
|
268
|
-
}
|
|
269
|
-
let {
|
|
270
|
-
parentMessageId,
|
|
271
|
-
messageId = uuidv4(),
|
|
272
|
-
timeoutMs,
|
|
273
|
-
onProgress,
|
|
274
|
-
stream = onProgress ? true : false,
|
|
275
|
-
completionParams,
|
|
276
|
-
conversationId
|
|
277
|
-
} = opts;
|
|
278
|
-
let { abortSignal } = opts;
|
|
279
|
-
let abortController = null;
|
|
280
|
-
if (timeoutMs && !abortSignal) {
|
|
281
|
-
abortController = new AbortController();
|
|
282
|
-
abortSignal = abortController.signal;
|
|
283
|
-
}
|
|
284
|
-
let message = {
|
|
285
|
-
role: "user",
|
|
286
|
-
id: messageId,
|
|
287
|
-
conversationId,
|
|
288
|
-
parentMessageId,
|
|
289
|
-
text
|
|
290
|
-
};
|
|
291
|
-
if (this._debug)
|
|
292
|
-
console.log("\u8DDF\u8E2A1, \u8D85\u65F6\u65F6\u95F4ms", timeoutMs);
|
|
293
|
-
let latestQuestion = message, last_assistant_res_message = null, last_assistant_res = null, last_plugin_res = null;
|
|
294
|
-
if (pluginParams) {
|
|
295
|
-
last_assistant_res_message = pluginParams.assistant_res.detail.choices[0];
|
|
296
|
-
last_assistant_res = {
|
|
297
|
-
role: last_assistant_res_message.message.role,
|
|
298
|
-
id: parentMsg.id,
|
|
299
|
-
conversationId,
|
|
300
|
-
parentMessageId: parentMsg.parentMessageId,
|
|
301
|
-
text,
|
|
302
|
-
content: last_assistant_res_message
|
|
303
|
-
};
|
|
304
|
-
let r = "tool";
|
|
305
|
-
if (this._manufacturer.toLowerCase() === "azure") {
|
|
306
|
-
r = "function";
|
|
307
|
-
}
|
|
308
|
-
last_plugin_res = {
|
|
309
|
-
role: r,
|
|
310
|
-
id: messageId,
|
|
311
|
-
name: last_assistant_res_message.message.tool_calls[0].function.name,
|
|
312
|
-
conversationId,
|
|
313
|
-
parentMessageId: pluginParams.assistant_res.id,
|
|
314
|
-
text,
|
|
315
|
-
content: pluginParams.plugin_res,
|
|
316
|
-
tool_call_id: last_assistant_res_message.message.tool_calls[0].id
|
|
317
|
-
};
|
|
318
|
-
await this._upsertMessage(last_assistant_res);
|
|
319
|
-
latestQuestion = last_plugin_res;
|
|
320
|
-
}
|
|
321
|
-
if (this._debug)
|
|
322
|
-
console.log("\u8DDF\u8E2A2");
|
|
323
|
-
const { messages, maxTokens, numTokens, errorMessage, objText } = await this._buildMessages(text, opts, last_plugin_res);
|
|
324
|
-
latestQuestion.text = objText;
|
|
325
|
-
if (this._debug)
|
|
326
|
-
console.log(
|
|
327
|
-
`typeof errorMessage ${typeof errorMessage},numTokens:${numTokens}, _maxModelTokens:${this._maxModelTokens},errorMessage: ${errorMessage}`
|
|
328
|
-
);
|
|
329
|
-
if (errorMessage !== "" && errorMessage !== null && errorMessage.length > 0) {
|
|
330
|
-
return new Promise((resolve, reject) => {
|
|
331
|
-
const errMsg = {
|
|
332
|
-
manufacturer: this._manufacturer,
|
|
333
|
-
statusCode: 400,
|
|
334
|
-
message: errorMessage
|
|
335
|
-
};
|
|
336
|
-
return reject(errMsg);
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
const result = {
|
|
340
|
-
role: "assistant",
|
|
341
|
-
id: uuidv4(),
|
|
342
|
-
conversationId,
|
|
343
|
-
parentMessageId: messageId,
|
|
344
|
-
text: "",
|
|
345
|
-
result: "",
|
|
346
|
-
detail: { usage: null }
|
|
347
|
-
};
|
|
348
|
-
const responseP = new Promise(
|
|
349
|
-
async (resolve, reject) => {
|
|
350
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
351
|
-
let url = `${this._apiBaseUrl}/chat/completions`;
|
|
352
|
-
const headers = {
|
|
353
|
-
"Content-Type": "application/json",
|
|
354
|
-
Authorization: `Bearer ${this._apiKey}`
|
|
355
|
-
};
|
|
356
|
-
if (this._manufacturer.toLowerCase() === "baidu") {
|
|
357
|
-
url = this._apiBaseUrl;
|
|
358
|
-
delete headers.Authorization;
|
|
359
|
-
} else if (this._manufacturer.toLowerCase() === "aliyun") {
|
|
360
|
-
url = this._apiBaseUrl;
|
|
361
|
-
if (stream)
|
|
362
|
-
headers["X-DashScope-SSE"] = "enable";
|
|
363
|
-
} else if (this._manufacturer.toLowerCase() === "zhipu") {
|
|
364
|
-
url = this._apiBaseUrl;
|
|
365
|
-
headers["Authorization"] = this._apiKey;
|
|
366
|
-
if (stream)
|
|
367
|
-
headers["accept"] = "text/event-stream";
|
|
368
|
-
} else if (this._manufacturer.toLowerCase() === "azure") {
|
|
369
|
-
url = this._apiBaseUrl;
|
|
370
|
-
headers["api-key"] = this._apiKey;
|
|
371
|
-
delete headers.Authorization;
|
|
372
|
-
} else if (this._manufacturer.toLowerCase() === "xunfei") {
|
|
373
|
-
url = "";
|
|
374
|
-
delete headers.Authorization;
|
|
375
|
-
} else if (this._manufacturer.toLowerCase() === "chatdoc") {
|
|
376
|
-
url = this._apiBaseUrl;
|
|
377
|
-
} else if (this._manufacturer.toLocaleLowerCase() === "anthropic") {
|
|
378
|
-
url = this._apiBaseUrl;
|
|
379
|
-
}
|
|
380
|
-
let pluginList;
|
|
381
|
-
if (completionParams.pluginList) {
|
|
382
|
-
pluginList = completionParams.pluginList;
|
|
383
|
-
}
|
|
384
|
-
if (typeof completionParams.pluginList !== "undefined")
|
|
385
|
-
delete completionParams.pluginList;
|
|
386
|
-
if (typeof completionParams.fileList !== "undefined")
|
|
387
|
-
delete completionParams.fileList;
|
|
388
|
-
let body = {
|
|
389
|
-
max_tokens: maxTokens,
|
|
390
|
-
...this._completionParams,
|
|
391
|
-
...completionParams,
|
|
392
|
-
messages,
|
|
393
|
-
stream
|
|
394
|
-
};
|
|
395
|
-
if (!isPositiveNumber(maxTokens)) {
|
|
396
|
-
delete body.max_tokens;
|
|
397
|
-
}
|
|
398
|
-
if (this._manufacturer.toLowerCase() === "baidu" && typeof pluginList === "string" && pluginList.indexOf("zhishiku") > -1) {
|
|
399
|
-
if (body.model)
|
|
400
|
-
delete body.model;
|
|
401
|
-
if (body.max_tokens)
|
|
402
|
-
delete body.max_tokens;
|
|
403
|
-
if (body.temperature)
|
|
404
|
-
delete body.temperature;
|
|
405
|
-
} else {
|
|
406
|
-
if (typeof body.plugins !== void 0)
|
|
407
|
-
delete body.plugins;
|
|
408
|
-
}
|
|
409
|
-
if (["openai", "azure"].indexOf(this._manufacturer.toLowerCase()) > -1) {
|
|
410
|
-
switch (pluginList) {
|
|
411
|
-
case "dall-e-3":
|
|
412
|
-
let tools_key = "tools", tool_choice_key = "tool_choice", funArr = null;
|
|
413
|
-
if (this._manufacturer.toLowerCase() === "azure")
|
|
414
|
-
tools_key = "functions", tool_choice_key = "function_call";
|
|
415
|
-
funArr = [
|
|
416
|
-
{
|
|
417
|
-
type: "function",
|
|
418
|
-
function: {
|
|
419
|
-
name: "DallE2Fun",
|
|
420
|
-
description: this.pluginListMap(pluginList).description,
|
|
421
|
-
parameters: {
|
|
422
|
-
type: "object",
|
|
423
|
-
properties: {
|
|
424
|
-
prompt: {
|
|
425
|
-
type: "string",
|
|
426
|
-
description: "\u7528\u6237\u5BF9\u9700\u8981\u7F16\u8F91\u7684\u56FE\u7247\u4FEE\u6539\u7684\u63D0\u793A\u5185\u5BB9"
|
|
427
|
-
},
|
|
428
|
-
image_url: {
|
|
429
|
-
type: "string",
|
|
430
|
-
description: "\u4ECE\u5BF9\u8BDD\u5386\u53F2\u8BB0\u5F55\u548C\u7528\u6237\u63D0\u793A\u8BCD\u91CC\u5339\u914D\u6700\u8FD1\u4E00\u6B21\u51FA\u73B0\u7684\u4EE5http\u5F00\u5934\u7684\u56FE\u7247\u7684\u94FE\u63A5\u5730\u5740"
|
|
431
|
-
}
|
|
432
|
-
},
|
|
433
|
-
required: ["prompt", "image_url"]
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
},
|
|
437
|
-
{
|
|
438
|
-
type: "function",
|
|
439
|
-
function: {
|
|
440
|
-
name: "DallE3Fun",
|
|
441
|
-
description: this.pluginListMap(pluginList).description,
|
|
442
|
-
parameters: {
|
|
443
|
-
type: "object",
|
|
444
|
-
properties: {
|
|
445
|
-
prompt: {
|
|
446
|
-
type: "string",
|
|
447
|
-
description: "\u7ED8\u56FE\u7684\u63D0\u793A\u8BCD"
|
|
448
|
-
}
|
|
449
|
-
},
|
|
450
|
-
required: ["prompt"]
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
];
|
|
455
|
-
if (this._manufacturer.toLowerCase() === "azure") {
|
|
456
|
-
funArr = funArr.map((item) => {
|
|
457
|
-
return item.function;
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
body = Object.assign(body, {
|
|
461
|
-
[tools_key]: funArr,
|
|
462
|
-
[tool_choice_key]: "auto"
|
|
463
|
-
});
|
|
464
|
-
break;
|
|
465
|
-
default:
|
|
466
|
-
break;
|
|
467
|
-
}
|
|
468
|
-
} else if (this._manufacturer.toLowerCase() === "aliyun") {
|
|
469
|
-
body = Object.assign(body, {
|
|
470
|
-
parameters: { result_format: "message" },
|
|
471
|
-
input: { messages }
|
|
472
|
-
});
|
|
473
|
-
delete body.messages;
|
|
474
|
-
} else if (this._manufacturer.toLowerCase() === "zhipu") {
|
|
475
|
-
if (completionParams.model === "glm-4") {
|
|
476
|
-
} else {
|
|
477
|
-
delete body.messages;
|
|
478
|
-
body = Object.assign(body, { prompt: messages });
|
|
479
|
-
}
|
|
480
|
-
} else if (this._manufacturer.toLowerCase() === "tencent") {
|
|
481
|
-
url = this._apiBaseUrl;
|
|
482
|
-
const timestamp = Math.ceil((/* @__PURE__ */ new Date()).getTime() / 1e3) + 1;
|
|
483
|
-
const keyList = this._apiKey.split(".");
|
|
484
|
-
body = Object.assign(body, {
|
|
485
|
-
app_id: parseInt(keyList[0]),
|
|
486
|
-
secret_id: keyList[1],
|
|
487
|
-
timestamp,
|
|
488
|
-
expired: timestamp + 24 * 60 * 60,
|
|
489
|
-
stream: stream ? 1 : 0
|
|
490
|
-
});
|
|
491
|
-
delete body.model;
|
|
492
|
-
delete body.max_tokens;
|
|
493
|
-
headers["Authorization"] = signTencentHunyuan(body, url, keyList);
|
|
494
|
-
} else if (this._manufacturer.toLowerCase() === "baidu") {
|
|
495
|
-
if (pluginList && pluginList.indexOf("zhishiku") > -1) {
|
|
496
|
-
let query = messages.splice(messages.length - 1, 1);
|
|
497
|
-
body = Object.assign(body, {
|
|
498
|
-
query: (_a = query[0]) == null ? void 0 : _a.content,
|
|
499
|
-
history: messages
|
|
500
|
-
});
|
|
501
|
-
delete body.messages;
|
|
502
|
-
}
|
|
503
|
-
} else if (this._manufacturer.toLowerCase() === "chatdoc") {
|
|
504
|
-
let query = messages.splice(messages.length - 1, 1);
|
|
505
|
-
body = Object.assign(body, {
|
|
506
|
-
upload_id: (_b = completionParams == null ? void 0 : completionParams.extParams) == null ? void 0 : _b.upload_id,
|
|
507
|
-
question: (_c = query[0]) == null ? void 0 : _c.content,
|
|
508
|
-
history: messages
|
|
509
|
-
});
|
|
510
|
-
if (body.extParams)
|
|
511
|
-
delete body.extParams;
|
|
512
|
-
if (body.model)
|
|
513
|
-
delete body.model;
|
|
514
|
-
if (body.max_tokens)
|
|
515
|
-
delete body.max_tokens;
|
|
516
|
-
if (body.temperature)
|
|
517
|
-
delete body.temperature;
|
|
518
|
-
if (body.messages)
|
|
519
|
-
delete body.messages;
|
|
520
|
-
}
|
|
521
|
-
if (this._apiOrg && this._manufacturer.toLowerCase() === "openai") {
|
|
522
|
-
headers["OpenAI-Organization"] = this._apiOrg;
|
|
523
|
-
}
|
|
524
|
-
if (this._debug) {
|
|
525
|
-
console.log(`api url ${url}`);
|
|
526
|
-
console.log(`api header ${JSON.stringify(headers)}`);
|
|
527
|
-
console.log(`sendMessage (${numTokens} tokens) body: `, body);
|
|
528
|
-
console.log(
|
|
529
|
-
`sendMessage (${numTokens} tokens) message : `,
|
|
530
|
-
messages,
|
|
531
|
-
typeof messages
|
|
532
|
-
);
|
|
533
|
-
}
|
|
534
|
-
if (this._manufacturer.toLowerCase() === "xunfei") {
|
|
535
|
-
const self = this;
|
|
536
|
-
const keyList = this._apiKey.split(".");
|
|
537
|
-
const options = {
|
|
538
|
-
secret: keyList[2],
|
|
539
|
-
key: keyList[1],
|
|
540
|
-
appid: keyList[0],
|
|
541
|
-
temperature: body == null ? void 0 : body.temperature,
|
|
542
|
-
useHistory: !!parentMessageId,
|
|
543
|
-
chatId: ""
|
|
544
|
-
};
|
|
545
|
-
if (message == null ? void 0 : message.conversationId)
|
|
546
|
-
options.chatId = message == null ? void 0 : message.conversationId;
|
|
547
|
-
if (self._debug)
|
|
548
|
-
console.log("spark options ", options);
|
|
549
|
-
const sparkIns = new Spark(options);
|
|
550
|
-
const url2 = sparkIns.chat({
|
|
551
|
-
content: messages && JSON.stringify(messages),
|
|
552
|
-
// onData 表示分段拿到返回结果
|
|
553
|
-
onData({ content, start, end, seq }) {
|
|
554
|
-
if (self._debug)
|
|
555
|
-
console.log("onData", content, start, end, seq);
|
|
556
|
-
result.id = `xunfei-${Math.floor(
|
|
557
|
-
Math.random() * 1e7
|
|
558
|
-
)}${(/* @__PURE__ */ new Date()).getTime()}`;
|
|
559
|
-
result.delta = content;
|
|
560
|
-
if (content)
|
|
561
|
-
result.text += content;
|
|
562
|
-
result.role = "assistant";
|
|
563
|
-
onProgress == null ? void 0 : onProgress(result);
|
|
564
|
-
},
|
|
565
|
-
onEnd({ content, tokens, questionTokens }) {
|
|
566
|
-
if (self._debug)
|
|
567
|
-
console.log("onEnd", content, tokens, questionTokens);
|
|
568
|
-
result.detail = {
|
|
569
|
-
usage: {
|
|
570
|
-
prompt_tokens: questionTokens,
|
|
571
|
-
completion_tokens: tokens,
|
|
572
|
-
total_tokens: questionTokens + tokens
|
|
573
|
-
}
|
|
574
|
-
};
|
|
575
|
-
result.text = content.trim();
|
|
576
|
-
return resolve(result);
|
|
577
|
-
}
|
|
578
|
-
});
|
|
579
|
-
} else {
|
|
580
|
-
if (stream) {
|
|
581
|
-
fetchSSE(
|
|
582
|
-
url,
|
|
583
|
-
{
|
|
584
|
-
method: "POST",
|
|
585
|
-
headers,
|
|
586
|
-
body: JSON.stringify(body),
|
|
587
|
-
signal: abortSignal,
|
|
588
|
-
onMessage: (data) => {
|
|
589
|
-
var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
|
|
590
|
-
if (data === "[DONE]") {
|
|
591
|
-
result.text = result.text.trim();
|
|
592
|
-
return resolve(result);
|
|
593
|
-
}
|
|
594
|
-
try {
|
|
595
|
-
const response = JSON.parse(data);
|
|
596
|
-
if (this._debug) {
|
|
597
|
-
console.log(
|
|
598
|
-
`row data ${typeof response} : `,
|
|
599
|
-
response,
|
|
600
|
-
response == null ? void 0 : response.choices
|
|
601
|
-
);
|
|
602
|
-
}
|
|
603
|
-
if (this._manufacturer.toLowerCase() === "baidu") {
|
|
604
|
-
if ((response == null ? void 0 : response.is_end) === true) {
|
|
605
|
-
result.text += response.result.trim();
|
|
606
|
-
result.detail = response;
|
|
607
|
-
return resolve(result);
|
|
608
|
-
}
|
|
609
|
-
} else if (this._manufacturer.toLowerCase() === "azure") {
|
|
610
|
-
if (((_a2 = response.choices[0]) == null ? void 0 : _a2.finish_reason) === "stop") {
|
|
611
|
-
result.text = result.text.trim();
|
|
612
|
-
return resolve(result);
|
|
613
|
-
}
|
|
614
|
-
} else if (this._manufacturer.toLowerCase() === "aliyun") {
|
|
615
|
-
if (["stop", "length"].indexOf(
|
|
616
|
-
(_c2 = (_b2 = response == null ? void 0 : response.output) == null ? void 0 : _b2.choices[0]) == null ? void 0 : _c2.finish_reason
|
|
617
|
-
) > -1) {
|
|
618
|
-
result.text = (_f2 = (_e2 = (_d2 = response == null ? void 0 : response.output) == null ? void 0 : _d2.choices[0]) == null ? void 0 : _e2.message) == null ? void 0 : _f2.content.trim();
|
|
619
|
-
return resolve(result);
|
|
620
|
-
}
|
|
621
|
-
} else if (this._manufacturer.toLowerCase() === "zhipu") {
|
|
622
|
-
if (completionParams.model === "glm-4") {
|
|
623
|
-
const gelResponse = JSON.parse(response.data);
|
|
624
|
-
if (((_h2 = (_g2 = gelResponse == null ? void 0 : gelResponse.choices) == null ? void 0 : _g2[0]) == null ? void 0 : _h2.finish_reason) === "stop") {
|
|
625
|
-
result.text = result.text.trim();
|
|
626
|
-
return resolve(result);
|
|
627
|
-
}
|
|
628
|
-
} else {
|
|
629
|
-
if ((response == null ? void 0 : response.event) === "finish") {
|
|
630
|
-
result.text += response == null ? void 0 : response.data.trim();
|
|
631
|
-
return resolve(result);
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
} else if (this._manufacturer.toLowerCase() === "tencent") {
|
|
635
|
-
if (((_i2 = response.choices[0]) == null ? void 0 : _i2.finish_reason) === "stop") {
|
|
636
|
-
result.text += (_k = (_j = response == null ? void 0 : response.choices[0]) == null ? void 0 : _j.delta) == null ? void 0 : _k.content.trim();
|
|
637
|
-
return resolve(result);
|
|
638
|
-
}
|
|
639
|
-
} else if (this._manufacturer.toLowerCase() === "chatdoc") {
|
|
640
|
-
result.id = `chatdoc-${Math.floor(
|
|
641
|
-
Math.random() * 1e7
|
|
642
|
-
)}${(/* @__PURE__ */ new Date()).getTime()}`;
|
|
643
|
-
if (response == null ? void 0 : response.source_info) {
|
|
644
|
-
result.text += response == null ? void 0 : response.answer;
|
|
645
|
-
return resolve(result);
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
if (this._manufacturer.toLowerCase() === "aliyun") {
|
|
649
|
-
if (response == null ? void 0 : response.request_id) {
|
|
650
|
-
result.id = response.request_id;
|
|
651
|
-
}
|
|
652
|
-
} else {
|
|
653
|
-
if (response == null ? void 0 : response.id) {
|
|
654
|
-
result.id = response.id;
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
if (((_l = response.choices) == null ? void 0 : _l.length) && ["openai", "azure", "tencent", "anthropic"].indexOf(
|
|
658
|
-
this._manufacturer.toLowerCase()
|
|
659
|
-
) > -1) {
|
|
660
|
-
const delta = response.choices[0].delta;
|
|
661
|
-
result.delta = "";
|
|
662
|
-
if (response.choices[0].finish_reason === "tool_calls") {
|
|
663
|
-
result.delta = text;
|
|
664
|
-
} else if (delta.content) {
|
|
665
|
-
result.delta = delta.content;
|
|
666
|
-
}
|
|
667
|
-
if (delta
|
|
668
|
-
result.
|
|
669
|
-
|
|
670
|
-
if (
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
result.
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
result.
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
result.
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
result.
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
result.
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
error.
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
} else if ((
|
|
795
|
-
result.text =
|
|
796
|
-
result.role = "assistant";
|
|
797
|
-
} else {
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
this._manufacturer
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
this._maxModelTokens
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
this._maxResponseTokens
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
this._apiBaseUrl
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
this._apiKey
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
this._apiOrg
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
const
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
"
|
|
958
|
-
"
|
|
959
|
-
"
|
|
960
|
-
"
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
case "
|
|
988
|
-
return prompt2.concat([`
|
|
989
|
-
|
|
990
|
-
case "
|
|
991
|
-
return prompt2.concat([
|
|
992
|
-
${message.content}`]);
|
|
993
|
-
|
|
994
|
-
return prompt2.concat([`${
|
|
995
|
-
${message.content}`]);
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
if (!
|
|
1009
|
-
break;
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
"
|
|
1022
|
-
"
|
|
1023
|
-
"
|
|
1024
|
-
"
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
this.
|
|
1101
|
-
this.
|
|
1102
|
-
this.
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
if (!this.
|
|
1107
|
-
throw new Error("
|
|
1108
|
-
}
|
|
1109
|
-
if (
|
|
1110
|
-
throw new Error(
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
this._accessToken
|
|
1118
|
-
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
*
|
|
1124
|
-
*
|
|
1125
|
-
*
|
|
1126
|
-
* If you want to
|
|
1127
|
-
*
|
|
1128
|
-
*
|
|
1129
|
-
*
|
|
1130
|
-
*
|
|
1131
|
-
*
|
|
1132
|
-
*
|
|
1133
|
-
*
|
|
1134
|
-
*
|
|
1135
|
-
* @param
|
|
1136
|
-
* @param opts.
|
|
1137
|
-
* @param opts.
|
|
1138
|
-
* @param opts.
|
|
1139
|
-
*
|
|
1140
|
-
* @
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
url,
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
if (
|
|
1231
|
-
result.
|
|
1232
|
-
}
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1
|
+
// src/chatgpt-api.ts
|
|
2
|
+
import { Spark } from "@leikeduntech/spark-nodejs";
|
|
3
|
+
import Keyv from "keyv";
|
|
4
|
+
import pTimeout from "p-timeout";
|
|
5
|
+
import QuickLRU from "quick-lru";
|
|
6
|
+
import { v4 as uuidv4 } from "uuid";
|
|
7
|
+
|
|
8
|
+
// src/tokenizer.ts
|
|
9
|
+
import { getEncoding } from "js-tiktoken";
|
|
10
|
+
var tokenizer = getEncoding("cl100k_base");
|
|
11
|
+
function encode(input) {
|
|
12
|
+
return new Uint32Array(tokenizer.encode(input));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// src/types.ts
|
|
16
|
+
var ChatGPTError = class extends Error {
|
|
17
|
+
};
|
|
18
|
+
var openai;
|
|
19
|
+
((openai2) => {
|
|
20
|
+
})(openai || (openai = {}));
|
|
21
|
+
|
|
22
|
+
// src/fetch.ts
|
|
23
|
+
var fetch = globalThis.fetch;
|
|
24
|
+
|
|
25
|
+
// src/fetch-sse.ts
|
|
26
|
+
import { createParser } from "eventsource-parser";
|
|
27
|
+
|
|
28
|
+
// src/stream-async-iterable.ts
|
|
29
|
+
async function* streamAsyncIterable(stream) {
|
|
30
|
+
const reader = stream.getReader();
|
|
31
|
+
try {
|
|
32
|
+
while (true) {
|
|
33
|
+
const { done, value } = await reader.read();
|
|
34
|
+
if (done) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
yield value;
|
|
38
|
+
}
|
|
39
|
+
} finally {
|
|
40
|
+
reader.releaseLock();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/fetch-sse.ts
|
|
45
|
+
async function fetchSSE(url, options, fetch2 = fetch, manufacturer = "OpenAI") {
|
|
46
|
+
const { onMessage, onError, ...fetchOptions } = options;
|
|
47
|
+
const res = await fetch2(url, fetchOptions);
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
let reason;
|
|
50
|
+
try {
|
|
51
|
+
reason = await res.text();
|
|
52
|
+
} catch (err) {
|
|
53
|
+
reason = res.statusText;
|
|
54
|
+
}
|
|
55
|
+
const msg = `${manufacturer} error ${res.status}: ${reason}`;
|
|
56
|
+
const error = new ChatGPTError(msg, { cause: res });
|
|
57
|
+
error.statusCode = res.status;
|
|
58
|
+
error.statusText = res.statusText;
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
const parser = createParser((event) => {
|
|
62
|
+
if (event.type === "event") {
|
|
63
|
+
if (manufacturer.toLowerCase() === "zhipu") {
|
|
64
|
+
onMessage(JSON.stringify(event));
|
|
65
|
+
} else {
|
|
66
|
+
onMessage(event.data);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
const feed = (chunk) => {
|
|
71
|
+
var _a;
|
|
72
|
+
let response = null;
|
|
73
|
+
try {
|
|
74
|
+
response = JSON.parse(chunk);
|
|
75
|
+
} catch {
|
|
76
|
+
}
|
|
77
|
+
if (((_a = response == null ? void 0 : response.detail) == null ? void 0 : _a.type) === "invalid_request_error") {
|
|
78
|
+
const msg = `${manufacturer} error ${response.detail.message}: ${response.detail.code} (${response.detail.type})`;
|
|
79
|
+
const error = new ChatGPTError(msg, { cause: response });
|
|
80
|
+
error.statusCode = response.detail.code;
|
|
81
|
+
error.statusText = response.detail.message;
|
|
82
|
+
if (onError) {
|
|
83
|
+
onError(error);
|
|
84
|
+
} else {
|
|
85
|
+
console.error(error);
|
|
86
|
+
}
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
parser.feed(chunk);
|
|
90
|
+
};
|
|
91
|
+
if (!res.body.getReader) {
|
|
92
|
+
const body = res.body;
|
|
93
|
+
if (!body.on || !body.read) {
|
|
94
|
+
throw new ChatGPTError('unsupported "fetch" implementation');
|
|
95
|
+
}
|
|
96
|
+
body.on("readable", () => {
|
|
97
|
+
let chunk;
|
|
98
|
+
while (null !== (chunk = body.read())) {
|
|
99
|
+
feed(chunk.toString());
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
} else {
|
|
103
|
+
for await (const chunk of streamAsyncIterable(res.body)) {
|
|
104
|
+
const str = new TextDecoder().decode(chunk);
|
|
105
|
+
feed(str);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/utils.ts
|
|
111
|
+
import CryptoJS from "crypto-js";
|
|
112
|
+
var uuidv4Re = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
113
|
+
function isValidUUIDv4(str) {
|
|
114
|
+
return str && uuidv4Re.test(str);
|
|
115
|
+
}
|
|
116
|
+
function convertArrayToString(arr) {
|
|
117
|
+
let result = "[";
|
|
118
|
+
for (let i = 0; i < arr.length; i++) {
|
|
119
|
+
const obj = arr[i];
|
|
120
|
+
const keys = Object.keys(obj);
|
|
121
|
+
result += "{";
|
|
122
|
+
for (let j = 0; j < keys.length; j++) {
|
|
123
|
+
const key = keys[j];
|
|
124
|
+
const value = obj[key];
|
|
125
|
+
result += '"' + key + '":' + (typeof value === "string" ? '"' + value + '"' : value) + ",";
|
|
126
|
+
}
|
|
127
|
+
result = result.slice(0, -1);
|
|
128
|
+
result += "},";
|
|
129
|
+
}
|
|
130
|
+
result = result.slice(0, -1);
|
|
131
|
+
result += "]";
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
function signTencentHunyuan(bodyData, url, keyList) {
|
|
135
|
+
const sortedObj = {};
|
|
136
|
+
Object.keys(bodyData).sort().forEach((key) => {
|
|
137
|
+
sortedObj[key] = bodyData[key];
|
|
138
|
+
});
|
|
139
|
+
let signStr = "";
|
|
140
|
+
for (let key in sortedObj) {
|
|
141
|
+
if (signStr) {
|
|
142
|
+
if (typeof sortedObj[key] === "object") {
|
|
143
|
+
signStr += `&${key}=${convertArrayToString(sortedObj[key])}`;
|
|
144
|
+
} else {
|
|
145
|
+
signStr += `&${key}=${sortedObj[key]}`;
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
signStr += `${key}=${sortedObj[key]}`;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
signStr = `${url.replace("https://", "")}?${signStr}`;
|
|
152
|
+
const hmac = CryptoJS.HmacSHA1(signStr, keyList[2]);
|
|
153
|
+
const signBase64 = CryptoJS.enc.Base64.stringify(hmac);
|
|
154
|
+
return signBase64;
|
|
155
|
+
}
|
|
156
|
+
function isPositiveNumber(str) {
|
|
157
|
+
return /^[1-9]\d*$/.test(str);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// src/chatgpt-api.ts
|
|
161
|
+
var CHATGPT_MODEL = "gpt-3.5-turbo";
|
|
162
|
+
var USER_LABEL_DEFAULT = "User";
|
|
163
|
+
var ASSISTANT_LABEL_DEFAULT = "ChatGPT";
|
|
164
|
+
var ChatGPTAPI = class {
|
|
165
|
+
/**
|
|
166
|
+
* Creates a new client wrapper around OpenAI's chat completion API, mimicing the official ChatGPT webapp's functionality as closely as possible.
|
|
167
|
+
*
|
|
168
|
+
* @param apiKey - OpenAI API key (required).
|
|
169
|
+
* @param apiOrg - Optional OpenAI API organization (optional).
|
|
170
|
+
* @param apiBaseUrl - Optional override for the OpenAI API base URL.
|
|
171
|
+
* @param debug - Optional enables logging debugging info to stdout.
|
|
172
|
+
* @param completionParams - Param overrides to send to the [OpenAI chat completion API](https://platform.openai.com/docs/api-reference/chat/create). Options like `temperature` and `presence_penalty` can be tweaked to change the personality of the assistant.
|
|
173
|
+
* @param maxModelTokens - Optional override for the maximum number of tokens allowed by the model's context. Defaults to 4096.
|
|
174
|
+
* @param maxResponseTokens - Optional override for the minimum number of tokens allowed for the model's response. Defaults to 1000.
|
|
175
|
+
* @param messageStore - Optional [Keyv](https://github.com/jaredwray/keyv) store to persist chat messages to. If not provided, messages will be lost when the process exits.
|
|
176
|
+
* @param getMessageById - Optional function to retrieve a message by its ID. If not provided, the default implementation will be used (using an in-memory `messageStore`).
|
|
177
|
+
* @param upsertMessage - Optional function to insert or update a message. If not provided, the default implementation will be used (using an in-memory `messageStore`).
|
|
178
|
+
* @param fetch - Optional override for the `fetch` implementation to use. Defaults to the global `fetch` function.
|
|
179
|
+
*/
|
|
180
|
+
constructor(opts) {
|
|
181
|
+
const {
|
|
182
|
+
manufacturer = "OpenAI",
|
|
183
|
+
apiKey,
|
|
184
|
+
apiOrg,
|
|
185
|
+
apiBaseUrl = "https://api.openai.com/v1",
|
|
186
|
+
debug = false,
|
|
187
|
+
messageStore,
|
|
188
|
+
completionParams,
|
|
189
|
+
systemMessage,
|
|
190
|
+
maxModelTokens = 0,
|
|
191
|
+
maxResponseTokens = -1e7,
|
|
192
|
+
getMessageById,
|
|
193
|
+
upsertMessage,
|
|
194
|
+
fetch: fetch2 = fetch
|
|
195
|
+
} = opts;
|
|
196
|
+
this._manufacturer = manufacturer;
|
|
197
|
+
this._apiKey = apiKey;
|
|
198
|
+
this._apiOrg = apiOrg;
|
|
199
|
+
this._apiBaseUrl = apiBaseUrl;
|
|
200
|
+
this._debug = !!debug;
|
|
201
|
+
this._fetch = fetch2;
|
|
202
|
+
this._completionParams = {
|
|
203
|
+
model: CHATGPT_MODEL,
|
|
204
|
+
...completionParams
|
|
205
|
+
};
|
|
206
|
+
this._systemMessage = systemMessage;
|
|
207
|
+
this._maxModelTokens = maxModelTokens;
|
|
208
|
+
this._maxResponseTokens = maxResponseTokens;
|
|
209
|
+
this._getMessageById = getMessageById ?? this._defaultGetMessageById;
|
|
210
|
+
this._upsertMessage = upsertMessage ?? this._defaultUpsertMessage;
|
|
211
|
+
if (messageStore) {
|
|
212
|
+
this._messageStore = messageStore;
|
|
213
|
+
} else {
|
|
214
|
+
this._messageStore = new Keyv({
|
|
215
|
+
store: new QuickLRU({ maxSize: 1e4 })
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
if (!this._apiKey) {
|
|
219
|
+
throw new Error(`${this._manufacturer} missing required apiKey`);
|
|
220
|
+
}
|
|
221
|
+
if (!this._fetch) {
|
|
222
|
+
throw new Error("Invalid environment; fetch is not defined");
|
|
223
|
+
}
|
|
224
|
+
if (typeof this._fetch !== "function") {
|
|
225
|
+
throw new Error('Invalid "fetch" is not a function');
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
pluginListMap(pluginList) {
|
|
229
|
+
const list = {
|
|
230
|
+
"dall-e-3": {
|
|
231
|
+
name: "DallE3Fun",
|
|
232
|
+
description: "\u4F7F\u7528DALL-E3\u6A21\u578B\u6839\u636E\u7528\u6237\u63CF\u8FF0\u63D0\u793A\u521B\u4F5C\u4E00\u5F20\u65B0\u7684\u56FE\u7247"
|
|
233
|
+
},
|
|
234
|
+
"dall-e-2": {
|
|
235
|
+
name: "DallE2Fun",
|
|
236
|
+
description: "\u4F7F\u7528DALL-E2\u6A21\u578B\u628A\u7528\u6237\u63D0\u4F9B\u7684\u56FE\u7247\u548C\u6839\u636E\u63D0\u793A\u8BCD\u91CD\u65B0\u753B\u56FE\u4FEE\u6539\u56FE\u7247\u7F16\u8F91\u56FE\u7247\u66FF\u6362\u56FE\u7247\u90E8\u4EFD\u5185\u5BB9\u6362\u6539\u91CD\u753B\u56FE\u7247"
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
return list[pluginList];
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Sends a message to the OpenAI chat completions endpoint, waits for the response
|
|
243
|
+
* to resolve, and returns the response.
|
|
244
|
+
*
|
|
245
|
+
* If you want your response to have historical context, you must provide a valid `parentMessageId`.
|
|
246
|
+
*
|
|
247
|
+
* If you want to receive a stream of partial responses, use `opts.onProgress`.
|
|
248
|
+
*
|
|
249
|
+
* Set `debug: true` in the `ChatGPTAPI` constructor to log more info on the full prompt sent to the OpenAI chat completions API. You can override the `systemMessage` in `opts` to customize the assistant's instructions.
|
|
250
|
+
*
|
|
251
|
+
* @param message - The prompt message to send
|
|
252
|
+
* @param opts.parentMessageId - Optional ID of the previous message in the conversation (defaults to `undefined`)
|
|
253
|
+
* @param opts.conversationId - Optional ID of the conversation (defaults to `undefined`)
|
|
254
|
+
* @param opts.messageId - Optional ID of the message to send (defaults to a random UUID)
|
|
255
|
+
* @param opts.systemMessage - Optional override for the chat "system message" which acts as instructions to the model (defaults to the ChatGPT system message)
|
|
256
|
+
* @param opts.timeoutMs - Optional timeout in milliseconds (defaults to no timeout)
|
|
257
|
+
* @param opts.onProgress - Optional callback which will be invoked every time the partial response is updated
|
|
258
|
+
* @param opts.abortSignal - Optional callback used to abort the underlying `fetch` call using an [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)
|
|
259
|
+
* @param completionParams - Optional overrides to send to the [OpenAI chat completion API](https://platform.openai.com/docs/api-reference/chat/create). Options like `temperature` and `presence_penalty` can be tweaked to change the personality of the assistant.
|
|
260
|
+
*
|
|
261
|
+
* @returns The response from ChatGPT
|
|
262
|
+
*/
|
|
263
|
+
async sendMessage(text, opts = {}, pluginParams) {
|
|
264
|
+
let parentMsg;
|
|
265
|
+
if (pluginParams) {
|
|
266
|
+
parentMsg = await this._getMessageById(pluginParams.assistant_res.id);
|
|
267
|
+
opts.parentMessageId = parentMsg.id;
|
|
268
|
+
}
|
|
269
|
+
let {
|
|
270
|
+
parentMessageId,
|
|
271
|
+
messageId = uuidv4(),
|
|
272
|
+
timeoutMs,
|
|
273
|
+
onProgress,
|
|
274
|
+
stream = onProgress ? true : false,
|
|
275
|
+
completionParams,
|
|
276
|
+
conversationId
|
|
277
|
+
} = opts;
|
|
278
|
+
let { abortSignal } = opts;
|
|
279
|
+
let abortController = null;
|
|
280
|
+
if (timeoutMs && !abortSignal) {
|
|
281
|
+
abortController = new AbortController();
|
|
282
|
+
abortSignal = abortController.signal;
|
|
283
|
+
}
|
|
284
|
+
let message = {
|
|
285
|
+
role: "user",
|
|
286
|
+
id: messageId,
|
|
287
|
+
conversationId,
|
|
288
|
+
parentMessageId,
|
|
289
|
+
text
|
|
290
|
+
};
|
|
291
|
+
if (this._debug)
|
|
292
|
+
console.log("\u8DDF\u8E2A1, \u8D85\u65F6\u65F6\u95F4ms", timeoutMs);
|
|
293
|
+
let latestQuestion = message, last_assistant_res_message = null, last_assistant_res = null, last_plugin_res = null;
|
|
294
|
+
if (pluginParams) {
|
|
295
|
+
last_assistant_res_message = pluginParams.assistant_res.detail.choices[0];
|
|
296
|
+
last_assistant_res = {
|
|
297
|
+
role: last_assistant_res_message.message.role,
|
|
298
|
+
id: parentMsg.id,
|
|
299
|
+
conversationId,
|
|
300
|
+
parentMessageId: parentMsg.parentMessageId,
|
|
301
|
+
text,
|
|
302
|
+
content: last_assistant_res_message
|
|
303
|
+
};
|
|
304
|
+
let r = "tool";
|
|
305
|
+
if (this._manufacturer.toLowerCase() === "azure") {
|
|
306
|
+
r = "function";
|
|
307
|
+
}
|
|
308
|
+
last_plugin_res = {
|
|
309
|
+
role: r,
|
|
310
|
+
id: messageId,
|
|
311
|
+
name: last_assistant_res_message.message.tool_calls[0].function.name,
|
|
312
|
+
conversationId,
|
|
313
|
+
parentMessageId: pluginParams.assistant_res.id,
|
|
314
|
+
text,
|
|
315
|
+
content: pluginParams.plugin_res,
|
|
316
|
+
tool_call_id: last_assistant_res_message.message.tool_calls[0].id
|
|
317
|
+
};
|
|
318
|
+
await this._upsertMessage(last_assistant_res);
|
|
319
|
+
latestQuestion = last_plugin_res;
|
|
320
|
+
}
|
|
321
|
+
if (this._debug)
|
|
322
|
+
console.log("\u8DDF\u8E2A2");
|
|
323
|
+
const { messages, maxTokens, numTokens, errorMessage, objText } = await this._buildMessages(text, opts, last_plugin_res);
|
|
324
|
+
latestQuestion.text = objText;
|
|
325
|
+
if (this._debug)
|
|
326
|
+
console.log(
|
|
327
|
+
`typeof errorMessage ${typeof errorMessage},numTokens:${numTokens}, _maxModelTokens:${this._maxModelTokens},errorMessage: ${errorMessage}`
|
|
328
|
+
);
|
|
329
|
+
if (errorMessage !== "" && errorMessage !== null && errorMessage.length > 0) {
|
|
330
|
+
return new Promise((resolve, reject) => {
|
|
331
|
+
const errMsg = {
|
|
332
|
+
manufacturer: this._manufacturer,
|
|
333
|
+
statusCode: 400,
|
|
334
|
+
message: errorMessage
|
|
335
|
+
};
|
|
336
|
+
return reject(errMsg);
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
const result = {
|
|
340
|
+
role: "assistant",
|
|
341
|
+
id: uuidv4(),
|
|
342
|
+
conversationId,
|
|
343
|
+
parentMessageId: messageId,
|
|
344
|
+
text: "",
|
|
345
|
+
result: "",
|
|
346
|
+
detail: { usage: null }
|
|
347
|
+
};
|
|
348
|
+
const responseP = new Promise(
|
|
349
|
+
async (resolve, reject) => {
|
|
350
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
351
|
+
let url = `${this._apiBaseUrl}/chat/completions`;
|
|
352
|
+
const headers = {
|
|
353
|
+
"Content-Type": "application/json",
|
|
354
|
+
Authorization: `Bearer ${this._apiKey}`
|
|
355
|
+
};
|
|
356
|
+
if (this._manufacturer.toLowerCase() === "baidu") {
|
|
357
|
+
url = this._apiBaseUrl;
|
|
358
|
+
delete headers.Authorization;
|
|
359
|
+
} else if (this._manufacturer.toLowerCase() === "aliyun") {
|
|
360
|
+
url = this._apiBaseUrl;
|
|
361
|
+
if (stream)
|
|
362
|
+
headers["X-DashScope-SSE"] = "enable";
|
|
363
|
+
} else if (this._manufacturer.toLowerCase() === "zhipu") {
|
|
364
|
+
url = this._apiBaseUrl;
|
|
365
|
+
headers["Authorization"] = this._apiKey;
|
|
366
|
+
if (stream)
|
|
367
|
+
headers["accept"] = "text/event-stream";
|
|
368
|
+
} else if (this._manufacturer.toLowerCase() === "azure") {
|
|
369
|
+
url = this._apiBaseUrl;
|
|
370
|
+
headers["api-key"] = this._apiKey;
|
|
371
|
+
delete headers.Authorization;
|
|
372
|
+
} else if (this._manufacturer.toLowerCase() === "xunfei") {
|
|
373
|
+
url = "";
|
|
374
|
+
delete headers.Authorization;
|
|
375
|
+
} else if (this._manufacturer.toLowerCase() === "chatdoc") {
|
|
376
|
+
url = this._apiBaseUrl;
|
|
377
|
+
} else if (this._manufacturer.toLocaleLowerCase() === "anthropic") {
|
|
378
|
+
url = this._apiBaseUrl;
|
|
379
|
+
}
|
|
380
|
+
let pluginList;
|
|
381
|
+
if (completionParams.pluginList) {
|
|
382
|
+
pluginList = completionParams.pluginList;
|
|
383
|
+
}
|
|
384
|
+
if (typeof completionParams.pluginList !== "undefined")
|
|
385
|
+
delete completionParams.pluginList;
|
|
386
|
+
if (typeof completionParams.fileList !== "undefined")
|
|
387
|
+
delete completionParams.fileList;
|
|
388
|
+
let body = {
|
|
389
|
+
max_tokens: maxTokens,
|
|
390
|
+
...this._completionParams,
|
|
391
|
+
...completionParams,
|
|
392
|
+
messages,
|
|
393
|
+
stream
|
|
394
|
+
};
|
|
395
|
+
if (!isPositiveNumber(maxTokens)) {
|
|
396
|
+
delete body.max_tokens;
|
|
397
|
+
}
|
|
398
|
+
if (this._manufacturer.toLowerCase() === "baidu" && typeof pluginList === "string" && pluginList.indexOf("zhishiku") > -1) {
|
|
399
|
+
if (body.model)
|
|
400
|
+
delete body.model;
|
|
401
|
+
if (body.max_tokens)
|
|
402
|
+
delete body.max_tokens;
|
|
403
|
+
if (body.temperature)
|
|
404
|
+
delete body.temperature;
|
|
405
|
+
} else {
|
|
406
|
+
if (typeof body.plugins !== void 0)
|
|
407
|
+
delete body.plugins;
|
|
408
|
+
}
|
|
409
|
+
if (["openai", "azure"].indexOf(this._manufacturer.toLowerCase()) > -1) {
|
|
410
|
+
switch (pluginList) {
|
|
411
|
+
case "dall-e-3":
|
|
412
|
+
let tools_key = "tools", tool_choice_key = "tool_choice", funArr = null;
|
|
413
|
+
if (this._manufacturer.toLowerCase() === "azure")
|
|
414
|
+
tools_key = "functions", tool_choice_key = "function_call";
|
|
415
|
+
funArr = [
|
|
416
|
+
{
|
|
417
|
+
type: "function",
|
|
418
|
+
function: {
|
|
419
|
+
name: "DallE2Fun",
|
|
420
|
+
description: this.pluginListMap(pluginList).description,
|
|
421
|
+
parameters: {
|
|
422
|
+
type: "object",
|
|
423
|
+
properties: {
|
|
424
|
+
prompt: {
|
|
425
|
+
type: "string",
|
|
426
|
+
description: "\u7528\u6237\u5BF9\u9700\u8981\u7F16\u8F91\u7684\u56FE\u7247\u4FEE\u6539\u7684\u63D0\u793A\u5185\u5BB9"
|
|
427
|
+
},
|
|
428
|
+
image_url: {
|
|
429
|
+
type: "string",
|
|
430
|
+
description: "\u4ECE\u5BF9\u8BDD\u5386\u53F2\u8BB0\u5F55\u548C\u7528\u6237\u63D0\u793A\u8BCD\u91CC\u5339\u914D\u6700\u8FD1\u4E00\u6B21\u51FA\u73B0\u7684\u4EE5http\u5F00\u5934\u7684\u56FE\u7247\u7684\u94FE\u63A5\u5730\u5740"
|
|
431
|
+
}
|
|
432
|
+
},
|
|
433
|
+
required: ["prompt", "image_url"]
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
type: "function",
|
|
439
|
+
function: {
|
|
440
|
+
name: "DallE3Fun",
|
|
441
|
+
description: this.pluginListMap(pluginList).description,
|
|
442
|
+
parameters: {
|
|
443
|
+
type: "object",
|
|
444
|
+
properties: {
|
|
445
|
+
prompt: {
|
|
446
|
+
type: "string",
|
|
447
|
+
description: "\u7ED8\u56FE\u7684\u63D0\u793A\u8BCD"
|
|
448
|
+
}
|
|
449
|
+
},
|
|
450
|
+
required: ["prompt"]
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
];
|
|
455
|
+
if (this._manufacturer.toLowerCase() === "azure") {
|
|
456
|
+
funArr = funArr.map((item) => {
|
|
457
|
+
return item.function;
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
body = Object.assign(body, {
|
|
461
|
+
[tools_key]: funArr,
|
|
462
|
+
[tool_choice_key]: "auto"
|
|
463
|
+
});
|
|
464
|
+
break;
|
|
465
|
+
default:
|
|
466
|
+
break;
|
|
467
|
+
}
|
|
468
|
+
} else if (this._manufacturer.toLowerCase() === "aliyun") {
|
|
469
|
+
body = Object.assign(body, {
|
|
470
|
+
parameters: { result_format: "message" },
|
|
471
|
+
input: { messages }
|
|
472
|
+
});
|
|
473
|
+
delete body.messages;
|
|
474
|
+
} else if (this._manufacturer.toLowerCase() === "zhipu") {
|
|
475
|
+
if (completionParams.model === "glm-4") {
|
|
476
|
+
} else {
|
|
477
|
+
delete body.messages;
|
|
478
|
+
body = Object.assign(body, { prompt: messages });
|
|
479
|
+
}
|
|
480
|
+
} else if (this._manufacturer.toLowerCase() === "tencent") {
|
|
481
|
+
url = this._apiBaseUrl;
|
|
482
|
+
const timestamp = Math.ceil((/* @__PURE__ */ new Date()).getTime() / 1e3) + 1;
|
|
483
|
+
const keyList = this._apiKey.split(".");
|
|
484
|
+
body = Object.assign(body, {
|
|
485
|
+
app_id: parseInt(keyList[0]),
|
|
486
|
+
secret_id: keyList[1],
|
|
487
|
+
timestamp,
|
|
488
|
+
expired: timestamp + 24 * 60 * 60,
|
|
489
|
+
stream: stream ? 1 : 0
|
|
490
|
+
});
|
|
491
|
+
delete body.model;
|
|
492
|
+
delete body.max_tokens;
|
|
493
|
+
headers["Authorization"] = signTencentHunyuan(body, url, keyList);
|
|
494
|
+
} else if (this._manufacturer.toLowerCase() === "baidu") {
|
|
495
|
+
if (pluginList && pluginList.indexOf("zhishiku") > -1) {
|
|
496
|
+
let query = messages.splice(messages.length - 1, 1);
|
|
497
|
+
body = Object.assign(body, {
|
|
498
|
+
query: (_a = query[0]) == null ? void 0 : _a.content,
|
|
499
|
+
history: messages
|
|
500
|
+
});
|
|
501
|
+
delete body.messages;
|
|
502
|
+
}
|
|
503
|
+
} else if (this._manufacturer.toLowerCase() === "chatdoc") {
|
|
504
|
+
let query = messages.splice(messages.length - 1, 1);
|
|
505
|
+
body = Object.assign(body, {
|
|
506
|
+
upload_id: (_b = completionParams == null ? void 0 : completionParams.extParams) == null ? void 0 : _b.upload_id,
|
|
507
|
+
question: (_c = query[0]) == null ? void 0 : _c.content,
|
|
508
|
+
history: messages
|
|
509
|
+
});
|
|
510
|
+
if (body.extParams)
|
|
511
|
+
delete body.extParams;
|
|
512
|
+
if (body.model)
|
|
513
|
+
delete body.model;
|
|
514
|
+
if (body.max_tokens)
|
|
515
|
+
delete body.max_tokens;
|
|
516
|
+
if (body.temperature)
|
|
517
|
+
delete body.temperature;
|
|
518
|
+
if (body.messages)
|
|
519
|
+
delete body.messages;
|
|
520
|
+
}
|
|
521
|
+
if (this._apiOrg && this._manufacturer.toLowerCase() === "openai") {
|
|
522
|
+
headers["OpenAI-Organization"] = this._apiOrg;
|
|
523
|
+
}
|
|
524
|
+
if (this._debug) {
|
|
525
|
+
console.log(`api url ${url}`);
|
|
526
|
+
console.log(`api header ${JSON.stringify(headers)}`);
|
|
527
|
+
console.log(`sendMessage (${numTokens} tokens) body: `, body);
|
|
528
|
+
console.log(
|
|
529
|
+
`sendMessage (${numTokens} tokens) message : `,
|
|
530
|
+
messages,
|
|
531
|
+
typeof messages
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
if (this._manufacturer.toLowerCase() === "xunfei") {
|
|
535
|
+
const self = this;
|
|
536
|
+
const keyList = this._apiKey.split(".");
|
|
537
|
+
const options = {
|
|
538
|
+
secret: keyList[2],
|
|
539
|
+
key: keyList[1],
|
|
540
|
+
appid: keyList[0],
|
|
541
|
+
temperature: body == null ? void 0 : body.temperature,
|
|
542
|
+
useHistory: !!parentMessageId,
|
|
543
|
+
chatId: ""
|
|
544
|
+
};
|
|
545
|
+
if (message == null ? void 0 : message.conversationId)
|
|
546
|
+
options.chatId = message == null ? void 0 : message.conversationId;
|
|
547
|
+
if (self._debug)
|
|
548
|
+
console.log("spark options ", options);
|
|
549
|
+
const sparkIns = new Spark(options);
|
|
550
|
+
const url2 = sparkIns.chat({
|
|
551
|
+
content: messages && JSON.stringify(messages),
|
|
552
|
+
// onData 表示分段拿到返回结果
|
|
553
|
+
onData({ content, start, end, seq }) {
|
|
554
|
+
if (self._debug)
|
|
555
|
+
console.log("onData", content, start, end, seq);
|
|
556
|
+
result.id = `xunfei-${Math.floor(
|
|
557
|
+
Math.random() * 1e7
|
|
558
|
+
)}${(/* @__PURE__ */ new Date()).getTime()}`;
|
|
559
|
+
result.delta = content;
|
|
560
|
+
if (content)
|
|
561
|
+
result.text += content;
|
|
562
|
+
result.role = "assistant";
|
|
563
|
+
onProgress == null ? void 0 : onProgress(result);
|
|
564
|
+
},
|
|
565
|
+
onEnd({ content, tokens, questionTokens }) {
|
|
566
|
+
if (self._debug)
|
|
567
|
+
console.log("onEnd", content, tokens, questionTokens);
|
|
568
|
+
result.detail = {
|
|
569
|
+
usage: {
|
|
570
|
+
prompt_tokens: questionTokens,
|
|
571
|
+
completion_tokens: tokens,
|
|
572
|
+
total_tokens: questionTokens + tokens
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
result.text = content.trim();
|
|
576
|
+
return resolve(result);
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
} else {
|
|
580
|
+
if (stream) {
|
|
581
|
+
fetchSSE(
|
|
582
|
+
url,
|
|
583
|
+
{
|
|
584
|
+
method: "POST",
|
|
585
|
+
headers,
|
|
586
|
+
body: JSON.stringify(body),
|
|
587
|
+
signal: abortSignal,
|
|
588
|
+
onMessage: (data) => {
|
|
589
|
+
var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
|
|
590
|
+
if (data === "[DONE]") {
|
|
591
|
+
result.text = result.text.trim();
|
|
592
|
+
return resolve(result);
|
|
593
|
+
}
|
|
594
|
+
try {
|
|
595
|
+
const response = JSON.parse(data);
|
|
596
|
+
if (this._debug) {
|
|
597
|
+
console.log(
|
|
598
|
+
`row data ${typeof response} : `,
|
|
599
|
+
response,
|
|
600
|
+
response == null ? void 0 : response.choices
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
if (this._manufacturer.toLowerCase() === "baidu") {
|
|
604
|
+
if ((response == null ? void 0 : response.is_end) === true) {
|
|
605
|
+
result.text += response.result.trim();
|
|
606
|
+
result.detail = response;
|
|
607
|
+
return resolve(result);
|
|
608
|
+
}
|
|
609
|
+
} else if (this._manufacturer.toLowerCase() === "azure") {
|
|
610
|
+
if (((_a2 = response.choices[0]) == null ? void 0 : _a2.finish_reason) === "stop") {
|
|
611
|
+
result.text = result.text.trim();
|
|
612
|
+
return resolve(result);
|
|
613
|
+
}
|
|
614
|
+
} else if (this._manufacturer.toLowerCase() === "aliyun") {
|
|
615
|
+
if (["stop", "length"].indexOf(
|
|
616
|
+
(_c2 = (_b2 = response == null ? void 0 : response.output) == null ? void 0 : _b2.choices[0]) == null ? void 0 : _c2.finish_reason
|
|
617
|
+
) > -1) {
|
|
618
|
+
result.text = (_f2 = (_e2 = (_d2 = response == null ? void 0 : response.output) == null ? void 0 : _d2.choices[0]) == null ? void 0 : _e2.message) == null ? void 0 : _f2.content.trim();
|
|
619
|
+
return resolve(result);
|
|
620
|
+
}
|
|
621
|
+
} else if (this._manufacturer.toLowerCase() === "zhipu") {
|
|
622
|
+
if (completionParams.model === "glm-4") {
|
|
623
|
+
const gelResponse = JSON.parse(response.data);
|
|
624
|
+
if (((_h2 = (_g2 = gelResponse == null ? void 0 : gelResponse.choices) == null ? void 0 : _g2[0]) == null ? void 0 : _h2.finish_reason) === "stop") {
|
|
625
|
+
result.text = result.text.trim();
|
|
626
|
+
return resolve(result);
|
|
627
|
+
}
|
|
628
|
+
} else {
|
|
629
|
+
if ((response == null ? void 0 : response.event) === "finish") {
|
|
630
|
+
result.text += response == null ? void 0 : response.data.trim();
|
|
631
|
+
return resolve(result);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
} else if (this._manufacturer.toLowerCase() === "tencent") {
|
|
635
|
+
if (((_i2 = response.choices[0]) == null ? void 0 : _i2.finish_reason) === "stop") {
|
|
636
|
+
result.text += (_k = (_j = response == null ? void 0 : response.choices[0]) == null ? void 0 : _j.delta) == null ? void 0 : _k.content.trim();
|
|
637
|
+
return resolve(result);
|
|
638
|
+
}
|
|
639
|
+
} else if (this._manufacturer.toLowerCase() === "chatdoc") {
|
|
640
|
+
result.id = `chatdoc-${Math.floor(
|
|
641
|
+
Math.random() * 1e7
|
|
642
|
+
)}${(/* @__PURE__ */ new Date()).getTime()}`;
|
|
643
|
+
if (response == null ? void 0 : response.source_info) {
|
|
644
|
+
result.text += response == null ? void 0 : response.answer;
|
|
645
|
+
return resolve(result);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
if (this._manufacturer.toLowerCase() === "aliyun") {
|
|
649
|
+
if (response == null ? void 0 : response.request_id) {
|
|
650
|
+
result.id = response.request_id;
|
|
651
|
+
}
|
|
652
|
+
} else {
|
|
653
|
+
if (response == null ? void 0 : response.id) {
|
|
654
|
+
result.id = response.id;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
if (((_l = response.choices) == null ? void 0 : _l.length) && ["openai", "azure", "tencent", "anthropic"].indexOf(
|
|
658
|
+
this._manufacturer.toLowerCase()
|
|
659
|
+
) > -1) {
|
|
660
|
+
const delta = response.choices[0].delta;
|
|
661
|
+
result.delta = "";
|
|
662
|
+
if (response.choices[0].finish_reason === "tool_calls") {
|
|
663
|
+
result.delta = text;
|
|
664
|
+
} else if (delta.content) {
|
|
665
|
+
result.delta = delta.content;
|
|
666
|
+
}
|
|
667
|
+
if (delta.reasoning_content) {
|
|
668
|
+
result.delta = `<think>${delta.reasoning_content}</think>${result.delta}`;
|
|
669
|
+
}
|
|
670
|
+
if ((delta == null ? void 0 : delta.content) || (delta == null ? void 0 : delta.reasoning_content))
|
|
671
|
+
result.text += result.delta;
|
|
672
|
+
result.role = "assistant";
|
|
673
|
+
if (response.choices[0].finish_reason === "tool_calls") {
|
|
674
|
+
} else if (delta.role) {
|
|
675
|
+
result.role = delta.role;
|
|
676
|
+
}
|
|
677
|
+
result.detail = response;
|
|
678
|
+
onProgress == null ? void 0 : onProgress(result);
|
|
679
|
+
} else if ((response == null ? void 0 : response.result) && this._manufacturer.toLowerCase() === "baidu") {
|
|
680
|
+
result.delta = response.result;
|
|
681
|
+
if (response == null ? void 0 : response.result)
|
|
682
|
+
result.text += response.result;
|
|
683
|
+
result.role = "assistant";
|
|
684
|
+
result.detail = response;
|
|
685
|
+
onProgress == null ? void 0 : onProgress(result);
|
|
686
|
+
} else if ((response == null ? void 0 : response.output) && this._manufacturer.toLowerCase() === "aliyun") {
|
|
687
|
+
response.usage = Object.assign(response.usage, {
|
|
688
|
+
prompt_tokens: (_m = response.usage) == null ? void 0 : _m.input_tokens,
|
|
689
|
+
completion_tokens: (_n = response.usage) == null ? void 0 : _n.output_tokens,
|
|
690
|
+
total_tokens: ((_o = response.usage) == null ? void 0 : _o.input_tokens) + ((_p = response.usage) == null ? void 0 : _p.output_tokens)
|
|
691
|
+
});
|
|
692
|
+
result.delta = "";
|
|
693
|
+
if ((_s = (_r = (_q = response == null ? void 0 : response.output) == null ? void 0 : _q.choices[0]) == null ? void 0 : _r.message) == null ? void 0 : _s.content)
|
|
694
|
+
result.text = (_v = (_u = (_t = response == null ? void 0 : response.output) == null ? void 0 : _t.choices[0]) == null ? void 0 : _u.message) == null ? void 0 : _v.content;
|
|
695
|
+
result.role = "assistant";
|
|
696
|
+
result.detail = response;
|
|
697
|
+
onProgress == null ? void 0 : onProgress(result);
|
|
698
|
+
} else if ((response == null ? void 0 : response.data) && this._manufacturer.toLowerCase() === "zhipu") {
|
|
699
|
+
if (completionParams.model === "glm-4") {
|
|
700
|
+
const glmResponse = JSON.parse(response.data);
|
|
701
|
+
if (((_x = (_w = glmResponse == null ? void 0 : glmResponse.choices) == null ? void 0 : _w[0]) == null ? void 0 : _x.finish_reason) === "stop") {
|
|
702
|
+
response.usage = glmResponse.usage;
|
|
703
|
+
}
|
|
704
|
+
let data2 = (_z = (_y = glmResponse == null ? void 0 : glmResponse.choices) == null ? void 0 : _y[0]) == null ? void 0 : _z.delta.content;
|
|
705
|
+
result.delta = data2;
|
|
706
|
+
if (data2) {
|
|
707
|
+
result.text += data2;
|
|
708
|
+
}
|
|
709
|
+
result.role = "assistant";
|
|
710
|
+
result.detail = response;
|
|
711
|
+
onProgress == null ? void 0 : onProgress(result);
|
|
712
|
+
} else {
|
|
713
|
+
if (response.event === "finish") {
|
|
714
|
+
if ((_A = response == null ? void 0 : response.meta) == null ? void 0 : _A.usage) {
|
|
715
|
+
response.usage = (_B = response == null ? void 0 : response.meta) == null ? void 0 : _B.usage;
|
|
716
|
+
} else {
|
|
717
|
+
response.usage = {
|
|
718
|
+
prompt_tokens: 1,
|
|
719
|
+
completion_tokens: 1,
|
|
720
|
+
total_tokens: 2
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
result.delta = response.data;
|
|
725
|
+
if (response == null ? void 0 : response.data)
|
|
726
|
+
result.text += response == null ? void 0 : response.data;
|
|
727
|
+
result.role = "assistant";
|
|
728
|
+
result.detail = response;
|
|
729
|
+
onProgress == null ? void 0 : onProgress(result);
|
|
730
|
+
}
|
|
731
|
+
} else if ((response == null ? void 0 : response.answer) && this._manufacturer.toLowerCase() === "chatdoc") {
|
|
732
|
+
result.delta = response.answer;
|
|
733
|
+
if (response == null ? void 0 : response.answer)
|
|
734
|
+
result.text += response.answer;
|
|
735
|
+
result.role = "assistant";
|
|
736
|
+
result.detail = response;
|
|
737
|
+
onProgress == null ? void 0 : onProgress(result);
|
|
738
|
+
}
|
|
739
|
+
} catch (err) {
|
|
740
|
+
console.warn(
|
|
741
|
+
`${this._manufacturer} stream SEE event unexpected error`,
|
|
742
|
+
err
|
|
743
|
+
);
|
|
744
|
+
return reject(err);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
this._fetch,
|
|
749
|
+
this._manufacturer
|
|
750
|
+
).catch(reject);
|
|
751
|
+
} else {
|
|
752
|
+
try {
|
|
753
|
+
if (this._debug)
|
|
754
|
+
console.log("\u8DDF\u8E2A3");
|
|
755
|
+
const res = await this._fetch(url, {
|
|
756
|
+
method: "POST",
|
|
757
|
+
headers,
|
|
758
|
+
body: JSON.stringify(body),
|
|
759
|
+
signal: abortSignal
|
|
760
|
+
});
|
|
761
|
+
if (this._debug)
|
|
762
|
+
console.log("\u8DDF\u8E2A4");
|
|
763
|
+
if (!res.ok) {
|
|
764
|
+
const reason = await res.text();
|
|
765
|
+
const msg = `${this._manufacturer} error ${res.status || res.statusText}: ${reason}`;
|
|
766
|
+
const error = new ChatGPTError(msg, { cause: res });
|
|
767
|
+
error.statusCode = res.status;
|
|
768
|
+
error.statusText = res.statusText;
|
|
769
|
+
return reject(error);
|
|
770
|
+
}
|
|
771
|
+
const response = await res.json();
|
|
772
|
+
if (this._debug) {
|
|
773
|
+
console.log(
|
|
774
|
+
`row data ${typeof response} : `,
|
|
775
|
+
response,
|
|
776
|
+
(response == null ? void 0 : response.choices) && ((_d = response == null ? void 0 : response.choices[0]) == null ? void 0 : _d.message)
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
if (this._manufacturer.toLowerCase() === "aliyun") {
|
|
780
|
+
if (response == null ? void 0 : response.request_id) {
|
|
781
|
+
result.id = response.request_id;
|
|
782
|
+
}
|
|
783
|
+
} else {
|
|
784
|
+
if (response == null ? void 0 : response.id) {
|
|
785
|
+
result.id = response.id;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
if (((_e = response == null ? void 0 : response.choices) == null ? void 0 : _e.length) && ["openai", "azure"].indexOf(this._manufacturer.toLowerCase()) > -1) {
|
|
789
|
+
const message2 = response.choices[0].message;
|
|
790
|
+
result.text = message2.content;
|
|
791
|
+
if (message2.role) {
|
|
792
|
+
result.role = message2.role;
|
|
793
|
+
}
|
|
794
|
+
} else if ((response == null ? void 0 : response.result) && this._manufacturer.toLowerCase() === "baidu") {
|
|
795
|
+
result.text = response.result;
|
|
796
|
+
result.role = "assistant";
|
|
797
|
+
} else if (((_f = response == null ? void 0 : response.output) == null ? void 0 : _f.text) && this._manufacturer.toLowerCase() === "aliyun") {
|
|
798
|
+
result.text = (_g = response == null ? void 0 : response.output) == null ? void 0 : _g.text;
|
|
799
|
+
result.role = "assistant";
|
|
800
|
+
} else {
|
|
801
|
+
const res2 = response;
|
|
802
|
+
return reject(
|
|
803
|
+
new Error(
|
|
804
|
+
`${this._manufacturer} error: ${((_h = res2 == null ? void 0 : res2.detail) == null ? void 0 : _h.message) || ((_i = res2 == null ? void 0 : res2.detail) == null ? void 0 : _i.error_msg) || (res2 == null ? void 0 : res2.detail) || "unknown"}`
|
|
805
|
+
)
|
|
806
|
+
);
|
|
807
|
+
}
|
|
808
|
+
result.detail = response;
|
|
809
|
+
if (this._debug)
|
|
810
|
+
console.log("\u8DDF\u8E2A5");
|
|
811
|
+
return resolve(result);
|
|
812
|
+
} catch (err) {
|
|
813
|
+
if (this._debug)
|
|
814
|
+
console.log("\u8DDF\u8E2A6");
|
|
815
|
+
return reject(err);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
).then(async (message2) => {
|
|
821
|
+
var _a, _b, _c, _d, _e;
|
|
822
|
+
if (this._debug)
|
|
823
|
+
console.log("\u8DDF\u8E2A7", JSON.stringify(message2));
|
|
824
|
+
if (message2.detail) {
|
|
825
|
+
if (!message2.detail.usage) {
|
|
826
|
+
try {
|
|
827
|
+
const promptTokens = numTokens;
|
|
828
|
+
let completionTokens = 0;
|
|
829
|
+
if (["baidu", "aliyun"].indexOf(this._manufacturer.toLowerCase()) > -1) {
|
|
830
|
+
completionTokens = (_b = (_a = message2.detail) == null ? void 0 : _a.usage) == null ? void 0 : _b.total_tokens;
|
|
831
|
+
} else {
|
|
832
|
+
completionTokens = await this._getTokenCount(message2.text);
|
|
833
|
+
}
|
|
834
|
+
message2.detail.usage = {
|
|
835
|
+
prompt_tokens: promptTokens,
|
|
836
|
+
completion_tokens: completionTokens,
|
|
837
|
+
total_tokens: promptTokens + completionTokens,
|
|
838
|
+
estimated: true
|
|
839
|
+
};
|
|
840
|
+
} catch (err) {
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
if (this._manufacturer.toLowerCase() === "azure") {
|
|
844
|
+
if (((_d = (_c = message2.detail) == null ? void 0 : _c.choices[0]) == null ? void 0 : _d.finish_reason) === "function_call") {
|
|
845
|
+
message2.detail.choices[0].finish_reason = "tool_calls";
|
|
846
|
+
message2.detail.choices[0].message = {
|
|
847
|
+
role: message2.detail.choices[0].message.role,
|
|
848
|
+
tool_calls: [
|
|
849
|
+
{
|
|
850
|
+
id: `call_${uuidv4()}`,
|
|
851
|
+
type: "function",
|
|
852
|
+
function: (_e = message2.detail.choices[0].message) == null ? void 0 : _e.function_call
|
|
853
|
+
}
|
|
854
|
+
]
|
|
855
|
+
};
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
const pRes = Promise.all([
|
|
860
|
+
this._upsertMessage(latestQuestion),
|
|
861
|
+
this._upsertMessage(message2)
|
|
862
|
+
]).then(() => message2);
|
|
863
|
+
return pRes;
|
|
864
|
+
});
|
|
865
|
+
if (this._debug)
|
|
866
|
+
console.log("\u8DDF\u8E2A8");
|
|
867
|
+
if (timeoutMs) {
|
|
868
|
+
if (this._debug)
|
|
869
|
+
console.log("\u8DDF\u8E2A9");
|
|
870
|
+
if (abortController) {
|
|
871
|
+
;
|
|
872
|
+
responseP.cancel = () => {
|
|
873
|
+
console.log("responseP cancel error ", responseP);
|
|
874
|
+
abortController.abort();
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
return pTimeout(responseP, {
|
|
878
|
+
milliseconds: timeoutMs,
|
|
879
|
+
message: `${this._manufacturer} timed out waiting for response`
|
|
880
|
+
});
|
|
881
|
+
} else {
|
|
882
|
+
if (this._debug)
|
|
883
|
+
console.log("\u8DDF\u8E2A10");
|
|
884
|
+
return responseP;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
get manufacturer() {
|
|
888
|
+
return this._manufacturer;
|
|
889
|
+
}
|
|
890
|
+
set manufacturer(manufacturer) {
|
|
891
|
+
this._manufacturer = manufacturer;
|
|
892
|
+
}
|
|
893
|
+
get maxModelTokens() {
|
|
894
|
+
return this._maxModelTokens;
|
|
895
|
+
}
|
|
896
|
+
set maxModelTokens(maxModelTokens) {
|
|
897
|
+
this._maxModelTokens = maxModelTokens;
|
|
898
|
+
}
|
|
899
|
+
get maxResponseTokens() {
|
|
900
|
+
return this._maxResponseTokens;
|
|
901
|
+
}
|
|
902
|
+
set maxResponseTokens(maxResponseTokens) {
|
|
903
|
+
this._maxResponseTokens = maxResponseTokens;
|
|
904
|
+
}
|
|
905
|
+
get apiBaseUrl() {
|
|
906
|
+
return this._apiBaseUrl;
|
|
907
|
+
}
|
|
908
|
+
set apiBaseUrl(apiBaseUrl) {
|
|
909
|
+
this._apiBaseUrl = apiBaseUrl;
|
|
910
|
+
}
|
|
911
|
+
get apiKey() {
|
|
912
|
+
return this._apiKey;
|
|
913
|
+
}
|
|
914
|
+
set apiKey(apiKey) {
|
|
915
|
+
this._apiKey = apiKey;
|
|
916
|
+
}
|
|
917
|
+
get apiOrg() {
|
|
918
|
+
return this._apiOrg;
|
|
919
|
+
}
|
|
920
|
+
set apiOrg(apiOrg) {
|
|
921
|
+
this._apiOrg = apiOrg;
|
|
922
|
+
}
|
|
923
|
+
async _buildMessages(text, opts, pluginData) {
|
|
924
|
+
var _a, _b;
|
|
925
|
+
const { systemMessage = this._systemMessage, completionParams } = opts;
|
|
926
|
+
let { parentMessageId, contextRestriction } = opts;
|
|
927
|
+
let errorMessage = "";
|
|
928
|
+
const userLabel = USER_LABEL_DEFAULT;
|
|
929
|
+
const assistantLabel = ASSISTANT_LABEL_DEFAULT;
|
|
930
|
+
const maxNumTokens = this._maxModelTokens - this._maxResponseTokens;
|
|
931
|
+
let messages = [];
|
|
932
|
+
if (systemMessage) {
|
|
933
|
+
messages.push({
|
|
934
|
+
role: "system",
|
|
935
|
+
content: systemMessage
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
let objText = [{ type: "text", text }];
|
|
939
|
+
if (completionParams.fileList && completionParams.fileList.length > 0) {
|
|
940
|
+
completionParams.fileList.forEach((item) => {
|
|
941
|
+
if ((item == null ? void 0 : item.type.indexOf("image")) > -1) {
|
|
942
|
+
objText.push({
|
|
943
|
+
type: "image_url",
|
|
944
|
+
image_url: {
|
|
945
|
+
url: item.imgUrl
|
|
946
|
+
}
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
});
|
|
950
|
+
if (["openai", "azure"].indexOf(this._manufacturer.toLowerCase()) > -1) {
|
|
951
|
+
text = objText;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
const systemMessageOffset = messages.length;
|
|
955
|
+
let userMessage = null;
|
|
956
|
+
if ([
|
|
957
|
+
"baidu",
|
|
958
|
+
"zhipu",
|
|
959
|
+
"xunfei",
|
|
960
|
+
"aliyun",
|
|
961
|
+
"tencent",
|
|
962
|
+
"chatdoc",
|
|
963
|
+
"anthropic"
|
|
964
|
+
].indexOf(this._manufacturer.toLowerCase()) > -1) {
|
|
965
|
+
userMessage = [{ role: "user", content: text }];
|
|
966
|
+
} else if (pluginData) {
|
|
967
|
+
userMessage = {
|
|
968
|
+
role: pluginData.role,
|
|
969
|
+
name: pluginData.name,
|
|
970
|
+
content: JSON.stringify(pluginData.content),
|
|
971
|
+
tool_call_id: pluginData.tool_call_id
|
|
972
|
+
};
|
|
973
|
+
if (["azure"].indexOf(this._manufacturer.toLowerCase()) > -1) {
|
|
974
|
+
delete userMessage.tool_call_id;
|
|
975
|
+
}
|
|
976
|
+
} else {
|
|
977
|
+
userMessage = [{ role: "user", content: text, name: opts.name }];
|
|
978
|
+
}
|
|
979
|
+
let nextMessages = messages;
|
|
980
|
+
if (pluginData || text) {
|
|
981
|
+
nextMessages = nextMessages.concat(userMessage);
|
|
982
|
+
}
|
|
983
|
+
let numTokens = 0;
|
|
984
|
+
do {
|
|
985
|
+
const prompt = nextMessages.reduce((prompt2, message) => {
|
|
986
|
+
switch (message.role) {
|
|
987
|
+
case "tool":
|
|
988
|
+
return prompt2.concat([`Tool:
|
|
989
|
+
function call`]);
|
|
990
|
+
case "system":
|
|
991
|
+
return prompt2.concat([`Instructions:
|
|
992
|
+
${message.content}`]);
|
|
993
|
+
case "user":
|
|
994
|
+
return prompt2.concat([`${userLabel}:
|
|
995
|
+
${message.content}`]);
|
|
996
|
+
default:
|
|
997
|
+
return prompt2.concat([`${assistantLabel}:
|
|
998
|
+
${message.content}`]);
|
|
999
|
+
}
|
|
1000
|
+
}, []).join("\n\n");
|
|
1001
|
+
const nextNumTokensEstimate = await this._getTokenCount(prompt);
|
|
1002
|
+
const isValidPrompt = nextNumTokensEstimate <= maxNumTokens;
|
|
1003
|
+
if (prompt && !isValidPrompt && ["openai", "azure"].indexOf(this._manufacturer.toLowerCase()) > -1) {
|
|
1004
|
+
break;
|
|
1005
|
+
}
|
|
1006
|
+
messages = nextMessages;
|
|
1007
|
+
numTokens = nextNumTokensEstimate;
|
|
1008
|
+
if (!isValidPrompt && ["openai", "azure"].indexOf(this._manufacturer.toLowerCase()) > -1) {
|
|
1009
|
+
break;
|
|
1010
|
+
}
|
|
1011
|
+
if (!parentMessageId) {
|
|
1012
|
+
break;
|
|
1013
|
+
}
|
|
1014
|
+
const parentMessage = await this._getMessageById(parentMessageId);
|
|
1015
|
+
if (!parentMessage) {
|
|
1016
|
+
break;
|
|
1017
|
+
}
|
|
1018
|
+
const parentMessageRole = parentMessage.role || "user";
|
|
1019
|
+
let parentMessageItem = null;
|
|
1020
|
+
if ([
|
|
1021
|
+
"baidu",
|
|
1022
|
+
"zhipu",
|
|
1023
|
+
"xunfei",
|
|
1024
|
+
"aliyun",
|
|
1025
|
+
"tencent",
|
|
1026
|
+
"chatdoc",
|
|
1027
|
+
"anthropic"
|
|
1028
|
+
].indexOf(this._manufacturer.toLowerCase()) > -1) {
|
|
1029
|
+
parentMessageItem = {
|
|
1030
|
+
role: parentMessageRole,
|
|
1031
|
+
content: parentMessage.text
|
|
1032
|
+
};
|
|
1033
|
+
} else if (parentMessage.content && ((_a = parentMessage.content) == null ? void 0 : _a.finish_reason) === "tool_calls") {
|
|
1034
|
+
if (["azure"].indexOf(this._manufacturer.toLowerCase()) > -1) {
|
|
1035
|
+
parentMessageItem = Object.assign(parentMessage.content.message, {
|
|
1036
|
+
function_call: (_b = parentMessage.content.message.tool_calls[0]) == null ? void 0 : _b.function,
|
|
1037
|
+
content: parentMessage.text || parentMessage.content
|
|
1038
|
+
});
|
|
1039
|
+
delete parentMessage.content.message.tool_calls;
|
|
1040
|
+
} else {
|
|
1041
|
+
parentMessageItem = parentMessage.content.message;
|
|
1042
|
+
}
|
|
1043
|
+
} else {
|
|
1044
|
+
parentMessageItem = {
|
|
1045
|
+
role: parentMessageRole,
|
|
1046
|
+
content: parentMessage.text || parentMessage.content,
|
|
1047
|
+
name: parentMessage.name
|
|
1048
|
+
};
|
|
1049
|
+
if (parentMessage.tool_call_id)
|
|
1050
|
+
parentMessageItem.tool_call_id = parentMessage.tool_call_id;
|
|
1051
|
+
}
|
|
1052
|
+
nextMessages = nextMessages.slice(0, systemMessageOffset).concat([parentMessageItem, ...nextMessages.slice(systemMessageOffset)]);
|
|
1053
|
+
if (nextMessages.length >= contextRestriction)
|
|
1054
|
+
break;
|
|
1055
|
+
parentMessageId = parentMessage.parentMessageId;
|
|
1056
|
+
} while (true);
|
|
1057
|
+
let maxTokens = this._maxModelTokens;
|
|
1058
|
+
if (isPositiveNumber(maxTokens)) {
|
|
1059
|
+
if (["openai", "azure"].indexOf(this._manufacturer.toLowerCase()) > -1) {
|
|
1060
|
+
maxTokens = Math.max(
|
|
1061
|
+
1,
|
|
1062
|
+
Math.min(this._maxModelTokens - numTokens, this._maxResponseTokens)
|
|
1063
|
+
);
|
|
1064
|
+
} else if (numTokens > this._maxModelTokens) {
|
|
1065
|
+
maxTokens = this._maxModelTokens;
|
|
1066
|
+
errorMessage = `${this._manufacturer}\uFF1A\u5F53\u524D\u63D0\u95EE\u4E0A\u4E0B\u6587\u5185\u5BB9\u957F\u5EA6${numTokens}tokns\u8D85\u957F\uFF0C\u8BE5\u6A21\u578B\u6700\u5927\u63D0\u95EE\u957F\u5EA6\u4E3A${this._maxModelTokens}tokens\uFF0C\u8BF7\u5207\u6362\u5176\u4ED6\u589E\u5F3AAI\u6A21\u578B\u6216\u51CF\u5C11\u5B57\u6570\u6216\u8005\u5173\u95ED\u4E0A\u4E0B\u6587\u5386\u53F2\u63D0\u9AD8\u5355\u6B21\u63D0\u95EE\u957F\u5EA6\uFF01`;
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
return { messages, maxTokens, numTokens, errorMessage, objText };
|
|
1070
|
+
}
|
|
1071
|
+
async _getTokenCount(text) {
|
|
1072
|
+
text = text.replace(/<\|endoftext\|>/g, "");
|
|
1073
|
+
return encode(text).length;
|
|
1074
|
+
}
|
|
1075
|
+
async _defaultGetMessageById(id) {
|
|
1076
|
+
const res = await this._messageStore.get(id);
|
|
1077
|
+
return res;
|
|
1078
|
+
}
|
|
1079
|
+
async _defaultUpsertMessage(message) {
|
|
1080
|
+
await this._messageStore.set(message.id, message);
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
|
|
1084
|
+
// src/chatgpt-unofficial-proxy-api.ts
|
|
1085
|
+
import pTimeout2 from "p-timeout";
|
|
1086
|
+
import { v4 as uuidv42 } from "uuid";
|
|
1087
|
+
var ChatGPTUnofficialProxyAPI = class {
|
|
1088
|
+
/**
|
|
1089
|
+
* @param fetch - Optional override for the `fetch` implementation to use. Defaults to the global `fetch` function.
|
|
1090
|
+
*/
|
|
1091
|
+
constructor(opts) {
|
|
1092
|
+
const {
|
|
1093
|
+
accessToken,
|
|
1094
|
+
apiReverseProxyUrl = "https://bypass.duti.tech/api/conversation",
|
|
1095
|
+
model = "text-davinci-002-render-sha",
|
|
1096
|
+
debug = false,
|
|
1097
|
+
headers,
|
|
1098
|
+
fetch: fetch2 = fetch
|
|
1099
|
+
} = opts;
|
|
1100
|
+
this._accessToken = accessToken;
|
|
1101
|
+
this._apiReverseProxyUrl = apiReverseProxyUrl;
|
|
1102
|
+
this._debug = !!debug;
|
|
1103
|
+
this._model = model;
|
|
1104
|
+
this._fetch = fetch2;
|
|
1105
|
+
this._headers = headers;
|
|
1106
|
+
if (!this._accessToken) {
|
|
1107
|
+
throw new Error("ChatGPT invalid accessToken");
|
|
1108
|
+
}
|
|
1109
|
+
if (!this._fetch) {
|
|
1110
|
+
throw new Error("Invalid environment; fetch is not defined");
|
|
1111
|
+
}
|
|
1112
|
+
if (typeof this._fetch !== "function") {
|
|
1113
|
+
throw new Error('Invalid "fetch" is not a function');
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
get accessToken() {
|
|
1117
|
+
return this._accessToken;
|
|
1118
|
+
}
|
|
1119
|
+
set accessToken(value) {
|
|
1120
|
+
this._accessToken = value;
|
|
1121
|
+
}
|
|
1122
|
+
/**
|
|
1123
|
+
* Sends a message to ChatGPT, waits for the response to resolve, and returns
|
|
1124
|
+
* the response.
|
|
1125
|
+
*
|
|
1126
|
+
* If you want your response to have historical context, you must provide a valid `parentMessageId`.
|
|
1127
|
+
*
|
|
1128
|
+
* If you want to receive a stream of partial responses, use `opts.onProgress`.
|
|
1129
|
+
* If you want to receive the full response, including message and conversation IDs,
|
|
1130
|
+
* you can use `opts.onConversationResponse` or use the `ChatGPTAPI.getConversation`
|
|
1131
|
+
* helper.
|
|
1132
|
+
*
|
|
1133
|
+
* Set `debug: true` in the `ChatGPTAPI` constructor to log more info on the full prompt sent to the OpenAI completions API. You can override the `promptPrefix` and `promptSuffix` in `opts` to customize the prompt.
|
|
1134
|
+
*
|
|
1135
|
+
* @param message - The prompt message to send
|
|
1136
|
+
* @param opts.conversationId - Optional ID of a conversation to continue (defaults to a random UUID)
|
|
1137
|
+
* @param opts.parentMessageId - Optional ID of the previous message in the conversation (defaults to `undefined`)
|
|
1138
|
+
* @param opts.messageId - Optional ID of the message to send (defaults to a random UUID)
|
|
1139
|
+
* @param opts.timeoutMs - Optional timeout in milliseconds (defaults to no timeout)
|
|
1140
|
+
* @param opts.onProgress - Optional callback which will be invoked every time the partial response is updated
|
|
1141
|
+
* @param opts.abortSignal - Optional callback used to abort the underlying `fetch` call using an [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)
|
|
1142
|
+
*
|
|
1143
|
+
* @returns The response from ChatGPT
|
|
1144
|
+
*/
|
|
1145
|
+
async sendMessage(text, opts = {}) {
|
|
1146
|
+
if (!!opts.conversationId !== !!opts.parentMessageId) {
|
|
1147
|
+
throw new Error(
|
|
1148
|
+
"ChatGPTUnofficialProxyAPI.sendMessage: conversationId and parentMessageId must both be set or both be undefined"
|
|
1149
|
+
);
|
|
1150
|
+
}
|
|
1151
|
+
if (opts.conversationId && !isValidUUIDv4(opts.conversationId)) {
|
|
1152
|
+
throw new Error(
|
|
1153
|
+
"ChatGPTUnofficialProxyAPI.sendMessage: conversationId is not a valid v4 UUID"
|
|
1154
|
+
);
|
|
1155
|
+
}
|
|
1156
|
+
if (opts.parentMessageId && !isValidUUIDv4(opts.parentMessageId)) {
|
|
1157
|
+
throw new Error(
|
|
1158
|
+
"ChatGPTUnofficialProxyAPI.sendMessage: parentMessageId is not a valid v4 UUID"
|
|
1159
|
+
);
|
|
1160
|
+
}
|
|
1161
|
+
if (opts.messageId && !isValidUUIDv4(opts.messageId)) {
|
|
1162
|
+
throw new Error(
|
|
1163
|
+
"ChatGPTUnofficialProxyAPI.sendMessage: messageId is not a valid v4 UUID"
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
const {
|
|
1167
|
+
conversationId,
|
|
1168
|
+
parentMessageId = uuidv42(),
|
|
1169
|
+
messageId = uuidv42(),
|
|
1170
|
+
action = "next",
|
|
1171
|
+
timeoutMs,
|
|
1172
|
+
onProgress
|
|
1173
|
+
} = opts;
|
|
1174
|
+
let { abortSignal } = opts;
|
|
1175
|
+
let abortController = null;
|
|
1176
|
+
if (timeoutMs && !abortSignal) {
|
|
1177
|
+
abortController = new AbortController();
|
|
1178
|
+
abortSignal = abortController.signal;
|
|
1179
|
+
}
|
|
1180
|
+
const body = {
|
|
1181
|
+
action,
|
|
1182
|
+
messages: [
|
|
1183
|
+
{
|
|
1184
|
+
id: messageId,
|
|
1185
|
+
role: "user",
|
|
1186
|
+
content: {
|
|
1187
|
+
content_type: "text",
|
|
1188
|
+
parts: [text]
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
],
|
|
1192
|
+
model: this._model,
|
|
1193
|
+
parent_message_id: parentMessageId
|
|
1194
|
+
};
|
|
1195
|
+
if (conversationId) {
|
|
1196
|
+
body.conversation_id = conversationId;
|
|
1197
|
+
}
|
|
1198
|
+
const result = {
|
|
1199
|
+
role: "assistant",
|
|
1200
|
+
id: uuidv42(),
|
|
1201
|
+
parentMessageId: messageId,
|
|
1202
|
+
conversationId,
|
|
1203
|
+
text: ""
|
|
1204
|
+
};
|
|
1205
|
+
const responseP = new Promise((resolve, reject) => {
|
|
1206
|
+
const url = this._apiReverseProxyUrl;
|
|
1207
|
+
const headers = {
|
|
1208
|
+
...this._headers,
|
|
1209
|
+
Authorization: `Bearer ${this._accessToken}`,
|
|
1210
|
+
Accept: "text/event-stream",
|
|
1211
|
+
"Content-Type": "application/json"
|
|
1212
|
+
};
|
|
1213
|
+
if (this._debug) {
|
|
1214
|
+
console.log("POST", url, { body, headers });
|
|
1215
|
+
}
|
|
1216
|
+
fetchSSE(
|
|
1217
|
+
url,
|
|
1218
|
+
{
|
|
1219
|
+
method: "POST",
|
|
1220
|
+
headers,
|
|
1221
|
+
body: JSON.stringify(body),
|
|
1222
|
+
signal: abortSignal,
|
|
1223
|
+
onMessage: (data) => {
|
|
1224
|
+
var _a, _b, _c;
|
|
1225
|
+
if (data === "[DONE]") {
|
|
1226
|
+
return resolve(result);
|
|
1227
|
+
}
|
|
1228
|
+
try {
|
|
1229
|
+
const convoResponseEvent = JSON.parse(data);
|
|
1230
|
+
if (convoResponseEvent.conversation_id) {
|
|
1231
|
+
result.conversationId = convoResponseEvent.conversation_id;
|
|
1232
|
+
}
|
|
1233
|
+
if ((_a = convoResponseEvent.message) == null ? void 0 : _a.id) {
|
|
1234
|
+
result.id = convoResponseEvent.message.id;
|
|
1235
|
+
}
|
|
1236
|
+
const message = convoResponseEvent.message;
|
|
1237
|
+
if (message) {
|
|
1238
|
+
let text2 = (_c = (_b = message == null ? void 0 : message.content) == null ? void 0 : _b.parts) == null ? void 0 : _c[0];
|
|
1239
|
+
if (text2) {
|
|
1240
|
+
result.text = text2;
|
|
1241
|
+
if (onProgress) {
|
|
1242
|
+
onProgress(result);
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
} catch (err) {
|
|
1247
|
+
if (this._debug) {
|
|
1248
|
+
console.warn("chatgpt unexpected JSON error", err);
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
},
|
|
1252
|
+
onError: (err) => {
|
|
1253
|
+
reject(err);
|
|
1254
|
+
}
|
|
1255
|
+
},
|
|
1256
|
+
this._fetch
|
|
1257
|
+
).catch((err) => {
|
|
1258
|
+
const errMessageL = err.toString().toLowerCase();
|
|
1259
|
+
if (result.text && (errMessageL === "error: typeerror: terminated" || errMessageL === "typeerror: terminated")) {
|
|
1260
|
+
return resolve(result);
|
|
1261
|
+
} else {
|
|
1262
|
+
return reject(err);
|
|
1263
|
+
}
|
|
1264
|
+
});
|
|
1265
|
+
});
|
|
1266
|
+
if (timeoutMs) {
|
|
1267
|
+
if (abortController) {
|
|
1268
|
+
;
|
|
1269
|
+
responseP.cancel = () => {
|
|
1270
|
+
abortController.abort();
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
return pTimeout2(responseP, {
|
|
1274
|
+
milliseconds: timeoutMs,
|
|
1275
|
+
message: "ChatGPT timed out waiting for response"
|
|
1276
|
+
});
|
|
1277
|
+
} else {
|
|
1278
|
+
return responseP;
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
};
|
|
1282
|
+
export {
|
|
1283
|
+
ChatGPTAPI,
|
|
1284
|
+
ChatGPTError,
|
|
1285
|
+
ChatGPTUnofficialProxyAPI,
|
|
1286
|
+
openai
|
|
1287
|
+
};
|