diff --git a/packages/shared/agents/claudecode/types.ts b/packages/shared/agents/claudecode/types.ts new file mode 100644 index 0000000000..d9cd236393 --- /dev/null +++ b/packages/shared/agents/claudecode/types.ts @@ -0,0 +1,12 @@ +import type { SDKMessage } from '@anthropic-ai/claude-code' +import type { ContentBlockParam } from '@anthropic-ai/sdk/resources/messages' + +export type ClaudeCodeRawValue = + | { + type: string + session_id: string + slash_commands: string[] + tools: string[] + raw: Extract + } + | ContentBlockParam diff --git a/src/main/services/agents/services/claudecode/transform.ts b/src/main/services/agents/services/claudecode/transform.ts index cd2f14a59c..33d6e72226 100644 --- a/src/main/services/agents/services/claudecode/transform.ts +++ b/src/main/services/agents/services/claudecode/transform.ts @@ -3,6 +3,7 @@ import type { LanguageModelV2Usage } from '@ai-sdk/provider' import { SDKMessage } from '@anthropic-ai/claude-code' import { loggerService } from '@logger' +import type { ClaudeCodeRawValue } from '@shared/agents/claudecode/types' import type { ProviderMetadata, TextStreamPart } from 'ai' import { v4 as uuidv4 } from 'uuid' @@ -281,15 +282,16 @@ function handleSystemMessage(message: Extract): chunks.push({ type: 'start' }) + const rawValue: ClaudeCodeRawValue = { + type: 'init', + session_id: message.session_id, + slash_commands: message.slash_commands, + tools: message.tools, + raw: message + } chunks.push({ type: 'raw', - rawValue: { - type: 'init', - session_id: message.session_id, - slash_commands: message.slash_commands, - tools: message.tools, - raw: message - } + rawValue }) } } diff --git a/src/renderer/src/aiCore/chunk/AiSdkToChunkAdapter.ts b/src/renderer/src/aiCore/chunk/AiSdkToChunkAdapter.ts index f813f6bafa..7932dea86d 100644 --- a/src/renderer/src/aiCore/chunk/AiSdkToChunkAdapter.ts +++ b/src/renderer/src/aiCore/chunk/AiSdkToChunkAdapter.ts @@ -7,6 +7,7 @@ import { loggerService } from '@logger' import { AISDKWebSearchResult, MCPTool, WebSearchResults, WebSearchSource } from '@renderer/types' import { Chunk, ChunkType } from '@renderer/types/chunk' import { convertLinks, flushLinkConverterBuffer } from '@renderer/utils/linkConverter' +import type { ClaudeCodeRawValue } from '@shared/agents/claudecode/types' import type { TextStreamPart, ToolSet } from 'ai' import { ToolCallChunkHandler } from './handleToolCallChunk' @@ -101,14 +102,19 @@ export class AiSdkToChunkAdapter { chunk: TextStreamPart, final: { text: string; reasoningContent: string; webSearchResults: AISDKWebSearchResult[]; reasoningId: string } ) { - // @ts-ignore - if (chunk.type === 'raw' && chunk.rawValue.type === 'init' && chunk.rawValue.session_id) { - // @ts-ignore - this.onSessionUpdate?.(chunk.rawValue.session_id) - } - logger.silly(`AI SDK chunk type: ${chunk.type}`, chunk) switch (chunk.type) { + case 'raw': { + const agentRawMessage = chunk.rawValue as ClaudeCodeRawValue + if (agentRawMessage.type === 'init' && agentRawMessage.session_id) { + this.onSessionUpdate?.(agentRawMessage.session_id) + } + this.onChunk({ + type: ChunkType.RAW, + content: agentRawMessage + }) + break + } // === 文本相关事件 === case 'text-start': this.onChunk({ diff --git a/src/renderer/src/types/chunk.ts b/src/renderer/src/types/chunk.ts index f28cff54c5..913f402876 100644 --- a/src/renderer/src/types/chunk.ts +++ b/src/renderer/src/types/chunk.ts @@ -47,7 +47,8 @@ export enum ChunkType { SEARCH_IN_PROGRESS_UNION = 'search_in_progress_union', SEARCH_COMPLETE_UNION = 'search_complete_union', VIDEO_SEARCHED = 'video.searched', - IMAGE_SEARCHED = 'image.searched' + IMAGE_SEARCHED = 'image.searched', + RAW = 'raw' } export interface LLMResponseCreatedChunk { @@ -414,6 +415,17 @@ export interface ImageSearchedChunk { metadata: Record } +export interface RawChunk { + /** + * The type of the chunk + */ + type: ChunkType.RAW + + content: unknown + + metadata?: Record +} + export type Chunk = | BlockCreatedChunk // 消息块创建,无意义 | BlockInProgressChunk // 消息块进行中,无意义 @@ -450,3 +462,4 @@ export type Chunk = | SearchCompleteUnionChunk // 搜索(知识库/互联网)完成 | VideoSearchedChunk // 知识库检索视频 | ImageSearchedChunk // 知识库检索图片 + | RawChunk