buildship-agent 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +123 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +123 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -424,6 +424,13 @@ function updateAgentMessageParts(parts, newPart) {
|
|
|
424
424
|
}
|
|
425
425
|
|
|
426
426
|
// src/use-agent.ts
|
|
427
|
+
var AgentPausedError = class extends Error {
|
|
428
|
+
constructor(pauseData) {
|
|
429
|
+
super("Agent paused");
|
|
430
|
+
this.pauseData = pauseData;
|
|
431
|
+
this.name = "AgentPausedError";
|
|
432
|
+
}
|
|
433
|
+
};
|
|
427
434
|
function useAgent(agentId, agentUrl, accessKey) {
|
|
428
435
|
const { allSessions, setAllSessions, debugData, setDebugData } = useAgentGlobalState();
|
|
429
436
|
const [inProgress, setInProgress] = (0, import_react2.useState)(false);
|
|
@@ -494,7 +501,8 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
494
501
|
})),
|
|
495
502
|
clientTools: options?.clientTools?.map((t) => ({
|
|
496
503
|
...t,
|
|
497
|
-
parameters: cleanSchema(t.parameters)
|
|
504
|
+
parameters: cleanSchema(t.parameters),
|
|
505
|
+
requiresResult: t.requiresResult ?? false
|
|
498
506
|
}))
|
|
499
507
|
};
|
|
500
508
|
try {
|
|
@@ -521,6 +529,57 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
521
529
|
setCurrentSessionId(sessionId);
|
|
522
530
|
}
|
|
523
531
|
}
|
|
532
|
+
if (resp.headers.get("content-type")?.includes("application/json")) {
|
|
533
|
+
const data = await resp.json();
|
|
534
|
+
if (data.result?._?.paused) {
|
|
535
|
+
setMessages((prev) => {
|
|
536
|
+
const lastMessage = prev[prev.length - 1];
|
|
537
|
+
const newParts = data.result.clientActions.map((action, index) => ({
|
|
538
|
+
type: "widget",
|
|
539
|
+
toolName: action.toolName,
|
|
540
|
+
callId: action.callId,
|
|
541
|
+
inputs: action.inputs,
|
|
542
|
+
sequence: (lastMessage?.parts?.length || 0) + index
|
|
543
|
+
}));
|
|
544
|
+
let updatedMessages;
|
|
545
|
+
if (lastMessage?.role === "agent") {
|
|
546
|
+
const updatedMessage = {
|
|
547
|
+
...lastMessage,
|
|
548
|
+
parts: [...lastMessage.parts || [], ...newParts]
|
|
549
|
+
};
|
|
550
|
+
updatedMessages = [...prev.slice(0, -1), updatedMessage];
|
|
551
|
+
} else {
|
|
552
|
+
const updatedMessage = {
|
|
553
|
+
role: "agent",
|
|
554
|
+
content: "",
|
|
555
|
+
parts: newParts,
|
|
556
|
+
executionId: Date.now().toString()
|
|
557
|
+
// No execution ID in pause response?
|
|
558
|
+
};
|
|
559
|
+
updatedMessages = [...prev, updatedMessage];
|
|
560
|
+
}
|
|
561
|
+
if (sessionUtils.syncSessionRef.current) {
|
|
562
|
+
sessionUtils.syncSessionRef.current(updatedMessages);
|
|
563
|
+
}
|
|
564
|
+
return updatedMessages;
|
|
565
|
+
});
|
|
566
|
+
setPendingToolCalls((prev) => {
|
|
567
|
+
const updated = new Map(prev);
|
|
568
|
+
data.result.clientActions.forEach((action) => {
|
|
569
|
+
updated.set(action.callId, {
|
|
570
|
+
toolName: action.toolName,
|
|
571
|
+
callId: action.callId,
|
|
572
|
+
inputs: action.inputs,
|
|
573
|
+
requiresResult: true
|
|
574
|
+
// Implicitly true for paused actions
|
|
575
|
+
});
|
|
576
|
+
});
|
|
577
|
+
return updated;
|
|
578
|
+
});
|
|
579
|
+
setIsPaused(true);
|
|
580
|
+
throw new AgentPausedError(data.result);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
524
583
|
const executionId = resp.headers.get("x-buildship-agent-execution-id");
|
|
525
584
|
if (executionId) {
|
|
526
585
|
setMessages((prev) => {
|
|
@@ -643,6 +702,9 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
643
702
|
}
|
|
644
703
|
},
|
|
645
704
|
onerror: (e) => {
|
|
705
|
+
if (e instanceof AgentPausedError) {
|
|
706
|
+
throw e;
|
|
707
|
+
}
|
|
646
708
|
console.log("Agent error", e);
|
|
647
709
|
setInProgress(false);
|
|
648
710
|
if (sessionUtils.syncSessionRef.current) {
|
|
@@ -652,6 +714,10 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
652
714
|
}
|
|
653
715
|
});
|
|
654
716
|
} catch (error) {
|
|
717
|
+
if (error instanceof AgentPausedError) {
|
|
718
|
+
setInProgress(false);
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
655
721
|
console.log("Agent execution failed", error);
|
|
656
722
|
setInProgress(false);
|
|
657
723
|
if (sessionUtils.syncSessionRef.current) {
|
|
@@ -701,6 +767,55 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
701
767
|
}
|
|
702
768
|
throw new Error(`Error status ${resp.status}`);
|
|
703
769
|
}
|
|
770
|
+
if (resp.headers.get("content-type")?.includes("application/json")) {
|
|
771
|
+
const data = await resp.json();
|
|
772
|
+
if (data.result?._?.paused) {
|
|
773
|
+
setMessages((prev) => {
|
|
774
|
+
const lastMessage = prev[prev.length - 1];
|
|
775
|
+
const newParts = data.result.clientActions.map((action, index) => ({
|
|
776
|
+
type: "widget",
|
|
777
|
+
toolName: action.toolName,
|
|
778
|
+
callId: action.callId,
|
|
779
|
+
inputs: action.inputs,
|
|
780
|
+
sequence: (lastMessage?.parts?.length || 0) + index
|
|
781
|
+
}));
|
|
782
|
+
let updatedMessages;
|
|
783
|
+
if (lastMessage?.role === "agent") {
|
|
784
|
+
const updatedMessage = {
|
|
785
|
+
...lastMessage,
|
|
786
|
+
parts: [...lastMessage.parts || [], ...newParts]
|
|
787
|
+
};
|
|
788
|
+
updatedMessages = [...prev.slice(0, -1), updatedMessage];
|
|
789
|
+
} else {
|
|
790
|
+
const updatedMessage = {
|
|
791
|
+
role: "agent",
|
|
792
|
+
content: "",
|
|
793
|
+
parts: newParts,
|
|
794
|
+
executionId: Date.now().toString()
|
|
795
|
+
};
|
|
796
|
+
updatedMessages = [...prev, updatedMessage];
|
|
797
|
+
}
|
|
798
|
+
if (sessionUtils.syncSessionRef.current) {
|
|
799
|
+
sessionUtils.syncSessionRef.current(updatedMessages);
|
|
800
|
+
}
|
|
801
|
+
return updatedMessages;
|
|
802
|
+
});
|
|
803
|
+
setPendingToolCalls((prev) => {
|
|
804
|
+
const updated = new Map(prev);
|
|
805
|
+
data.result.clientActions.forEach((action) => {
|
|
806
|
+
updated.set(action.callId, {
|
|
807
|
+
toolName: action.toolName,
|
|
808
|
+
callId: action.callId,
|
|
809
|
+
inputs: action.inputs,
|
|
810
|
+
requiresResult: true
|
|
811
|
+
});
|
|
812
|
+
});
|
|
813
|
+
return updated;
|
|
814
|
+
});
|
|
815
|
+
setIsPaused(true);
|
|
816
|
+
throw new AgentPausedError(data.result);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
704
819
|
const executionId = resp.headers.get("x-buildship-agent-execution-id");
|
|
705
820
|
if (executionId && options?.input) {
|
|
706
821
|
setMessages((prev) => {
|
|
@@ -819,6 +934,9 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
819
934
|
}
|
|
820
935
|
},
|
|
821
936
|
onerror: (e) => {
|
|
937
|
+
if (e instanceof AgentPausedError) {
|
|
938
|
+
throw e;
|
|
939
|
+
}
|
|
822
940
|
console.log("Agent resume error", e);
|
|
823
941
|
setInProgress(false);
|
|
824
942
|
if (sessionUtils.syncSessionRef.current) {
|
|
@@ -828,6 +946,10 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
828
946
|
}
|
|
829
947
|
});
|
|
830
948
|
} catch (error) {
|
|
949
|
+
if (error instanceof AgentPausedError) {
|
|
950
|
+
setInProgress(false);
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
831
953
|
console.log("Agent resume execution failed", error);
|
|
832
954
|
setInProgress(false);
|
|
833
955
|
if (sessionUtils.syncSessionRef.current) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/agent-context.tsx","../src/use-agent.ts","../src/constants.ts","../src/session-utils.ts","../src/debug-handlers.ts","../src/utils/schema.ts","../src/utils/message.ts","../src/utils/use-synced-local-storage.ts"],"sourcesContent":["export * from \"./types\";\nexport * from \"./agent-context\";\nexport { default as useAgent } from \"./use-agent\";\nexport * from \"./constants\";\nexport * from \"./utils/schema\";\nexport * from \"./utils/message\";\n","import {\n createContext,\n useContext,\n useCallback,\n useRef,\n useState,\n useEffect,\n useMemo,\n ReactNode,\n} from \"react\";\nimport useAgent from \"./use-agent\";\nimport type {\n Message,\n Session,\n DebugDataType,\n ClientToolDefinition,\n ClientToolResult,\n PendingToolCall,\n} from \"./types\";\nimport { useSyncedLocalStorage } from \"./utils/use-synced-local-storage\";\nimport { AGENT_SESSIONS_KEY, AGENT_DEBUG_DATA_KEY } from \"./constants\";\n\nexport interface AgentRunner {\n messages: Message[];\n inProgress: boolean;\n sessionId: string;\n sessions: Session[];\n debugData: Record<string, DebugDataType>;\n pendingToolCalls: PendingToolCall[];\n isPaused: boolean;\n handleSend: (\n input: string,\n options?: {\n context?: Record<string, unknown>;\n testBuildId?: string;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n tools?: ClientToolDefinition[];\n clientTools?: ClientToolDefinition[];\n },\n ) => Promise<void>;\n submitToolResults: (\n toolResults: ClientToolResult[],\n options?: {\n input?: string;\n context?: object;\n additionalHeaders?: Record<string, string>;\n },\n ) => Promise<void>;\n switchSession: (sessionId?: string) => void;\n deleteSession: (sessionId: string) => void;\n addOptimisticMessage: (input: string) => void;\n abort: () => void;\n}\n\ninterface AgentContextValue {\n initializeAgent: (agentId: string, agentUrl: string, accessKey?: string) => void;\n registerRunner: (agentId: string, runner: AgentRunner) => void;\n getRunner: (agentId: string) => AgentRunner | null;\n // Global state provided to useAgent hooks\n allSessions: Record<string, Record<string, Session>>;\n setAllSessions: (\n value:\n | Record<string, Record<string, Session>>\n | ((\n prev: Record<string, Record<string, Session>>,\n ) => Record<string, Record<string, Session>>),\n ) => void;\n debugData: Record<string, DebugDataType>;\n setDebugData: (\n value:\n | Record<string, DebugDataType>\n | ((prev: Record<string, DebugDataType>) => Record<string, DebugDataType>),\n ) => void;\n}\n\nconst AgentContext = createContext<AgentContextValue | null>(null);\n\nexport function AgentContextProvider({ children }: { children: ReactNode }) {\n const activeAgentsRef = useRef<Map<string, { agentUrl: string; accessKey?: string }>>(new Map());\n // Store runners in a ref since we push updates via registerRunner\n // Note: Changes to this Ref won't trigger re-renders of consumers of getRunner directly,\n // but since we return the 'runner' object which contains state,\n // and we access it via a hook that listens to updates (implemented below), it works out.\n // Actually, to make 'useAgentContext' reactive to runner changes, we need a subscription mechanism.\n const runnersRef = useRef<Map<string, AgentRunner>>(new Map());\n const listenersRef = useRef<Map<string, Set<() => void>>>(new Map());\n\n const [, forceUpdate] = useState({});\n\n // Global Sync State managed here to be shared\n const [allSessions, setAllSessions] = useSyncedLocalStorage<\n Record<string, Record<string, Session>>\n >(AGENT_SESSIONS_KEY, {});\n\n const [debugData, setDebugData] = useSyncedLocalStorage<Record<string, DebugDataType>>(\n AGENT_DEBUG_DATA_KEY,\n {},\n );\n\n const initializeAgent = useCallback((agentId: string, agentUrl: string, accessKey?: string) => {\n const existing = activeAgentsRef.current.get(agentId);\n\n if (!existing) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey });\n forceUpdate({});\n } else if (existing.agentUrl !== agentUrl || existing.accessKey !== accessKey) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey });\n forceUpdate({});\n }\n }, []);\n\n const registerRunner = useCallback((agentId: string, runner: AgentRunner) => {\n runnersRef.current.set(agentId, runner);\n // Notify listeners for this agentId\n const listeners = listenersRef.current.get(agentId);\n if (listeners) {\n listeners.forEach((callback) => callback());\n }\n }, []);\n\n const getRunner = useCallback((agentId: string) => {\n return runnersRef.current.get(agentId) || null;\n }, []);\n\n const contextValue = useMemo(\n () => ({\n initializeAgent,\n registerRunner,\n getRunner,\n allSessions,\n setAllSessions,\n debugData,\n setDebugData,\n runnersRef,\n listenersRef,\n }),\n [\n initializeAgent,\n registerRunner,\n getRunner,\n allSessions,\n setAllSessions,\n debugData,\n setDebugData,\n ],\n );\n\n return (\n <AgentContext.Provider value={contextValue}>\n {children}\n {Array.from(activeAgentsRef.current.entries()).map(([agentId, { agentUrl, accessKey }]) => (\n <AgentRunnerInstance key={agentId} agentId={agentId} agentUrl={agentUrl} accessKey={accessKey} />\n ))}\n </AgentContext.Provider>\n );\n}\n\nfunction AgentRunnerInstance({\n agentId,\n agentUrl,\n accessKey,\n}: {\n agentId: string;\n agentUrl: string;\n accessKey?: string;\n}) {\n const agent = useAgent(agentId, agentUrl, accessKey);\n const context = useContext(AgentContext);\n\n if (!context) return null;\n\n useEffect(() => {\n context.registerRunner(agentId, agent);\n }, [agentId, agent, context]);\n\n return null;\n}\n\nexport function useAgentContext(\n agentId: string,\n agentUrl: string,\n accessKey?: string,\n): AgentRunner {\n const context = useContext(AgentContext);\n\n if (!context) {\n throw new Error(\"useAgentContext must be used within AgentContextProvider\");\n }\n\n const { initializeAgent, getRunner, listenersRef } = context as AgentContextValue & {\n listenersRef: React.MutableRefObject<Map<string, Set<() => void>>>;\n };\n\n useEffect(() => {\n initializeAgent(agentId, agentUrl, accessKey);\n }, [agentId, agentUrl, initializeAgent]);\n\n // Reactive subscription to runner updates\n const [runner, setRunner] = useState<AgentRunner | null>(() => getRunner(agentId));\n\n useEffect(() => {\n // Current runner state\n const currentRunner = getRunner(agentId);\n if (currentRunner !== runner) {\n setRunner(currentRunner);\n }\n\n // Subscribe to future updates\n const callback = () => {\n setRunner(getRunner(agentId));\n };\n\n if (!listenersRef.current.has(agentId)) {\n listenersRef.current.set(agentId, new Set());\n }\n listenersRef.current.get(agentId)?.add(callback);\n\n return () => {\n listenersRef.current.get(agentId)?.delete(callback);\n };\n }, [agentId, getRunner]);\n\n const placeholder = useMemo(\n () => ({\n messages: [],\n inProgress: false,\n sessionId: \"\",\n sessions: [],\n debugData: {},\n pendingToolCalls: [],\n isPaused: false,\n handleSend: async () => {},\n submitToolResults: async () => {},\n switchSession: () => {},\n deleteSession: () => {},\n addOptimisticMessage: () => {},\n abort: () => {},\n }),\n [],\n );\n\n return runner || placeholder;\n}\n\n// Hook to access the global state for use-agent\nexport function useAgentGlobalState() {\n const context = useContext(AgentContext);\n if (!context) {\n throw new Error(\"useAgentGlobalState must be used within AgentContextProvider\");\n }\n return {\n allSessions: context.allSessions,\n setAllSessions: context.setAllSessions,\n debugData: context.debugData,\n setDebugData: context.setDebugData,\n };\n}\n","import { useCallback, useRef, useState, useEffect } from \"react\";\nimport { EventSourceMessage, fetchEventSource } from \"@microsoft/fetch-event-source\";\n\nimport { DEFAULT_SESSION_NAME, TEMPORARY_SESSION_ID } from \"./constants\";\nimport { useSessionUtils } from \"./session-utils\";\nimport { createDebugHandlers } from \"./debug-handlers\";\nimport { useAgentGlobalState } from \"./agent-context\";\nimport type {\n Message,\n MessagePart,\n OutputStreamEventType,\n ClientToolDefinition,\n ClientToolResult,\n PendingToolCall,\n} from \"./types\";\nimport { cleanSchema, tryParseJSON } from \"./utils/schema\";\nimport { updateAgentMessageParts } from \"./utils/message\";\n\nexport default function useAgent(agentId: string, agentUrl: string, accessKey?: string) {\n // Use global state from Context instead of Jotai atoms\n const { allSessions, setAllSessions, debugData, setDebugData } = useAgentGlobalState();\n\n const [inProgress, setInProgress] = useState(false);\n const [messages, setMessages] = useState<Array<Message>>([]);\n const [pendingToolCalls, setPendingToolCalls] = useState<Map<string, PendingToolCall>>(new Map());\n const [isPaused, setIsPaused] = useState(false);\n\n const messagesRef = useRef<Array<Message>>([]);\n const clientToolsRef = useRef<ClientToolDefinition[]>([]);\n\n // Initialize currentSessionId later after sessionUtils is available\n const [currentSessionId, setCurrentSessionId] = useState<string>(TEMPORARY_SESSION_ID);\n\n const sessionUtils = useSessionUtils(\n agentId,\n allSessions,\n setAllSessions,\n currentSessionId,\n setCurrentSessionId,\n messagesRef,\n );\n\n // Set initial session ID after sessionUtils is available\n useEffect(() => {\n const initialSessionId = sessionUtils.getInitialSessionId();\n setCurrentSessionId(initialSessionId);\n }, []);\n\n const debugHandlers = createDebugHandlers(setDebugData);\n\n // Keep messagesRef in sync with messages state\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n // Initialize or load session\n useEffect(() => {\n // Don't reset messages if we're currently in progress (streaming)\n if (inProgress) {\n return;\n }\n\n const session = sessionUtils.agentSessions[currentSessionId];\n\n if (session) {\n setMessages(session.messages);\n } else {\n setMessages([]);\n }\n }, [currentSessionId, sessionUtils.agentSessions, agentId, inProgress]);\n\n // Only sync on unmount to prevent data loss\n useEffect(() => {\n return () => {\n if (messagesRef.current.length > 0 && sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current();\n }\n };\n }, []);\n\n const controller = useRef<AbortController>();\n\n const runAgent = useCallback(\n async (\n input: string,\n options?: {\n context?: object;\n testBuildId?: string;\n additionalHeaders?: Record<string, string>;\n tools?: ClientToolDefinition[];\n clientTools?: ClientToolDefinition[];\n },\n ) => {\n setInProgress(true);\n // Abort any existing request before creating a new controller\n if (controller.current) {\n controller.current.abort();\n }\n controller.current = new AbortController();\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options?.additionalHeaders || {}),\n ...(accessKey ? { Authorization: `Bearer ${accessKey}` } : {}),\n };\n\n // Include session ID in headers if we have one\n if (currentSessionId) {\n headers[\"x-buildship-agent-session-id\"] = currentSessionId;\n }\n\n const body = {\n stream: true,\n input,\n context: options?.context || {},\n testBuildId: options?.testBuildId,\n tools: options?.tools?.map((t: { parameters: unknown }) => ({\n ...t,\n parameters: cleanSchema(t.parameters),\n })),\n clientTools: options?.clientTools?.map((t: { parameters: unknown }) => ({\n ...t,\n parameters: cleanSchema(t.parameters),\n })),\n };\n\n try {\n await fetchEventSource(agentUrl, {\n method: \"POST\",\n headers,\n signal: controller.current.signal,\n openWhenHidden: true,\n body: JSON.stringify(body),\n onopen: async (resp) => {\n // catch the 404 status\n if (resp.status >= 400) {\n console.log(`AI onopen error with status: ${resp.status}`);\n\n if (resp.status === 404) {\n // for resume operations with 404, throw a specific error for retry\n throw new Error(`Not Found (${resp.statusText})`);\n }\n\n throw new Error(`Error status ${resp.status}`);\n }\n\n // Extract session ID from response headers if we don't have one\n if (!currentSessionId || currentSessionId === TEMPORARY_SESSION_ID) {\n const sessionId = resp.headers.get(\"x-buildship-agent-session-id\");\n if (sessionId) {\n // Transfer current messages to the new session before switching\n const currentMessages = messagesRef.current;\n const sessionName =\n resp.headers.get(\"x-buildship-agent-session-name\") || DEFAULT_SESSION_NAME;\n\n sessionUtils.createSessionFromResponse(sessionId, sessionName, currentMessages);\n setCurrentSessionId(sessionId);\n }\n }\n\n // Extract execution ID from response headers and update the last user message\n const executionId = resp.headers.get(\"x-buildship-agent-execution-id\");\n if (executionId) {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n if (lastMessage?.role === \"user\") {\n const updatedMessage = {\n ...lastMessage,\n executionId: executionId,\n };\n const updatedMessages = [...prev.slice(0, -1), updatedMessage];\n\n // Sync updated user message\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n }\n return prev;\n });\n }\n },\n onmessage: (event: EventSourceMessage) => {\n try {\n const parsed = JSON.parse(event.data) as OutputStreamEventType;\n\n if (parsed.type === \"llm_text_delta\") {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const sequence = parsed.meta.sequence;\n const newPart: MessagePart = {\n type: \"text\",\n text: parsed.data,\n firstSequence: sequence,\n lastSequence: sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n content: lastMessage.content + parsed.data, // content is still useful for simple displays\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: parsed.data,\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (parsed.type === \"client_tool_call\") {\n const { toolName, callId, inputs } = parsed.data;\n\n // Check if this tool requires a result\n const toolDefinition = clientToolsRef.current.find((t) => t.name === toolName);\n const requiresResult = toolDefinition?.requiresResult ?? false;\n\n // Track pending tool call if it requires a result\n if (requiresResult) {\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n updated.set(callId, {\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n requiresResult,\n });\n return updated;\n });\n }\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newPart: MessagePart = {\n type: \"widget\",\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n sequence: parsed.meta.sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: \"\",\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (\n parsed.type.startsWith(\"debug_\") ||\n parsed.type === \"llm_reasoning_delta\" ||\n parsed.type === \"agent_handoff\" ||\n parsed.type === \"mcp_tool_call_start\" ||\n parsed.type === \"mcp_tool_call_end\"\n ) {\n debugHandlers.handleDebugEvent(parsed);\n }\n } catch (e) {\n console.log(\"Failed to parse agent message\", e);\n }\n },\n onclose: () => {\n console.log(\"Agent closed\");\n setInProgress(false);\n\n // Check if there are pending tool calls that require results\n setPendingToolCalls((currentPending) => {\n if (currentPending.size > 0) {\n setIsPaused(true);\n }\n return currentPending;\n });\n\n // Sync messages when streaming completes\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current();\n }\n },\n onerror: (e) => {\n console.log(\"Agent error\", e);\n setInProgress(false);\n // Sync messages on error to prevent data loss\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw new Error(\"Failed to execute agent\");\n },\n });\n } catch (error) {\n console.log(\"Agent execution failed\", error);\n setInProgress(false);\n // Sync messages on execution failure\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw error;\n }\n },\n [agentUrl, accessKey, currentSessionId, sessionUtils, debugHandlers],\n );\n\n const resumeAgent = useCallback(\n async (\n toolResults: ClientToolResult[],\n options?: {\n input?: string;\n context?: object;\n additionalHeaders?: Record<string, string>;\n },\n ) => {\n if (!currentSessionId || currentSessionId === TEMPORARY_SESSION_ID) {\n throw new Error(\"Cannot resume: no active session\");\n }\n\n setInProgress(true);\n setIsPaused(false);\n\n // Abort any existing request before creating a new controller\n if (controller.current) {\n controller.current.abort();\n }\n controller.current = new AbortController();\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options?.additionalHeaders || {}),\n ...(accessKey ? { Authorization: `Bearer ${accessKey}` } : {}),\n };\n\n // Build resume URL - replace /executeAgent with /resumeAgent\n const baseUrl = agentUrl.replace(/\\/executeAgent\\/.*$/, \"\");\n const resumeUrl = `${baseUrl}/resumeAgent/${agentId}/${currentSessionId}`;\n\n const body = {\n stream: true,\n input: options?.input || \"\",\n context: options?.context || {},\n clientToolResults: toolResults,\n };\n\n try {\n await fetchEventSource(resumeUrl, {\n method: \"POST\",\n headers,\n signal: controller.current.signal,\n openWhenHidden: true,\n body: JSON.stringify(body),\n onopen: async (resp) => {\n if (resp.status >= 400) {\n console.log(`AI onopen error with status: ${resp.status}`);\n\n if (resp.status === 404) {\n throw new Error(`Session not found (${resp.statusText})`);\n }\n\n throw new Error(`Error status ${resp.status}`);\n }\n\n // Extract execution ID from response headers\n const executionId = resp.headers.get(\"x-buildship-agent-execution-id\");\n if (executionId && options?.input) {\n // Add user message if input was provided\n setMessages((prev) => {\n const userMessage: Message = {\n role: \"user\" as const,\n content: options.input || \"\",\n executionId: executionId,\n };\n const updatedMessages = [...prev, userMessage];\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n }\n },\n onmessage: (event: EventSourceMessage) => {\n try {\n const parsed = JSON.parse(event.data) as OutputStreamEventType;\n\n if (parsed.type === \"llm_text_delta\") {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const sequence = parsed.meta.sequence;\n const newPart: MessagePart = {\n type: \"text\",\n text: parsed.data,\n firstSequence: sequence,\n lastSequence: sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n content: lastMessage.content + parsed.data,\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: parsed.data,\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (parsed.type === \"client_tool_call\") {\n const { toolName, callId, inputs } = parsed.data;\n\n // Check if this tool requires a result\n const toolDefinition = clientToolsRef.current.find((t) => t.name === toolName);\n const requiresResult = toolDefinition?.requiresResult ?? false;\n\n // Track pending tool call if it requires a result\n if (requiresResult) {\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n updated.set(callId, {\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n requiresResult,\n });\n return updated;\n });\n }\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newPart: MessagePart = {\n type: \"widget\",\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n sequence: parsed.meta.sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: \"\",\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (\n parsed.type.startsWith(\"debug_\") ||\n parsed.type === \"llm_reasoning_delta\" ||\n parsed.type === \"agent_handoff\" ||\n parsed.type === \"mcp_tool_call_start\" ||\n parsed.type === \"mcp_tool_call_end\"\n ) {\n debugHandlers.handleDebugEvent(parsed);\n }\n } catch (e) {\n console.log(\"Failed to parse agent message\", e);\n }\n },\n onclose: () => {\n console.log(\"Agent resume closed\");\n setInProgress(false);\n\n // Check if there are pending tool calls that require results\n setPendingToolCalls((currentPending) => {\n if (currentPending.size > 0) {\n setIsPaused(true);\n }\n return currentPending;\n });\n\n // Sync messages when streaming completes\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current();\n }\n },\n onerror: (e) => {\n console.log(\"Agent resume error\", e);\n setInProgress(false);\n // Sync messages on error to prevent data loss\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw new Error(\"Failed to resume agent\");\n },\n });\n } catch (error) {\n console.log(\"Agent resume execution failed\", error);\n setInProgress(false);\n // Sync messages on execution failure\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw error;\n }\n },\n [agentUrl, accessKey, currentSessionId, sessionUtils, debugHandlers],\n );\n\n const handleSend = useCallback(\n async (\n input: string,\n options?: {\n context?: object;\n testBuildId?: string;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n tools?: ClientToolDefinition[];\n clientTools?: ClientToolDefinition[];\n },\n ) => {\n // Store client tools for tracking requiresResult\n if (options?.clientTools) {\n clientToolsRef.current = options.clientTools;\n }\n\n // Clear pending tool calls when starting a new conversation\n setPendingToolCalls(new Map());\n setIsPaused(false);\n\n const userMessage = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n };\n\n // Only add user message if not skipping\n if (!options?.skipUserMessage) {\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n // Sync immediately after user message\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n }\n\n try {\n await runAgent(input, options);\n } catch (error) {\n // Ensure user message is preserved even if agent execution fails\n if (!options?.skipUserMessage) {\n setMessages((prev) => {\n const updatedMessages = prev.some((m) => m === userMessage)\n ? prev\n : [...prev, userMessage];\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n }\n throw error;\n }\n },\n [runAgent, sessionUtils.syncSessionRef],\n );\n\n const addOptimisticMessage = useCallback(\n (input: string) => {\n const userMessage = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n };\n\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n // Sync immediately after user message\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n },\n [sessionUtils.syncSessionRef],\n );\n\n const submitToolResults = useCallback(\n async (\n toolResults: ClientToolResult[],\n options?: {\n input?: string;\n context?: object;\n additionalHeaders?: Record<string, string>;\n },\n ) => {\n // Remove submitted tool calls from pending\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n toolResults.forEach((result) => {\n updated.delete(result.callId);\n });\n return updated;\n });\n\n try {\n await resumeAgent(toolResults, options);\n } catch (error) {\n console.error(\"Failed to submit tool results:\", error);\n throw error;\n }\n },\n [resumeAgent],\n );\n\n const abort = useCallback(() => {\n if (controller.current) {\n controller.current.abort();\n }\n setInProgress(false);\n // Sync messages to prevent data loss\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n }, [sessionUtils.syncSessionRef]);\n\n return {\n inProgress,\n messages,\n handleSend,\n addOptimisticMessage,\n submitToolResults,\n abort,\n sessionId: currentSessionId,\n switchSession: sessionUtils.switchSession,\n deleteSession: sessionUtils.deleteSession,\n sessions: sessionUtils.sessionsList,\n debugData,\n pendingToolCalls: Array.from(pendingToolCalls.values()),\n isPaused,\n };\n}\n","export const AGENT_SESSIONS_KEY = \"buildship:agent:conversations\";\nexport const AGENT_DEBUG_DATA_KEY = \"buildship:agent:debug\";\n\nexport const DEFAULT_SESSION_NAME = \"New Chat\";\nexport const TEMPORARY_SESSION_ID = \"sess_temp\";\n","import { useCallback, useMemo, useRef } from \"react\";\nimport type { Message, Session } from \"./types\";\nimport { TEMPORARY_SESSION_ID } from \"./constants\";\n\nexport const useSessionUtils = (\n agentId: string,\n allSessions: Record<string, Record<string, Session>>,\n setAllSessions: (\n value:\n | Record<string, Record<string, Session>>\n | ((\n prev: Record<string, Record<string, Session>>,\n ) => Record<string, Record<string, Session>>),\n ) => void,\n currentSessionId: string,\n setCurrentSessionId: (sessionId: string) => void,\n messagesRef: React.MutableRefObject<Array<Message>>,\n) => {\n const agentSessions = useMemo(() => allSessions[agentId] || {}, [agentId, allSessions]);\n\n const syncSessionRef = useRef<(messages?: Array<Message>) => void>();\n\n syncSessionRef.current = (updatedMessages?: Array<Message>) => {\n if (!currentSessionId || currentSessionId === TEMPORARY_SESSION_ID) {\n return;\n }\n\n setAllSessions((prev) => ({\n ...prev,\n [agentId]: {\n ...prev[agentId],\n [currentSessionId]: {\n ...prev[agentId]?.[currentSessionId],\n messages: updatedMessages ?? messagesRef.current,\n updatedAt: Date.now(),\n },\n },\n }));\n };\n\n const getInitialSessionId = () => {\n const sessions = Object.values(agentSessions);\n if (sessions.length > 0) {\n return sessions.sort((a, b) => b.updatedAt - a.updatedAt)[0].id;\n }\n return TEMPORARY_SESSION_ID;\n };\n\n const switchSession = useCallback(\n (sessionId: string = TEMPORARY_SESSION_ID) => {\n setCurrentSessionId(sessionId);\n },\n [setCurrentSessionId],\n );\n\n const deleteSession = useCallback(\n (sessionId: string) => {\n if (!sessionId || sessionId === TEMPORARY_SESSION_ID) {\n return;\n }\n\n setAllSessions((prev) => {\n const updatedAgentSessions = { ...prev[agentId] };\n delete updatedAgentSessions[sessionId];\n\n return {\n ...prev,\n [agentId]: updatedAgentSessions,\n };\n });\n\n if (sessionId === currentSessionId) {\n const remainingSessions = Object.values(agentSessions).filter((s) => s.id !== sessionId);\n if (remainingSessions.length > 0) {\n const mostRecent = remainingSessions.sort((a, b) => b.updatedAt - a.updatedAt)[0];\n setCurrentSessionId(mostRecent.id);\n } else {\n setCurrentSessionId(TEMPORARY_SESSION_ID);\n }\n }\n },\n [agentId, currentSessionId, agentSessions, setAllSessions, setCurrentSessionId],\n );\n\n const sessionsList = useMemo(\n () => Object.values(agentSessions).sort((a, b) => b.updatedAt - a.updatedAt),\n [agentSessions],\n );\n\n const createSessionFromResponse = (\n sessionId: string,\n sessionName: string,\n currentMessages: Array<Message>,\n ) => {\n setAllSessions((prev) => ({\n ...prev,\n [agentId]: {\n ...prev[agentId],\n [sessionId]: {\n id: sessionId,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n messages: currentMessages,\n name: sessionName,\n },\n },\n }));\n };\n\n return {\n agentSessions,\n syncSessionRef,\n getInitialSessionId,\n switchSession,\n deleteSession,\n sessionsList,\n createSessionFromResponse,\n };\n};\n","import type {\n AgentDebugEventType,\n AgentHandoffEventType,\n DebugDataType,\n LLMReasoningDeltaEventType,\n ReasoningItem,\n ToolExecutionItem,\n HandoffItem,\n MCPToolCallStartEventType,\n MCPToolCallEndEventType,\n MCPToolExecutionItem,\n} from \"./types\";\n\nexport const createDebugHandlers = (\n setDebugData: (\n value:\n | Record<string, DebugDataType>\n | ((prev: Record<string, DebugDataType>) => Record<string, DebugDataType>),\n ) => void,\n) => {\n const handleDebugToolExecutionStarted = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"tool_call\",\n toolId: (parsed.data as { toolId?: string }).toolId || \"unknown\",\n toolCallId: (parsed.data as { toolCallId?: string }).toolCallId,\n status: \"progress\",\n },\n ],\n }));\n };\n\n const handleDebugToolExecutionInputs = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n currentData[i] = {\n ...toolItem,\n inputs: (parsed.data as { value: unknown }).value,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugToolExecutionFinished = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n currentData[i] = {\n ...toolItem,\n status: \"complete\",\n output: (parsed.data as { value: unknown }).value,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugToolExecutionError = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n currentData[i] = {\n ...toolItem,\n status: \"error\",\n output: (parsed.data as { value: unknown }).value,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugToolLog = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n const currentLogs = toolItem.logs || [];\n currentData[i] = {\n ...toolItem,\n logs: [...currentLogs, (parsed.data as { value: unknown[] }).value[0]],\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n let lastReasoningIndex = -1;\n const handleDebugReasoningStep = (parsed: LLMReasoningDeltaEventType) => {\n const executionId = parsed.meta.executionId;\n const { delta, index } = parsed.data;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n if (lastReasoningIndex < index) {\n currentData.push({ itemType: \"reasoning\", reasoning: \"\" });\n lastReasoningIndex = index;\n }\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"reasoning\") {\n currentData[i] = {\n itemType: \"reasoning\",\n reasoning: (currentData[i] as ReasoningItem).reasoning + delta,\n };\n break;\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleAgentHandoff = (parsed: AgentHandoffEventType) => {\n const executionId = parsed.meta.executionId;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"handoff\",\n agentName: parsed.data.agentName,\n } as HandoffItem,\n ],\n }));\n };\n\n const handleMCPToolCallStart = (parsed: MCPToolCallStartEventType) => {\n const executionId = parsed.meta.executionId;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"mcp_tool_call\",\n toolName: parsed.data.toolName,\n serverName: parsed.data.serverName,\n callId: parsed.data.callId,\n status: \"progress\",\n inputs: parsed.data.inputs,\n } as MCPToolExecutionItem,\n ],\n }));\n };\n\n const handleMCPToolCallEnd = (parsed: MCPToolCallEndEventType) => {\n const executionId = parsed.meta.executionId;\n const callId = parsed.data.callId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"mcp_tool_call\") {\n const mcpToolItem = currentData[i] as MCPToolExecutionItem;\n if (mcpToolItem.callId === callId) {\n currentData[i] = {\n ...mcpToolItem,\n status: parsed.data.error ? \"error\" : \"complete\",\n output: parsed.data.result,\n error: parsed.data.error,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugEvent = (\n parsed:\n | AgentDebugEventType\n | LLMReasoningDeltaEventType\n | AgentHandoffEventType\n | MCPToolCallStartEventType\n | MCPToolCallEndEventType,\n ) => {\n switch (parsed.type) {\n case \"debug_tool_execution_started\":\n handleDebugToolExecutionStarted(parsed);\n break;\n case \"debug_tool_execution_inputs\":\n handleDebugToolExecutionInputs(parsed);\n break;\n case \"debug_tool_execution_finished\":\n handleDebugToolExecutionFinished(parsed);\n break;\n case \"debug_tool_execution_error\":\n handleDebugToolExecutionError(parsed);\n break;\n case \"debug_tool_log\":\n handleDebugToolLog(parsed);\n break;\n case \"llm_reasoning_delta\":\n handleDebugReasoningStep(parsed);\n break;\n case \"agent_handoff\":\n handleAgentHandoff(parsed);\n break;\n case \"mcp_tool_call_start\":\n handleMCPToolCallStart(parsed);\n break;\n case \"mcp_tool_call_end\":\n handleMCPToolCallEnd(parsed);\n break;\n }\n };\n\n return {\n handleDebugEvent,\n };\n};\n","/**\n * Helper to clean JSON Schema for LLM compatibility.\n * Replaces modern Draft 2020-12 features with older, more compatible alternatives.\n * Specifically handles OpenAI's 'Strict Mode' requirements.\n */\nexport function cleanSchema(obj: unknown): unknown {\n if (Array.isArray(obj)) {\n return obj.map(cleanSchema);\n } else if (obj !== null && typeof obj === \"object\") {\n const newObj: Record<string, unknown> = {};\n const currentObj = obj as Record<string, any>;\n\n for (const key in currentObj) {\n // Remove keys that are not supported by most LLMs\n if (key === \"propertyNames\" || key === \"$schema\") {\n continue;\n }\n newObj[key] = cleanSchema(currentObj[key]);\n }\n\n // OpenAI and some other LLMs require additionalProperties: false for all objects in strict mode\n // AND every property must be explicitly listed in the 'required' array\n if (newObj.type === \"object\") {\n if (\n newObj.additionalProperties === undefined ||\n (newObj.additionalProperties &&\n typeof newObj.additionalProperties === \"object\" &&\n Object.keys(newObj.additionalProperties).length === 0)\n ) {\n newObj.additionalProperties = false;\n }\n\n if (newObj.additionalProperties === false && newObj.properties) {\n newObj.required = Object.keys(newObj.properties as object);\n }\n }\n\n return newObj;\n }\n return obj;\n}\n\n/**\n * Safely attempts to parse a value as JSON if it's a string.\n */\nexport function tryParseJSON(value: unknown): any {\n if (typeof value === \"string\") {\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n }\n return value;\n}\n","import type { MessagePart } from \"../types\";\n\n/**\n * Updates a list of message parts with a new part,\n * ensuring chronological order by sequence and merging contiguous text deltas.\n */\nexport function updateAgentMessageParts(parts: MessagePart[], newPart: MessagePart): MessagePart[] {\n // 1. Combine and sort all parts by their sequence ID\n const sorted = [...parts, newPart].sort((a, b) => {\n const aStart = a.type === \"text\" ? a.firstSequence : a.sequence;\n const bStart = b.type === \"text\" ? b.firstSequence : b.sequence;\n return aStart - bStart;\n });\n\n // 2. Reduce the sorted parts to merge contiguous text blocks\n return sorted.reduce<MessagePart[]>((acc, current) => {\n const last = acc[acc.length - 1];\n\n // Check if we can merge this text part with the previous one\n const canMerge =\n last?.type === \"text\" &&\n current.type === \"text\" &&\n current.firstSequence === last.lastSequence + 1;\n\n if (canMerge) {\n acc[acc.length - 1] = {\n ...last,\n text: last.text + current.text,\n lastSequence: current.lastSequence,\n };\n return acc;\n }\n\n acc.push(current);\n return acc;\n }, []);\n}\n","import { useState, useEffect, useCallback } from \"react\";\n\n// Helper to handle JSON parsing cleanly\nfunction parseJSON<T>(value: string | null, defaultValue: T): T {\n if (value === null) return defaultValue;\n try {\n return JSON.parse(value);\n } catch {\n return defaultValue;\n }\n}\n\nexport function useSyncedLocalStorage<T>(\n key: string,\n initialValue: T,\n): [T, (value: T | ((val: T) => T)) => void] {\n // Initialize state function to avoid reading localStorage on every render\n const [storedValue, setStoredValue] = useState<T>(() => {\n if (typeof window === \"undefined\") {\n return initialValue;\n }\n try {\n const item = window.localStorage.getItem(key);\n return parseJSON(item, initialValue);\n } catch (error) {\n console.warn(`Error reading localStorage key \"${key}\":`, error);\n return initialValue;\n }\n });\n\n // Function to update state and localStorage\n const setValue = useCallback(\n (value: T | ((val: T) => T)) => {\n try {\n setStoredValue((prev) => {\n const valueToStore = value instanceof Function ? value(prev) : value;\n\n if (typeof window !== \"undefined\") {\n window.localStorage.setItem(key, JSON.stringify(valueToStore));\n // Dispatch a custom event so other hooks in the same window update\n window.dispatchEvent(\n new StorageEvent(\"storage\", { key, newValue: JSON.stringify(valueToStore) }),\n );\n }\n return valueToStore;\n });\n } catch (error) {\n console.warn(`Error setting localStorage key \"${key}\":`, error);\n }\n },\n [key],\n );\n\n // Sync across tabs/windows and within the same window\n useEffect(() => {\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key === key) {\n setStoredValue(parseJSON(event.newValue, initialValue));\n }\n };\n\n window.addEventListener(\"storage\", handleStorageChange);\n return () => window.removeEventListener(\"storage\", handleStorageChange);\n }, [key, initialValue]);\n\n return [storedValue, setValue];\n}\n"],"mappings":"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","names":["import_react","import_react","import_react"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/agent-context.tsx","../src/use-agent.ts","../src/constants.ts","../src/session-utils.ts","../src/debug-handlers.ts","../src/utils/schema.ts","../src/utils/message.ts","../src/utils/use-synced-local-storage.ts"],"sourcesContent":["export * from \"./types\";\nexport * from \"./agent-context\";\nexport { default as useAgent } from \"./use-agent\";\nexport * from \"./constants\";\nexport * from \"./utils/schema\";\nexport * from \"./utils/message\";\n","import {\n createContext,\n useContext,\n useCallback,\n useRef,\n useState,\n useEffect,\n useMemo,\n ReactNode,\n} from \"react\";\nimport useAgent from \"./use-agent\";\nimport type {\n Message,\n Session,\n DebugDataType,\n ClientToolDefinition,\n ClientToolResult,\n PendingToolCall,\n} from \"./types\";\nimport { useSyncedLocalStorage } from \"./utils/use-synced-local-storage\";\nimport { AGENT_SESSIONS_KEY, AGENT_DEBUG_DATA_KEY } from \"./constants\";\n\nexport interface AgentRunner {\n messages: Message[];\n inProgress: boolean;\n sessionId: string;\n sessions: Session[];\n debugData: Record<string, DebugDataType>;\n pendingToolCalls: PendingToolCall[];\n isPaused: boolean;\n handleSend: (\n input: string,\n options?: {\n context?: Record<string, unknown>;\n testBuildId?: string;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n tools?: ClientToolDefinition[];\n clientTools?: ClientToolDefinition[];\n },\n ) => Promise<void>;\n submitToolResults: (\n toolResults: ClientToolResult[],\n options?: {\n input?: string;\n context?: object;\n additionalHeaders?: Record<string, string>;\n },\n ) => Promise<void>;\n switchSession: (sessionId?: string) => void;\n deleteSession: (sessionId: string) => void;\n addOptimisticMessage: (input: string) => void;\n abort: () => void;\n}\n\ninterface AgentContextValue {\n initializeAgent: (agentId: string, agentUrl: string, accessKey?: string) => void;\n registerRunner: (agentId: string, runner: AgentRunner) => void;\n getRunner: (agentId: string) => AgentRunner | null;\n // Global state provided to useAgent hooks\n allSessions: Record<string, Record<string, Session>>;\n setAllSessions: (\n value:\n | Record<string, Record<string, Session>>\n | ((\n prev: Record<string, Record<string, Session>>,\n ) => Record<string, Record<string, Session>>),\n ) => void;\n debugData: Record<string, DebugDataType>;\n setDebugData: (\n value:\n | Record<string, DebugDataType>\n | ((prev: Record<string, DebugDataType>) => Record<string, DebugDataType>),\n ) => void;\n}\n\nconst AgentContext = createContext<AgentContextValue | null>(null);\n\nexport function AgentContextProvider({ children }: { children: ReactNode }) {\n const activeAgentsRef = useRef<Map<string, { agentUrl: string; accessKey?: string }>>(new Map());\n // Store runners in a ref since we push updates via registerRunner\n // Note: Changes to this Ref won't trigger re-renders of consumers of getRunner directly,\n // but since we return the 'runner' object which contains state,\n // and we access it via a hook that listens to updates (implemented below), it works out.\n // Actually, to make 'useAgentContext' reactive to runner changes, we need a subscription mechanism.\n const runnersRef = useRef<Map<string, AgentRunner>>(new Map());\n const listenersRef = useRef<Map<string, Set<() => void>>>(new Map());\n\n const [, forceUpdate] = useState({});\n\n // Global Sync State managed here to be shared\n const [allSessions, setAllSessions] = useSyncedLocalStorage<\n Record<string, Record<string, Session>>\n >(AGENT_SESSIONS_KEY, {});\n\n const [debugData, setDebugData] = useSyncedLocalStorage<Record<string, DebugDataType>>(\n AGENT_DEBUG_DATA_KEY,\n {},\n );\n\n const initializeAgent = useCallback((agentId: string, agentUrl: string, accessKey?: string) => {\n const existing = activeAgentsRef.current.get(agentId);\n\n if (!existing) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey });\n forceUpdate({});\n } else if (existing.agentUrl !== agentUrl || existing.accessKey !== accessKey) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey });\n forceUpdate({});\n }\n }, []);\n\n const registerRunner = useCallback((agentId: string, runner: AgentRunner) => {\n runnersRef.current.set(agentId, runner);\n // Notify listeners for this agentId\n const listeners = listenersRef.current.get(agentId);\n if (listeners) {\n listeners.forEach((callback) => callback());\n }\n }, []);\n\n const getRunner = useCallback((agentId: string) => {\n return runnersRef.current.get(agentId) || null;\n }, []);\n\n const contextValue = useMemo(\n () => ({\n initializeAgent,\n registerRunner,\n getRunner,\n allSessions,\n setAllSessions,\n debugData,\n setDebugData,\n runnersRef,\n listenersRef,\n }),\n [\n initializeAgent,\n registerRunner,\n getRunner,\n allSessions,\n setAllSessions,\n debugData,\n setDebugData,\n ],\n );\n\n return (\n <AgentContext.Provider value={contextValue}>\n {children}\n {Array.from(activeAgentsRef.current.entries()).map(([agentId, { agentUrl, accessKey }]) => (\n <AgentRunnerInstance key={agentId} agentId={agentId} agentUrl={agentUrl} accessKey={accessKey} />\n ))}\n </AgentContext.Provider>\n );\n}\n\nfunction AgentRunnerInstance({\n agentId,\n agentUrl,\n accessKey,\n}: {\n agentId: string;\n agentUrl: string;\n accessKey?: string;\n}) {\n const agent = useAgent(agentId, agentUrl, accessKey);\n const context = useContext(AgentContext);\n\n if (!context) return null;\n\n useEffect(() => {\n context.registerRunner(agentId, agent);\n }, [agentId, agent, context]);\n\n return null;\n}\n\nexport function useAgentContext(\n agentId: string,\n agentUrl: string,\n accessKey?: string,\n): AgentRunner {\n const context = useContext(AgentContext);\n\n if (!context) {\n throw new Error(\"useAgentContext must be used within AgentContextProvider\");\n }\n\n const { initializeAgent, getRunner, listenersRef } = context as AgentContextValue & {\n listenersRef: React.MutableRefObject<Map<string, Set<() => void>>>;\n };\n\n useEffect(() => {\n initializeAgent(agentId, agentUrl, accessKey);\n }, [agentId, agentUrl, initializeAgent]);\n\n // Reactive subscription to runner updates\n const [runner, setRunner] = useState<AgentRunner | null>(() => getRunner(agentId));\n\n useEffect(() => {\n // Current runner state\n const currentRunner = getRunner(agentId);\n if (currentRunner !== runner) {\n setRunner(currentRunner);\n }\n\n // Subscribe to future updates\n const callback = () => {\n setRunner(getRunner(agentId));\n };\n\n if (!listenersRef.current.has(agentId)) {\n listenersRef.current.set(agentId, new Set());\n }\n listenersRef.current.get(agentId)?.add(callback);\n\n return () => {\n listenersRef.current.get(agentId)?.delete(callback);\n };\n }, [agentId, getRunner]);\n\n const placeholder = useMemo(\n () => ({\n messages: [],\n inProgress: false,\n sessionId: \"\",\n sessions: [],\n debugData: {},\n pendingToolCalls: [],\n isPaused: false,\n handleSend: async () => {},\n submitToolResults: async () => {},\n switchSession: () => {},\n deleteSession: () => {},\n addOptimisticMessage: () => {},\n abort: () => {},\n }),\n [],\n );\n\n return runner || placeholder;\n}\n\n// Hook to access the global state for use-agent\nexport function useAgentGlobalState() {\n const context = useContext(AgentContext);\n if (!context) {\n throw new Error(\"useAgentGlobalState must be used within AgentContextProvider\");\n }\n return {\n allSessions: context.allSessions,\n setAllSessions: context.setAllSessions,\n debugData: context.debugData,\n setDebugData: context.setDebugData,\n };\n}\n","import { useCallback, useRef, useState, useEffect } from \"react\";\nimport { EventSourceMessage, fetchEventSource } from \"@microsoft/fetch-event-source\";\n\nimport { DEFAULT_SESSION_NAME, TEMPORARY_SESSION_ID } from \"./constants\";\nimport { useSessionUtils } from \"./session-utils\";\nimport { createDebugHandlers } from \"./debug-handlers\";\nimport { useAgentGlobalState } from \"./agent-context\";\nimport type {\n Message,\n MessagePart,\n OutputStreamEventType,\n ClientToolDefinition,\n ClientToolResult,\n PendingToolCall,\n AgentPausedResponse,\n} from \"./types\";\nimport { cleanSchema, tryParseJSON } from \"./utils/schema\";\nimport { updateAgentMessageParts } from \"./utils/message\";\n\nclass AgentPausedError extends Error {\n constructor(public pauseData: AgentPausedResponse[\"result\"]) {\n super(\"Agent paused\");\n this.name = \"AgentPausedError\";\n }\n}\n\nexport default function useAgent(agentId: string, agentUrl: string, accessKey?: string) {\n // Use global state from Context instead of Jotai atoms\n const { allSessions, setAllSessions, debugData, setDebugData } = useAgentGlobalState();\n\n const [inProgress, setInProgress] = useState(false);\n const [messages, setMessages] = useState<Array<Message>>([]);\n const [pendingToolCalls, setPendingToolCalls] = useState<Map<string, PendingToolCall>>(new Map());\n const [isPaused, setIsPaused] = useState(false);\n\n const messagesRef = useRef<Array<Message>>([]);\n const clientToolsRef = useRef<ClientToolDefinition[]>([]);\n\n // Initialize currentSessionId later after sessionUtils is available\n const [currentSessionId, setCurrentSessionId] = useState<string>(TEMPORARY_SESSION_ID);\n\n const sessionUtils = useSessionUtils(\n agentId,\n allSessions,\n setAllSessions,\n currentSessionId,\n setCurrentSessionId,\n messagesRef,\n );\n\n // Set initial session ID after sessionUtils is available\n useEffect(() => {\n const initialSessionId = sessionUtils.getInitialSessionId();\n setCurrentSessionId(initialSessionId);\n }, []);\n\n const debugHandlers = createDebugHandlers(setDebugData);\n\n // Keep messagesRef in sync with messages state\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n // Initialize or load session\n useEffect(() => {\n // Don't reset messages if we're currently in progress (streaming)\n if (inProgress) {\n return;\n }\n\n const session = sessionUtils.agentSessions[currentSessionId];\n\n if (session) {\n setMessages(session.messages);\n } else {\n setMessages([]);\n }\n }, [currentSessionId, sessionUtils.agentSessions, agentId, inProgress]);\n\n // Only sync on unmount to prevent data loss\n useEffect(() => {\n return () => {\n if (messagesRef.current.length > 0 && sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current();\n }\n };\n }, []);\n\n const controller = useRef<AbortController>();\n\n const runAgent = useCallback(\n async (\n input: string,\n options?: {\n context?: object;\n testBuildId?: string;\n additionalHeaders?: Record<string, string>;\n tools?: ClientToolDefinition[];\n clientTools?: ClientToolDefinition[];\n },\n ) => {\n setInProgress(true);\n // Abort any existing request before creating a new controller\n if (controller.current) {\n controller.current.abort();\n }\n controller.current = new AbortController();\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options?.additionalHeaders || {}),\n ...(accessKey ? { Authorization: `Bearer ${accessKey}` } : {}),\n };\n\n // Include session ID in headers if we have one\n if (currentSessionId) {\n headers[\"x-buildship-agent-session-id\"] = currentSessionId;\n }\n\n const body = {\n stream: true,\n input,\n context: options?.context || {},\n testBuildId: options?.testBuildId,\n tools: options?.tools?.map((t: { parameters: unknown }) => ({\n ...t,\n parameters: cleanSchema(t.parameters),\n })),\n clientTools: options?.clientTools?.map((t) => ({\n ...t,\n parameters: cleanSchema(t.parameters),\n requiresResult: t.requiresResult??false,\n })),\n };\n\n try {\n await fetchEventSource(agentUrl, {\n method: \"POST\",\n headers,\n signal: controller.current.signal,\n openWhenHidden: true,\n body: JSON.stringify(body),\n onopen: async (resp) => {\n // catch the 404 status\n if (resp.status >= 400) {\n console.log(`AI onopen error with status: ${resp.status}`);\n\n if (resp.status === 404) {\n // for resume operations with 404, throw a specific error for retry\n throw new Error(`Not Found (${resp.statusText})`);\n }\n\n throw new Error(`Error status ${resp.status}`);\n }\n\n // Extract session ID from response headers if we don't have one\n if (!currentSessionId || currentSessionId === TEMPORARY_SESSION_ID) {\n const sessionId = resp.headers.get(\"x-buildship-agent-session-id\");\n if (sessionId) {\n // Transfer current messages to the new session before switching\n const currentMessages = messagesRef.current;\n const sessionName =\n resp.headers.get(\"x-buildship-agent-session-name\") || DEFAULT_SESSION_NAME;\n\n sessionUtils.createSessionFromResponse(sessionId, sessionName, currentMessages);\n setCurrentSessionId(sessionId);\n }\n }\n\n if (resp.headers.get(\"content-type\")?.includes(\"application/json\")) {\n const data = (await resp.json()) as AgentPausedResponse;\n if (data.result?._?.paused) {\n // Agent paused for client tools\n // Add widget parts for pending actions\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newParts: MessagePart[] = data.result.clientActions.map((action, index) => ({\n type: \"widget\",\n toolName: action.toolName,\n callId: action.callId,\n inputs: action.inputs,\n sequence: (lastMessage?.parts?.length || 0) + index,\n }));\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n parts: [...(lastMessage.parts || []), ...newParts],\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: \"\",\n parts: newParts,\n executionId: Date.now().toString(), // No execution ID in pause response?\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n data.result.clientActions.forEach((action) => {\n updated.set(action.callId, {\n toolName: action.toolName,\n callId: action.callId,\n inputs: action.inputs,\n requiresResult: true, // Implicitly true for paused actions\n });\n });\n return updated;\n });\n\n setIsPaused(true);\n throw new AgentPausedError(data.result);\n }\n }\n\n // Extract execution ID from response headers and update the last user message\n const executionId = resp.headers.get(\"x-buildship-agent-execution-id\");\n if (executionId) {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n if (lastMessage?.role === \"user\") {\n const updatedMessage = {\n ...lastMessage,\n executionId: executionId,\n };\n const updatedMessages = [...prev.slice(0, -1), updatedMessage];\n\n // Sync updated user message\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n }\n return prev;\n });\n }\n },\n onmessage: (event: EventSourceMessage) => {\n try {\n const parsed = JSON.parse(event.data) as OutputStreamEventType;\n\n if (parsed.type === \"llm_text_delta\") {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const sequence = parsed.meta.sequence;\n const newPart: MessagePart = {\n type: \"text\",\n text: parsed.data,\n firstSequence: sequence,\n lastSequence: sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n content: lastMessage.content + parsed.data, // content is still useful for simple displays\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: parsed.data,\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (parsed.type === \"client_tool_call\") {\n const { toolName, callId, inputs } = parsed.data;\n\n // Check if this tool requires a result\n const toolDefinition = clientToolsRef.current.find((t) => t.name === toolName);\n const requiresResult = toolDefinition?.requiresResult ?? false;\n\n // Track pending tool call if it requires a result\n if (requiresResult) {\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n updated.set(callId, {\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n requiresResult,\n });\n return updated;\n });\n }\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newPart: MessagePart = {\n type: \"widget\",\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n sequence: parsed.meta.sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: \"\",\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (\n parsed.type.startsWith(\"debug_\") ||\n parsed.type === \"llm_reasoning_delta\" ||\n parsed.type === \"agent_handoff\" ||\n parsed.type === \"mcp_tool_call_start\" ||\n parsed.type === \"mcp_tool_call_end\"\n ) {\n debugHandlers.handleDebugEvent(parsed);\n }\n } catch (e) {\n console.log(\"Failed to parse agent message\", e);\n }\n },\n onclose: () => {\n console.log(\"Agent closed\");\n setInProgress(false);\n\n // Check if there are pending tool calls that require results\n setPendingToolCalls((currentPending) => {\n if (currentPending.size > 0) {\n setIsPaused(true);\n }\n return currentPending;\n });\n\n // Sync messages when streaming completes\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current();\n }\n },\n onerror: (e) => {\n if (e instanceof AgentPausedError) {\n throw e; // Stop retrying\n }\n console.log(\"Agent error\", e);\n setInProgress(false);\n // Sync messages on error to prevent data loss\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw new Error(\"Failed to execute agent\");\n },\n });\n } catch (error) {\n if (error instanceof AgentPausedError) {\n setInProgress(false);\n return;\n }\n console.log(\"Agent execution failed\", error);\n setInProgress(false);\n // Sync messages on execution failure\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw error;\n }\n },\n [agentUrl, accessKey, currentSessionId, sessionUtils, debugHandlers],\n );\n\n const resumeAgent = useCallback(\n async (\n toolResults: ClientToolResult[],\n options?: {\n input?: string;\n context?: object;\n additionalHeaders?: Record<string, string>;\n },\n ) => {\n if (!currentSessionId || currentSessionId === TEMPORARY_SESSION_ID) {\n throw new Error(\"Cannot resume: no active session\");\n }\n\n setInProgress(true);\n setIsPaused(false);\n\n // Abort any existing request before creating a new controller\n if (controller.current) {\n controller.current.abort();\n }\n controller.current = new AbortController();\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options?.additionalHeaders || {}),\n ...(accessKey ? { Authorization: `Bearer ${accessKey}` } : {}),\n };\n\n // Build resume URL - replace /executeAgent with /resumeAgent\n const baseUrl = agentUrl.replace(/\\/executeAgent\\/.*$/, \"\");\n const resumeUrl = `${baseUrl}/resumeAgent/${agentId}/${currentSessionId}`;\n\n const body = {\n stream: true,\n input: options?.input || \"\",\n context: options?.context || {},\n clientToolResults: toolResults,\n };\n\n try {\n await fetchEventSource(resumeUrl, {\n method: \"POST\",\n headers,\n signal: controller.current.signal,\n openWhenHidden: true,\n body: JSON.stringify(body),\n onopen: async (resp) => {\n if (resp.status >= 400) {\n console.log(`AI onopen error with status: ${resp.status}`);\n\n if (resp.status === 404) {\n throw new Error(`Session not found (${resp.statusText})`);\n }\n\n throw new Error(`Error status ${resp.status}`);\n }\n\n if (resp.headers.get(\"content-type\")?.includes(\"application/json\")) {\n const data = (await resp.json()) as AgentPausedResponse;\n if (data.result?._?.paused) {\n // Agent paused for client tools\n // Add widget parts for pending actions\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newParts: MessagePart[] = data.result.clientActions.map((action, index) => ({\n type: \"widget\",\n toolName: action.toolName,\n callId: action.callId,\n inputs: action.inputs,\n sequence: (lastMessage?.parts?.length || 0) + index,\n }));\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n parts: [...(lastMessage.parts || []), ...newParts],\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: \"\",\n parts: newParts,\n executionId: Date.now().toString(),\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n data.result.clientActions.forEach((action) => {\n updated.set(action.callId, {\n toolName: action.toolName,\n callId: action.callId,\n inputs: action.inputs,\n requiresResult: true,\n });\n });\n return updated;\n });\n\n setIsPaused(true);\n throw new AgentPausedError(data.result);\n }\n }\n\n // Extract execution ID from response headers\n const executionId = resp.headers.get(\"x-buildship-agent-execution-id\");\n if (executionId && options?.input) {\n // Add user message if input was provided\n setMessages((prev) => {\n const userMessage: Message = {\n role: \"user\" as const,\n content: options.input || \"\",\n executionId: executionId,\n };\n const updatedMessages = [...prev, userMessage];\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n }\n },\n onmessage: (event: EventSourceMessage) => {\n try {\n const parsed = JSON.parse(event.data) as OutputStreamEventType;\n\n if (parsed.type === \"llm_text_delta\") {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const sequence = parsed.meta.sequence;\n const newPart: MessagePart = {\n type: \"text\",\n text: parsed.data,\n firstSequence: sequence,\n lastSequence: sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n content: lastMessage.content + parsed.data,\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: parsed.data,\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (parsed.type === \"client_tool_call\") {\n const { toolName, callId, inputs } = parsed.data;\n\n // Check if this tool requires a result\n const toolDefinition = clientToolsRef.current.find((t) => t.name === toolName);\n const requiresResult = toolDefinition?.requiresResult ?? false;\n\n // Track pending tool call if it requires a result\n if (requiresResult) {\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n updated.set(callId, {\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n requiresResult,\n });\n return updated;\n });\n }\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newPart: MessagePart = {\n type: \"widget\",\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n sequence: parsed.meta.sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: \"\",\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (\n parsed.type.startsWith(\"debug_\") ||\n parsed.type === \"llm_reasoning_delta\" ||\n parsed.type === \"agent_handoff\" ||\n parsed.type === \"mcp_tool_call_start\" ||\n parsed.type === \"mcp_tool_call_end\"\n ) {\n debugHandlers.handleDebugEvent(parsed);\n }\n } catch (e) {\n console.log(\"Failed to parse agent message\", e);\n }\n },\n onclose: () => {\n console.log(\"Agent resume closed\");\n setInProgress(false);\n\n // Check if there are pending tool calls that require results\n setPendingToolCalls((currentPending) => {\n if (currentPending.size > 0) {\n setIsPaused(true);\n }\n return currentPending;\n });\n\n // Sync messages when streaming completes\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current();\n }\n },\n onerror: (e) => {\n if (e instanceof AgentPausedError) {\n throw e;\n }\n console.log(\"Agent resume error\", e);\n setInProgress(false);\n // Sync messages on error to prevent data loss\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw new Error(\"Failed to resume agent\");\n },\n });\n } catch (error) {\n if (error instanceof AgentPausedError) {\n setInProgress(false);\n return;\n }\n console.log(\"Agent resume execution failed\", error);\n setInProgress(false);\n // Sync messages on execution failure\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw error;\n }\n },\n [agentUrl, accessKey, currentSessionId, sessionUtils, debugHandlers],\n );\n\n const handleSend = useCallback(\n async (\n input: string,\n options?: {\n context?: object;\n testBuildId?: string;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n tools?: ClientToolDefinition[];\n clientTools?: ClientToolDefinition[];\n },\n ) => {\n // Store client tools for tracking requiresResult\n if (options?.clientTools) {\n clientToolsRef.current = options.clientTools;\n }\n\n // Clear pending tool calls when starting a new conversation\n setPendingToolCalls(new Map());\n setIsPaused(false);\n\n const userMessage = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n };\n\n // Only add user message if not skipping\n if (!options?.skipUserMessage) {\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n // Sync immediately after user message\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n }\n\n try {\n await runAgent(input, options);\n } catch (error) {\n // Ensure user message is preserved even if agent execution fails\n if (!options?.skipUserMessage) {\n setMessages((prev) => {\n const updatedMessages = prev.some((m) => m === userMessage)\n ? prev\n : [...prev, userMessage];\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n }\n throw error;\n }\n },\n [runAgent, sessionUtils.syncSessionRef],\n );\n\n const addOptimisticMessage = useCallback(\n (input: string) => {\n const userMessage = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n };\n\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n // Sync immediately after user message\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n },\n [sessionUtils.syncSessionRef],\n );\n\n const submitToolResults = useCallback(\n async (\n toolResults: ClientToolResult[],\n options?: {\n input?: string;\n context?: object;\n additionalHeaders?: Record<string, string>;\n },\n ) => {\n // Remove submitted tool calls from pending\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n toolResults.forEach((result) => {\n updated.delete(result.callId);\n });\n return updated;\n });\n\n try {\n await resumeAgent(toolResults, options);\n } catch (error) {\n console.error(\"Failed to submit tool results:\", error);\n throw error;\n }\n },\n [resumeAgent],\n );\n\n const abort = useCallback(() => {\n if (controller.current) {\n controller.current.abort();\n }\n setInProgress(false);\n // Sync messages to prevent data loss\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n }, [sessionUtils.syncSessionRef]);\n\n return {\n inProgress,\n messages,\n handleSend,\n addOptimisticMessage,\n submitToolResults,\n abort,\n sessionId: currentSessionId,\n switchSession: sessionUtils.switchSession,\n deleteSession: sessionUtils.deleteSession,\n sessions: sessionUtils.sessionsList,\n debugData,\n pendingToolCalls: Array.from(pendingToolCalls.values()),\n isPaused,\n };\n}\n","export const AGENT_SESSIONS_KEY = \"buildship:agent:conversations\";\nexport const AGENT_DEBUG_DATA_KEY = \"buildship:agent:debug\";\n\nexport const DEFAULT_SESSION_NAME = \"New Chat\";\nexport const TEMPORARY_SESSION_ID = \"sess_temp\";\n","import { useCallback, useMemo, useRef } from \"react\";\nimport type { Message, Session } from \"./types\";\nimport { TEMPORARY_SESSION_ID } from \"./constants\";\n\nexport const useSessionUtils = (\n agentId: string,\n allSessions: Record<string, Record<string, Session>>,\n setAllSessions: (\n value:\n | Record<string, Record<string, Session>>\n | ((\n prev: Record<string, Record<string, Session>>,\n ) => Record<string, Record<string, Session>>),\n ) => void,\n currentSessionId: string,\n setCurrentSessionId: (sessionId: string) => void,\n messagesRef: React.MutableRefObject<Array<Message>>,\n) => {\n const agentSessions = useMemo(() => allSessions[agentId] || {}, [agentId, allSessions]);\n\n const syncSessionRef = useRef<(messages?: Array<Message>) => void>();\n\n syncSessionRef.current = (updatedMessages?: Array<Message>) => {\n if (!currentSessionId || currentSessionId === TEMPORARY_SESSION_ID) {\n return;\n }\n\n setAllSessions((prev) => ({\n ...prev,\n [agentId]: {\n ...prev[agentId],\n [currentSessionId]: {\n ...prev[agentId]?.[currentSessionId],\n messages: updatedMessages ?? messagesRef.current,\n updatedAt: Date.now(),\n },\n },\n }));\n };\n\n const getInitialSessionId = () => {\n const sessions = Object.values(agentSessions);\n if (sessions.length > 0) {\n return sessions.sort((a, b) => b.updatedAt - a.updatedAt)[0].id;\n }\n return TEMPORARY_SESSION_ID;\n };\n\n const switchSession = useCallback(\n (sessionId: string = TEMPORARY_SESSION_ID) => {\n setCurrentSessionId(sessionId);\n },\n [setCurrentSessionId],\n );\n\n const deleteSession = useCallback(\n (sessionId: string) => {\n if (!sessionId || sessionId === TEMPORARY_SESSION_ID) {\n return;\n }\n\n setAllSessions((prev) => {\n const updatedAgentSessions = { ...prev[agentId] };\n delete updatedAgentSessions[sessionId];\n\n return {\n ...prev,\n [agentId]: updatedAgentSessions,\n };\n });\n\n if (sessionId === currentSessionId) {\n const remainingSessions = Object.values(agentSessions).filter((s) => s.id !== sessionId);\n if (remainingSessions.length > 0) {\n const mostRecent = remainingSessions.sort((a, b) => b.updatedAt - a.updatedAt)[0];\n setCurrentSessionId(mostRecent.id);\n } else {\n setCurrentSessionId(TEMPORARY_SESSION_ID);\n }\n }\n },\n [agentId, currentSessionId, agentSessions, setAllSessions, setCurrentSessionId],\n );\n\n const sessionsList = useMemo(\n () => Object.values(agentSessions).sort((a, b) => b.updatedAt - a.updatedAt),\n [agentSessions],\n );\n\n const createSessionFromResponse = (\n sessionId: string,\n sessionName: string,\n currentMessages: Array<Message>,\n ) => {\n setAllSessions((prev) => ({\n ...prev,\n [agentId]: {\n ...prev[agentId],\n [sessionId]: {\n id: sessionId,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n messages: currentMessages,\n name: sessionName,\n },\n },\n }));\n };\n\n return {\n agentSessions,\n syncSessionRef,\n getInitialSessionId,\n switchSession,\n deleteSession,\n sessionsList,\n createSessionFromResponse,\n };\n};\n","import type {\n AgentDebugEventType,\n AgentHandoffEventType,\n DebugDataType,\n LLMReasoningDeltaEventType,\n ReasoningItem,\n ToolExecutionItem,\n HandoffItem,\n MCPToolCallStartEventType,\n MCPToolCallEndEventType,\n MCPToolExecutionItem,\n} from \"./types\";\n\nexport const createDebugHandlers = (\n setDebugData: (\n value:\n | Record<string, DebugDataType>\n | ((prev: Record<string, DebugDataType>) => Record<string, DebugDataType>),\n ) => void,\n) => {\n const handleDebugToolExecutionStarted = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"tool_call\",\n toolId: (parsed.data as { toolId?: string }).toolId || \"unknown\",\n toolCallId: (parsed.data as { toolCallId?: string }).toolCallId,\n status: \"progress\",\n },\n ],\n }));\n };\n\n const handleDebugToolExecutionInputs = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n currentData[i] = {\n ...toolItem,\n inputs: (parsed.data as { value: unknown }).value,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugToolExecutionFinished = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n currentData[i] = {\n ...toolItem,\n status: \"complete\",\n output: (parsed.data as { value: unknown }).value,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugToolExecutionError = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n currentData[i] = {\n ...toolItem,\n status: \"error\",\n output: (parsed.data as { value: unknown }).value,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugToolLog = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n const currentLogs = toolItem.logs || [];\n currentData[i] = {\n ...toolItem,\n logs: [...currentLogs, (parsed.data as { value: unknown[] }).value[0]],\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n let lastReasoningIndex = -1;\n const handleDebugReasoningStep = (parsed: LLMReasoningDeltaEventType) => {\n const executionId = parsed.meta.executionId;\n const { delta, index } = parsed.data;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n if (lastReasoningIndex < index) {\n currentData.push({ itemType: \"reasoning\", reasoning: \"\" });\n lastReasoningIndex = index;\n }\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"reasoning\") {\n currentData[i] = {\n itemType: \"reasoning\",\n reasoning: (currentData[i] as ReasoningItem).reasoning + delta,\n };\n break;\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleAgentHandoff = (parsed: AgentHandoffEventType) => {\n const executionId = parsed.meta.executionId;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"handoff\",\n agentName: parsed.data.agentName,\n } as HandoffItem,\n ],\n }));\n };\n\n const handleMCPToolCallStart = (parsed: MCPToolCallStartEventType) => {\n const executionId = parsed.meta.executionId;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"mcp_tool_call\",\n toolName: parsed.data.toolName,\n serverName: parsed.data.serverName,\n callId: parsed.data.callId,\n status: \"progress\",\n inputs: parsed.data.inputs,\n } as MCPToolExecutionItem,\n ],\n }));\n };\n\n const handleMCPToolCallEnd = (parsed: MCPToolCallEndEventType) => {\n const executionId = parsed.meta.executionId;\n const callId = parsed.data.callId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"mcp_tool_call\") {\n const mcpToolItem = currentData[i] as MCPToolExecutionItem;\n if (mcpToolItem.callId === callId) {\n currentData[i] = {\n ...mcpToolItem,\n status: parsed.data.error ? \"error\" : \"complete\",\n output: parsed.data.result,\n error: parsed.data.error,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugEvent = (\n parsed:\n | AgentDebugEventType\n | LLMReasoningDeltaEventType\n | AgentHandoffEventType\n | MCPToolCallStartEventType\n | MCPToolCallEndEventType,\n ) => {\n switch (parsed.type) {\n case \"debug_tool_execution_started\":\n handleDebugToolExecutionStarted(parsed);\n break;\n case \"debug_tool_execution_inputs\":\n handleDebugToolExecutionInputs(parsed);\n break;\n case \"debug_tool_execution_finished\":\n handleDebugToolExecutionFinished(parsed);\n break;\n case \"debug_tool_execution_error\":\n handleDebugToolExecutionError(parsed);\n break;\n case \"debug_tool_log\":\n handleDebugToolLog(parsed);\n break;\n case \"llm_reasoning_delta\":\n handleDebugReasoningStep(parsed);\n break;\n case \"agent_handoff\":\n handleAgentHandoff(parsed);\n break;\n case \"mcp_tool_call_start\":\n handleMCPToolCallStart(parsed);\n break;\n case \"mcp_tool_call_end\":\n handleMCPToolCallEnd(parsed);\n break;\n }\n };\n\n return {\n handleDebugEvent,\n };\n};\n","/**\n * Helper to clean JSON Schema for LLM compatibility.\n * Replaces modern Draft 2020-12 features with older, more compatible alternatives.\n * Specifically handles OpenAI's 'Strict Mode' requirements.\n */\nexport function cleanSchema(obj: unknown): unknown {\n if (Array.isArray(obj)) {\n return obj.map(cleanSchema);\n } else if (obj !== null && typeof obj === \"object\") {\n const newObj: Record<string, unknown> = {};\n const currentObj = obj as Record<string, any>;\n\n for (const key in currentObj) {\n // Remove keys that are not supported by most LLMs\n if (key === \"propertyNames\" || key === \"$schema\") {\n continue;\n }\n newObj[key] = cleanSchema(currentObj[key]);\n }\n\n // OpenAI and some other LLMs require additionalProperties: false for all objects in strict mode\n // AND every property must be explicitly listed in the 'required' array\n if (newObj.type === \"object\") {\n if (\n newObj.additionalProperties === undefined ||\n (newObj.additionalProperties &&\n typeof newObj.additionalProperties === \"object\" &&\n Object.keys(newObj.additionalProperties).length === 0)\n ) {\n newObj.additionalProperties = false;\n }\n\n if (newObj.additionalProperties === false && newObj.properties) {\n newObj.required = Object.keys(newObj.properties as object);\n }\n }\n\n return newObj;\n }\n return obj;\n}\n\n/**\n * Safely attempts to parse a value as JSON if it's a string.\n */\nexport function tryParseJSON(value: unknown): any {\n if (typeof value === \"string\") {\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n }\n return value;\n}\n","import type { MessagePart } from \"../types\";\n\n/**\n * Updates a list of message parts with a new part,\n * ensuring chronological order by sequence and merging contiguous text deltas.\n */\nexport function updateAgentMessageParts(parts: MessagePart[], newPart: MessagePart): MessagePart[] {\n // 1. Combine and sort all parts by their sequence ID\n const sorted = [...parts, newPart].sort((a, b) => {\n const aStart = a.type === \"text\" ? a.firstSequence : a.sequence;\n const bStart = b.type === \"text\" ? b.firstSequence : b.sequence;\n return aStart - bStart;\n });\n\n // 2. Reduce the sorted parts to merge contiguous text blocks\n return sorted.reduce<MessagePart[]>((acc, current) => {\n const last = acc[acc.length - 1];\n\n // Check if we can merge this text part with the previous one\n const canMerge =\n last?.type === \"text\" &&\n current.type === \"text\" &&\n current.firstSequence === last.lastSequence + 1;\n\n if (canMerge) {\n acc[acc.length - 1] = {\n ...last,\n text: last.text + current.text,\n lastSequence: current.lastSequence,\n };\n return acc;\n }\n\n acc.push(current);\n return acc;\n }, []);\n}\n","import { useState, useEffect, useCallback } from \"react\";\n\n// Helper to handle JSON parsing cleanly\nfunction parseJSON<T>(value: string | null, defaultValue: T): T {\n if (value === null) return defaultValue;\n try {\n return JSON.parse(value);\n } catch {\n return defaultValue;\n }\n}\n\nexport function useSyncedLocalStorage<T>(\n key: string,\n initialValue: T,\n): [T, (value: T | ((val: T) => T)) => void] {\n // Initialize state function to avoid reading localStorage on every render\n const [storedValue, setStoredValue] = useState<T>(() => {\n if (typeof window === \"undefined\") {\n return initialValue;\n }\n try {\n const item = window.localStorage.getItem(key);\n return parseJSON(item, initialValue);\n } catch (error) {\n console.warn(`Error reading localStorage key \"${key}\":`, error);\n return initialValue;\n }\n });\n\n // Function to update state and localStorage\n const setValue = useCallback(\n (value: T | ((val: T) => T)) => {\n try {\n setStoredValue((prev) => {\n const valueToStore = value instanceof Function ? value(prev) : value;\n\n if (typeof window !== \"undefined\") {\n window.localStorage.setItem(key, JSON.stringify(valueToStore));\n // Dispatch a custom event so other hooks in the same window update\n window.dispatchEvent(\n new StorageEvent(\"storage\", { key, newValue: JSON.stringify(valueToStore) }),\n );\n }\n return valueToStore;\n });\n } catch (error) {\n console.warn(`Error setting localStorage key \"${key}\":`, error);\n }\n },\n [key],\n );\n\n // Sync across tabs/windows and within the same window\n useEffect(() => {\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key === key) {\n setStoredValue(parseJSON(event.newValue, initialValue));\n }\n };\n\n window.addEventListener(\"storage\", handleStorageChange);\n return () => window.removeEventListener(\"storage\", handleStorageChange);\n }, [key, initialValue]);\n\n return [storedValue, setValue];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBASO;;;ACTP,IAAAC,gBAAyD;AACzD,gCAAqD;;;ACD9C,IAAM,qBAAqB;AAC3B,IAAM,uBAAuB;AAE7B,IAAM,uBAAuB;AAC7B,IAAM,uBAAuB;;;ACJpC,mBAA6C;AAItC,IAAM,kBAAkB,CAC7B,SACA,aACA,gBAOA,kBACA,qBACA,gBACG;AACH,QAAM,oBAAgB,sBAAQ,MAAM,YAAY,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,WAAW,CAAC;AAEtF,QAAM,qBAAiB,qBAA4C;AAEnE,iBAAe,UAAU,CAAC,oBAAqC;AAC7D,QAAI,CAAC,oBAAoB,qBAAqB,sBAAsB;AAClE;AAAA,IACF;AAEA,mBAAe,CAAC,UAAU;AAAA,MACxB,GAAG;AAAA,MACH,CAAC,OAAO,GAAG;AAAA,QACT,GAAG,KAAK,OAAO;AAAA,QACf,CAAC,gBAAgB,GAAG;AAAA,UAClB,GAAG,KAAK,OAAO,IAAI,gBAAgB;AAAA,UACnC,UAAU,mBAAmB,YAAY;AAAA,UACzC,WAAW,KAAK,IAAI;AAAA,QACtB;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAEA,QAAM,sBAAsB,MAAM;AAChC,UAAM,WAAW,OAAO,OAAO,aAAa;AAC5C,QAAI,SAAS,SAAS,GAAG;AACvB,aAAO,SAAS,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,EAAE;AAAA,IAC/D;AACA,WAAO;AAAA,EACT;AAEA,QAAM,oBAAgB;AAAA,IACpB,CAAC,YAAoB,yBAAyB;AAC5C,0BAAoB,SAAS;AAAA,IAC/B;AAAA,IACA,CAAC,mBAAmB;AAAA,EACtB;AAEA,QAAM,oBAAgB;AAAA,IACpB,CAAC,cAAsB;AACrB,UAAI,CAAC,aAAa,cAAc,sBAAsB;AACpD;AAAA,MACF;AAEA,qBAAe,CAAC,SAAS;AACvB,cAAM,uBAAuB,EAAE,GAAG,KAAK,OAAO,EAAE;AAChD,eAAO,qBAAqB,SAAS;AAErC,eAAO;AAAA,UACL,GAAG;AAAA,UACH,CAAC,OAAO,GAAG;AAAA,QACb;AAAA,MACF,CAAC;AAED,UAAI,cAAc,kBAAkB;AAClC,cAAM,oBAAoB,OAAO,OAAO,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS;AACvF,YAAI,kBAAkB,SAAS,GAAG;AAChC,gBAAM,aAAa,kBAAkB,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AAChF,8BAAoB,WAAW,EAAE;AAAA,QACnC,OAAO;AACL,8BAAoB,oBAAoB;AAAA,QAC1C;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS,kBAAkB,eAAe,gBAAgB,mBAAmB;AAAA,EAChF;AAEA,QAAM,mBAAe;AAAA,IACnB,MAAM,OAAO,OAAO,aAAa,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAAA,IAC3E,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,4BAA4B,CAChC,WACA,aACA,oBACG;AACH,mBAAe,CAAC,UAAU;AAAA,MACxB,GAAG;AAAA,MACH,CAAC,OAAO,GAAG;AAAA,QACT,GAAG,KAAK,OAAO;AAAA,QACf,CAAC,SAAS,GAAG;AAAA,UACX,IAAI;AAAA,UACJ,WAAW,KAAK,IAAI;AAAA,UACpB,WAAW,KAAK,IAAI;AAAA,UACpB,UAAU;AAAA,UACV,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACzGO,IAAM,sBAAsB,CACjC,iBAKG;AACH,QAAM,kCAAkC,CAAC,WAAgC;AACvE,UAAM,cAAc,OAAO,KAAK;AAChC,iBAAa,CAAC,UAAU;AAAA,MACtB,GAAG;AAAA,MACH,CAAC,WAAW,GAAG;AAAA,QACb,GAAI,KAAK,WAAW,KAAK,CAAC;AAAA,QAC1B;AAAA,UACE,UAAU;AAAA,UACV,QAAS,OAAO,KAA6B,UAAU;AAAA,UACvD,YAAa,OAAO,KAAiC;AAAA,UACrD,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAEA,QAAM,iCAAiC,CAAC,WAAgC;AACtE,UAAM,cAAc,OAAO,KAAK;AAChC,UAAM,aAAc,OAAO,KAAiC;AAC5D,iBAAa,CAAC,SAAS;AACrB,YAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,eAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAI,YAAY,CAAC,EAAE,aAAa,aAAa;AAC3C,gBAAM,WAAW,YAAY,CAAC;AAC9B,cAAI,SAAS,eAAe,YAAY;AACtC,wBAAY,CAAC,IAAI;AAAA,cACf,GAAG;AAAA,cACH,QAAS,OAAO,KAA4B;AAAA,YAC9C;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,WAAW,GAAG;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,mCAAmC,CAAC,WAAgC;AACxE,UAAM,cAAc,OAAO,KAAK;AAChC,UAAM,aAAc,OAAO,KAAiC;AAC5D,iBAAa,CAAC,SAAS;AACrB,YAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,eAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAI,YAAY,CAAC,EAAE,aAAa,aAAa;AAC3C,gBAAM,WAAW,YAAY,CAAC;AAC9B,cAAI,SAAS,eAAe,YAAY;AACtC,wBAAY,CAAC,IAAI;AAAA,cACf,GAAG;AAAA,cACH,QAAQ;AAAA,cACR,QAAS,OAAO,KAA4B;AAAA,YAC9C;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,WAAW,GAAG;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,gCAAgC,CAAC,WAAgC;AACrE,UAAM,cAAc,OAAO,KAAK;AAChC,UAAM,aAAc,OAAO,KAAiC;AAC5D,iBAAa,CAAC,SAAS;AACrB,YAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,eAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAI,YAAY,CAAC,EAAE,aAAa,aAAa;AAC3C,gBAAM,WAAW,YAAY,CAAC;AAC9B,cAAI,SAAS,eAAe,YAAY;AACtC,wBAAY,CAAC,IAAI;AAAA,cACf,GAAG;AAAA,cACH,QAAQ;AAAA,cACR,QAAS,OAAO,KAA4B;AAAA,YAC9C;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,WAAW,GAAG;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,qBAAqB,CAAC,WAAgC;AAC1D,UAAM,cAAc,OAAO,KAAK;AAChC,UAAM,aAAc,OAAO,KAAiC;AAC5D,iBAAa,CAAC,SAAS;AACrB,YAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,eAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAI,YAAY,CAAC,EAAE,aAAa,aAAa;AAC3C,gBAAM,WAAW,YAAY,CAAC;AAC9B,cAAI,SAAS,eAAe,YAAY;AACtC,kBAAM,cAAc,SAAS,QAAQ,CAAC;AACtC,wBAAY,CAAC,IAAI;AAAA,cACf,GAAG;AAAA,cACH,MAAM,CAAC,GAAG,aAAc,OAAO,KAA8B,MAAM,CAAC,CAAC;AAAA,YACvE;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,WAAW,GAAG;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,qBAAqB;AACzB,QAAM,2BAA2B,CAAC,WAAuC;AACvE,UAAM,cAAc,OAAO,KAAK;AAChC,UAAM,EAAE,OAAO,MAAM,IAAI,OAAO;AAChC,iBAAa,CAAC,SAAS;AACrB,YAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,UAAI,qBAAqB,OAAO;AAC9B,oBAAY,KAAK,EAAE,UAAU,aAAa,WAAW,GAAG,CAAC;AACzD,6BAAqB;AAAA,MACvB;AAEA,eAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAI,YAAY,CAAC,EAAE,aAAa,aAAa;AAC3C,sBAAY,CAAC,IAAI;AAAA,YACf,UAAU;AAAA,YACV,WAAY,YAAY,CAAC,EAAoB,YAAY;AAAA,UAC3D;AACA;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,WAAW,GAAG;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,qBAAqB,CAAC,WAAkC;AAC5D,UAAM,cAAc,OAAO,KAAK;AAChC,iBAAa,CAAC,UAAU;AAAA,MACtB,GAAG;AAAA,MACH,CAAC,WAAW,GAAG;AAAA,QACb,GAAI,KAAK,WAAW,KAAK,CAAC;AAAA,QAC1B;AAAA,UACE,UAAU;AAAA,UACV,WAAW,OAAO,KAAK;AAAA,QACzB;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAEA,QAAM,yBAAyB,CAAC,WAAsC;AACpE,UAAM,cAAc,OAAO,KAAK;AAChC,iBAAa,CAAC,UAAU;AAAA,MACtB,GAAG;AAAA,MACH,CAAC,WAAW,GAAG;AAAA,QACb,GAAI,KAAK,WAAW,KAAK,CAAC;AAAA,QAC1B;AAAA,UACE,UAAU;AAAA,UACV,UAAU,OAAO,KAAK;AAAA,UACtB,YAAY,OAAO,KAAK;AAAA,UACxB,QAAQ,OAAO,KAAK;AAAA,UACpB,QAAQ;AAAA,UACR,QAAQ,OAAO,KAAK;AAAA,QACtB;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAEA,QAAM,uBAAuB,CAAC,WAAoC;AAChE,UAAM,cAAc,OAAO,KAAK;AAChC,UAAM,SAAS,OAAO,KAAK;AAC3B,iBAAa,CAAC,SAAS;AACrB,YAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,eAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAI,YAAY,CAAC,EAAE,aAAa,iBAAiB;AAC/C,gBAAM,cAAc,YAAY,CAAC;AACjC,cAAI,YAAY,WAAW,QAAQ;AACjC,wBAAY,CAAC,IAAI;AAAA,cACf,GAAG;AAAA,cACH,QAAQ,OAAO,KAAK,QAAQ,UAAU;AAAA,cACtC,QAAQ,OAAO,KAAK;AAAA,cACpB,OAAO,OAAO,KAAK;AAAA,YACrB;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,WAAW,GAAG;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,mBAAmB,CACvB,WAMG;AACH,YAAQ,OAAO,MAAM;AAAA,MACnB,KAAK;AACH,wCAAgC,MAAM;AACtC;AAAA,MACF,KAAK;AACH,uCAA+B,MAAM;AACrC;AAAA,MACF,KAAK;AACH,yCAAiC,MAAM;AACvC;AAAA,MACF,KAAK;AACH,sCAA8B,MAAM;AACpC;AAAA,MACF,KAAK;AACH,2BAAmB,MAAM;AACzB;AAAA,MACF,KAAK;AACH,iCAAyB,MAAM;AAC/B;AAAA,MACF,KAAK;AACH,2BAAmB,MAAM;AACzB;AAAA,MACF,KAAK;AACH,+BAAuB,MAAM;AAC7B;AAAA,MACF,KAAK;AACH,6BAAqB,MAAM;AAC3B;AAAA,IACJ;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,EACF;AACF;;;AC7QO,SAAS,YAAY,KAAuB;AACjD,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAO,IAAI,IAAI,WAAW;AAAA,EAC5B,WAAW,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAClD,UAAM,SAAkC,CAAC;AACzC,UAAM,aAAa;AAEnB,eAAW,OAAO,YAAY;AAE5B,UAAI,QAAQ,mBAAmB,QAAQ,WAAW;AAChD;AAAA,MACF;AACA,aAAO,GAAG,IAAI,YAAY,WAAW,GAAG,CAAC;AAAA,IAC3C;AAIA,QAAI,OAAO,SAAS,UAAU;AAC5B,UACE,OAAO,yBAAyB,UAC/B,OAAO,wBACN,OAAO,OAAO,yBAAyB,YACvC,OAAO,KAAK,OAAO,oBAAoB,EAAE,WAAW,GACtD;AACA,eAAO,uBAAuB;AAAA,MAChC;AAEA,UAAI,OAAO,yBAAyB,SAAS,OAAO,YAAY;AAC9D,eAAO,WAAW,OAAO,KAAK,OAAO,UAAoB;AAAA,MAC3D;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKO,SAAS,aAAa,OAAqB;AAChD,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI;AACF,aAAO,KAAK,MAAM,KAAK;AAAA,IACzB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;;;AChDO,SAAS,wBAAwB,OAAsB,SAAqC;AAEjG,QAAM,SAAS,CAAC,GAAG,OAAO,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM;AAChD,UAAM,SAAS,EAAE,SAAS,SAAS,EAAE,gBAAgB,EAAE;AACvD,UAAM,SAAS,EAAE,SAAS,SAAS,EAAE,gBAAgB,EAAE;AACvD,WAAO,SAAS;AAAA,EAClB,CAAC;AAGD,SAAO,OAAO,OAAsB,CAAC,KAAK,YAAY;AACpD,UAAM,OAAO,IAAI,IAAI,SAAS,CAAC;AAG/B,UAAM,WACJ,MAAM,SAAS,UACf,QAAQ,SAAS,UACjB,QAAQ,kBAAkB,KAAK,eAAe;AAEhD,QAAI,UAAU;AACZ,UAAI,IAAI,SAAS,CAAC,IAAI;AAAA,QACpB,GAAG;AAAA,QACH,MAAM,KAAK,OAAO,QAAQ;AAAA,QAC1B,cAAc,QAAQ;AAAA,MACxB;AACA,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,OAAO;AAChB,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACP;;;ALjBA,IAAM,mBAAN,cAA+B,MAAM;AAAA,EACnC,YAAmB,WAA0C;AAC3D,UAAM,cAAc;AADH;AAEjB,SAAK,OAAO;AAAA,EACd;AACF;AAEe,SAAR,SAA0B,SAAiB,UAAkB,WAAoB;AAEtF,QAAM,EAAE,aAAa,gBAAgB,WAAW,aAAa,IAAI,oBAAoB;AAErF,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAS,KAAK;AAClD,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAyB,CAAC,CAAC;AAC3D,QAAM,CAAC,kBAAkB,mBAAmB,QAAI,wBAAuC,oBAAI,IAAI,CAAC;AAChG,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAS,KAAK;AAE9C,QAAM,kBAAc,sBAAuB,CAAC,CAAC;AAC7C,QAAM,qBAAiB,sBAA+B,CAAC,CAAC;AAGxD,QAAM,CAAC,kBAAkB,mBAAmB,QAAI,wBAAiB,oBAAoB;AAErF,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,+BAAU,MAAM;AACd,UAAM,mBAAmB,aAAa,oBAAoB;AAC1D,wBAAoB,gBAAgB;AAAA,EACtC,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgB,oBAAoB,YAAY;AAGtD,+BAAU,MAAM;AACd,gBAAY,UAAU;AAAA,EACxB,GAAG,CAAC,QAAQ,CAAC;AAGb,+BAAU,MAAM;AAEd,QAAI,YAAY;AACd;AAAA,IACF;AAEA,UAAM,UAAU,aAAa,cAAc,gBAAgB;AAE3D,QAAI,SAAS;AACX,kBAAY,QAAQ,QAAQ;AAAA,IAC9B,OAAO;AACL,kBAAY,CAAC,CAAC;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,kBAAkB,aAAa,eAAe,SAAS,UAAU,CAAC;AAGtE,+BAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,YAAY,QAAQ,SAAS,KAAK,aAAa,eAAe,SAAS;AACzE,qBAAa,eAAe,QAAQ;AAAA,MACtC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAa,sBAAwB;AAE3C,QAAM,eAAW;AAAA,IACf,OACE,OACA,YAOG;AACH,oBAAc,IAAI;AAElB,UAAI,WAAW,SAAS;AACtB,mBAAW,QAAQ,MAAM;AAAA,MAC3B;AACA,iBAAW,UAAU,IAAI,gBAAgB;AAEzC,YAAM,UAAkC;AAAA,QACtC,gBAAgB;AAAA,QAChB,GAAI,SAAS,qBAAqB,CAAC;AAAA,QACnC,GAAI,YAAY,EAAE,eAAe,UAAU,SAAS,GAAG,IAAI,CAAC;AAAA,MAC9D;AAGA,UAAI,kBAAkB;AACpB,gBAAQ,8BAA8B,IAAI;AAAA,MAC5C;AAEA,YAAM,OAAO;AAAA,QACX,QAAQ;AAAA,QACR;AAAA,QACA,SAAS,SAAS,WAAW,CAAC;AAAA,QAC9B,aAAa,SAAS;AAAA,QACtB,OAAO,SAAS,OAAO,IAAI,CAAC,OAAgC;AAAA,UAC1D,GAAG;AAAA,UACH,YAAY,YAAY,EAAE,UAAU;AAAA,QACtC,EAAE;AAAA,QACF,aAAa,SAAS,aAAa,IAAI,CAAC,OAAO;AAAA,UAC7C,GAAG;AAAA,UACH,YAAY,YAAY,EAAE,UAAU;AAAA,UACpC,gBAAgB,EAAE,kBAAgB;AAAA,QACpC,EAAE;AAAA,MACJ;AAEA,UAAI;AACF,kBAAM,4CAAiB,UAAU;AAAA,UAC/B,QAAQ;AAAA,UACR;AAAA,UACA,QAAQ,WAAW,QAAQ;AAAA,UAC3B,gBAAgB;AAAA,UAChB,MAAM,KAAK,UAAU,IAAI;AAAA,UACzB,QAAQ,OAAO,SAAS;AAEtB,gBAAI,KAAK,UAAU,KAAK;AACtB,sBAAQ,IAAI,gCAAgC,KAAK,MAAM,EAAE;AAEzD,kBAAI,KAAK,WAAW,KAAK;AAEvB,sBAAM,IAAI,MAAM,cAAc,KAAK,UAAU,GAAG;AAAA,cAClD;AAEA,oBAAM,IAAI,MAAM,gBAAgB,KAAK,MAAM,EAAE;AAAA,YAC/C;AAGA,gBAAI,CAAC,oBAAoB,qBAAqB,sBAAsB;AAClE,oBAAM,YAAY,KAAK,QAAQ,IAAI,8BAA8B;AACjE,kBAAI,WAAW;AAEb,sBAAM,kBAAkB,YAAY;AACpC,sBAAM,cACJ,KAAK,QAAQ,IAAI,gCAAgC,KAAK;AAExD,6BAAa,0BAA0B,WAAW,aAAa,eAAe;AAC9E,oCAAoB,SAAS;AAAA,cAC/B;AAAA,YACF;AAEA,gBAAI,KAAK,QAAQ,IAAI,cAAc,GAAG,SAAS,kBAAkB,GAAG;AAClE,oBAAM,OAAQ,MAAM,KAAK,KAAK;AAC9B,kBAAI,KAAK,QAAQ,GAAG,QAAQ;AAG1B,4BAAY,CAAC,SAAS;AACpB,wBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,wBAAM,WAA0B,KAAK,OAAO,cAAc,IAAI,CAAC,QAAQ,WAAW;AAAA,oBAChF,MAAM;AAAA,oBACN,UAAU,OAAO;AAAA,oBACjB,QAAQ,OAAO;AAAA,oBACf,QAAQ,OAAO;AAAA,oBACf,WAAW,aAAa,OAAO,UAAU,KAAK;AAAA,kBAChD,EAAE;AAEF,sBAAI;AAEJ,sBAAI,aAAa,SAAS,SAAS;AACjC,0BAAM,iBAA0B;AAAA,sBAC9B,GAAG;AAAA,sBACH,OAAO,CAAC,GAAI,YAAY,SAAS,CAAC,GAAI,GAAG,QAAQ;AAAA,oBACnD;AACA,sCAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,kBACzD,OAAO;AACL,0BAAM,iBAA0B;AAAA,sBAC9B,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,OAAO;AAAA,sBACP,aAAa,KAAK,IAAI,EAAE,SAAS;AAAA;AAAA,oBACnC;AACA,sCAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,kBAC5C;AAEA,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT,CAAC;AAED,oCAAoB,CAAC,SAAS;AAC5B,wBAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,uBAAK,OAAO,cAAc,QAAQ,CAAC,WAAW;AAC5C,4BAAQ,IAAI,OAAO,QAAQ;AAAA,sBACzB,UAAU,OAAO;AAAA,sBACjB,QAAQ,OAAO;AAAA,sBACf,QAAQ,OAAO;AAAA,sBACf,gBAAgB;AAAA;AAAA,oBAClB,CAAC;AAAA,kBACH,CAAC;AACD,yBAAO;AAAA,gBACT,CAAC;AAED,4BAAY,IAAI;AAChB,sBAAM,IAAI,iBAAiB,KAAK,MAAM;AAAA,cACxC;AAAA,YACF;AAGA,kBAAM,cAAc,KAAK,QAAQ,IAAI,gCAAgC;AACrE,gBAAI,aAAa;AACf,0BAAY,CAAC,SAAS;AACpB,sBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,oBAAI,aAAa,SAAS,QAAQ;AAChC,wBAAM,iBAAiB;AAAA,oBACrB,GAAG;AAAA,oBACH;AAAA,kBACF;AACA,wBAAM,kBAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAG7D,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT;AACA,uBAAO;AAAA,cACT,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UACA,WAAW,CAAC,UAA8B;AACxC,gBAAI;AACF,oBAAM,SAAS,KAAK,MAAM,MAAM,IAAI;AAEpC,kBAAI,OAAO,SAAS,kBAAkB;AACpC,4BAAY,CAAC,SAAS;AACpB,wBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,wBAAM,WAAW,OAAO,KAAK;AAC7B,wBAAM,UAAuB;AAAA,oBAC3B,MAAM;AAAA,oBACN,MAAM,OAAO;AAAA,oBACb,eAAe;AAAA,oBACf,cAAc;AAAA,kBAChB;AAEA,sBAAI;AAEJ,sBAAI,aAAa,SAAS,SAAS;AACjC,0BAAM,iBAA0B;AAAA,sBAC9B,GAAG;AAAA,sBACH,SAAS,YAAY,UAAU,OAAO;AAAA;AAAA,sBACtC,OAAO,wBAAwB,YAAY,SAAS,CAAC,GAAG,OAAO;AAAA,oBACjE;AACA,sCAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,kBACzD,OAAO;AACL,0BAAM,iBAA0B;AAAA,sBAC9B,MAAM;AAAA,sBACN,SAAS,OAAO;AAAA,sBAChB,OAAO,CAAC,OAAO;AAAA,sBACf,aAAa,OAAO,KAAK;AAAA,oBAC3B;AACA,sCAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,kBAC5C;AAEA,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT,CAAC;AAAA,cACH,WAAW,OAAO,SAAS,oBAAoB;AAC7C,sBAAM,EAAE,UAAU,QAAQ,OAAO,IAAI,OAAO;AAG5C,sBAAM,iBAAiB,eAAe,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAC7E,sBAAM,iBAAiB,gBAAgB,kBAAkB;AAGzD,oBAAI,gBAAgB;AAClB,sCAAoB,CAAC,SAAS;AAC5B,0BAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,4BAAQ,IAAI,QAAQ;AAAA,sBAClB;AAAA,sBACA;AAAA,sBACA,QAAQ,aAAa,MAAM;AAAA,sBAC3B;AAAA,oBACF,CAAC;AACD,2BAAO;AAAA,kBACT,CAAC;AAAA,gBACH;AAEA,4BAAY,CAAC,SAAS;AACpB,wBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,wBAAM,UAAuB;AAAA,oBAC3B,MAAM;AAAA,oBACN;AAAA,oBACA;AAAA,oBACA,QAAQ,aAAa,MAAM;AAAA,oBAC3B,UAAU,OAAO,KAAK;AAAA,kBACxB;AAEA,sBAAI;AAEJ,sBAAI,aAAa,SAAS,SAAS;AACjC,0BAAM,iBAA0B;AAAA,sBAC9B,GAAG;AAAA,sBACH,OAAO,wBAAwB,YAAY,SAAS,CAAC,GAAG,OAAO;AAAA,oBACjE;AACA,sCAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,kBACzD,OAAO;AACL,0BAAM,iBAA0B;AAAA,sBAC9B,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,OAAO,CAAC,OAAO;AAAA,sBACf,aAAa,OAAO,KAAK;AAAA,oBAC3B;AACA,sCAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,kBAC5C;AAEA,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT,CAAC;AAAA,cACH,WACE,OAAO,KAAK,WAAW,QAAQ,KAC/B,OAAO,SAAS,yBAChB,OAAO,SAAS,mBAChB,OAAO,SAAS,yBAChB,OAAO,SAAS,qBAChB;AACA,8BAAc,iBAAiB,MAAM;AAAA,cACvC;AAAA,YACF,SAAS,GAAG;AACV,sBAAQ,IAAI,iCAAiC,CAAC;AAAA,YAChD;AAAA,UACF;AAAA,UACA,SAAS,MAAM;AACb,oBAAQ,IAAI,cAAc;AAC1B,0BAAc,KAAK;AAGnB,gCAAoB,CAAC,mBAAmB;AACtC,kBAAI,eAAe,OAAO,GAAG;AAC3B,4BAAY,IAAI;AAAA,cAClB;AACA,qBAAO;AAAA,YACT,CAAC;AAGD,gBAAI,aAAa,eAAe,SAAS;AACvC,2BAAa,eAAe,QAAQ;AAAA,YACtC;AAAA,UACF;AAAA,UACA,SAAS,CAAC,MAAM;AACd,gBAAI,aAAa,kBAAkB;AACjC,oBAAM;AAAA,YACR;AACA,oBAAQ,IAAI,eAAe,CAAC;AAC5B,0BAAc,KAAK;AAEnB,gBAAI,aAAa,eAAe,SAAS;AACvC,2BAAa,eAAe,QAAQ,YAAY,OAAO;AAAA,YACzD;AACA,kBAAM,IAAI,MAAM,yBAAyB;AAAA,UAC3C;AAAA,QACF,CAAC;AAAA,MACH,SAAS,OAAO;AACd,YAAI,iBAAiB,kBAAkB;AACrC,wBAAc,KAAK;AACnB;AAAA,QACF;AACA,gBAAQ,IAAI,0BAA0B,KAAK;AAC3C,sBAAc,KAAK;AAEnB,YAAI,aAAa,eAAe,SAAS;AACvC,uBAAa,eAAe,QAAQ,YAAY,OAAO;AAAA,QACzD;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,UAAU,WAAW,kBAAkB,cAAc,aAAa;AAAA,EACrE;AAEA,QAAM,kBAAc;AAAA,IAClB,OACE,aACA,YAKG;AACH,UAAI,CAAC,oBAAoB,qBAAqB,sBAAsB;AAClE,cAAM,IAAI,MAAM,kCAAkC;AAAA,MACpD;AAEA,oBAAc,IAAI;AAClB,kBAAY,KAAK;AAGjB,UAAI,WAAW,SAAS;AACtB,mBAAW,QAAQ,MAAM;AAAA,MAC3B;AACA,iBAAW,UAAU,IAAI,gBAAgB;AAEzC,YAAM,UAAkC;AAAA,QACtC,gBAAgB;AAAA,QAChB,GAAI,SAAS,qBAAqB,CAAC;AAAA,QACnC,GAAI,YAAY,EAAE,eAAe,UAAU,SAAS,GAAG,IAAI,CAAC;AAAA,MAC9D;AAGA,YAAM,UAAU,SAAS,QAAQ,uBAAuB,EAAE;AAC1D,YAAM,YAAY,GAAG,OAAO,gBAAgB,OAAO,IAAI,gBAAgB;AAEvE,YAAM,OAAO;AAAA,QACX,QAAQ;AAAA,QACR,OAAO,SAAS,SAAS;AAAA,QACzB,SAAS,SAAS,WAAW,CAAC;AAAA,QAC9B,mBAAmB;AAAA,MACrB;AAEA,UAAI;AACF,kBAAM,4CAAiB,WAAW;AAAA,UAChC,QAAQ;AAAA,UACR;AAAA,UACA,QAAQ,WAAW,QAAQ;AAAA,UAC3B,gBAAgB;AAAA,UAChB,MAAM,KAAK,UAAU,IAAI;AAAA,UACzB,QAAQ,OAAO,SAAS;AACtB,gBAAI,KAAK,UAAU,KAAK;AACtB,sBAAQ,IAAI,gCAAgC,KAAK,MAAM,EAAE;AAEzD,kBAAI,KAAK,WAAW,KAAK;AACvB,sBAAM,IAAI,MAAM,sBAAsB,KAAK,UAAU,GAAG;AAAA,cAC1D;AAEA,oBAAM,IAAI,MAAM,gBAAgB,KAAK,MAAM,EAAE;AAAA,YAC/C;AAEA,gBAAI,KAAK,QAAQ,IAAI,cAAc,GAAG,SAAS,kBAAkB,GAAG;AAClE,oBAAM,OAAQ,MAAM,KAAK,KAAK;AAC9B,kBAAI,KAAK,QAAQ,GAAG,QAAQ;AAG1B,4BAAY,CAAC,SAAS;AACpB,wBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,wBAAM,WAA0B,KAAK,OAAO,cAAc,IAAI,CAAC,QAAQ,WAAW;AAAA,oBAChF,MAAM;AAAA,oBACN,UAAU,OAAO;AAAA,oBACjB,QAAQ,OAAO;AAAA,oBACf,QAAQ,OAAO;AAAA,oBACf,WAAW,aAAa,OAAO,UAAU,KAAK;AAAA,kBAChD,EAAE;AAEF,sBAAI;AAEJ,sBAAI,aAAa,SAAS,SAAS;AACjC,0BAAM,iBAA0B;AAAA,sBAC9B,GAAG;AAAA,sBACH,OAAO,CAAC,GAAI,YAAY,SAAS,CAAC,GAAI,GAAG,QAAQ;AAAA,oBACnD;AACA,sCAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,kBACzD,OAAO;AACL,0BAAM,iBAA0B;AAAA,sBAC9B,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,OAAO;AAAA,sBACP,aAAa,KAAK,IAAI,EAAE,SAAS;AAAA,oBACnC;AACA,sCAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,kBAC5C;AAEA,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT,CAAC;AAED,oCAAoB,CAAC,SAAS;AAC5B,wBAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,uBAAK,OAAO,cAAc,QAAQ,CAAC,WAAW;AAC5C,4BAAQ,IAAI,OAAO,QAAQ;AAAA,sBACzB,UAAU,OAAO;AAAA,sBACjB,QAAQ,OAAO;AAAA,sBACf,QAAQ,OAAO;AAAA,sBACf,gBAAgB;AAAA,oBAClB,CAAC;AAAA,kBACH,CAAC;AACD,yBAAO;AAAA,gBACT,CAAC;AAED,4BAAY,IAAI;AAChB,sBAAM,IAAI,iBAAiB,KAAK,MAAM;AAAA,cACxC;AAAA,YACF;AAGA,kBAAM,cAAc,KAAK,QAAQ,IAAI,gCAAgC;AACrE,gBAAI,eAAe,SAAS,OAAO;AAEjC,0BAAY,CAAC,SAAS;AACpB,sBAAM,cAAuB;AAAA,kBAC3B,MAAM;AAAA,kBACN,SAAS,QAAQ,SAAS;AAAA,kBAC1B;AAAA,gBACF;AACA,sBAAM,kBAAkB,CAAC,GAAG,MAAM,WAAW;AAE7C,oBAAI,aAAa,eAAe,SAAS;AACvC,+BAAa,eAAe,QAAQ,eAAe;AAAA,gBACrD;AAEA,uBAAO;AAAA,cACT,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UACA,WAAW,CAAC,UAA8B;AACxC,gBAAI;AACF,oBAAM,SAAS,KAAK,MAAM,MAAM,IAAI;AAEpC,kBAAI,OAAO,SAAS,kBAAkB;AACpC,4BAAY,CAAC,SAAS;AACpB,wBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,wBAAM,WAAW,OAAO,KAAK;AAC7B,wBAAM,UAAuB;AAAA,oBAC3B,MAAM;AAAA,oBACN,MAAM,OAAO;AAAA,oBACb,eAAe;AAAA,oBACf,cAAc;AAAA,kBAChB;AAEA,sBAAI;AAEJ,sBAAI,aAAa,SAAS,SAAS;AACjC,0BAAM,iBAA0B;AAAA,sBAC9B,GAAG;AAAA,sBACH,SAAS,YAAY,UAAU,OAAO;AAAA,sBACtC,OAAO,wBAAwB,YAAY,SAAS,CAAC,GAAG,OAAO;AAAA,oBACjE;AACA,sCAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,kBACzD,OAAO;AACL,0BAAM,iBAA0B;AAAA,sBAC9B,MAAM;AAAA,sBACN,SAAS,OAAO;AAAA,sBAChB,OAAO,CAAC,OAAO;AAAA,sBACf,aAAa,OAAO,KAAK;AAAA,oBAC3B;AACA,sCAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,kBAC5C;AAEA,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT,CAAC;AAAA,cACH,WAAW,OAAO,SAAS,oBAAoB;AAC7C,sBAAM,EAAE,UAAU,QAAQ,OAAO,IAAI,OAAO;AAG5C,sBAAM,iBAAiB,eAAe,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAC7E,sBAAM,iBAAiB,gBAAgB,kBAAkB;AAGzD,oBAAI,gBAAgB;AAClB,sCAAoB,CAAC,SAAS;AAC5B,0BAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,4BAAQ,IAAI,QAAQ;AAAA,sBAClB;AAAA,sBACA;AAAA,sBACA,QAAQ,aAAa,MAAM;AAAA,sBAC3B;AAAA,oBACF,CAAC;AACD,2BAAO;AAAA,kBACT,CAAC;AAAA,gBACH;AAEA,4BAAY,CAAC,SAAS;AACpB,wBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,wBAAM,UAAuB;AAAA,oBAC3B,MAAM;AAAA,oBACN;AAAA,oBACA;AAAA,oBACA,QAAQ,aAAa,MAAM;AAAA,oBAC3B,UAAU,OAAO,KAAK;AAAA,kBACxB;AAEA,sBAAI;AAEJ,sBAAI,aAAa,SAAS,SAAS;AACjC,0BAAM,iBAA0B;AAAA,sBAC9B,GAAG;AAAA,sBACH,OAAO,wBAAwB,YAAY,SAAS,CAAC,GAAG,OAAO;AAAA,oBACjE;AACA,sCAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,kBACzD,OAAO;AACL,0BAAM,iBAA0B;AAAA,sBAC9B,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,OAAO,CAAC,OAAO;AAAA,sBACf,aAAa,OAAO,KAAK;AAAA,oBAC3B;AACA,sCAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,kBAC5C;AAEA,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT,CAAC;AAAA,cACH,WACE,OAAO,KAAK,WAAW,QAAQ,KAC/B,OAAO,SAAS,yBAChB,OAAO,SAAS,mBAChB,OAAO,SAAS,yBAChB,OAAO,SAAS,qBAChB;AACA,8BAAc,iBAAiB,MAAM;AAAA,cACvC;AAAA,YACF,SAAS,GAAG;AACV,sBAAQ,IAAI,iCAAiC,CAAC;AAAA,YAChD;AAAA,UACF;AAAA,UACA,SAAS,MAAM;AACb,oBAAQ,IAAI,qBAAqB;AACjC,0BAAc,KAAK;AAGnB,gCAAoB,CAAC,mBAAmB;AACtC,kBAAI,eAAe,OAAO,GAAG;AAC3B,4BAAY,IAAI;AAAA,cAClB;AACA,qBAAO;AAAA,YACT,CAAC;AAGD,gBAAI,aAAa,eAAe,SAAS;AACvC,2BAAa,eAAe,QAAQ;AAAA,YACtC;AAAA,UACF;AAAA,UACA,SAAS,CAAC,MAAM;AACd,gBAAI,aAAa,kBAAkB;AACjC,oBAAM;AAAA,YACR;AACA,oBAAQ,IAAI,sBAAsB,CAAC;AACnC,0BAAc,KAAK;AAEnB,gBAAI,aAAa,eAAe,SAAS;AACvC,2BAAa,eAAe,QAAQ,YAAY,OAAO;AAAA,YACzD;AACA,kBAAM,IAAI,MAAM,wBAAwB;AAAA,UAC1C;AAAA,QACF,CAAC;AAAA,MACH,SAAS,OAAO;AACd,YAAI,iBAAiB,kBAAkB;AACrC,wBAAc,KAAK;AACnB;AAAA,QACF;AACA,gBAAQ,IAAI,iCAAiC,KAAK;AAClD,sBAAc,KAAK;AAEnB,YAAI,aAAa,eAAe,SAAS;AACvC,uBAAa,eAAe,QAAQ,YAAY,OAAO;AAAA,QACzD;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,UAAU,WAAW,kBAAkB,cAAc,aAAa;AAAA,EACrE;AAEA,QAAM,iBAAa;AAAA,IACjB,OACE,OACA,YAQG;AAEH,UAAI,SAAS,aAAa;AACxB,uBAAe,UAAU,QAAQ;AAAA,MACnC;AAGA,0BAAoB,oBAAI,IAAI,CAAC;AAC7B,kBAAY,KAAK;AAEjB,YAAM,cAAc;AAAA,QAClB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aAAa,KAAK,IAAI,EAAE,SAAS;AAAA,MACnC;AAGA,UAAI,CAAC,SAAS,iBAAiB;AAC7B,oBAAY,CAAC,SAAS;AACpB,gBAAM,kBAAkB,CAAC,GAAG,MAAM,WAAW;AAE7C,cAAI,aAAa,eAAe,SAAS;AACvC,yBAAa,eAAe,QAAQ,eAAe;AAAA,UACrD;AACA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAEA,UAAI;AACF,cAAM,SAAS,OAAO,OAAO;AAAA,MAC/B,SAAS,OAAO;AAEd,YAAI,CAAC,SAAS,iBAAiB;AAC7B,sBAAY,CAAC,SAAS;AACpB,kBAAM,kBAAkB,KAAK,KAAK,CAAC,MAAM,MAAM,WAAW,IACtD,OACA,CAAC,GAAG,MAAM,WAAW;AACzB,gBAAI,aAAa,eAAe,SAAS;AACvC,2BAAa,eAAe,QAAQ,eAAe;AAAA,YACrD;AACA,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,UAAU,aAAa,cAAc;AAAA,EACxC;AAEA,QAAM,2BAAuB;AAAA,IAC3B,CAAC,UAAkB;AACjB,YAAM,cAAc;AAAA,QAClB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aAAa,KAAK,IAAI,EAAE,SAAS;AAAA,MACnC;AAEA,kBAAY,CAAC,SAAS;AACpB,cAAM,kBAAkB,CAAC,GAAG,MAAM,WAAW;AAE7C,YAAI,aAAa,eAAe,SAAS;AACvC,uBAAa,eAAe,QAAQ,eAAe;AAAA,QACrD;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAAC,aAAa,cAAc;AAAA,EAC9B;AAEA,QAAM,wBAAoB;AAAA,IACxB,OACE,aACA,YAKG;AAEH,0BAAoB,CAAC,SAAS;AAC5B,cAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,oBAAY,QAAQ,CAAC,WAAW;AAC9B,kBAAQ,OAAO,OAAO,MAAM;AAAA,QAC9B,CAAC;AACD,eAAO;AAAA,MACT,CAAC;AAED,UAAI;AACF,cAAM,YAAY,aAAa,OAAO;AAAA,MACxC,SAAS,OAAO;AACd,gBAAQ,MAAM,kCAAkC,KAAK;AACrD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,QAAM,YAAQ,2BAAY,MAAM;AAC9B,QAAI,WAAW,SAAS;AACtB,iBAAW,QAAQ,MAAM;AAAA,IAC3B;AACA,kBAAc,KAAK;AAEnB,QAAI,aAAa,eAAe,SAAS;AACvC,mBAAa,eAAe,QAAQ,YAAY,OAAO;AAAA,IACzD;AAAA,EACF,GAAG,CAAC,aAAa,cAAc,CAAC;AAEhC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,eAAe,aAAa;AAAA,IAC5B,eAAe,aAAa;AAAA,IAC5B,UAAU,aAAa;AAAA,IACvB;AAAA,IACA,kBAAkB,MAAM,KAAK,iBAAiB,OAAO,CAAC;AAAA,IACtD;AAAA,EACF;AACF;;;AM7zBA,IAAAC,gBAAiD;AAGjD,SAAS,UAAa,OAAsB,cAAoB;AAC9D,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI;AACF,WAAO,KAAK,MAAM,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,sBACd,KACA,cAC2C;AAE3C,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAY,MAAM;AACtD,QAAI,OAAO,WAAW,aAAa;AACjC,aAAO;AAAA,IACT;AACA,QAAI;AACF,YAAM,OAAO,OAAO,aAAa,QAAQ,GAAG;AAC5C,aAAO,UAAU,MAAM,YAAY;AAAA,IACrC,SAAS,OAAO;AACd,cAAQ,KAAK,mCAAmC,GAAG,MAAM,KAAK;AAC9D,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAGD,QAAM,eAAW;AAAA,IACf,CAAC,UAA+B;AAC9B,UAAI;AACF,uBAAe,CAAC,SAAS;AACvB,gBAAM,eAAe,iBAAiB,WAAW,MAAM,IAAI,IAAI;AAE/D,cAAI,OAAO,WAAW,aAAa;AACjC,mBAAO,aAAa,QAAQ,KAAK,KAAK,UAAU,YAAY,CAAC;AAE7D,mBAAO;AAAA,cACL,IAAI,aAAa,WAAW,EAAE,KAAK,UAAU,KAAK,UAAU,YAAY,EAAE,CAAC;AAAA,YAC7E;AAAA,UACF;AACA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH,SAAS,OAAO;AACd,gBAAQ,KAAK,mCAAmC,GAAG,MAAM,KAAK;AAAA,MAChE;AAAA,IACF;AAAA,IACA,CAAC,GAAG;AAAA,EACN;AAGA,+BAAU,MAAM;AACd,UAAM,sBAAsB,CAAC,UAAwB;AACnD,UAAI,MAAM,QAAQ,KAAK;AACrB,uBAAe,UAAU,MAAM,UAAU,YAAY,CAAC;AAAA,MACxD;AAAA,IACF;AAEA,WAAO,iBAAiB,WAAW,mBAAmB;AACtD,WAAO,MAAM,OAAO,oBAAoB,WAAW,mBAAmB;AAAA,EACxE,GAAG,CAAC,KAAK,YAAY,CAAC;AAEtB,SAAO,CAAC,aAAa,QAAQ;AAC/B;;;APmFI;AAzEJ,IAAM,mBAAe,6BAAwC,IAAI;AAE1D,SAAS,qBAAqB,EAAE,SAAS,GAA4B;AAC1E,QAAM,sBAAkB,sBAA8D,oBAAI,IAAI,CAAC;AAM/F,QAAM,iBAAa,sBAAiC,oBAAI,IAAI,CAAC;AAC7D,QAAM,mBAAe,sBAAqC,oBAAI,IAAI,CAAC;AAEnE,QAAM,CAAC,EAAE,WAAW,QAAI,wBAAS,CAAC,CAAC;AAGnC,QAAM,CAAC,aAAa,cAAc,IAAI,sBAEpC,oBAAoB,CAAC,CAAC;AAExB,QAAM,CAAC,WAAW,YAAY,IAAI;AAAA,IAChC;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,sBAAkB,2BAAY,CAAC,SAAiB,UAAkB,cAAuB;AAC7F,UAAM,WAAW,gBAAgB,QAAQ,IAAI,OAAO;AAEpD,QAAI,CAAC,UAAU;AACb,sBAAgB,QAAQ,IAAI,SAAS,EAAE,UAAU,UAAU,CAAC;AAC5D,kBAAY,CAAC,CAAC;AAAA,IAChB,WAAW,SAAS,aAAa,YAAY,SAAS,cAAc,WAAW;AAC7E,sBAAgB,QAAQ,IAAI,SAAS,EAAE,UAAU,UAAU,CAAC;AAC5D,kBAAY,CAAC,CAAC;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAiB,2BAAY,CAAC,SAAiB,WAAwB;AAC3E,eAAW,QAAQ,IAAI,SAAS,MAAM;AAEtC,UAAM,YAAY,aAAa,QAAQ,IAAI,OAAO;AAClD,QAAI,WAAW;AACb,gBAAU,QAAQ,CAAC,aAAa,SAAS,CAAC;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAY,2BAAY,CAAC,YAAoB;AACjD,WAAO,WAAW,QAAQ,IAAI,OAAO,KAAK;AAAA,EAC5C,GAAG,CAAC,CAAC;AAEL,QAAM,mBAAe;AAAA,IACnB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SACE,6CAAC,aAAa,UAAb,EAAsB,OAAO,cAC3B;AAAA;AAAA,IACA,MAAM,KAAK,gBAAgB,QAAQ,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,EAAE,UAAU,UAAU,CAAC,MACnF,4CAAC,uBAAkC,SAAkB,UAAoB,aAA/C,OAAqE,CAChG;AAAA,KACH;AAEJ;AAEA,SAAS,oBAAoB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,QAAQ,SAAS,SAAS,UAAU,SAAS;AACnD,QAAM,cAAU,0BAAW,YAAY;AAEvC,MAAI,CAAC,QAAS,QAAO;AAErB,+BAAU,MAAM;AACd,YAAQ,eAAe,SAAS,KAAK;AAAA,EACvC,GAAG,CAAC,SAAS,OAAO,OAAO,CAAC;AAE5B,SAAO;AACT;AAEO,SAAS,gBACd,SACA,UACA,WACa;AACb,QAAM,cAAU,0BAAW,YAAY;AAEvC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AAEA,QAAM,EAAE,iBAAiB,WAAW,aAAa,IAAI;AAIrD,+BAAU,MAAM;AACd,oBAAgB,SAAS,UAAU,SAAS;AAAA,EAC9C,GAAG,CAAC,SAAS,UAAU,eAAe,CAAC;AAGvC,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAA6B,MAAM,UAAU,OAAO,CAAC;AAEjF,+BAAU,MAAM;AAEd,UAAM,gBAAgB,UAAU,OAAO;AACvC,QAAI,kBAAkB,QAAQ;AAC5B,gBAAU,aAAa;AAAA,IACzB;AAGA,UAAM,WAAW,MAAM;AACrB,gBAAU,UAAU,OAAO,CAAC;AAAA,IAC9B;AAEA,QAAI,CAAC,aAAa,QAAQ,IAAI,OAAO,GAAG;AACtC,mBAAa,QAAQ,IAAI,SAAS,oBAAI,IAAI,CAAC;AAAA,IAC7C;AACA,iBAAa,QAAQ,IAAI,OAAO,GAAG,IAAI,QAAQ;AAE/C,WAAO,MAAM;AACX,mBAAa,QAAQ,IAAI,OAAO,GAAG,OAAO,QAAQ;AAAA,IACpD;AAAA,EACF,GAAG,CAAC,SAAS,SAAS,CAAC;AAEvB,QAAM,kBAAc;AAAA,IAClB,OAAO;AAAA,MACL,UAAU,CAAC;AAAA,MACX,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,UAAU,CAAC;AAAA,MACX,WAAW,CAAC;AAAA,MACZ,kBAAkB,CAAC;AAAA,MACnB,UAAU;AAAA,MACV,YAAY,YAAY;AAAA,MAAC;AAAA,MACzB,mBAAmB,YAAY;AAAA,MAAC;AAAA,MAChC,eAAe,MAAM;AAAA,MAAC;AAAA,MACtB,eAAe,MAAM;AAAA,MAAC;AAAA,MACtB,sBAAsB,MAAM;AAAA,MAAC;AAAA,MAC7B,OAAO,MAAM;AAAA,MAAC;AAAA,IAChB;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SAAO,UAAU;AACnB;AAGO,SAAS,sBAAsB;AACpC,QAAM,cAAU,0BAAW,YAAY;AACvC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,8DAA8D;AAAA,EAChF;AACA,SAAO;AAAA,IACL,aAAa,QAAQ;AAAA,IACrB,gBAAgB,QAAQ;AAAA,IACxB,WAAW,QAAQ;AAAA,IACnB,cAAc,QAAQ;AAAA,EACxB;AACF;","names":["import_react","import_react","import_react"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -131,6 +131,21 @@ type ClientToolCallEventType = OutputStreamMetaType & {
|
|
|
131
131
|
};
|
|
132
132
|
};
|
|
133
133
|
type OutputStreamEventType = LLMTextDeltaEventType | LLMReasoningDeltaEventType | AgentDebugEventType | AgentHandoffEventType | MCPToolCallStartEventType | MCPToolCallEndEventType | ClientToolCallEventType;
|
|
134
|
+
interface AgentPausedResponse {
|
|
135
|
+
result: {
|
|
136
|
+
_: {
|
|
137
|
+
paused: true;
|
|
138
|
+
sessionId: string;
|
|
139
|
+
};
|
|
140
|
+
clientActions: Array<{
|
|
141
|
+
callId: string;
|
|
142
|
+
toolName: string;
|
|
143
|
+
inputs: Record<string, any>;
|
|
144
|
+
status: "pending";
|
|
145
|
+
message: string;
|
|
146
|
+
}>;
|
|
147
|
+
};
|
|
148
|
+
}
|
|
134
149
|
|
|
135
150
|
interface AgentRunner {
|
|
136
151
|
messages: Message[];
|
|
@@ -218,4 +233,4 @@ declare function tryParseJSON(value: unknown): any;
|
|
|
218
233
|
*/
|
|
219
234
|
declare function updateAgentMessageParts(parts: MessagePart[], newPart: MessagePart): MessagePart[];
|
|
220
235
|
|
|
221
|
-
export { AGENT_DEBUG_DATA_KEY, AGENT_SESSIONS_KEY, AgentContextProvider, type AgentDebugEventType, type AgentHandoffEventType, type AgentRunner, type ClientToolCallEventType, type ClientToolDefinition, type ClientToolResult, DEFAULT_SESSION_NAME, type DebugDataType, type HandoffItem, type LLMReasoningDeltaEventType, type MCPToolCallEndEventType, type MCPToolCallStartEventType, type MCPToolExecutionItem, type Message, type MessagePart, type OutputStreamEventType, type OutputStreamMetaType, type PendingToolCall, type ReasoningItem, type Session, TEMPORARY_SESSION_ID, type ToolExecutionItem, type WidgetExecutionItem, cleanSchema, tryParseJSON, updateAgentMessageParts, useAgent, useAgentContext, useAgentGlobalState };
|
|
236
|
+
export { AGENT_DEBUG_DATA_KEY, AGENT_SESSIONS_KEY, AgentContextProvider, type AgentDebugEventType, type AgentHandoffEventType, type AgentPausedResponse, type AgentRunner, type ClientToolCallEventType, type ClientToolDefinition, type ClientToolResult, DEFAULT_SESSION_NAME, type DebugDataType, type HandoffItem, type LLMReasoningDeltaEventType, type MCPToolCallEndEventType, type MCPToolCallStartEventType, type MCPToolExecutionItem, type Message, type MessagePart, type OutputStreamEventType, type OutputStreamMetaType, type PendingToolCall, type ReasoningItem, type Session, TEMPORARY_SESSION_ID, type ToolExecutionItem, type WidgetExecutionItem, cleanSchema, tryParseJSON, updateAgentMessageParts, useAgent, useAgentContext, useAgentGlobalState };
|
package/dist/index.d.ts
CHANGED
|
@@ -131,6 +131,21 @@ type ClientToolCallEventType = OutputStreamMetaType & {
|
|
|
131
131
|
};
|
|
132
132
|
};
|
|
133
133
|
type OutputStreamEventType = LLMTextDeltaEventType | LLMReasoningDeltaEventType | AgentDebugEventType | AgentHandoffEventType | MCPToolCallStartEventType | MCPToolCallEndEventType | ClientToolCallEventType;
|
|
134
|
+
interface AgentPausedResponse {
|
|
135
|
+
result: {
|
|
136
|
+
_: {
|
|
137
|
+
paused: true;
|
|
138
|
+
sessionId: string;
|
|
139
|
+
};
|
|
140
|
+
clientActions: Array<{
|
|
141
|
+
callId: string;
|
|
142
|
+
toolName: string;
|
|
143
|
+
inputs: Record<string, any>;
|
|
144
|
+
status: "pending";
|
|
145
|
+
message: string;
|
|
146
|
+
}>;
|
|
147
|
+
};
|
|
148
|
+
}
|
|
134
149
|
|
|
135
150
|
interface AgentRunner {
|
|
136
151
|
messages: Message[];
|
|
@@ -218,4 +233,4 @@ declare function tryParseJSON(value: unknown): any;
|
|
|
218
233
|
*/
|
|
219
234
|
declare function updateAgentMessageParts(parts: MessagePart[], newPart: MessagePart): MessagePart[];
|
|
220
235
|
|
|
221
|
-
export { AGENT_DEBUG_DATA_KEY, AGENT_SESSIONS_KEY, AgentContextProvider, type AgentDebugEventType, type AgentHandoffEventType, type AgentRunner, type ClientToolCallEventType, type ClientToolDefinition, type ClientToolResult, DEFAULT_SESSION_NAME, type DebugDataType, type HandoffItem, type LLMReasoningDeltaEventType, type MCPToolCallEndEventType, type MCPToolCallStartEventType, type MCPToolExecutionItem, type Message, type MessagePart, type OutputStreamEventType, type OutputStreamMetaType, type PendingToolCall, type ReasoningItem, type Session, TEMPORARY_SESSION_ID, type ToolExecutionItem, type WidgetExecutionItem, cleanSchema, tryParseJSON, updateAgentMessageParts, useAgent, useAgentContext, useAgentGlobalState };
|
|
236
|
+
export { AGENT_DEBUG_DATA_KEY, AGENT_SESSIONS_KEY, AgentContextProvider, type AgentDebugEventType, type AgentHandoffEventType, type AgentPausedResponse, type AgentRunner, type ClientToolCallEventType, type ClientToolDefinition, type ClientToolResult, DEFAULT_SESSION_NAME, type DebugDataType, type HandoffItem, type LLMReasoningDeltaEventType, type MCPToolCallEndEventType, type MCPToolCallStartEventType, type MCPToolExecutionItem, type Message, type MessagePart, type OutputStreamEventType, type OutputStreamMetaType, type PendingToolCall, type ReasoningItem, type Session, TEMPORARY_SESSION_ID, type ToolExecutionItem, type WidgetExecutionItem, cleanSchema, tryParseJSON, updateAgentMessageParts, useAgent, useAgentContext, useAgentGlobalState };
|
package/dist/index.js
CHANGED
|
@@ -396,6 +396,13 @@ function updateAgentMessageParts(parts, newPart) {
|
|
|
396
396
|
}
|
|
397
397
|
|
|
398
398
|
// src/use-agent.ts
|
|
399
|
+
var AgentPausedError = class extends Error {
|
|
400
|
+
constructor(pauseData) {
|
|
401
|
+
super("Agent paused");
|
|
402
|
+
this.pauseData = pauseData;
|
|
403
|
+
this.name = "AgentPausedError";
|
|
404
|
+
}
|
|
405
|
+
};
|
|
399
406
|
function useAgent(agentId, agentUrl, accessKey) {
|
|
400
407
|
const { allSessions, setAllSessions, debugData, setDebugData } = useAgentGlobalState();
|
|
401
408
|
const [inProgress, setInProgress] = useState(false);
|
|
@@ -466,7 +473,8 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
466
473
|
})),
|
|
467
474
|
clientTools: options?.clientTools?.map((t) => ({
|
|
468
475
|
...t,
|
|
469
|
-
parameters: cleanSchema(t.parameters)
|
|
476
|
+
parameters: cleanSchema(t.parameters),
|
|
477
|
+
requiresResult: t.requiresResult ?? false
|
|
470
478
|
}))
|
|
471
479
|
};
|
|
472
480
|
try {
|
|
@@ -493,6 +501,57 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
493
501
|
setCurrentSessionId(sessionId);
|
|
494
502
|
}
|
|
495
503
|
}
|
|
504
|
+
if (resp.headers.get("content-type")?.includes("application/json")) {
|
|
505
|
+
const data = await resp.json();
|
|
506
|
+
if (data.result?._?.paused) {
|
|
507
|
+
setMessages((prev) => {
|
|
508
|
+
const lastMessage = prev[prev.length - 1];
|
|
509
|
+
const newParts = data.result.clientActions.map((action, index) => ({
|
|
510
|
+
type: "widget",
|
|
511
|
+
toolName: action.toolName,
|
|
512
|
+
callId: action.callId,
|
|
513
|
+
inputs: action.inputs,
|
|
514
|
+
sequence: (lastMessage?.parts?.length || 0) + index
|
|
515
|
+
}));
|
|
516
|
+
let updatedMessages;
|
|
517
|
+
if (lastMessage?.role === "agent") {
|
|
518
|
+
const updatedMessage = {
|
|
519
|
+
...lastMessage,
|
|
520
|
+
parts: [...lastMessage.parts || [], ...newParts]
|
|
521
|
+
};
|
|
522
|
+
updatedMessages = [...prev.slice(0, -1), updatedMessage];
|
|
523
|
+
} else {
|
|
524
|
+
const updatedMessage = {
|
|
525
|
+
role: "agent",
|
|
526
|
+
content: "",
|
|
527
|
+
parts: newParts,
|
|
528
|
+
executionId: Date.now().toString()
|
|
529
|
+
// No execution ID in pause response?
|
|
530
|
+
};
|
|
531
|
+
updatedMessages = [...prev, updatedMessage];
|
|
532
|
+
}
|
|
533
|
+
if (sessionUtils.syncSessionRef.current) {
|
|
534
|
+
sessionUtils.syncSessionRef.current(updatedMessages);
|
|
535
|
+
}
|
|
536
|
+
return updatedMessages;
|
|
537
|
+
});
|
|
538
|
+
setPendingToolCalls((prev) => {
|
|
539
|
+
const updated = new Map(prev);
|
|
540
|
+
data.result.clientActions.forEach((action) => {
|
|
541
|
+
updated.set(action.callId, {
|
|
542
|
+
toolName: action.toolName,
|
|
543
|
+
callId: action.callId,
|
|
544
|
+
inputs: action.inputs,
|
|
545
|
+
requiresResult: true
|
|
546
|
+
// Implicitly true for paused actions
|
|
547
|
+
});
|
|
548
|
+
});
|
|
549
|
+
return updated;
|
|
550
|
+
});
|
|
551
|
+
setIsPaused(true);
|
|
552
|
+
throw new AgentPausedError(data.result);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
496
555
|
const executionId = resp.headers.get("x-buildship-agent-execution-id");
|
|
497
556
|
if (executionId) {
|
|
498
557
|
setMessages((prev) => {
|
|
@@ -615,6 +674,9 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
615
674
|
}
|
|
616
675
|
},
|
|
617
676
|
onerror: (e) => {
|
|
677
|
+
if (e instanceof AgentPausedError) {
|
|
678
|
+
throw e;
|
|
679
|
+
}
|
|
618
680
|
console.log("Agent error", e);
|
|
619
681
|
setInProgress(false);
|
|
620
682
|
if (sessionUtils.syncSessionRef.current) {
|
|
@@ -624,6 +686,10 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
624
686
|
}
|
|
625
687
|
});
|
|
626
688
|
} catch (error) {
|
|
689
|
+
if (error instanceof AgentPausedError) {
|
|
690
|
+
setInProgress(false);
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
627
693
|
console.log("Agent execution failed", error);
|
|
628
694
|
setInProgress(false);
|
|
629
695
|
if (sessionUtils.syncSessionRef.current) {
|
|
@@ -673,6 +739,55 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
673
739
|
}
|
|
674
740
|
throw new Error(`Error status ${resp.status}`);
|
|
675
741
|
}
|
|
742
|
+
if (resp.headers.get("content-type")?.includes("application/json")) {
|
|
743
|
+
const data = await resp.json();
|
|
744
|
+
if (data.result?._?.paused) {
|
|
745
|
+
setMessages((prev) => {
|
|
746
|
+
const lastMessage = prev[prev.length - 1];
|
|
747
|
+
const newParts = data.result.clientActions.map((action, index) => ({
|
|
748
|
+
type: "widget",
|
|
749
|
+
toolName: action.toolName,
|
|
750
|
+
callId: action.callId,
|
|
751
|
+
inputs: action.inputs,
|
|
752
|
+
sequence: (lastMessage?.parts?.length || 0) + index
|
|
753
|
+
}));
|
|
754
|
+
let updatedMessages;
|
|
755
|
+
if (lastMessage?.role === "agent") {
|
|
756
|
+
const updatedMessage = {
|
|
757
|
+
...lastMessage,
|
|
758
|
+
parts: [...lastMessage.parts || [], ...newParts]
|
|
759
|
+
};
|
|
760
|
+
updatedMessages = [...prev.slice(0, -1), updatedMessage];
|
|
761
|
+
} else {
|
|
762
|
+
const updatedMessage = {
|
|
763
|
+
role: "agent",
|
|
764
|
+
content: "",
|
|
765
|
+
parts: newParts,
|
|
766
|
+
executionId: Date.now().toString()
|
|
767
|
+
};
|
|
768
|
+
updatedMessages = [...prev, updatedMessage];
|
|
769
|
+
}
|
|
770
|
+
if (sessionUtils.syncSessionRef.current) {
|
|
771
|
+
sessionUtils.syncSessionRef.current(updatedMessages);
|
|
772
|
+
}
|
|
773
|
+
return updatedMessages;
|
|
774
|
+
});
|
|
775
|
+
setPendingToolCalls((prev) => {
|
|
776
|
+
const updated = new Map(prev);
|
|
777
|
+
data.result.clientActions.forEach((action) => {
|
|
778
|
+
updated.set(action.callId, {
|
|
779
|
+
toolName: action.toolName,
|
|
780
|
+
callId: action.callId,
|
|
781
|
+
inputs: action.inputs,
|
|
782
|
+
requiresResult: true
|
|
783
|
+
});
|
|
784
|
+
});
|
|
785
|
+
return updated;
|
|
786
|
+
});
|
|
787
|
+
setIsPaused(true);
|
|
788
|
+
throw new AgentPausedError(data.result);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
676
791
|
const executionId = resp.headers.get("x-buildship-agent-execution-id");
|
|
677
792
|
if (executionId && options?.input) {
|
|
678
793
|
setMessages((prev) => {
|
|
@@ -791,6 +906,9 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
791
906
|
}
|
|
792
907
|
},
|
|
793
908
|
onerror: (e) => {
|
|
909
|
+
if (e instanceof AgentPausedError) {
|
|
910
|
+
throw e;
|
|
911
|
+
}
|
|
794
912
|
console.log("Agent resume error", e);
|
|
795
913
|
setInProgress(false);
|
|
796
914
|
if (sessionUtils.syncSessionRef.current) {
|
|
@@ -800,6 +918,10 @@ function useAgent(agentId, agentUrl, accessKey) {
|
|
|
800
918
|
}
|
|
801
919
|
});
|
|
802
920
|
} catch (error) {
|
|
921
|
+
if (error instanceof AgentPausedError) {
|
|
922
|
+
setInProgress(false);
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
803
925
|
console.log("Agent resume execution failed", error);
|
|
804
926
|
setInProgress(false);
|
|
805
927
|
if (sessionUtils.syncSessionRef.current) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agent-context.tsx","../src/use-agent.ts","../src/constants.ts","../src/session-utils.ts","../src/debug-handlers.ts","../src/utils/schema.ts","../src/utils/message.ts","../src/utils/use-synced-local-storage.ts"],"sourcesContent":["import {\n createContext,\n useContext,\n useCallback,\n useRef,\n useState,\n useEffect,\n useMemo,\n ReactNode,\n} from \"react\";\nimport useAgent from \"./use-agent\";\nimport type {\n Message,\n Session,\n DebugDataType,\n ClientToolDefinition,\n ClientToolResult,\n PendingToolCall,\n} from \"./types\";\nimport { useSyncedLocalStorage } from \"./utils/use-synced-local-storage\";\nimport { AGENT_SESSIONS_KEY, AGENT_DEBUG_DATA_KEY } from \"./constants\";\n\nexport interface AgentRunner {\n messages: Message[];\n inProgress: boolean;\n sessionId: string;\n sessions: Session[];\n debugData: Record<string, DebugDataType>;\n pendingToolCalls: PendingToolCall[];\n isPaused: boolean;\n handleSend: (\n input: string,\n options?: {\n context?: Record<string, unknown>;\n testBuildId?: string;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n tools?: ClientToolDefinition[];\n clientTools?: ClientToolDefinition[];\n },\n ) => Promise<void>;\n submitToolResults: (\n toolResults: ClientToolResult[],\n options?: {\n input?: string;\n context?: object;\n additionalHeaders?: Record<string, string>;\n },\n ) => Promise<void>;\n switchSession: (sessionId?: string) => void;\n deleteSession: (sessionId: string) => void;\n addOptimisticMessage: (input: string) => void;\n abort: () => void;\n}\n\ninterface AgentContextValue {\n initializeAgent: (agentId: string, agentUrl: string, accessKey?: string) => void;\n registerRunner: (agentId: string, runner: AgentRunner) => void;\n getRunner: (agentId: string) => AgentRunner | null;\n // Global state provided to useAgent hooks\n allSessions: Record<string, Record<string, Session>>;\n setAllSessions: (\n value:\n | Record<string, Record<string, Session>>\n | ((\n prev: Record<string, Record<string, Session>>,\n ) => Record<string, Record<string, Session>>),\n ) => void;\n debugData: Record<string, DebugDataType>;\n setDebugData: (\n value:\n | Record<string, DebugDataType>\n | ((prev: Record<string, DebugDataType>) => Record<string, DebugDataType>),\n ) => void;\n}\n\nconst AgentContext = createContext<AgentContextValue | null>(null);\n\nexport function AgentContextProvider({ children }: { children: ReactNode }) {\n const activeAgentsRef = useRef<Map<string, { agentUrl: string; accessKey?: string }>>(new Map());\n // Store runners in a ref since we push updates via registerRunner\n // Note: Changes to this Ref won't trigger re-renders of consumers of getRunner directly,\n // but since we return the 'runner' object which contains state,\n // and we access it via a hook that listens to updates (implemented below), it works out.\n // Actually, to make 'useAgentContext' reactive to runner changes, we need a subscription mechanism.\n const runnersRef = useRef<Map<string, AgentRunner>>(new Map());\n const listenersRef = useRef<Map<string, Set<() => void>>>(new Map());\n\n const [, forceUpdate] = useState({});\n\n // Global Sync State managed here to be shared\n const [allSessions, setAllSessions] = useSyncedLocalStorage<\n Record<string, Record<string, Session>>\n >(AGENT_SESSIONS_KEY, {});\n\n const [debugData, setDebugData] = useSyncedLocalStorage<Record<string, DebugDataType>>(\n AGENT_DEBUG_DATA_KEY,\n {},\n );\n\n const initializeAgent = useCallback((agentId: string, agentUrl: string, accessKey?: string) => {\n const existing = activeAgentsRef.current.get(agentId);\n\n if (!existing) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey });\n forceUpdate({});\n } else if (existing.agentUrl !== agentUrl || existing.accessKey !== accessKey) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey });\n forceUpdate({});\n }\n }, []);\n\n const registerRunner = useCallback((agentId: string, runner: AgentRunner) => {\n runnersRef.current.set(agentId, runner);\n // Notify listeners for this agentId\n const listeners = listenersRef.current.get(agentId);\n if (listeners) {\n listeners.forEach((callback) => callback());\n }\n }, []);\n\n const getRunner = useCallback((agentId: string) => {\n return runnersRef.current.get(agentId) || null;\n }, []);\n\n const contextValue = useMemo(\n () => ({\n initializeAgent,\n registerRunner,\n getRunner,\n allSessions,\n setAllSessions,\n debugData,\n setDebugData,\n runnersRef,\n listenersRef,\n }),\n [\n initializeAgent,\n registerRunner,\n getRunner,\n allSessions,\n setAllSessions,\n debugData,\n setDebugData,\n ],\n );\n\n return (\n <AgentContext.Provider value={contextValue}>\n {children}\n {Array.from(activeAgentsRef.current.entries()).map(([agentId, { agentUrl, accessKey }]) => (\n <AgentRunnerInstance key={agentId} agentId={agentId} agentUrl={agentUrl} accessKey={accessKey} />\n ))}\n </AgentContext.Provider>\n );\n}\n\nfunction AgentRunnerInstance({\n agentId,\n agentUrl,\n accessKey,\n}: {\n agentId: string;\n agentUrl: string;\n accessKey?: string;\n}) {\n const agent = useAgent(agentId, agentUrl, accessKey);\n const context = useContext(AgentContext);\n\n if (!context) return null;\n\n useEffect(() => {\n context.registerRunner(agentId, agent);\n }, [agentId, agent, context]);\n\n return null;\n}\n\nexport function useAgentContext(\n agentId: string,\n agentUrl: string,\n accessKey?: string,\n): AgentRunner {\n const context = useContext(AgentContext);\n\n if (!context) {\n throw new Error(\"useAgentContext must be used within AgentContextProvider\");\n }\n\n const { initializeAgent, getRunner, listenersRef } = context as AgentContextValue & {\n listenersRef: React.MutableRefObject<Map<string, Set<() => void>>>;\n };\n\n useEffect(() => {\n initializeAgent(agentId, agentUrl, accessKey);\n }, [agentId, agentUrl, initializeAgent]);\n\n // Reactive subscription to runner updates\n const [runner, setRunner] = useState<AgentRunner | null>(() => getRunner(agentId));\n\n useEffect(() => {\n // Current runner state\n const currentRunner = getRunner(agentId);\n if (currentRunner !== runner) {\n setRunner(currentRunner);\n }\n\n // Subscribe to future updates\n const callback = () => {\n setRunner(getRunner(agentId));\n };\n\n if (!listenersRef.current.has(agentId)) {\n listenersRef.current.set(agentId, new Set());\n }\n listenersRef.current.get(agentId)?.add(callback);\n\n return () => {\n listenersRef.current.get(agentId)?.delete(callback);\n };\n }, [agentId, getRunner]);\n\n const placeholder = useMemo(\n () => ({\n messages: [],\n inProgress: false,\n sessionId: \"\",\n sessions: [],\n debugData: {},\n pendingToolCalls: [],\n isPaused: false,\n handleSend: async () => {},\n submitToolResults: async () => {},\n switchSession: () => {},\n deleteSession: () => {},\n addOptimisticMessage: () => {},\n abort: () => {},\n }),\n [],\n );\n\n return runner || placeholder;\n}\n\n// Hook to access the global state for use-agent\nexport function useAgentGlobalState() {\n const context = useContext(AgentContext);\n if (!context) {\n throw new Error(\"useAgentGlobalState must be used within AgentContextProvider\");\n }\n return {\n allSessions: context.allSessions,\n setAllSessions: context.setAllSessions,\n debugData: context.debugData,\n setDebugData: context.setDebugData,\n };\n}\n","import { useCallback, useRef, useState, useEffect } from \"react\";\nimport { EventSourceMessage, fetchEventSource } from \"@microsoft/fetch-event-source\";\n\nimport { DEFAULT_SESSION_NAME, TEMPORARY_SESSION_ID } from \"./constants\";\nimport { useSessionUtils } from \"./session-utils\";\nimport { createDebugHandlers } from \"./debug-handlers\";\nimport { useAgentGlobalState } from \"./agent-context\";\nimport type {\n Message,\n MessagePart,\n OutputStreamEventType,\n ClientToolDefinition,\n ClientToolResult,\n PendingToolCall,\n} from \"./types\";\nimport { cleanSchema, tryParseJSON } from \"./utils/schema\";\nimport { updateAgentMessageParts } from \"./utils/message\";\n\nexport default function useAgent(agentId: string, agentUrl: string, accessKey?: string) {\n // Use global state from Context instead of Jotai atoms\n const { allSessions, setAllSessions, debugData, setDebugData } = useAgentGlobalState();\n\n const [inProgress, setInProgress] = useState(false);\n const [messages, setMessages] = useState<Array<Message>>([]);\n const [pendingToolCalls, setPendingToolCalls] = useState<Map<string, PendingToolCall>>(new Map());\n const [isPaused, setIsPaused] = useState(false);\n\n const messagesRef = useRef<Array<Message>>([]);\n const clientToolsRef = useRef<ClientToolDefinition[]>([]);\n\n // Initialize currentSessionId later after sessionUtils is available\n const [currentSessionId, setCurrentSessionId] = useState<string>(TEMPORARY_SESSION_ID);\n\n const sessionUtils = useSessionUtils(\n agentId,\n allSessions,\n setAllSessions,\n currentSessionId,\n setCurrentSessionId,\n messagesRef,\n );\n\n // Set initial session ID after sessionUtils is available\n useEffect(() => {\n const initialSessionId = sessionUtils.getInitialSessionId();\n setCurrentSessionId(initialSessionId);\n }, []);\n\n const debugHandlers = createDebugHandlers(setDebugData);\n\n // Keep messagesRef in sync with messages state\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n // Initialize or load session\n useEffect(() => {\n // Don't reset messages if we're currently in progress (streaming)\n if (inProgress) {\n return;\n }\n\n const session = sessionUtils.agentSessions[currentSessionId];\n\n if (session) {\n setMessages(session.messages);\n } else {\n setMessages([]);\n }\n }, [currentSessionId, sessionUtils.agentSessions, agentId, inProgress]);\n\n // Only sync on unmount to prevent data loss\n useEffect(() => {\n return () => {\n if (messagesRef.current.length > 0 && sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current();\n }\n };\n }, []);\n\n const controller = useRef<AbortController>();\n\n const runAgent = useCallback(\n async (\n input: string,\n options?: {\n context?: object;\n testBuildId?: string;\n additionalHeaders?: Record<string, string>;\n tools?: ClientToolDefinition[];\n clientTools?: ClientToolDefinition[];\n },\n ) => {\n setInProgress(true);\n // Abort any existing request before creating a new controller\n if (controller.current) {\n controller.current.abort();\n }\n controller.current = new AbortController();\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options?.additionalHeaders || {}),\n ...(accessKey ? { Authorization: `Bearer ${accessKey}` } : {}),\n };\n\n // Include session ID in headers if we have one\n if (currentSessionId) {\n headers[\"x-buildship-agent-session-id\"] = currentSessionId;\n }\n\n const body = {\n stream: true,\n input,\n context: options?.context || {},\n testBuildId: options?.testBuildId,\n tools: options?.tools?.map((t: { parameters: unknown }) => ({\n ...t,\n parameters: cleanSchema(t.parameters),\n })),\n clientTools: options?.clientTools?.map((t: { parameters: unknown }) => ({\n ...t,\n parameters: cleanSchema(t.parameters),\n })),\n };\n\n try {\n await fetchEventSource(agentUrl, {\n method: \"POST\",\n headers,\n signal: controller.current.signal,\n openWhenHidden: true,\n body: JSON.stringify(body),\n onopen: async (resp) => {\n // catch the 404 status\n if (resp.status >= 400) {\n console.log(`AI onopen error with status: ${resp.status}`);\n\n if (resp.status === 404) {\n // for resume operations with 404, throw a specific error for retry\n throw new Error(`Not Found (${resp.statusText})`);\n }\n\n throw new Error(`Error status ${resp.status}`);\n }\n\n // Extract session ID from response headers if we don't have one\n if (!currentSessionId || currentSessionId === TEMPORARY_SESSION_ID) {\n const sessionId = resp.headers.get(\"x-buildship-agent-session-id\");\n if (sessionId) {\n // Transfer current messages to the new session before switching\n const currentMessages = messagesRef.current;\n const sessionName =\n resp.headers.get(\"x-buildship-agent-session-name\") || DEFAULT_SESSION_NAME;\n\n sessionUtils.createSessionFromResponse(sessionId, sessionName, currentMessages);\n setCurrentSessionId(sessionId);\n }\n }\n\n // Extract execution ID from response headers and update the last user message\n const executionId = resp.headers.get(\"x-buildship-agent-execution-id\");\n if (executionId) {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n if (lastMessage?.role === \"user\") {\n const updatedMessage = {\n ...lastMessage,\n executionId: executionId,\n };\n const updatedMessages = [...prev.slice(0, -1), updatedMessage];\n\n // Sync updated user message\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n }\n return prev;\n });\n }\n },\n onmessage: (event: EventSourceMessage) => {\n try {\n const parsed = JSON.parse(event.data) as OutputStreamEventType;\n\n if (parsed.type === \"llm_text_delta\") {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const sequence = parsed.meta.sequence;\n const newPart: MessagePart = {\n type: \"text\",\n text: parsed.data,\n firstSequence: sequence,\n lastSequence: sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n content: lastMessage.content + parsed.data, // content is still useful for simple displays\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: parsed.data,\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (parsed.type === \"client_tool_call\") {\n const { toolName, callId, inputs } = parsed.data;\n\n // Check if this tool requires a result\n const toolDefinition = clientToolsRef.current.find((t) => t.name === toolName);\n const requiresResult = toolDefinition?.requiresResult ?? false;\n\n // Track pending tool call if it requires a result\n if (requiresResult) {\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n updated.set(callId, {\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n requiresResult,\n });\n return updated;\n });\n }\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newPart: MessagePart = {\n type: \"widget\",\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n sequence: parsed.meta.sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: \"\",\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (\n parsed.type.startsWith(\"debug_\") ||\n parsed.type === \"llm_reasoning_delta\" ||\n parsed.type === \"agent_handoff\" ||\n parsed.type === \"mcp_tool_call_start\" ||\n parsed.type === \"mcp_tool_call_end\"\n ) {\n debugHandlers.handleDebugEvent(parsed);\n }\n } catch (e) {\n console.log(\"Failed to parse agent message\", e);\n }\n },\n onclose: () => {\n console.log(\"Agent closed\");\n setInProgress(false);\n\n // Check if there are pending tool calls that require results\n setPendingToolCalls((currentPending) => {\n if (currentPending.size > 0) {\n setIsPaused(true);\n }\n return currentPending;\n });\n\n // Sync messages when streaming completes\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current();\n }\n },\n onerror: (e) => {\n console.log(\"Agent error\", e);\n setInProgress(false);\n // Sync messages on error to prevent data loss\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw new Error(\"Failed to execute agent\");\n },\n });\n } catch (error) {\n console.log(\"Agent execution failed\", error);\n setInProgress(false);\n // Sync messages on execution failure\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw error;\n }\n },\n [agentUrl, accessKey, currentSessionId, sessionUtils, debugHandlers],\n );\n\n const resumeAgent = useCallback(\n async (\n toolResults: ClientToolResult[],\n options?: {\n input?: string;\n context?: object;\n additionalHeaders?: Record<string, string>;\n },\n ) => {\n if (!currentSessionId || currentSessionId === TEMPORARY_SESSION_ID) {\n throw new Error(\"Cannot resume: no active session\");\n }\n\n setInProgress(true);\n setIsPaused(false);\n\n // Abort any existing request before creating a new controller\n if (controller.current) {\n controller.current.abort();\n }\n controller.current = new AbortController();\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options?.additionalHeaders || {}),\n ...(accessKey ? { Authorization: `Bearer ${accessKey}` } : {}),\n };\n\n // Build resume URL - replace /executeAgent with /resumeAgent\n const baseUrl = agentUrl.replace(/\\/executeAgent\\/.*$/, \"\");\n const resumeUrl = `${baseUrl}/resumeAgent/${agentId}/${currentSessionId}`;\n\n const body = {\n stream: true,\n input: options?.input || \"\",\n context: options?.context || {},\n clientToolResults: toolResults,\n };\n\n try {\n await fetchEventSource(resumeUrl, {\n method: \"POST\",\n headers,\n signal: controller.current.signal,\n openWhenHidden: true,\n body: JSON.stringify(body),\n onopen: async (resp) => {\n if (resp.status >= 400) {\n console.log(`AI onopen error with status: ${resp.status}`);\n\n if (resp.status === 404) {\n throw new Error(`Session not found (${resp.statusText})`);\n }\n\n throw new Error(`Error status ${resp.status}`);\n }\n\n // Extract execution ID from response headers\n const executionId = resp.headers.get(\"x-buildship-agent-execution-id\");\n if (executionId && options?.input) {\n // Add user message if input was provided\n setMessages((prev) => {\n const userMessage: Message = {\n role: \"user\" as const,\n content: options.input || \"\",\n executionId: executionId,\n };\n const updatedMessages = [...prev, userMessage];\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n }\n },\n onmessage: (event: EventSourceMessage) => {\n try {\n const parsed = JSON.parse(event.data) as OutputStreamEventType;\n\n if (parsed.type === \"llm_text_delta\") {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const sequence = parsed.meta.sequence;\n const newPart: MessagePart = {\n type: \"text\",\n text: parsed.data,\n firstSequence: sequence,\n lastSequence: sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n content: lastMessage.content + parsed.data,\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: parsed.data,\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (parsed.type === \"client_tool_call\") {\n const { toolName, callId, inputs } = parsed.data;\n\n // Check if this tool requires a result\n const toolDefinition = clientToolsRef.current.find((t) => t.name === toolName);\n const requiresResult = toolDefinition?.requiresResult ?? false;\n\n // Track pending tool call if it requires a result\n if (requiresResult) {\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n updated.set(callId, {\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n requiresResult,\n });\n return updated;\n });\n }\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newPart: MessagePart = {\n type: \"widget\",\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n sequence: parsed.meta.sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: \"\",\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (\n parsed.type.startsWith(\"debug_\") ||\n parsed.type === \"llm_reasoning_delta\" ||\n parsed.type === \"agent_handoff\" ||\n parsed.type === \"mcp_tool_call_start\" ||\n parsed.type === \"mcp_tool_call_end\"\n ) {\n debugHandlers.handleDebugEvent(parsed);\n }\n } catch (e) {\n console.log(\"Failed to parse agent message\", e);\n }\n },\n onclose: () => {\n console.log(\"Agent resume closed\");\n setInProgress(false);\n\n // Check if there are pending tool calls that require results\n setPendingToolCalls((currentPending) => {\n if (currentPending.size > 0) {\n setIsPaused(true);\n }\n return currentPending;\n });\n\n // Sync messages when streaming completes\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current();\n }\n },\n onerror: (e) => {\n console.log(\"Agent resume error\", e);\n setInProgress(false);\n // Sync messages on error to prevent data loss\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw new Error(\"Failed to resume agent\");\n },\n });\n } catch (error) {\n console.log(\"Agent resume execution failed\", error);\n setInProgress(false);\n // Sync messages on execution failure\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw error;\n }\n },\n [agentUrl, accessKey, currentSessionId, sessionUtils, debugHandlers],\n );\n\n const handleSend = useCallback(\n async (\n input: string,\n options?: {\n context?: object;\n testBuildId?: string;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n tools?: ClientToolDefinition[];\n clientTools?: ClientToolDefinition[];\n },\n ) => {\n // Store client tools for tracking requiresResult\n if (options?.clientTools) {\n clientToolsRef.current = options.clientTools;\n }\n\n // Clear pending tool calls when starting a new conversation\n setPendingToolCalls(new Map());\n setIsPaused(false);\n\n const userMessage = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n };\n\n // Only add user message if not skipping\n if (!options?.skipUserMessage) {\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n // Sync immediately after user message\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n }\n\n try {\n await runAgent(input, options);\n } catch (error) {\n // Ensure user message is preserved even if agent execution fails\n if (!options?.skipUserMessage) {\n setMessages((prev) => {\n const updatedMessages = prev.some((m) => m === userMessage)\n ? prev\n : [...prev, userMessage];\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n }\n throw error;\n }\n },\n [runAgent, sessionUtils.syncSessionRef],\n );\n\n const addOptimisticMessage = useCallback(\n (input: string) => {\n const userMessage = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n };\n\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n // Sync immediately after user message\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n },\n [sessionUtils.syncSessionRef],\n );\n\n const submitToolResults = useCallback(\n async (\n toolResults: ClientToolResult[],\n options?: {\n input?: string;\n context?: object;\n additionalHeaders?: Record<string, string>;\n },\n ) => {\n // Remove submitted tool calls from pending\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n toolResults.forEach((result) => {\n updated.delete(result.callId);\n });\n return updated;\n });\n\n try {\n await resumeAgent(toolResults, options);\n } catch (error) {\n console.error(\"Failed to submit tool results:\", error);\n throw error;\n }\n },\n [resumeAgent],\n );\n\n const abort = useCallback(() => {\n if (controller.current) {\n controller.current.abort();\n }\n setInProgress(false);\n // Sync messages to prevent data loss\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n }, [sessionUtils.syncSessionRef]);\n\n return {\n inProgress,\n messages,\n handleSend,\n addOptimisticMessage,\n submitToolResults,\n abort,\n sessionId: currentSessionId,\n switchSession: sessionUtils.switchSession,\n deleteSession: sessionUtils.deleteSession,\n sessions: sessionUtils.sessionsList,\n debugData,\n pendingToolCalls: Array.from(pendingToolCalls.values()),\n isPaused,\n };\n}\n","export const AGENT_SESSIONS_KEY = \"buildship:agent:conversations\";\nexport const AGENT_DEBUG_DATA_KEY = \"buildship:agent:debug\";\n\nexport const DEFAULT_SESSION_NAME = \"New Chat\";\nexport const TEMPORARY_SESSION_ID = \"sess_temp\";\n","import { useCallback, useMemo, useRef } from \"react\";\nimport type { Message, Session } from \"./types\";\nimport { TEMPORARY_SESSION_ID } from \"./constants\";\n\nexport const useSessionUtils = (\n agentId: string,\n allSessions: Record<string, Record<string, Session>>,\n setAllSessions: (\n value:\n | Record<string, Record<string, Session>>\n | ((\n prev: Record<string, Record<string, Session>>,\n ) => Record<string, Record<string, Session>>),\n ) => void,\n currentSessionId: string,\n setCurrentSessionId: (sessionId: string) => void,\n messagesRef: React.MutableRefObject<Array<Message>>,\n) => {\n const agentSessions = useMemo(() => allSessions[agentId] || {}, [agentId, allSessions]);\n\n const syncSessionRef = useRef<(messages?: Array<Message>) => void>();\n\n syncSessionRef.current = (updatedMessages?: Array<Message>) => {\n if (!currentSessionId || currentSessionId === TEMPORARY_SESSION_ID) {\n return;\n }\n\n setAllSessions((prev) => ({\n ...prev,\n [agentId]: {\n ...prev[agentId],\n [currentSessionId]: {\n ...prev[agentId]?.[currentSessionId],\n messages: updatedMessages ?? messagesRef.current,\n updatedAt: Date.now(),\n },\n },\n }));\n };\n\n const getInitialSessionId = () => {\n const sessions = Object.values(agentSessions);\n if (sessions.length > 0) {\n return sessions.sort((a, b) => b.updatedAt - a.updatedAt)[0].id;\n }\n return TEMPORARY_SESSION_ID;\n };\n\n const switchSession = useCallback(\n (sessionId: string = TEMPORARY_SESSION_ID) => {\n setCurrentSessionId(sessionId);\n },\n [setCurrentSessionId],\n );\n\n const deleteSession = useCallback(\n (sessionId: string) => {\n if (!sessionId || sessionId === TEMPORARY_SESSION_ID) {\n return;\n }\n\n setAllSessions((prev) => {\n const updatedAgentSessions = { ...prev[agentId] };\n delete updatedAgentSessions[sessionId];\n\n return {\n ...prev,\n [agentId]: updatedAgentSessions,\n };\n });\n\n if (sessionId === currentSessionId) {\n const remainingSessions = Object.values(agentSessions).filter((s) => s.id !== sessionId);\n if (remainingSessions.length > 0) {\n const mostRecent = remainingSessions.sort((a, b) => b.updatedAt - a.updatedAt)[0];\n setCurrentSessionId(mostRecent.id);\n } else {\n setCurrentSessionId(TEMPORARY_SESSION_ID);\n }\n }\n },\n [agentId, currentSessionId, agentSessions, setAllSessions, setCurrentSessionId],\n );\n\n const sessionsList = useMemo(\n () => Object.values(agentSessions).sort((a, b) => b.updatedAt - a.updatedAt),\n [agentSessions],\n );\n\n const createSessionFromResponse = (\n sessionId: string,\n sessionName: string,\n currentMessages: Array<Message>,\n ) => {\n setAllSessions((prev) => ({\n ...prev,\n [agentId]: {\n ...prev[agentId],\n [sessionId]: {\n id: sessionId,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n messages: currentMessages,\n name: sessionName,\n },\n },\n }));\n };\n\n return {\n agentSessions,\n syncSessionRef,\n getInitialSessionId,\n switchSession,\n deleteSession,\n sessionsList,\n createSessionFromResponse,\n };\n};\n","import type {\n AgentDebugEventType,\n AgentHandoffEventType,\n DebugDataType,\n LLMReasoningDeltaEventType,\n ReasoningItem,\n ToolExecutionItem,\n HandoffItem,\n MCPToolCallStartEventType,\n MCPToolCallEndEventType,\n MCPToolExecutionItem,\n} from \"./types\";\n\nexport const createDebugHandlers = (\n setDebugData: (\n value:\n | Record<string, DebugDataType>\n | ((prev: Record<string, DebugDataType>) => Record<string, DebugDataType>),\n ) => void,\n) => {\n const handleDebugToolExecutionStarted = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"tool_call\",\n toolId: (parsed.data as { toolId?: string }).toolId || \"unknown\",\n toolCallId: (parsed.data as { toolCallId?: string }).toolCallId,\n status: \"progress\",\n },\n ],\n }));\n };\n\n const handleDebugToolExecutionInputs = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n currentData[i] = {\n ...toolItem,\n inputs: (parsed.data as { value: unknown }).value,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugToolExecutionFinished = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n currentData[i] = {\n ...toolItem,\n status: \"complete\",\n output: (parsed.data as { value: unknown }).value,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugToolExecutionError = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n currentData[i] = {\n ...toolItem,\n status: \"error\",\n output: (parsed.data as { value: unknown }).value,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugToolLog = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n const currentLogs = toolItem.logs || [];\n currentData[i] = {\n ...toolItem,\n logs: [...currentLogs, (parsed.data as { value: unknown[] }).value[0]],\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n let lastReasoningIndex = -1;\n const handleDebugReasoningStep = (parsed: LLMReasoningDeltaEventType) => {\n const executionId = parsed.meta.executionId;\n const { delta, index } = parsed.data;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n if (lastReasoningIndex < index) {\n currentData.push({ itemType: \"reasoning\", reasoning: \"\" });\n lastReasoningIndex = index;\n }\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"reasoning\") {\n currentData[i] = {\n itemType: \"reasoning\",\n reasoning: (currentData[i] as ReasoningItem).reasoning + delta,\n };\n break;\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleAgentHandoff = (parsed: AgentHandoffEventType) => {\n const executionId = parsed.meta.executionId;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"handoff\",\n agentName: parsed.data.agentName,\n } as HandoffItem,\n ],\n }));\n };\n\n const handleMCPToolCallStart = (parsed: MCPToolCallStartEventType) => {\n const executionId = parsed.meta.executionId;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"mcp_tool_call\",\n toolName: parsed.data.toolName,\n serverName: parsed.data.serverName,\n callId: parsed.data.callId,\n status: \"progress\",\n inputs: parsed.data.inputs,\n } as MCPToolExecutionItem,\n ],\n }));\n };\n\n const handleMCPToolCallEnd = (parsed: MCPToolCallEndEventType) => {\n const executionId = parsed.meta.executionId;\n const callId = parsed.data.callId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"mcp_tool_call\") {\n const mcpToolItem = currentData[i] as MCPToolExecutionItem;\n if (mcpToolItem.callId === callId) {\n currentData[i] = {\n ...mcpToolItem,\n status: parsed.data.error ? \"error\" : \"complete\",\n output: parsed.data.result,\n error: parsed.data.error,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugEvent = (\n parsed:\n | AgentDebugEventType\n | LLMReasoningDeltaEventType\n | AgentHandoffEventType\n | MCPToolCallStartEventType\n | MCPToolCallEndEventType,\n ) => {\n switch (parsed.type) {\n case \"debug_tool_execution_started\":\n handleDebugToolExecutionStarted(parsed);\n break;\n case \"debug_tool_execution_inputs\":\n handleDebugToolExecutionInputs(parsed);\n break;\n case \"debug_tool_execution_finished\":\n handleDebugToolExecutionFinished(parsed);\n break;\n case \"debug_tool_execution_error\":\n handleDebugToolExecutionError(parsed);\n break;\n case \"debug_tool_log\":\n handleDebugToolLog(parsed);\n break;\n case \"llm_reasoning_delta\":\n handleDebugReasoningStep(parsed);\n break;\n case \"agent_handoff\":\n handleAgentHandoff(parsed);\n break;\n case \"mcp_tool_call_start\":\n handleMCPToolCallStart(parsed);\n break;\n case \"mcp_tool_call_end\":\n handleMCPToolCallEnd(parsed);\n break;\n }\n };\n\n return {\n handleDebugEvent,\n };\n};\n","/**\n * Helper to clean JSON Schema for LLM compatibility.\n * Replaces modern Draft 2020-12 features with older, more compatible alternatives.\n * Specifically handles OpenAI's 'Strict Mode' requirements.\n */\nexport function cleanSchema(obj: unknown): unknown {\n if (Array.isArray(obj)) {\n return obj.map(cleanSchema);\n } else if (obj !== null && typeof obj === \"object\") {\n const newObj: Record<string, unknown> = {};\n const currentObj = obj as Record<string, any>;\n\n for (const key in currentObj) {\n // Remove keys that are not supported by most LLMs\n if (key === \"propertyNames\" || key === \"$schema\") {\n continue;\n }\n newObj[key] = cleanSchema(currentObj[key]);\n }\n\n // OpenAI and some other LLMs require additionalProperties: false for all objects in strict mode\n // AND every property must be explicitly listed in the 'required' array\n if (newObj.type === \"object\") {\n if (\n newObj.additionalProperties === undefined ||\n (newObj.additionalProperties &&\n typeof newObj.additionalProperties === \"object\" &&\n Object.keys(newObj.additionalProperties).length === 0)\n ) {\n newObj.additionalProperties = false;\n }\n\n if (newObj.additionalProperties === false && newObj.properties) {\n newObj.required = Object.keys(newObj.properties as object);\n }\n }\n\n return newObj;\n }\n return obj;\n}\n\n/**\n * Safely attempts to parse a value as JSON if it's a string.\n */\nexport function tryParseJSON(value: unknown): any {\n if (typeof value === \"string\") {\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n }\n return value;\n}\n","import type { MessagePart } from \"../types\";\n\n/**\n * Updates a list of message parts with a new part,\n * ensuring chronological order by sequence and merging contiguous text deltas.\n */\nexport function updateAgentMessageParts(parts: MessagePart[], newPart: MessagePart): MessagePart[] {\n // 1. Combine and sort all parts by their sequence ID\n const sorted = [...parts, newPart].sort((a, b) => {\n const aStart = a.type === \"text\" ? a.firstSequence : a.sequence;\n const bStart = b.type === \"text\" ? b.firstSequence : b.sequence;\n return aStart - bStart;\n });\n\n // 2. Reduce the sorted parts to merge contiguous text blocks\n return sorted.reduce<MessagePart[]>((acc, current) => {\n const last = acc[acc.length - 1];\n\n // Check if we can merge this text part with the previous one\n const canMerge =\n last?.type === \"text\" &&\n current.type === \"text\" &&\n current.firstSequence === last.lastSequence + 1;\n\n if (canMerge) {\n acc[acc.length - 1] = {\n ...last,\n text: last.text + current.text,\n lastSequence: current.lastSequence,\n };\n return acc;\n }\n\n acc.push(current);\n return acc;\n }, []);\n}\n","import { useState, useEffect, useCallback } from \"react\";\n\n// Helper to handle JSON parsing cleanly\nfunction parseJSON<T>(value: string | null, defaultValue: T): T {\n if (value === null) return defaultValue;\n try {\n return JSON.parse(value);\n } catch {\n return defaultValue;\n }\n}\n\nexport function useSyncedLocalStorage<T>(\n key: string,\n initialValue: T,\n): [T, (value: T | ((val: T) => T)) => void] {\n // Initialize state function to avoid reading localStorage on every render\n const [storedValue, setStoredValue] = useState<T>(() => {\n if (typeof window === \"undefined\") {\n return initialValue;\n }\n try {\n const item = window.localStorage.getItem(key);\n return parseJSON(item, initialValue);\n } catch (error) {\n console.warn(`Error reading localStorage key \"${key}\":`, error);\n return initialValue;\n }\n });\n\n // Function to update state and localStorage\n const setValue = useCallback(\n (value: T | ((val: T) => T)) => {\n try {\n setStoredValue((prev) => {\n const valueToStore = value instanceof Function ? value(prev) : value;\n\n if (typeof window !== \"undefined\") {\n window.localStorage.setItem(key, JSON.stringify(valueToStore));\n // Dispatch a custom event so other hooks in the same window update\n window.dispatchEvent(\n new StorageEvent(\"storage\", { key, newValue: JSON.stringify(valueToStore) }),\n );\n }\n return valueToStore;\n });\n } catch (error) {\n console.warn(`Error setting localStorage key \"${key}\":`, error);\n }\n },\n [key],\n );\n\n // Sync across tabs/windows and within the same window\n useEffect(() => {\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key === key) {\n setStoredValue(parseJSON(event.newValue, initialValue));\n }\n };\n\n window.addEventListener(\"storage\", handleStorageChange);\n return () => window.removeEventListener(\"storage\", handleStorageChange);\n }, [key, initialValue]);\n\n return [storedValue, setValue];\n}\n"],"mappings":"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","names":["useCallback","useRef","useState","useEffect","useMemo","useCallback","useRef","useRef","useCallback","useState","useEffect","useCallback","useRef","useState","useCallback","useMemo","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../src/agent-context.tsx","../src/use-agent.ts","../src/constants.ts","../src/session-utils.ts","../src/debug-handlers.ts","../src/utils/schema.ts","../src/utils/message.ts","../src/utils/use-synced-local-storage.ts"],"sourcesContent":["import {\n createContext,\n useContext,\n useCallback,\n useRef,\n useState,\n useEffect,\n useMemo,\n ReactNode,\n} from \"react\";\nimport useAgent from \"./use-agent\";\nimport type {\n Message,\n Session,\n DebugDataType,\n ClientToolDefinition,\n ClientToolResult,\n PendingToolCall,\n} from \"./types\";\nimport { useSyncedLocalStorage } from \"./utils/use-synced-local-storage\";\nimport { AGENT_SESSIONS_KEY, AGENT_DEBUG_DATA_KEY } from \"./constants\";\n\nexport interface AgentRunner {\n messages: Message[];\n inProgress: boolean;\n sessionId: string;\n sessions: Session[];\n debugData: Record<string, DebugDataType>;\n pendingToolCalls: PendingToolCall[];\n isPaused: boolean;\n handleSend: (\n input: string,\n options?: {\n context?: Record<string, unknown>;\n testBuildId?: string;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n tools?: ClientToolDefinition[];\n clientTools?: ClientToolDefinition[];\n },\n ) => Promise<void>;\n submitToolResults: (\n toolResults: ClientToolResult[],\n options?: {\n input?: string;\n context?: object;\n additionalHeaders?: Record<string, string>;\n },\n ) => Promise<void>;\n switchSession: (sessionId?: string) => void;\n deleteSession: (sessionId: string) => void;\n addOptimisticMessage: (input: string) => void;\n abort: () => void;\n}\n\ninterface AgentContextValue {\n initializeAgent: (agentId: string, agentUrl: string, accessKey?: string) => void;\n registerRunner: (agentId: string, runner: AgentRunner) => void;\n getRunner: (agentId: string) => AgentRunner | null;\n // Global state provided to useAgent hooks\n allSessions: Record<string, Record<string, Session>>;\n setAllSessions: (\n value:\n | Record<string, Record<string, Session>>\n | ((\n prev: Record<string, Record<string, Session>>,\n ) => Record<string, Record<string, Session>>),\n ) => void;\n debugData: Record<string, DebugDataType>;\n setDebugData: (\n value:\n | Record<string, DebugDataType>\n | ((prev: Record<string, DebugDataType>) => Record<string, DebugDataType>),\n ) => void;\n}\n\nconst AgentContext = createContext<AgentContextValue | null>(null);\n\nexport function AgentContextProvider({ children }: { children: ReactNode }) {\n const activeAgentsRef = useRef<Map<string, { agentUrl: string; accessKey?: string }>>(new Map());\n // Store runners in a ref since we push updates via registerRunner\n // Note: Changes to this Ref won't trigger re-renders of consumers of getRunner directly,\n // but since we return the 'runner' object which contains state,\n // and we access it via a hook that listens to updates (implemented below), it works out.\n // Actually, to make 'useAgentContext' reactive to runner changes, we need a subscription mechanism.\n const runnersRef = useRef<Map<string, AgentRunner>>(new Map());\n const listenersRef = useRef<Map<string, Set<() => void>>>(new Map());\n\n const [, forceUpdate] = useState({});\n\n // Global Sync State managed here to be shared\n const [allSessions, setAllSessions] = useSyncedLocalStorage<\n Record<string, Record<string, Session>>\n >(AGENT_SESSIONS_KEY, {});\n\n const [debugData, setDebugData] = useSyncedLocalStorage<Record<string, DebugDataType>>(\n AGENT_DEBUG_DATA_KEY,\n {},\n );\n\n const initializeAgent = useCallback((agentId: string, agentUrl: string, accessKey?: string) => {\n const existing = activeAgentsRef.current.get(agentId);\n\n if (!existing) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey });\n forceUpdate({});\n } else if (existing.agentUrl !== agentUrl || existing.accessKey !== accessKey) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey });\n forceUpdate({});\n }\n }, []);\n\n const registerRunner = useCallback((agentId: string, runner: AgentRunner) => {\n runnersRef.current.set(agentId, runner);\n // Notify listeners for this agentId\n const listeners = listenersRef.current.get(agentId);\n if (listeners) {\n listeners.forEach((callback) => callback());\n }\n }, []);\n\n const getRunner = useCallback((agentId: string) => {\n return runnersRef.current.get(agentId) || null;\n }, []);\n\n const contextValue = useMemo(\n () => ({\n initializeAgent,\n registerRunner,\n getRunner,\n allSessions,\n setAllSessions,\n debugData,\n setDebugData,\n runnersRef,\n listenersRef,\n }),\n [\n initializeAgent,\n registerRunner,\n getRunner,\n allSessions,\n setAllSessions,\n debugData,\n setDebugData,\n ],\n );\n\n return (\n <AgentContext.Provider value={contextValue}>\n {children}\n {Array.from(activeAgentsRef.current.entries()).map(([agentId, { agentUrl, accessKey }]) => (\n <AgentRunnerInstance key={agentId} agentId={agentId} agentUrl={agentUrl} accessKey={accessKey} />\n ))}\n </AgentContext.Provider>\n );\n}\n\nfunction AgentRunnerInstance({\n agentId,\n agentUrl,\n accessKey,\n}: {\n agentId: string;\n agentUrl: string;\n accessKey?: string;\n}) {\n const agent = useAgent(agentId, agentUrl, accessKey);\n const context = useContext(AgentContext);\n\n if (!context) return null;\n\n useEffect(() => {\n context.registerRunner(agentId, agent);\n }, [agentId, agent, context]);\n\n return null;\n}\n\nexport function useAgentContext(\n agentId: string,\n agentUrl: string,\n accessKey?: string,\n): AgentRunner {\n const context = useContext(AgentContext);\n\n if (!context) {\n throw new Error(\"useAgentContext must be used within AgentContextProvider\");\n }\n\n const { initializeAgent, getRunner, listenersRef } = context as AgentContextValue & {\n listenersRef: React.MutableRefObject<Map<string, Set<() => void>>>;\n };\n\n useEffect(() => {\n initializeAgent(agentId, agentUrl, accessKey);\n }, [agentId, agentUrl, initializeAgent]);\n\n // Reactive subscription to runner updates\n const [runner, setRunner] = useState<AgentRunner | null>(() => getRunner(agentId));\n\n useEffect(() => {\n // Current runner state\n const currentRunner = getRunner(agentId);\n if (currentRunner !== runner) {\n setRunner(currentRunner);\n }\n\n // Subscribe to future updates\n const callback = () => {\n setRunner(getRunner(agentId));\n };\n\n if (!listenersRef.current.has(agentId)) {\n listenersRef.current.set(agentId, new Set());\n }\n listenersRef.current.get(agentId)?.add(callback);\n\n return () => {\n listenersRef.current.get(agentId)?.delete(callback);\n };\n }, [agentId, getRunner]);\n\n const placeholder = useMemo(\n () => ({\n messages: [],\n inProgress: false,\n sessionId: \"\",\n sessions: [],\n debugData: {},\n pendingToolCalls: [],\n isPaused: false,\n handleSend: async () => {},\n submitToolResults: async () => {},\n switchSession: () => {},\n deleteSession: () => {},\n addOptimisticMessage: () => {},\n abort: () => {},\n }),\n [],\n );\n\n return runner || placeholder;\n}\n\n// Hook to access the global state for use-agent\nexport function useAgentGlobalState() {\n const context = useContext(AgentContext);\n if (!context) {\n throw new Error(\"useAgentGlobalState must be used within AgentContextProvider\");\n }\n return {\n allSessions: context.allSessions,\n setAllSessions: context.setAllSessions,\n debugData: context.debugData,\n setDebugData: context.setDebugData,\n };\n}\n","import { useCallback, useRef, useState, useEffect } from \"react\";\nimport { EventSourceMessage, fetchEventSource } from \"@microsoft/fetch-event-source\";\n\nimport { DEFAULT_SESSION_NAME, TEMPORARY_SESSION_ID } from \"./constants\";\nimport { useSessionUtils } from \"./session-utils\";\nimport { createDebugHandlers } from \"./debug-handlers\";\nimport { useAgentGlobalState } from \"./agent-context\";\nimport type {\n Message,\n MessagePart,\n OutputStreamEventType,\n ClientToolDefinition,\n ClientToolResult,\n PendingToolCall,\n AgentPausedResponse,\n} from \"./types\";\nimport { cleanSchema, tryParseJSON } from \"./utils/schema\";\nimport { updateAgentMessageParts } from \"./utils/message\";\n\nclass AgentPausedError extends Error {\n constructor(public pauseData: AgentPausedResponse[\"result\"]) {\n super(\"Agent paused\");\n this.name = \"AgentPausedError\";\n }\n}\n\nexport default function useAgent(agentId: string, agentUrl: string, accessKey?: string) {\n // Use global state from Context instead of Jotai atoms\n const { allSessions, setAllSessions, debugData, setDebugData } = useAgentGlobalState();\n\n const [inProgress, setInProgress] = useState(false);\n const [messages, setMessages] = useState<Array<Message>>([]);\n const [pendingToolCalls, setPendingToolCalls] = useState<Map<string, PendingToolCall>>(new Map());\n const [isPaused, setIsPaused] = useState(false);\n\n const messagesRef = useRef<Array<Message>>([]);\n const clientToolsRef = useRef<ClientToolDefinition[]>([]);\n\n // Initialize currentSessionId later after sessionUtils is available\n const [currentSessionId, setCurrentSessionId] = useState<string>(TEMPORARY_SESSION_ID);\n\n const sessionUtils = useSessionUtils(\n agentId,\n allSessions,\n setAllSessions,\n currentSessionId,\n setCurrentSessionId,\n messagesRef,\n );\n\n // Set initial session ID after sessionUtils is available\n useEffect(() => {\n const initialSessionId = sessionUtils.getInitialSessionId();\n setCurrentSessionId(initialSessionId);\n }, []);\n\n const debugHandlers = createDebugHandlers(setDebugData);\n\n // Keep messagesRef in sync with messages state\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n // Initialize or load session\n useEffect(() => {\n // Don't reset messages if we're currently in progress (streaming)\n if (inProgress) {\n return;\n }\n\n const session = sessionUtils.agentSessions[currentSessionId];\n\n if (session) {\n setMessages(session.messages);\n } else {\n setMessages([]);\n }\n }, [currentSessionId, sessionUtils.agentSessions, agentId, inProgress]);\n\n // Only sync on unmount to prevent data loss\n useEffect(() => {\n return () => {\n if (messagesRef.current.length > 0 && sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current();\n }\n };\n }, []);\n\n const controller = useRef<AbortController>();\n\n const runAgent = useCallback(\n async (\n input: string,\n options?: {\n context?: object;\n testBuildId?: string;\n additionalHeaders?: Record<string, string>;\n tools?: ClientToolDefinition[];\n clientTools?: ClientToolDefinition[];\n },\n ) => {\n setInProgress(true);\n // Abort any existing request before creating a new controller\n if (controller.current) {\n controller.current.abort();\n }\n controller.current = new AbortController();\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options?.additionalHeaders || {}),\n ...(accessKey ? { Authorization: `Bearer ${accessKey}` } : {}),\n };\n\n // Include session ID in headers if we have one\n if (currentSessionId) {\n headers[\"x-buildship-agent-session-id\"] = currentSessionId;\n }\n\n const body = {\n stream: true,\n input,\n context: options?.context || {},\n testBuildId: options?.testBuildId,\n tools: options?.tools?.map((t: { parameters: unknown }) => ({\n ...t,\n parameters: cleanSchema(t.parameters),\n })),\n clientTools: options?.clientTools?.map((t) => ({\n ...t,\n parameters: cleanSchema(t.parameters),\n requiresResult: t.requiresResult??false,\n })),\n };\n\n try {\n await fetchEventSource(agentUrl, {\n method: \"POST\",\n headers,\n signal: controller.current.signal,\n openWhenHidden: true,\n body: JSON.stringify(body),\n onopen: async (resp) => {\n // catch the 404 status\n if (resp.status >= 400) {\n console.log(`AI onopen error with status: ${resp.status}`);\n\n if (resp.status === 404) {\n // for resume operations with 404, throw a specific error for retry\n throw new Error(`Not Found (${resp.statusText})`);\n }\n\n throw new Error(`Error status ${resp.status}`);\n }\n\n // Extract session ID from response headers if we don't have one\n if (!currentSessionId || currentSessionId === TEMPORARY_SESSION_ID) {\n const sessionId = resp.headers.get(\"x-buildship-agent-session-id\");\n if (sessionId) {\n // Transfer current messages to the new session before switching\n const currentMessages = messagesRef.current;\n const sessionName =\n resp.headers.get(\"x-buildship-agent-session-name\") || DEFAULT_SESSION_NAME;\n\n sessionUtils.createSessionFromResponse(sessionId, sessionName, currentMessages);\n setCurrentSessionId(sessionId);\n }\n }\n\n if (resp.headers.get(\"content-type\")?.includes(\"application/json\")) {\n const data = (await resp.json()) as AgentPausedResponse;\n if (data.result?._?.paused) {\n // Agent paused for client tools\n // Add widget parts for pending actions\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newParts: MessagePart[] = data.result.clientActions.map((action, index) => ({\n type: \"widget\",\n toolName: action.toolName,\n callId: action.callId,\n inputs: action.inputs,\n sequence: (lastMessage?.parts?.length || 0) + index,\n }));\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n parts: [...(lastMessage.parts || []), ...newParts],\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: \"\",\n parts: newParts,\n executionId: Date.now().toString(), // No execution ID in pause response?\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n data.result.clientActions.forEach((action) => {\n updated.set(action.callId, {\n toolName: action.toolName,\n callId: action.callId,\n inputs: action.inputs,\n requiresResult: true, // Implicitly true for paused actions\n });\n });\n return updated;\n });\n\n setIsPaused(true);\n throw new AgentPausedError(data.result);\n }\n }\n\n // Extract execution ID from response headers and update the last user message\n const executionId = resp.headers.get(\"x-buildship-agent-execution-id\");\n if (executionId) {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n if (lastMessage?.role === \"user\") {\n const updatedMessage = {\n ...lastMessage,\n executionId: executionId,\n };\n const updatedMessages = [...prev.slice(0, -1), updatedMessage];\n\n // Sync updated user message\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n }\n return prev;\n });\n }\n },\n onmessage: (event: EventSourceMessage) => {\n try {\n const parsed = JSON.parse(event.data) as OutputStreamEventType;\n\n if (parsed.type === \"llm_text_delta\") {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const sequence = parsed.meta.sequence;\n const newPart: MessagePart = {\n type: \"text\",\n text: parsed.data,\n firstSequence: sequence,\n lastSequence: sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n content: lastMessage.content + parsed.data, // content is still useful for simple displays\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: parsed.data,\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (parsed.type === \"client_tool_call\") {\n const { toolName, callId, inputs } = parsed.data;\n\n // Check if this tool requires a result\n const toolDefinition = clientToolsRef.current.find((t) => t.name === toolName);\n const requiresResult = toolDefinition?.requiresResult ?? false;\n\n // Track pending tool call if it requires a result\n if (requiresResult) {\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n updated.set(callId, {\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n requiresResult,\n });\n return updated;\n });\n }\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newPart: MessagePart = {\n type: \"widget\",\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n sequence: parsed.meta.sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: \"\",\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (\n parsed.type.startsWith(\"debug_\") ||\n parsed.type === \"llm_reasoning_delta\" ||\n parsed.type === \"agent_handoff\" ||\n parsed.type === \"mcp_tool_call_start\" ||\n parsed.type === \"mcp_tool_call_end\"\n ) {\n debugHandlers.handleDebugEvent(parsed);\n }\n } catch (e) {\n console.log(\"Failed to parse agent message\", e);\n }\n },\n onclose: () => {\n console.log(\"Agent closed\");\n setInProgress(false);\n\n // Check if there are pending tool calls that require results\n setPendingToolCalls((currentPending) => {\n if (currentPending.size > 0) {\n setIsPaused(true);\n }\n return currentPending;\n });\n\n // Sync messages when streaming completes\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current();\n }\n },\n onerror: (e) => {\n if (e instanceof AgentPausedError) {\n throw e; // Stop retrying\n }\n console.log(\"Agent error\", e);\n setInProgress(false);\n // Sync messages on error to prevent data loss\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw new Error(\"Failed to execute agent\");\n },\n });\n } catch (error) {\n if (error instanceof AgentPausedError) {\n setInProgress(false);\n return;\n }\n console.log(\"Agent execution failed\", error);\n setInProgress(false);\n // Sync messages on execution failure\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw error;\n }\n },\n [agentUrl, accessKey, currentSessionId, sessionUtils, debugHandlers],\n );\n\n const resumeAgent = useCallback(\n async (\n toolResults: ClientToolResult[],\n options?: {\n input?: string;\n context?: object;\n additionalHeaders?: Record<string, string>;\n },\n ) => {\n if (!currentSessionId || currentSessionId === TEMPORARY_SESSION_ID) {\n throw new Error(\"Cannot resume: no active session\");\n }\n\n setInProgress(true);\n setIsPaused(false);\n\n // Abort any existing request before creating a new controller\n if (controller.current) {\n controller.current.abort();\n }\n controller.current = new AbortController();\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options?.additionalHeaders || {}),\n ...(accessKey ? { Authorization: `Bearer ${accessKey}` } : {}),\n };\n\n // Build resume URL - replace /executeAgent with /resumeAgent\n const baseUrl = agentUrl.replace(/\\/executeAgent\\/.*$/, \"\");\n const resumeUrl = `${baseUrl}/resumeAgent/${agentId}/${currentSessionId}`;\n\n const body = {\n stream: true,\n input: options?.input || \"\",\n context: options?.context || {},\n clientToolResults: toolResults,\n };\n\n try {\n await fetchEventSource(resumeUrl, {\n method: \"POST\",\n headers,\n signal: controller.current.signal,\n openWhenHidden: true,\n body: JSON.stringify(body),\n onopen: async (resp) => {\n if (resp.status >= 400) {\n console.log(`AI onopen error with status: ${resp.status}`);\n\n if (resp.status === 404) {\n throw new Error(`Session not found (${resp.statusText})`);\n }\n\n throw new Error(`Error status ${resp.status}`);\n }\n\n if (resp.headers.get(\"content-type\")?.includes(\"application/json\")) {\n const data = (await resp.json()) as AgentPausedResponse;\n if (data.result?._?.paused) {\n // Agent paused for client tools\n // Add widget parts for pending actions\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newParts: MessagePart[] = data.result.clientActions.map((action, index) => ({\n type: \"widget\",\n toolName: action.toolName,\n callId: action.callId,\n inputs: action.inputs,\n sequence: (lastMessage?.parts?.length || 0) + index,\n }));\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n parts: [...(lastMessage.parts || []), ...newParts],\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: \"\",\n parts: newParts,\n executionId: Date.now().toString(),\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n data.result.clientActions.forEach((action) => {\n updated.set(action.callId, {\n toolName: action.toolName,\n callId: action.callId,\n inputs: action.inputs,\n requiresResult: true,\n });\n });\n return updated;\n });\n\n setIsPaused(true);\n throw new AgentPausedError(data.result);\n }\n }\n\n // Extract execution ID from response headers\n const executionId = resp.headers.get(\"x-buildship-agent-execution-id\");\n if (executionId && options?.input) {\n // Add user message if input was provided\n setMessages((prev) => {\n const userMessage: Message = {\n role: \"user\" as const,\n content: options.input || \"\",\n executionId: executionId,\n };\n const updatedMessages = [...prev, userMessage];\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n }\n },\n onmessage: (event: EventSourceMessage) => {\n try {\n const parsed = JSON.parse(event.data) as OutputStreamEventType;\n\n if (parsed.type === \"llm_text_delta\") {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const sequence = parsed.meta.sequence;\n const newPart: MessagePart = {\n type: \"text\",\n text: parsed.data,\n firstSequence: sequence,\n lastSequence: sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n content: lastMessage.content + parsed.data,\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: parsed.data,\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (parsed.type === \"client_tool_call\") {\n const { toolName, callId, inputs } = parsed.data;\n\n // Check if this tool requires a result\n const toolDefinition = clientToolsRef.current.find((t) => t.name === toolName);\n const requiresResult = toolDefinition?.requiresResult ?? false;\n\n // Track pending tool call if it requires a result\n if (requiresResult) {\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n updated.set(callId, {\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n requiresResult,\n });\n return updated;\n });\n }\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newPart: MessagePart = {\n type: \"widget\",\n toolName,\n callId,\n inputs: tryParseJSON(inputs),\n sequence: parsed.meta.sequence,\n };\n\n let updatedMessages: Message[];\n\n if (lastMessage?.role === \"agent\") {\n const updatedMessage: Message = {\n ...lastMessage,\n parts: updateAgentMessageParts(lastMessage.parts || [], newPart),\n };\n updatedMessages = [...prev.slice(0, -1), updatedMessage];\n } else {\n const updatedMessage: Message = {\n role: \"agent\" as const,\n content: \"\",\n parts: [newPart],\n executionId: parsed.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n } else if (\n parsed.type.startsWith(\"debug_\") ||\n parsed.type === \"llm_reasoning_delta\" ||\n parsed.type === \"agent_handoff\" ||\n parsed.type === \"mcp_tool_call_start\" ||\n parsed.type === \"mcp_tool_call_end\"\n ) {\n debugHandlers.handleDebugEvent(parsed);\n }\n } catch (e) {\n console.log(\"Failed to parse agent message\", e);\n }\n },\n onclose: () => {\n console.log(\"Agent resume closed\");\n setInProgress(false);\n\n // Check if there are pending tool calls that require results\n setPendingToolCalls((currentPending) => {\n if (currentPending.size > 0) {\n setIsPaused(true);\n }\n return currentPending;\n });\n\n // Sync messages when streaming completes\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current();\n }\n },\n onerror: (e) => {\n if (e instanceof AgentPausedError) {\n throw e;\n }\n console.log(\"Agent resume error\", e);\n setInProgress(false);\n // Sync messages on error to prevent data loss\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw new Error(\"Failed to resume agent\");\n },\n });\n } catch (error) {\n if (error instanceof AgentPausedError) {\n setInProgress(false);\n return;\n }\n console.log(\"Agent resume execution failed\", error);\n setInProgress(false);\n // Sync messages on execution failure\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw error;\n }\n },\n [agentUrl, accessKey, currentSessionId, sessionUtils, debugHandlers],\n );\n\n const handleSend = useCallback(\n async (\n input: string,\n options?: {\n context?: object;\n testBuildId?: string;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n tools?: ClientToolDefinition[];\n clientTools?: ClientToolDefinition[];\n },\n ) => {\n // Store client tools for tracking requiresResult\n if (options?.clientTools) {\n clientToolsRef.current = options.clientTools;\n }\n\n // Clear pending tool calls when starting a new conversation\n setPendingToolCalls(new Map());\n setIsPaused(false);\n\n const userMessage = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n };\n\n // Only add user message if not skipping\n if (!options?.skipUserMessage) {\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n // Sync immediately after user message\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n }\n\n try {\n await runAgent(input, options);\n } catch (error) {\n // Ensure user message is preserved even if agent execution fails\n if (!options?.skipUserMessage) {\n setMessages((prev) => {\n const updatedMessages = prev.some((m) => m === userMessage)\n ? prev\n : [...prev, userMessage];\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n }\n throw error;\n }\n },\n [runAgent, sessionUtils.syncSessionRef],\n );\n\n const addOptimisticMessage = useCallback(\n (input: string) => {\n const userMessage = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n };\n\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n // Sync immediately after user message\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n },\n [sessionUtils.syncSessionRef],\n );\n\n const submitToolResults = useCallback(\n async (\n toolResults: ClientToolResult[],\n options?: {\n input?: string;\n context?: object;\n additionalHeaders?: Record<string, string>;\n },\n ) => {\n // Remove submitted tool calls from pending\n setPendingToolCalls((prev) => {\n const updated = new Map(prev);\n toolResults.forEach((result) => {\n updated.delete(result.callId);\n });\n return updated;\n });\n\n try {\n await resumeAgent(toolResults, options);\n } catch (error) {\n console.error(\"Failed to submit tool results:\", error);\n throw error;\n }\n },\n [resumeAgent],\n );\n\n const abort = useCallback(() => {\n if (controller.current) {\n controller.current.abort();\n }\n setInProgress(false);\n // Sync messages to prevent data loss\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n }, [sessionUtils.syncSessionRef]);\n\n return {\n inProgress,\n messages,\n handleSend,\n addOptimisticMessage,\n submitToolResults,\n abort,\n sessionId: currentSessionId,\n switchSession: sessionUtils.switchSession,\n deleteSession: sessionUtils.deleteSession,\n sessions: sessionUtils.sessionsList,\n debugData,\n pendingToolCalls: Array.from(pendingToolCalls.values()),\n isPaused,\n };\n}\n","export const AGENT_SESSIONS_KEY = \"buildship:agent:conversations\";\nexport const AGENT_DEBUG_DATA_KEY = \"buildship:agent:debug\";\n\nexport const DEFAULT_SESSION_NAME = \"New Chat\";\nexport const TEMPORARY_SESSION_ID = \"sess_temp\";\n","import { useCallback, useMemo, useRef } from \"react\";\nimport type { Message, Session } from \"./types\";\nimport { TEMPORARY_SESSION_ID } from \"./constants\";\n\nexport const useSessionUtils = (\n agentId: string,\n allSessions: Record<string, Record<string, Session>>,\n setAllSessions: (\n value:\n | Record<string, Record<string, Session>>\n | ((\n prev: Record<string, Record<string, Session>>,\n ) => Record<string, Record<string, Session>>),\n ) => void,\n currentSessionId: string,\n setCurrentSessionId: (sessionId: string) => void,\n messagesRef: React.MutableRefObject<Array<Message>>,\n) => {\n const agentSessions = useMemo(() => allSessions[agentId] || {}, [agentId, allSessions]);\n\n const syncSessionRef = useRef<(messages?: Array<Message>) => void>();\n\n syncSessionRef.current = (updatedMessages?: Array<Message>) => {\n if (!currentSessionId || currentSessionId === TEMPORARY_SESSION_ID) {\n return;\n }\n\n setAllSessions((prev) => ({\n ...prev,\n [agentId]: {\n ...prev[agentId],\n [currentSessionId]: {\n ...prev[agentId]?.[currentSessionId],\n messages: updatedMessages ?? messagesRef.current,\n updatedAt: Date.now(),\n },\n },\n }));\n };\n\n const getInitialSessionId = () => {\n const sessions = Object.values(agentSessions);\n if (sessions.length > 0) {\n return sessions.sort((a, b) => b.updatedAt - a.updatedAt)[0].id;\n }\n return TEMPORARY_SESSION_ID;\n };\n\n const switchSession = useCallback(\n (sessionId: string = TEMPORARY_SESSION_ID) => {\n setCurrentSessionId(sessionId);\n },\n [setCurrentSessionId],\n );\n\n const deleteSession = useCallback(\n (sessionId: string) => {\n if (!sessionId || sessionId === TEMPORARY_SESSION_ID) {\n return;\n }\n\n setAllSessions((prev) => {\n const updatedAgentSessions = { ...prev[agentId] };\n delete updatedAgentSessions[sessionId];\n\n return {\n ...prev,\n [agentId]: updatedAgentSessions,\n };\n });\n\n if (sessionId === currentSessionId) {\n const remainingSessions = Object.values(agentSessions).filter((s) => s.id !== sessionId);\n if (remainingSessions.length > 0) {\n const mostRecent = remainingSessions.sort((a, b) => b.updatedAt - a.updatedAt)[0];\n setCurrentSessionId(mostRecent.id);\n } else {\n setCurrentSessionId(TEMPORARY_SESSION_ID);\n }\n }\n },\n [agentId, currentSessionId, agentSessions, setAllSessions, setCurrentSessionId],\n );\n\n const sessionsList = useMemo(\n () => Object.values(agentSessions).sort((a, b) => b.updatedAt - a.updatedAt),\n [agentSessions],\n );\n\n const createSessionFromResponse = (\n sessionId: string,\n sessionName: string,\n currentMessages: Array<Message>,\n ) => {\n setAllSessions((prev) => ({\n ...prev,\n [agentId]: {\n ...prev[agentId],\n [sessionId]: {\n id: sessionId,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n messages: currentMessages,\n name: sessionName,\n },\n },\n }));\n };\n\n return {\n agentSessions,\n syncSessionRef,\n getInitialSessionId,\n switchSession,\n deleteSession,\n sessionsList,\n createSessionFromResponse,\n };\n};\n","import type {\n AgentDebugEventType,\n AgentHandoffEventType,\n DebugDataType,\n LLMReasoningDeltaEventType,\n ReasoningItem,\n ToolExecutionItem,\n HandoffItem,\n MCPToolCallStartEventType,\n MCPToolCallEndEventType,\n MCPToolExecutionItem,\n} from \"./types\";\n\nexport const createDebugHandlers = (\n setDebugData: (\n value:\n | Record<string, DebugDataType>\n | ((prev: Record<string, DebugDataType>) => Record<string, DebugDataType>),\n ) => void,\n) => {\n const handleDebugToolExecutionStarted = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"tool_call\",\n toolId: (parsed.data as { toolId?: string }).toolId || \"unknown\",\n toolCallId: (parsed.data as { toolCallId?: string }).toolCallId,\n status: \"progress\",\n },\n ],\n }));\n };\n\n const handleDebugToolExecutionInputs = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n currentData[i] = {\n ...toolItem,\n inputs: (parsed.data as { value: unknown }).value,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugToolExecutionFinished = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n currentData[i] = {\n ...toolItem,\n status: \"complete\",\n output: (parsed.data as { value: unknown }).value,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugToolExecutionError = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n currentData[i] = {\n ...toolItem,\n status: \"error\",\n output: (parsed.data as { value: unknown }).value,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugToolLog = (parsed: AgentDebugEventType) => {\n const executionId = parsed.meta.executionId;\n const toolCallId = (parsed.data as { toolCallId?: string }).toolCallId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"tool_call\") {\n const toolItem = currentData[i] as ToolExecutionItem;\n if (toolItem.toolCallId === toolCallId) {\n const currentLogs = toolItem.logs || [];\n currentData[i] = {\n ...toolItem,\n logs: [...currentLogs, (parsed.data as { value: unknown[] }).value[0]],\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n let lastReasoningIndex = -1;\n const handleDebugReasoningStep = (parsed: LLMReasoningDeltaEventType) => {\n const executionId = parsed.meta.executionId;\n const { delta, index } = parsed.data;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n if (lastReasoningIndex < index) {\n currentData.push({ itemType: \"reasoning\", reasoning: \"\" });\n lastReasoningIndex = index;\n }\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"reasoning\") {\n currentData[i] = {\n itemType: \"reasoning\",\n reasoning: (currentData[i] as ReasoningItem).reasoning + delta,\n };\n break;\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleAgentHandoff = (parsed: AgentHandoffEventType) => {\n const executionId = parsed.meta.executionId;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"handoff\",\n agentName: parsed.data.agentName,\n } as HandoffItem,\n ],\n }));\n };\n\n const handleMCPToolCallStart = (parsed: MCPToolCallStartEventType) => {\n const executionId = parsed.meta.executionId;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"mcp_tool_call\",\n toolName: parsed.data.toolName,\n serverName: parsed.data.serverName,\n callId: parsed.data.callId,\n status: \"progress\",\n inputs: parsed.data.inputs,\n } as MCPToolExecutionItem,\n ],\n }));\n };\n\n const handleMCPToolCallEnd = (parsed: MCPToolCallEndEventType) => {\n const executionId = parsed.meta.executionId;\n const callId = parsed.data.callId;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n for (let i = currentData.length - 1; i >= 0; i--) {\n if (currentData[i].itemType === \"mcp_tool_call\") {\n const mcpToolItem = currentData[i] as MCPToolExecutionItem;\n if (mcpToolItem.callId === callId) {\n currentData[i] = {\n ...mcpToolItem,\n status: parsed.data.error ? \"error\" : \"complete\",\n output: parsed.data.result,\n error: parsed.data.error,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n };\n\n const handleDebugEvent = (\n parsed:\n | AgentDebugEventType\n | LLMReasoningDeltaEventType\n | AgentHandoffEventType\n | MCPToolCallStartEventType\n | MCPToolCallEndEventType,\n ) => {\n switch (parsed.type) {\n case \"debug_tool_execution_started\":\n handleDebugToolExecutionStarted(parsed);\n break;\n case \"debug_tool_execution_inputs\":\n handleDebugToolExecutionInputs(parsed);\n break;\n case \"debug_tool_execution_finished\":\n handleDebugToolExecutionFinished(parsed);\n break;\n case \"debug_tool_execution_error\":\n handleDebugToolExecutionError(parsed);\n break;\n case \"debug_tool_log\":\n handleDebugToolLog(parsed);\n break;\n case \"llm_reasoning_delta\":\n handleDebugReasoningStep(parsed);\n break;\n case \"agent_handoff\":\n handleAgentHandoff(parsed);\n break;\n case \"mcp_tool_call_start\":\n handleMCPToolCallStart(parsed);\n break;\n case \"mcp_tool_call_end\":\n handleMCPToolCallEnd(parsed);\n break;\n }\n };\n\n return {\n handleDebugEvent,\n };\n};\n","/**\n * Helper to clean JSON Schema for LLM compatibility.\n * Replaces modern Draft 2020-12 features with older, more compatible alternatives.\n * Specifically handles OpenAI's 'Strict Mode' requirements.\n */\nexport function cleanSchema(obj: unknown): unknown {\n if (Array.isArray(obj)) {\n return obj.map(cleanSchema);\n } else if (obj !== null && typeof obj === \"object\") {\n const newObj: Record<string, unknown> = {};\n const currentObj = obj as Record<string, any>;\n\n for (const key in currentObj) {\n // Remove keys that are not supported by most LLMs\n if (key === \"propertyNames\" || key === \"$schema\") {\n continue;\n }\n newObj[key] = cleanSchema(currentObj[key]);\n }\n\n // OpenAI and some other LLMs require additionalProperties: false for all objects in strict mode\n // AND every property must be explicitly listed in the 'required' array\n if (newObj.type === \"object\") {\n if (\n newObj.additionalProperties === undefined ||\n (newObj.additionalProperties &&\n typeof newObj.additionalProperties === \"object\" &&\n Object.keys(newObj.additionalProperties).length === 0)\n ) {\n newObj.additionalProperties = false;\n }\n\n if (newObj.additionalProperties === false && newObj.properties) {\n newObj.required = Object.keys(newObj.properties as object);\n }\n }\n\n return newObj;\n }\n return obj;\n}\n\n/**\n * Safely attempts to parse a value as JSON if it's a string.\n */\nexport function tryParseJSON(value: unknown): any {\n if (typeof value === \"string\") {\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n }\n return value;\n}\n","import type { MessagePart } from \"../types\";\n\n/**\n * Updates a list of message parts with a new part,\n * ensuring chronological order by sequence and merging contiguous text deltas.\n */\nexport function updateAgentMessageParts(parts: MessagePart[], newPart: MessagePart): MessagePart[] {\n // 1. Combine and sort all parts by their sequence ID\n const sorted = [...parts, newPart].sort((a, b) => {\n const aStart = a.type === \"text\" ? a.firstSequence : a.sequence;\n const bStart = b.type === \"text\" ? b.firstSequence : b.sequence;\n return aStart - bStart;\n });\n\n // 2. Reduce the sorted parts to merge contiguous text blocks\n return sorted.reduce<MessagePart[]>((acc, current) => {\n const last = acc[acc.length - 1];\n\n // Check if we can merge this text part with the previous one\n const canMerge =\n last?.type === \"text\" &&\n current.type === \"text\" &&\n current.firstSequence === last.lastSequence + 1;\n\n if (canMerge) {\n acc[acc.length - 1] = {\n ...last,\n text: last.text + current.text,\n lastSequence: current.lastSequence,\n };\n return acc;\n }\n\n acc.push(current);\n return acc;\n }, []);\n}\n","import { useState, useEffect, useCallback } from \"react\";\n\n// Helper to handle JSON parsing cleanly\nfunction parseJSON<T>(value: string | null, defaultValue: T): T {\n if (value === null) return defaultValue;\n try {\n return JSON.parse(value);\n } catch {\n return defaultValue;\n }\n}\n\nexport function useSyncedLocalStorage<T>(\n key: string,\n initialValue: T,\n): [T, (value: T | ((val: T) => T)) => void] {\n // Initialize state function to avoid reading localStorage on every render\n const [storedValue, setStoredValue] = useState<T>(() => {\n if (typeof window === \"undefined\") {\n return initialValue;\n }\n try {\n const item = window.localStorage.getItem(key);\n return parseJSON(item, initialValue);\n } catch (error) {\n console.warn(`Error reading localStorage key \"${key}\":`, error);\n return initialValue;\n }\n });\n\n // Function to update state and localStorage\n const setValue = useCallback(\n (value: T | ((val: T) => T)) => {\n try {\n setStoredValue((prev) => {\n const valueToStore = value instanceof Function ? value(prev) : value;\n\n if (typeof window !== \"undefined\") {\n window.localStorage.setItem(key, JSON.stringify(valueToStore));\n // Dispatch a custom event so other hooks in the same window update\n window.dispatchEvent(\n new StorageEvent(\"storage\", { key, newValue: JSON.stringify(valueToStore) }),\n );\n }\n return valueToStore;\n });\n } catch (error) {\n console.warn(`Error setting localStorage key \"${key}\":`, error);\n }\n },\n [key],\n );\n\n // Sync across tabs/windows and within the same window\n useEffect(() => {\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key === key) {\n setStoredValue(parseJSON(event.newValue, initialValue));\n }\n };\n\n window.addEventListener(\"storage\", handleStorageChange);\n return () => window.removeEventListener(\"storage\", handleStorageChange);\n }, [key, initialValue]);\n\n return [storedValue, setValue];\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA,eAAAA;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC;AAAA,OAEK;;;ACTP,SAAS,eAAAC,cAAa,UAAAC,SAAQ,UAAU,iBAAiB;AACzD,SAA6B,wBAAwB;;;ACD9C,IAAM,qBAAqB;AAC3B,IAAM,uBAAuB;AAE7B,IAAM,uBAAuB;AAC7B,IAAM,uBAAuB;;;ACJpC,SAAS,aAAa,SAAS,cAAc;AAItC,IAAM,kBAAkB,CAC7B,SACA,aACA,gBAOA,kBACA,qBACA,gBACG;AACH,QAAM,gBAAgB,QAAQ,MAAM,YAAY,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,WAAW,CAAC;AAEtF,QAAM,iBAAiB,OAA4C;AAEnE,iBAAe,UAAU,CAAC,oBAAqC;AAC7D,QAAI,CAAC,oBAAoB,qBAAqB,sBAAsB;AAClE;AAAA,IACF;AAEA,mBAAe,CAAC,UAAU;AAAA,MACxB,GAAG;AAAA,MACH,CAAC,OAAO,GAAG;AAAA,QACT,GAAG,KAAK,OAAO;AAAA,QACf,CAAC,gBAAgB,GAAG;AAAA,UAClB,GAAG,KAAK,OAAO,IAAI,gBAAgB;AAAA,UACnC,UAAU,mBAAmB,YAAY;AAAA,UACzC,WAAW,KAAK,IAAI;AAAA,QACtB;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAEA,QAAM,sBAAsB,MAAM;AAChC,UAAM,WAAW,OAAO,OAAO,aAAa;AAC5C,QAAI,SAAS,SAAS,GAAG;AACvB,aAAO,SAAS,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,EAAE;AAAA,IAC/D;AACA,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB;AAAA,IACpB,CAAC,YAAoB,yBAAyB;AAC5C,0BAAoB,SAAS;AAAA,IAC/B;AAAA,IACA,CAAC,mBAAmB;AAAA,EACtB;AAEA,QAAM,gBAAgB;AAAA,IACpB,CAAC,cAAsB;AACrB,UAAI,CAAC,aAAa,cAAc,sBAAsB;AACpD;AAAA,MACF;AAEA,qBAAe,CAAC,SAAS;AACvB,cAAM,uBAAuB,EAAE,GAAG,KAAK,OAAO,EAAE;AAChD,eAAO,qBAAqB,SAAS;AAErC,eAAO;AAAA,UACL,GAAG;AAAA,UACH,CAAC,OAAO,GAAG;AAAA,QACb;AAAA,MACF,CAAC;AAED,UAAI,cAAc,kBAAkB;AAClC,cAAM,oBAAoB,OAAO,OAAO,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS;AACvF,YAAI,kBAAkB,SAAS,GAAG;AAChC,gBAAM,aAAa,kBAAkB,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AAChF,8BAAoB,WAAW,EAAE;AAAA,QACnC,OAAO;AACL,8BAAoB,oBAAoB;AAAA,QAC1C;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS,kBAAkB,eAAe,gBAAgB,mBAAmB;AAAA,EAChF;AAEA,QAAM,eAAe;AAAA,IACnB,MAAM,OAAO,OAAO,aAAa,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAAA,IAC3E,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,4BAA4B,CAChC,WACA,aACA,oBACG;AACH,mBAAe,CAAC,UAAU;AAAA,MACxB,GAAG;AAAA,MACH,CAAC,OAAO,GAAG;AAAA,QACT,GAAG,KAAK,OAAO;AAAA,QACf,CAAC,SAAS,GAAG;AAAA,UACX,IAAI;AAAA,UACJ,WAAW,KAAK,IAAI;AAAA,UACpB,WAAW,KAAK,IAAI;AAAA,UACpB,UAAU;AAAA,UACV,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACzGO,IAAM,sBAAsB,CACjC,iBAKG;AACH,QAAM,kCAAkC,CAAC,WAAgC;AACvE,UAAM,cAAc,OAAO,KAAK;AAChC,iBAAa,CAAC,UAAU;AAAA,MACtB,GAAG;AAAA,MACH,CAAC,WAAW,GAAG;AAAA,QACb,GAAI,KAAK,WAAW,KAAK,CAAC;AAAA,QAC1B;AAAA,UACE,UAAU;AAAA,UACV,QAAS,OAAO,KAA6B,UAAU;AAAA,UACvD,YAAa,OAAO,KAAiC;AAAA,UACrD,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAEA,QAAM,iCAAiC,CAAC,WAAgC;AACtE,UAAM,cAAc,OAAO,KAAK;AAChC,UAAM,aAAc,OAAO,KAAiC;AAC5D,iBAAa,CAAC,SAAS;AACrB,YAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,eAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAI,YAAY,CAAC,EAAE,aAAa,aAAa;AAC3C,gBAAM,WAAW,YAAY,CAAC;AAC9B,cAAI,SAAS,eAAe,YAAY;AACtC,wBAAY,CAAC,IAAI;AAAA,cACf,GAAG;AAAA,cACH,QAAS,OAAO,KAA4B;AAAA,YAC9C;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,WAAW,GAAG;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,mCAAmC,CAAC,WAAgC;AACxE,UAAM,cAAc,OAAO,KAAK;AAChC,UAAM,aAAc,OAAO,KAAiC;AAC5D,iBAAa,CAAC,SAAS;AACrB,YAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,eAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAI,YAAY,CAAC,EAAE,aAAa,aAAa;AAC3C,gBAAM,WAAW,YAAY,CAAC;AAC9B,cAAI,SAAS,eAAe,YAAY;AACtC,wBAAY,CAAC,IAAI;AAAA,cACf,GAAG;AAAA,cACH,QAAQ;AAAA,cACR,QAAS,OAAO,KAA4B;AAAA,YAC9C;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,WAAW,GAAG;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,gCAAgC,CAAC,WAAgC;AACrE,UAAM,cAAc,OAAO,KAAK;AAChC,UAAM,aAAc,OAAO,KAAiC;AAC5D,iBAAa,CAAC,SAAS;AACrB,YAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,eAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAI,YAAY,CAAC,EAAE,aAAa,aAAa;AAC3C,gBAAM,WAAW,YAAY,CAAC;AAC9B,cAAI,SAAS,eAAe,YAAY;AACtC,wBAAY,CAAC,IAAI;AAAA,cACf,GAAG;AAAA,cACH,QAAQ;AAAA,cACR,QAAS,OAAO,KAA4B;AAAA,YAC9C;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,WAAW,GAAG;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,qBAAqB,CAAC,WAAgC;AAC1D,UAAM,cAAc,OAAO,KAAK;AAChC,UAAM,aAAc,OAAO,KAAiC;AAC5D,iBAAa,CAAC,SAAS;AACrB,YAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,eAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAI,YAAY,CAAC,EAAE,aAAa,aAAa;AAC3C,gBAAM,WAAW,YAAY,CAAC;AAC9B,cAAI,SAAS,eAAe,YAAY;AACtC,kBAAM,cAAc,SAAS,QAAQ,CAAC;AACtC,wBAAY,CAAC,IAAI;AAAA,cACf,GAAG;AAAA,cACH,MAAM,CAAC,GAAG,aAAc,OAAO,KAA8B,MAAM,CAAC,CAAC;AAAA,YACvE;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,WAAW,GAAG;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,qBAAqB;AACzB,QAAM,2BAA2B,CAAC,WAAuC;AACvE,UAAM,cAAc,OAAO,KAAK;AAChC,UAAM,EAAE,OAAO,MAAM,IAAI,OAAO;AAChC,iBAAa,CAAC,SAAS;AACrB,YAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,UAAI,qBAAqB,OAAO;AAC9B,oBAAY,KAAK,EAAE,UAAU,aAAa,WAAW,GAAG,CAAC;AACzD,6BAAqB;AAAA,MACvB;AAEA,eAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAI,YAAY,CAAC,EAAE,aAAa,aAAa;AAC3C,sBAAY,CAAC,IAAI;AAAA,YACf,UAAU;AAAA,YACV,WAAY,YAAY,CAAC,EAAoB,YAAY;AAAA,UAC3D;AACA;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,WAAW,GAAG;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,qBAAqB,CAAC,WAAkC;AAC5D,UAAM,cAAc,OAAO,KAAK;AAChC,iBAAa,CAAC,UAAU;AAAA,MACtB,GAAG;AAAA,MACH,CAAC,WAAW,GAAG;AAAA,QACb,GAAI,KAAK,WAAW,KAAK,CAAC;AAAA,QAC1B;AAAA,UACE,UAAU;AAAA,UACV,WAAW,OAAO,KAAK;AAAA,QACzB;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAEA,QAAM,yBAAyB,CAAC,WAAsC;AACpE,UAAM,cAAc,OAAO,KAAK;AAChC,iBAAa,CAAC,UAAU;AAAA,MACtB,GAAG;AAAA,MACH,CAAC,WAAW,GAAG;AAAA,QACb,GAAI,KAAK,WAAW,KAAK,CAAC;AAAA,QAC1B;AAAA,UACE,UAAU;AAAA,UACV,UAAU,OAAO,KAAK;AAAA,UACtB,YAAY,OAAO,KAAK;AAAA,UACxB,QAAQ,OAAO,KAAK;AAAA,UACpB,QAAQ;AAAA,UACR,QAAQ,OAAO,KAAK;AAAA,QACtB;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAEA,QAAM,uBAAuB,CAAC,WAAoC;AAChE,UAAM,cAAc,OAAO,KAAK;AAChC,UAAM,SAAS,OAAO,KAAK;AAC3B,iBAAa,CAAC,SAAS;AACrB,YAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,eAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAI,YAAY,CAAC,EAAE,aAAa,iBAAiB;AAC/C,gBAAM,cAAc,YAAY,CAAC;AACjC,cAAI,YAAY,WAAW,QAAQ;AACjC,wBAAY,CAAC,IAAI;AAAA,cACf,GAAG;AAAA,cACH,QAAQ,OAAO,KAAK,QAAQ,UAAU;AAAA,cACtC,QAAQ,OAAO,KAAK;AAAA,cACpB,OAAO,OAAO,KAAK;AAAA,YACrB;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,WAAW,GAAG;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,mBAAmB,CACvB,WAMG;AACH,YAAQ,OAAO,MAAM;AAAA,MACnB,KAAK;AACH,wCAAgC,MAAM;AACtC;AAAA,MACF,KAAK;AACH,uCAA+B,MAAM;AACrC;AAAA,MACF,KAAK;AACH,yCAAiC,MAAM;AACvC;AAAA,MACF,KAAK;AACH,sCAA8B,MAAM;AACpC;AAAA,MACF,KAAK;AACH,2BAAmB,MAAM;AACzB;AAAA,MACF,KAAK;AACH,iCAAyB,MAAM;AAC/B;AAAA,MACF,KAAK;AACH,2BAAmB,MAAM;AACzB;AAAA,MACF,KAAK;AACH,+BAAuB,MAAM;AAC7B;AAAA,MACF,KAAK;AACH,6BAAqB,MAAM;AAC3B;AAAA,IACJ;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,EACF;AACF;;;AC7QO,SAAS,YAAY,KAAuB;AACjD,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAO,IAAI,IAAI,WAAW;AAAA,EAC5B,WAAW,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAClD,UAAM,SAAkC,CAAC;AACzC,UAAM,aAAa;AAEnB,eAAW,OAAO,YAAY;AAE5B,UAAI,QAAQ,mBAAmB,QAAQ,WAAW;AAChD;AAAA,MACF;AACA,aAAO,GAAG,IAAI,YAAY,WAAW,GAAG,CAAC;AAAA,IAC3C;AAIA,QAAI,OAAO,SAAS,UAAU;AAC5B,UACE,OAAO,yBAAyB,UAC/B,OAAO,wBACN,OAAO,OAAO,yBAAyB,YACvC,OAAO,KAAK,OAAO,oBAAoB,EAAE,WAAW,GACtD;AACA,eAAO,uBAAuB;AAAA,MAChC;AAEA,UAAI,OAAO,yBAAyB,SAAS,OAAO,YAAY;AAC9D,eAAO,WAAW,OAAO,KAAK,OAAO,UAAoB;AAAA,MAC3D;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKO,SAAS,aAAa,OAAqB;AAChD,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI;AACF,aAAO,KAAK,MAAM,KAAK;AAAA,IACzB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;;;AChDO,SAAS,wBAAwB,OAAsB,SAAqC;AAEjG,QAAM,SAAS,CAAC,GAAG,OAAO,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM;AAChD,UAAM,SAAS,EAAE,SAAS,SAAS,EAAE,gBAAgB,EAAE;AACvD,UAAM,SAAS,EAAE,SAAS,SAAS,EAAE,gBAAgB,EAAE;AACvD,WAAO,SAAS;AAAA,EAClB,CAAC;AAGD,SAAO,OAAO,OAAsB,CAAC,KAAK,YAAY;AACpD,UAAM,OAAO,IAAI,IAAI,SAAS,CAAC;AAG/B,UAAM,WACJ,MAAM,SAAS,UACf,QAAQ,SAAS,UACjB,QAAQ,kBAAkB,KAAK,eAAe;AAEhD,QAAI,UAAU;AACZ,UAAI,IAAI,SAAS,CAAC,IAAI;AAAA,QACpB,GAAG;AAAA,QACH,MAAM,KAAK,OAAO,QAAQ;AAAA,QAC1B,cAAc,QAAQ;AAAA,MACxB;AACA,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,OAAO;AAChB,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACP;;;ALjBA,IAAM,mBAAN,cAA+B,MAAM;AAAA,EACnC,YAAmB,WAA0C;AAC3D,UAAM,cAAc;AADH;AAEjB,SAAK,OAAO;AAAA,EACd;AACF;AAEe,SAAR,SAA0B,SAAiB,UAAkB,WAAoB;AAEtF,QAAM,EAAE,aAAa,gBAAgB,WAAW,aAAa,IAAI,oBAAoB;AAErF,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAyB,CAAC,CAAC;AAC3D,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAuC,oBAAI,IAAI,CAAC;AAChG,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,QAAM,cAAcC,QAAuB,CAAC,CAAC;AAC7C,QAAM,iBAAiBA,QAA+B,CAAC,CAAC;AAGxD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAiB,oBAAoB;AAErF,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,YAAU,MAAM;AACd,UAAM,mBAAmB,aAAa,oBAAoB;AAC1D,wBAAoB,gBAAgB;AAAA,EACtC,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgB,oBAAoB,YAAY;AAGtD,YAAU,MAAM;AACd,gBAAY,UAAU;AAAA,EACxB,GAAG,CAAC,QAAQ,CAAC;AAGb,YAAU,MAAM;AAEd,QAAI,YAAY;AACd;AAAA,IACF;AAEA,UAAM,UAAU,aAAa,cAAc,gBAAgB;AAE3D,QAAI,SAAS;AACX,kBAAY,QAAQ,QAAQ;AAAA,IAC9B,OAAO;AACL,kBAAY,CAAC,CAAC;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,kBAAkB,aAAa,eAAe,SAAS,UAAU,CAAC;AAGtE,YAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,YAAY,QAAQ,SAAS,KAAK,aAAa,eAAe,SAAS;AACzE,qBAAa,eAAe,QAAQ;AAAA,MACtC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,aAAaA,QAAwB;AAE3C,QAAM,WAAWC;AAAA,IACf,OACE,OACA,YAOG;AACH,oBAAc,IAAI;AAElB,UAAI,WAAW,SAAS;AACtB,mBAAW,QAAQ,MAAM;AAAA,MAC3B;AACA,iBAAW,UAAU,IAAI,gBAAgB;AAEzC,YAAM,UAAkC;AAAA,QACtC,gBAAgB;AAAA,QAChB,GAAI,SAAS,qBAAqB,CAAC;AAAA,QACnC,GAAI,YAAY,EAAE,eAAe,UAAU,SAAS,GAAG,IAAI,CAAC;AAAA,MAC9D;AAGA,UAAI,kBAAkB;AACpB,gBAAQ,8BAA8B,IAAI;AAAA,MAC5C;AAEA,YAAM,OAAO;AAAA,QACX,QAAQ;AAAA,QACR;AAAA,QACA,SAAS,SAAS,WAAW,CAAC;AAAA,QAC9B,aAAa,SAAS;AAAA,QACtB,OAAO,SAAS,OAAO,IAAI,CAAC,OAAgC;AAAA,UAC1D,GAAG;AAAA,UACH,YAAY,YAAY,EAAE,UAAU;AAAA,QACtC,EAAE;AAAA,QACF,aAAa,SAAS,aAAa,IAAI,CAAC,OAAO;AAAA,UAC7C,GAAG;AAAA,UACH,YAAY,YAAY,EAAE,UAAU;AAAA,UACpC,gBAAgB,EAAE,kBAAgB;AAAA,QACpC,EAAE;AAAA,MACJ;AAEA,UAAI;AACF,cAAM,iBAAiB,UAAU;AAAA,UAC/B,QAAQ;AAAA,UACR;AAAA,UACA,QAAQ,WAAW,QAAQ;AAAA,UAC3B,gBAAgB;AAAA,UAChB,MAAM,KAAK,UAAU,IAAI;AAAA,UACzB,QAAQ,OAAO,SAAS;AAEtB,gBAAI,KAAK,UAAU,KAAK;AACtB,sBAAQ,IAAI,gCAAgC,KAAK,MAAM,EAAE;AAEzD,kBAAI,KAAK,WAAW,KAAK;AAEvB,sBAAM,IAAI,MAAM,cAAc,KAAK,UAAU,GAAG;AAAA,cAClD;AAEA,oBAAM,IAAI,MAAM,gBAAgB,KAAK,MAAM,EAAE;AAAA,YAC/C;AAGA,gBAAI,CAAC,oBAAoB,qBAAqB,sBAAsB;AAClE,oBAAM,YAAY,KAAK,QAAQ,IAAI,8BAA8B;AACjE,kBAAI,WAAW;AAEb,sBAAM,kBAAkB,YAAY;AACpC,sBAAM,cACJ,KAAK,QAAQ,IAAI,gCAAgC,KAAK;AAExD,6BAAa,0BAA0B,WAAW,aAAa,eAAe;AAC9E,oCAAoB,SAAS;AAAA,cAC/B;AAAA,YACF;AAEA,gBAAI,KAAK,QAAQ,IAAI,cAAc,GAAG,SAAS,kBAAkB,GAAG;AAClE,oBAAM,OAAQ,MAAM,KAAK,KAAK;AAC9B,kBAAI,KAAK,QAAQ,GAAG,QAAQ;AAG1B,4BAAY,CAAC,SAAS;AACpB,wBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,wBAAM,WAA0B,KAAK,OAAO,cAAc,IAAI,CAAC,QAAQ,WAAW;AAAA,oBAChF,MAAM;AAAA,oBACN,UAAU,OAAO;AAAA,oBACjB,QAAQ,OAAO;AAAA,oBACf,QAAQ,OAAO;AAAA,oBACf,WAAW,aAAa,OAAO,UAAU,KAAK;AAAA,kBAChD,EAAE;AAEF,sBAAI;AAEJ,sBAAI,aAAa,SAAS,SAAS;AACjC,0BAAM,iBAA0B;AAAA,sBAC9B,GAAG;AAAA,sBACH,OAAO,CAAC,GAAI,YAAY,SAAS,CAAC,GAAI,GAAG,QAAQ;AAAA,oBACnD;AACA,sCAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,kBACzD,OAAO;AACL,0BAAM,iBAA0B;AAAA,sBAC9B,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,OAAO;AAAA,sBACP,aAAa,KAAK,IAAI,EAAE,SAAS;AAAA;AAAA,oBACnC;AACA,sCAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,kBAC5C;AAEA,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT,CAAC;AAED,oCAAoB,CAAC,SAAS;AAC5B,wBAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,uBAAK,OAAO,cAAc,QAAQ,CAAC,WAAW;AAC5C,4BAAQ,IAAI,OAAO,QAAQ;AAAA,sBACzB,UAAU,OAAO;AAAA,sBACjB,QAAQ,OAAO;AAAA,sBACf,QAAQ,OAAO;AAAA,sBACf,gBAAgB;AAAA;AAAA,oBAClB,CAAC;AAAA,kBACH,CAAC;AACD,yBAAO;AAAA,gBACT,CAAC;AAED,4BAAY,IAAI;AAChB,sBAAM,IAAI,iBAAiB,KAAK,MAAM;AAAA,cACxC;AAAA,YACF;AAGA,kBAAM,cAAc,KAAK,QAAQ,IAAI,gCAAgC;AACrE,gBAAI,aAAa;AACf,0BAAY,CAAC,SAAS;AACpB,sBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,oBAAI,aAAa,SAAS,QAAQ;AAChC,wBAAM,iBAAiB;AAAA,oBACrB,GAAG;AAAA,oBACH;AAAA,kBACF;AACA,wBAAM,kBAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAG7D,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT;AACA,uBAAO;AAAA,cACT,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UACA,WAAW,CAAC,UAA8B;AACxC,gBAAI;AACF,oBAAM,SAAS,KAAK,MAAM,MAAM,IAAI;AAEpC,kBAAI,OAAO,SAAS,kBAAkB;AACpC,4BAAY,CAAC,SAAS;AACpB,wBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,wBAAM,WAAW,OAAO,KAAK;AAC7B,wBAAM,UAAuB;AAAA,oBAC3B,MAAM;AAAA,oBACN,MAAM,OAAO;AAAA,oBACb,eAAe;AAAA,oBACf,cAAc;AAAA,kBAChB;AAEA,sBAAI;AAEJ,sBAAI,aAAa,SAAS,SAAS;AACjC,0BAAM,iBAA0B;AAAA,sBAC9B,GAAG;AAAA,sBACH,SAAS,YAAY,UAAU,OAAO;AAAA;AAAA,sBACtC,OAAO,wBAAwB,YAAY,SAAS,CAAC,GAAG,OAAO;AAAA,oBACjE;AACA,sCAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,kBACzD,OAAO;AACL,0BAAM,iBAA0B;AAAA,sBAC9B,MAAM;AAAA,sBACN,SAAS,OAAO;AAAA,sBAChB,OAAO,CAAC,OAAO;AAAA,sBACf,aAAa,OAAO,KAAK;AAAA,oBAC3B;AACA,sCAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,kBAC5C;AAEA,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT,CAAC;AAAA,cACH,WAAW,OAAO,SAAS,oBAAoB;AAC7C,sBAAM,EAAE,UAAU,QAAQ,OAAO,IAAI,OAAO;AAG5C,sBAAM,iBAAiB,eAAe,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAC7E,sBAAM,iBAAiB,gBAAgB,kBAAkB;AAGzD,oBAAI,gBAAgB;AAClB,sCAAoB,CAAC,SAAS;AAC5B,0BAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,4BAAQ,IAAI,QAAQ;AAAA,sBAClB;AAAA,sBACA;AAAA,sBACA,QAAQ,aAAa,MAAM;AAAA,sBAC3B;AAAA,oBACF,CAAC;AACD,2BAAO;AAAA,kBACT,CAAC;AAAA,gBACH;AAEA,4BAAY,CAAC,SAAS;AACpB,wBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,wBAAM,UAAuB;AAAA,oBAC3B,MAAM;AAAA,oBACN;AAAA,oBACA;AAAA,oBACA,QAAQ,aAAa,MAAM;AAAA,oBAC3B,UAAU,OAAO,KAAK;AAAA,kBACxB;AAEA,sBAAI;AAEJ,sBAAI,aAAa,SAAS,SAAS;AACjC,0BAAM,iBAA0B;AAAA,sBAC9B,GAAG;AAAA,sBACH,OAAO,wBAAwB,YAAY,SAAS,CAAC,GAAG,OAAO;AAAA,oBACjE;AACA,sCAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,kBACzD,OAAO;AACL,0BAAM,iBAA0B;AAAA,sBAC9B,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,OAAO,CAAC,OAAO;AAAA,sBACf,aAAa,OAAO,KAAK;AAAA,oBAC3B;AACA,sCAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,kBAC5C;AAEA,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT,CAAC;AAAA,cACH,WACE,OAAO,KAAK,WAAW,QAAQ,KAC/B,OAAO,SAAS,yBAChB,OAAO,SAAS,mBAChB,OAAO,SAAS,yBAChB,OAAO,SAAS,qBAChB;AACA,8BAAc,iBAAiB,MAAM;AAAA,cACvC;AAAA,YACF,SAAS,GAAG;AACV,sBAAQ,IAAI,iCAAiC,CAAC;AAAA,YAChD;AAAA,UACF;AAAA,UACA,SAAS,MAAM;AACb,oBAAQ,IAAI,cAAc;AAC1B,0BAAc,KAAK;AAGnB,gCAAoB,CAAC,mBAAmB;AACtC,kBAAI,eAAe,OAAO,GAAG;AAC3B,4BAAY,IAAI;AAAA,cAClB;AACA,qBAAO;AAAA,YACT,CAAC;AAGD,gBAAI,aAAa,eAAe,SAAS;AACvC,2BAAa,eAAe,QAAQ;AAAA,YACtC;AAAA,UACF;AAAA,UACA,SAAS,CAAC,MAAM;AACd,gBAAI,aAAa,kBAAkB;AACjC,oBAAM;AAAA,YACR;AACA,oBAAQ,IAAI,eAAe,CAAC;AAC5B,0BAAc,KAAK;AAEnB,gBAAI,aAAa,eAAe,SAAS;AACvC,2BAAa,eAAe,QAAQ,YAAY,OAAO;AAAA,YACzD;AACA,kBAAM,IAAI,MAAM,yBAAyB;AAAA,UAC3C;AAAA,QACF,CAAC;AAAA,MACH,SAAS,OAAO;AACd,YAAI,iBAAiB,kBAAkB;AACrC,wBAAc,KAAK;AACnB;AAAA,QACF;AACA,gBAAQ,IAAI,0BAA0B,KAAK;AAC3C,sBAAc,KAAK;AAEnB,YAAI,aAAa,eAAe,SAAS;AACvC,uBAAa,eAAe,QAAQ,YAAY,OAAO;AAAA,QACzD;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,UAAU,WAAW,kBAAkB,cAAc,aAAa;AAAA,EACrE;AAEA,QAAM,cAAcA;AAAA,IAClB,OACE,aACA,YAKG;AACH,UAAI,CAAC,oBAAoB,qBAAqB,sBAAsB;AAClE,cAAM,IAAI,MAAM,kCAAkC;AAAA,MACpD;AAEA,oBAAc,IAAI;AAClB,kBAAY,KAAK;AAGjB,UAAI,WAAW,SAAS;AACtB,mBAAW,QAAQ,MAAM;AAAA,MAC3B;AACA,iBAAW,UAAU,IAAI,gBAAgB;AAEzC,YAAM,UAAkC;AAAA,QACtC,gBAAgB;AAAA,QAChB,GAAI,SAAS,qBAAqB,CAAC;AAAA,QACnC,GAAI,YAAY,EAAE,eAAe,UAAU,SAAS,GAAG,IAAI,CAAC;AAAA,MAC9D;AAGA,YAAM,UAAU,SAAS,QAAQ,uBAAuB,EAAE;AAC1D,YAAM,YAAY,GAAG,OAAO,gBAAgB,OAAO,IAAI,gBAAgB;AAEvE,YAAM,OAAO;AAAA,QACX,QAAQ;AAAA,QACR,OAAO,SAAS,SAAS;AAAA,QACzB,SAAS,SAAS,WAAW,CAAC;AAAA,QAC9B,mBAAmB;AAAA,MACrB;AAEA,UAAI;AACF,cAAM,iBAAiB,WAAW;AAAA,UAChC,QAAQ;AAAA,UACR;AAAA,UACA,QAAQ,WAAW,QAAQ;AAAA,UAC3B,gBAAgB;AAAA,UAChB,MAAM,KAAK,UAAU,IAAI;AAAA,UACzB,QAAQ,OAAO,SAAS;AACtB,gBAAI,KAAK,UAAU,KAAK;AACtB,sBAAQ,IAAI,gCAAgC,KAAK,MAAM,EAAE;AAEzD,kBAAI,KAAK,WAAW,KAAK;AACvB,sBAAM,IAAI,MAAM,sBAAsB,KAAK,UAAU,GAAG;AAAA,cAC1D;AAEA,oBAAM,IAAI,MAAM,gBAAgB,KAAK,MAAM,EAAE;AAAA,YAC/C;AAEA,gBAAI,KAAK,QAAQ,IAAI,cAAc,GAAG,SAAS,kBAAkB,GAAG;AAClE,oBAAM,OAAQ,MAAM,KAAK,KAAK;AAC9B,kBAAI,KAAK,QAAQ,GAAG,QAAQ;AAG1B,4BAAY,CAAC,SAAS;AACpB,wBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,wBAAM,WAA0B,KAAK,OAAO,cAAc,IAAI,CAAC,QAAQ,WAAW;AAAA,oBAChF,MAAM;AAAA,oBACN,UAAU,OAAO;AAAA,oBACjB,QAAQ,OAAO;AAAA,oBACf,QAAQ,OAAO;AAAA,oBACf,WAAW,aAAa,OAAO,UAAU,KAAK;AAAA,kBAChD,EAAE;AAEF,sBAAI;AAEJ,sBAAI,aAAa,SAAS,SAAS;AACjC,0BAAM,iBAA0B;AAAA,sBAC9B,GAAG;AAAA,sBACH,OAAO,CAAC,GAAI,YAAY,SAAS,CAAC,GAAI,GAAG,QAAQ;AAAA,oBACnD;AACA,sCAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,kBACzD,OAAO;AACL,0BAAM,iBAA0B;AAAA,sBAC9B,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,OAAO;AAAA,sBACP,aAAa,KAAK,IAAI,EAAE,SAAS;AAAA,oBACnC;AACA,sCAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,kBAC5C;AAEA,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT,CAAC;AAED,oCAAoB,CAAC,SAAS;AAC5B,wBAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,uBAAK,OAAO,cAAc,QAAQ,CAAC,WAAW;AAC5C,4BAAQ,IAAI,OAAO,QAAQ;AAAA,sBACzB,UAAU,OAAO;AAAA,sBACjB,QAAQ,OAAO;AAAA,sBACf,QAAQ,OAAO;AAAA,sBACf,gBAAgB;AAAA,oBAClB,CAAC;AAAA,kBACH,CAAC;AACD,yBAAO;AAAA,gBACT,CAAC;AAED,4BAAY,IAAI;AAChB,sBAAM,IAAI,iBAAiB,KAAK,MAAM;AAAA,cACxC;AAAA,YACF;AAGA,kBAAM,cAAc,KAAK,QAAQ,IAAI,gCAAgC;AACrE,gBAAI,eAAe,SAAS,OAAO;AAEjC,0BAAY,CAAC,SAAS;AACpB,sBAAM,cAAuB;AAAA,kBAC3B,MAAM;AAAA,kBACN,SAAS,QAAQ,SAAS;AAAA,kBAC1B;AAAA,gBACF;AACA,sBAAM,kBAAkB,CAAC,GAAG,MAAM,WAAW;AAE7C,oBAAI,aAAa,eAAe,SAAS;AACvC,+BAAa,eAAe,QAAQ,eAAe;AAAA,gBACrD;AAEA,uBAAO;AAAA,cACT,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UACA,WAAW,CAAC,UAA8B;AACxC,gBAAI;AACF,oBAAM,SAAS,KAAK,MAAM,MAAM,IAAI;AAEpC,kBAAI,OAAO,SAAS,kBAAkB;AACpC,4BAAY,CAAC,SAAS;AACpB,wBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,wBAAM,WAAW,OAAO,KAAK;AAC7B,wBAAM,UAAuB;AAAA,oBAC3B,MAAM;AAAA,oBACN,MAAM,OAAO;AAAA,oBACb,eAAe;AAAA,oBACf,cAAc;AAAA,kBAChB;AAEA,sBAAI;AAEJ,sBAAI,aAAa,SAAS,SAAS;AACjC,0BAAM,iBAA0B;AAAA,sBAC9B,GAAG;AAAA,sBACH,SAAS,YAAY,UAAU,OAAO;AAAA,sBACtC,OAAO,wBAAwB,YAAY,SAAS,CAAC,GAAG,OAAO;AAAA,oBACjE;AACA,sCAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,kBACzD,OAAO;AACL,0BAAM,iBAA0B;AAAA,sBAC9B,MAAM;AAAA,sBACN,SAAS,OAAO;AAAA,sBAChB,OAAO,CAAC,OAAO;AAAA,sBACf,aAAa,OAAO,KAAK;AAAA,oBAC3B;AACA,sCAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,kBAC5C;AAEA,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT,CAAC;AAAA,cACH,WAAW,OAAO,SAAS,oBAAoB;AAC7C,sBAAM,EAAE,UAAU,QAAQ,OAAO,IAAI,OAAO;AAG5C,sBAAM,iBAAiB,eAAe,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAC7E,sBAAM,iBAAiB,gBAAgB,kBAAkB;AAGzD,oBAAI,gBAAgB;AAClB,sCAAoB,CAAC,SAAS;AAC5B,0BAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,4BAAQ,IAAI,QAAQ;AAAA,sBAClB;AAAA,sBACA;AAAA,sBACA,QAAQ,aAAa,MAAM;AAAA,sBAC3B;AAAA,oBACF,CAAC;AACD,2BAAO;AAAA,kBACT,CAAC;AAAA,gBACH;AAEA,4BAAY,CAAC,SAAS;AACpB,wBAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,wBAAM,UAAuB;AAAA,oBAC3B,MAAM;AAAA,oBACN;AAAA,oBACA;AAAA,oBACA,QAAQ,aAAa,MAAM;AAAA,oBAC3B,UAAU,OAAO,KAAK;AAAA,kBACxB;AAEA,sBAAI;AAEJ,sBAAI,aAAa,SAAS,SAAS;AACjC,0BAAM,iBAA0B;AAAA,sBAC9B,GAAG;AAAA,sBACH,OAAO,wBAAwB,YAAY,SAAS,CAAC,GAAG,OAAO;AAAA,oBACjE;AACA,sCAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,kBACzD,OAAO;AACL,0BAAM,iBAA0B;AAAA,sBAC9B,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,OAAO,CAAC,OAAO;AAAA,sBACf,aAAa,OAAO,KAAK;AAAA,oBAC3B;AACA,sCAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,kBAC5C;AAEA,sBAAI,aAAa,eAAe,SAAS;AACvC,iCAAa,eAAe,QAAQ,eAAe;AAAA,kBACrD;AAEA,yBAAO;AAAA,gBACT,CAAC;AAAA,cACH,WACE,OAAO,KAAK,WAAW,QAAQ,KAC/B,OAAO,SAAS,yBAChB,OAAO,SAAS,mBAChB,OAAO,SAAS,yBAChB,OAAO,SAAS,qBAChB;AACA,8BAAc,iBAAiB,MAAM;AAAA,cACvC;AAAA,YACF,SAAS,GAAG;AACV,sBAAQ,IAAI,iCAAiC,CAAC;AAAA,YAChD;AAAA,UACF;AAAA,UACA,SAAS,MAAM;AACb,oBAAQ,IAAI,qBAAqB;AACjC,0BAAc,KAAK;AAGnB,gCAAoB,CAAC,mBAAmB;AACtC,kBAAI,eAAe,OAAO,GAAG;AAC3B,4BAAY,IAAI;AAAA,cAClB;AACA,qBAAO;AAAA,YACT,CAAC;AAGD,gBAAI,aAAa,eAAe,SAAS;AACvC,2BAAa,eAAe,QAAQ;AAAA,YACtC;AAAA,UACF;AAAA,UACA,SAAS,CAAC,MAAM;AACd,gBAAI,aAAa,kBAAkB;AACjC,oBAAM;AAAA,YACR;AACA,oBAAQ,IAAI,sBAAsB,CAAC;AACnC,0BAAc,KAAK;AAEnB,gBAAI,aAAa,eAAe,SAAS;AACvC,2BAAa,eAAe,QAAQ,YAAY,OAAO;AAAA,YACzD;AACA,kBAAM,IAAI,MAAM,wBAAwB;AAAA,UAC1C;AAAA,QACF,CAAC;AAAA,MACH,SAAS,OAAO;AACd,YAAI,iBAAiB,kBAAkB;AACrC,wBAAc,KAAK;AACnB;AAAA,QACF;AACA,gBAAQ,IAAI,iCAAiC,KAAK;AAClD,sBAAc,KAAK;AAEnB,YAAI,aAAa,eAAe,SAAS;AACvC,uBAAa,eAAe,QAAQ,YAAY,OAAO;AAAA,QACzD;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,UAAU,WAAW,kBAAkB,cAAc,aAAa;AAAA,EACrE;AAEA,QAAM,aAAaA;AAAA,IACjB,OACE,OACA,YAQG;AAEH,UAAI,SAAS,aAAa;AACxB,uBAAe,UAAU,QAAQ;AAAA,MACnC;AAGA,0BAAoB,oBAAI,IAAI,CAAC;AAC7B,kBAAY,KAAK;AAEjB,YAAM,cAAc;AAAA,QAClB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aAAa,KAAK,IAAI,EAAE,SAAS;AAAA,MACnC;AAGA,UAAI,CAAC,SAAS,iBAAiB;AAC7B,oBAAY,CAAC,SAAS;AACpB,gBAAM,kBAAkB,CAAC,GAAG,MAAM,WAAW;AAE7C,cAAI,aAAa,eAAe,SAAS;AACvC,yBAAa,eAAe,QAAQ,eAAe;AAAA,UACrD;AACA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAEA,UAAI;AACF,cAAM,SAAS,OAAO,OAAO;AAAA,MAC/B,SAAS,OAAO;AAEd,YAAI,CAAC,SAAS,iBAAiB;AAC7B,sBAAY,CAAC,SAAS;AACpB,kBAAM,kBAAkB,KAAK,KAAK,CAAC,MAAM,MAAM,WAAW,IACtD,OACA,CAAC,GAAG,MAAM,WAAW;AACzB,gBAAI,aAAa,eAAe,SAAS;AACvC,2BAAa,eAAe,QAAQ,eAAe;AAAA,YACrD;AACA,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,UAAU,aAAa,cAAc;AAAA,EACxC;AAEA,QAAM,uBAAuBA;AAAA,IAC3B,CAAC,UAAkB;AACjB,YAAM,cAAc;AAAA,QAClB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aAAa,KAAK,IAAI,EAAE,SAAS;AAAA,MACnC;AAEA,kBAAY,CAAC,SAAS;AACpB,cAAM,kBAAkB,CAAC,GAAG,MAAM,WAAW;AAE7C,YAAI,aAAa,eAAe,SAAS;AACvC,uBAAa,eAAe,QAAQ,eAAe;AAAA,QACrD;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAAC,aAAa,cAAc;AAAA,EAC9B;AAEA,QAAM,oBAAoBA;AAAA,IACxB,OACE,aACA,YAKG;AAEH,0BAAoB,CAAC,SAAS;AAC5B,cAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,oBAAY,QAAQ,CAAC,WAAW;AAC9B,kBAAQ,OAAO,OAAO,MAAM;AAAA,QAC9B,CAAC;AACD,eAAO;AAAA,MACT,CAAC;AAED,UAAI;AACF,cAAM,YAAY,aAAa,OAAO;AAAA,MACxC,SAAS,OAAO;AACd,gBAAQ,MAAM,kCAAkC,KAAK;AACrD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,QAAM,QAAQA,aAAY,MAAM;AAC9B,QAAI,WAAW,SAAS;AACtB,iBAAW,QAAQ,MAAM;AAAA,IAC3B;AACA,kBAAc,KAAK;AAEnB,QAAI,aAAa,eAAe,SAAS;AACvC,mBAAa,eAAe,QAAQ,YAAY,OAAO;AAAA,IACzD;AAAA,EACF,GAAG,CAAC,aAAa,cAAc,CAAC;AAEhC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,eAAe,aAAa;AAAA,IAC5B,eAAe,aAAa;AAAA,IAC5B,UAAU,aAAa;AAAA,IACvB;AAAA,IACA,kBAAkB,MAAM,KAAK,iBAAiB,OAAO,CAAC;AAAA,IACtD;AAAA,EACF;AACF;;;AM7zBA,SAAS,YAAAC,WAAU,aAAAC,YAAW,eAAAC,oBAAmB;AAGjD,SAAS,UAAa,OAAsB,cAAoB;AAC9D,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI;AACF,WAAO,KAAK,MAAM,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,sBACd,KACA,cAC2C;AAE3C,QAAM,CAAC,aAAa,cAAc,IAAIF,UAAY,MAAM;AACtD,QAAI,OAAO,WAAW,aAAa;AACjC,aAAO;AAAA,IACT;AACA,QAAI;AACF,YAAM,OAAO,OAAO,aAAa,QAAQ,GAAG;AAC5C,aAAO,UAAU,MAAM,YAAY;AAAA,IACrC,SAAS,OAAO;AACd,cAAQ,KAAK,mCAAmC,GAAG,MAAM,KAAK;AAC9D,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAGD,QAAM,WAAWE;AAAA,IACf,CAAC,UAA+B;AAC9B,UAAI;AACF,uBAAe,CAAC,SAAS;AACvB,gBAAM,eAAe,iBAAiB,WAAW,MAAM,IAAI,IAAI;AAE/D,cAAI,OAAO,WAAW,aAAa;AACjC,mBAAO,aAAa,QAAQ,KAAK,KAAK,UAAU,YAAY,CAAC;AAE7D,mBAAO;AAAA,cACL,IAAI,aAAa,WAAW,EAAE,KAAK,UAAU,KAAK,UAAU,YAAY,EAAE,CAAC;AAAA,YAC7E;AAAA,UACF;AACA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH,SAAS,OAAO;AACd,gBAAQ,KAAK,mCAAmC,GAAG,MAAM,KAAK;AAAA,MAChE;AAAA,IACF;AAAA,IACA,CAAC,GAAG;AAAA,EACN;AAGA,EAAAD,WAAU,MAAM;AACd,UAAM,sBAAsB,CAAC,UAAwB;AACnD,UAAI,MAAM,QAAQ,KAAK;AACrB,uBAAe,UAAU,MAAM,UAAU,YAAY,CAAC;AAAA,MACxD;AAAA,IACF;AAEA,WAAO,iBAAiB,WAAW,mBAAmB;AACtD,WAAO,MAAM,OAAO,oBAAoB,WAAW,mBAAmB;AAAA,EACxE,GAAG,CAAC,KAAK,YAAY,CAAC;AAEtB,SAAO,CAAC,aAAa,QAAQ;AAC/B;;;APmFI,SAGI,KAHJ;AAzEJ,IAAM,eAAe,cAAwC,IAAI;AAE1D,SAAS,qBAAqB,EAAE,SAAS,GAA4B;AAC1E,QAAM,kBAAkBE,QAA8D,oBAAI,IAAI,CAAC;AAM/F,QAAM,aAAaA,QAAiC,oBAAI,IAAI,CAAC;AAC7D,QAAM,eAAeA,QAAqC,oBAAI,IAAI,CAAC;AAEnE,QAAM,CAAC,EAAE,WAAW,IAAIC,UAAS,CAAC,CAAC;AAGnC,QAAM,CAAC,aAAa,cAAc,IAAI,sBAEpC,oBAAoB,CAAC,CAAC;AAExB,QAAM,CAAC,WAAW,YAAY,IAAI;AAAA,IAChC;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,kBAAkBC,aAAY,CAAC,SAAiB,UAAkB,cAAuB;AAC7F,UAAM,WAAW,gBAAgB,QAAQ,IAAI,OAAO;AAEpD,QAAI,CAAC,UAAU;AACb,sBAAgB,QAAQ,IAAI,SAAS,EAAE,UAAU,UAAU,CAAC;AAC5D,kBAAY,CAAC,CAAC;AAAA,IAChB,WAAW,SAAS,aAAa,YAAY,SAAS,cAAc,WAAW;AAC7E,sBAAgB,QAAQ,IAAI,SAAS,EAAE,UAAU,UAAU,CAAC;AAC5D,kBAAY,CAAC,CAAC;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAiBA,aAAY,CAAC,SAAiB,WAAwB;AAC3E,eAAW,QAAQ,IAAI,SAAS,MAAM;AAEtC,UAAM,YAAY,aAAa,QAAQ,IAAI,OAAO;AAClD,QAAI,WAAW;AACb,gBAAU,QAAQ,CAAC,aAAa,SAAS,CAAC;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,YAAYA,aAAY,CAAC,YAAoB;AACjD,WAAO,WAAW,QAAQ,IAAI,OAAO,KAAK;AAAA,EAC5C,GAAG,CAAC,CAAC;AAEL,QAAM,eAAeC;AAAA,IACnB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SACE,qBAAC,aAAa,UAAb,EAAsB,OAAO,cAC3B;AAAA;AAAA,IACA,MAAM,KAAK,gBAAgB,QAAQ,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,EAAE,UAAU,UAAU,CAAC,MACnF,oBAAC,uBAAkC,SAAkB,UAAoB,aAA/C,OAAqE,CAChG;AAAA,KACH;AAEJ;AAEA,SAAS,oBAAoB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,QAAQ,SAAS,SAAS,UAAU,SAAS;AACnD,QAAM,UAAU,WAAW,YAAY;AAEvC,MAAI,CAAC,QAAS,QAAO;AAErB,EAAAC,WAAU,MAAM;AACd,YAAQ,eAAe,SAAS,KAAK;AAAA,EACvC,GAAG,CAAC,SAAS,OAAO,OAAO,CAAC;AAE5B,SAAO;AACT;AAEO,SAAS,gBACd,SACA,UACA,WACa;AACb,QAAM,UAAU,WAAW,YAAY;AAEvC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AAEA,QAAM,EAAE,iBAAiB,WAAW,aAAa,IAAI;AAIrD,EAAAA,WAAU,MAAM;AACd,oBAAgB,SAAS,UAAU,SAAS;AAAA,EAC9C,GAAG,CAAC,SAAS,UAAU,eAAe,CAAC;AAGvC,QAAM,CAAC,QAAQ,SAAS,IAAIH,UAA6B,MAAM,UAAU,OAAO,CAAC;AAEjF,EAAAG,WAAU,MAAM;AAEd,UAAM,gBAAgB,UAAU,OAAO;AACvC,QAAI,kBAAkB,QAAQ;AAC5B,gBAAU,aAAa;AAAA,IACzB;AAGA,UAAM,WAAW,MAAM;AACrB,gBAAU,UAAU,OAAO,CAAC;AAAA,IAC9B;AAEA,QAAI,CAAC,aAAa,QAAQ,IAAI,OAAO,GAAG;AACtC,mBAAa,QAAQ,IAAI,SAAS,oBAAI,IAAI,CAAC;AAAA,IAC7C;AACA,iBAAa,QAAQ,IAAI,OAAO,GAAG,IAAI,QAAQ;AAE/C,WAAO,MAAM;AACX,mBAAa,QAAQ,IAAI,OAAO,GAAG,OAAO,QAAQ;AAAA,IACpD;AAAA,EACF,GAAG,CAAC,SAAS,SAAS,CAAC;AAEvB,QAAM,cAAcD;AAAA,IAClB,OAAO;AAAA,MACL,UAAU,CAAC;AAAA,MACX,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,UAAU,CAAC;AAAA,MACX,WAAW,CAAC;AAAA,MACZ,kBAAkB,CAAC;AAAA,MACnB,UAAU;AAAA,MACV,YAAY,YAAY;AAAA,MAAC;AAAA,MACzB,mBAAmB,YAAY;AAAA,MAAC;AAAA,MAChC,eAAe,MAAM;AAAA,MAAC;AAAA,MACtB,eAAe,MAAM;AAAA,MAAC;AAAA,MACtB,sBAAsB,MAAM;AAAA,MAAC;AAAA,MAC7B,OAAO,MAAM;AAAA,MAAC;AAAA,IAChB;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SAAO,UAAU;AACnB;AAGO,SAAS,sBAAsB;AACpC,QAAM,UAAU,WAAW,YAAY;AACvC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,8DAA8D;AAAA,EAChF;AACA,SAAO;AAAA,IACL,aAAa,QAAQ;AAAA,IACrB,gBAAgB,QAAQ;AAAA,IACxB,WAAW,QAAQ;AAAA,IACnB,cAAc,QAAQ;AAAA,EACxB;AACF;","names":["useCallback","useRef","useState","useEffect","useMemo","useCallback","useRef","useRef","useCallback","useState","useEffect","useCallback","useRef","useState","useCallback","useMemo","useEffect"]}
|
package/package.json
CHANGED