@baishuyun/coze-provider 0.0.17 → 0.1.0
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/.turbo/turbo-build.log +23 -22
- package/CHANGELOG.md +13 -0
- package/dist/index.js +121 -119
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +121 -119
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/coze-language-model.ts +67 -23
- package/src/stream-trasnformer/fields-json-transform-stream.ts +11 -19
- package/src/utils/accumulate-sse-response.ts +83 -0
package/dist/index.mjs
CHANGED
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
var VERSION = "0.0.1";
|
|
13
13
|
|
|
14
14
|
// src/coze-language-model.ts
|
|
15
|
-
import { ServerSentEventTransformStream } from "parse-sse";
|
|
16
|
-
import { TextDecoderStream } from "stream/web";
|
|
15
|
+
import { ServerSentEventTransformStream as ServerSentEventTransformStream2 } from "parse-sse";
|
|
16
|
+
import { TextDecoderStream as TextDecoderStream2 } from "stream/web";
|
|
17
17
|
|
|
18
18
|
// src/utils/prompt-to-model-msg.ts
|
|
19
19
|
import { RoleType } from "@coze/api";
|
|
@@ -107,6 +107,62 @@ var convertPromptToMessages = (messages) => {
|
|
|
107
107
|
});
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
+
// src/utils/accumulate-sse-response.ts
|
|
111
|
+
import { ServerSentEventTransformStream } from "parse-sse";
|
|
112
|
+
import { TextDecoderStream } from "stream/web";
|
|
113
|
+
async function accumulateSSEResponse(body) {
|
|
114
|
+
const sseStream = body.pipeThrough(
|
|
115
|
+
new TextDecoderStream()
|
|
116
|
+
).pipeThrough(new ServerSentEventTransformStream());
|
|
117
|
+
let textContent = "";
|
|
118
|
+
let reasoningContent = "";
|
|
119
|
+
let finishReason = "stop";
|
|
120
|
+
let usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
|
|
121
|
+
const reader = sseStream.getReader();
|
|
122
|
+
try {
|
|
123
|
+
while (true) {
|
|
124
|
+
const { done, value: evt } = await reader.read();
|
|
125
|
+
if (done) break;
|
|
126
|
+
if (!evt) continue;
|
|
127
|
+
let evtData;
|
|
128
|
+
try {
|
|
129
|
+
evtData = JSON.parse(evt.data);
|
|
130
|
+
} catch {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const event = evt.type;
|
|
134
|
+
if (event === "conversation.message.delta") {
|
|
135
|
+
if (evtData.reasoning_content) {
|
|
136
|
+
reasoningContent += evtData.reasoning_content;
|
|
137
|
+
} else if (evtData.content) {
|
|
138
|
+
textContent += evtData.content;
|
|
139
|
+
}
|
|
140
|
+
} else if (event === "conversation.chat.completed" || event === "done") {
|
|
141
|
+
finishReason = "stop";
|
|
142
|
+
if (evtData.usage) {
|
|
143
|
+
usage = {
|
|
144
|
+
inputTokens: evtData.usage.input_count || 0,
|
|
145
|
+
outputTokens: evtData.usage.output_count || 0,
|
|
146
|
+
totalTokens: evtData.usage.total_count || 0
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
} else if (event === "error") {
|
|
150
|
+
finishReason = "error";
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
} finally {
|
|
154
|
+
reader.releaseLock();
|
|
155
|
+
}
|
|
156
|
+
const content = [];
|
|
157
|
+
if (reasoningContent) {
|
|
158
|
+
content.push({ type: "reasoning", text: reasoningContent });
|
|
159
|
+
}
|
|
160
|
+
if (textContent) {
|
|
161
|
+
content.push({ type: "text", text: textContent });
|
|
162
|
+
}
|
|
163
|
+
return { content, finishReason, usage };
|
|
164
|
+
}
|
|
165
|
+
|
|
110
166
|
// src/utils/create-error-stream.ts
|
|
111
167
|
import { generateId } from "@ai-sdk/provider-utils";
|
|
112
168
|
var createErrorStream = (error) => {
|
|
@@ -333,57 +389,6 @@ var LLMPartTrasnformStream = class extends TransformStream {
|
|
|
333
389
|
}
|
|
334
390
|
};
|
|
335
391
|
|
|
336
|
-
// src/utils/create-coze-non-streaming-chat.ts
|
|
337
|
-
var createCozeNonStreamingChat = async (botId, options, chatConfig) => {
|
|
338
|
-
const messages = convertPromptToMessages(options.prompt);
|
|
339
|
-
const url = chatConfig.url({
|
|
340
|
-
path: "/chat"
|
|
341
|
-
});
|
|
342
|
-
const user_id = (options.headers ? options.headers["x-user-id"] : "") || Date.now().toString();
|
|
343
|
-
const user_var = options.headers ? options.headers["x-user-var"] : "";
|
|
344
|
-
let customVar;
|
|
345
|
-
if (user_var) {
|
|
346
|
-
try {
|
|
347
|
-
customVar = JSON.parse(user_var);
|
|
348
|
-
} catch (e) {
|
|
349
|
-
console.warn("x-user-var parse error", e);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
const body = {
|
|
353
|
-
bot_id: botId,
|
|
354
|
-
auto_save_history: true,
|
|
355
|
-
user_id: user_id || "7543191937730215936",
|
|
356
|
-
additional_messages: messages,
|
|
357
|
-
stream: false
|
|
358
|
-
};
|
|
359
|
-
if (customVar) {
|
|
360
|
-
body.custom_var = customVar;
|
|
361
|
-
}
|
|
362
|
-
const headers = chatConfig.headers();
|
|
363
|
-
const abortSignal = options.abortSignal;
|
|
364
|
-
const response = await fetch(url, {
|
|
365
|
-
method: "POST",
|
|
366
|
-
headers,
|
|
367
|
-
credentials: "include",
|
|
368
|
-
body: JSON.stringify(body),
|
|
369
|
-
signal: abortSignal
|
|
370
|
-
});
|
|
371
|
-
return response;
|
|
372
|
-
};
|
|
373
|
-
|
|
374
|
-
// src/utils/get-coze-chat-msg-detail.ts
|
|
375
|
-
var getCozeChatMsgDetail = async (conversationId, chatId, chatConfig) => {
|
|
376
|
-
const url = chatConfig.url({
|
|
377
|
-
path: `/chat/message/list?conversation_id=${conversationId}&chat_id=${chatId}`
|
|
378
|
-
});
|
|
379
|
-
const response = await fetch(url, {
|
|
380
|
-
method: "POST",
|
|
381
|
-
headers: chatConfig.headers(),
|
|
382
|
-
credentials: "include"
|
|
383
|
-
});
|
|
384
|
-
return response;
|
|
385
|
-
};
|
|
386
|
-
|
|
387
392
|
// src/utils/build-generate-result-by-chat-res.ts
|
|
388
393
|
var BuildWarningGenerateResult = (message) => {
|
|
389
394
|
return {
|
|
@@ -408,42 +413,6 @@ var BuildWarningGenerateResult = (message) => {
|
|
|
408
413
|
]
|
|
409
414
|
};
|
|
410
415
|
};
|
|
411
|
-
var BuildGenerateResultByChatRes = async (response, chatConfig, reqBody) => {
|
|
412
|
-
if (!response.ok) {
|
|
413
|
-
return Promise.reject(
|
|
414
|
-
BuildWarningGenerateResult(`Coze API error: ${response.status} ${response.statusText}`)
|
|
415
|
-
);
|
|
416
|
-
}
|
|
417
|
-
const res = await response.json();
|
|
418
|
-
if (res.code !== 0) {
|
|
419
|
-
return Promise.reject(BuildWarningGenerateResult(`Coze API error: ${res.code} ${res.msg}`));
|
|
420
|
-
}
|
|
421
|
-
const msgRes = await getCozeChatMsgDetail(res.data.conversation_id, res.data.id, chatConfig);
|
|
422
|
-
if (!msgRes.ok) {
|
|
423
|
-
return Promise.reject(
|
|
424
|
-
BuildWarningGenerateResult(
|
|
425
|
-
`Failed to get message detail: ${msgRes.status} ${msgRes.statusText}`
|
|
426
|
-
)
|
|
427
|
-
);
|
|
428
|
-
}
|
|
429
|
-
const msgDetail = await msgRes.json();
|
|
430
|
-
return {
|
|
431
|
-
content: msgDetail.data.message.content,
|
|
432
|
-
finishReason: msgDetail.data.message.status === "finished" ? "stop" : "error",
|
|
433
|
-
request: {
|
|
434
|
-
body: reqBody
|
|
435
|
-
},
|
|
436
|
-
usage: {
|
|
437
|
-
inputTokens: 0,
|
|
438
|
-
outputTokens: 0,
|
|
439
|
-
totalTokens: 0
|
|
440
|
-
},
|
|
441
|
-
response: {
|
|
442
|
-
body: msgDetail
|
|
443
|
-
},
|
|
444
|
-
warnings: []
|
|
445
|
-
};
|
|
446
|
-
};
|
|
447
416
|
|
|
448
417
|
// src/coze-language-model.ts
|
|
449
418
|
var CozeLanguageModel = class {
|
|
@@ -458,23 +427,59 @@ var CozeLanguageModel = class {
|
|
|
458
427
|
this.supportedUrls = config.supportedUrls?.() || {};
|
|
459
428
|
this.config = config;
|
|
460
429
|
}
|
|
461
|
-
// @not-support
|
|
462
|
-
// coze 目前不支持非流式接口,为了兼容接口规范,仍然实现了 doGenerate 方法
|
|
463
430
|
async doGenerate(options) {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
);
|
|
467
|
-
const
|
|
468
|
-
|
|
469
|
-
|
|
431
|
+
const messages = convertPromptToMessages(options.prompt);
|
|
432
|
+
const warnings = [];
|
|
433
|
+
const url = this.config.url({ path: "/chat" });
|
|
434
|
+
const user_id = options.headers ? options.headers["x-user-id"] : "";
|
|
435
|
+
const user_var = options.headers ? options.headers["x-user-var"] : "";
|
|
436
|
+
let customVar;
|
|
437
|
+
if (user_var) {
|
|
438
|
+
try {
|
|
439
|
+
customVar = JSON.parse(user_var);
|
|
440
|
+
} catch (e) {
|
|
441
|
+
console.warn("x-user-var parse error", e);
|
|
442
|
+
}
|
|
470
443
|
}
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
444
|
+
const body = {
|
|
445
|
+
bot_id: this.config.botId,
|
|
446
|
+
auto_save_history: false,
|
|
447
|
+
user_id: user_id || "7543191937730215936",
|
|
448
|
+
stream: true,
|
|
449
|
+
additional_messages: messages
|
|
450
|
+
};
|
|
451
|
+
if (customVar) {
|
|
452
|
+
body.custom_variables = customVar;
|
|
453
|
+
}
|
|
454
|
+
const headers = this.config.headers();
|
|
455
|
+
const abortSignal = options.abortSignal;
|
|
456
|
+
const response = await fetch(url, {
|
|
457
|
+
method: "POST",
|
|
458
|
+
headers,
|
|
459
|
+
credentials: "include",
|
|
460
|
+
body: JSON.stringify(body),
|
|
461
|
+
signal: abortSignal
|
|
462
|
+
});
|
|
463
|
+
if (!response.ok || !response.body) {
|
|
464
|
+
const rawError = await response.text();
|
|
465
|
+
let errorDetail;
|
|
466
|
+
try {
|
|
467
|
+
errorDetail = JSON.parse(rawError);
|
|
468
|
+
} catch {
|
|
469
|
+
errorDetail = rawError;
|
|
470
|
+
}
|
|
471
|
+
const errorMessage = typeof errorDetail === "object" && errorDetail?.msg ? errorDetail.msg : `Coze API error: ${response.status} ${response.statusText}`;
|
|
472
|
+
return BuildWarningGenerateResult(errorMessage);
|
|
473
|
+
}
|
|
474
|
+
const { content, finishReason, usage } = await accumulateSSEResponse(response.body);
|
|
475
|
+
return {
|
|
476
|
+
content,
|
|
477
|
+
finishReason,
|
|
478
|
+
usage,
|
|
479
|
+
request: { body },
|
|
480
|
+
response: { body: null },
|
|
481
|
+
warnings
|
|
482
|
+
};
|
|
478
483
|
}
|
|
479
484
|
isVisibleMsgPart(evtData) {
|
|
480
485
|
if (evtData.type === "knowledge" && evtData.role === "assistant") {
|
|
@@ -488,7 +493,7 @@ var CozeLanguageModel = class {
|
|
|
488
493
|
const url = this.config.url({
|
|
489
494
|
path: "/chat"
|
|
490
495
|
});
|
|
491
|
-
const user_id =
|
|
496
|
+
const user_id = options.headers ? options.headers["x-user-id"] : "";
|
|
492
497
|
const user_var = options.headers ? options.headers["x-user-var"] : "";
|
|
493
498
|
let customVar;
|
|
494
499
|
if (user_var) {
|
|
@@ -501,13 +506,12 @@ var CozeLanguageModel = class {
|
|
|
501
506
|
const body = {
|
|
502
507
|
bot_id: this.config.botId,
|
|
503
508
|
auto_save_history: false,
|
|
504
|
-
user_id: "7543191937730215936",
|
|
505
|
-
// user_id,
|
|
509
|
+
user_id: user_id || "7543191937730215936",
|
|
506
510
|
stream: true,
|
|
507
511
|
additional_messages: messages
|
|
508
512
|
};
|
|
509
513
|
if (customVar) {
|
|
510
|
-
body.
|
|
514
|
+
body.custom_variables = customVar;
|
|
511
515
|
}
|
|
512
516
|
const headers = this.config.headers();
|
|
513
517
|
const abortSignal = options.abortSignal;
|
|
@@ -539,8 +543,8 @@ var CozeLanguageModel = class {
|
|
|
539
543
|
const isBuildStage = stage === "build";
|
|
540
544
|
const isFillStage = stage === "fill";
|
|
541
545
|
const result = response.body.pipeThrough(
|
|
542
|
-
new
|
|
543
|
-
).pipeThrough(new
|
|
546
|
+
new TextDecoderStream2()
|
|
547
|
+
).pipeThrough(new ServerSentEventTransformStream2()).pipeThrough(new MCPChunkFilterTransformStream(isBuildStage || isFillStage)).pipeThrough(new LLMChunkInjectorTransformStream()).pipeThrough(new LLMPartTrasnformStream());
|
|
544
548
|
let finalResult = result;
|
|
545
549
|
if (externalTransformers.length > 0) {
|
|
546
550
|
finalResult = externalTransformers.reduce(
|
|
@@ -1805,10 +1809,12 @@ var rebuildFieldsJsonStructure = (truncatedJson, subItemsOnly = false) => {
|
|
|
1805
1809
|
// src/stream-trasnformer/fields-json-transform-stream.ts
|
|
1806
1810
|
var createFieldsJsonTransformStream = (enableJsonParser) => {
|
|
1807
1811
|
let parser;
|
|
1812
|
+
let enqueueTextDelta;
|
|
1808
1813
|
let id;
|
|
1809
1814
|
let isFirstChunk = true;
|
|
1815
|
+
let passthroughMode = false;
|
|
1810
1816
|
const chunkGuard = (chunk) => {
|
|
1811
|
-
if (!enableJsonParser) {
|
|
1817
|
+
if (!enableJsonParser || passthroughMode) {
|
|
1812
1818
|
return false;
|
|
1813
1819
|
}
|
|
1814
1820
|
if (chunk.type !== "text-delta" || !("delta" in chunk)) {
|
|
@@ -1825,7 +1831,7 @@ var createFieldsJsonTransformStream = (enableJsonParser) => {
|
|
|
1825
1831
|
}
|
|
1826
1832
|
},
|
|
1827
1833
|
transform: (chunk, controller) => {
|
|
1828
|
-
if (!parser) {
|
|
1834
|
+
if (!parser && !passthroughMode) {
|
|
1829
1835
|
return;
|
|
1830
1836
|
}
|
|
1831
1837
|
try {
|
|
@@ -1854,7 +1860,7 @@ var createFieldsJsonTransformStream = (enableJsonParser) => {
|
|
|
1854
1860
|
parser = new JSONParser({
|
|
1855
1861
|
paths: ["$.*"]
|
|
1856
1862
|
});
|
|
1857
|
-
|
|
1863
|
+
enqueueTextDelta = enableJsonParser ? createTextInfoEnqueuer(controller) : (content) => {
|
|
1858
1864
|
};
|
|
1859
1865
|
parser.onValue = (parsedInfo) => {
|
|
1860
1866
|
const value = parsedInfo.value;
|
|
@@ -1870,13 +1876,9 @@ var createFieldsJsonTransformStream = (enableJsonParser) => {
|
|
|
1870
1876
|
id
|
|
1871
1877
|
);
|
|
1872
1878
|
};
|
|
1873
|
-
let errorLogged = false;
|
|
1874
1879
|
parser.onError = (err) => {
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
console.error("JsonWidgetStream: JSON Parsing Error:", err);
|
|
1878
|
-
errorLogged = true;
|
|
1879
|
-
}
|
|
1880
|
+
console.error("JsonWidgetStream: JSON Parsing Error:", err);
|
|
1881
|
+
passthroughMode = true;
|
|
1880
1882
|
};
|
|
1881
1883
|
parser.onEnd = () => {
|
|
1882
1884
|
enqueueTextDelta(
|