@baishuyun/coze-provider 2.0.45 → 2.0.47

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/dist/index.mjs CHANGED
@@ -78,6 +78,109 @@ var convertPromptToMessages = (messages) => {
78
78
  // src/utils/accumulate-sse-response.ts
79
79
  import { ServerSentEventTransformStream } from "parse-sse";
80
80
  import { TextDecoderStream } from "stream/web";
81
+
82
+ // src/utils/mcp-to-llm-chunk.ts
83
+ import { ChatEventType } from "@coze/api";
84
+ var mapCozeUsage = (usage) => {
85
+ const inputTokens = usage?.input_count || 0;
86
+ const outputTokens = usage?.output_count || 0;
87
+ const totalTokens = usage?.total_count ?? usage?.token_count ?? inputTokens + outputTokens;
88
+ return { inputTokens, outputTokens, totalTokens };
89
+ };
90
+ var extractUsageFromMsgMeta = (meta) => {
91
+ if (!meta) return null;
92
+ const totalTokens = Number(meta.token);
93
+ if (!totalTokens) return null;
94
+ return {
95
+ inputTokens: Number(meta.input_tokens) || 0,
96
+ outputTokens: Number(meta.output_tokens) || 0,
97
+ totalTokens
98
+ };
99
+ };
100
+ var mcp2llmChunk = (part) => {
101
+ const fullData = JSON.stringify(part);
102
+ switch (part.event) {
103
+ case ChatEventType.CONVERSATION_CHAT_CREATED:
104
+ return {
105
+ type: "raw",
106
+ rawValue: part.data
107
+ };
108
+ break;
109
+ case ChatEventType.CONVERSATION_CHAT_IN_PROGRESS:
110
+ return {
111
+ // type: "text-delta",
112
+ // id: part.data.conversation_id,
113
+ // delta: part.data.content || "",
114
+ // providerMetadata: {
115
+ // raw: { data: fullData },
116
+ // },
117
+ type: "raw",
118
+ rawValue: part.data
119
+ };
120
+ break;
121
+ case ChatEventType.CONVERSATION_MESSAGE_DELTA:
122
+ const isReasoning = Boolean(part.data.reasoning_content);
123
+ return {
124
+ type: isReasoning ? "reasoning-delta" : "text-delta",
125
+ delta: isReasoning ? part.data.reasoning_content : part.data.content,
126
+ id: part.data.conversation_id,
127
+ providerMetadata: {}
128
+ };
129
+ break;
130
+ case ChatEventType.CONVERSATION_MESSAGE_COMPLETED:
131
+ if (part.data && part.data.type === "follow_up") {
132
+ return {
133
+ type: "raw",
134
+ rawValue: part.data
135
+ };
136
+ }
137
+ if (part.status === "completed") {
138
+ return {
139
+ type: "text-end",
140
+ id: part.data.conversation_id,
141
+ // delta: part.data.content || part.data.reasoning_content || "",
142
+ providerMetadata: {}
143
+ };
144
+ }
145
+ return {
146
+ type: "raw",
147
+ rawValue: part.data
148
+ };
149
+ break;
150
+ case ChatEventType.CONVERSATION_CHAT_COMPLETED:
151
+ return {
152
+ type: "finish",
153
+ finishReason: "stop",
154
+ usage: mapCozeUsage(part.data.usage)
155
+ };
156
+ break;
157
+ case ChatEventType.DONE:
158
+ return {
159
+ type: "finish",
160
+ finishReason: "stop",
161
+ usage: mapCozeUsage(part.data.usage)
162
+ };
163
+ break;
164
+ case ChatEventType.ERROR:
165
+ console.error("[ERROR]", part.data);
166
+ return {
167
+ type: "error",
168
+ error: part.data
169
+ };
170
+ default:
171
+ console.warn("Unknown event type:", part.event);
172
+ return {
173
+ type: "error",
174
+ error: "Unknown event type" + part.event
175
+ };
176
+ }
177
+ return {
178
+ type: "error",
179
+ error: "unknown"
180
+ };
181
+ };
182
+
183
+ // src/utils/accumulate-sse-response.ts
81
184
  async function accumulateSSEResponse(body) {
82
185
  const sseStream = body.pipeThrough(
83
186
  new TextDecoderStream()
@@ -108,11 +211,7 @@ async function accumulateSSEResponse(body) {
108
211
  } else if (event === "conversation.chat.completed" || event === "done") {
109
212
  finishReason = "stop";
110
213
  if (evtData.usage) {
111
- usage = {
112
- inputTokens: evtData.usage.input_count || 0,
113
- outputTokens: evtData.usage.output_count || 0,
114
- totalTokens: evtData.usage.total_count || 0
115
- };
214
+ usage = mapCozeUsage(evtData.usage);
116
215
  }
117
216
  } else if (event === "error") {
118
217
  finishReason = "error";
@@ -211,13 +310,13 @@ var LLMChunkInjectorTransformStream = class extends TransformStream {
211
310
  };
212
311
 
213
312
  // src/stream-trasnformer/mcp-chunk-filter-transform-stream.ts
214
- import { ChatEventType } from "@coze/api";
313
+ import { ChatEventType as ChatEventType2 } from "@coze/api";
215
314
  var MCPChunkFilterTransformStream = class extends TransformStream {
216
315
  isVisibleMsgPart(evtData, part, omitTextEndChunk) {
217
316
  if (evtData.type === "knowledge" && evtData.role === "assistant") {
218
317
  return false;
219
318
  }
220
- if (omitTextEndChunk && part.event === ChatEventType.CONVERSATION_MESSAGE_COMPLETED && part.data.type !== "follow_up") {
319
+ if (omitTextEndChunk && part.event === ChatEventType2.CONVERSATION_MESSAGE_COMPLETED && part.data.type !== "follow_up") {
221
320
  return false;
222
321
  }
223
322
  if (part.event === "conversation.message.completed" && evtData.type == "verbose") {
@@ -241,101 +340,15 @@ var MCPChunkFilterTransformStream = class extends TransformStream {
241
340
  }
242
341
  };
243
342
 
244
- // src/utils/mcp-to-llm-chunk.ts
245
- import { ChatEventType as ChatEventType2 } from "@coze/api";
246
- var mcp2llmChunk = (part) => {
247
- const fullData = JSON.stringify(part);
248
- switch (part.event) {
249
- case ChatEventType2.CONVERSATION_CHAT_CREATED:
250
- return {
251
- type: "raw",
252
- rawValue: part.data
253
- };
254
- break;
255
- case ChatEventType2.CONVERSATION_CHAT_IN_PROGRESS:
256
- return {
257
- // type: "text-delta",
258
- // id: part.data.conversation_id,
259
- // delta: part.data.content || "",
260
- // providerMetadata: {
261
- // raw: { data: fullData },
262
- // },
263
- type: "raw",
264
- rawValue: part.data
265
- };
266
- break;
267
- case ChatEventType2.CONVERSATION_MESSAGE_DELTA:
268
- const isReasoning = Boolean(part.data.reasoning_content);
269
- return {
270
- type: isReasoning ? "reasoning-delta" : "text-delta",
271
- delta: isReasoning ? part.data.reasoning_content : part.data.content,
272
- id: part.data.conversation_id,
273
- providerMetadata: {}
274
- };
275
- break;
276
- case ChatEventType2.CONVERSATION_MESSAGE_COMPLETED:
277
- if (part.data && part.data.type === "follow_up") {
278
- return {
279
- type: "raw",
280
- rawValue: part.data
281
- };
282
- }
283
- if (part.status === "completed") {
284
- return {
285
- type: "text-end",
286
- id: part.data.conversation_id,
287
- // delta: part.data.content || part.data.reasoning_content || "",
288
- providerMetadata: {}
289
- };
290
- }
291
- return {
292
- type: "raw",
293
- rawValue: part.data
294
- };
295
- break;
296
- case ChatEventType2.CONVERSATION_CHAT_COMPLETED:
297
- return {
298
- type: "finish",
299
- finishReason: "stop",
300
- usage: {
301
- inputTokens: part.data.usage?.input_count || 0,
302
- outputTokens: part.data.usage?.output_count || 0,
303
- totalTokens: part.data.usage?.total_count || 0
304
- }
305
- };
306
- break;
307
- case ChatEventType2.DONE:
308
- return {
309
- type: "finish",
310
- finishReason: "stop",
311
- usage: {
312
- inputTokens: part.data.usage?.input_count || 0,
313
- outputTokens: part.data.usage?.output_count || 0,
314
- totalTokens: part.data.usage?.total_count || 0
315
- }
316
- };
317
- break;
318
- case ChatEventType2.ERROR:
319
- console.error("[ERROR]", part.data);
320
- return {
321
- type: "error",
322
- error: part.data
323
- };
324
- default:
325
- console.warn("Unknown event type:", part.event);
326
- return {
327
- type: "error",
328
- error: "Unknown event type" + part.event
329
- };
330
- }
331
- return {
332
- type: "error",
333
- error: "unknown"
334
- };
335
- };
336
-
337
343
  // src/stream-trasnformer/llm-part-transform-stream.ts
344
+ import { ChatEventType as ChatEventType3 } from "@coze/api";
338
345
  var LLMPartTrasnformStream = class extends TransformStream {
346
+ /**
347
+ * 本轮最近一条消息 meta_data 中携带的 token 用量。
348
+ * 旧版上游不在 conversation.chat.completed 事件中携带 usage,
349
+ * 发 finish chunk 时若事件 usage 缺失则用此兜底(事件已带则不覆盖)
350
+ */
351
+ lastMsgUsage = null;
339
352
  constructor() {
340
353
  super({
341
354
  transform: (part, controller) => {
@@ -345,8 +358,17 @@ var LLMPartTrasnformStream = class extends TransformStream {
345
358
  return;
346
359
  }
347
360
  try {
361
+ if (part.event === ChatEventType3.CONVERSATION_MESSAGE_COMPLETED) {
362
+ const usage = extractUsageFromMsgMeta(part.data?.meta_data);
363
+ if (usage) {
364
+ this.lastMsgUsage = usage;
365
+ }
366
+ }
348
367
  const chunk = mcp2llmChunk(part);
349
368
  if (chunk) {
369
+ if (chunk.type === "finish" && !chunk.usage?.totalTokens && this.lastMsgUsage) {
370
+ chunk.usage = this.lastMsgUsage;
371
+ }
350
372
  controller.enqueue(chunk);
351
373
  }
352
374
  } catch (error) {
@@ -465,13 +487,15 @@ var CozeLanguageModel = class {
465
487
  path: `/chat${queryStr}`
466
488
  });
467
489
  const user_id = options.headers ? options.headers["x-user-id"] : "";
490
+ const operator_id = (options.headers ? options.headers["x-operator-id"] : "") ?? "";
468
491
  const user_var = options.headers ? options.headers["x-user-var"] : "";
469
492
  const user_param = (options.headers ? options.headers["x-user-param"] : "") ?? "";
470
493
  const params = user_param ? safeParseJson(user_param) : {};
471
494
  console.log("params 2 workflow", params);
472
495
  console.log("conversation id 2 workflow", conversation_id);
473
496
  const chatCtx = options?.providerOptions?.chatCtx;
474
- const userId = chatCtx?.user?._id || user_id || Date.now().toString();
497
+ console.log("chatCtx", chatCtx);
498
+ const userId = operator_id || chatCtx?.user?._id || user_id || Date.now().toString();
475
499
  const body = {
476
500
  bot_id: this.config.botId,
477
501
  auto_save_history: Boolean(conversation_id),
@@ -489,6 +513,7 @@ var CozeLanguageModel = class {
489
513
  const abortSignal = options.abortSignal;
490
514
  console.log("url", url);
491
515
  console.log("body", JSON.stringify(body, null, 2));
516
+ console.log("operator_id", operator_id);
492
517
  const response = await fetch(url, {
493
518
  method: "POST",
494
519
  headers,
@@ -496,6 +521,7 @@ var CozeLanguageModel = class {
496
521
  body: JSON.stringify(body),
497
522
  signal: abortSignal
498
523
  });
524
+ console.log("chat res status", response.status);
499
525
  if (!response.ok || !response.body) {
500
526
  const rawError = await response.text();
501
527
  let errorDetail;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/coze-provider.ts","../src/const.ts","../src/coze-language-model.ts","../src/utils/prompt-to-model-msg.ts","../src/utils/accumulate-sse-response.ts","../src/utils/create-error-stream.ts","../src/evt-sample.ts","../src/stream-trasnformer/llm-chunk-injector-transform-stream.ts","../src/stream-trasnformer/mcp-chunk-filter-transform-stream.ts","../src/utils/mcp-to-llm-chunk.ts","../src/stream-trasnformer/llm-part-transform-stream.ts","../src/utils/build-generate-result-by-chat-res.ts","../src/stream-trasnformer/fields-json-transform-stream.ts","../src/utils/enqueue-text-info.ts","../src/stream-trasnformer/suggestion-transform-stream.ts"],"sourcesContent":["import {\n LanguageModelV2,\n LanguageModelV2StreamPart,\n NoSuchModelError,\n ProviderV2,\n} from '@ai-sdk/provider';\n\nimport {\n FetchFunction,\n loadApiKey,\n withoutTrailingSlash,\n withUserAgentSuffix,\n} from '@ai-sdk/provider-utils';\nimport { CozeChatModelId } from './types';\nimport { VERSION } from './const';\nimport { CozeLanguageModel } from './coze-language-model';\n\nexport interface CozeProviderSettings {\n apiKey?: string;\n /**\nBase URL for the API calls.\n*/\n baseURL?: string;\n\n botId: string;\n\n /**\nCustom headers to include in the requests.\n*/\n headers?: Record<string, string>;\n /**\nCustom fetch implementation. You can use it as a middleware to intercept requests,\nor to provide a custom fetch implementation for e.g. testing.\n*/\n fetch?: FetchFunction;\n\n extraStreamTransformers?: (() => TransformStream<LanguageModelV2StreamPart, any>)[];\n}\n\nexport interface CozeProvider extends ProviderV2 {\n (modelId: CozeChatModelId): LanguageModelV2;\n\n languageModel(modelId: CozeChatModelId): LanguageModelV2;\n\n /**\nCreates a DeepSeek chat model for text generation.\n*/\n chat(modelId: CozeChatModelId): LanguageModelV2;\n}\n\nexport function createCoze(\n options: CozeProviderSettings = {\n botId: '',\n }\n): CozeProvider {\n const baseURL = withoutTrailingSlash(options.baseURL);\n\n const agentPartHeader = withUserAgentSuffix(options.headers || {}, `ai-sdk/coze/${VERSION}`);\n const authorizationHeader = `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'COZE_API_KEY',\n description: '',\n })}`;\n\n const getHeaders = () => ({\n ...agentPartHeader,\n Authorization: authorizationHeader,\n 'content-type': 'application/json',\n });\n\n const createLanguageModel = (modelId: CozeChatModelId) => {\n return new CozeLanguageModel(modelId, {\n botId: options.botId,\n provider: `coze.chat`,\n url: ({ path }) => `${baseURL}${path}`,\n headers: getHeaders,\n fetch: options.fetch,\n extraStreamTransformers: options.extraStreamTransformers || [],\n });\n };\n\n const provider = (modelId: CozeChatModelId) => createLanguageModel(modelId);\n\n provider.specificationVersion = 'v3' as const;\n provider.languageModel = createLanguageModel;\n provider.chat = createLanguageModel;\n\n provider.embeddingModel = (modelId: string) => {\n throw new NoSuchModelError({ modelId, modelType: 'textEmbeddingModel' });\n };\n provider.imageModel = (modelId: string) => {\n throw new NoSuchModelError({ modelId, modelType: 'imageModel' });\n };\n provider.textEmbeddingModel = (modelId: string) => {\n throw new NoSuchModelError({ modelId, modelType: 'textEmbeddingModel' });\n };\n\n return provider;\n}\n","export const VERSION = \"0.0.1\";\n","import {\n LanguageModelV2,\n LanguageModelV2CallOptions,\n LanguageModelV2CallWarning,\n LanguageModelV2Prompt,\n LanguageModelV2StreamPart,\n SharedV2Headers,\n} from '@ai-sdk/provider';\nimport { CozeChatConfig, IGenerateResult } from './types';\nimport { ServerSentEventTransformStream } from 'parse-sse';\nimport { TextDecoderStream } from 'stream/web';\nimport { convertPromptToMessages } from './utils/prompt-to-model-msg';\nimport { accumulateSSEResponse } from './utils/accumulate-sse-response';\nimport { createErrorStream } from './utils/create-error-stream';\nimport { LLMChunkInjectorTransformStream } from './stream-trasnformer/llm-chunk-injector-transform-stream';\nimport MCPChunkFilterTransformStream from './stream-trasnformer/mcp-chunk-filter-transform-stream';\nimport LLMPartTrasnformStream from './stream-trasnformer/llm-part-transform-stream';\nimport { BuildWarningGenerateResult } from './utils/build-generate-result-by-chat-res';\nimport { getChatCtxForHuman, getChatCtxForMcp, safeParseJson } from '@baishuyun/ai-feat-utils';\nimport { IChatCtx } from '@baishuyun/types';\n\nexport class CozeLanguageModel implements LanguageModelV2 {\n specificationVersion: 'v2' = 'v2';\n provider: string;\n modelId: string;\n supportedUrls: Record<string, RegExp[]> | PromiseLike<Record<string, RegExp[]>>;\n\n private readonly config: CozeChatConfig;\n\n constructor(modelId: string, config: CozeChatConfig) {\n this.modelId = modelId;\n this.provider = config.provider || 'coze';\n this.supportedUrls = config.supportedUrls?.() || {};\n this.config = config;\n }\n\n async doGenerate(options: LanguageModelV2CallOptions): Promise<IGenerateResult> {\n const messages = convertPromptToMessages(options.prompt);\n const warnings: LanguageModelV2CallWarning[] = [];\n\n const url = this.config.url({ path: '/chat' });\n\n const user_id = options.headers ? options.headers['x-user-id'] : '';\n const user_var = options.headers ? options.headers['x-user-var'] : '';\n\n let customVar;\n if (user_var) {\n try {\n customVar = JSON.parse(user_var);\n } catch (e) {\n console.warn('x-user-var parse error', e);\n }\n }\n\n const body = {\n bot_id: this.config.botId,\n auto_save_history: false,\n user_id: user_id || '7543191937730215936',\n stream: true,\n additional_messages: messages,\n };\n\n if (customVar) {\n (body as any).custom_variables = customVar;\n }\n\n const headers = this.config.headers();\n const abortSignal = options.abortSignal;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: headers,\n credentials: 'include',\n body: JSON.stringify(body),\n signal: abortSignal,\n });\n\n if (!response.ok || !response.body) {\n const rawError = await response.text();\n let errorDetail;\n try {\n errorDetail = JSON.parse(rawError);\n } catch {\n errorDetail = rawError;\n }\n\n const errorMessage =\n typeof errorDetail === 'object' && errorDetail?.msg\n ? errorDetail.msg\n : `Coze API error: ${response.status} ${response.statusText}`;\n\n return BuildWarningGenerateResult(errorMessage);\n }\n\n const { content, finishReason, usage } = await accumulateSSEResponse(response.body);\n\n return {\n content,\n finishReason,\n usage,\n request: { body },\n response: { body: null },\n warnings,\n };\n }\n\n isVisibleMsgPart(evtData: any) {\n if (evtData.type === 'knowledge' && evtData.role === 'assistant') {\n return false;\n }\n\n return true;\n }\n\n async doStream(options: LanguageModelV2CallOptions): Promise<{\n stream: ReadableStream<LanguageModelV2StreamPart>;\n request?: { body?: unknown };\n response?: { headers?: SharedV2Headers };\n }> {\n const conversation_id = options.headers ? options.headers['x-conversation-id'] : '';\n\n // 有 conversation_id 时,服务端会话中已持有完整历史(含中断记录)。\n const prompt = conversation_id ? keepOnlyLastUserMessage(options.prompt) : options.prompt;\n\n const messages = convertPromptToMessages(prompt);\n const queryStr = conversation_id ? `?conversation_id=${conversation_id}` : '';\n\n const url = this.config.url({\n path: `/chat${queryStr}`,\n });\n\n const user_id = options.headers ? options.headers['x-user-id'] : '';\n\n const user_var = options.headers ? options.headers['x-user-var'] : '';\n const user_param = (options.headers ? options.headers['x-user-param'] : '') ?? '';\n\n const params = user_param ? safeParseJson(user_param) : {};\n\n console.log('params 2 workflow', params);\n console.log('conversation id 2 workflow', conversation_id);\n const chatCtx = options?.providerOptions?.chatCtx as unknown as IChatCtx;\n\n const userId = chatCtx?.user?._id || user_id || Date.now().toString();\n\n const body = {\n bot_id: this.config.botId,\n auto_save_history: Boolean(conversation_id),\n user_id: userId,\n stream: true,\n additional_messages: messages,\n parameters: params,\n custom_variables: user_var ? safeParseJson(user_var) : {},\n extra_params: {\n remark: getChatCtxForHuman(chatCtx),\n mcp_ctx: getChatCtxForMcp(chatCtx),\n },\n };\n\n const headers = this.config.headers();\n\n const abortSignal = options.abortSignal;\n\n console.log('url', url);\n console.log('body', JSON.stringify(body, null, 2));\n\n const response = await fetch(url, {\n method: 'POST',\n headers: headers,\n credentials: 'include',\n body: JSON.stringify(body),\n signal: abortSignal,\n });\n\n if (!response.ok || !response.body) {\n // if (true) {\n const rawError = await response.text();\n let errorDetail;\n try {\n errorDetail = JSON.parse(rawError); // 尝试解析为 JSON\n } catch {\n errorDetail = rawError; // 非 JSON 直接使用\n }\n\n // 创建一个包含错误信息的流,让 UI 层处理\n const errorMessage =\n typeof errorDetail === 'object' && errorDetail?.msg\n ? errorDetail.msg\n : `Coze API error: ${response.status} ${response.statusText}`;\n\n console.error(errorMessage);\n\n return {\n stream: createErrorStream('会话异常,请重试'),\n };\n }\n\n let externalTransformers = (this.config.extraStreamTransformers || []).map((factory) =>\n factory()\n );\n\n /// 不同阶段,可能需要不同的流处理逻辑\n const stage = options.headers ? options.headers['x-user-stage'] : '';\n const isBuildStage = stage === 'build';\n const isFillStage = stage === 'fill';\n\n const result = response.body\n // 将字节流解码为文本流\n .pipeThrough(\n new TextDecoderStream() as ReadableWritablePair<\n string | undefined,\n Uint8Array<ArrayBufferLike>\n >\n )\n // 解析为 SSE 事件流\n .pipeThrough(new ServerSentEventTransformStream())\n .pipeThrough(new MCPChunkFilterTransformStream(isBuildStage || isFillStage))\n // 补充特殊 llm chunk\n .pipeThrough(new LLMChunkInjectorTransformStream())\n // 转换为 LanguageModelV2StreamPart 格式\n .pipeThrough(new LLMPartTrasnformStream());\n\n let finalResult = result;\n\n if (externalTransformers.length > 0) {\n finalResult = externalTransformers.reduce(\n (stream, transformer) => stream.pipeThrough(transformer),\n result // 初始累积值(原始流)\n );\n }\n\n return {\n stream: finalResult as ReadableStream<LanguageModelV2StreamPart>,\n };\n }\n}\n\n/**\n * 只保留最后一条 user 消息(含其内容),用于有 conversation_id 的场景:\n * 服务端会话中已持有完整历史,只需发送当前用户输入。\n */\nfunction keepOnlyLastUserMessage(prompt: LanguageModelV2Prompt): LanguageModelV2Prompt {\n for (let i = prompt.length - 1; i >= 0; i--) {\n if (prompt[i].role === 'user') {\n return [prompt[i]];\n }\n }\n return prompt;\n}\n","import {\n LanguageModelV2FilePart,\n LanguageModelV2Message,\n LanguageModelV2Prompt,\n LanguageModelV2TextPart,\n} from '@ai-sdk/provider';\nimport { RoleType } from '@coze/api';\nimport { Attachment } from '@baishuyun/types/src/chat';\nimport { excel2json } from './excel2json';\n\nconst decoder = new TextDecoder('utf-8');\n\nconst data2csvText = (data: Uint8Array) => {\n return decoder.decode(data);\n};\n\ntype userMsg = {\n role: 'user';\n content: Array<LanguageModelV2TextPart | LanguageModelV2FilePart>;\n};\n\nconst getPartType = (part: LanguageModelV2TextPart | LanguageModelV2FilePart) => {\n if (part.type === 'text') {\n return 'text';\n }\n\n const isImg = part.mediaType?.startsWith('image/');\n if (isImg) {\n return 'image';\n }\n\n const isAudio = part.mediaType?.startsWith('audio/');\n if (isAudio) {\n return 'audio';\n }\n\n return 'file';\n};\n\nconst parseMessageContent = (message: LanguageModelV2Message, isTextOnly?: boolean) => {\n if (isTextOnly) {\n return (message.content as Array<LanguageModelV2TextPart>)\n .map((part: LanguageModelV2TextPart) => part.text)\n .join('\\n');\n }\n\n const result = (message.content as Array<LanguageModelV2TextPart | LanguageModelV2FilePart>).map(\n (part) => {\n const meta = part.providerOptions?.uploadMetadata as Attachment;\n const url = meta?.url;\n\n return {\n type: getPartType(part),\n text: part.type === 'text' ? (part as LanguageModelV2TextPart).text : '',\n file_id: meta?.file_id,\n name: meta?.name,\n // 附件地址:模型需要在「附件上传」标准动作中引用(IAttachment.attachmentUrl)\n url,\n };\n }\n );\n\n return JSON.stringify(result);\n};\n\nconst isTextOnlyMsg = (message: userMsg) => message.content.every((part) => part.type === 'text');\n\nexport const convertPromptToMessages = (messages: LanguageModelV2Prompt) => {\n return messages.map((message) => {\n const isTextOnly = isTextOnlyMsg(message as userMsg);\n switch (message.role) {\n case 'user':\n return {\n role: RoleType.User,\n content: parseMessageContent(message, isTextOnly),\n content_type: isTextOnly ? 'text' : 'object_string',\n };\n break;\n\n case 'assistant':\n return {\n role: RoleType.Assistant,\n content: (message.content as Array<LanguageModelV2TextPart>)\n .map((part: LanguageModelV2TextPart) => (part.type === 'text' ? part.text : ''))\n .join(''),\n content_type: 'text',\n };\n break;\n }\n });\n};\n","import {\n LanguageModelV2Content,\n LanguageModelV2FinishReason,\n LanguageModelV2Usage,\n} from '@ai-sdk/provider';\nimport { ServerSentEventTransformStream } from 'parse-sse';\nimport { TextDecoderStream } from 'stream/web';\n\nexport interface AccumulatedSSEResponse {\n content: LanguageModelV2Content[];\n finishReason: LanguageModelV2FinishReason;\n usage: LanguageModelV2Usage;\n}\n\n/**\n * 从字节流中解码 SSE 事件并累积完整响应内容\n */\nexport async function accumulateSSEResponse(\n body: ReadableStream<Uint8Array>\n): Promise<AccumulatedSSEResponse> {\n const sseStream = body\n .pipeThrough(\n new TextDecoderStream() as ReadableWritablePair<\n string | undefined,\n Uint8Array<ArrayBufferLike>\n >\n )\n .pipeThrough(new ServerSentEventTransformStream());\n\n let textContent = '';\n let reasoningContent = '';\n let finishReason: LanguageModelV2FinishReason = 'stop';\n let usage: LanguageModelV2Usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n\n const reader = sseStream.getReader();\n try {\n while (true) {\n const { done, value: evt } = await reader.read();\n if (done) break;\n if (!evt) continue;\n\n let evtData;\n try {\n evtData = JSON.parse(evt.data);\n } catch {\n continue;\n }\n\n const event = evt.type;\n\n if (event === 'conversation.message.delta') {\n if (evtData.reasoning_content) {\n reasoningContent += evtData.reasoning_content;\n } else if (evtData.content) {\n textContent += evtData.content;\n }\n } else if (event === 'conversation.chat.completed' || event === 'done') {\n finishReason = 'stop';\n if (evtData.usage) {\n usage = {\n inputTokens: evtData.usage.input_count || 0,\n outputTokens: evtData.usage.output_count || 0,\n totalTokens: evtData.usage.total_count || 0,\n };\n }\n } else if (event === 'error') {\n finishReason = 'error';\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n const content: LanguageModelV2Content[] = [];\n if (reasoningContent) {\n content.push({ type: 'reasoning', text: reasoningContent });\n }\n if (textContent) {\n content.push({ type: 'text', text: textContent });\n }\n\n return { content, finishReason, usage };\n}\n","import { LanguageModelV2StreamPart } from '@ai-sdk/provider';\nimport { generateId } from '@ai-sdk/provider-utils';\n\n/**\n * 创建一个包含错误信息的流\n * @param error 错误信息\n * @returns ReadableStream<LanguageModelV2StreamPart>\n */\nexport const createErrorStream = (error: string): ReadableStream<LanguageModelV2StreamPart> => {\n return new ReadableStream<LanguageModelV2StreamPart>({\n start(controller) {\n const id = generateId();\n controller.enqueue({\n id,\n type: 'text-start',\n });\n controller.enqueue({\n id,\n type: 'text-delta',\n providerMetadata: {\n raw: { data: { type: 'agent-error', error } },\n },\n delta: error,\n });\n controller.enqueue({\n type: 'text-end',\n id,\n });\n controller.close();\n },\n });\n};\n","/**\n * 事件数据取样,某些流 chunk 处理,需要用到前后的 chunk 信息,因此设计一个类缓存相邻 chunk,用于处理依据\n */\nexport class EvtSample {\n private _evtSampleMap: Map<string, any> = new Map();\n private _key1: string = \"1\";\n private _key2: string = \"2\";\n private _maxSample = 2;\n\n public addEventSample(evt: any) {\n if (this._evtSampleMap.size >= this._maxSample) {\n const evt2 = this._evtSampleMap.get(this._key2);\n this._evtSampleMap.set(this._key1, evt2);\n this._evtSampleMap.set(this._key2, evt);\n return;\n }\n\n this._evtSampleMap.set((this._evtSampleMap.size + 1).toString(), evt);\n }\n\n public getFirstSample() {\n return this._evtSampleMap.get(this._key1);\n }\n\n public getSecondSample() {\n return this._evtSampleMap.get(this._key2);\n }\n}\n","import { LanguageModelV2StreamPart } from '@ai-sdk/provider';\nimport { StreamChatData } from '@coze/api';\nimport { EvtSample } from '../evt-sample';\n\n/**\n * 补充特殊的 llm chunk, reasoning-end, text-start\n */\nexport class LLMChunkInjectorTransformStream extends TransformStream<\n StreamChatData,\n | StreamChatData\n | (LanguageModelV2StreamPart & {\n disableTransform: boolean;\n })\n> {\n private eventSampleMap = new EvtSample();\n\n constructor() {\n super({\n transform: (\n part: StreamChatData,\n controller: TransformStreamDefaultController<\n StreamChatData | (LanguageModelV2StreamPart & { disableTransform: boolean })\n >\n ) => {\n // 添加事件样本(原逻辑中的addEventSample)\n this.eventSampleMap.addEventSample(part);\n\n // 处理sample1/sample2特殊判断逻辑\n const sample1 = this.eventSampleMap.getFirstSample();\n const sample2 = this.eventSampleMap.getSecondSample();\n\n // handle reasoning end\n if (\n sample1 &&\n sample2 &&\n sample1.data.reasoning_content &&\n !sample2.data.reasoning_content\n ) {\n controller.enqueue({\n disableTransform: true,\n type: 'reasoning-end',\n id: sample1.data.conversation_id,\n });\n }\n\n // handle text-start\n if (sample1 && sample2 && !sample1.data.content && sample2.data.content) {\n controller.enqueue({\n disableTransform: true,\n type: 'text-start',\n id: sample2.data.conversation_id,\n });\n }\n\n // 传递part到下一个转换流\n controller.enqueue(part);\n },\n });\n }\n}\n","import { ChatEventType, StreamChatData } from '@coze/api';\nimport { ServerSentEvent } from 'parse-sse';\n\nexport default class MCPChunkFilterTransformStream extends TransformStream {\n isVisibleMsgPart(evtData: any, part: any, omitTextEndChunk?: boolean) {\n if (evtData.type === 'knowledge' && evtData.role === 'assistant') {\n return false;\n }\n\n // Omit text-end chunk if the flag is set\n if (\n omitTextEndChunk &&\n part.event === ChatEventType.CONVERSATION_MESSAGE_COMPLETED &&\n part.data.type !== 'follow_up'\n ) {\n return false;\n }\n\n if (part.event === 'conversation.message.completed' && evtData.type == 'verbose') {\n return false;\n }\n\n return true;\n }\n\n constructor(omitTextEndChunk: boolean = false) {\n super({\n transform: (\n evt: ServerSentEvent,\n controller: TransformStreamDefaultController<StreamChatData>\n ) => {\n if (!evt) return;\n\n // 解析evt为part对象(原逻辑中的part构建)\n const part = {\n event: evt.type,\n data: JSON.parse(evt.data) || {},\n } as StreamChatData;\n\n // 过滤逻辑:仅传递满足条件的part\n if (this.isVisibleMsgPart(part.data, part, omitTextEndChunk)) {\n controller.enqueue(part);\n }\n },\n });\n }\n}\n","import { LanguageModelV2StreamPart, SharedV2ProviderMetadata } from '@ai-sdk/provider';\nimport { ChatEventType } from '@coze/api';\n\nexport const mcp2llmChunk = (part: any): LanguageModelV2StreamPart | null => {\n const fullData = JSON.stringify(part);\n\n switch (part.event) {\n case ChatEventType.CONVERSATION_CHAT_CREATED:\n return {\n type: 'raw',\n rawValue: part.data,\n };\n break;\n\n case ChatEventType.CONVERSATION_CHAT_IN_PROGRESS:\n return {\n // type: \"text-delta\",\n // id: part.data.conversation_id,\n // delta: part.data.content || \"\",\n // providerMetadata: {\n // raw: { data: fullData },\n // },\n type: 'raw',\n rawValue: part.data,\n };\n break;\n\n case ChatEventType.CONVERSATION_MESSAGE_DELTA:\n const isReasoning = Boolean(part.data.reasoning_content);\n return {\n type: isReasoning ? 'reasoning-delta' : 'text-delta',\n delta: isReasoning ? part.data.reasoning_content : part.data.content,\n id: part.data.conversation_id,\n providerMetadata: {},\n };\n break;\n\n case ChatEventType.CONVERSATION_MESSAGE_COMPLETED:\n if (part.data && part.data.type === 'follow_up') {\n return {\n type: 'raw',\n rawValue: part.data,\n };\n }\n\n if (part.status === 'completed') {\n return {\n type: 'text-end',\n id: part.data.conversation_id,\n // delta: part.data.content || part.data.reasoning_content || \"\",\n providerMetadata: {},\n };\n }\n\n return {\n type: 'raw',\n rawValue: part.data,\n };\n\n break;\n\n case ChatEventType.CONVERSATION_CHAT_COMPLETED:\n // Yield finish event with usage information\n return {\n type: 'finish',\n finishReason: 'stop',\n usage: {\n inputTokens: part.data.usage?.input_count || 0,\n outputTokens: part.data.usage?.output_count || 0,\n totalTokens: part.data.usage?.total_count || 0,\n },\n };\n break;\n\n case ChatEventType.DONE:\n // Stream completed successfully\n return {\n type: 'finish',\n finishReason: 'stop',\n usage: {\n inputTokens: part.data.usage?.input_count || 0,\n outputTokens: part.data.usage?.output_count || 0,\n totalTokens: part.data.usage?.total_count || 0,\n },\n };\n break;\n\n case ChatEventType.ERROR:\n // Handle errors\n console.error('[ERROR]', part.data);\n return {\n type: 'error',\n error: part.data,\n };\n\n default:\n // Handle unknown event types\n console.warn('Unknown event type:', part.event);\n return {\n type: 'error',\n error: 'Unknown event type' + part.event,\n };\n }\n\n return {\n type: 'error',\n error: 'unknown',\n };\n};\n","import { ChatEventType, StreamChatData } from '@coze/api';\nimport { mcp2llmChunk } from '../utils/mcp-to-llm-chunk';\nimport { LanguageModelV2StreamPart } from '@ai-sdk/provider';\n\nexport default class LLMPartTrasnformStream extends TransformStream {\n constructor() {\n super({\n transform: (\n part: StreamChatData | (LanguageModelV2StreamPart & { disableTransform: boolean }),\n controller: TransformStreamDefaultController<LanguageModelV2StreamPart | undefined>\n ) => {\n // Bypass transform if disableTransform flag is set\n const { disableTransform } = part as any;\n if (disableTransform) {\n controller.enqueue(part as any);\n return;\n }\n\n try {\n const chunk = mcp2llmChunk(part as any);\n if (chunk) {\n controller.enqueue(chunk as any);\n }\n } catch (error) {\n console.error('transform coze evt error');\n }\n },\n });\n }\n}\n","import { CreateChatRes } from '@coze/api';\nimport { CozeChatConfig, IGenerateResult } from '../types';\nimport { getCozeChatMsgDetail } from './get-coze-chat-msg-detail';\n\nexport const BuildWarningGenerateResult = (message: string): IGenerateResult => {\n return {\n content: [],\n finishReason: 'error',\n request: {\n body: null,\n },\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n },\n response: {\n body: null,\n },\n warnings: [\n {\n type: 'other',\n message,\n },\n ],\n };\n};\n\nexport const BuildGenerateResultByChatRes = async (\n response: Response,\n chatConfig: CozeChatConfig,\n reqBody?: unknown\n): Promise<IGenerateResult> => {\n if (!response.ok) {\n return Promise.reject(\n BuildWarningGenerateResult(`Coze API error: ${response.status} ${response.statusText}`)\n );\n }\n\n const res = (await response.json()) as CreateChatRes;\n if (res.code !== 0) {\n return Promise.reject(BuildWarningGenerateResult(`Coze API error: ${res.code} ${res.msg}`));\n }\n\n const msgRes = await getCozeChatMsgDetail(res.data.conversation_id, res.data.id, chatConfig);\n if (!msgRes.ok) {\n return Promise.reject(\n BuildWarningGenerateResult(\n `Failed to get message detail: ${msgRes.status} ${msgRes.statusText}`\n )\n );\n }\n const msgDetail = await msgRes.json();\n\n return {\n content: msgDetail.data.message.content,\n finishReason: msgDetail.data.message.status === 'finished' ? 'stop' : 'error',\n request: {\n body: reqBody,\n },\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n },\n response: {\n body: msgDetail,\n },\n warnings: [],\n };\n};\n","import { LanguageModelV2StreamPart } from '@ai-sdk/provider';\nimport { JSONParser } from '@streamparser/json';\nimport { createTextInfoEnqueuer, TextInfoEnqueuer } from '../utils/enqueue-text-info';\nimport { rebuildFieldsJsonStructure } from '@baishuyun/ai-feat-utils';\n\nexport const createFieldsJsonTransformStream = (enableJsonParser: boolean) => {\n let parser: JSONParser;\n let enqueueTextDelta: TextInfoEnqueuer;\n let id: string;\n let isFirstChunk = true;\n // 当 LLM 返回的不是 JSON 而是普通文本时,切换到直通模式\n let passthroughMode = false;\n\n const chunkGuard = (chunk: LanguageModelV2StreamPart): boolean => {\n if (!enableJsonParser || passthroughMode) {\n return false;\n }\n\n if (chunk.type !== 'text-delta' || !('delta' in chunk)) {\n return false;\n }\n\n return true;\n };\n\n const transformer = {\n flush: (controller: TransformStreamDefaultController<any>) => {\n try {\n // parser?.end();\n controller.terminate(); // 信号通知下游可读流已关闭\n } catch (e) {\n controller.error('stop error' + e);\n }\n },\n transform: (\n chunk: LanguageModelV2StreamPart,\n controller: TransformStreamDefaultController<LanguageModelV2StreamPart>\n ) => {\n if (!parser && !passthroughMode) {\n return;\n }\n\n try {\n if (chunkGuard(chunk)) {\n if ('id' in chunk && 'delta' in chunk) {\n id = chunk.id;\n let delta = chunk.delta;\n if (isFirstChunk) {\n delta = delta.replace(/^\\uFEFF/, '');\n isFirstChunk = false;\n }\n parser.write(delta);\n } else {\n console.warn('Unexpected chunk format for JSON parsing:', chunk);\n controller.enqueue(chunk);\n }\n } else {\n controller.enqueue(chunk);\n }\n } catch (e) {\n console.log('write or enqueue error', e);\n controller.error(e);\n }\n },\n start: (controller: TransformStreamDefaultController<any>) => {\n parser = new JSONParser({\n paths: ['$.*'],\n });\n\n enqueueTextDelta = enableJsonParser\n ? createTextInfoEnqueuer(controller)\n : (content: string) => {};\n\n parser.onValue = (parsedInfo: any) => {\n const value = parsedInfo.value;\n\n if (value.widget) {\n value.widget.widgetName = `_widget_${Date.now()}`;\n }\n\n enqueueTextDelta(\n JSON.stringify(value),\n JSON.stringify({\n type: 'mcp-fields-json',\n field: rebuildFieldsJsonStructure(value),\n }),\n id\n );\n };\n\n parser.onError = (err: any) => {\n console.error('JsonWidgetStream: JSON Parsing Error:', err);\n\n // LLM 返回的不是 JSON,切换到直通模式,后续 text-delta 直接透传\n passthroughMode = true;\n };\n\n parser.onEnd = () => {\n enqueueTextDelta(\n ' ',\n JSON.stringify({\n appendConfirm: 'save-fields',\n })\n );\n };\n },\n };\n\n return new TransformStream<LanguageModelV2StreamPart, any>(transformer);\n};\n","import { JSONValue, LanguageModelV2StreamPart } from '@ai-sdk/provider';\nimport { generateId } from '@ai-sdk/provider-utils';\n\nexport type TextInfoEnqueuer = (textInfo: string, metaPayload?: JSONValue, id?: string) => void;\n\nexport const createTextInfoEnqueuer =\n (controller: TransformStreamDefaultController<LanguageModelV2StreamPart>) =>\n (\n textInfo: string,\n metaPayload?: JSONValue,\n id: string = generateId(),\n deltaOnly: boolean = false\n ) => {\n const i = id ?? generateId();\n\n const startPart: LanguageModelV2StreamPart = {\n type: 'text-start',\n id: i,\n };\n\n const deltaPart: LanguageModelV2StreamPart = {\n type: 'text-delta',\n id: i,\n delta: textInfo,\n providerMetadata: metaPayload\n ? {\n raw: { data: metaPayload },\n }\n : undefined,\n };\n\n const endPart: LanguageModelV2StreamPart = {\n type: 'text-end',\n id: i,\n };\n\n if (deltaOnly) {\n controller.enqueue(deltaPart);\n return;\n }\n\n controller.enqueue(startPart);\n controller.enqueue(deltaPart);\n controller.enqueue(endPart);\n };\n","import {\n createTextInfoEnqueuer,\n TextInfoEnqueuer,\n} from \"../utils/enqueue-text-info\";\n\nexport default class SuggestionTransformStream extends TransformStream<\n any,\n any\n> {\n constructor(enable: boolean) {\n let enqueuer: TextInfoEnqueuer;\n super({\n start(controller) {\n enqueuer = createTextInfoEnqueuer(controller);\n },\n transform(chunk, controller) {\n if (\n enable &&\n chunk.type === \"raw\" &&\n chunk.rawValue.type === \"follow_up\" &&\n enqueuer\n ) {\n enqueuer(\n chunk.rawValue.content,\n JSON.stringify({\n type: \"suggestion\",\n }),\n );\n } else {\n controller.enqueue(chunk);\n }\n },\n });\n }\n}\n"],"mappings":"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","names":["ServerSentEventTransformStream","TextDecoderStream","ChatEventType","TextDecoderStream","ServerSentEventTransformStream","generateId"]}
1
+ {"version":3,"sources":["../src/coze-provider.ts","../src/const.ts","../src/coze-language-model.ts","../src/utils/prompt-to-model-msg.ts","../src/utils/accumulate-sse-response.ts","../src/utils/mcp-to-llm-chunk.ts","../src/utils/create-error-stream.ts","../src/evt-sample.ts","../src/stream-trasnformer/llm-chunk-injector-transform-stream.ts","../src/stream-trasnformer/mcp-chunk-filter-transform-stream.ts","../src/stream-trasnformer/llm-part-transform-stream.ts","../src/utils/build-generate-result-by-chat-res.ts","../src/stream-trasnformer/fields-json-transform-stream.ts","../src/utils/enqueue-text-info.ts","../src/stream-trasnformer/suggestion-transform-stream.ts"],"sourcesContent":["import {\n LanguageModelV2,\n LanguageModelV2StreamPart,\n NoSuchModelError,\n ProviderV2,\n} from '@ai-sdk/provider';\n\nimport {\n FetchFunction,\n loadApiKey,\n withoutTrailingSlash,\n withUserAgentSuffix,\n} from '@ai-sdk/provider-utils';\nimport { CozeChatModelId } from './types';\nimport { VERSION } from './const';\nimport { CozeLanguageModel } from './coze-language-model';\n\nexport interface CozeProviderSettings {\n apiKey?: string;\n /**\nBase URL for the API calls.\n*/\n baseURL?: string;\n\n botId: string;\n\n /**\nCustom headers to include in the requests.\n*/\n headers?: Record<string, string>;\n /**\nCustom fetch implementation. You can use it as a middleware to intercept requests,\nor to provide a custom fetch implementation for e.g. testing.\n*/\n fetch?: FetchFunction;\n\n extraStreamTransformers?: (() => TransformStream<LanguageModelV2StreamPart, any>)[];\n}\n\nexport interface CozeProvider extends ProviderV2 {\n (modelId: CozeChatModelId): LanguageModelV2;\n\n languageModel(modelId: CozeChatModelId): LanguageModelV2;\n\n /**\nCreates a DeepSeek chat model for text generation.\n*/\n chat(modelId: CozeChatModelId): LanguageModelV2;\n}\n\nexport function createCoze(\n options: CozeProviderSettings = {\n botId: '',\n }\n): CozeProvider {\n const baseURL = withoutTrailingSlash(options.baseURL);\n\n const agentPartHeader = withUserAgentSuffix(options.headers || {}, `ai-sdk/coze/${VERSION}`);\n const authorizationHeader = `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'COZE_API_KEY',\n description: '',\n })}`;\n\n const getHeaders = () => ({\n ...agentPartHeader,\n Authorization: authorizationHeader,\n 'content-type': 'application/json',\n });\n\n const createLanguageModel = (modelId: CozeChatModelId) => {\n return new CozeLanguageModel(modelId, {\n botId: options.botId,\n provider: `coze.chat`,\n url: ({ path }) => `${baseURL}${path}`,\n headers: getHeaders,\n fetch: options.fetch,\n extraStreamTransformers: options.extraStreamTransformers || [],\n });\n };\n\n const provider = (modelId: CozeChatModelId) => createLanguageModel(modelId);\n\n provider.specificationVersion = 'v3' as const;\n provider.languageModel = createLanguageModel;\n provider.chat = createLanguageModel;\n\n provider.embeddingModel = (modelId: string) => {\n throw new NoSuchModelError({ modelId, modelType: 'textEmbeddingModel' });\n };\n provider.imageModel = (modelId: string) => {\n throw new NoSuchModelError({ modelId, modelType: 'imageModel' });\n };\n provider.textEmbeddingModel = (modelId: string) => {\n throw new NoSuchModelError({ modelId, modelType: 'textEmbeddingModel' });\n };\n\n return provider;\n}\n","export const VERSION = \"0.0.1\";\n","import {\n LanguageModelV2,\n LanguageModelV2CallOptions,\n LanguageModelV2CallWarning,\n LanguageModelV2Prompt,\n LanguageModelV2StreamPart,\n SharedV2Headers,\n} from '@ai-sdk/provider';\nimport { CozeChatConfig, IGenerateResult } from './types';\nimport { ServerSentEventTransformStream } from 'parse-sse';\nimport { TextDecoderStream } from 'stream/web';\nimport { convertPromptToMessages } from './utils/prompt-to-model-msg';\nimport { accumulateSSEResponse } from './utils/accumulate-sse-response';\nimport { createErrorStream } from './utils/create-error-stream';\nimport { LLMChunkInjectorTransformStream } from './stream-trasnformer/llm-chunk-injector-transform-stream';\nimport MCPChunkFilterTransformStream from './stream-trasnformer/mcp-chunk-filter-transform-stream';\nimport LLMPartTrasnformStream from './stream-trasnformer/llm-part-transform-stream';\nimport { BuildWarningGenerateResult } from './utils/build-generate-result-by-chat-res';\nimport { getChatCtxForHuman, getChatCtxForMcp, safeParseJson } from '@baishuyun/ai-feat-utils';\nimport { IChatCtx } from '@baishuyun/types';\n\nexport class CozeLanguageModel implements LanguageModelV2 {\n specificationVersion: 'v2' = 'v2';\n provider: string;\n modelId: string;\n supportedUrls: Record<string, RegExp[]> | PromiseLike<Record<string, RegExp[]>>;\n\n private readonly config: CozeChatConfig;\n\n constructor(modelId: string, config: CozeChatConfig) {\n this.modelId = modelId;\n this.provider = config.provider || 'coze';\n this.supportedUrls = config.supportedUrls?.() || {};\n this.config = config;\n }\n\n async doGenerate(options: LanguageModelV2CallOptions): Promise<IGenerateResult> {\n const messages = convertPromptToMessages(options.prompt);\n const warnings: LanguageModelV2CallWarning[] = [];\n\n const url = this.config.url({ path: '/chat' });\n\n const user_id = options.headers ? options.headers['x-user-id'] : '';\n const user_var = options.headers ? options.headers['x-user-var'] : '';\n\n let customVar;\n if (user_var) {\n try {\n customVar = JSON.parse(user_var);\n } catch (e) {\n console.warn('x-user-var parse error', e);\n }\n }\n\n const body = {\n bot_id: this.config.botId,\n auto_save_history: false,\n user_id: user_id || '7543191937730215936',\n stream: true,\n additional_messages: messages,\n };\n\n if (customVar) {\n (body as any).custom_variables = customVar;\n }\n\n const headers = this.config.headers();\n const abortSignal = options.abortSignal;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: headers,\n credentials: 'include',\n body: JSON.stringify(body),\n signal: abortSignal,\n });\n\n if (!response.ok || !response.body) {\n const rawError = await response.text();\n let errorDetail;\n try {\n errorDetail = JSON.parse(rawError);\n } catch {\n errorDetail = rawError;\n }\n\n const errorMessage =\n typeof errorDetail === 'object' && errorDetail?.msg\n ? errorDetail.msg\n : `Coze API error: ${response.status} ${response.statusText}`;\n\n return BuildWarningGenerateResult(errorMessage);\n }\n\n const { content, finishReason, usage } = await accumulateSSEResponse(response.body);\n\n return {\n content,\n finishReason,\n usage,\n request: { body },\n response: { body: null },\n warnings,\n };\n }\n\n isVisibleMsgPart(evtData: any) {\n if (evtData.type === 'knowledge' && evtData.role === 'assistant') {\n return false;\n }\n\n return true;\n }\n\n async doStream(options: LanguageModelV2CallOptions): Promise<{\n stream: ReadableStream<LanguageModelV2StreamPart>;\n request?: { body?: unknown };\n response?: { headers?: SharedV2Headers };\n }> {\n const conversation_id = options.headers ? options.headers['x-conversation-id'] : '';\n\n // 有 conversation_id 时,服务端会话中已持有完整历史(含中断记录)。\n const prompt = conversation_id ? keepOnlyLastUserMessage(options.prompt) : options.prompt;\n\n const messages = convertPromptToMessages(prompt);\n const queryStr = conversation_id ? `?conversation_id=${conversation_id}` : '';\n\n const url = this.config.url({\n path: `/chat${queryStr}`,\n });\n\n // 团队级别\n const user_id = options.headers ? options.headers['x-user-id'] : '';\n\n // 个人用户\n const operator_id = (options.headers ? options.headers['x-operator-id'] : '') ?? '';\n\n const user_var = options.headers ? options.headers['x-user-var'] : '';\n const user_param = (options.headers ? options.headers['x-user-param'] : '') ?? '';\n\n const params = user_param ? safeParseJson(user_param) : {};\n\n console.log('params 2 workflow', params);\n console.log('conversation id 2 workflow', conversation_id);\n const chatCtx = options?.providerOptions?.chatCtx as unknown as IChatCtx;\n\n console.log('chatCtx', chatCtx);\n\n const userId = operator_id || chatCtx?.user?._id || user_id || Date.now().toString();\n\n const body = {\n bot_id: this.config.botId,\n auto_save_history: Boolean(conversation_id),\n user_id: userId,\n stream: true,\n additional_messages: messages,\n parameters: params,\n custom_variables: user_var ? safeParseJson(user_var) : {},\n extra_params: {\n remark: getChatCtxForHuman(chatCtx),\n mcp_ctx: getChatCtxForMcp(chatCtx),\n },\n };\n\n const headers = this.config.headers();\n\n const abortSignal = options.abortSignal;\n\n console.log('url', url);\n console.log('body', JSON.stringify(body, null, 2));\n console.log('operator_id', operator_id);\n\n const response = await fetch(url, {\n method: 'POST',\n headers: headers,\n credentials: 'include',\n body: JSON.stringify(body),\n signal: abortSignal,\n });\n\n console.log('chat res status', response.status);\n\n if (!response.ok || !response.body) {\n // if (true) {\n const rawError = await response.text();\n let errorDetail;\n try {\n errorDetail = JSON.parse(rawError); // 尝试解析为 JSON\n } catch {\n errorDetail = rawError; // 非 JSON 直接使用\n }\n\n // 创建一个包含错误信息的流,让 UI 层处理\n const errorMessage =\n typeof errorDetail === 'object' && errorDetail?.msg\n ? errorDetail.msg\n : `Coze API error: ${response.status} ${response.statusText}`;\n\n console.error(errorMessage);\n\n return {\n stream: createErrorStream('会话异常,请重试'),\n };\n }\n\n let externalTransformers = (this.config.extraStreamTransformers || []).map((factory) =>\n factory()\n );\n\n /// 不同阶段,可能需要不同的流处理逻辑\n const stage = options.headers ? options.headers['x-user-stage'] : '';\n const isBuildStage = stage === 'build';\n const isFillStage = stage === 'fill';\n\n const result = response.body\n // 将字节流解码为文本流\n .pipeThrough(\n new TextDecoderStream() as ReadableWritablePair<\n string | undefined,\n Uint8Array<ArrayBufferLike>\n >\n )\n // 解析为 SSE 事件流\n .pipeThrough(new ServerSentEventTransformStream())\n .pipeThrough(new MCPChunkFilterTransformStream(isBuildStage || isFillStage))\n // 补充特殊 llm chunk\n .pipeThrough(new LLMChunkInjectorTransformStream())\n // 转换为 LanguageModelV2StreamPart 格式\n .pipeThrough(new LLMPartTrasnformStream());\n\n let finalResult = result;\n\n if (externalTransformers.length > 0) {\n finalResult = externalTransformers.reduce(\n (stream, transformer) => stream.pipeThrough(transformer),\n result // 初始累积值(原始流)\n );\n }\n\n return {\n stream: finalResult as ReadableStream<LanguageModelV2StreamPart>,\n };\n }\n}\n\n/**\n * 只保留最后一条 user 消息(含其内容),用于有 conversation_id 的场景:\n * 服务端会话中已持有完整历史,只需发送当前用户输入。\n */\nfunction keepOnlyLastUserMessage(prompt: LanguageModelV2Prompt): LanguageModelV2Prompt {\n for (let i = prompt.length - 1; i >= 0; i--) {\n if (prompt[i].role === 'user') {\n return [prompt[i]];\n }\n }\n return prompt;\n}\n","import {\n LanguageModelV2FilePart,\n LanguageModelV2Message,\n LanguageModelV2Prompt,\n LanguageModelV2TextPart,\n} from '@ai-sdk/provider';\nimport { RoleType } from '@coze/api';\nimport { Attachment } from '@baishuyun/types/src/chat';\nimport { excel2json } from './excel2json';\n\nconst decoder = new TextDecoder('utf-8');\n\nconst data2csvText = (data: Uint8Array) => {\n return decoder.decode(data);\n};\n\ntype userMsg = {\n role: 'user';\n content: Array<LanguageModelV2TextPart | LanguageModelV2FilePart>;\n};\n\nconst getPartType = (part: LanguageModelV2TextPart | LanguageModelV2FilePart) => {\n if (part.type === 'text') {\n return 'text';\n }\n\n const isImg = part.mediaType?.startsWith('image/');\n if (isImg) {\n return 'image';\n }\n\n const isAudio = part.mediaType?.startsWith('audio/');\n if (isAudio) {\n return 'audio';\n }\n\n return 'file';\n};\n\nconst parseMessageContent = (message: LanguageModelV2Message, isTextOnly?: boolean) => {\n if (isTextOnly) {\n return (message.content as Array<LanguageModelV2TextPart>)\n .map((part: LanguageModelV2TextPart) => part.text)\n .join('\\n');\n }\n\n const result = (message.content as Array<LanguageModelV2TextPart | LanguageModelV2FilePart>).map(\n (part) => {\n const meta = part.providerOptions?.uploadMetadata as Attachment;\n const url = meta?.url;\n\n return {\n type: getPartType(part),\n text: part.type === 'text' ? (part as LanguageModelV2TextPart).text : '',\n file_id: meta?.file_id,\n name: meta?.name,\n // 附件地址:模型需要在「附件上传」标准动作中引用(IAttachment.attachmentUrl)\n url,\n };\n }\n );\n\n return JSON.stringify(result);\n};\n\nconst isTextOnlyMsg = (message: userMsg) => message.content.every((part) => part.type === 'text');\n\nexport const convertPromptToMessages = (messages: LanguageModelV2Prompt) => {\n return messages.map((message) => {\n const isTextOnly = isTextOnlyMsg(message as userMsg);\n switch (message.role) {\n case 'user':\n return {\n role: RoleType.User,\n content: parseMessageContent(message, isTextOnly),\n content_type: isTextOnly ? 'text' : 'object_string',\n };\n break;\n\n case 'assistant':\n return {\n role: RoleType.Assistant,\n content: (message.content as Array<LanguageModelV2TextPart>)\n .map((part: LanguageModelV2TextPart) => (part.type === 'text' ? part.text : ''))\n .join(''),\n content_type: 'text',\n };\n break;\n }\n });\n};\n","import {\n LanguageModelV2Content,\n LanguageModelV2FinishReason,\n LanguageModelV2Usage,\n} from '@ai-sdk/provider';\nimport { ServerSentEventTransformStream } from 'parse-sse';\nimport { TextDecoderStream } from 'stream/web';\nimport { mapCozeUsage } from './mcp-to-llm-chunk';\n\nexport interface AccumulatedSSEResponse {\n content: LanguageModelV2Content[];\n finishReason: LanguageModelV2FinishReason;\n usage: LanguageModelV2Usage;\n}\n\n/**\n * 从字节流中解码 SSE 事件并累积完整响应内容\n */\nexport async function accumulateSSEResponse(\n body: ReadableStream<Uint8Array>\n): Promise<AccumulatedSSEResponse> {\n const sseStream = body\n .pipeThrough(\n new TextDecoderStream() as ReadableWritablePair<\n string | undefined,\n Uint8Array<ArrayBufferLike>\n >\n )\n .pipeThrough(new ServerSentEventTransformStream());\n\n let textContent = '';\n let reasoningContent = '';\n let finishReason: LanguageModelV2FinishReason = 'stop';\n let usage: LanguageModelV2Usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n\n const reader = sseStream.getReader();\n try {\n while (true) {\n const { done, value: evt } = await reader.read();\n if (done) break;\n if (!evt) continue;\n\n let evtData;\n try {\n evtData = JSON.parse(evt.data);\n } catch {\n continue;\n }\n\n const event = evt.type;\n\n if (event === 'conversation.message.delta') {\n if (evtData.reasoning_content) {\n reasoningContent += evtData.reasoning_content;\n } else if (evtData.content) {\n textContent += evtData.content;\n }\n } else if (event === 'conversation.chat.completed' || event === 'done') {\n finishReason = 'stop';\n if (evtData.usage) {\n usage = mapCozeUsage(evtData.usage);\n }\n } else if (event === 'error') {\n finishReason = 'error';\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n const content: LanguageModelV2Content[] = [];\n if (reasoningContent) {\n content.push({ type: 'reasoning', text: reasoningContent });\n }\n if (textContent) {\n content.push({ type: 'text', text: textContent });\n }\n\n return { content, finishReason, usage };\n}\n","import { LanguageModelV2StreamPart, SharedV2ProviderMetadata } from '@ai-sdk/provider';\nimport { ChatEventType } from '@coze/api';\n\n/**\n * 上游 usage 字段兼容:官方 Coze v3 的 completed 事件为\n * token_count/input_count/output_count(无 total_count),\n * 总额按 total_count → token_count → input+output 的顺序取\n */\nexport const mapCozeUsage = (usage: any) => {\n const inputTokens = usage?.input_count || 0;\n const outputTokens = usage?.output_count || 0;\n const totalTokens = usage?.total_count ?? usage?.token_count ?? inputTokens + outputTokens;\n return { inputTokens, outputTokens, totalTokens };\n};\n\n/**\n * 从消息 meta_data 提取 token 用量。上游会把本轮模型用量写入 answer 消息\n * (含 workflow 用量消息)的 meta_data:token / input_tokens / output_tokens,\n * 是 chat.completed 事件不带 usage 时(旧版上游)的兜底来源\n */\nexport const extractUsageFromMsgMeta = (meta: any) => {\n if (!meta) return null;\n const totalTokens = Number(meta.token);\n if (!totalTokens) return null;\n return {\n inputTokens: Number(meta.input_tokens) || 0,\n outputTokens: Number(meta.output_tokens) || 0,\n totalTokens,\n };\n};\n\nexport const mcp2llmChunk = (part: any): LanguageModelV2StreamPart | null => {\n const fullData = JSON.stringify(part);\n\n switch (part.event) {\n case ChatEventType.CONVERSATION_CHAT_CREATED:\n return {\n type: 'raw',\n rawValue: part.data,\n };\n break;\n\n case ChatEventType.CONVERSATION_CHAT_IN_PROGRESS:\n return {\n // type: \"text-delta\",\n // id: part.data.conversation_id,\n // delta: part.data.content || \"\",\n // providerMetadata: {\n // raw: { data: fullData },\n // },\n type: 'raw',\n rawValue: part.data,\n };\n break;\n\n case ChatEventType.CONVERSATION_MESSAGE_DELTA:\n const isReasoning = Boolean(part.data.reasoning_content);\n return {\n type: isReasoning ? 'reasoning-delta' : 'text-delta',\n delta: isReasoning ? part.data.reasoning_content : part.data.content,\n id: part.data.conversation_id,\n providerMetadata: {},\n };\n break;\n\n case ChatEventType.CONVERSATION_MESSAGE_COMPLETED:\n if (part.data && part.data.type === 'follow_up') {\n return {\n type: 'raw',\n rawValue: part.data,\n };\n }\n\n if (part.status === 'completed') {\n return {\n type: 'text-end',\n id: part.data.conversation_id,\n // delta: part.data.content || part.data.reasoning_content || \"\",\n providerMetadata: {},\n };\n }\n\n return {\n type: 'raw',\n rawValue: part.data,\n };\n\n break;\n\n case ChatEventType.CONVERSATION_CHAT_COMPLETED:\n // Yield finish event with usage information\n return {\n type: 'finish',\n finishReason: 'stop',\n usage: mapCozeUsage(part.data.usage),\n };\n break;\n\n case ChatEventType.DONE:\n // Stream completed successfully\n return {\n type: 'finish',\n finishReason: 'stop',\n usage: mapCozeUsage(part.data.usage),\n };\n break;\n\n case ChatEventType.ERROR:\n // Handle errors\n console.error('[ERROR]', part.data);\n return {\n type: 'error',\n error: part.data,\n };\n\n default:\n // Handle unknown event types\n console.warn('Unknown event type:', part.event);\n return {\n type: 'error',\n error: 'Unknown event type' + part.event,\n };\n }\n\n return {\n type: 'error',\n error: 'unknown',\n };\n};\n","import { LanguageModelV2StreamPart } from '@ai-sdk/provider';\nimport { generateId } from '@ai-sdk/provider-utils';\n\n/**\n * 创建一个包含错误信息的流\n * @param error 错误信息\n * @returns ReadableStream<LanguageModelV2StreamPart>\n */\nexport const createErrorStream = (error: string): ReadableStream<LanguageModelV2StreamPart> => {\n return new ReadableStream<LanguageModelV2StreamPart>({\n start(controller) {\n const id = generateId();\n controller.enqueue({\n id,\n type: 'text-start',\n });\n controller.enqueue({\n id,\n type: 'text-delta',\n providerMetadata: {\n raw: { data: { type: 'agent-error', error } },\n },\n delta: error,\n });\n controller.enqueue({\n type: 'text-end',\n id,\n });\n controller.close();\n },\n });\n};\n","/**\n * 事件数据取样,某些流 chunk 处理,需要用到前后的 chunk 信息,因此设计一个类缓存相邻 chunk,用于处理依据\n */\nexport class EvtSample {\n private _evtSampleMap: Map<string, any> = new Map();\n private _key1: string = \"1\";\n private _key2: string = \"2\";\n private _maxSample = 2;\n\n public addEventSample(evt: any) {\n if (this._evtSampleMap.size >= this._maxSample) {\n const evt2 = this._evtSampleMap.get(this._key2);\n this._evtSampleMap.set(this._key1, evt2);\n this._evtSampleMap.set(this._key2, evt);\n return;\n }\n\n this._evtSampleMap.set((this._evtSampleMap.size + 1).toString(), evt);\n }\n\n public getFirstSample() {\n return this._evtSampleMap.get(this._key1);\n }\n\n public getSecondSample() {\n return this._evtSampleMap.get(this._key2);\n }\n}\n","import { LanguageModelV2StreamPart } from '@ai-sdk/provider';\nimport { StreamChatData } from '@coze/api';\nimport { EvtSample } from '../evt-sample';\n\n/**\n * 补充特殊的 llm chunk, reasoning-end, text-start\n */\nexport class LLMChunkInjectorTransformStream extends TransformStream<\n StreamChatData,\n | StreamChatData\n | (LanguageModelV2StreamPart & {\n disableTransform: boolean;\n })\n> {\n private eventSampleMap = new EvtSample();\n\n constructor() {\n super({\n transform: (\n part: StreamChatData,\n controller: TransformStreamDefaultController<\n StreamChatData | (LanguageModelV2StreamPart & { disableTransform: boolean })\n >\n ) => {\n // 添加事件样本(原逻辑中的addEventSample)\n this.eventSampleMap.addEventSample(part);\n\n // 处理sample1/sample2特殊判断逻辑\n const sample1 = this.eventSampleMap.getFirstSample();\n const sample2 = this.eventSampleMap.getSecondSample();\n\n // handle reasoning end\n if (\n sample1 &&\n sample2 &&\n sample1.data.reasoning_content &&\n !sample2.data.reasoning_content\n ) {\n controller.enqueue({\n disableTransform: true,\n type: 'reasoning-end',\n id: sample1.data.conversation_id,\n });\n }\n\n // handle text-start\n if (sample1 && sample2 && !sample1.data.content && sample2.data.content) {\n controller.enqueue({\n disableTransform: true,\n type: 'text-start',\n id: sample2.data.conversation_id,\n });\n }\n\n // 传递part到下一个转换流\n controller.enqueue(part);\n },\n });\n }\n}\n","import { ChatEventType, StreamChatData } from '@coze/api';\nimport { ServerSentEvent } from 'parse-sse';\n\nexport default class MCPChunkFilterTransformStream extends TransformStream {\n isVisibleMsgPart(evtData: any, part: any, omitTextEndChunk?: boolean) {\n if (evtData.type === 'knowledge' && evtData.role === 'assistant') {\n return false;\n }\n\n // Omit text-end chunk if the flag is set\n if (\n omitTextEndChunk &&\n part.event === ChatEventType.CONVERSATION_MESSAGE_COMPLETED &&\n part.data.type !== 'follow_up'\n ) {\n return false;\n }\n\n if (part.event === 'conversation.message.completed' && evtData.type == 'verbose') {\n return false;\n }\n\n return true;\n }\n\n constructor(omitTextEndChunk: boolean = false) {\n super({\n transform: (\n evt: ServerSentEvent,\n controller: TransformStreamDefaultController<StreamChatData>\n ) => {\n if (!evt) return;\n\n // 解析evt为part对象(原逻辑中的part构建)\n const part = {\n event: evt.type,\n data: JSON.parse(evt.data) || {},\n } as StreamChatData;\n\n // 过滤逻辑:仅传递满足条件的part\n if (this.isVisibleMsgPart(part.data, part, omitTextEndChunk)) {\n controller.enqueue(part);\n }\n },\n });\n }\n}\n","import { ChatEventType, StreamChatData } from '@coze/api';\nimport { extractUsageFromMsgMeta, mcp2llmChunk } from '../utils/mcp-to-llm-chunk';\nimport { LanguageModelV2StreamPart, LanguageModelV2Usage } from '@ai-sdk/provider';\n\nexport default class LLMPartTrasnformStream extends TransformStream {\n /**\n * 本轮最近一条消息 meta_data 中携带的 token 用量。\n * 旧版上游不在 conversation.chat.completed 事件中携带 usage,\n * 发 finish chunk 时若事件 usage 缺失则用此兜底(事件已带则不覆盖)\n */\n private lastMsgUsage: LanguageModelV2Usage | null = null;\n\n constructor() {\n super({\n transform: (\n part: StreamChatData | (LanguageModelV2StreamPart & { disableTransform: boolean }),\n controller: TransformStreamDefaultController<LanguageModelV2StreamPart | undefined>\n ) => {\n // Bypass transform if disableTransform flag is set\n const { disableTransform } = part as any;\n if (disableTransform) {\n controller.enqueue(part as any);\n return;\n }\n\n try {\n if ((part as any).event === ChatEventType.CONVERSATION_MESSAGE_COMPLETED) {\n const usage = extractUsageFromMsgMeta((part as any).data?.meta_data);\n if (usage) {\n this.lastMsgUsage = usage;\n }\n }\n\n const chunk = mcp2llmChunk(part as any);\n if (chunk) {\n if (chunk.type === 'finish' && !chunk.usage?.totalTokens && this.lastMsgUsage) {\n chunk.usage = this.lastMsgUsage;\n }\n controller.enqueue(chunk as any);\n }\n } catch (error) {\n console.error('transform coze evt error');\n }\n },\n });\n }\n}\n","import { CreateChatRes } from '@coze/api';\nimport { CozeChatConfig, IGenerateResult } from '../types';\nimport { getCozeChatMsgDetail } from './get-coze-chat-msg-detail';\n\nexport const BuildWarningGenerateResult = (message: string): IGenerateResult => {\n return {\n content: [],\n finishReason: 'error',\n request: {\n body: null,\n },\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n },\n response: {\n body: null,\n },\n warnings: [\n {\n type: 'other',\n message,\n },\n ],\n };\n};\n\nexport const BuildGenerateResultByChatRes = async (\n response: Response,\n chatConfig: CozeChatConfig,\n reqBody?: unknown\n): Promise<IGenerateResult> => {\n if (!response.ok) {\n return Promise.reject(\n BuildWarningGenerateResult(`Coze API error: ${response.status} ${response.statusText}`)\n );\n }\n\n const res = (await response.json()) as CreateChatRes;\n if (res.code !== 0) {\n return Promise.reject(BuildWarningGenerateResult(`Coze API error: ${res.code} ${res.msg}`));\n }\n\n const msgRes = await getCozeChatMsgDetail(res.data.conversation_id, res.data.id, chatConfig);\n if (!msgRes.ok) {\n return Promise.reject(\n BuildWarningGenerateResult(\n `Failed to get message detail: ${msgRes.status} ${msgRes.statusText}`\n )\n );\n }\n const msgDetail = await msgRes.json();\n\n return {\n content: msgDetail.data.message.content,\n finishReason: msgDetail.data.message.status === 'finished' ? 'stop' : 'error',\n request: {\n body: reqBody,\n },\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n },\n response: {\n body: msgDetail,\n },\n warnings: [],\n };\n};\n","import { LanguageModelV2StreamPart } from '@ai-sdk/provider';\nimport { JSONParser } from '@streamparser/json';\nimport { createTextInfoEnqueuer, TextInfoEnqueuer } from '../utils/enqueue-text-info';\nimport { rebuildFieldsJsonStructure } from '@baishuyun/ai-feat-utils';\n\nexport const createFieldsJsonTransformStream = (enableJsonParser: boolean) => {\n let parser: JSONParser;\n let enqueueTextDelta: TextInfoEnqueuer;\n let id: string;\n let isFirstChunk = true;\n // 当 LLM 返回的不是 JSON 而是普通文本时,切换到直通模式\n let passthroughMode = false;\n\n const chunkGuard = (chunk: LanguageModelV2StreamPart): boolean => {\n if (!enableJsonParser || passthroughMode) {\n return false;\n }\n\n if (chunk.type !== 'text-delta' || !('delta' in chunk)) {\n return false;\n }\n\n return true;\n };\n\n const transformer = {\n flush: (controller: TransformStreamDefaultController<any>) => {\n try {\n // parser?.end();\n controller.terminate(); // 信号通知下游可读流已关闭\n } catch (e) {\n controller.error('stop error' + e);\n }\n },\n transform: (\n chunk: LanguageModelV2StreamPart,\n controller: TransformStreamDefaultController<LanguageModelV2StreamPart>\n ) => {\n if (!parser && !passthroughMode) {\n return;\n }\n\n try {\n if (chunkGuard(chunk)) {\n if ('id' in chunk && 'delta' in chunk) {\n id = chunk.id;\n let delta = chunk.delta;\n if (isFirstChunk) {\n delta = delta.replace(/^\\uFEFF/, '');\n isFirstChunk = false;\n }\n parser.write(delta);\n } else {\n console.warn('Unexpected chunk format for JSON parsing:', chunk);\n controller.enqueue(chunk);\n }\n } else {\n controller.enqueue(chunk);\n }\n } catch (e) {\n console.log('write or enqueue error', e);\n controller.error(e);\n }\n },\n start: (controller: TransformStreamDefaultController<any>) => {\n parser = new JSONParser({\n paths: ['$.*'],\n });\n\n enqueueTextDelta = enableJsonParser\n ? createTextInfoEnqueuer(controller)\n : (content: string) => {};\n\n parser.onValue = (parsedInfo: any) => {\n const value = parsedInfo.value;\n\n if (value.widget) {\n value.widget.widgetName = `_widget_${Date.now()}`;\n }\n\n enqueueTextDelta(\n JSON.stringify(value),\n JSON.stringify({\n type: 'mcp-fields-json',\n field: rebuildFieldsJsonStructure(value),\n }),\n id\n );\n };\n\n parser.onError = (err: any) => {\n console.error('JsonWidgetStream: JSON Parsing Error:', err);\n\n // LLM 返回的不是 JSON,切换到直通模式,后续 text-delta 直接透传\n passthroughMode = true;\n };\n\n parser.onEnd = () => {\n enqueueTextDelta(\n ' ',\n JSON.stringify({\n appendConfirm: 'save-fields',\n })\n );\n };\n },\n };\n\n return new TransformStream<LanguageModelV2StreamPart, any>(transformer);\n};\n","import { JSONValue, LanguageModelV2StreamPart } from '@ai-sdk/provider';\nimport { generateId } from '@ai-sdk/provider-utils';\n\nexport type TextInfoEnqueuer = (textInfo: string, metaPayload?: JSONValue, id?: string) => void;\n\nexport const createTextInfoEnqueuer =\n (controller: TransformStreamDefaultController<LanguageModelV2StreamPart>) =>\n (\n textInfo: string,\n metaPayload?: JSONValue,\n id: string = generateId(),\n deltaOnly: boolean = false\n ) => {\n const i = id ?? generateId();\n\n const startPart: LanguageModelV2StreamPart = {\n type: 'text-start',\n id: i,\n };\n\n const deltaPart: LanguageModelV2StreamPart = {\n type: 'text-delta',\n id: i,\n delta: textInfo,\n providerMetadata: metaPayload\n ? {\n raw: { data: metaPayload },\n }\n : undefined,\n };\n\n const endPart: LanguageModelV2StreamPart = {\n type: 'text-end',\n id: i,\n };\n\n if (deltaOnly) {\n controller.enqueue(deltaPart);\n return;\n }\n\n controller.enqueue(startPart);\n controller.enqueue(deltaPart);\n controller.enqueue(endPart);\n };\n","import {\n createTextInfoEnqueuer,\n TextInfoEnqueuer,\n} from \"../utils/enqueue-text-info\";\n\nexport default class SuggestionTransformStream extends TransformStream<\n any,\n any\n> {\n constructor(enable: boolean) {\n let enqueuer: TextInfoEnqueuer;\n super({\n start(controller) {\n enqueuer = createTextInfoEnqueuer(controller);\n },\n transform(chunk, controller) {\n if (\n enable &&\n chunk.type === \"raw\" &&\n chunk.rawValue.type === \"follow_up\" &&\n enqueuer\n ) {\n enqueuer(\n chunk.rawValue.content,\n JSON.stringify({\n type: \"suggestion\",\n }),\n );\n } else {\n controller.enqueue(chunk);\n }\n },\n });\n }\n}\n"],"mappings":"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","names":["ServerSentEventTransformStream","TextDecoderStream","ChatEventType","ChatEventType","ChatEventType","TextDecoderStream","ServerSentEventTransformStream","generateId"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@baishuyun/coze-provider",
3
- "version": "2.0.45",
3
+ "version": "2.0.47",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org/"
@@ -23,7 +23,7 @@
23
23
  "parse-sse": "^0.1.0",
24
24
  "stream-json": "^1.9.1",
25
25
  "xlsx": "^0.18.5",
26
- "@baishuyun/ai-feat-utils": "2.0.45"
26
+ "@baishuyun/ai-feat-utils": "2.0.47"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@changesets/cli": "^2.29.8",
@@ -33,7 +33,7 @@
33
33
  "typescript": "5.8.3",
34
34
  "vite": "^5.1.4",
35
35
  "vite-plugin-dts": "^4.5.4",
36
- "@baishuyun/types": "3.0.42",
36
+ "@baishuyun/types": "3.0.43",
37
37
  "@baishuyun/typescript-config": "2.0.9"
38
38
  },
39
39
  "peerDependencies": {
@@ -44,7 +44,7 @@
44
44
  "license": "ISC",
45
45
  "scripts": {
46
46
  "build": "tsup --tsconfig tsconfig.json --clean",
47
- "dev": "pnpm clean && tsup --watch",
47
+ "dev": "tsup --watch",
48
48
  "clean": "rimraf --glob dist *.tsbuildinfo",
49
49
  "test": "echo \"Error: no test specified\" && exit 1"
50
50
  }
@@ -129,8 +129,12 @@ export class CozeLanguageModel implements LanguageModelV2 {
129
129
  path: `/chat${queryStr}`,
130
130
  });
131
131
 
132
+ // 团队级别
132
133
  const user_id = options.headers ? options.headers['x-user-id'] : '';
133
134
 
135
+ // 个人用户
136
+ const operator_id = (options.headers ? options.headers['x-operator-id'] : '') ?? '';
137
+
134
138
  const user_var = options.headers ? options.headers['x-user-var'] : '';
135
139
  const user_param = (options.headers ? options.headers['x-user-param'] : '') ?? '';
136
140
 
@@ -140,7 +144,9 @@ export class CozeLanguageModel implements LanguageModelV2 {
140
144
  console.log('conversation id 2 workflow', conversation_id);
141
145
  const chatCtx = options?.providerOptions?.chatCtx as unknown as IChatCtx;
142
146
 
143
- const userId = chatCtx?.user?._id || user_id || Date.now().toString();
147
+ console.log('chatCtx', chatCtx);
148
+
149
+ const userId = operator_id || chatCtx?.user?._id || user_id || Date.now().toString();
144
150
 
145
151
  const body = {
146
152
  bot_id: this.config.botId,
@@ -162,6 +168,7 @@ export class CozeLanguageModel implements LanguageModelV2 {
162
168
 
163
169
  console.log('url', url);
164
170
  console.log('body', JSON.stringify(body, null, 2));
171
+ console.log('operator_id', operator_id);
165
172
 
166
173
  const response = await fetch(url, {
167
174
  method: 'POST',
@@ -171,6 +178,8 @@ export class CozeLanguageModel implements LanguageModelV2 {
171
178
  signal: abortSignal,
172
179
  });
173
180
 
181
+ console.log('chat res status', response.status);
182
+
174
183
  if (!response.ok || !response.body) {
175
184
  // if (true) {
176
185
  const rawError = await response.text();
@@ -1,8 +1,15 @@
1
1
  import { ChatEventType, StreamChatData } from '@coze/api';
2
- import { mcp2llmChunk } from '../utils/mcp-to-llm-chunk';
3
- import { LanguageModelV2StreamPart } from '@ai-sdk/provider';
2
+ import { extractUsageFromMsgMeta, mcp2llmChunk } from '../utils/mcp-to-llm-chunk';
3
+ import { LanguageModelV2StreamPart, LanguageModelV2Usage } from '@ai-sdk/provider';
4
4
 
5
5
  export default class LLMPartTrasnformStream extends TransformStream {
6
+ /**
7
+ * 本轮最近一条消息 meta_data 中携带的 token 用量。
8
+ * 旧版上游不在 conversation.chat.completed 事件中携带 usage,
9
+ * 发 finish chunk 时若事件 usage 缺失则用此兜底(事件已带则不覆盖)
10
+ */
11
+ private lastMsgUsage: LanguageModelV2Usage | null = null;
12
+
6
13
  constructor() {
7
14
  super({
8
15
  transform: (
@@ -17,8 +24,18 @@ export default class LLMPartTrasnformStream extends TransformStream {
17
24
  }
18
25
 
19
26
  try {
27
+ if ((part as any).event === ChatEventType.CONVERSATION_MESSAGE_COMPLETED) {
28
+ const usage = extractUsageFromMsgMeta((part as any).data?.meta_data);
29
+ if (usage) {
30
+ this.lastMsgUsage = usage;
31
+ }
32
+ }
33
+
20
34
  const chunk = mcp2llmChunk(part as any);
21
35
  if (chunk) {
36
+ if (chunk.type === 'finish' && !chunk.usage?.totalTokens && this.lastMsgUsage) {
37
+ chunk.usage = this.lastMsgUsage;
38
+ }
22
39
  controller.enqueue(chunk as any);
23
40
  }
24
41
  } catch (error) {