Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

96 lines
2.8 KiB
TypeScript

import type { JSX } from "react";
import { translate } from "../../../../i18n/index";
import { AgentCodeBlock } from "./code/AgentCodeBlock";
import { AgentUnifiedPatchViewer } from "./file-diff/AgentUnifiedPatchViewer";
import {
stringValue,
ToolMarkdownBlock,
ToolSection,
type AgentToolRendererProps
} from "./agentToolContentShared";
import {
getFileChangeRenderData,
getToolCallFailureText
} from "./render-data/agentToolRenderData";
export function AgentWriteContent({
call,
onLinkClick
}: AgentToolRendererProps): JSX.Element | null {
"use memo";
const files = getFileChangeRenderData(call);
const [file] = files;
const path =
file?.path ??
stringValue(call.input?.path) ??
stringValue(call.input?.file_path) ??
stringValue(call.input?.filePath) ??
null;
const contentFiles = files.filter((candidate) => candidate.content !== null);
const contentPaths = new Set(contentFiles.map((candidate) => candidate.path));
const patchFiles = files.filter(
(candidate) =>
candidate.unifiedDiff !== null && !contentPaths.has(candidate.path)
);
const fallbackContent =
files.length === 0 ? call.summary.trim() || null : null;
const failureText = getToolCallFailureText(call);
const showFileHeaders = files.length > 1;
const hasRenderableContent =
Boolean(failureText) ||
Boolean(path && files.length === 0) ||
patchFiles.length > 0 ||
contentFiles.length > 0 ||
Boolean(fallbackContent);
if (!hasRenderableContent) {
return null;
}
return (
<div className="workspace-agents-status-panel__detail-tool-body workspace-agents-status-panel__detail-tool-body--flat">
{failureText ? (
<ToolSection title={translate("agentHost.agentTool.details.error")}>
<ToolMarkdownBlock
content={failureText}
onLinkClick={onLinkClick}
collapsible
/>
</ToolSection>
) : null}
{path && files.length === 0 ? (
<ToolMarkdownBlock content={path} onLinkClick={onLinkClick} />
) : null}
{patchFiles.map((candidate) => (
<AgentUnifiedPatchViewer
key={`patch:${candidate.path}`}
path={candidate.path}
diffText={candidate.unifiedDiff!}
showHeader={showFileHeaders}
compact
flat
/>
))}
{contentFiles.map((candidate) => (
<AgentCodeBlock
key={`content:${candidate.path}`}
path={candidate.path}
content={candidate.content!}
language={candidate.language}
showHeader={showFileHeaders}
flat
/>
))}
{fallbackContent ? (
<AgentCodeBlock
path={path}
content={fallbackContent}
language={file?.language ?? null}
showHeader={false}
flat
/>
) : null}
</div>
);
}