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 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) {
@@ -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":"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","names":["useCallback","useRef","useState","useEffect","useMemo","useCallback","useRef","useRef","useCallback","useState","useEffect","useCallback","useRef","useState","useCallback","useMemo","useEffect"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buildship-agent",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "A React library for building AI agent applications with streaming responses, interactive tools, and session management.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",