@agentscope-ai/agentscope 0.0.2
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/agent/index.d.mts +234 -0
- package/dist/agent/index.d.ts +234 -0
- package/dist/agent/index.js +1412 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/index.mjs +1375 -0
- package/dist/agent/index.mjs.map +1 -0
- package/dist/base-BOx3UzOl.d.mts +41 -0
- package/dist/base-BoIps2RL.d.ts +41 -0
- package/dist/base-C7jwyH4Z.d.mts +52 -0
- package/dist/base-Cwi4bjze.d.ts +127 -0
- package/dist/base-DYlBMCy_.d.mts +127 -0
- package/dist/base-NX-knWOv.d.ts +52 -0
- package/dist/block-VsnHrllL.d.mts +48 -0
- package/dist/block-VsnHrllL.d.ts +48 -0
- package/dist/event/index.d.mts +181 -0
- package/dist/event/index.d.ts +181 -0
- package/dist/event/index.js +58 -0
- package/dist/event/index.js.map +1 -0
- package/dist/event/index.mjs +33 -0
- package/dist/event/index.mjs.map +1 -0
- package/dist/formatter/index.d.mts +187 -0
- package/dist/formatter/index.d.ts +187 -0
- package/dist/formatter/index.js +647 -0
- package/dist/formatter/index.js.map +1 -0
- package/dist/formatter/index.mjs +616 -0
- package/dist/formatter/index.mjs.map +1 -0
- package/dist/index-BTJDlKvQ.d.mts +195 -0
- package/dist/index-BcatlwXQ.d.ts +195 -0
- package/dist/index-CAxQAkiP.d.mts +21 -0
- package/dist/index-CAxQAkiP.d.ts +21 -0
- package/dist/mcp/index.d.mts +9 -0
- package/dist/mcp/index.d.ts +9 -0
- package/dist/mcp/index.js +432 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/index.mjs +408 -0
- package/dist/mcp/index.mjs.map +1 -0
- package/dist/message/index.d.mts +10 -0
- package/dist/message/index.d.ts +10 -0
- package/dist/message/index.js +67 -0
- package/dist/message/index.js.map +1 -0
- package/dist/message/index.mjs +37 -0
- package/dist/message/index.mjs.map +1 -0
- package/dist/message-CkN21KaY.d.mts +99 -0
- package/dist/message-CzLeTlua.d.ts +99 -0
- package/dist/model/index.d.mts +377 -0
- package/dist/model/index.d.ts +377 -0
- package/dist/model/index.js +1880 -0
- package/dist/model/index.js.map +1 -0
- package/dist/model/index.mjs +1849 -0
- package/dist/model/index.mjs.map +1 -0
- package/dist/storage/index.d.mts +68 -0
- package/dist/storage/index.d.ts +68 -0
- package/dist/storage/index.js +250 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/index.mjs +212 -0
- package/dist/storage/index.mjs.map +1 -0
- package/dist/tool/index.d.mts +311 -0
- package/dist/tool/index.d.ts +311 -0
- package/dist/tool/index.js +1494 -0
- package/dist/tool/index.js.map +1 -0
- package/dist/tool/index.mjs +1447 -0
- package/dist/tool/index.mjs.map +1 -0
- package/dist/toolkit-CEpulFi0.d.ts +99 -0
- package/dist/toolkit-CGEZSZPa.d.mts +99 -0
- package/jest.config.js +11 -0
- package/package.json +92 -0
- package/src/_utils/common.ts +104 -0
- package/src/_utils/index.ts +1 -0
- package/src/agent/agent-base.ts +0 -0
- package/src/agent/agent.test.ts +1028 -0
- package/src/agent/agent.ts +1032 -0
- package/src/agent/index.ts +2 -0
- package/src/agent/interfaces.ts +23 -0
- package/src/agent/test-compression.ts +72 -0
- package/src/event/index.ts +250 -0
- package/src/formatter/base.ts +133 -0
- package/src/formatter/dashscope-chat-formatter.test.ts +372 -0
- package/src/formatter/dashscope-chat-formatter.ts +163 -0
- package/src/formatter/deepseek-chat-formatter.ts +130 -0
- package/src/formatter/index.ts +5 -0
- package/src/formatter/ollama-chat-formatter.ts +67 -0
- package/src/formatter/openai-chat-formatter.test.ts +263 -0
- package/src/formatter/openai-chat-formatter.ts +301 -0
- package/src/formatter/openai.md +767 -0
- package/src/mcp/base.ts +114 -0
- package/src/mcp/http.test.ts +303 -0
- package/src/mcp/http.ts +224 -0
- package/src/mcp/index.ts +2 -0
- package/src/mcp/stdio.test.ts +91 -0
- package/src/mcp/stdio.ts +119 -0
- package/src/message/block.ts +60 -0
- package/src/message/enums.ts +4 -0
- package/src/message/index.ts +12 -0
- package/src/message/message.test.ts +80 -0
- package/src/message/message.ts +131 -0
- package/src/model/base.ts +226 -0
- package/src/model/dashscope-model.test.ts +335 -0
- package/src/model/dashscope-model.ts +441 -0
- package/src/model/deepseek-model.test.ts +279 -0
- package/src/model/deepseek-model.ts +401 -0
- package/src/model/index.ts +7 -0
- package/src/model/ollama-model.test.ts +307 -0
- package/src/model/ollama-model.ts +356 -0
- package/src/model/openai-model.ts +327 -0
- package/src/model/response.ts +22 -0
- package/src/model/usage.ts +12 -0
- package/src/storage/base.ts +52 -0
- package/src/storage/file-system.test.ts +587 -0
- package/src/storage/file-system.ts +269 -0
- package/src/storage/index.ts +2 -0
- package/src/tool/base.ts +23 -0
- package/src/tool/bash.test.ts +174 -0
- package/src/tool/bash.ts +152 -0
- package/src/tool/edit.test.ts +83 -0
- package/src/tool/edit.ts +95 -0
- package/src/tool/glob.test.ts +63 -0
- package/src/tool/glob.ts +166 -0
- package/src/tool/grep.test.ts +74 -0
- package/src/tool/grep.ts +256 -0
- package/src/tool/index.ts +10 -0
- package/src/tool/read.test.ts +77 -0
- package/src/tool/read.ts +117 -0
- package/src/tool/response.ts +82 -0
- package/src/tool/task.test.ts +299 -0
- package/src/tool/task.ts +399 -0
- package/src/tool/toolkit.test.ts +636 -0
- package/src/tool/toolkit.ts +601 -0
- package/src/tool/write.test.ts +52 -0
- package/src/tool/write.ts +57 -0
- package/src/type/index.ts +52 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.cjs.json +11 -0
- package/tsconfig.esm.json +10 -0
- package/tsconfig.json +14 -0
- package/tsup.config.ts +20 -0
- package/typedoc.json +52 -0
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
import { ChatModelBase, ChatModelOptions, ChatModelRequestOptions } from './base';
|
|
2
|
+
import { ChatResponse } from './response';
|
|
3
|
+
import { DataBlock, TextBlock, ThinkingBlock, ToolCallBlock } from '../message';
|
|
4
|
+
import { ToolChoice, ToolSchema } from '../type';
|
|
5
|
+
import { ChatUsage } from './usage';
|
|
6
|
+
import { _parseStreamedResponse } from '../_utils';
|
|
7
|
+
import { DashScopeChatFormatter } from '../formatter';
|
|
8
|
+
|
|
9
|
+
interface _DashScopeStreamChunk {
|
|
10
|
+
output?: {
|
|
11
|
+
choices: {
|
|
12
|
+
message?: {
|
|
13
|
+
content?: string | { text: string }[];
|
|
14
|
+
reasoning_content?: string;
|
|
15
|
+
tool_calls?: {
|
|
16
|
+
index: number;
|
|
17
|
+
id?: string;
|
|
18
|
+
function?: {
|
|
19
|
+
name?: string;
|
|
20
|
+
arguments?: string;
|
|
21
|
+
};
|
|
22
|
+
}[];
|
|
23
|
+
};
|
|
24
|
+
}[];
|
|
25
|
+
};
|
|
26
|
+
usage?: {
|
|
27
|
+
input_tokens?: number;
|
|
28
|
+
output_tokens?: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface DashScopeThinkingConfig {
|
|
33
|
+
/**
|
|
34
|
+
* Whether to enable thinking or not.
|
|
35
|
+
*/
|
|
36
|
+
enableThinking: boolean;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Maximum tokens for reasoning (optional).
|
|
40
|
+
*/
|
|
41
|
+
thinkingBudget?: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface DashScopeChatModelOptions extends ChatModelOptions {
|
|
45
|
+
/**
|
|
46
|
+
* The API key for authenticating with DashScope API.
|
|
47
|
+
*/
|
|
48
|
+
apiKey: string;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Thinking configuration for DashScope models.
|
|
52
|
+
*/
|
|
53
|
+
thinkingConfig?: DashScopeThinkingConfig;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* (Deprecated) Use thinkingConfig instead.
|
|
57
|
+
* Whether to enable the "thinking" feature in the model.
|
|
58
|
+
*/
|
|
59
|
+
enableThinking?: boolean;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Whether the model is multimodal or not, this will decide the default API endpoint.
|
|
63
|
+
*/
|
|
64
|
+
multimodal?: boolean;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Preset generation parameters to include in each request.
|
|
68
|
+
* These parameters will be merged with the request-specific parameters.
|
|
69
|
+
*/
|
|
70
|
+
presetGenParams?: Record<string, unknown>;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Preset headers that will be included in each request.
|
|
74
|
+
*/
|
|
75
|
+
presetHeaders?: Record<string, unknown>;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The DashScope API chat model.
|
|
80
|
+
*/
|
|
81
|
+
export class DashScopeChatModel extends ChatModelBase {
|
|
82
|
+
apiURL: string;
|
|
83
|
+
protected apiKey: string;
|
|
84
|
+
protected presetGenParams: Record<string, unknown> | undefined;
|
|
85
|
+
protected presetHeaders: Record<string, unknown> | undefined;
|
|
86
|
+
protected thinkingConfig?: DashScopeThinkingConfig;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Initializes a new instance of the DashScopeChatModel class.
|
|
90
|
+
*
|
|
91
|
+
* @param options - The DashScope chat model options.
|
|
92
|
+
* @param options.modelName - The name of the model to use.
|
|
93
|
+
* @param options.apiKey - The API key for authentication.
|
|
94
|
+
* @param options.stream - Whether to use streaming responses. Default is true.
|
|
95
|
+
* @param options.thinkingConfig - The thinking configuration for DashScope models, including whether to enable thinking and the thinking budget.
|
|
96
|
+
* @param options.maxRetries - The maximum number of retries for failed requests. Default is 3.
|
|
97
|
+
* @param options.fallbackModelName - The fallback model name to use if the primary model fails.
|
|
98
|
+
* @param options.presetGenParams - Preset generation parameters to include in each request.
|
|
99
|
+
* @param options.presetHeaders - Preset headers that will be included in each request.
|
|
100
|
+
* @param options.multimodal - Whether the model is multimodal or not, this will decide the default API endpoint. If not provided, it will be inferred from the model name.
|
|
101
|
+
* @param options.formatter - An optional custom formatter. If not provided, a default DashScopeChatFormatter will be used.
|
|
102
|
+
*/
|
|
103
|
+
constructor({
|
|
104
|
+
modelName,
|
|
105
|
+
apiKey,
|
|
106
|
+
stream = true,
|
|
107
|
+
thinkingConfig,
|
|
108
|
+
maxRetries = 0,
|
|
109
|
+
fallbackModelName,
|
|
110
|
+
presetGenParams,
|
|
111
|
+
presetHeaders,
|
|
112
|
+
multimodal,
|
|
113
|
+
formatter,
|
|
114
|
+
}: DashScopeChatModelOptions) {
|
|
115
|
+
// If no formatter is provided, create a default DashScopeChatFormatter
|
|
116
|
+
const defaultFormatter = formatter || new DashScopeChatFormatter();
|
|
117
|
+
super({
|
|
118
|
+
modelName,
|
|
119
|
+
stream,
|
|
120
|
+
maxRetries,
|
|
121
|
+
fallbackModelName,
|
|
122
|
+
formatter: defaultFormatter,
|
|
123
|
+
} as ChatModelOptions);
|
|
124
|
+
|
|
125
|
+
this.apiKey = apiKey;
|
|
126
|
+
this.thinkingConfig = thinkingConfig;
|
|
127
|
+
this.presetGenParams = presetGenParams;
|
|
128
|
+
this.presetHeaders = presetHeaders;
|
|
129
|
+
|
|
130
|
+
// Infer the apiURL based on the multimodal option or the model name
|
|
131
|
+
if (multimodal === undefined) {
|
|
132
|
+
// Router according to the model name
|
|
133
|
+
multimodal =
|
|
134
|
+
modelName.includes('vl') ||
|
|
135
|
+
modelName.includes('qwen3.5-plus') ||
|
|
136
|
+
modelName.includes('qvq');
|
|
137
|
+
}
|
|
138
|
+
this.apiURL = multimodal
|
|
139
|
+
? 'https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation'
|
|
140
|
+
: 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Calls the DashScope API with the given parameters.
|
|
145
|
+
*
|
|
146
|
+
* @param modelName - The name of the model to use.
|
|
147
|
+
* @param options - The chat model options.
|
|
148
|
+
* @returns A promise that resolves to either a ChatResponse or an AsyncGenerator of ChatResponses.
|
|
149
|
+
*/
|
|
150
|
+
async _callAPI(
|
|
151
|
+
modelName: string,
|
|
152
|
+
options: ChatModelRequestOptions<Record<string, unknown>>
|
|
153
|
+
): Promise<ChatResponse | AsyncGenerator<ChatResponse, ChatResponse>> {
|
|
154
|
+
// Set up request data
|
|
155
|
+
const data = {
|
|
156
|
+
model: modelName,
|
|
157
|
+
input: {
|
|
158
|
+
messages: options.messages,
|
|
159
|
+
},
|
|
160
|
+
parameters: {
|
|
161
|
+
result_format: 'message',
|
|
162
|
+
tools: this._formatToolSchemas(options.tools),
|
|
163
|
+
toolChoice: this._formatToolChoice(options.toolChoice),
|
|
164
|
+
enable_thinking: this.thinkingConfig?.enableThinking ?? false,
|
|
165
|
+
...(this.thinkingConfig?.thinkingBudget !== undefined && {
|
|
166
|
+
thinking_budget: this.thinkingConfig.thinkingBudget,
|
|
167
|
+
}),
|
|
168
|
+
...(this.presetGenParams ?? {}),
|
|
169
|
+
incremental_output: true,
|
|
170
|
+
} as Record<string, unknown>,
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// Set up headers
|
|
174
|
+
const headers: Record<string, unknown> = {
|
|
175
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
176
|
+
'Content-Type': 'application/json',
|
|
177
|
+
...this.presetHeaders,
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// Set up streaming header if needed
|
|
181
|
+
if (this.stream) {
|
|
182
|
+
headers['X-DashScope-SSE'] = 'enable';
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Counting the time cost
|
|
186
|
+
const startTime = Date.now();
|
|
187
|
+
const response = await fetch(this.apiURL, {
|
|
188
|
+
method: 'POST',
|
|
189
|
+
headers: headers as HeadersInit,
|
|
190
|
+
body: JSON.stringify(data),
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
if (!response.ok) {
|
|
194
|
+
throw new Error(
|
|
195
|
+
`DashScope API request failed with status ${response.status}: ${await response.text()}`
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (this.stream) {
|
|
200
|
+
// Handle the streaming response
|
|
201
|
+
return this._parseDashScopeStreamedResponse(response, startTime);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Handle the non-streaming response
|
|
205
|
+
const blocks: Array<TextBlock | ToolCallBlock | ThinkingBlock | DataBlock> = [];
|
|
206
|
+
const res = await response.json();
|
|
207
|
+
const choice = res.output.choices[0];
|
|
208
|
+
if (choice.message.reasoning_content) {
|
|
209
|
+
blocks.push({
|
|
210
|
+
type: 'thinking',
|
|
211
|
+
thinking: choice.message.reasoning_content,
|
|
212
|
+
id: crypto.randomUUID(),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
if (choice.message.content) {
|
|
216
|
+
blocks.push({ type: 'text', text: choice.message.content, id: crypto.randomUUID() });
|
|
217
|
+
}
|
|
218
|
+
if (choice.message.tool_calls && Array.isArray(choice.message.tool_calls)) {
|
|
219
|
+
choice.message.tool_calls.forEach((toolCall: object) => {
|
|
220
|
+
if (
|
|
221
|
+
'id' in toolCall &&
|
|
222
|
+
'function' in toolCall &&
|
|
223
|
+
typeof toolCall.function === 'object' &&
|
|
224
|
+
toolCall.function &&
|
|
225
|
+
'name' in toolCall.function &&
|
|
226
|
+
'arguments' in toolCall.function
|
|
227
|
+
) {
|
|
228
|
+
const inputString = String(toolCall.function.arguments);
|
|
229
|
+
blocks.push({
|
|
230
|
+
type: 'tool_call',
|
|
231
|
+
id: String(toolCall.id),
|
|
232
|
+
name: String(toolCall.function.name),
|
|
233
|
+
input: inputString,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const usage = res.usage
|
|
240
|
+
? {
|
|
241
|
+
type: 'chat_usage',
|
|
242
|
+
inputTokens: res.usage.input_tokens || 0,
|
|
243
|
+
outputTokens: res.usage.output_tokens || 0,
|
|
244
|
+
time: (Date.now() - startTime) / 1000,
|
|
245
|
+
}
|
|
246
|
+
: undefined;
|
|
247
|
+
|
|
248
|
+
return {
|
|
249
|
+
type: 'chat',
|
|
250
|
+
id: crypto.randomUUID(),
|
|
251
|
+
createdAt: new Date().toISOString(),
|
|
252
|
+
content: blocks,
|
|
253
|
+
usage,
|
|
254
|
+
} as ChatResponse;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* The method to format the tool choice parameter.
|
|
259
|
+
*
|
|
260
|
+
* @param toolChoice - The tool choice option.
|
|
261
|
+
* @returns The formatted tool choice.
|
|
262
|
+
*/
|
|
263
|
+
_formatToolChoice(toolChoice?: ToolChoice): 'auto' | 'none' | Record<string, unknown> {
|
|
264
|
+
if (toolChoice) {
|
|
265
|
+
if (toolChoice === 'auto') return 'auto';
|
|
266
|
+
if (toolChoice === 'none') return 'none';
|
|
267
|
+
return {
|
|
268
|
+
type: 'function',
|
|
269
|
+
function: {
|
|
270
|
+
name: toolChoice,
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
return 'auto';
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Parses a streamed response from DashScope API specifically for chat responses.
|
|
279
|
+
* An async generator that yields delta ChatResponse objects as they are received.
|
|
280
|
+
*
|
|
281
|
+
* @param response - The fetch response object.
|
|
282
|
+
* @param startTime - The start time of the request for usage calculation.
|
|
283
|
+
* @returns An async generator yielding delta ChatResponse objects, and returns the complete ChatResponse.
|
|
284
|
+
*/
|
|
285
|
+
async *_parseDashScopeStreamedResponse(
|
|
286
|
+
response: Response,
|
|
287
|
+
startTime: number
|
|
288
|
+
): AsyncGenerator<ChatResponse, ChatResponse> {
|
|
289
|
+
const asyncGenerator = _parseStreamedResponse<_DashScopeStreamChunk>(response);
|
|
290
|
+
|
|
291
|
+
let accText: string = '';
|
|
292
|
+
let accThinking: string = '';
|
|
293
|
+
// Store accumulated input strings for each tool call
|
|
294
|
+
const accToolInputs: Map<string, string> = new Map();
|
|
295
|
+
// Store tool call metadata (id, name)
|
|
296
|
+
const toolCallMeta: Map<string, { id: string; name: string }> = new Map();
|
|
297
|
+
let lastUsage: ChatUsage | undefined = undefined;
|
|
298
|
+
|
|
299
|
+
for await (const jsonObj of asyncGenerator) {
|
|
300
|
+
if (jsonObj.output && jsonObj.output.choices) {
|
|
301
|
+
const choice = jsonObj.output.choices[0];
|
|
302
|
+
|
|
303
|
+
// Delta data for this chunk
|
|
304
|
+
let deltaText: string = '';
|
|
305
|
+
let deltaThinking: string = '';
|
|
306
|
+
const deltaToolCalls: Map<string, ToolCallBlock> = new Map();
|
|
307
|
+
|
|
308
|
+
const content = choice.message?.content;
|
|
309
|
+
if (content) {
|
|
310
|
+
if (typeof content === 'string') {
|
|
311
|
+
deltaText = content;
|
|
312
|
+
} else if (Array.isArray(content)) {
|
|
313
|
+
for (const block of content) {
|
|
314
|
+
if (block.text) {
|
|
315
|
+
deltaText += block.text;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
accText += deltaText;
|
|
320
|
+
}
|
|
321
|
+
if (choice.message?.reasoning_content) {
|
|
322
|
+
deltaThinking = choice.message.reasoning_content;
|
|
323
|
+
accThinking += deltaThinking;
|
|
324
|
+
}
|
|
325
|
+
if (choice.message?.tool_calls) {
|
|
326
|
+
choice.message.tool_calls.forEach(toolCall => {
|
|
327
|
+
const index = toolCall.index.toString();
|
|
328
|
+
|
|
329
|
+
// Initialize metadata if not exists
|
|
330
|
+
if (!toolCallMeta.has(index)) {
|
|
331
|
+
toolCallMeta.set(index, { id: '', name: '' });
|
|
332
|
+
}
|
|
333
|
+
if (!accToolInputs.has(index)) {
|
|
334
|
+
accToolInputs.set(index, '');
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Update the tool use id
|
|
338
|
+
if (toolCall.id) {
|
|
339
|
+
toolCallMeta.get(index)!.id = toolCall.id;
|
|
340
|
+
}
|
|
341
|
+
// Update the tool use name
|
|
342
|
+
if (toolCall.function?.name) {
|
|
343
|
+
toolCallMeta.get(index)!.name = toolCall.function.name;
|
|
344
|
+
}
|
|
345
|
+
// Update the tool use input
|
|
346
|
+
if (toolCall.function?.arguments) {
|
|
347
|
+
const deltaArgs = toolCall.function.arguments;
|
|
348
|
+
accToolInputs.set(index, accToolInputs.get(index)! + deltaArgs);
|
|
349
|
+
|
|
350
|
+
// Create delta tool call with incremental input
|
|
351
|
+
const meta = toolCallMeta.get(index)!;
|
|
352
|
+
deltaToolCalls.set(index, {
|
|
353
|
+
type: 'tool_call',
|
|
354
|
+
id: meta.id,
|
|
355
|
+
name: meta.name,
|
|
356
|
+
input: deltaArgs,
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Create a delta ChatResponse object
|
|
363
|
+
const deltaBlocks = this._dataToBlocks(deltaText, deltaThinking, deltaToolCalls);
|
|
364
|
+
lastUsage = jsonObj.usage
|
|
365
|
+
? {
|
|
366
|
+
type: 'chat_usage',
|
|
367
|
+
inputTokens: jsonObj.usage.input_tokens || 0,
|
|
368
|
+
outputTokens: jsonObj.usage.output_tokens || 0,
|
|
369
|
+
time: (Date.now() - startTime) / 1000,
|
|
370
|
+
}
|
|
371
|
+
: undefined;
|
|
372
|
+
|
|
373
|
+
yield {
|
|
374
|
+
type: 'chat',
|
|
375
|
+
id: crypto.randomUUID(),
|
|
376
|
+
createdAt: new Date().toISOString(),
|
|
377
|
+
content: deltaBlocks,
|
|
378
|
+
usage: lastUsage,
|
|
379
|
+
} as ChatResponse;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// Build final tool calls with complete JSON strings
|
|
383
|
+
const finalToolCalls: Map<string, ToolCallBlock> = new Map();
|
|
384
|
+
toolCallMeta.forEach((meta, index) => {
|
|
385
|
+
finalToolCalls.set(index, {
|
|
386
|
+
type: 'tool_call',
|
|
387
|
+
id: meta.id,
|
|
388
|
+
name: meta.name,
|
|
389
|
+
input: accToolInputs.get(index) || '{}',
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
const blocks = this._dataToBlocks(accText, accThinking, finalToolCalls);
|
|
394
|
+
return {
|
|
395
|
+
type: 'chat',
|
|
396
|
+
id: crypto.randomUUID(),
|
|
397
|
+
createdAt: new Date().toISOString(),
|
|
398
|
+
content: blocks,
|
|
399
|
+
usage: lastUsage,
|
|
400
|
+
} as ChatResponse;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Convert data into blocks
|
|
405
|
+
*
|
|
406
|
+
* @param text - The text response from the llm API
|
|
407
|
+
* @param thinking - The thinking response
|
|
408
|
+
* @param toolCalls - The tool calls
|
|
409
|
+
* @returns An array of blocks
|
|
410
|
+
*/
|
|
411
|
+
_dataToBlocks(
|
|
412
|
+
text: string,
|
|
413
|
+
thinking: string,
|
|
414
|
+
toolCalls: Map<string, ToolCallBlock>
|
|
415
|
+
): (TextBlock | ThinkingBlock | ToolCallBlock)[] {
|
|
416
|
+
const blocks: (TextBlock | ThinkingBlock | ToolCallBlock)[] = [];
|
|
417
|
+
if (thinking) {
|
|
418
|
+
blocks.push({ type: 'thinking', thinking: thinking, id: crypto.randomUUID() });
|
|
419
|
+
}
|
|
420
|
+
if (text) {
|
|
421
|
+
blocks.push({ type: 'text', text: text, id: crypto.randomUUID() });
|
|
422
|
+
}
|
|
423
|
+
// Push the tool calls into the blocks
|
|
424
|
+
if (toolCalls.size > 0) {
|
|
425
|
+
toolCalls.forEach(value => {
|
|
426
|
+
blocks.push(value);
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
return blocks;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Format the tool schemas to the expected API format.
|
|
435
|
+
* @param tools
|
|
436
|
+
* @returns The formatted tool schemas.
|
|
437
|
+
*/
|
|
438
|
+
_formatToolSchemas(tools: ToolSchema[] | undefined): ToolSchema[] {
|
|
439
|
+
return tools || [];
|
|
440
|
+
}
|
|
441
|
+
}
|