export type PendingCanvasAgentSlotFillRequest = { nodeId?: string; label?: string; }; export type PendingCanvasAgentAnnotationEditRequest = { nodeId?: string; title?: string; annotationCount?: number; }; export type CanvasAgentPendingRequestWindow = Window & { __canvasAgentPendingSlotFillRequest?: PendingCanvasAgentSlotFillRequest; __canvasAgentPendingAnnotationEditRequest?: PendingCanvasAgentAnnotationEditRequest; }; export const CANVAS_AGENT_OPEN_CHAT_PANEL_EVENT = "canvas-open-chat-panel-request"; export const CANVAS_AGENT_SLOT_FILL_EVENT = "canvas-agent-slot-fill-request"; export const CANVAS_AGENT_ANNOTATION_EDIT_EVENT = "canvas-agent-annotation-edit-request"; function normalizeNodeId(value: unknown) { return String(value || "").trim(); } function shouldConsumePendingRequest(params: { pendingNodeId?: string; detailNodeId?: string; hasDetail: boolean; }) { const pendingNodeId = normalizeNodeId(params.pendingNodeId); const detailNodeId = normalizeNodeId(params.detailNodeId); return !params.hasDetail || !pendingNodeId || pendingNodeId === detailNodeId; } export function storeCanvasAgentSlotFillRequest( targetWindow: CanvasAgentPendingRequestWindow, request: PendingCanvasAgentSlotFillRequest ) { targetWindow.__canvasAgentPendingSlotFillRequest = { ...request }; } export function getPendingCanvasAgentSlotFillRequest( targetWindow: CanvasAgentPendingRequestWindow ) { return targetWindow.__canvasAgentPendingSlotFillRequest || null; } export function consumeCanvasAgentSlotFillRequest( targetWindow: CanvasAgentPendingRequestWindow, detail?: PendingCanvasAgentSlotFillRequest | null ) { const pending = getPendingCanvasAgentSlotFillRequest(targetWindow); if (!pending) return null; if ( shouldConsumePendingRequest({ pendingNodeId: pending.nodeId, detailNodeId: detail?.nodeId, hasDetail: Boolean(detail), }) ) { delete targetWindow.__canvasAgentPendingSlotFillRequest; } return pending; } export function storeCanvasAgentAnnotationEditRequest( targetWindow: CanvasAgentPendingRequestWindow, request: PendingCanvasAgentAnnotationEditRequest ) { targetWindow.__canvasAgentPendingAnnotationEditRequest = { ...request }; } export function getPendingCanvasAgentAnnotationEditRequest( targetWindow: CanvasAgentPendingRequestWindow ) { return targetWindow.__canvasAgentPendingAnnotationEditRequest || null; } export function consumeCanvasAgentAnnotationEditRequest( targetWindow: CanvasAgentPendingRequestWindow, detail?: PendingCanvasAgentAnnotationEditRequest | null ) { const pending = getPendingCanvasAgentAnnotationEditRequest(targetWindow); if (!pending) return null; if ( shouldConsumePendingRequest({ pendingNodeId: pending.nodeId, detailNodeId: detail?.nodeId, hasDetail: Boolean(detail), }) ) { delete targetWindow.__canvasAgentPendingAnnotationEditRequest; } return pending; } export function dispatchCanvasAgentOpenChatPanelRequest( targetWindow: Window, detail: { reason: "agent-slot-fill" | "agent-annotation-edit"; nodeId?: string } ) { targetWindow.dispatchEvent( new CustomEvent(CANVAS_AGENT_OPEN_CHAT_PANEL_EVENT, { detail }) ); } export function dispatchCanvasAgentSlotFillRequest( targetWindow: Window, detail: PendingCanvasAgentSlotFillRequest ) { targetWindow.dispatchEvent(new CustomEvent(CANVAS_AGENT_SLOT_FILL_EVENT, { detail })); } export function dispatchCanvasAgentAnnotationEditRequest( targetWindow: Window, detail: PendingCanvasAgentAnnotationEditRequest ) { targetWindow.dispatchEvent( new CustomEvent(CANVAS_AGENT_ANNOTATION_EDIT_EVENT, { detail }) ); }