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