feat(cloud-agent): 操作记录 - 折叠成一行只报最新一步并支持展开完整记录

(cherry picked from commit fce39c847b046ec8b3f11a83f1e809a4a88100d6)
This commit is contained in:
AetherNo2332 committed 2026-09-25 20:57:09 +08:00
1 parent 84e5be0bdb
commit 73ca5a5e9f
7 files changed
+412 -12

No files matched your search

@@ -19,6 +19,7 @@ import { canvasThemes, type CanvasTheme } from "@/lib/canvas-theme";
import { agentErrorPresentation, agentSubmissionErrorTitle } from "@/lib/canvas/agent-error-presentation";
import { cancelAgentRun, getAgentCapabilities, getAgentProfile, getAgentRun, createAgentRun, decideAgentApproval, sendAgentInterjection, sendAgentMessage, subscribeAgentEvents, updateAgentProfile, type AgentEvent, type AgentPermissionMode, type AgentProfileScope, type AgentProfileView, type AgentReasoningMode, type AgentRun } from "@/services/api/agent";
import { agentApprovalPresentation } from "@/lib/canvas/agent-approval-presentation";
import { buildAgentFeedSegments } from "@/lib/canvas/agent-operation-feed";
import { agentApprovalMatchesSettings, agentImageApproval } from "@/lib/canvas/agent-media-approval";
import type { AgentMediaSettings } from "@/services/api/agent";
import { CanvasAgentImageApprovalSettings } from "./canvas-agent-image-approval-settings";
@@ -32,7 +33,7 @@ import { getActiveUserScope } from "@/lib/user-scope";
import { applyAgentCanvasPatches, refreshCanvasAfterAgent, saveRemoteUserDataNow } from "@/services/user-data-sync";
import { createAgentCanvasSync } from "@/services/agent-canvas-sync";
import { buildSkillMentionReferences, resolveSkillMentions } from "@/services/skill-runtime";
import { AgentChatComposer, AgentChatMessage, AgentPlanBar, AgentQuestionBar, AgentSceneCapsules, AgentWorkingMessage, AGENT_SCENE_DEFS, type AgentSceneBucket, type CloudAgentChatMessage, type CloudAgentPlanItem } from "./canvas-cloud-agent-chat-ui";
import { AGENT_SCENE_DEFS, AgentChatComposer, AgentChatMessage, AgentOperationFeed, AgentPlanBar, AgentQuestionBar, AgentSceneCapsules, AgentWorkingMessage, type AgentSceneBucket, type CloudAgentChatMessage, type CloudAgentPlanItem } from "./canvas-cloud-agent-chat-ui";
import { CanvasAgentSkillLibraryModal } from "./canvas-agent-skill-library-modal";
import { CanvasCloudAgentSettings, agentPermissionLabel, agentPermissionMenuItems, agentPermissionVisual, type AgentContextKey } from "./canvas-cloud-agent-settings";
import { useAgentPanelLayout } from "./use-agent-panel-layout";
@@ -1241,6 +1242,9 @@ function AgentConversation({
const contentRef = useRef<HTMLDivElement>(null);
const followRef = useRef(true);
const lastUserId = messages.findLast((item) => item.role === "user")?.id;
// 连续的工具记录折成一行(只报最新一步),计划/提问载体由输入区上方的固定条渲染。
const segments = useMemo(() => buildAgentFeedSegments(messages), [messages]);
const lastMessage = messages.at(-1);
// 自己发送时恢复跟随;阅读旧消息时不让流式输出抢走滚动位置。
useLayoutEffect(() => {
@@ -1269,9 +1273,20 @@ function AgentConversation({
}}>
{!messages.length ? <AgentWelcome appearance={appearance} nodeCount={nodeCount} onChooseSkill={onChooseSkill} onDraftPrompt={onDraftPrompt} /> : null}
<div ref={contentRef} className="agent-conversation-messages">
{messages.map((item) => (
<AgentChatMessage key={item.id} item={item} theme={theme} references={references} onFocusNode={onFocusNode} isStreaming={busy && !approval && item.streaming === true && item === messages.at(-1)} />
))}
{segments.map((segment) =>
segment.kind === "operations" ? (
<AgentOperationFeed key={segment.key} items={segment.items} theme={theme} references={references} onFocusNode={onFocusNode} />
) : (
<AgentChatMessage
key={segment.key}
item={segment.item}
theme={theme}
references={references}
onFocusNode={onFocusNode}
isStreaming={busy && !approval && segment.item.streaming === true && segment.item === lastMessage}
/>
),
)}
{approval ? <ApprovalCard key={approval.approvalId} approval={approval} theme={theme} submitting={approvalSubmitting} onFocusNode={onFocusNode} onReasonChange={onApprovalReasonChange} onApprove={onApprove} onReject={onReject} /> : null}
{busy && !approval ? (
<AgentWorkingMessage theme={theme} label="正在处理当前画布" />