ai-chatbot/lib/canvas/agent-result-view.ts

89 lines
2.6 KiB
TypeScript

import type {
CanvasOperationKind,
CanvasViewOperationPlan,
} from "@/types/canvas/agent-protocol";
function normalizeNodeIds(nodeIds?: string[]) {
return Array.from(
new Set(
(nodeIds || [])
.map((nodeId) => String(nodeId || "").trim())
.filter(Boolean)
)
);
}
export function buildCanvasAgentResultViewOperation(params: {
projectId?: string | null;
operationId: string;
mutationOperation?: CanvasOperationKind;
sourceNodeIds?: string[];
createdNodeIds?: string[];
updatedNodeIds?: string[];
anchorNodeId?: string | null;
padding?: number;
durationMs?: number;
reason?: string;
}): CanvasViewOperationPlan | null {
const projectId = String(params.projectId || "").trim();
const operationId = String(params.operationId || "").trim();
if (!projectId || !operationId) return null;
const createdNodeIds = normalizeNodeIds(params.createdNodeIds);
const sourceNodeIds = normalizeNodeIds(params.sourceNodeIds).filter(
(nodeId) => !createdNodeIds.includes(nodeId)
);
const updatedNodeIds = normalizeNodeIds(params.updatedNodeIds).filter(
(nodeId) => !createdNodeIds.includes(nodeId) && !sourceNodeIds.includes(nodeId)
);
const hasCreatedResult = createdNodeIds.length > 0;
const comparisonNodeIds =
hasCreatedResult && sourceNodeIds.length > 0
? [...sourceNodeIds, ...createdNodeIds]
: [];
const nodeIds =
comparisonNodeIds.length > 0
? comparisonNodeIds
: createdNodeIds.length > 0
? createdNodeIds
: updatedNodeIds;
if (nodeIds.length === 0) return null;
const requestedAnchorNodeId = String(params.anchorNodeId || "").trim();
const anchorNodeId =
comparisonNodeIds.length > 0
? sourceNodeIds.includes(requestedAnchorNodeId)
? requestedAnchorNodeId
: sourceNodeIds[0]
: nodeIds.includes(requestedAnchorNodeId)
? requestedAnchorNodeId
: nodeIds[0];
const operation =
nodeIds.length > 1
? "focus_nodes"
: hasCreatedResult
? "focus_latest_result"
: "focus_node";
return {
version: 1,
viewOperationId: `${operationId}:view`,
operation,
projectId,
nodeIds,
anchorNodeId,
padding: params.padding ?? 120,
durationMs: params.durationMs ?? 360,
persist: false,
reason:
params.reason ||
(params.mutationOperation === "replace_node_media"
? "focus_canvas_agent_replaced_nodes"
: comparisonNodeIds.length > 0
? "focus_canvas_agent_writeback_comparison"
: hasCreatedResult
? "focus_canvas_agent_writeback_result"
: "focus_canvas_agent_updated_nodes"),
};
}