mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-19 14:41:24 +08:00
Merge eb2aaf1759 into eb7a2cc85a
This commit is contained in:
commit
0ee1ad7322
@ -120,6 +120,23 @@ export class AiSdkToChunkAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果有累积的思考内容,发送 THINKING_COMPLETE chunk 并清空
|
||||
* @param final 包含 reasoningContent 的状态对象
|
||||
* @returns 是否发送了 THINKING_COMPLETE chunk
|
||||
*/
|
||||
private emitThinkingCompleteIfNeeded(final: { reasoningContent: string; [key: string]: any }): boolean {
|
||||
if (final.reasoningContent) {
|
||||
this.onChunk({
|
||||
type: ChunkType.THINKING_COMPLETE,
|
||||
text: final.reasoningContent
|
||||
})
|
||||
final.reasoningContent = ''
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换 AI SDK chunk 为 Cherry Studio chunk 并调用回调
|
||||
* @param chunk AI SDK 的 chunk 数据
|
||||
@ -145,6 +162,9 @@ export class AiSdkToChunkAdapter {
|
||||
}
|
||||
// === 文本相关事件 ===
|
||||
case 'text-start':
|
||||
// 如果有未完成的思考内容,先生成 THINKING_COMPLETE
|
||||
// 这处理了某些提供商不发送 reasoning-end 事件的情况
|
||||
this.emitThinkingCompleteIfNeeded(final)
|
||||
this.onChunk({
|
||||
type: ChunkType.TEXT_START
|
||||
})
|
||||
@ -215,11 +235,7 @@ export class AiSdkToChunkAdapter {
|
||||
})
|
||||
break
|
||||
case 'reasoning-end':
|
||||
this.onChunk({
|
||||
type: ChunkType.THINKING_COMPLETE,
|
||||
text: final.reasoningContent || ''
|
||||
})
|
||||
final.reasoningContent = ''
|
||||
this.emitThinkingCompleteIfNeeded(final)
|
||||
break
|
||||
|
||||
// === 工具调用相关事件(原始 AI SDK 事件,如果没有被中间件处理) ===
|
||||
|
||||
@ -29,10 +29,20 @@ interface BaseCallbacksDependencies {
|
||||
assistantMsgId: string
|
||||
saveUpdatesToDB: any
|
||||
assistant: Assistant
|
||||
getCurrentThinkingInfo?: () => { blockId: string | null; millsec: number }
|
||||
}
|
||||
|
||||
export const createBaseCallbacks = (deps: BaseCallbacksDependencies) => {
|
||||
const { blockManager, dispatch, getState, topicId, assistantMsgId, saveUpdatesToDB, assistant } = deps
|
||||
const {
|
||||
blockManager,
|
||||
dispatch,
|
||||
getState,
|
||||
topicId,
|
||||
assistantMsgId,
|
||||
saveUpdatesToDB,
|
||||
assistant,
|
||||
getCurrentThinkingInfo
|
||||
} = deps
|
||||
|
||||
const startTime = Date.now()
|
||||
const notificationService = NotificationService.getInstance()
|
||||
@ -98,10 +108,17 @@ export const createBaseCallbacks = (deps: BaseCallbacksDependencies) => {
|
||||
const possibleBlockId = findBlockIdForCompletion()
|
||||
|
||||
if (possibleBlockId) {
|
||||
// 更改上一个block的状态为ERROR
|
||||
const changes = {
|
||||
// 更改上一个block的状态为ERROR/PAUSED
|
||||
const changes: Record<string, any> = {
|
||||
status: isErrorTypeAbort ? MessageBlockStatus.PAUSED : MessageBlockStatus.ERROR
|
||||
}
|
||||
// 如果是 thinking block,保留实际思考时间
|
||||
if (blockManager.lastBlockType === MessageBlockType.THINKING) {
|
||||
const thinkingInfo = getCurrentThinkingInfo?.()
|
||||
if (thinkingInfo?.blockId === possibleBlockId && thinkingInfo?.millsec && thinkingInfo.millsec > 0) {
|
||||
changes.thinking_millsec = thinkingInfo.millsec
|
||||
}
|
||||
}
|
||||
blockManager.smartBlockUpdate(possibleBlockId, changes, blockManager.lastBlockType!, true)
|
||||
}
|
||||
|
||||
@ -111,13 +128,28 @@ export const createBaseCallbacks = (deps: BaseCallbacksDependencies) => {
|
||||
if (currentMessage) {
|
||||
const allBlockRefs = findAllBlocks(currentMessage)
|
||||
const blockState = getState().messageBlocks
|
||||
// 获取当前思考信息(如果有),用于保留实际思考时间
|
||||
const thinkingInfo = getCurrentThinkingInfo?.()
|
||||
for (const blockRef of allBlockRefs) {
|
||||
const block = blockState.entities[blockRef.id]
|
||||
if (block && block.status === MessageBlockStatus.STREAMING && block.id !== possibleBlockId) {
|
||||
// 构建更新对象
|
||||
const changes: Record<string, any> = {
|
||||
status: isErrorTypeAbort ? MessageBlockStatus.PAUSED : MessageBlockStatus.ERROR
|
||||
}
|
||||
// 如果是 thinking block 且有思考时间信息,保留实际思考时间
|
||||
if (
|
||||
block.type === MessageBlockType.THINKING &&
|
||||
thinkingInfo?.blockId === block.id &&
|
||||
thinkingInfo?.millsec &&
|
||||
thinkingInfo.millsec > 0
|
||||
) {
|
||||
changes.thinking_millsec = thinkingInfo.millsec
|
||||
}
|
||||
dispatch(
|
||||
updateOneBlock({
|
||||
id: block.id,
|
||||
changes: { status: isErrorTypeAbort ? MessageBlockStatus.PAUSED : MessageBlockStatus.ERROR }
|
||||
changes
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
@ -23,6 +23,12 @@ interface CallbacksDependencies {
|
||||
export const createCallbacks = (deps: CallbacksDependencies) => {
|
||||
const { blockManager, dispatch, getState, topicId, assistantMsgId, saveUpdatesToDB, assistant } = deps
|
||||
|
||||
// 首先创建 thinkingCallbacks ,以便传递 getCurrentThinkingInfo 给 baseCallbacks
|
||||
const thinkingCallbacks = createThinkingCallbacks({
|
||||
blockManager,
|
||||
assistantMsgId
|
||||
})
|
||||
|
||||
// 创建基础回调
|
||||
const baseCallbacks = createBaseCallbacks({
|
||||
blockManager,
|
||||
@ -31,13 +37,8 @@ export const createCallbacks = (deps: CallbacksDependencies) => {
|
||||
topicId,
|
||||
assistantMsgId,
|
||||
saveUpdatesToDB,
|
||||
assistant
|
||||
})
|
||||
|
||||
// 创建各类回调
|
||||
const thinkingCallbacks = createThinkingCallbacks({
|
||||
blockManager,
|
||||
assistantMsgId
|
||||
assistant,
|
||||
getCurrentThinkingInfo: thinkingCallbacks.getCurrentThinkingInfo
|
||||
})
|
||||
|
||||
const toolCallbacks = createToolCallbacks({
|
||||
|
||||
@ -19,6 +19,12 @@ export const createThinkingCallbacks = (deps: ThinkingCallbacksDependencies) =>
|
||||
let thinking_millsec_now: number = 0
|
||||
|
||||
return {
|
||||
// 获取当前思考时间(用于停止回复时保留思考时间)
|
||||
getCurrentThinkingInfo: () => ({
|
||||
blockId: thinkingBlockId,
|
||||
millsec: thinking_millsec_now > 0 ? performance.now() - thinking_millsec_now : 0
|
||||
}),
|
||||
|
||||
onThinkingStart: async () => {
|
||||
if (blockManager.hasInitialPlaceholder) {
|
||||
const changes: Partial<MessageBlock> = {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user