@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.
@@ -5,6 +5,7 @@ import {
5
5
  } from '@ai-sdk/provider';
6
6
  import { ServerSentEventTransformStream } from 'parse-sse';
7
7
  import { TextDecoderStream } from 'stream/web';
8
+ import { mapCozeUsage } from './mcp-to-llm-chunk';
8
9
 
9
10
  export interface AccumulatedSSEResponse {
10
11
  content: LanguageModelV2Content[];
@@ -57,11 +58,7 @@ export async function accumulateSSEResponse(
57
58
  } else if (event === 'conversation.chat.completed' || event === 'done') {
58
59
  finishReason = 'stop';
59
60
  if (evtData.usage) {
60
- usage = {
61
- inputTokens: evtData.usage.input_count || 0,
62
- outputTokens: evtData.usage.output_count || 0,
63
- totalTokens: evtData.usage.total_count || 0,
64
- };
61
+ usage = mapCozeUsage(evtData.usage);
65
62
  }
66
63
  } else if (event === 'error') {
67
64
  finishReason = 'error';
@@ -1,6 +1,34 @@
1
1
  import { LanguageModelV2StreamPart, SharedV2ProviderMetadata } from '@ai-sdk/provider';
2
2
  import { ChatEventType } from '@coze/api';
3
3
 
4
+ /**
5
+ * 上游 usage 字段兼容:官方 Coze v3 的 completed 事件为
6
+ * token_count/input_count/output_count(无 total_count),
7
+ * 总额按 total_count → token_count → input+output 的顺序取
8
+ */
9
+ export const mapCozeUsage = (usage: any) => {
10
+ const inputTokens = usage?.input_count || 0;
11
+ const outputTokens = usage?.output_count || 0;
12
+ const totalTokens = usage?.total_count ?? usage?.token_count ?? inputTokens + outputTokens;
13
+ return { inputTokens, outputTokens, totalTokens };
14
+ };
15
+
16
+ /**
17
+ * 从消息 meta_data 提取 token 用量。上游会把本轮模型用量写入 answer 消息
18
+ * (含 workflow 用量消息)的 meta_data:token / input_tokens / output_tokens,
19
+ * 是 chat.completed 事件不带 usage 时(旧版上游)的兜底来源
20
+ */
21
+ export const extractUsageFromMsgMeta = (meta: any) => {
22
+ if (!meta) return null;
23
+ const totalTokens = Number(meta.token);
24
+ if (!totalTokens) return null;
25
+ return {
26
+ inputTokens: Number(meta.input_tokens) || 0,
27
+ outputTokens: Number(meta.output_tokens) || 0,
28
+ totalTokens,
29
+ };
30
+ };
31
+
4
32
  export const mcp2llmChunk = (part: any): LanguageModelV2StreamPart | null => {
5
33
  const fullData = JSON.stringify(part);
6
34
 
@@ -64,11 +92,7 @@ export const mcp2llmChunk = (part: any): LanguageModelV2StreamPart | null => {
64
92
  return {
65
93
  type: 'finish',
66
94
  finishReason: 'stop',
67
- usage: {
68
- inputTokens: part.data.usage?.input_count || 0,
69
- outputTokens: part.data.usage?.output_count || 0,
70
- totalTokens: part.data.usage?.total_count || 0,
71
- },
95
+ usage: mapCozeUsage(part.data.usage),
72
96
  };
73
97
  break;
74
98
 
@@ -77,11 +101,7 @@ export const mcp2llmChunk = (part: any): LanguageModelV2StreamPart | null => {
77
101
  return {
78
102
  type: 'finish',
79
103
  finishReason: 'stop',
80
- usage: {
81
- inputTokens: part.data.usage?.input_count || 0,
82
- outputTokens: part.data.usage?.output_count || 0,
83
- totalTokens: part.data.usage?.total_count || 0,
84
- },
104
+ usage: mapCozeUsage(part.data.usage),
85
105
  };
86
106
  break;
87
107