89 lines
2.6 KiB
TypeScript
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"),
|
|
};
|
|
}
|