Files
claude-code/src/components/messages/UserToolResultMessage/UserToolResultMessage.tsx
claude-code-best c80e593212 feature: langfuse thinking 及 文本edit的问题修复( #371); 省略 diff 以减少内存峰值 (#376)
* feat: langfuse tracing 增加 thinking 参数记录

在 recordLLMObservation 中添加 thinking 配置(type/budgetTokens),
所有 provider(claude/gemini/openai)及 tokenEstimation、sideQuery
调用处同步传递 thinking 信息,便于 Langfuse 面板观察 thinking 使用情况。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: langfuse tracing 兼容 budget_tokens snake_case 格式

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: 统一传递完整 thinking 配置而非仅 thinkingType

Langfuse 追踪直接传递整个 thinking 对象(含 type 和 budget_tokens),
Analytics 日志同步补充 thinkingBudgetTokens 字段,logAPIQuery 改为
接收 ThinkingConfig 类型参数。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat: 省略旧消息的代码 diff 展示,仅保留最新消息的完整 diff

* fix: Edit 工具增加 Tab/空格规范化匹配,修复中文和缩进文件编辑失败

Read 工具输出将 Tab 渲染为空格,用户复制后 Edit 工具无法匹配。
在 findActualString 中增加 Tab→空格规范化回退匹配,并精确映射回原始文件位置。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs: README 添加安装/更新失败的解决方案提示

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-27 17:06:33 +08:00

105 lines
2.7 KiB
TypeScript

import type { ToolResultBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'
import * as React from 'react'
import type { Tools } from '../../../Tool.js'
import type {
NormalizedUserMessage,
ProgressMessage,
} from '../../../types/message.js'
import {
type buildMessageLookups,
CANCEL_MESSAGE,
INTERRUPT_MESSAGE_FOR_TOOL_USE,
REJECT_MESSAGE,
} from '../../../utils/messages.js'
import { UserToolCanceledMessage } from './UserToolCanceledMessage.js'
import { UserToolErrorMessage } from './UserToolErrorMessage.js'
import { UserToolRejectMessage } from './UserToolRejectMessage.js'
import { UserToolSuccessMessage } from './UserToolSuccessMessage.js'
import { useGetToolFromMessages } from './utils.js'
type Props = {
param: ToolResultBlockParam
message: NormalizedUserMessage
lookups: ReturnType<typeof buildMessageLookups>
progressMessagesForMessage: ProgressMessage[]
style?: 'condensed'
tools: Tools
verbose: boolean
width: number | string
isTranscriptMode?: boolean
shouldCollapseDiffs?: boolean
}
export function UserToolResultMessage({
param,
message,
lookups,
progressMessagesForMessage,
style,
tools,
verbose,
width,
isTranscriptMode,
shouldCollapseDiffs,
}: Props): React.ReactNode {
const toolUse = useGetToolFromMessages(param.tool_use_id, tools, lookups)
if (!toolUse) {
return null
}
if (
typeof param.content === 'string' &&
param.content.startsWith(CANCEL_MESSAGE)
) {
return <UserToolCanceledMessage />
}
if (
(typeof param.content === 'string' &&
param.content.startsWith(REJECT_MESSAGE)) ||
param.content === INTERRUPT_MESSAGE_FOR_TOOL_USE
) {
return (
<UserToolRejectMessage
input={toolUse.toolUse.input as { [key: string]: unknown }}
progressMessagesForMessage={progressMessagesForMessage}
tool={toolUse.tool}
tools={tools}
lookups={lookups}
style={style}
verbose={verbose}
isTranscriptMode={isTranscriptMode}
/>
)
}
if (param.is_error) {
return (
<UserToolErrorMessage
progressMessagesForMessage={progressMessagesForMessage}
tool={toolUse.tool}
tools={tools}
param={param}
verbose={verbose}
isTranscriptMode={isTranscriptMode}
/>
)
}
return (
<UserToolSuccessMessage
message={message}
lookups={lookups}
toolUseID={toolUse.toolUse.id}
progressMessagesForMessage={progressMessagesForMessage}
style={style}
tool={toolUse.tool}
tools={tools}
verbose={verbose}
width={width}
isTranscriptMode={isTranscriptMode}
shouldCollapseDiffs={shouldCollapseDiffs}
/>
)
}