fix(AnthropicAPIClient): non stream tooluse (#7338)

- Added debug logging in buildSdkMessages for better traceability.
- Improved handling of tool calls in the transform method to correctly index multiple tool uses.
- Enqueued additional response types to enhance the output structure for better integration with the streaming API.
- Refactored event listener attachment for clarity and maintainability.
This commit is contained in:
SuYao 2025-06-19 01:11:15 +08:00 committed by GitHub
parent ccff6dc2b8
commit d05ff5ce48
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -372,7 +372,8 @@ export class AnthropicAPIClient extends BaseApiClient<
listener: RawStreamListener<AnthropicSdkRawChunk> listener: RawStreamListener<AnthropicSdkRawChunk>
): AnthropicSdkRawOutput { ): AnthropicSdkRawOutput {
console.log(`[AnthropicApiClient] 附加流监听器到原始输出`) console.log(`[AnthropicApiClient] 附加流监听器到原始输出`)
// 专用的Anthropic事件处理
const anthropicListener = listener as AnthropicStreamListener
// 检查是否为MessageStream // 检查是否为MessageStream
if (rawOutput instanceof MessageStream) { if (rawOutput instanceof MessageStream) {
console.log(`[AnthropicApiClient] 检测到 Anthropic MessageStream附加专用监听器`) console.log(`[AnthropicApiClient] 检测到 Anthropic MessageStream附加专用监听器`)
@ -387,9 +388,6 @@ export class AnthropicAPIClient extends BaseApiClient<
}) })
} }
// 专用的Anthropic事件处理
const anthropicListener = listener as AnthropicStreamListener
if (anthropicListener.onContentBlock) { if (anthropicListener.onContentBlock) {
rawOutput.on('contentBlock', anthropicListener.onContentBlock) rawOutput.on('contentBlock', anthropicListener.onContentBlock)
} }
@ -413,6 +411,10 @@ export class AnthropicAPIClient extends BaseApiClient<
return rawOutput return rawOutput
} }
if (anthropicListener.onMessage) {
anthropicListener.onMessage(rawOutput)
}
// 对于非MessageStream响应 // 对于非MessageStream响应
return rawOutput return rawOutput
} }
@ -518,6 +520,7 @@ export class AnthropicAPIClient extends BaseApiClient<
async transform(rawChunk: AnthropicSdkRawChunk, controller: TransformStreamDefaultController<GenericChunk>) { async transform(rawChunk: AnthropicSdkRawChunk, controller: TransformStreamDefaultController<GenericChunk>) {
switch (rawChunk.type) { switch (rawChunk.type) {
case 'message': { case 'message': {
let i = 0
for (const content of rawChunk.content) { for (const content of rawChunk.content) {
switch (content.type) { switch (content.type) {
case 'text': { case 'text': {
@ -528,7 +531,8 @@ export class AnthropicAPIClient extends BaseApiClient<
break break
} }
case 'tool_use': { case 'tool_use': {
toolCalls[0] = content toolCalls[i] = content
i++
break break
} }
case 'thinking': { case 'thinking': {
@ -550,6 +554,22 @@ export class AnthropicAPIClient extends BaseApiClient<
} }
} }
} }
if (i > 0) {
controller.enqueue({
type: ChunkType.MCP_TOOL_CREATED,
tool_calls: Object.values(toolCalls)
} as MCPToolCreatedChunk)
}
controller.enqueue({
type: ChunkType.LLM_RESPONSE_COMPLETE,
response: {
usage: {
prompt_tokens: rawChunk.usage.input_tokens || 0,
completion_tokens: rawChunk.usage.output_tokens || 0,
total_tokens: (rawChunk.usage.input_tokens || 0) + (rawChunk.usage.output_tokens || 0)
}
}
})
break break
} }
case 'content_block_start': { case 'content_block_start': {