update at 2025-10-15 15:07:45

This commit is contained in:
douboer
2025-10-15 15:07:45 +08:00
parent eb8fb51283
commit 901d00e4e1
21 changed files with 4030 additions and 57 deletions

View File

@@ -293,9 +293,12 @@ export class ModelServiceManager {
case 'dashscope':
return [
'qwen3-max',
'qwen3-vl-30b-a3b-thinking',
'qwen3-vl-8b-thinking',
'qwen-flash',
'qwen-turbo-latest', // 通义千问 Turbo 最新版 - 高性价比,响应快
'qwen-plus', // 通义千问增强版 - 推理能力强
'qwen3-max',
'qwen-long', // 通义千问长文本版 - 支持超长上下文(1M tokens)
'qwen3-omni-flash' // 通义千问全能闪电版 - 多模态,极速响应
]
@@ -307,11 +310,9 @@ export class ModelServiceManager {
// DeepSeek-V3 系列 - 深度思考模型
'deepseek-v3-1-terminus', // DeepSeek V3.1 terminus版本
'deepseek-v3-1-250821', // DeepSeek V3.1 250821版本
// Doubao Seed 1.6 系列 - 深度思考模型(推荐)
'doubao-seed-1-6-flash', // 快速多模态深度思考
'doubao-seed-1-6-vision-250815', // 多模态深度思考(图片+视频+GUI)
'doubao-seed-1-6-250615', // 纯文本深度思考
'doubao-seed-1-6-flash-250828', // 快速多模态深度思考
'doubao-seed-1-6-thinking-250715', // 纯思考模型
]
@@ -408,7 +409,8 @@ export class ModelServiceManager {
messages: any[],
model: string,
onChunk: (chunk: string) => void,
tools?: any[]
tools?: any[],
signal?: AbortSignal
): Promise<ApiResponse<{ toolCalls?: any[] }>> {
const startTime = performance.now()
console.log('🚀🚀🚀 [sendChatRequestStream] === 进入流式请求方法 ===')
@@ -431,7 +433,7 @@ export class ModelServiceManager {
}
try {
const toolCalls = await this.makeChatRequestStream(service, messages, model, onChunk, tools)
const toolCalls = await this.makeChatRequestStream(service, messages, model, onChunk, tools, signal)
const endTime = performance.now()
console.log('⏱️ [sendChatRequestStream] 流式请求完成,总耗时:', (endTime - startTime).toFixed(2), 'ms')
@@ -600,7 +602,8 @@ export class ModelServiceManager {
messages: any[],
model: string,
onChunk: (text: string) => void,
tools?: any[]
tools?: any[],
signal?: AbortSignal
): Promise<any[] | undefined> {
const requestStartTime = performance.now()
@@ -675,8 +678,9 @@ export class ModelServiceManager {
console.log(' URL:', url)
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), 60000) // 流式请求60秒超时
// 使用外部传入的 signal或创建一个带超时的内部 controller
const controller = signal ? null : new AbortController()
const timeoutId = controller ? setTimeout(() => controller.abort(), 60000) : undefined // 流式请求60秒超时
try {
const beforeFetch = performance.now()
@@ -686,10 +690,10 @@ export class ModelServiceManager {
method: 'POST',
headers,
body: JSON.stringify(body),
signal: controller.signal
signal: signal || controller?.signal
})
clearTimeout(timeoutId)
if (timeoutId) clearTimeout(timeoutId)
if (!response.ok) {
const errorText = await response.text()
@@ -715,6 +719,13 @@ export class ModelServiceManager {
const toolCallsMap = new Map<number, any>()
while (true) {
// 检查是否被中止(参考 cherry-studio 的实现)
if (signal?.aborted) {
console.log('🛑 [makeChatRequestStream] 检测到中止信号,停止读取流')
reader.cancel()
throw new DOMException('用户中止操作', 'AbortError')
}
const { done, value } = await reader.read()
if (done) break
@@ -753,6 +764,11 @@ export class ModelServiceManager {
// 处理工具调用
if (delta?.tool_calls) {
// 只在第一次检测到时输出日志
if (toolCallsMap.size === 0) {
console.log('🔧 [makeChatRequestStream] 检测到工具调用,开始收集...')
}
for (const toolCall of delta.tool_calls) {
const index = toolCall.index
if (!toolCallsMap.has(index)) {
@@ -785,7 +801,18 @@ export class ModelServiceManager {
// 收集所有工具调用
if (toolCallsMap.size > 0) {
collectedToolCalls = Array.from(toolCallsMap.values())
console.log('🔧 [makeChatRequestStream] 检测到工具调用:', collectedToolCalls.length, '个')
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')
console.log('🔧 [makeChatRequestStream] 最终收集到工具调用:', collectedToolCalls.length, '个')
collectedToolCalls.forEach((tc, idx) => {
console.log(` 工具 [${idx}]:`, {
id: tc.id,
name: tc.function.name,
arguments: tc.function.arguments
})
})
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')
} else {
console.log('⚠️ [makeChatRequestStream] 没有检测到工具调用')
}
const endTime = performance.now()
@@ -795,10 +822,18 @@ export class ModelServiceManager {
return collectedToolCalls.length > 0 ? collectedToolCalls : undefined
} catch (error) {
clearTimeout(timeoutId)
if (timeoutId) clearTimeout(timeoutId)
// 如果是 AbortError直接抛出原始错误可能是用户中止或超时
if (error instanceof Error && error.name === 'AbortError') {
throw new Error('流式请求超时(60秒)')
console.log('⚠️ [makeChatRequestStream] 请求被中止:', error.message)
throw error
}
if (error instanceof DOMException && error.name === 'AbortError') {
console.log('⚠️ [makeChatRequestStream] 请求被中止:', error.message)
throw error
}
throw error
}
}