Skip to content

Commit 9843a2f

Browse files
authored
Update alibaba.ts
1 parent 64fc226 commit 9843a2f

File tree

1 file changed

+62
-15
lines changed

1 file changed

+62
-15
lines changed

app/client/platforms/alibaba.ts

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -204,22 +204,24 @@ export class QwenApi implements LLMApi {
204204
return { isThinking: false, content: "[解析响应错误]" };
205205
}
206206

207-
// --- 加入这个关键的检查 ---
208-
// 检查 json 对象是否存在,以及它是否包含 output 和 output.choices
209-
if (!json || typeof json.output !== 'object' || !Array.isArray(json.output.choices)) {
210-
// 如果没有 output.choices,就打印一个警告(方便调试,看看是啥样的块)
211-
console.warn("收到的SSE块没有预期的 output.choices 结构:", json);
207+
// --- 修改这里的检查逻辑 ---
208+
// 现在我们直接检查 json.choices 是否是一个数组
209+
if (!json || !Array.isArray(json.choices)) {
210+
// 如果没有 json.choices,打印日志并检查是否是错误或结束块
211+
console.warn("收到的SSE块没有预期的 choices 结构 (直接在顶层):", json);
212212

213-
// 这里可以进一步判断:
214-
// 1. 是否是包含错误信息的块?
215213
if (json.code && json.message) {
216214
console.error("DashScope API 流式传输错误:", json);
217-
return { isThinking: false, content: `[API错误: ${json.message}]` }; // 可以显示错误信息
215+
return { isThinking: false, content: `[API错误: ${json.message}]` };
216+
}
217+
// 你可以检查是否有 usage 字段来判断是否是结束块
218+
if (json.usage) {
219+
console.log("收到包含 usage 的结束块:", json);
220+
// 这里通常可以安全返回空,表示内容流结束
221+
return { isThinking: false, content: "" };
218222
}
219-
// 2. 是否是包含使用量(usage)的结束块?(如果需要处理usage可以在这里加逻辑)
220-
// if (json.usage) { ... }
221223

222-
// 如果都不是,就认为它是一个非内容块(比如结束信号),安全地返回空内容
224+
// 其他未知结构,也返回空
223225
return { isThinking: false, content: "" };
224226
}
225227
// --- 检查结束 ---
@@ -228,12 +230,20 @@ export class QwenApi implements LLMApi {
228230

229231

230232

231-
const choices = json.output.choices as Array<{
233+
//const choices = json.output.choices as Array<{
234+
const choices = json.choices as Array<{
232235
message: {
233236
content: string | null | MultimodalContentForAlibaba[];
234237
tool_calls: ChatMessageTool[];
235238
reasoning_content: string | null;
236239
};
240+
delta?: { // 兼容 delta 结构
241+
content?: string | null;
242+
tool_calls?: ChatMessageTool[];
243+
reasoning_content?: string | null;
244+
245+
};
246+
finish_reason?: string; // 结束原因
237247
}>;
238248

239249

@@ -246,11 +256,40 @@ export class QwenApi implements LLMApi {
246256

247257

248258

249-
if (!choices?.length) return { isThinking: false, content: "" };
259+
if (!choices?.length) return {
260+
console.log("收到的SSE块 choices 数组为空:", json);
261+
isThinking: false, content: "" };
262+
263+
264+
265+
// --- 从 choices[0] 中提取信息 ---
266+
// 需要同时考虑 message 和 delta 两种可能的结构
267+
const firstChoice = choices[0];
268+
const message = firstChoice.message;
269+
const delta = firstChoice.delta;
270+
271+
// 优先从 delta 获取,其次从 message 获取(流式响应通常用 delta)
272+
const tool_calls = delta?.tool_calls ?? message?.tool_calls;
273+
const reasoning = delta?.reasoning_content ?? message?.reasoning_content;
274+
let content = delta?.content ?? message?.content; // content 可能是字符串或数组
275+
276+
277+
278+
279+
250280

251-
const tool_calls = choices[0]?.message?.tool_calls;
281+
282+
//const tool_calls = choices[0]?.message?.tool_calls;
252283
if (tool_calls?.length > 0) {
253-
const index = tool_calls[0]?.index;
284+
//const index = tool_calls[0]?.index;
285+
286+
287+
const toolCall = tool_calls[0]; // 假设每次只处理一个 tool call chunk
288+
const index = (toolCall as any).index; // DashScope 可能有 index
289+
290+
291+
292+
254293
const id = tool_calls[0]?.id;
255294
const args = tool_calls[0]?.function?.arguments;
256295
if (id) {
@@ -283,6 +322,14 @@ export class QwenApi implements LLMApi {
283322
};
284323
}
285324

325+
// 检查 finish_reason,如果是 'tool_calls',说明是工具调用结束,可能没有 content
326+
if (firstChoice.finish_reason === "tool_calls") {
327+
console.log("收到 tool_calls 结束标记");
328+
return { isThinking: false, content: "" };
329+
}
330+
331+
332+
286333
if (reasoning && reasoning.length > 0) {
287334
return {
288335
isThinking: true,

0 commit comments

Comments
 (0)