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

148 lines
4.9 KiB
TypeScript

import { memo, useCallback, type JSX, type ReactNode } from "react";
import type { WorkspaceLinkAction } from "../../../contexts/workspace/presentation/renderer/actions/workspaceLinkActions";
import type { AgentMessageMarkdownWorkspaceAppIcon } from "../../AgentMessageMarkdown";
import type { AgentGUIProviderSkillOption } from "../../../agent-gui/agentGuiNode/model/agentGuiNodeTypes";
import { resolveAgentConversationLinkAction } from "../actions/agentConversationLinkActions";
import type { AgentTranscriptRowVM } from "../contracts/agentTranscriptRowVM";
import type { AgentConversationParticipantPresentation } from "../contracts/agentConversationParticipantPresentation";
import { AgentGeneratedImageRow } from "./AgentGeneratedImageRow";
import { AgentGoalControlRow } from "./AgentGoalControlRow";
import { AgentMessageBlock } from "./AgentMessageBlock";
import { AgentProcessingRow } from "./AgentProcessingRow";
import { AgentToolGroupRow } from "./AgentToolGroupRow";
import { AgentTurnSummaryRow } from "./AgentTurnSummaryRow";
import type { AgentUserMessageEditRetryControl } from "./AgentUserMessageEditRetry";
interface AgentTranscriptItemViewProps {
workspaceRoot: string | null;
basePath: string;
row: AgentTranscriptRowVM;
editRetry?: AgentUserMessageEditRetryControl;
labels: {
toolCallsLabel: (count: number) => string;
thinkingLabel: string;
processing: string;
turnSummary: string;
rawTimelineJson?: string;
};
onLinkAction?: (action: WorkspaceLinkAction) => void;
onAuthLogin?: (provider?: string | null) => void;
provider?: string | null;
availableSkills?: readonly AgentGUIProviderSkillOption[];
workspaceAppIcons?: readonly AgentMessageMarkdownWorkspaceAppIcon[];
showRawTimelineJson?: boolean;
participantPresentation?: AgentConversationParticipantPresentation;
showParticipantHeader?: boolean;
isActiveTurn?: boolean;
processingPaused?: boolean;
toolGroupExpanded?: boolean;
toolGroupExpansionKey?: string;
onToolGroupExpandedChange?: (key: string, expanded: boolean) => void;
footerAction?: ReactNode;
}
export const AgentTranscriptItemView = memo(function AgentTranscriptItemView({
workspaceRoot,
basePath,
row,
editRetry,
labels,
onLinkAction,
onAuthLogin,
provider,
availableSkills,
workspaceAppIcons,
showRawTimelineJson = false,
participantPresentation,
showParticipantHeader,
isActiveTurn = false,
processingPaused = false,
toolGroupExpanded,
toolGroupExpansionKey,
onToolGroupExpandedChange,
footerAction
}: AgentTranscriptItemViewProps): JSX.Element {
"use memo";
const handleLinkClick = useCallback(
(href: string) => {
const action = resolveAgentConversationLinkAction({
workspaceRoot,
basePath,
href,
source: "agent-markdown"
});
if (action) {
onLinkAction?.(action);
}
},
[basePath, onLinkAction, workspaceRoot]
);
switch (row.kind) {
case "generated-image":
return <AgentGeneratedImageRow row={row} />;
case "goal-control":
return (
<AgentGoalControlRow
row={row}
availableSkills={availableSkills}
workspaceAppIcons={workspaceAppIcons}
/>
);
case "message":
return (
<AgentMessageBlock
workspaceRoot={workspaceRoot}
basePath={basePath}
row={row}
editRetry={editRetry}
onLinkAction={onLinkAction}
onAuthLogin={onAuthLogin}
provider={provider}
availableSkills={availableSkills}
workspaceAppIcons={workspaceAppIcons}
thinkingLabel={labels.thinkingLabel}
toolCallsLabel={labels.toolCallsLabel}
showRawTimelineJson={showRawTimelineJson}
rawTimelineJsonLabel={labels.rawTimelineJson}
participantPresentation={participantPresentation}
showParticipantHeader={showParticipantHeader}
isActiveTurn={isActiveTurn}
footerAction={footerAction}
/>
);
case "tool-group":
return (
<AgentToolGroupRow
row={row}
label={labels.toolCallsLabel}
thinkingLabel={labels.thinkingLabel}
onLinkClick={handleLinkClick}
showRawTimelineJson={showRawTimelineJson}
rawTimelineJsonLabel={labels.rawTimelineJson}
expanded={row.grouped ? toolGroupExpanded : undefined}
onExpandedChange={row.grouped ? onToolGroupExpandedChange : undefined}
expansionKey={toolGroupExpansionKey}
/>
);
case "turn-summary":
return (
<AgentTurnSummaryRow
row={row}
workspaceRoot={workspaceRoot}
basePath={basePath}
label={labels.turnSummary}
onLinkAction={onLinkAction}
/>
);
case "processing":
return (
<AgentProcessingRow
row={row}
label={labels.processing}
paused={processingPaused}
/>
);
}
});