bs-agent 0.0.18 → 0.0.19
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/react/index.cjs +14 -0
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +14 -0
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.cjs
CHANGED
|
@@ -637,6 +637,20 @@ function useAgent(agent, options) {
|
|
|
637
637
|
}
|
|
638
638
|
return updatedMessages;
|
|
639
639
|
});
|
|
640
|
+
} else if (options2?.skipUserMessage && options2?.context) {
|
|
641
|
+
setMessages((prev) => {
|
|
642
|
+
const lastUserIdx = prev.findLastIndex((m) => m.role === "user");
|
|
643
|
+
if (lastUserIdx === -1) return prev;
|
|
644
|
+
const updatedMessages = [...prev];
|
|
645
|
+
updatedMessages[lastUserIdx] = {
|
|
646
|
+
...updatedMessages[lastUserIdx],
|
|
647
|
+
context: options2.context
|
|
648
|
+
};
|
|
649
|
+
if (sessionUtils.syncSessionRef.current) {
|
|
650
|
+
sessionUtils.syncSessionRef.current(updatedMessages);
|
|
651
|
+
}
|
|
652
|
+
return updatedMessages;
|
|
653
|
+
});
|
|
640
654
|
}
|
|
641
655
|
const effectiveExecutionId = options2?.skipUserMessage ? messagesRef.current.findLast((m) => m.role === "user")?.executionId ?? userMessage.executionId : userMessage.executionId;
|
|
642
656
|
lastRunOptionsRef.current = {
|
package/dist/react/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/index.ts","../../src/react/agent-context.tsx","../../src/react/use-agent.ts","../../src/react/constants.ts","../../src/react/session-utils.ts","../../src/react/debug-handlers.ts","../../src/react/client-tools.ts","../../src/react/utils/schema.ts","../../src/react/utils/message.ts","../../src/react/stream-callbacks.ts","../../src/core/stream.ts","../../src/core/session.ts","../../src/core/agent.ts","../../src/react/utils/use-synced-local-storage.ts","../../src/react/use-client-tool.ts"],"sourcesContent":["export * from \"./types\";\nexport * from \"./agent-context\";\nexport { default as useAgent } from \"./use-agent\";\nexport { useClientTool, ToolRenderer } from \"./use-client-tool\";\nexport type { ClientToolConfig, ClientToolRenderProps } from \"./use-client-tool\";\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, { type UseAgentOptions } from \"./use-agent\";\nimport { BuildShipAgent } from \"../core/agent\";\nimport type { Message, Session, DebugDataType } from \"./types\";\nimport type { ClientToolConfig } from \"./use-client-tool\";\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 handleSend: (\n input: string,\n options?: {\n context?: Record<string, unknown>;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n /** @deprecated Use `useClientTool` hook instead. */\n clientTools?: Array<{\n name: string;\n description: string;\n parameters: unknown;\n await?: boolean;\n }>;\n },\n ) => Promise<void>;\n resumeTool: (callId: string, result: any) => Promise<void>;\n switchSession: (sessionId?: string) => void;\n deleteSession: (sessionId: string) => void;\n addOptimisticMessage: (input: string, context?: Record<string, any>) => void;\n abort: () => void;\n}\n\n// ─── Tool Registry Context ──────────────────────────────────────────────────\n\nexport interface AgentToolContextValue {\n registerTool: (agentId: string, config: ClientToolConfig) => void;\n unregisterTool: (agentId: string, toolName: string) => void;\n getTool: (agentId: string, toolName: string) => ClientToolConfig | undefined;\n getToolsForAgent: (agentId: string) => ClientToolConfig[];\n resumeTool: (agentId: string, callId: string, result: any) => void;\n}\n\nexport const AgentToolContext = createContext<AgentToolContextValue | null>(null);\n\n// ─── Agent Context ──────────────────────────────────────────────────────────\n\ninterface AgentContextValue {\n initializeAgent: (\n agentId: string,\n agentUrl: string,\n accessKey?: string,\n options?: UseAgentOptions,\n ) => 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<\n Map<string, { agentUrl: string; accessKey?: string; options?: UseAgentOptions }>\n >(new Map());\n const runnersRef = useRef<Map<string, AgentRunner>>(new Map());\n const listenersRef = useRef<Map<string, Set<() => void>>>(new Map());\n\n // Tool registry: agentId -> Map<toolName, ClientToolConfig>\n const toolRegistryRef = useRef<Map<string, Map<string, ClientToolConfig>>>(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(\n (agentId: string, agentUrl: string, accessKey?: string, options?: UseAgentOptions) => {\n const existing = activeAgentsRef.current.get(agentId);\n\n if (!existing) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey, options });\n forceUpdate({});\n } else if (existing.agentUrl !== agentUrl || existing.accessKey !== accessKey) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey, options });\n forceUpdate({});\n } else if (options) {\n // Always update options ref (e.g. textDeltaModifier) without triggering re-render\n existing.options = options;\n }\n },\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 // ─── Tool registry methods ─────────────────────────────────────────\n\n const registerTool = useCallback((agentId: string, config: ClientToolConfig) => {\n if (!toolRegistryRef.current.has(agentId)) {\n toolRegistryRef.current.set(agentId, new Map());\n }\n toolRegistryRef.current.get(agentId)!.set(config.name, config);\n }, []);\n\n const unregisterTool = useCallback((agentId: string, toolName: string) => {\n toolRegistryRef.current.get(agentId)?.delete(toolName);\n }, []);\n\n const getTool = useCallback((agentId: string, toolName: string) => {\n return toolRegistryRef.current.get(agentId)?.get(toolName);\n }, []);\n\n const getToolsForAgent = useCallback((agentId: string) => {\n const toolMap = toolRegistryRef.current.get(agentId);\n return toolMap ? Array.from(toolMap.values()) : [];\n }, []);\n\n const resumeToolFromContext = useCallback((agentId: string, callId: string, result: any) => {\n const runner = runnersRef.current.get(agentId);\n if (runner) {\n runner.resumeTool(callId, result);\n } else {\n console.warn(`Cannot resume tool: no runner found for agent \"${agentId}\"`);\n }\n }, []);\n\n // ─── Context values ────────────────────────────────────────────────\n\n const agentContextValue = 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 const toolContextValue = useMemo(\n () => ({\n registerTool,\n unregisterTool,\n getTool,\n getToolsForAgent,\n resumeTool: resumeToolFromContext,\n }),\n [registerTool, unregisterTool, getTool, getToolsForAgent, resumeToolFromContext],\n );\n\n return (\n <AgentContext.Provider value={agentContextValue}>\n <AgentToolContext.Provider value={toolContextValue}>\n {children}\n {Array.from(activeAgentsRef.current.entries()).map(\n ([agentId, { agentUrl, accessKey, options }]) => (\n <AgentRunnerInstance\n key={agentId}\n agentId={agentId}\n agentUrl={agentUrl}\n accessKey={accessKey}\n options={options}\n />\n ),\n )}\n </AgentToolContext.Provider>\n </AgentContext.Provider>\n );\n}\n\nfunction AgentRunnerInstance({\n agentId,\n agentUrl,\n accessKey,\n options,\n}: {\n agentId: string;\n agentUrl: string;\n accessKey?: string;\n options?: UseAgentOptions;\n}) {\n const agent = useMemo(\n () => new BuildShipAgent({ agentId, baseUrl: agentUrl, accessKey }),\n [agentId, agentUrl, accessKey],\n );\n // Use a ref for options to avoid re-renders when function references change\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const agentRunner = useAgent(agent, optionsRef.current);\n const context = useContext(AgentContext);\n\n useEffect(() => {\n if (context) {\n context.registerRunner(agentId, agentRunner);\n }\n }, [agentId, agentRunner, context]);\n\n if (!context) return null;\n\n return null;\n}\n\nexport function useAgentContext(\n agentId: string,\n agentUrl: string,\n accessKey?: string,\n options?: UseAgentOptions,\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 // Use a ref for options so function identity changes don't trigger re-renders\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n useEffect(() => {\n initializeAgent(agentId, agentUrl, accessKey, optionsRef.current);\n }, [agentId, agentUrl, accessKey, 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 handleSend: async () => {},\n resumeTool: 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, useContext, useMemo } from \"react\";\nimport type { BuildShipAgent } from \"../core/agent\";\nimport type { AgentSession } from \"../core/session\";\nimport { DEFAULT_SESSION_NAME, TEMPORARY_SESSION_ID } from \"./constants\";\nimport { useSessionUtils } from \"./session-utils\";\nimport { createDebugHandlers } from \"./debug-handlers\";\nimport { useAgentGlobalState, AgentToolContext } from \"./agent-context\";\nimport type { Message } from \"./types\";\nimport { useClientToolHelpers } from \"./client-tools\";\nimport { buildStreamCallbacks } from \"./stream-callbacks\";\nimport type { RunOptions } from \"./stream-callbacks\";\n\nexport interface UseAgentOptions {\n textDeltaModifier?: (\n delta: string,\n fullText: string,\n meta: { executionId: string; sequence: number; agentId: string },\n ) => string;\n}\n\nexport default function useAgent(agent: BuildShipAgent, options?: UseAgentOptions) {\n const agentId = agent._agentId;\n\n const { allSessions, setAllSessions, debugData, setDebugData } = useAgentGlobalState();\n const toolContext = useContext(AgentToolContext);\n\n const [inProgress, setInProgress] = useState(false);\n const [messages, setMessages] = useState<Array<Message>>([]);\n const messagesRef = useRef<Array<Message>>([]);\n\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 useEffect(() => {\n const initialSessionId = sessionUtils.getInitialSessionId();\n setCurrentSessionId(initialSessionId);\n }, [agentId]);\n\n const debugHandlers = useMemo(() => createDebugHandlers(setDebugData), [setDebugData]);\n\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n // Reload messages from session storage only on session/agent switch\n useEffect(() => {\n if (inProgress) return;\n const session = sessionUtils.agentSessions[currentSessionId];\n if (session) {\n setMessages(session.messages);\n } else {\n setMessages([]);\n }\n }, [currentSessionId, agentId, sessionUtils.agentSessions, inProgress]);\n\n useEffect(() => {\n const syncRef = sessionUtils.syncSessionRef;\n const msgRef = messagesRef;\n return () => {\n if (msgRef.current.length > 0 && syncRef.current) {\n syncRef.current();\n }\n };\n }, [sessionUtils.syncSessionRef]);\n\n // Make a stable ref to avoid dependency cycles and redefinitions\n const optionsRef = useRef(options);\n useEffect(() => {\n optionsRef.current = options;\n }, [options]);\n\n const lastRunOptionsRef = useRef<{\n context?: object;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n }>({});\n\n const { getClientToolsMap } = useClientToolHelpers(agentId, toolContext);\n\n const activeSessionRef = useRef<AgentSession | null>(null);\n\n const runAgent = useCallback(\n async (input: string | undefined, runOptions?: RunOptions) => {\n const isNewSession = !currentSessionId || currentSessionId === TEMPORARY_SESSION_ID;\n\n setInProgress(true);\n\n const debugKey =\n runOptions?.optimisticExecutionId ||\n messagesRef.current.findLast((m) => m.role === \"user\")?.executionId;\n\n const deps = {\n agentId,\n currentSessionId,\n messagesRef,\n setMessages,\n setInProgress,\n syncSessionRef: sessionUtils.syncSessionRef,\n debugHandlers,\n toolContext,\n textDeltaModifier: optionsRef.current?.textDeltaModifier,\n };\n\n const callbacks = buildStreamCallbacks(deps, debugKey);\n\n const executeOptions = {\n context: runOptions?.context,\n headers: runOptions?.additionalHeaders,\n body: runOptions?.additionalBody,\n };\n\n // Ensure React-registered tools are synced into the core agent's map\n const toolsMap = getClientToolsMap();\n for (const tool of toolsMap.values()) {\n agent.registerClientTool(tool);\n }\n\n // Merge legacy client tool definitions safely\n if (runOptions?.clientTools && runOptions.clientTools.length > 0) {\n executeOptions.body = {\n ...(executeOptions.body || {}),\n clientTools: [\n ...((executeOptions.body?.clientTools as any[]) || []),\n ...runOptions.clientTools,\n ],\n };\n }\n\n try {\n if (runOptions?.resumeToolCallId) {\n if (isNewSession) throw new Error(\"Cannot resume a tool call on a temporary session.\");\n const session = agent.session(currentSessionId);\n activeSessionRef.current = session;\n await session.resumeWithCallId(\n runOptions.resumeToolCallId,\n runOptions.resumeToolResult,\n callbacks,\n executeOptions,\n );\n } else {\n if (isNewSession) {\n const extendedOptions = {\n ...executeOptions,\n onSessionId: (newSessionId: string, sessionName?: string) => {\n sessionUtils.createSessionFromResponse(\n newSessionId,\n sessionName || DEFAULT_SESSION_NAME,\n messagesRef.current,\n );\n setCurrentSessionId(newSessionId);\n },\n };\n const session = await agent.execute(input || \"\", callbacks, extendedOptions);\n activeSessionRef.current = session;\n } else {\n const session = agent.session(currentSessionId);\n activeSessionRef.current = session;\n await session.execute(input || \"\", callbacks, executeOptions);\n }\n }\n } catch (error) {\n console.log(\"Agent execution failed\", error);\n setInProgress(false);\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw error;\n } finally {\n activeSessionRef.current = null;\n }\n },\n [currentSessionId, sessionUtils, debugHandlers, agentId, toolContext, agent, getClientToolsMap],\n );\n\n const handleSend = useCallback(\n async (\n input: string,\n options?: {\n context?: object;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n },\n ) => {\n const userMessage: Message = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n ...(options?.context ? { context: options.context } : {}),\n };\n\n if (!options?.skipUserMessage) {\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n }\n\n const effectiveExecutionId = options?.skipUserMessage\n ? (messagesRef.current.findLast((m) => m.role === \"user\")?.executionId ??\n userMessage.executionId)\n : userMessage.executionId;\n\n // Track options so they can be re-applied during string continuations (like tool resumes)\n lastRunOptionsRef.current = {\n context: options?.context,\n additionalHeaders: options?.additionalHeaders,\n additionalBody: options?.additionalBody,\n };\n\n try {\n await runAgent(input, {\n ...options,\n optimisticExecutionId: effectiveExecutionId,\n });\n } catch (error) {\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 resumeTool = useCallback(\n async (callId: string, result: any) => {\n setMessages((prev) => {\n const updatedMessages = prev.map((msg) => {\n if (msg.parts) {\n const updatedParts = msg.parts.map((part) => {\n if (part.type === \"widget\" && part.callId === callId) {\n return { ...part, status: \"submitted\" as const, result };\n }\n return part;\n });\n return { ...msg, parts: updatedParts };\n }\n return msg;\n });\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n\n const lastUserMessage = messagesRef.current.findLast((m) => m.role === \"user\");\n const debugKey = lastUserMessage?.executionId;\n if (debugKey) {\n debugHandlers.handleStreamEvent({\n type: \"tool_call_end\",\n data: { callId, toolName: \"\", toolType: \"client\" as const, result },\n meta: { executionId: debugKey, sequence: 0 },\n } as any);\n }\n\n await runAgent(undefined, {\n resumeToolCallId: callId,\n resumeToolResult: result,\n ...lastRunOptionsRef.current,\n // Restore context from the persisted user message (survives page refresh)\n context: lastUserMessage?.context ?? lastRunOptionsRef.current.context,\n });\n },\n [runAgent, sessionUtils.syncSessionRef, debugHandlers],\n );\n\n const addOptimisticMessage = useCallback(\n (input: string, context?: Record<string, any>) => {\n const userMessage: Message = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n ...(context ? { context } : {}),\n };\n\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n },\n [sessionUtils.syncSessionRef],\n );\n\n const abort = useCallback(() => {\n if (activeSessionRef.current) {\n activeSessionRef.current.abort();\n }\n setInProgress(false);\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 resumeTool,\n addOptimisticMessage,\n abort,\n sessionId: currentSessionId,\n switchSession: sessionUtils.switchSession,\n deleteSession: sessionUtils.deleteSession,\n sessions: sessionUtils.sessionsList,\n debugData,\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 // If we're deleting the current session, switch to the most recent remaining one\n if (sessionId === currentSessionId) {\n const remainingSessions = Object.values(updatedAgentSessions);\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 return {\n ...prev,\n [agentId]: updatedAgentSessions,\n };\n });\n },\n [agentId, currentSessionId, 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 { StreamEvent } from \"../core/types\";\nimport type {\n DebugDataType,\n ToolExecutionItem,\n ReasoningItem,\n HandoffItem,\n RunErrorItem,\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 handleStreamEvent = (event: StreamEvent) => {\n const executionId = event.meta.executionId;\n\n switch (event.type) {\n case \"tool_call_start\": {\n const { callId, toolName, toolType, inputs, serverName } = event.data;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"tool_call\",\n toolName,\n callId,\n toolType,\n status: \"progress\",\n inputs,\n serverName,\n } as ToolExecutionItem,\n ],\n }));\n break;\n }\n\n case \"tool_call_end\": {\n const { callId, result, error } = event.data;\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.callId === callId) {\n currentData[i] = {\n ...toolItem,\n status: error ? \"error\" : \"complete\",\n output: result,\n error,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n break;\n }\n\n case \"reasoning_delta\": {\n const { delta, index } = event.data;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n let existingItemIndex = -1;\n for (let i = currentData.length - 1; i >= 0; i--) {\n const item = currentData[i];\n if (item.itemType === \"reasoning\" && (item as ReasoningItem).index === index) {\n existingItemIndex = i;\n break;\n }\n }\n\n if (existingItemIndex === -1) {\n currentData.push({ itemType: \"reasoning\", reasoning: delta, index });\n } else {\n currentData[existingItemIndex] = {\n itemType: \"reasoning\",\n reasoning: (currentData[existingItemIndex] as ReasoningItem).reasoning + delta,\n index,\n };\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n break;\n }\n\n case \"agent_handoff\": {\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"handoff\",\n agentName: event.data.agentName,\n } as HandoffItem,\n ],\n }));\n break;\n }\n\n case \"run_error\": {\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"run_error\",\n message: event.data.message,\n code: event.data.code,\n } as RunErrorItem,\n ],\n }));\n break;\n }\n }\n };\n\n return {\n handleStreamEvent,\n };\n};\n","import { useCallback, useContext } from \"react\";\nimport { toJSONSchema, type ZodSchema } from \"zod\";\n\nimport type { ExecuteRequestBody, ClientTool } from \"../core/types\";\nimport type { AgentToolContextValue } from \"./agent-context\";\nimport { cleanSchema } from \"./utils/schema\";\n\n/**\n * Resolve parameters — accepts Zod schema or plain JSON Schema object.\n */\nexport function resolveParameters(params: any): Record<string, any> {\n let schema: Record<string, any>;\n\n // Detect Zod schema: ZodType instances have a `_def` property\n if (params && typeof params === \"object\" && \"_def\" in params) {\n schema = toJSONSchema(params as ZodSchema) as Record<string, any>;\n delete schema.$schema;\n } else {\n schema = cleanSchema(params) as Record<string, any>;\n }\n\n // Gemini requires additionalProperties: false and required to include every key\n if (schema.type === \"object\") {\n schema.additionalProperties = false;\n if (schema.properties) {\n schema.required = Object.keys(schema.properties);\n }\n }\n\n return schema;\n}\n\n/**\n * Build the ClientTool map from ALL registered tools (handlers + widgets).\n * These are registered into the core agent's _clientTools so that\n * session._getClientToolDefs() can send their definitions to the server.\n * The core stream.ts handles tools without handlers correctly\n * (pauses for user interaction, or silently skips fire-and-forget).\n * Widget rendering is handled separately via onEvent → handleClientToolCall\n * in stream-callbacks.ts.\n */\nexport function useClientToolHelpers(agentId: string, toolContext: AgentToolContextValue | null) {\n const getClientToolsMap = useCallback((): Map<string, ClientTool> => {\n if (!toolContext) return new Map();\n const tools = toolContext.getToolsForAgent(agentId);\n const map = new Map<string, ClientTool>();\n\n for (const tool of tools) {\n map.set(tool.name, {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n await: tool.await,\n handler: tool.handler,\n });\n }\n\n return map;\n }, [agentId, toolContext]);\n\n /**\n * Build client tool definitions for the request body.\n * Includes ALL registered tools (handlers + widgets).\n */\n const getClientToolDefs = useCallback((): ExecuteRequestBody[\"clientTools\"] => {\n if (!toolContext) return [];\n const tools = toolContext.getToolsForAgent(agentId);\n\n return tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: resolveParameters(tool.parameters),\n await: tool.await,\n }));\n }, [agentId, toolContext]);\n\n return { getClientToolsMap, getClientToolDefs };\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 * appending it and merging with the previous part if both are contiguous text deltas.\n * Parts are kept in arrival order (no sorting) since events stream chronologically.\n */\nexport function updateAgentMessageParts(parts: MessagePart[], newPart: MessagePart): MessagePart[] {\n const last = parts[parts.length - 1];\n\n // Merge contiguous text deltas\n const canMerge =\n last?.type === \"text\" &&\n newPart.type === \"text\" &&\n newPart.firstSequence === last.lastSequence + 1;\n\n if (canMerge) {\n return [\n ...parts.slice(0, -1),\n {\n ...last,\n text: last.text + newPart.text,\n lastSequence: newPart.lastSequence,\n },\n ];\n }\n\n return [...parts, newPart];\n}\n","import type {\n StreamCallbacks,\n StreamEvent,\n TextDeltaEvent,\n ToolCallStartEvent,\n} from \"../core/types\";\n\nimport type { AgentToolContextValue } from \"./agent-context\";\nimport type { createDebugHandlers } from \"./debug-handlers\";\nimport type { Message, MessagePart } from \"./types\";\nimport { tryParseJSON } from \"./utils/schema\";\nimport { updateAgentMessageParts } from \"./utils/message\";\n\n// ── Types ──────────────────────────────────────────────────────────────\n\nexport type RunOptions = {\n context?: object;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n optimisticExecutionId?: string;\n /** @deprecated Use `useClientTool` hook instead. */\n clientTools?: Array<{\n name: string;\n description: string;\n parameters: unknown;\n await?: boolean;\n }>;\n // Resume params\n resumeToolCallId?: string;\n resumeToolResult?: any;\n};\n\nexport type StreamDeps = {\n agentId: string;\n currentSessionId: string;\n messagesRef: React.MutableRefObject<Array<Message>>;\n setMessages: React.Dispatch<React.SetStateAction<Array<Message>>>;\n setInProgress: React.Dispatch<React.SetStateAction<boolean>>;\n syncSessionRef: React.MutableRefObject<((messages?: Array<Message>) => void) | undefined>;\n debugHandlers: ReturnType<typeof createDebugHandlers>;\n toolContext: AgentToolContextValue | null;\n textDeltaModifier?: (\n delta: string,\n fullText: string,\n meta: { executionId: string; sequence: number; agentId: string },\n ) => string;\n};\n\n// ── Build callbacks ────────────────────────────────────────────────────\n\n/**\n * Build the StreamCallbacks object from dependencies.\n * Keeps event-handling logic out of the main hook.\n */\nexport function buildStreamCallbacks(\n deps: StreamDeps,\n debugKey: string | undefined,\n): StreamCallbacks {\n const {\n setMessages,\n setInProgress,\n syncSessionRef,\n messagesRef,\n toolContext,\n agentId,\n textDeltaModifier,\n } = deps;\n\n return {\n onComplete: () => {\n console.log(\"Agent closed\");\n setInProgress(false);\n if (syncSessionRef.current) {\n syncSessionRef.current(messagesRef.current);\n }\n },\n onError: (error: Error) => {\n console.log(\"Agent error\", error);\n setInProgress(false);\n if (syncSessionRef.current) {\n syncSessionRef.current(messagesRef.current);\n }\n },\n onEvent: (event: StreamEvent) => {\n if (event.type === \"text_delta\") {\n handleTextDelta(event, setMessages, syncSessionRef, textDeltaModifier, agentId);\n } else if (event.type === \"tool_call_start\" && event.data.toolType === \"client\") {\n // Create a widget part for tools with a render function\n handleClientToolCall(event, setMessages, syncSessionRef, toolContext, agentId);\n // Send to debug so the tool shows in the debug panel\n if (debugKey) {\n const debugMeta = { ...event.meta, executionId: debugKey };\n deps.debugHandlers.handleStreamEvent({\n ...event,\n meta: debugMeta,\n } as StreamEvent);\n\n // Server never sends tool_call_end for client tools.\n // For non-paused (fire-and-forget) tools, immediately mark complete.\n if (!event.data.paused) {\n deps.debugHandlers.handleStreamEvent({\n type: \"tool_call_end\",\n data: {\n callId: event.data.callId,\n toolName: event.data.toolName,\n toolType: event.data.toolType,\n },\n meta: debugMeta,\n } as StreamEvent);\n }\n }\n } else if (debugKey) {\n // All other events (server tools, reasoning, handoffs, etc.)\n deps.debugHandlers.handleStreamEvent({\n ...event,\n meta: { ...event.meta, executionId: debugKey },\n } as StreamEvent);\n }\n },\n };\n}\n\n// ── Event handlers (private) ───────────────────────────────────────────\n\nfunction handleTextDelta(\n event: TextDeltaEvent,\n setMessages: React.Dispatch<React.SetStateAction<Array<Message>>>,\n syncSessionRef: React.MutableRefObject<((messages?: Array<Message>) => void) | undefined>,\n modifier:\n | ((\n delta: string,\n fullText: string,\n meta: { executionId: string; sequence: number; agentId: string },\n ) => string)\n | undefined,\n agentId: string,\n) {\n const sequence = event.meta.sequence;\n const originalText = event.data;\n const eventExecutionId = event.meta.executionId;\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n\n // Calculate the modified text delta using the full text accumulation so far\n let text = originalText;\n if (modifier) {\n const currentFullText = lastMessage?.role === \"agent\" ? lastMessage.content : \"\";\n text = modifier(originalText, currentFullText, {\n executionId: eventExecutionId,\n sequence,\n agentId: event.meta.agentId || agentId,\n });\n }\n\n const newPart: MessagePart = {\n type: \"text\",\n text,\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 + text,\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: text,\n parts: [newPart],\n executionId: eventExecutionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (syncSessionRef.current) {\n syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n}\n\nfunction handleClientToolCall(\n event: ToolCallStartEvent,\n setMessages: React.Dispatch<React.SetStateAction<Array<Message>>>,\n syncSessionRef: React.MutableRefObject<((messages?: Array<Message>) => void) | undefined>,\n toolContext: AgentToolContextValue | null,\n agentId: string,\n) {\n // Only create widget for tools with a registered render function\n const tool = toolContext?.getTool(agentId, event.data.toolName);\n if (!tool?.render) return;\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newPart: MessagePart = {\n type: \"widget\",\n toolName: event.data.toolName,\n callId: event.data.callId,\n inputs: tryParseJSON(event.data.inputs),\n sequence: event.meta.sequence,\n paused: event.data.paused,\n status: \"pending\",\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: event.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (syncSessionRef.current) {\n syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n}\n","import type { StreamEvent, StreamOptions, SessionId } from \"./types\";\n\n/** Safely parse a value as JSON if it's a string, otherwise return as-is. */\nfunction 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\n/**\n * Fatal error — will NOT be retried.\n */\nclass FatalStreamError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n ) {\n super(message);\n this.name = \"FatalStreamError\";\n }\n}\n\n/**\n * Opens an SSE connection to the BuildShip agent endpoint using native\n * `fetch` + `ReadableStream`, parses events, and dispatches to the\n * appropriate callbacks.\n *\n * Zero runtime dependencies — works in both browser and Node.js.\n *\n * @internal\n */\nexport async function executeStream(options: StreamOptions): Promise<void> {\n const {\n url,\n body,\n headers,\n callbacks,\n clientTools,\n signal,\n onSessionId,\n onPaused,\n onAutoResume,\n onResponse,\n } = options;\n\n let fullText = \"\";\n\n // Track pending auto-resume operations so we don't call onComplete prematurely\n const pendingAutoResumes: Promise<{ callId: string; result: unknown } | null>[] = [];\n\n // ── Make the request ────────────────────────────────────────────────\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n ...headers,\n },\n body: JSON.stringify(body),\n signal,\n });\n\n // ── Extract session ID and name from response headers ──────────────\n const sessionId = response.headers.get(\"X-BuildShip-Agent-Session-ID\");\n if (sessionId && onSessionId) {\n const sessionName = response.headers.get(\"X-BuildShip-Agent-Session-Name\") || undefined;\n onSessionId(sessionId as SessionId, sessionName);\n }\n\n // Expose the raw Response object\n onResponse?.(response);\n\n // ── Handle HTTP errors ─────────────────────────────────────────────\n if (!response.ok) {\n let errorBody = \"\";\n try {\n errorBody = await response.text();\n } catch {\n // ignore\n }\n const error = new FatalStreamError(\n `HTTP ${response.status}: ${errorBody || response.statusText}`,\n response.status,\n );\n callbacks.onError?.(error);\n throw error;\n }\n\n // ── Read the SSE stream ────────────────────────────────────────────\n if (!response.body) {\n callbacks.onComplete?.(fullText);\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // SSE events are separated by double newlines\n const parts = buffer.split(\"\\n\\n\");\n buffer = parts.pop() || \"\";\n\n for (const part of parts) {\n const trimmedPart = part.trim();\n if (!trimmedPart) continue;\n\n // Extract the data field from SSE format\n let jsonStr = \"\";\n for (const line of trimmedPart.split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n jsonStr += line.slice(6);\n } else if (line.startsWith(\"data:\")) {\n jsonStr += line.slice(5);\n }\n }\n\n jsonStr = jsonStr.trim();\n if (!jsonStr) continue;\n\n let raw: any;\n try {\n raw = JSON.parse(jsonStr);\n } catch {\n // Skip malformed events\n continue;\n }\n\n // Normalize backend event type names (llm_text_delta → text_delta, etc.)\n const streamEvent = normalizeEvent(raw) as StreamEvent;\n\n handleEvent(\n streamEvent,\n fullText,\n callbacks,\n clientTools,\n onPaused,\n onAutoResume,\n pendingAutoResumes,\n );\n\n // Accumulate text\n if (streamEvent.type === \"text_delta\") {\n fullText += streamEvent.data;\n }\n }\n }\n\n // Process any remaining data in buffer\n if (buffer.trim()) {\n let jsonStr = \"\";\n for (const line of buffer.trim().split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n jsonStr += line.slice(6);\n } else if (line.startsWith(\"data:\")) {\n jsonStr += line.slice(5);\n }\n }\n\n jsonStr = jsonStr.trim();\n if (jsonStr) {\n try {\n const raw = JSON.parse(jsonStr);\n const streamEvent = normalizeEvent(raw) as StreamEvent;\n handleEvent(\n streamEvent,\n fullText,\n callbacks,\n clientTools,\n onPaused,\n onAutoResume,\n pendingAutoResumes,\n );\n if (streamEvent.type === \"text_delta\") {\n fullText += streamEvent.data;\n }\n } catch {\n // Skip malformed trailing data\n }\n }\n }\n } catch (err) {\n // AbortError — re-throw\n if (err instanceof Error && err.name === \"AbortError\") {\n throw err;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n callbacks.onError?.(error);\n throw error;\n }\n\n // Wait for any pending auto-resume handlers before signaling completion\n if (pendingAutoResumes.length > 0) {\n const handlerResults = await Promise.allSettled(pendingAutoResumes);\n for (const settled of handlerResults) {\n if (settled.status === \"fulfilled\" && settled.value) {\n const { callId, result } = settled.value;\n await onAutoResume?.(callId, result);\n }\n }\n }\n\n callbacks.onComplete?.(fullText);\n}\n\n/**\n * Normalize backend event type names.\n * The backend sends `llm_text_delta` / `llm_reasoning_delta` but the SDK\n * exposes them as `text_delta` / `reasoning_delta`.\n * @internal\n */\nfunction normalizeEvent(raw: any): any {\n const typeMap: Record<string, string> = {\n llm_text_delta: \"text_delta\",\n llm_reasoning_delta: \"reasoning_delta\",\n };\n if (raw && typeof raw.type === \"string\" && typeMap[raw.type]) {\n raw.type = typeMap[raw.type];\n }\n return raw;\n}\n\n/**\n * Dispatch a parsed stream event to the appropriate callbacks.\n * @internal\n */\nfunction handleEvent(\n event: StreamEvent,\n _fullText: string,\n callbacks: StreamOptions[\"callbacks\"],\n clientTools: StreamOptions[\"clientTools\"],\n onPaused: StreamOptions[\"onPaused\"],\n onAutoResume: StreamOptions[\"onAutoResume\"],\n pendingAutoResumes: Promise<{ callId: string; result: unknown } | null>[],\n): void {\n // Notify raw event consumers\n callbacks.onEvent?.(event);\n\n switch (event.type) {\n case \"text_delta\": {\n callbacks.onText?.(event.data);\n break;\n }\n\n case \"reasoning_delta\": {\n callbacks.onReasoning?.(event.data.delta, event.data.index);\n break;\n }\n\n case \"agent_handoff\": {\n callbacks.onAgentHandoff?.(event.data.agentName);\n break;\n }\n\n case \"tool_call_start\": {\n const { callId, toolName, toolType, inputs: rawInputs, paused } = event.data;\n // Backend sends toolCall.arguments as a JSON string — parse it\n const inputs = tryParseJSON(rawInputs);\n\n // Notify callback\n callbacks.onToolStart?.(toolName, toolType);\n\n // Handle client tools\n if (toolType === \"client\") {\n const tool = clientTools.get(toolName);\n if (tool) {\n if (paused && tool.handler) {\n // Blocking tool with handler → auto-execute and resume\n const handlerPromise = (async (): Promise<{\n callId: string;\n result: unknown;\n } | null> => {\n try {\n const result = await tool.handler!(inputs);\n\n // Synthesize a tool_call_end event for local observers (like debug panels)\n // since the backend only emits for server-side executed tools\n callbacks.onEvent?.({\n type: \"tool_call_end\",\n data: {\n callId,\n toolName,\n toolType: \"client\",\n result,\n },\n meta: event.meta,\n });\n\n return { callId, result };\n } catch (error) {\n // If handler fails, still call onPaused so user can decide\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n return null;\n }\n })();\n pendingAutoResumes.push(handlerPromise);\n } else if (paused) {\n // Blocking tool without handler → pause for user\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n } else if (tool.handler) {\n // Fire-and-forget tool with handler\n try {\n tool.handler(inputs);\n } catch {\n // Swallow errors on fire-and-forget\n }\n }\n } else if (paused) {\n // No registered tool but paused — notify user\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n }\n }\n break;\n }\n\n case \"tool_call_end\": {\n const { toolName, result, error } = event.data;\n callbacks.onToolEnd?.(toolName, result, error);\n break;\n }\n\n case \"run_error\": {\n const { message, code } = event.data;\n const error = new Error(message);\n if (code != null) (error as any).code = code;\n callbacks.onError?.(error);\n break;\n }\n }\n}\n","import type {\n SessionId,\n StreamCallbacks,\n PausedToolInfo,\n ExecuteRequestBody,\n ExecuteOptions,\n} from \"./types\";\nimport type { BuildShipAgent } from \"./agent\";\nimport { executeStream } from \"./stream\";\nimport { toJSONSchema, type ZodSchema } from \"zod\";\n\n/**\n * Represents a conversation session with a BuildShip agent.\n *\n * Sessions maintain history across multiple turns and support\n * pause/resume for blocking client tools.\n */\nexport class AgentSession {\n /** @internal */ private _agent: BuildShipAgent;\n /** @internal */ private _sessionId: SessionId | undefined;\n /** @internal */ private _paused = false;\n /** @internal */ private _pausedToolInfo: PausedToolInfo | null = null;\n /** @internal */ private _abortController: AbortController | null = null;\n\n /** @internal */\n constructor(agent: BuildShipAgent, sessionId?: SessionId) {\n this._agent = agent;\n this._sessionId = sessionId;\n }\n\n // ─── Public API ────────────────────────────────────────────────────\n\n /**\n * Send a message in this session.\n *\n * @param message - The message to send\n * @param callbacks - Event handlers for the stream\n * @param callbacks - Event handlers for the stream\n * @param options - Optional settings like context, headers, or body\n * @returns This session (for chaining)\n */\n async execute(\n message: string,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n this._paused = false;\n this._pausedToolInfo = null;\n\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n input: message,\n stream: true,\n };\n\n // Attach context as top-level properties if provided\n if (options?.context) {\n Object.assign(body, { context: options.context });\n }\n\n // Include client tool definitions\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n await this._run(body, callbacks, options);\n return this;\n }\n\n /**\n * Resume a paused session with a tool result.\n *\n * @param result - The result to send back to the agent\n * @param callbacks - Event handlers for the resumed stream\n * @param options - Optional settings like headers or body\n * @returns This session (for chaining)\n */\n async resume(\n result: any,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n if (!this._paused || !this._pausedToolInfo) {\n throw new Error(\"AgentSession.resume(): session is not paused. Check isPaused() first.\");\n }\n\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: {\n callId: this._pausedToolInfo.callId,\n result,\n },\n };\n\n // Attach context if provided\n if (options?.context) {\n Object.assign(body, { context: options.context });\n }\n\n // Include client tool definitions for resume requests too\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n this._paused = false;\n this._pausedToolInfo = null;\n\n await this._run(body, callbacks, options);\n return this;\n }\n\n /**\n * Resume a session with an explicit tool call ID and result.\n *\n * Unlike `resume()`, this does NOT require the session to be in a paused state,\n * making it suitable for external resume flows (e.g. React widget submissions)\n * where the session object may have been re-created.\n *\n * @param callId - The tool call ID to resume\n * @param result - The result to send back to the agent\n * @param callbacks - Event handlers for the resumed stream\n * @param options - Optional settings like headers or body\n * @returns This session (for chaining)\n */\n async resumeWithCallId(\n callId: string,\n result: any,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: { callId, result },\n };\n\n // Attach context if provided\n if (options?.context) {\n Object.assign(body, { context: options.context });\n }\n\n // Include client tool definitions for resume requests too\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n // Clear any stale pause state\n this._paused = false;\n this._pausedToolInfo = null;\n\n await this._run(body, callbacks, options);\n return this;\n }\n\n /**\n * Check if this session is waiting for a tool result.\n */\n isPaused(): boolean {\n return this._paused;\n }\n\n /**\n * Get information about the paused tool call.\n * Returns `null` if the session is not paused.\n */\n getPausedTool(): PausedToolInfo | null {\n return this._pausedToolInfo;\n }\n\n /**\n * Get the session ID.\n * May be `undefined` if the session hasn't executed yet.\n */\n getSessionId(): SessionId {\n if (!this._sessionId) {\n throw new Error(\n \"AgentSession.getSessionId(): session ID not yet available. Call execute() first.\",\n );\n }\n return this._sessionId;\n }\n\n /**\n * Cancel the current streaming operation.\n */\n abort(): void {\n this._abortController?.abort();\n this._abortController = null;\n }\n\n // ─── Private helpers ───────────────────────────────────────────────\n\n /** @internal */\n private async _run(\n body: ExecuteRequestBody,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<void> {\n // Create a fresh abort controller for this run\n this._abortController = new AbortController();\n\n const baseHeaders = this._agent._buildHeaders(this._sessionId);\n const mergedHeaders = { ...baseHeaders, ...(options?.headers || {}) };\n\n await executeStream({\n url: this._agent._url,\n body,\n headers: mergedHeaders,\n callbacks,\n clientTools: this._agent._clientTools,\n signal: this._abortController.signal,\n\n onSessionId: (id, name) => {\n this._sessionId = id;\n options?.onSessionId?.(id, name);\n },\n\n onPaused: (info) => {\n this._paused = true;\n this._pausedToolInfo = info;\n },\n\n onAutoResume: async (callId, result) => {\n // Auto-resume: send the tool result back immediately\n const resumeBody: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: { callId, result },\n };\n\n // Carry context forward from the original execute options\n if (options?.context) {\n Object.assign(resumeBody, { context: options.context });\n }\n\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n resumeBody.clientTools = clientToolDefs;\n }\n\n await this._run(resumeBody, callbacks, options);\n },\n });\n }\n\n /** @internal */\n private _getClientToolDefs() {\n const defs: ExecuteRequestBody[\"clientTools\"] = [];\n for (const tool of this._agent._clientTools.values()) {\n defs.push({\n name: tool.name,\n description: tool.description,\n parameters: resolveParameters(tool.parameters),\n await: tool.await,\n });\n }\n return defs;\n }\n}\n\n/**\n * Convert tool parameters to a JSON Schema object.\n * - If it's a Zod schema, uses Zod's built-in `toJSONSchema` to convert.\n * - Always ensures `additionalProperties: false` is set (required by the backend).\n * - Always ensures `required` includes every key in `properties` (Gemini requirement).\n * @internal\n */\nfunction resolveParameters(params: any): Record<string, any> {\n let schema: Record<string, any>;\n\n // Detect Zod schema: ZodType instances have a `_def` property\n if (params && typeof params === \"object\" && \"_def\" in params) {\n schema = toJSONSchema(params as ZodSchema) as Record<string, any>;\n // Remove $schema key if present\n delete schema.$schema;\n } else {\n schema = { ...params };\n }\n\n if (schema.type === \"object\") {\n // Backend requires additionalProperties: false\n schema.additionalProperties = false;\n\n // Gemini requires `required` to include every key in `properties`\n if (schema.properties) {\n schema.required = Object.keys(schema.properties);\n }\n }\n\n return schema;\n}\n","import type { AgentConfig, ClientTool, ExecuteOptions, SessionId, StreamCallbacks } from \"./types\";\nimport { AgentSession } from \"./session\";\n\nconst DEFAULT_BASE_URL = \"https://api.buildship.run\";\n\n/**\n * Main entry point for interacting with a BuildShip agent.\n *\n * @example\n * ```ts\n * import { BuildShipAgent } from \"buildship-agent-sdk/core\";\n *\n * const agent = new BuildShipAgent({\n * agentId: \"your-agent-id\",\n * accessKey: \"your-access-key\",\n * });\n *\n * const session = await agent.execute(\"Hello!\", {\n * onText: (text) => console.log(text),\n * onComplete: (fullText) => console.log(\"Done!\", fullText),\n * });\n * ```\n */\nexport class BuildShipAgent {\n /** @internal */ readonly _agentId: string;\n /** @internal */ readonly _accessKey?: string;\n /** @internal */ readonly _baseUrl: string;\n /** @internal */ readonly _clientTools = new Map<string, ClientTool>();\n\n constructor(config: AgentConfig) {\n if (!config.agentId) {\n throw new Error(\"BuildShipAgent: agentId is required\");\n }\n this._agentId = config.agentId;\n this._accessKey = config.accessKey;\n this._baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/$/, \"\");\n }\n\n /**\n * The URL for the agent's execute endpoint.\n * @internal\n */\n get _url(): string {\n return `${this._baseUrl}/executeAgent/${this._agentId}`;\n }\n\n /**\n * Build the authorization / common headers.\n * @internal\n */\n _buildHeaders(sessionId?: SessionId): Record<string, string> {\n const headers: Record<string, string> = {};\n if (this._accessKey) {\n headers[\"Authorization\"] = `Bearer ${this._accessKey}`;\n }\n if (sessionId) {\n headers[\"X-BuildShip-Agent-Session-ID\"] = sessionId;\n }\n return headers;\n }\n\n // ─── Public API ────────────────────────────────────────────────────\n\n /**\n * Start a new conversation.\n *\n * Creates a fresh session and sends the first message.\n *\n * @param message - The message to send\n * @param callbacks - Event handlers for the stream\n * @param options - Optional execution settings (context, headers, body, onSessionId)\n * @returns The new session\n */\n async execute(\n message: string,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n const session = new AgentSession(this);\n await session.execute(message, callbacks, options);\n return session;\n }\n\n /**\n * Get an existing session by ID to continue a conversation.\n *\n * @param sessionId - The session ID from a previous conversation\n * @returns The session object\n */\n session(sessionId: SessionId | string): AgentSession {\n if (!sessionId) {\n throw new Error(\"BuildShipAgent.session(): sessionId is required\");\n }\n return new AgentSession(this, sessionId as SessionId);\n }\n\n /**\n * Register a client-side tool that the agent can call.\n */\n registerClientTool(tool: ClientTool): void {\n if (!tool.name) {\n throw new Error(\"registerClientTool: tool.name is required\");\n }\n this._clientTools.set(tool.name, tool);\n }\n\n /**\n * Remove a registered client tool.\n */\n unregisterClientTool(name: string): void {\n this._clientTools.delete(name);\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","import { useContext, useEffect, useState, useCallback, createElement } from \"react\";\nimport type { ZodSchema } from \"zod\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/**\n * Infer the output type from a Zod schema's structural shape (`_zod.output`).\n * Falls back to `any` for raw JSON Schema objects or untyped parameters.\n * @internal\n */\ntype InferInput<T> = T extends { _zod: { output: infer O } } ? O : any;\n\nexport interface ClientToolRenderProps<T = any> {\n /** Parsed inputs from the agent. */\n inputs: T;\n /** Submit a result back to the agent (only available when `await: true`). */\n submit: (result: any) => void;\n /** Current status of this widget instance. */\n status: \"pending\" | \"submitted\";\n /** The persisted result from a previous submission (available after submit or on reload). */\n result?: any;\n}\n\nexport interface ClientToolConfig<TParams = any> {\n /** Tool name — must match the name the agent knows. */\n name: string;\n /** Description of what the tool does. */\n description: string;\n /**\n * Tool parameters — accepts a **Zod schema** or a raw JSON Schema object.\n * When a Zod schema is provided, `handler` and `render` inputs are\n * automatically typed — no explicit generic needed.\n *\n * @example\n * parameters: z.object({ question: z.string() })\n */\n parameters: TParams;\n /** If true, agent pauses and waits for the tool result before continuing. */\n await?: boolean;\n /**\n * Handler function for headless tools (no UI).\n * If `await: true`, the return value is sent back to the agent.\n * If `await: false`, runs as fire-and-forget.\n * Inputs are automatically typed when `parameters` is a Zod schema.\n */\n handler?: (inputs: InferInput<TParams>) => any | Promise<any>;\n /**\n * Render function for widget tools (with UI).\n * Receives `{ inputs, submit, status }`.\n * - `submit(result)` resumes the agent when `await: true`.\n * - `status` is `\"pending\"` until submitted, then `\"submitted\"`.\n * Inputs are automatically typed when `parameters` is a Zod schema.\n */\n render?: (props: ClientToolRenderProps<InferInput<TParams>>) => any;\n}\n\n// ─── Context import (late-bound to avoid circular deps) ──────────────────────\n\n// We import the context lazily from agent-context\nimport { AgentToolContext } from \"./agent-context\";\n\n// ─── useClientTool hook ──────────────────────────────────────────────────────\n\n/**\n * Register a client tool for a specific agent.\n *\n * @example\n * ```tsx\n * // Headless tool\n * useClientTool(\"agent-123\", {\n * name: \"get_location\",\n * description: \"Gets user location\",\n * parameters: z.object({}),\n * handler: async () => {\n * const pos = await getPosition();\n * return { lat: pos.coords.latitude, lng: pos.coords.longitude };\n * },\n * });\n *\n * // Widget tool with submission\n * useClientTool(\"agent-123\", {\n * name: \"feedback_form\",\n * description: \"Collects feedback\",\n * parameters: z.object({ question: z.string() }),\n * await: true,\n * render: ({ inputs, submit, status }) => (\n * <form onSubmit={() => submit({ answer: \"...\" })}>\n * <p>{inputs.question}</p>\n * <button disabled={status !== \"pending\"}>Submit</button>\n * </form>\n * ),\n * });\n * ```\n */\nexport function useClientTool<TParams>(agentId: string, config: ClientToolConfig<TParams>): void {\n const context = useContext(AgentToolContext);\n\n if (!context) {\n throw new Error(\"useClientTool must be used within <AgentContextProvider>\");\n }\n\n useEffect(() => {\n context.registerTool(agentId, config);\n return () => {\n context.unregisterTool(agentId, config.name);\n };\n // Note: consumers should memoize `config` to avoid unnecessary re-registrations.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agentId, config.name, config.handler, config.render, config.parameters]);\n}\n\n// ─── ToolRenderer component ──────────────────────────────────────────────────\n\ninterface ToolRendererProps {\n /** The agent ID this tool belongs to. */\n agentId: string;\n /** The widget message part to render. */\n part: {\n toolName: string;\n callId: string;\n inputs: any;\n paused?: boolean;\n status?: \"pending\" | \"submitted\";\n result?: any;\n };\n}\n\n/**\n * Renders a registered widget tool.\n * Looks up the tool by name from the registry and renders it with\n * the appropriate props (inputs, submit, status).\n *\n * @example\n * ```tsx\n * {message.parts?.map((part) => {\n * if (part.type === \"widget\") {\n * return <ToolRenderer key={part.callId} agentId=\"agent-123\" part={part} />;\n * }\n * return <Markdown key={part.firstSequence}>{part.text}</Markdown>;\n * })}\n * ```\n */\nexport function ToolRenderer({ agentId, part }: ToolRendererProps) {\n const context = useContext(AgentToolContext);\n const [localStatus, setLocalStatus] = useState<\"pending\" | \"submitted\">(part.status || \"pending\");\n\n // Sync localStatus when part.status changes externally\n // (e.g., messages reloaded from session storage after resume)\n useEffect(() => {\n setLocalStatus(part.status || \"pending\");\n }, [part.status]);\n\n if (!context) {\n throw new Error(\"ToolRenderer must be used within <AgentContextProvider>\");\n }\n\n const tool = context.getTool(agentId, part.toolName);\n\n const handleSubmit = useCallback(\n (result: any) => {\n if (localStatus === \"submitted\") return; // Prevent double-submission\n setLocalStatus(\"submitted\");\n context.resumeTool(agentId, part.callId, result);\n },\n [agentId, part.callId, localStatus, context],\n );\n\n if (!tool?.render) {\n return null; // No registered render function for this tool\n }\n\n return tool.render({\n inputs: part.inputs,\n submit: part.paused ? handleSubmit : () => {},\n status: localStatus,\n result: part.result,\n });\n}\n"],"mappings":"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","names":["import_react","import_react","import_react","options","tryParseJSON","import_zod","resolveParameters","import_react","import_react"]}
|
|
1
|
+
{"version":3,"sources":["../../src/react/index.ts","../../src/react/agent-context.tsx","../../src/react/use-agent.ts","../../src/react/constants.ts","../../src/react/session-utils.ts","../../src/react/debug-handlers.ts","../../src/react/client-tools.ts","../../src/react/utils/schema.ts","../../src/react/utils/message.ts","../../src/react/stream-callbacks.ts","../../src/core/stream.ts","../../src/core/session.ts","../../src/core/agent.ts","../../src/react/utils/use-synced-local-storage.ts","../../src/react/use-client-tool.ts"],"sourcesContent":["export * from \"./types\";\nexport * from \"./agent-context\";\nexport { default as useAgent } from \"./use-agent\";\nexport { useClientTool, ToolRenderer } from \"./use-client-tool\";\nexport type { ClientToolConfig, ClientToolRenderProps } from \"./use-client-tool\";\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, { type UseAgentOptions } from \"./use-agent\";\nimport { BuildShipAgent } from \"../core/agent\";\nimport type { Message, Session, DebugDataType } from \"./types\";\nimport type { ClientToolConfig } from \"./use-client-tool\";\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 handleSend: (\n input: string,\n options?: {\n context?: Record<string, unknown>;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n /** @deprecated Use `useClientTool` hook instead. */\n clientTools?: Array<{\n name: string;\n description: string;\n parameters: unknown;\n await?: boolean;\n }>;\n },\n ) => Promise<void>;\n resumeTool: (callId: string, result: any) => Promise<void>;\n switchSession: (sessionId?: string) => void;\n deleteSession: (sessionId: string) => void;\n addOptimisticMessage: (input: string, context?: Record<string, any>) => void;\n abort: () => void;\n}\n\n// ─── Tool Registry Context ──────────────────────────────────────────────────\n\nexport interface AgentToolContextValue {\n registerTool: (agentId: string, config: ClientToolConfig) => void;\n unregisterTool: (agentId: string, toolName: string) => void;\n getTool: (agentId: string, toolName: string) => ClientToolConfig | undefined;\n getToolsForAgent: (agentId: string) => ClientToolConfig[];\n resumeTool: (agentId: string, callId: string, result: any) => void;\n}\n\nexport const AgentToolContext = createContext<AgentToolContextValue | null>(null);\n\n// ─── Agent Context ──────────────────────────────────────────────────────────\n\ninterface AgentContextValue {\n initializeAgent: (\n agentId: string,\n agentUrl: string,\n accessKey?: string,\n options?: UseAgentOptions,\n ) => 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<\n Map<string, { agentUrl: string; accessKey?: string; options?: UseAgentOptions }>\n >(new Map());\n const runnersRef = useRef<Map<string, AgentRunner>>(new Map());\n const listenersRef = useRef<Map<string, Set<() => void>>>(new Map());\n\n // Tool registry: agentId -> Map<toolName, ClientToolConfig>\n const toolRegistryRef = useRef<Map<string, Map<string, ClientToolConfig>>>(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(\n (agentId: string, agentUrl: string, accessKey?: string, options?: UseAgentOptions) => {\n const existing = activeAgentsRef.current.get(agentId);\n\n if (!existing) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey, options });\n forceUpdate({});\n } else if (existing.agentUrl !== agentUrl || existing.accessKey !== accessKey) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey, options });\n forceUpdate({});\n } else if (options) {\n // Always update options ref (e.g. textDeltaModifier) without triggering re-render\n existing.options = options;\n }\n },\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 // ─── Tool registry methods ─────────────────────────────────────────\n\n const registerTool = useCallback((agentId: string, config: ClientToolConfig) => {\n if (!toolRegistryRef.current.has(agentId)) {\n toolRegistryRef.current.set(agentId, new Map());\n }\n toolRegistryRef.current.get(agentId)!.set(config.name, config);\n }, []);\n\n const unregisterTool = useCallback((agentId: string, toolName: string) => {\n toolRegistryRef.current.get(agentId)?.delete(toolName);\n }, []);\n\n const getTool = useCallback((agentId: string, toolName: string) => {\n return toolRegistryRef.current.get(agentId)?.get(toolName);\n }, []);\n\n const getToolsForAgent = useCallback((agentId: string) => {\n const toolMap = toolRegistryRef.current.get(agentId);\n return toolMap ? Array.from(toolMap.values()) : [];\n }, []);\n\n const resumeToolFromContext = useCallback((agentId: string, callId: string, result: any) => {\n const runner = runnersRef.current.get(agentId);\n if (runner) {\n runner.resumeTool(callId, result);\n } else {\n console.warn(`Cannot resume tool: no runner found for agent \"${agentId}\"`);\n }\n }, []);\n\n // ─── Context values ────────────────────────────────────────────────\n\n const agentContextValue = 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 const toolContextValue = useMemo(\n () => ({\n registerTool,\n unregisterTool,\n getTool,\n getToolsForAgent,\n resumeTool: resumeToolFromContext,\n }),\n [registerTool, unregisterTool, getTool, getToolsForAgent, resumeToolFromContext],\n );\n\n return (\n <AgentContext.Provider value={agentContextValue}>\n <AgentToolContext.Provider value={toolContextValue}>\n {children}\n {Array.from(activeAgentsRef.current.entries()).map(\n ([agentId, { agentUrl, accessKey, options }]) => (\n <AgentRunnerInstance\n key={agentId}\n agentId={agentId}\n agentUrl={agentUrl}\n accessKey={accessKey}\n options={options}\n />\n ),\n )}\n </AgentToolContext.Provider>\n </AgentContext.Provider>\n );\n}\n\nfunction AgentRunnerInstance({\n agentId,\n agentUrl,\n accessKey,\n options,\n}: {\n agentId: string;\n agentUrl: string;\n accessKey?: string;\n options?: UseAgentOptions;\n}) {\n const agent = useMemo(\n () => new BuildShipAgent({ agentId, baseUrl: agentUrl, accessKey }),\n [agentId, agentUrl, accessKey],\n );\n // Use a ref for options to avoid re-renders when function references change\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const agentRunner = useAgent(agent, optionsRef.current);\n const context = useContext(AgentContext);\n\n useEffect(() => {\n if (context) {\n context.registerRunner(agentId, agentRunner);\n }\n }, [agentId, agentRunner, context]);\n\n if (!context) return null;\n\n return null;\n}\n\nexport function useAgentContext(\n agentId: string,\n agentUrl: string,\n accessKey?: string,\n options?: UseAgentOptions,\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 // Use a ref for options so function identity changes don't trigger re-renders\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n useEffect(() => {\n initializeAgent(agentId, agentUrl, accessKey, optionsRef.current);\n }, [agentId, agentUrl, accessKey, 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 handleSend: async () => {},\n resumeTool: 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, useContext, useMemo } from \"react\";\nimport type { BuildShipAgent } from \"../core/agent\";\nimport type { AgentSession } from \"../core/session\";\nimport { DEFAULT_SESSION_NAME, TEMPORARY_SESSION_ID } from \"./constants\";\nimport { useSessionUtils } from \"./session-utils\";\nimport { createDebugHandlers } from \"./debug-handlers\";\nimport { useAgentGlobalState, AgentToolContext } from \"./agent-context\";\nimport type { Message } from \"./types\";\nimport { useClientToolHelpers } from \"./client-tools\";\nimport { buildStreamCallbacks } from \"./stream-callbacks\";\nimport type { RunOptions } from \"./stream-callbacks\";\n\nexport interface UseAgentOptions {\n textDeltaModifier?: (\n delta: string,\n fullText: string,\n meta: { executionId: string; sequence: number; agentId: string },\n ) => string;\n}\n\nexport default function useAgent(agent: BuildShipAgent, options?: UseAgentOptions) {\n const agentId = agent._agentId;\n\n const { allSessions, setAllSessions, debugData, setDebugData } = useAgentGlobalState();\n const toolContext = useContext(AgentToolContext);\n\n const [inProgress, setInProgress] = useState(false);\n const [messages, setMessages] = useState<Array<Message>>([]);\n const messagesRef = useRef<Array<Message>>([]);\n\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 useEffect(() => {\n const initialSessionId = sessionUtils.getInitialSessionId();\n setCurrentSessionId(initialSessionId);\n }, [agentId]);\n\n const debugHandlers = useMemo(() => createDebugHandlers(setDebugData), [setDebugData]);\n\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n // Reload messages from session storage only on session/agent switch\n useEffect(() => {\n if (inProgress) return;\n const session = sessionUtils.agentSessions[currentSessionId];\n if (session) {\n setMessages(session.messages);\n } else {\n setMessages([]);\n }\n }, [currentSessionId, agentId, sessionUtils.agentSessions, inProgress]);\n\n useEffect(() => {\n const syncRef = sessionUtils.syncSessionRef;\n const msgRef = messagesRef;\n return () => {\n if (msgRef.current.length > 0 && syncRef.current) {\n syncRef.current();\n }\n };\n }, [sessionUtils.syncSessionRef]);\n\n // Make a stable ref to avoid dependency cycles and redefinitions\n const optionsRef = useRef(options);\n useEffect(() => {\n optionsRef.current = options;\n }, [options]);\n\n const lastRunOptionsRef = useRef<{\n context?: object;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n }>({});\n\n const { getClientToolsMap } = useClientToolHelpers(agentId, toolContext);\n\n const activeSessionRef = useRef<AgentSession | null>(null);\n\n const runAgent = useCallback(\n async (input: string | undefined, runOptions?: RunOptions) => {\n const isNewSession = !currentSessionId || currentSessionId === TEMPORARY_SESSION_ID;\n\n setInProgress(true);\n\n const debugKey =\n runOptions?.optimisticExecutionId ||\n messagesRef.current.findLast((m) => m.role === \"user\")?.executionId;\n\n const deps = {\n agentId,\n currentSessionId,\n messagesRef,\n setMessages,\n setInProgress,\n syncSessionRef: sessionUtils.syncSessionRef,\n debugHandlers,\n toolContext,\n textDeltaModifier: optionsRef.current?.textDeltaModifier,\n };\n\n const callbacks = buildStreamCallbacks(deps, debugKey);\n\n const executeOptions = {\n context: runOptions?.context,\n headers: runOptions?.additionalHeaders,\n body: runOptions?.additionalBody,\n };\n\n // Ensure React-registered tools are synced into the core agent's map\n const toolsMap = getClientToolsMap();\n for (const tool of toolsMap.values()) {\n agent.registerClientTool(tool);\n }\n\n // Merge legacy client tool definitions safely\n if (runOptions?.clientTools && runOptions.clientTools.length > 0) {\n executeOptions.body = {\n ...(executeOptions.body || {}),\n clientTools: [\n ...((executeOptions.body?.clientTools as any[]) || []),\n ...runOptions.clientTools,\n ],\n };\n }\n\n try {\n if (runOptions?.resumeToolCallId) {\n if (isNewSession) throw new Error(\"Cannot resume a tool call on a temporary session.\");\n const session = agent.session(currentSessionId);\n activeSessionRef.current = session;\n await session.resumeWithCallId(\n runOptions.resumeToolCallId,\n runOptions.resumeToolResult,\n callbacks,\n executeOptions,\n );\n } else {\n if (isNewSession) {\n const extendedOptions = {\n ...executeOptions,\n onSessionId: (newSessionId: string, sessionName?: string) => {\n sessionUtils.createSessionFromResponse(\n newSessionId,\n sessionName || DEFAULT_SESSION_NAME,\n messagesRef.current,\n );\n setCurrentSessionId(newSessionId);\n },\n };\n const session = await agent.execute(input || \"\", callbacks, extendedOptions);\n activeSessionRef.current = session;\n } else {\n const session = agent.session(currentSessionId);\n activeSessionRef.current = session;\n await session.execute(input || \"\", callbacks, executeOptions);\n }\n }\n } catch (error) {\n console.log(\"Agent execution failed\", error);\n setInProgress(false);\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw error;\n } finally {\n activeSessionRef.current = null;\n }\n },\n [currentSessionId, sessionUtils, debugHandlers, agentId, toolContext, agent, getClientToolsMap],\n );\n\n const handleSend = useCallback(\n async (\n input: string,\n options?: {\n context?: object;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n },\n ) => {\n const userMessage: Message = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n ...(options?.context ? { context: options.context } : {}),\n };\n\n if (!options?.skipUserMessage) {\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n } else if (options?.skipUserMessage && options?.context) {\n // Sync the authoritative context onto the existing optimistic user message.\n // addOptimisticMessage may have stored a different/partial context earlier.\n setMessages((prev) => {\n const lastUserIdx = prev.findLastIndex((m) => m.role === \"user\");\n if (lastUserIdx === -1) return prev;\n const updatedMessages = [...prev];\n updatedMessages[lastUserIdx] = {\n ...updatedMessages[lastUserIdx],\n context: options.context as Record<string, any>,\n };\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n }\n\n const effectiveExecutionId = options?.skipUserMessage\n ? (messagesRef.current.findLast((m) => m.role === \"user\")?.executionId ??\n userMessage.executionId)\n : userMessage.executionId;\n\n // Track options so they can be re-applied during string continuations (like tool resumes)\n lastRunOptionsRef.current = {\n context: options?.context,\n additionalHeaders: options?.additionalHeaders,\n additionalBody: options?.additionalBody,\n };\n\n try {\n await runAgent(input, {\n ...options,\n optimisticExecutionId: effectiveExecutionId,\n });\n } catch (error) {\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 resumeTool = useCallback(\n async (callId: string, result: any) => {\n setMessages((prev) => {\n const updatedMessages = prev.map((msg) => {\n if (msg.parts) {\n const updatedParts = msg.parts.map((part) => {\n if (part.type === \"widget\" && part.callId === callId) {\n return { ...part, status: \"submitted\" as const, result };\n }\n return part;\n });\n return { ...msg, parts: updatedParts };\n }\n return msg;\n });\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n\n const lastUserMessage = messagesRef.current.findLast((m) => m.role === \"user\");\n const debugKey = lastUserMessage?.executionId;\n if (debugKey) {\n debugHandlers.handleStreamEvent({\n type: \"tool_call_end\",\n data: { callId, toolName: \"\", toolType: \"client\" as const, result },\n meta: { executionId: debugKey, sequence: 0 },\n } as any);\n }\n\n await runAgent(undefined, {\n resumeToolCallId: callId,\n resumeToolResult: result,\n ...lastRunOptionsRef.current,\n // Restore context from the persisted user message (survives page refresh)\n context: lastUserMessage?.context ?? lastRunOptionsRef.current.context,\n });\n },\n [runAgent, sessionUtils.syncSessionRef, debugHandlers],\n );\n\n const addOptimisticMessage = useCallback(\n (input: string, context?: Record<string, any>) => {\n const userMessage: Message = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n ...(context ? { context } : {}),\n };\n\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n },\n [sessionUtils.syncSessionRef],\n );\n\n const abort = useCallback(() => {\n if (activeSessionRef.current) {\n activeSessionRef.current.abort();\n }\n setInProgress(false);\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 resumeTool,\n addOptimisticMessage,\n abort,\n sessionId: currentSessionId,\n switchSession: sessionUtils.switchSession,\n deleteSession: sessionUtils.deleteSession,\n sessions: sessionUtils.sessionsList,\n debugData,\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 // If we're deleting the current session, switch to the most recent remaining one\n if (sessionId === currentSessionId) {\n const remainingSessions = Object.values(updatedAgentSessions);\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 return {\n ...prev,\n [agentId]: updatedAgentSessions,\n };\n });\n },\n [agentId, currentSessionId, 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 { StreamEvent } from \"../core/types\";\nimport type {\n DebugDataType,\n ToolExecutionItem,\n ReasoningItem,\n HandoffItem,\n RunErrorItem,\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 handleStreamEvent = (event: StreamEvent) => {\n const executionId = event.meta.executionId;\n\n switch (event.type) {\n case \"tool_call_start\": {\n const { callId, toolName, toolType, inputs, serverName } = event.data;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"tool_call\",\n toolName,\n callId,\n toolType,\n status: \"progress\",\n inputs,\n serverName,\n } as ToolExecutionItem,\n ],\n }));\n break;\n }\n\n case \"tool_call_end\": {\n const { callId, result, error } = event.data;\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.callId === callId) {\n currentData[i] = {\n ...toolItem,\n status: error ? \"error\" : \"complete\",\n output: result,\n error,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n break;\n }\n\n case \"reasoning_delta\": {\n const { delta, index } = event.data;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n let existingItemIndex = -1;\n for (let i = currentData.length - 1; i >= 0; i--) {\n const item = currentData[i];\n if (item.itemType === \"reasoning\" && (item as ReasoningItem).index === index) {\n existingItemIndex = i;\n break;\n }\n }\n\n if (existingItemIndex === -1) {\n currentData.push({ itemType: \"reasoning\", reasoning: delta, index });\n } else {\n currentData[existingItemIndex] = {\n itemType: \"reasoning\",\n reasoning: (currentData[existingItemIndex] as ReasoningItem).reasoning + delta,\n index,\n };\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n break;\n }\n\n case \"agent_handoff\": {\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"handoff\",\n agentName: event.data.agentName,\n } as HandoffItem,\n ],\n }));\n break;\n }\n\n case \"run_error\": {\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"run_error\",\n message: event.data.message,\n code: event.data.code,\n } as RunErrorItem,\n ],\n }));\n break;\n }\n }\n };\n\n return {\n handleStreamEvent,\n };\n};\n","import { useCallback, useContext } from \"react\";\nimport { toJSONSchema, type ZodSchema } from \"zod\";\n\nimport type { ExecuteRequestBody, ClientTool } from \"../core/types\";\nimport type { AgentToolContextValue } from \"./agent-context\";\nimport { cleanSchema } from \"./utils/schema\";\n\n/**\n * Resolve parameters — accepts Zod schema or plain JSON Schema object.\n */\nexport function resolveParameters(params: any): Record<string, any> {\n let schema: Record<string, any>;\n\n // Detect Zod schema: ZodType instances have a `_def` property\n if (params && typeof params === \"object\" && \"_def\" in params) {\n schema = toJSONSchema(params as ZodSchema) as Record<string, any>;\n delete schema.$schema;\n } else {\n schema = cleanSchema(params) as Record<string, any>;\n }\n\n // Gemini requires additionalProperties: false and required to include every key\n if (schema.type === \"object\") {\n schema.additionalProperties = false;\n if (schema.properties) {\n schema.required = Object.keys(schema.properties);\n }\n }\n\n return schema;\n}\n\n/**\n * Build the ClientTool map from ALL registered tools (handlers + widgets).\n * These are registered into the core agent's _clientTools so that\n * session._getClientToolDefs() can send their definitions to the server.\n * The core stream.ts handles tools without handlers correctly\n * (pauses for user interaction, or silently skips fire-and-forget).\n * Widget rendering is handled separately via onEvent → handleClientToolCall\n * in stream-callbacks.ts.\n */\nexport function useClientToolHelpers(agentId: string, toolContext: AgentToolContextValue | null) {\n const getClientToolsMap = useCallback((): Map<string, ClientTool> => {\n if (!toolContext) return new Map();\n const tools = toolContext.getToolsForAgent(agentId);\n const map = new Map<string, ClientTool>();\n\n for (const tool of tools) {\n map.set(tool.name, {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n await: tool.await,\n handler: tool.handler,\n });\n }\n\n return map;\n }, [agentId, toolContext]);\n\n /**\n * Build client tool definitions for the request body.\n * Includes ALL registered tools (handlers + widgets).\n */\n const getClientToolDefs = useCallback((): ExecuteRequestBody[\"clientTools\"] => {\n if (!toolContext) return [];\n const tools = toolContext.getToolsForAgent(agentId);\n\n return tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: resolveParameters(tool.parameters),\n await: tool.await,\n }));\n }, [agentId, toolContext]);\n\n return { getClientToolsMap, getClientToolDefs };\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 * appending it and merging with the previous part if both are contiguous text deltas.\n * Parts are kept in arrival order (no sorting) since events stream chronologically.\n */\nexport function updateAgentMessageParts(parts: MessagePart[], newPart: MessagePart): MessagePart[] {\n const last = parts[parts.length - 1];\n\n // Merge contiguous text deltas\n const canMerge =\n last?.type === \"text\" &&\n newPart.type === \"text\" &&\n newPart.firstSequence === last.lastSequence + 1;\n\n if (canMerge) {\n return [\n ...parts.slice(0, -1),\n {\n ...last,\n text: last.text + newPart.text,\n lastSequence: newPart.lastSequence,\n },\n ];\n }\n\n return [...parts, newPart];\n}\n","import type {\n StreamCallbacks,\n StreamEvent,\n TextDeltaEvent,\n ToolCallStartEvent,\n} from \"../core/types\";\n\nimport type { AgentToolContextValue } from \"./agent-context\";\nimport type { createDebugHandlers } from \"./debug-handlers\";\nimport type { Message, MessagePart } from \"./types\";\nimport { tryParseJSON } from \"./utils/schema\";\nimport { updateAgentMessageParts } from \"./utils/message\";\n\n// ── Types ──────────────────────────────────────────────────────────────\n\nexport type RunOptions = {\n context?: object;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n optimisticExecutionId?: string;\n /** @deprecated Use `useClientTool` hook instead. */\n clientTools?: Array<{\n name: string;\n description: string;\n parameters: unknown;\n await?: boolean;\n }>;\n // Resume params\n resumeToolCallId?: string;\n resumeToolResult?: any;\n};\n\nexport type StreamDeps = {\n agentId: string;\n currentSessionId: string;\n messagesRef: React.MutableRefObject<Array<Message>>;\n setMessages: React.Dispatch<React.SetStateAction<Array<Message>>>;\n setInProgress: React.Dispatch<React.SetStateAction<boolean>>;\n syncSessionRef: React.MutableRefObject<((messages?: Array<Message>) => void) | undefined>;\n debugHandlers: ReturnType<typeof createDebugHandlers>;\n toolContext: AgentToolContextValue | null;\n textDeltaModifier?: (\n delta: string,\n fullText: string,\n meta: { executionId: string; sequence: number; agentId: string },\n ) => string;\n};\n\n// ── Build callbacks ────────────────────────────────────────────────────\n\n/**\n * Build the StreamCallbacks object from dependencies.\n * Keeps event-handling logic out of the main hook.\n */\nexport function buildStreamCallbacks(\n deps: StreamDeps,\n debugKey: string | undefined,\n): StreamCallbacks {\n const {\n setMessages,\n setInProgress,\n syncSessionRef,\n messagesRef,\n toolContext,\n agentId,\n textDeltaModifier,\n } = deps;\n\n return {\n onComplete: () => {\n console.log(\"Agent closed\");\n setInProgress(false);\n if (syncSessionRef.current) {\n syncSessionRef.current(messagesRef.current);\n }\n },\n onError: (error: Error) => {\n console.log(\"Agent error\", error);\n setInProgress(false);\n if (syncSessionRef.current) {\n syncSessionRef.current(messagesRef.current);\n }\n },\n onEvent: (event: StreamEvent) => {\n if (event.type === \"text_delta\") {\n handleTextDelta(event, setMessages, syncSessionRef, textDeltaModifier, agentId);\n } else if (event.type === \"tool_call_start\" && event.data.toolType === \"client\") {\n // Create a widget part for tools with a render function\n handleClientToolCall(event, setMessages, syncSessionRef, toolContext, agentId);\n // Send to debug so the tool shows in the debug panel\n if (debugKey) {\n const debugMeta = { ...event.meta, executionId: debugKey };\n deps.debugHandlers.handleStreamEvent({\n ...event,\n meta: debugMeta,\n } as StreamEvent);\n\n // Server never sends tool_call_end for client tools.\n // For non-paused (fire-and-forget) tools, immediately mark complete.\n if (!event.data.paused) {\n deps.debugHandlers.handleStreamEvent({\n type: \"tool_call_end\",\n data: {\n callId: event.data.callId,\n toolName: event.data.toolName,\n toolType: event.data.toolType,\n },\n meta: debugMeta,\n } as StreamEvent);\n }\n }\n } else if (debugKey) {\n // All other events (server tools, reasoning, handoffs, etc.)\n deps.debugHandlers.handleStreamEvent({\n ...event,\n meta: { ...event.meta, executionId: debugKey },\n } as StreamEvent);\n }\n },\n };\n}\n\n// ── Event handlers (private) ───────────────────────────────────────────\n\nfunction handleTextDelta(\n event: TextDeltaEvent,\n setMessages: React.Dispatch<React.SetStateAction<Array<Message>>>,\n syncSessionRef: React.MutableRefObject<((messages?: Array<Message>) => void) | undefined>,\n modifier:\n | ((\n delta: string,\n fullText: string,\n meta: { executionId: string; sequence: number; agentId: string },\n ) => string)\n | undefined,\n agentId: string,\n) {\n const sequence = event.meta.sequence;\n const originalText = event.data;\n const eventExecutionId = event.meta.executionId;\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n\n // Calculate the modified text delta using the full text accumulation so far\n let text = originalText;\n if (modifier) {\n const currentFullText = lastMessage?.role === \"agent\" ? lastMessage.content : \"\";\n text = modifier(originalText, currentFullText, {\n executionId: eventExecutionId,\n sequence,\n agentId: event.meta.agentId || agentId,\n });\n }\n\n const newPart: MessagePart = {\n type: \"text\",\n text,\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 + text,\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: text,\n parts: [newPart],\n executionId: eventExecutionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (syncSessionRef.current) {\n syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n}\n\nfunction handleClientToolCall(\n event: ToolCallStartEvent,\n setMessages: React.Dispatch<React.SetStateAction<Array<Message>>>,\n syncSessionRef: React.MutableRefObject<((messages?: Array<Message>) => void) | undefined>,\n toolContext: AgentToolContextValue | null,\n agentId: string,\n) {\n // Only create widget for tools with a registered render function\n const tool = toolContext?.getTool(agentId, event.data.toolName);\n if (!tool?.render) return;\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newPart: MessagePart = {\n type: \"widget\",\n toolName: event.data.toolName,\n callId: event.data.callId,\n inputs: tryParseJSON(event.data.inputs),\n sequence: event.meta.sequence,\n paused: event.data.paused,\n status: \"pending\",\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: event.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (syncSessionRef.current) {\n syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n}\n","import type { StreamEvent, StreamOptions, SessionId } from \"./types\";\n\n/** Safely parse a value as JSON if it's a string, otherwise return as-is. */\nfunction 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\n/**\n * Fatal error — will NOT be retried.\n */\nclass FatalStreamError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n ) {\n super(message);\n this.name = \"FatalStreamError\";\n }\n}\n\n/**\n * Opens an SSE connection to the BuildShip agent endpoint using native\n * `fetch` + `ReadableStream`, parses events, and dispatches to the\n * appropriate callbacks.\n *\n * Zero runtime dependencies — works in both browser and Node.js.\n *\n * @internal\n */\nexport async function executeStream(options: StreamOptions): Promise<void> {\n const {\n url,\n body,\n headers,\n callbacks,\n clientTools,\n signal,\n onSessionId,\n onPaused,\n onAutoResume,\n onResponse,\n } = options;\n\n let fullText = \"\";\n\n // Track pending auto-resume operations so we don't call onComplete prematurely\n const pendingAutoResumes: Promise<{ callId: string; result: unknown } | null>[] = [];\n\n // ── Make the request ────────────────────────────────────────────────\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n ...headers,\n },\n body: JSON.stringify(body),\n signal,\n });\n\n // ── Extract session ID and name from response headers ──────────────\n const sessionId = response.headers.get(\"X-BuildShip-Agent-Session-ID\");\n if (sessionId && onSessionId) {\n const sessionName = response.headers.get(\"X-BuildShip-Agent-Session-Name\") || undefined;\n onSessionId(sessionId as SessionId, sessionName);\n }\n\n // Expose the raw Response object\n onResponse?.(response);\n\n // ── Handle HTTP errors ─────────────────────────────────────────────\n if (!response.ok) {\n let errorBody = \"\";\n try {\n errorBody = await response.text();\n } catch {\n // ignore\n }\n const error = new FatalStreamError(\n `HTTP ${response.status}: ${errorBody || response.statusText}`,\n response.status,\n );\n callbacks.onError?.(error);\n throw error;\n }\n\n // ── Read the SSE stream ────────────────────────────────────────────\n if (!response.body) {\n callbacks.onComplete?.(fullText);\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // SSE events are separated by double newlines\n const parts = buffer.split(\"\\n\\n\");\n buffer = parts.pop() || \"\";\n\n for (const part of parts) {\n const trimmedPart = part.trim();\n if (!trimmedPart) continue;\n\n // Extract the data field from SSE format\n let jsonStr = \"\";\n for (const line of trimmedPart.split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n jsonStr += line.slice(6);\n } else if (line.startsWith(\"data:\")) {\n jsonStr += line.slice(5);\n }\n }\n\n jsonStr = jsonStr.trim();\n if (!jsonStr) continue;\n\n let raw: any;\n try {\n raw = JSON.parse(jsonStr);\n } catch {\n // Skip malformed events\n continue;\n }\n\n // Normalize backend event type names (llm_text_delta → text_delta, etc.)\n const streamEvent = normalizeEvent(raw) as StreamEvent;\n\n handleEvent(\n streamEvent,\n fullText,\n callbacks,\n clientTools,\n onPaused,\n onAutoResume,\n pendingAutoResumes,\n );\n\n // Accumulate text\n if (streamEvent.type === \"text_delta\") {\n fullText += streamEvent.data;\n }\n }\n }\n\n // Process any remaining data in buffer\n if (buffer.trim()) {\n let jsonStr = \"\";\n for (const line of buffer.trim().split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n jsonStr += line.slice(6);\n } else if (line.startsWith(\"data:\")) {\n jsonStr += line.slice(5);\n }\n }\n\n jsonStr = jsonStr.trim();\n if (jsonStr) {\n try {\n const raw = JSON.parse(jsonStr);\n const streamEvent = normalizeEvent(raw) as StreamEvent;\n handleEvent(\n streamEvent,\n fullText,\n callbacks,\n clientTools,\n onPaused,\n onAutoResume,\n pendingAutoResumes,\n );\n if (streamEvent.type === \"text_delta\") {\n fullText += streamEvent.data;\n }\n } catch {\n // Skip malformed trailing data\n }\n }\n }\n } catch (err) {\n // AbortError — re-throw\n if (err instanceof Error && err.name === \"AbortError\") {\n throw err;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n callbacks.onError?.(error);\n throw error;\n }\n\n // Wait for any pending auto-resume handlers before signaling completion\n if (pendingAutoResumes.length > 0) {\n const handlerResults = await Promise.allSettled(pendingAutoResumes);\n for (const settled of handlerResults) {\n if (settled.status === \"fulfilled\" && settled.value) {\n const { callId, result } = settled.value;\n await onAutoResume?.(callId, result);\n }\n }\n }\n\n callbacks.onComplete?.(fullText);\n}\n\n/**\n * Normalize backend event type names.\n * The backend sends `llm_text_delta` / `llm_reasoning_delta` but the SDK\n * exposes them as `text_delta` / `reasoning_delta`.\n * @internal\n */\nfunction normalizeEvent(raw: any): any {\n const typeMap: Record<string, string> = {\n llm_text_delta: \"text_delta\",\n llm_reasoning_delta: \"reasoning_delta\",\n };\n if (raw && typeof raw.type === \"string\" && typeMap[raw.type]) {\n raw.type = typeMap[raw.type];\n }\n return raw;\n}\n\n/**\n * Dispatch a parsed stream event to the appropriate callbacks.\n * @internal\n */\nfunction handleEvent(\n event: StreamEvent,\n _fullText: string,\n callbacks: StreamOptions[\"callbacks\"],\n clientTools: StreamOptions[\"clientTools\"],\n onPaused: StreamOptions[\"onPaused\"],\n onAutoResume: StreamOptions[\"onAutoResume\"],\n pendingAutoResumes: Promise<{ callId: string; result: unknown } | null>[],\n): void {\n // Notify raw event consumers\n callbacks.onEvent?.(event);\n\n switch (event.type) {\n case \"text_delta\": {\n callbacks.onText?.(event.data);\n break;\n }\n\n case \"reasoning_delta\": {\n callbacks.onReasoning?.(event.data.delta, event.data.index);\n break;\n }\n\n case \"agent_handoff\": {\n callbacks.onAgentHandoff?.(event.data.agentName);\n break;\n }\n\n case \"tool_call_start\": {\n const { callId, toolName, toolType, inputs: rawInputs, paused } = event.data;\n // Backend sends toolCall.arguments as a JSON string — parse it\n const inputs = tryParseJSON(rawInputs);\n\n // Notify callback\n callbacks.onToolStart?.(toolName, toolType);\n\n // Handle client tools\n if (toolType === \"client\") {\n const tool = clientTools.get(toolName);\n if (tool) {\n if (paused && tool.handler) {\n // Blocking tool with handler → auto-execute and resume\n const handlerPromise = (async (): Promise<{\n callId: string;\n result: unknown;\n } | null> => {\n try {\n const result = await tool.handler!(inputs);\n\n // Synthesize a tool_call_end event for local observers (like debug panels)\n // since the backend only emits for server-side executed tools\n callbacks.onEvent?.({\n type: \"tool_call_end\",\n data: {\n callId,\n toolName,\n toolType: \"client\",\n result,\n },\n meta: event.meta,\n });\n\n return { callId, result };\n } catch (error) {\n // If handler fails, still call onPaused so user can decide\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n return null;\n }\n })();\n pendingAutoResumes.push(handlerPromise);\n } else if (paused) {\n // Blocking tool without handler → pause for user\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n } else if (tool.handler) {\n // Fire-and-forget tool with handler\n try {\n tool.handler(inputs);\n } catch {\n // Swallow errors on fire-and-forget\n }\n }\n } else if (paused) {\n // No registered tool but paused — notify user\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n }\n }\n break;\n }\n\n case \"tool_call_end\": {\n const { toolName, result, error } = event.data;\n callbacks.onToolEnd?.(toolName, result, error);\n break;\n }\n\n case \"run_error\": {\n const { message, code } = event.data;\n const error = new Error(message);\n if (code != null) (error as any).code = code;\n callbacks.onError?.(error);\n break;\n }\n }\n}\n","import type {\n SessionId,\n StreamCallbacks,\n PausedToolInfo,\n ExecuteRequestBody,\n ExecuteOptions,\n} from \"./types\";\nimport type { BuildShipAgent } from \"./agent\";\nimport { executeStream } from \"./stream\";\nimport { toJSONSchema, type ZodSchema } from \"zod\";\n\n/**\n * Represents a conversation session with a BuildShip agent.\n *\n * Sessions maintain history across multiple turns and support\n * pause/resume for blocking client tools.\n */\nexport class AgentSession {\n /** @internal */ private _agent: BuildShipAgent;\n /** @internal */ private _sessionId: SessionId | undefined;\n /** @internal */ private _paused = false;\n /** @internal */ private _pausedToolInfo: PausedToolInfo | null = null;\n /** @internal */ private _abortController: AbortController | null = null;\n\n /** @internal */\n constructor(agent: BuildShipAgent, sessionId?: SessionId) {\n this._agent = agent;\n this._sessionId = sessionId;\n }\n\n // ─── Public API ────────────────────────────────────────────────────\n\n /**\n * Send a message in this session.\n *\n * @param message - The message to send\n * @param callbacks - Event handlers for the stream\n * @param callbacks - Event handlers for the stream\n * @param options - Optional settings like context, headers, or body\n * @returns This session (for chaining)\n */\n async execute(\n message: string,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n this._paused = false;\n this._pausedToolInfo = null;\n\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n input: message,\n stream: true,\n };\n\n // Attach context as top-level properties if provided\n if (options?.context) {\n Object.assign(body, { context: options.context });\n }\n\n // Include client tool definitions\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n await this._run(body, callbacks, options);\n return this;\n }\n\n /**\n * Resume a paused session with a tool result.\n *\n * @param result - The result to send back to the agent\n * @param callbacks - Event handlers for the resumed stream\n * @param options - Optional settings like headers or body\n * @returns This session (for chaining)\n */\n async resume(\n result: any,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n if (!this._paused || !this._pausedToolInfo) {\n throw new Error(\"AgentSession.resume(): session is not paused. Check isPaused() first.\");\n }\n\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: {\n callId: this._pausedToolInfo.callId,\n result,\n },\n };\n\n // Attach context if provided\n if (options?.context) {\n Object.assign(body, { context: options.context });\n }\n\n // Include client tool definitions for resume requests too\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n this._paused = false;\n this._pausedToolInfo = null;\n\n await this._run(body, callbacks, options);\n return this;\n }\n\n /**\n * Resume a session with an explicit tool call ID and result.\n *\n * Unlike `resume()`, this does NOT require the session to be in a paused state,\n * making it suitable for external resume flows (e.g. React widget submissions)\n * where the session object may have been re-created.\n *\n * @param callId - The tool call ID to resume\n * @param result - The result to send back to the agent\n * @param callbacks - Event handlers for the resumed stream\n * @param options - Optional settings like headers or body\n * @returns This session (for chaining)\n */\n async resumeWithCallId(\n callId: string,\n result: any,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: { callId, result },\n };\n\n // Attach context if provided\n if (options?.context) {\n Object.assign(body, { context: options.context });\n }\n\n // Include client tool definitions for resume requests too\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n // Clear any stale pause state\n this._paused = false;\n this._pausedToolInfo = null;\n\n await this._run(body, callbacks, options);\n return this;\n }\n\n /**\n * Check if this session is waiting for a tool result.\n */\n isPaused(): boolean {\n return this._paused;\n }\n\n /**\n * Get information about the paused tool call.\n * Returns `null` if the session is not paused.\n */\n getPausedTool(): PausedToolInfo | null {\n return this._pausedToolInfo;\n }\n\n /**\n * Get the session ID.\n * May be `undefined` if the session hasn't executed yet.\n */\n getSessionId(): SessionId {\n if (!this._sessionId) {\n throw new Error(\n \"AgentSession.getSessionId(): session ID not yet available. Call execute() first.\",\n );\n }\n return this._sessionId;\n }\n\n /**\n * Cancel the current streaming operation.\n */\n abort(): void {\n this._abortController?.abort();\n this._abortController = null;\n }\n\n // ─── Private helpers ───────────────────────────────────────────────\n\n /** @internal */\n private async _run(\n body: ExecuteRequestBody,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<void> {\n // Create a fresh abort controller for this run\n this._abortController = new AbortController();\n\n const baseHeaders = this._agent._buildHeaders(this._sessionId);\n const mergedHeaders = { ...baseHeaders, ...(options?.headers || {}) };\n\n await executeStream({\n url: this._agent._url,\n body,\n headers: mergedHeaders,\n callbacks,\n clientTools: this._agent._clientTools,\n signal: this._abortController.signal,\n\n onSessionId: (id, name) => {\n this._sessionId = id;\n options?.onSessionId?.(id, name);\n },\n\n onPaused: (info) => {\n this._paused = true;\n this._pausedToolInfo = info;\n },\n\n onAutoResume: async (callId, result) => {\n // Auto-resume: send the tool result back immediately\n const resumeBody: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: { callId, result },\n };\n\n // Carry context forward from the original execute options\n if (options?.context) {\n Object.assign(resumeBody, { context: options.context });\n }\n\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n resumeBody.clientTools = clientToolDefs;\n }\n\n await this._run(resumeBody, callbacks, options);\n },\n });\n }\n\n /** @internal */\n private _getClientToolDefs() {\n const defs: ExecuteRequestBody[\"clientTools\"] = [];\n for (const tool of this._agent._clientTools.values()) {\n defs.push({\n name: tool.name,\n description: tool.description,\n parameters: resolveParameters(tool.parameters),\n await: tool.await,\n });\n }\n return defs;\n }\n}\n\n/**\n * Convert tool parameters to a JSON Schema object.\n * - If it's a Zod schema, uses Zod's built-in `toJSONSchema` to convert.\n * - Always ensures `additionalProperties: false` is set (required by the backend).\n * - Always ensures `required` includes every key in `properties` (Gemini requirement).\n * @internal\n */\nfunction resolveParameters(params: any): Record<string, any> {\n let schema: Record<string, any>;\n\n // Detect Zod schema: ZodType instances have a `_def` property\n if (params && typeof params === \"object\" && \"_def\" in params) {\n schema = toJSONSchema(params as ZodSchema) as Record<string, any>;\n // Remove $schema key if present\n delete schema.$schema;\n } else {\n schema = { ...params };\n }\n\n if (schema.type === \"object\") {\n // Backend requires additionalProperties: false\n schema.additionalProperties = false;\n\n // Gemini requires `required` to include every key in `properties`\n if (schema.properties) {\n schema.required = Object.keys(schema.properties);\n }\n }\n\n return schema;\n}\n","import type { AgentConfig, ClientTool, ExecuteOptions, SessionId, StreamCallbacks } from \"./types\";\nimport { AgentSession } from \"./session\";\n\nconst DEFAULT_BASE_URL = \"https://api.buildship.run\";\n\n/**\n * Main entry point for interacting with a BuildShip agent.\n *\n * @example\n * ```ts\n * import { BuildShipAgent } from \"buildship-agent-sdk/core\";\n *\n * const agent = new BuildShipAgent({\n * agentId: \"your-agent-id\",\n * accessKey: \"your-access-key\",\n * });\n *\n * const session = await agent.execute(\"Hello!\", {\n * onText: (text) => console.log(text),\n * onComplete: (fullText) => console.log(\"Done!\", fullText),\n * });\n * ```\n */\nexport class BuildShipAgent {\n /** @internal */ readonly _agentId: string;\n /** @internal */ readonly _accessKey?: string;\n /** @internal */ readonly _baseUrl: string;\n /** @internal */ readonly _clientTools = new Map<string, ClientTool>();\n\n constructor(config: AgentConfig) {\n if (!config.agentId) {\n throw new Error(\"BuildShipAgent: agentId is required\");\n }\n this._agentId = config.agentId;\n this._accessKey = config.accessKey;\n this._baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/$/, \"\");\n }\n\n /**\n * The URL for the agent's execute endpoint.\n * @internal\n */\n get _url(): string {\n return `${this._baseUrl}/executeAgent/${this._agentId}`;\n }\n\n /**\n * Build the authorization / common headers.\n * @internal\n */\n _buildHeaders(sessionId?: SessionId): Record<string, string> {\n const headers: Record<string, string> = {};\n if (this._accessKey) {\n headers[\"Authorization\"] = `Bearer ${this._accessKey}`;\n }\n if (sessionId) {\n headers[\"X-BuildShip-Agent-Session-ID\"] = sessionId;\n }\n return headers;\n }\n\n // ─── Public API ────────────────────────────────────────────────────\n\n /**\n * Start a new conversation.\n *\n * Creates a fresh session and sends the first message.\n *\n * @param message - The message to send\n * @param callbacks - Event handlers for the stream\n * @param options - Optional execution settings (context, headers, body, onSessionId)\n * @returns The new session\n */\n async execute(\n message: string,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n const session = new AgentSession(this);\n await session.execute(message, callbacks, options);\n return session;\n }\n\n /**\n * Get an existing session by ID to continue a conversation.\n *\n * @param sessionId - The session ID from a previous conversation\n * @returns The session object\n */\n session(sessionId: SessionId | string): AgentSession {\n if (!sessionId) {\n throw new Error(\"BuildShipAgent.session(): sessionId is required\");\n }\n return new AgentSession(this, sessionId as SessionId);\n }\n\n /**\n * Register a client-side tool that the agent can call.\n */\n registerClientTool(tool: ClientTool): void {\n if (!tool.name) {\n throw new Error(\"registerClientTool: tool.name is required\");\n }\n this._clientTools.set(tool.name, tool);\n }\n\n /**\n * Remove a registered client tool.\n */\n unregisterClientTool(name: string): void {\n this._clientTools.delete(name);\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","import { useContext, useEffect, useState, useCallback, createElement } from \"react\";\nimport type { ZodSchema } from \"zod\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/**\n * Infer the output type from a Zod schema's structural shape (`_zod.output`).\n * Falls back to `any` for raw JSON Schema objects or untyped parameters.\n * @internal\n */\ntype InferInput<T> = T extends { _zod: { output: infer O } } ? O : any;\n\nexport interface ClientToolRenderProps<T = any> {\n /** Parsed inputs from the agent. */\n inputs: T;\n /** Submit a result back to the agent (only available when `await: true`). */\n submit: (result: any) => void;\n /** Current status of this widget instance. */\n status: \"pending\" | \"submitted\";\n /** The persisted result from a previous submission (available after submit or on reload). */\n result?: any;\n}\n\nexport interface ClientToolConfig<TParams = any> {\n /** Tool name — must match the name the agent knows. */\n name: string;\n /** Description of what the tool does. */\n description: string;\n /**\n * Tool parameters — accepts a **Zod schema** or a raw JSON Schema object.\n * When a Zod schema is provided, `handler` and `render` inputs are\n * automatically typed — no explicit generic needed.\n *\n * @example\n * parameters: z.object({ question: z.string() })\n */\n parameters: TParams;\n /** If true, agent pauses and waits for the tool result before continuing. */\n await?: boolean;\n /**\n * Handler function for headless tools (no UI).\n * If `await: true`, the return value is sent back to the agent.\n * If `await: false`, runs as fire-and-forget.\n * Inputs are automatically typed when `parameters` is a Zod schema.\n */\n handler?: (inputs: InferInput<TParams>) => any | Promise<any>;\n /**\n * Render function for widget tools (with UI).\n * Receives `{ inputs, submit, status }`.\n * - `submit(result)` resumes the agent when `await: true`.\n * - `status` is `\"pending\"` until submitted, then `\"submitted\"`.\n * Inputs are automatically typed when `parameters` is a Zod schema.\n */\n render?: (props: ClientToolRenderProps<InferInput<TParams>>) => any;\n}\n\n// ─── Context import (late-bound to avoid circular deps) ──────────────────────\n\n// We import the context lazily from agent-context\nimport { AgentToolContext } from \"./agent-context\";\n\n// ─── useClientTool hook ──────────────────────────────────────────────────────\n\n/**\n * Register a client tool for a specific agent.\n *\n * @example\n * ```tsx\n * // Headless tool\n * useClientTool(\"agent-123\", {\n * name: \"get_location\",\n * description: \"Gets user location\",\n * parameters: z.object({}),\n * handler: async () => {\n * const pos = await getPosition();\n * return { lat: pos.coords.latitude, lng: pos.coords.longitude };\n * },\n * });\n *\n * // Widget tool with submission\n * useClientTool(\"agent-123\", {\n * name: \"feedback_form\",\n * description: \"Collects feedback\",\n * parameters: z.object({ question: z.string() }),\n * await: true,\n * render: ({ inputs, submit, status }) => (\n * <form onSubmit={() => submit({ answer: \"...\" })}>\n * <p>{inputs.question}</p>\n * <button disabled={status !== \"pending\"}>Submit</button>\n * </form>\n * ),\n * });\n * ```\n */\nexport function useClientTool<TParams>(agentId: string, config: ClientToolConfig<TParams>): void {\n const context = useContext(AgentToolContext);\n\n if (!context) {\n throw new Error(\"useClientTool must be used within <AgentContextProvider>\");\n }\n\n useEffect(() => {\n context.registerTool(agentId, config);\n return () => {\n context.unregisterTool(agentId, config.name);\n };\n // Note: consumers should memoize `config` to avoid unnecessary re-registrations.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agentId, config.name, config.handler, config.render, config.parameters]);\n}\n\n// ─── ToolRenderer component ──────────────────────────────────────────────────\n\ninterface ToolRendererProps {\n /** The agent ID this tool belongs to. */\n agentId: string;\n /** The widget message part to render. */\n part: {\n toolName: string;\n callId: string;\n inputs: any;\n paused?: boolean;\n status?: \"pending\" | \"submitted\";\n result?: any;\n };\n}\n\n/**\n * Renders a registered widget tool.\n * Looks up the tool by name from the registry and renders it with\n * the appropriate props (inputs, submit, status).\n *\n * @example\n * ```tsx\n * {message.parts?.map((part) => {\n * if (part.type === \"widget\") {\n * return <ToolRenderer key={part.callId} agentId=\"agent-123\" part={part} />;\n * }\n * return <Markdown key={part.firstSequence}>{part.text}</Markdown>;\n * })}\n * ```\n */\nexport function ToolRenderer({ agentId, part }: ToolRendererProps) {\n const context = useContext(AgentToolContext);\n const [localStatus, setLocalStatus] = useState<\"pending\" | \"submitted\">(part.status || \"pending\");\n\n // Sync localStatus when part.status changes externally\n // (e.g., messages reloaded from session storage after resume)\n useEffect(() => {\n setLocalStatus(part.status || \"pending\");\n }, [part.status]);\n\n if (!context) {\n throw new Error(\"ToolRenderer must be used within <AgentContextProvider>\");\n }\n\n const tool = context.getTool(agentId, part.toolName);\n\n const handleSubmit = useCallback(\n (result: any) => {\n if (localStatus === \"submitted\") return; // Prevent double-submission\n setLocalStatus(\"submitted\");\n context.resumeTool(agentId, part.callId, result);\n },\n [agentId, part.callId, localStatus, context],\n );\n\n if (!tool?.render) {\n return null; // No registered render function for this tool\n }\n\n return tool.render({\n inputs: part.inputs,\n submit: part.paused ? handleSubmit : () => {},\n status: localStatus,\n result: part.result,\n });\n}\n"],"mappings":"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","names":["import_react","import_react","import_react","options","tryParseJSON","import_zod","resolveParameters","import_react","import_react"]}
|
package/dist/react/index.js
CHANGED
|
@@ -606,6 +606,20 @@ function useAgent(agent, options) {
|
|
|
606
606
|
}
|
|
607
607
|
return updatedMessages;
|
|
608
608
|
});
|
|
609
|
+
} else if (options2?.skipUserMessage && options2?.context) {
|
|
610
|
+
setMessages((prev) => {
|
|
611
|
+
const lastUserIdx = prev.findLastIndex((m) => m.role === "user");
|
|
612
|
+
if (lastUserIdx === -1) return prev;
|
|
613
|
+
const updatedMessages = [...prev];
|
|
614
|
+
updatedMessages[lastUserIdx] = {
|
|
615
|
+
...updatedMessages[lastUserIdx],
|
|
616
|
+
context: options2.context
|
|
617
|
+
};
|
|
618
|
+
if (sessionUtils.syncSessionRef.current) {
|
|
619
|
+
sessionUtils.syncSessionRef.current(updatedMessages);
|
|
620
|
+
}
|
|
621
|
+
return updatedMessages;
|
|
622
|
+
});
|
|
609
623
|
}
|
|
610
624
|
const effectiveExecutionId = options2?.skipUserMessage ? messagesRef.current.findLast((m) => m.role === "user")?.executionId ?? userMessage.executionId : userMessage.executionId;
|
|
611
625
|
lastRunOptionsRef.current = {
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/agent-context.tsx","../../src/react/use-agent.ts","../../src/react/constants.ts","../../src/react/session-utils.ts","../../src/react/debug-handlers.ts","../../src/react/client-tools.ts","../../src/react/utils/schema.ts","../../src/react/utils/message.ts","../../src/react/stream-callbacks.ts","../../src/core/stream.ts","../../src/core/session.ts","../../src/core/agent.ts","../../src/react/utils/use-synced-local-storage.ts","../../src/react/use-client-tool.ts"],"sourcesContent":["import {\n createContext,\n useContext,\n useCallback,\n useRef,\n useState,\n useEffect,\n useMemo,\n ReactNode,\n} from \"react\";\nimport useAgent, { type UseAgentOptions } from \"./use-agent\";\nimport { BuildShipAgent } from \"../core/agent\";\nimport type { Message, Session, DebugDataType } from \"./types\";\nimport type { ClientToolConfig } from \"./use-client-tool\";\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 handleSend: (\n input: string,\n options?: {\n context?: Record<string, unknown>;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n /** @deprecated Use `useClientTool` hook instead. */\n clientTools?: Array<{\n name: string;\n description: string;\n parameters: unknown;\n await?: boolean;\n }>;\n },\n ) => Promise<void>;\n resumeTool: (callId: string, result: any) => Promise<void>;\n switchSession: (sessionId?: string) => void;\n deleteSession: (sessionId: string) => void;\n addOptimisticMessage: (input: string, context?: Record<string, any>) => void;\n abort: () => void;\n}\n\n// ─── Tool Registry Context ──────────────────────────────────────────────────\n\nexport interface AgentToolContextValue {\n registerTool: (agentId: string, config: ClientToolConfig) => void;\n unregisterTool: (agentId: string, toolName: string) => void;\n getTool: (agentId: string, toolName: string) => ClientToolConfig | undefined;\n getToolsForAgent: (agentId: string) => ClientToolConfig[];\n resumeTool: (agentId: string, callId: string, result: any) => void;\n}\n\nexport const AgentToolContext = createContext<AgentToolContextValue | null>(null);\n\n// ─── Agent Context ──────────────────────────────────────────────────────────\n\ninterface AgentContextValue {\n initializeAgent: (\n agentId: string,\n agentUrl: string,\n accessKey?: string,\n options?: UseAgentOptions,\n ) => 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<\n Map<string, { agentUrl: string; accessKey?: string; options?: UseAgentOptions }>\n >(new Map());\n const runnersRef = useRef<Map<string, AgentRunner>>(new Map());\n const listenersRef = useRef<Map<string, Set<() => void>>>(new Map());\n\n // Tool registry: agentId -> Map<toolName, ClientToolConfig>\n const toolRegistryRef = useRef<Map<string, Map<string, ClientToolConfig>>>(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(\n (agentId: string, agentUrl: string, accessKey?: string, options?: UseAgentOptions) => {\n const existing = activeAgentsRef.current.get(agentId);\n\n if (!existing) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey, options });\n forceUpdate({});\n } else if (existing.agentUrl !== agentUrl || existing.accessKey !== accessKey) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey, options });\n forceUpdate({});\n } else if (options) {\n // Always update options ref (e.g. textDeltaModifier) without triggering re-render\n existing.options = options;\n }\n },\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 // ─── Tool registry methods ─────────────────────────────────────────\n\n const registerTool = useCallback((agentId: string, config: ClientToolConfig) => {\n if (!toolRegistryRef.current.has(agentId)) {\n toolRegistryRef.current.set(agentId, new Map());\n }\n toolRegistryRef.current.get(agentId)!.set(config.name, config);\n }, []);\n\n const unregisterTool = useCallback((agentId: string, toolName: string) => {\n toolRegistryRef.current.get(agentId)?.delete(toolName);\n }, []);\n\n const getTool = useCallback((agentId: string, toolName: string) => {\n return toolRegistryRef.current.get(agentId)?.get(toolName);\n }, []);\n\n const getToolsForAgent = useCallback((agentId: string) => {\n const toolMap = toolRegistryRef.current.get(agentId);\n return toolMap ? Array.from(toolMap.values()) : [];\n }, []);\n\n const resumeToolFromContext = useCallback((agentId: string, callId: string, result: any) => {\n const runner = runnersRef.current.get(agentId);\n if (runner) {\n runner.resumeTool(callId, result);\n } else {\n console.warn(`Cannot resume tool: no runner found for agent \"${agentId}\"`);\n }\n }, []);\n\n // ─── Context values ────────────────────────────────────────────────\n\n const agentContextValue = 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 const toolContextValue = useMemo(\n () => ({\n registerTool,\n unregisterTool,\n getTool,\n getToolsForAgent,\n resumeTool: resumeToolFromContext,\n }),\n [registerTool, unregisterTool, getTool, getToolsForAgent, resumeToolFromContext],\n );\n\n return (\n <AgentContext.Provider value={agentContextValue}>\n <AgentToolContext.Provider value={toolContextValue}>\n {children}\n {Array.from(activeAgentsRef.current.entries()).map(\n ([agentId, { agentUrl, accessKey, options }]) => (\n <AgentRunnerInstance\n key={agentId}\n agentId={agentId}\n agentUrl={agentUrl}\n accessKey={accessKey}\n options={options}\n />\n ),\n )}\n </AgentToolContext.Provider>\n </AgentContext.Provider>\n );\n}\n\nfunction AgentRunnerInstance({\n agentId,\n agentUrl,\n accessKey,\n options,\n}: {\n agentId: string;\n agentUrl: string;\n accessKey?: string;\n options?: UseAgentOptions;\n}) {\n const agent = useMemo(\n () => new BuildShipAgent({ agentId, baseUrl: agentUrl, accessKey }),\n [agentId, agentUrl, accessKey],\n );\n // Use a ref for options to avoid re-renders when function references change\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const agentRunner = useAgent(agent, optionsRef.current);\n const context = useContext(AgentContext);\n\n useEffect(() => {\n if (context) {\n context.registerRunner(agentId, agentRunner);\n }\n }, [agentId, agentRunner, context]);\n\n if (!context) return null;\n\n return null;\n}\n\nexport function useAgentContext(\n agentId: string,\n agentUrl: string,\n accessKey?: string,\n options?: UseAgentOptions,\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 // Use a ref for options so function identity changes don't trigger re-renders\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n useEffect(() => {\n initializeAgent(agentId, agentUrl, accessKey, optionsRef.current);\n }, [agentId, agentUrl, accessKey, 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 handleSend: async () => {},\n resumeTool: 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, useContext, useMemo } from \"react\";\nimport type { BuildShipAgent } from \"../core/agent\";\nimport type { AgentSession } from \"../core/session\";\nimport { DEFAULT_SESSION_NAME, TEMPORARY_SESSION_ID } from \"./constants\";\nimport { useSessionUtils } from \"./session-utils\";\nimport { createDebugHandlers } from \"./debug-handlers\";\nimport { useAgentGlobalState, AgentToolContext } from \"./agent-context\";\nimport type { Message } from \"./types\";\nimport { useClientToolHelpers } from \"./client-tools\";\nimport { buildStreamCallbacks } from \"./stream-callbacks\";\nimport type { RunOptions } from \"./stream-callbacks\";\n\nexport interface UseAgentOptions {\n textDeltaModifier?: (\n delta: string,\n fullText: string,\n meta: { executionId: string; sequence: number; agentId: string },\n ) => string;\n}\n\nexport default function useAgent(agent: BuildShipAgent, options?: UseAgentOptions) {\n const agentId = agent._agentId;\n\n const { allSessions, setAllSessions, debugData, setDebugData } = useAgentGlobalState();\n const toolContext = useContext(AgentToolContext);\n\n const [inProgress, setInProgress] = useState(false);\n const [messages, setMessages] = useState<Array<Message>>([]);\n const messagesRef = useRef<Array<Message>>([]);\n\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 useEffect(() => {\n const initialSessionId = sessionUtils.getInitialSessionId();\n setCurrentSessionId(initialSessionId);\n }, [agentId]);\n\n const debugHandlers = useMemo(() => createDebugHandlers(setDebugData), [setDebugData]);\n\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n // Reload messages from session storage only on session/agent switch\n useEffect(() => {\n if (inProgress) return;\n const session = sessionUtils.agentSessions[currentSessionId];\n if (session) {\n setMessages(session.messages);\n } else {\n setMessages([]);\n }\n }, [currentSessionId, agentId, sessionUtils.agentSessions, inProgress]);\n\n useEffect(() => {\n const syncRef = sessionUtils.syncSessionRef;\n const msgRef = messagesRef;\n return () => {\n if (msgRef.current.length > 0 && syncRef.current) {\n syncRef.current();\n }\n };\n }, [sessionUtils.syncSessionRef]);\n\n // Make a stable ref to avoid dependency cycles and redefinitions\n const optionsRef = useRef(options);\n useEffect(() => {\n optionsRef.current = options;\n }, [options]);\n\n const lastRunOptionsRef = useRef<{\n context?: object;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n }>({});\n\n const { getClientToolsMap } = useClientToolHelpers(agentId, toolContext);\n\n const activeSessionRef = useRef<AgentSession | null>(null);\n\n const runAgent = useCallback(\n async (input: string | undefined, runOptions?: RunOptions) => {\n const isNewSession = !currentSessionId || currentSessionId === TEMPORARY_SESSION_ID;\n\n setInProgress(true);\n\n const debugKey =\n runOptions?.optimisticExecutionId ||\n messagesRef.current.findLast((m) => m.role === \"user\")?.executionId;\n\n const deps = {\n agentId,\n currentSessionId,\n messagesRef,\n setMessages,\n setInProgress,\n syncSessionRef: sessionUtils.syncSessionRef,\n debugHandlers,\n toolContext,\n textDeltaModifier: optionsRef.current?.textDeltaModifier,\n };\n\n const callbacks = buildStreamCallbacks(deps, debugKey);\n\n const executeOptions = {\n context: runOptions?.context,\n headers: runOptions?.additionalHeaders,\n body: runOptions?.additionalBody,\n };\n\n // Ensure React-registered tools are synced into the core agent's map\n const toolsMap = getClientToolsMap();\n for (const tool of toolsMap.values()) {\n agent.registerClientTool(tool);\n }\n\n // Merge legacy client tool definitions safely\n if (runOptions?.clientTools && runOptions.clientTools.length > 0) {\n executeOptions.body = {\n ...(executeOptions.body || {}),\n clientTools: [\n ...((executeOptions.body?.clientTools as any[]) || []),\n ...runOptions.clientTools,\n ],\n };\n }\n\n try {\n if (runOptions?.resumeToolCallId) {\n if (isNewSession) throw new Error(\"Cannot resume a tool call on a temporary session.\");\n const session = agent.session(currentSessionId);\n activeSessionRef.current = session;\n await session.resumeWithCallId(\n runOptions.resumeToolCallId,\n runOptions.resumeToolResult,\n callbacks,\n executeOptions,\n );\n } else {\n if (isNewSession) {\n const extendedOptions = {\n ...executeOptions,\n onSessionId: (newSessionId: string, sessionName?: string) => {\n sessionUtils.createSessionFromResponse(\n newSessionId,\n sessionName || DEFAULT_SESSION_NAME,\n messagesRef.current,\n );\n setCurrentSessionId(newSessionId);\n },\n };\n const session = await agent.execute(input || \"\", callbacks, extendedOptions);\n activeSessionRef.current = session;\n } else {\n const session = agent.session(currentSessionId);\n activeSessionRef.current = session;\n await session.execute(input || \"\", callbacks, executeOptions);\n }\n }\n } catch (error) {\n console.log(\"Agent execution failed\", error);\n setInProgress(false);\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw error;\n } finally {\n activeSessionRef.current = null;\n }\n },\n [currentSessionId, sessionUtils, debugHandlers, agentId, toolContext, agent, getClientToolsMap],\n );\n\n const handleSend = useCallback(\n async (\n input: string,\n options?: {\n context?: object;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n },\n ) => {\n const userMessage: Message = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n ...(options?.context ? { context: options.context } : {}),\n };\n\n if (!options?.skipUserMessage) {\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n }\n\n const effectiveExecutionId = options?.skipUserMessage\n ? (messagesRef.current.findLast((m) => m.role === \"user\")?.executionId ??\n userMessage.executionId)\n : userMessage.executionId;\n\n // Track options so they can be re-applied during string continuations (like tool resumes)\n lastRunOptionsRef.current = {\n context: options?.context,\n additionalHeaders: options?.additionalHeaders,\n additionalBody: options?.additionalBody,\n };\n\n try {\n await runAgent(input, {\n ...options,\n optimisticExecutionId: effectiveExecutionId,\n });\n } catch (error) {\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 resumeTool = useCallback(\n async (callId: string, result: any) => {\n setMessages((prev) => {\n const updatedMessages = prev.map((msg) => {\n if (msg.parts) {\n const updatedParts = msg.parts.map((part) => {\n if (part.type === \"widget\" && part.callId === callId) {\n return { ...part, status: \"submitted\" as const, result };\n }\n return part;\n });\n return { ...msg, parts: updatedParts };\n }\n return msg;\n });\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n\n const lastUserMessage = messagesRef.current.findLast((m) => m.role === \"user\");\n const debugKey = lastUserMessage?.executionId;\n if (debugKey) {\n debugHandlers.handleStreamEvent({\n type: \"tool_call_end\",\n data: { callId, toolName: \"\", toolType: \"client\" as const, result },\n meta: { executionId: debugKey, sequence: 0 },\n } as any);\n }\n\n await runAgent(undefined, {\n resumeToolCallId: callId,\n resumeToolResult: result,\n ...lastRunOptionsRef.current,\n // Restore context from the persisted user message (survives page refresh)\n context: lastUserMessage?.context ?? lastRunOptionsRef.current.context,\n });\n },\n [runAgent, sessionUtils.syncSessionRef, debugHandlers],\n );\n\n const addOptimisticMessage = useCallback(\n (input: string, context?: Record<string, any>) => {\n const userMessage: Message = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n ...(context ? { context } : {}),\n };\n\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n },\n [sessionUtils.syncSessionRef],\n );\n\n const abort = useCallback(() => {\n if (activeSessionRef.current) {\n activeSessionRef.current.abort();\n }\n setInProgress(false);\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 resumeTool,\n addOptimisticMessage,\n abort,\n sessionId: currentSessionId,\n switchSession: sessionUtils.switchSession,\n deleteSession: sessionUtils.deleteSession,\n sessions: sessionUtils.sessionsList,\n debugData,\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 // If we're deleting the current session, switch to the most recent remaining one\n if (sessionId === currentSessionId) {\n const remainingSessions = Object.values(updatedAgentSessions);\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 return {\n ...prev,\n [agentId]: updatedAgentSessions,\n };\n });\n },\n [agentId, currentSessionId, 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 { StreamEvent } from \"../core/types\";\nimport type {\n DebugDataType,\n ToolExecutionItem,\n ReasoningItem,\n HandoffItem,\n RunErrorItem,\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 handleStreamEvent = (event: StreamEvent) => {\n const executionId = event.meta.executionId;\n\n switch (event.type) {\n case \"tool_call_start\": {\n const { callId, toolName, toolType, inputs, serverName } = event.data;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"tool_call\",\n toolName,\n callId,\n toolType,\n status: \"progress\",\n inputs,\n serverName,\n } as ToolExecutionItem,\n ],\n }));\n break;\n }\n\n case \"tool_call_end\": {\n const { callId, result, error } = event.data;\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.callId === callId) {\n currentData[i] = {\n ...toolItem,\n status: error ? \"error\" : \"complete\",\n output: result,\n error,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n break;\n }\n\n case \"reasoning_delta\": {\n const { delta, index } = event.data;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n let existingItemIndex = -1;\n for (let i = currentData.length - 1; i >= 0; i--) {\n const item = currentData[i];\n if (item.itemType === \"reasoning\" && (item as ReasoningItem).index === index) {\n existingItemIndex = i;\n break;\n }\n }\n\n if (existingItemIndex === -1) {\n currentData.push({ itemType: \"reasoning\", reasoning: delta, index });\n } else {\n currentData[existingItemIndex] = {\n itemType: \"reasoning\",\n reasoning: (currentData[existingItemIndex] as ReasoningItem).reasoning + delta,\n index,\n };\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n break;\n }\n\n case \"agent_handoff\": {\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"handoff\",\n agentName: event.data.agentName,\n } as HandoffItem,\n ],\n }));\n break;\n }\n\n case \"run_error\": {\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"run_error\",\n message: event.data.message,\n code: event.data.code,\n } as RunErrorItem,\n ],\n }));\n break;\n }\n }\n };\n\n return {\n handleStreamEvent,\n };\n};\n","import { useCallback, useContext } from \"react\";\nimport { toJSONSchema, type ZodSchema } from \"zod\";\n\nimport type { ExecuteRequestBody, ClientTool } from \"../core/types\";\nimport type { AgentToolContextValue } from \"./agent-context\";\nimport { cleanSchema } from \"./utils/schema\";\n\n/**\n * Resolve parameters — accepts Zod schema or plain JSON Schema object.\n */\nexport function resolveParameters(params: any): Record<string, any> {\n let schema: Record<string, any>;\n\n // Detect Zod schema: ZodType instances have a `_def` property\n if (params && typeof params === \"object\" && \"_def\" in params) {\n schema = toJSONSchema(params as ZodSchema) as Record<string, any>;\n delete schema.$schema;\n } else {\n schema = cleanSchema(params) as Record<string, any>;\n }\n\n // Gemini requires additionalProperties: false and required to include every key\n if (schema.type === \"object\") {\n schema.additionalProperties = false;\n if (schema.properties) {\n schema.required = Object.keys(schema.properties);\n }\n }\n\n return schema;\n}\n\n/**\n * Build the ClientTool map from ALL registered tools (handlers + widgets).\n * These are registered into the core agent's _clientTools so that\n * session._getClientToolDefs() can send their definitions to the server.\n * The core stream.ts handles tools without handlers correctly\n * (pauses for user interaction, or silently skips fire-and-forget).\n * Widget rendering is handled separately via onEvent → handleClientToolCall\n * in stream-callbacks.ts.\n */\nexport function useClientToolHelpers(agentId: string, toolContext: AgentToolContextValue | null) {\n const getClientToolsMap = useCallback((): Map<string, ClientTool> => {\n if (!toolContext) return new Map();\n const tools = toolContext.getToolsForAgent(agentId);\n const map = new Map<string, ClientTool>();\n\n for (const tool of tools) {\n map.set(tool.name, {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n await: tool.await,\n handler: tool.handler,\n });\n }\n\n return map;\n }, [agentId, toolContext]);\n\n /**\n * Build client tool definitions for the request body.\n * Includes ALL registered tools (handlers + widgets).\n */\n const getClientToolDefs = useCallback((): ExecuteRequestBody[\"clientTools\"] => {\n if (!toolContext) return [];\n const tools = toolContext.getToolsForAgent(agentId);\n\n return tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: resolveParameters(tool.parameters),\n await: tool.await,\n }));\n }, [agentId, toolContext]);\n\n return { getClientToolsMap, getClientToolDefs };\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 * appending it and merging with the previous part if both are contiguous text deltas.\n * Parts are kept in arrival order (no sorting) since events stream chronologically.\n */\nexport function updateAgentMessageParts(parts: MessagePart[], newPart: MessagePart): MessagePart[] {\n const last = parts[parts.length - 1];\n\n // Merge contiguous text deltas\n const canMerge =\n last?.type === \"text\" &&\n newPart.type === \"text\" &&\n newPart.firstSequence === last.lastSequence + 1;\n\n if (canMerge) {\n return [\n ...parts.slice(0, -1),\n {\n ...last,\n text: last.text + newPart.text,\n lastSequence: newPart.lastSequence,\n },\n ];\n }\n\n return [...parts, newPart];\n}\n","import type {\n StreamCallbacks,\n StreamEvent,\n TextDeltaEvent,\n ToolCallStartEvent,\n} from \"../core/types\";\n\nimport type { AgentToolContextValue } from \"./agent-context\";\nimport type { createDebugHandlers } from \"./debug-handlers\";\nimport type { Message, MessagePart } from \"./types\";\nimport { tryParseJSON } from \"./utils/schema\";\nimport { updateAgentMessageParts } from \"./utils/message\";\n\n// ── Types ──────────────────────────────────────────────────────────────\n\nexport type RunOptions = {\n context?: object;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n optimisticExecutionId?: string;\n /** @deprecated Use `useClientTool` hook instead. */\n clientTools?: Array<{\n name: string;\n description: string;\n parameters: unknown;\n await?: boolean;\n }>;\n // Resume params\n resumeToolCallId?: string;\n resumeToolResult?: any;\n};\n\nexport type StreamDeps = {\n agentId: string;\n currentSessionId: string;\n messagesRef: React.MutableRefObject<Array<Message>>;\n setMessages: React.Dispatch<React.SetStateAction<Array<Message>>>;\n setInProgress: React.Dispatch<React.SetStateAction<boolean>>;\n syncSessionRef: React.MutableRefObject<((messages?: Array<Message>) => void) | undefined>;\n debugHandlers: ReturnType<typeof createDebugHandlers>;\n toolContext: AgentToolContextValue | null;\n textDeltaModifier?: (\n delta: string,\n fullText: string,\n meta: { executionId: string; sequence: number; agentId: string },\n ) => string;\n};\n\n// ── Build callbacks ────────────────────────────────────────────────────\n\n/**\n * Build the StreamCallbacks object from dependencies.\n * Keeps event-handling logic out of the main hook.\n */\nexport function buildStreamCallbacks(\n deps: StreamDeps,\n debugKey: string | undefined,\n): StreamCallbacks {\n const {\n setMessages,\n setInProgress,\n syncSessionRef,\n messagesRef,\n toolContext,\n agentId,\n textDeltaModifier,\n } = deps;\n\n return {\n onComplete: () => {\n console.log(\"Agent closed\");\n setInProgress(false);\n if (syncSessionRef.current) {\n syncSessionRef.current(messagesRef.current);\n }\n },\n onError: (error: Error) => {\n console.log(\"Agent error\", error);\n setInProgress(false);\n if (syncSessionRef.current) {\n syncSessionRef.current(messagesRef.current);\n }\n },\n onEvent: (event: StreamEvent) => {\n if (event.type === \"text_delta\") {\n handleTextDelta(event, setMessages, syncSessionRef, textDeltaModifier, agentId);\n } else if (event.type === \"tool_call_start\" && event.data.toolType === \"client\") {\n // Create a widget part for tools with a render function\n handleClientToolCall(event, setMessages, syncSessionRef, toolContext, agentId);\n // Send to debug so the tool shows in the debug panel\n if (debugKey) {\n const debugMeta = { ...event.meta, executionId: debugKey };\n deps.debugHandlers.handleStreamEvent({\n ...event,\n meta: debugMeta,\n } as StreamEvent);\n\n // Server never sends tool_call_end for client tools.\n // For non-paused (fire-and-forget) tools, immediately mark complete.\n if (!event.data.paused) {\n deps.debugHandlers.handleStreamEvent({\n type: \"tool_call_end\",\n data: {\n callId: event.data.callId,\n toolName: event.data.toolName,\n toolType: event.data.toolType,\n },\n meta: debugMeta,\n } as StreamEvent);\n }\n }\n } else if (debugKey) {\n // All other events (server tools, reasoning, handoffs, etc.)\n deps.debugHandlers.handleStreamEvent({\n ...event,\n meta: { ...event.meta, executionId: debugKey },\n } as StreamEvent);\n }\n },\n };\n}\n\n// ── Event handlers (private) ───────────────────────────────────────────\n\nfunction handleTextDelta(\n event: TextDeltaEvent,\n setMessages: React.Dispatch<React.SetStateAction<Array<Message>>>,\n syncSessionRef: React.MutableRefObject<((messages?: Array<Message>) => void) | undefined>,\n modifier:\n | ((\n delta: string,\n fullText: string,\n meta: { executionId: string; sequence: number; agentId: string },\n ) => string)\n | undefined,\n agentId: string,\n) {\n const sequence = event.meta.sequence;\n const originalText = event.data;\n const eventExecutionId = event.meta.executionId;\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n\n // Calculate the modified text delta using the full text accumulation so far\n let text = originalText;\n if (modifier) {\n const currentFullText = lastMessage?.role === \"agent\" ? lastMessage.content : \"\";\n text = modifier(originalText, currentFullText, {\n executionId: eventExecutionId,\n sequence,\n agentId: event.meta.agentId || agentId,\n });\n }\n\n const newPart: MessagePart = {\n type: \"text\",\n text,\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 + text,\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: text,\n parts: [newPart],\n executionId: eventExecutionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (syncSessionRef.current) {\n syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n}\n\nfunction handleClientToolCall(\n event: ToolCallStartEvent,\n setMessages: React.Dispatch<React.SetStateAction<Array<Message>>>,\n syncSessionRef: React.MutableRefObject<((messages?: Array<Message>) => void) | undefined>,\n toolContext: AgentToolContextValue | null,\n agentId: string,\n) {\n // Only create widget for tools with a registered render function\n const tool = toolContext?.getTool(agentId, event.data.toolName);\n if (!tool?.render) return;\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newPart: MessagePart = {\n type: \"widget\",\n toolName: event.data.toolName,\n callId: event.data.callId,\n inputs: tryParseJSON(event.data.inputs),\n sequence: event.meta.sequence,\n paused: event.data.paused,\n status: \"pending\",\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: event.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (syncSessionRef.current) {\n syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n}\n","import type { StreamEvent, StreamOptions, SessionId } from \"./types\";\n\n/** Safely parse a value as JSON if it's a string, otherwise return as-is. */\nfunction 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\n/**\n * Fatal error — will NOT be retried.\n */\nclass FatalStreamError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n ) {\n super(message);\n this.name = \"FatalStreamError\";\n }\n}\n\n/**\n * Opens an SSE connection to the BuildShip agent endpoint using native\n * `fetch` + `ReadableStream`, parses events, and dispatches to the\n * appropriate callbacks.\n *\n * Zero runtime dependencies — works in both browser and Node.js.\n *\n * @internal\n */\nexport async function executeStream(options: StreamOptions): Promise<void> {\n const {\n url,\n body,\n headers,\n callbacks,\n clientTools,\n signal,\n onSessionId,\n onPaused,\n onAutoResume,\n onResponse,\n } = options;\n\n let fullText = \"\";\n\n // Track pending auto-resume operations so we don't call onComplete prematurely\n const pendingAutoResumes: Promise<{ callId: string; result: unknown } | null>[] = [];\n\n // ── Make the request ────────────────────────────────────────────────\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n ...headers,\n },\n body: JSON.stringify(body),\n signal,\n });\n\n // ── Extract session ID and name from response headers ──────────────\n const sessionId = response.headers.get(\"X-BuildShip-Agent-Session-ID\");\n if (sessionId && onSessionId) {\n const sessionName = response.headers.get(\"X-BuildShip-Agent-Session-Name\") || undefined;\n onSessionId(sessionId as SessionId, sessionName);\n }\n\n // Expose the raw Response object\n onResponse?.(response);\n\n // ── Handle HTTP errors ─────────────────────────────────────────────\n if (!response.ok) {\n let errorBody = \"\";\n try {\n errorBody = await response.text();\n } catch {\n // ignore\n }\n const error = new FatalStreamError(\n `HTTP ${response.status}: ${errorBody || response.statusText}`,\n response.status,\n );\n callbacks.onError?.(error);\n throw error;\n }\n\n // ── Read the SSE stream ────────────────────────────────────────────\n if (!response.body) {\n callbacks.onComplete?.(fullText);\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // SSE events are separated by double newlines\n const parts = buffer.split(\"\\n\\n\");\n buffer = parts.pop() || \"\";\n\n for (const part of parts) {\n const trimmedPart = part.trim();\n if (!trimmedPart) continue;\n\n // Extract the data field from SSE format\n let jsonStr = \"\";\n for (const line of trimmedPart.split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n jsonStr += line.slice(6);\n } else if (line.startsWith(\"data:\")) {\n jsonStr += line.slice(5);\n }\n }\n\n jsonStr = jsonStr.trim();\n if (!jsonStr) continue;\n\n let raw: any;\n try {\n raw = JSON.parse(jsonStr);\n } catch {\n // Skip malformed events\n continue;\n }\n\n // Normalize backend event type names (llm_text_delta → text_delta, etc.)\n const streamEvent = normalizeEvent(raw) as StreamEvent;\n\n handleEvent(\n streamEvent,\n fullText,\n callbacks,\n clientTools,\n onPaused,\n onAutoResume,\n pendingAutoResumes,\n );\n\n // Accumulate text\n if (streamEvent.type === \"text_delta\") {\n fullText += streamEvent.data;\n }\n }\n }\n\n // Process any remaining data in buffer\n if (buffer.trim()) {\n let jsonStr = \"\";\n for (const line of buffer.trim().split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n jsonStr += line.slice(6);\n } else if (line.startsWith(\"data:\")) {\n jsonStr += line.slice(5);\n }\n }\n\n jsonStr = jsonStr.trim();\n if (jsonStr) {\n try {\n const raw = JSON.parse(jsonStr);\n const streamEvent = normalizeEvent(raw) as StreamEvent;\n handleEvent(\n streamEvent,\n fullText,\n callbacks,\n clientTools,\n onPaused,\n onAutoResume,\n pendingAutoResumes,\n );\n if (streamEvent.type === \"text_delta\") {\n fullText += streamEvent.data;\n }\n } catch {\n // Skip malformed trailing data\n }\n }\n }\n } catch (err) {\n // AbortError — re-throw\n if (err instanceof Error && err.name === \"AbortError\") {\n throw err;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n callbacks.onError?.(error);\n throw error;\n }\n\n // Wait for any pending auto-resume handlers before signaling completion\n if (pendingAutoResumes.length > 0) {\n const handlerResults = await Promise.allSettled(pendingAutoResumes);\n for (const settled of handlerResults) {\n if (settled.status === \"fulfilled\" && settled.value) {\n const { callId, result } = settled.value;\n await onAutoResume?.(callId, result);\n }\n }\n }\n\n callbacks.onComplete?.(fullText);\n}\n\n/**\n * Normalize backend event type names.\n * The backend sends `llm_text_delta` / `llm_reasoning_delta` but the SDK\n * exposes them as `text_delta` / `reasoning_delta`.\n * @internal\n */\nfunction normalizeEvent(raw: any): any {\n const typeMap: Record<string, string> = {\n llm_text_delta: \"text_delta\",\n llm_reasoning_delta: \"reasoning_delta\",\n };\n if (raw && typeof raw.type === \"string\" && typeMap[raw.type]) {\n raw.type = typeMap[raw.type];\n }\n return raw;\n}\n\n/**\n * Dispatch a parsed stream event to the appropriate callbacks.\n * @internal\n */\nfunction handleEvent(\n event: StreamEvent,\n _fullText: string,\n callbacks: StreamOptions[\"callbacks\"],\n clientTools: StreamOptions[\"clientTools\"],\n onPaused: StreamOptions[\"onPaused\"],\n onAutoResume: StreamOptions[\"onAutoResume\"],\n pendingAutoResumes: Promise<{ callId: string; result: unknown } | null>[],\n): void {\n // Notify raw event consumers\n callbacks.onEvent?.(event);\n\n switch (event.type) {\n case \"text_delta\": {\n callbacks.onText?.(event.data);\n break;\n }\n\n case \"reasoning_delta\": {\n callbacks.onReasoning?.(event.data.delta, event.data.index);\n break;\n }\n\n case \"agent_handoff\": {\n callbacks.onAgentHandoff?.(event.data.agentName);\n break;\n }\n\n case \"tool_call_start\": {\n const { callId, toolName, toolType, inputs: rawInputs, paused } = event.data;\n // Backend sends toolCall.arguments as a JSON string — parse it\n const inputs = tryParseJSON(rawInputs);\n\n // Notify callback\n callbacks.onToolStart?.(toolName, toolType);\n\n // Handle client tools\n if (toolType === \"client\") {\n const tool = clientTools.get(toolName);\n if (tool) {\n if (paused && tool.handler) {\n // Blocking tool with handler → auto-execute and resume\n const handlerPromise = (async (): Promise<{\n callId: string;\n result: unknown;\n } | null> => {\n try {\n const result = await tool.handler!(inputs);\n\n // Synthesize a tool_call_end event for local observers (like debug panels)\n // since the backend only emits for server-side executed tools\n callbacks.onEvent?.({\n type: \"tool_call_end\",\n data: {\n callId,\n toolName,\n toolType: \"client\",\n result,\n },\n meta: event.meta,\n });\n\n return { callId, result };\n } catch (error) {\n // If handler fails, still call onPaused so user can decide\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n return null;\n }\n })();\n pendingAutoResumes.push(handlerPromise);\n } else if (paused) {\n // Blocking tool without handler → pause for user\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n } else if (tool.handler) {\n // Fire-and-forget tool with handler\n try {\n tool.handler(inputs);\n } catch {\n // Swallow errors on fire-and-forget\n }\n }\n } else if (paused) {\n // No registered tool but paused — notify user\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n }\n }\n break;\n }\n\n case \"tool_call_end\": {\n const { toolName, result, error } = event.data;\n callbacks.onToolEnd?.(toolName, result, error);\n break;\n }\n\n case \"run_error\": {\n const { message, code } = event.data;\n const error = new Error(message);\n if (code != null) (error as any).code = code;\n callbacks.onError?.(error);\n break;\n }\n }\n}\n","import type {\n SessionId,\n StreamCallbacks,\n PausedToolInfo,\n ExecuteRequestBody,\n ExecuteOptions,\n} from \"./types\";\nimport type { BuildShipAgent } from \"./agent\";\nimport { executeStream } from \"./stream\";\nimport { toJSONSchema, type ZodSchema } from \"zod\";\n\n/**\n * Represents a conversation session with a BuildShip agent.\n *\n * Sessions maintain history across multiple turns and support\n * pause/resume for blocking client tools.\n */\nexport class AgentSession {\n /** @internal */ private _agent: BuildShipAgent;\n /** @internal */ private _sessionId: SessionId | undefined;\n /** @internal */ private _paused = false;\n /** @internal */ private _pausedToolInfo: PausedToolInfo | null = null;\n /** @internal */ private _abortController: AbortController | null = null;\n\n /** @internal */\n constructor(agent: BuildShipAgent, sessionId?: SessionId) {\n this._agent = agent;\n this._sessionId = sessionId;\n }\n\n // ─── Public API ────────────────────────────────────────────────────\n\n /**\n * Send a message in this session.\n *\n * @param message - The message to send\n * @param callbacks - Event handlers for the stream\n * @param callbacks - Event handlers for the stream\n * @param options - Optional settings like context, headers, or body\n * @returns This session (for chaining)\n */\n async execute(\n message: string,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n this._paused = false;\n this._pausedToolInfo = null;\n\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n input: message,\n stream: true,\n };\n\n // Attach context as top-level properties if provided\n if (options?.context) {\n Object.assign(body, { context: options.context });\n }\n\n // Include client tool definitions\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n await this._run(body, callbacks, options);\n return this;\n }\n\n /**\n * Resume a paused session with a tool result.\n *\n * @param result - The result to send back to the agent\n * @param callbacks - Event handlers for the resumed stream\n * @param options - Optional settings like headers or body\n * @returns This session (for chaining)\n */\n async resume(\n result: any,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n if (!this._paused || !this._pausedToolInfo) {\n throw new Error(\"AgentSession.resume(): session is not paused. Check isPaused() first.\");\n }\n\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: {\n callId: this._pausedToolInfo.callId,\n result,\n },\n };\n\n // Attach context if provided\n if (options?.context) {\n Object.assign(body, { context: options.context });\n }\n\n // Include client tool definitions for resume requests too\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n this._paused = false;\n this._pausedToolInfo = null;\n\n await this._run(body, callbacks, options);\n return this;\n }\n\n /**\n * Resume a session with an explicit tool call ID and result.\n *\n * Unlike `resume()`, this does NOT require the session to be in a paused state,\n * making it suitable for external resume flows (e.g. React widget submissions)\n * where the session object may have been re-created.\n *\n * @param callId - The tool call ID to resume\n * @param result - The result to send back to the agent\n * @param callbacks - Event handlers for the resumed stream\n * @param options - Optional settings like headers or body\n * @returns This session (for chaining)\n */\n async resumeWithCallId(\n callId: string,\n result: any,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: { callId, result },\n };\n\n // Attach context if provided\n if (options?.context) {\n Object.assign(body, { context: options.context });\n }\n\n // Include client tool definitions for resume requests too\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n // Clear any stale pause state\n this._paused = false;\n this._pausedToolInfo = null;\n\n await this._run(body, callbacks, options);\n return this;\n }\n\n /**\n * Check if this session is waiting for a tool result.\n */\n isPaused(): boolean {\n return this._paused;\n }\n\n /**\n * Get information about the paused tool call.\n * Returns `null` if the session is not paused.\n */\n getPausedTool(): PausedToolInfo | null {\n return this._pausedToolInfo;\n }\n\n /**\n * Get the session ID.\n * May be `undefined` if the session hasn't executed yet.\n */\n getSessionId(): SessionId {\n if (!this._sessionId) {\n throw new Error(\n \"AgentSession.getSessionId(): session ID not yet available. Call execute() first.\",\n );\n }\n return this._sessionId;\n }\n\n /**\n * Cancel the current streaming operation.\n */\n abort(): void {\n this._abortController?.abort();\n this._abortController = null;\n }\n\n // ─── Private helpers ───────────────────────────────────────────────\n\n /** @internal */\n private async _run(\n body: ExecuteRequestBody,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<void> {\n // Create a fresh abort controller for this run\n this._abortController = new AbortController();\n\n const baseHeaders = this._agent._buildHeaders(this._sessionId);\n const mergedHeaders = { ...baseHeaders, ...(options?.headers || {}) };\n\n await executeStream({\n url: this._agent._url,\n body,\n headers: mergedHeaders,\n callbacks,\n clientTools: this._agent._clientTools,\n signal: this._abortController.signal,\n\n onSessionId: (id, name) => {\n this._sessionId = id;\n options?.onSessionId?.(id, name);\n },\n\n onPaused: (info) => {\n this._paused = true;\n this._pausedToolInfo = info;\n },\n\n onAutoResume: async (callId, result) => {\n // Auto-resume: send the tool result back immediately\n const resumeBody: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: { callId, result },\n };\n\n // Carry context forward from the original execute options\n if (options?.context) {\n Object.assign(resumeBody, { context: options.context });\n }\n\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n resumeBody.clientTools = clientToolDefs;\n }\n\n await this._run(resumeBody, callbacks, options);\n },\n });\n }\n\n /** @internal */\n private _getClientToolDefs() {\n const defs: ExecuteRequestBody[\"clientTools\"] = [];\n for (const tool of this._agent._clientTools.values()) {\n defs.push({\n name: tool.name,\n description: tool.description,\n parameters: resolveParameters(tool.parameters),\n await: tool.await,\n });\n }\n return defs;\n }\n}\n\n/**\n * Convert tool parameters to a JSON Schema object.\n * - If it's a Zod schema, uses Zod's built-in `toJSONSchema` to convert.\n * - Always ensures `additionalProperties: false` is set (required by the backend).\n * - Always ensures `required` includes every key in `properties` (Gemini requirement).\n * @internal\n */\nfunction resolveParameters(params: any): Record<string, any> {\n let schema: Record<string, any>;\n\n // Detect Zod schema: ZodType instances have a `_def` property\n if (params && typeof params === \"object\" && \"_def\" in params) {\n schema = toJSONSchema(params as ZodSchema) as Record<string, any>;\n // Remove $schema key if present\n delete schema.$schema;\n } else {\n schema = { ...params };\n }\n\n if (schema.type === \"object\") {\n // Backend requires additionalProperties: false\n schema.additionalProperties = false;\n\n // Gemini requires `required` to include every key in `properties`\n if (schema.properties) {\n schema.required = Object.keys(schema.properties);\n }\n }\n\n return schema;\n}\n","import type { AgentConfig, ClientTool, ExecuteOptions, SessionId, StreamCallbacks } from \"./types\";\nimport { AgentSession } from \"./session\";\n\nconst DEFAULT_BASE_URL = \"https://api.buildship.run\";\n\n/**\n * Main entry point for interacting with a BuildShip agent.\n *\n * @example\n * ```ts\n * import { BuildShipAgent } from \"buildship-agent-sdk/core\";\n *\n * const agent = new BuildShipAgent({\n * agentId: \"your-agent-id\",\n * accessKey: \"your-access-key\",\n * });\n *\n * const session = await agent.execute(\"Hello!\", {\n * onText: (text) => console.log(text),\n * onComplete: (fullText) => console.log(\"Done!\", fullText),\n * });\n * ```\n */\nexport class BuildShipAgent {\n /** @internal */ readonly _agentId: string;\n /** @internal */ readonly _accessKey?: string;\n /** @internal */ readonly _baseUrl: string;\n /** @internal */ readonly _clientTools = new Map<string, ClientTool>();\n\n constructor(config: AgentConfig) {\n if (!config.agentId) {\n throw new Error(\"BuildShipAgent: agentId is required\");\n }\n this._agentId = config.agentId;\n this._accessKey = config.accessKey;\n this._baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/$/, \"\");\n }\n\n /**\n * The URL for the agent's execute endpoint.\n * @internal\n */\n get _url(): string {\n return `${this._baseUrl}/executeAgent/${this._agentId}`;\n }\n\n /**\n * Build the authorization / common headers.\n * @internal\n */\n _buildHeaders(sessionId?: SessionId): Record<string, string> {\n const headers: Record<string, string> = {};\n if (this._accessKey) {\n headers[\"Authorization\"] = `Bearer ${this._accessKey}`;\n }\n if (sessionId) {\n headers[\"X-BuildShip-Agent-Session-ID\"] = sessionId;\n }\n return headers;\n }\n\n // ─── Public API ────────────────────────────────────────────────────\n\n /**\n * Start a new conversation.\n *\n * Creates a fresh session and sends the first message.\n *\n * @param message - The message to send\n * @param callbacks - Event handlers for the stream\n * @param options - Optional execution settings (context, headers, body, onSessionId)\n * @returns The new session\n */\n async execute(\n message: string,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n const session = new AgentSession(this);\n await session.execute(message, callbacks, options);\n return session;\n }\n\n /**\n * Get an existing session by ID to continue a conversation.\n *\n * @param sessionId - The session ID from a previous conversation\n * @returns The session object\n */\n session(sessionId: SessionId | string): AgentSession {\n if (!sessionId) {\n throw new Error(\"BuildShipAgent.session(): sessionId is required\");\n }\n return new AgentSession(this, sessionId as SessionId);\n }\n\n /**\n * Register a client-side tool that the agent can call.\n */\n registerClientTool(tool: ClientTool): void {\n if (!tool.name) {\n throw new Error(\"registerClientTool: tool.name is required\");\n }\n this._clientTools.set(tool.name, tool);\n }\n\n /**\n * Remove a registered client tool.\n */\n unregisterClientTool(name: string): void {\n this._clientTools.delete(name);\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","import { useContext, useEffect, useState, useCallback, createElement } from \"react\";\nimport type { ZodSchema } from \"zod\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/**\n * Infer the output type from a Zod schema's structural shape (`_zod.output`).\n * Falls back to `any` for raw JSON Schema objects or untyped parameters.\n * @internal\n */\ntype InferInput<T> = T extends { _zod: { output: infer O } } ? O : any;\n\nexport interface ClientToolRenderProps<T = any> {\n /** Parsed inputs from the agent. */\n inputs: T;\n /** Submit a result back to the agent (only available when `await: true`). */\n submit: (result: any) => void;\n /** Current status of this widget instance. */\n status: \"pending\" | \"submitted\";\n /** The persisted result from a previous submission (available after submit or on reload). */\n result?: any;\n}\n\nexport interface ClientToolConfig<TParams = any> {\n /** Tool name — must match the name the agent knows. */\n name: string;\n /** Description of what the tool does. */\n description: string;\n /**\n * Tool parameters — accepts a **Zod schema** or a raw JSON Schema object.\n * When a Zod schema is provided, `handler` and `render` inputs are\n * automatically typed — no explicit generic needed.\n *\n * @example\n * parameters: z.object({ question: z.string() })\n */\n parameters: TParams;\n /** If true, agent pauses and waits for the tool result before continuing. */\n await?: boolean;\n /**\n * Handler function for headless tools (no UI).\n * If `await: true`, the return value is sent back to the agent.\n * If `await: false`, runs as fire-and-forget.\n * Inputs are automatically typed when `parameters` is a Zod schema.\n */\n handler?: (inputs: InferInput<TParams>) => any | Promise<any>;\n /**\n * Render function for widget tools (with UI).\n * Receives `{ inputs, submit, status }`.\n * - `submit(result)` resumes the agent when `await: true`.\n * - `status` is `\"pending\"` until submitted, then `\"submitted\"`.\n * Inputs are automatically typed when `parameters` is a Zod schema.\n */\n render?: (props: ClientToolRenderProps<InferInput<TParams>>) => any;\n}\n\n// ─── Context import (late-bound to avoid circular deps) ──────────────────────\n\n// We import the context lazily from agent-context\nimport { AgentToolContext } from \"./agent-context\";\n\n// ─── useClientTool hook ──────────────────────────────────────────────────────\n\n/**\n * Register a client tool for a specific agent.\n *\n * @example\n * ```tsx\n * // Headless tool\n * useClientTool(\"agent-123\", {\n * name: \"get_location\",\n * description: \"Gets user location\",\n * parameters: z.object({}),\n * handler: async () => {\n * const pos = await getPosition();\n * return { lat: pos.coords.latitude, lng: pos.coords.longitude };\n * },\n * });\n *\n * // Widget tool with submission\n * useClientTool(\"agent-123\", {\n * name: \"feedback_form\",\n * description: \"Collects feedback\",\n * parameters: z.object({ question: z.string() }),\n * await: true,\n * render: ({ inputs, submit, status }) => (\n * <form onSubmit={() => submit({ answer: \"...\" })}>\n * <p>{inputs.question}</p>\n * <button disabled={status !== \"pending\"}>Submit</button>\n * </form>\n * ),\n * });\n * ```\n */\nexport function useClientTool<TParams>(agentId: string, config: ClientToolConfig<TParams>): void {\n const context = useContext(AgentToolContext);\n\n if (!context) {\n throw new Error(\"useClientTool must be used within <AgentContextProvider>\");\n }\n\n useEffect(() => {\n context.registerTool(agentId, config);\n return () => {\n context.unregisterTool(agentId, config.name);\n };\n // Note: consumers should memoize `config` to avoid unnecessary re-registrations.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agentId, config.name, config.handler, config.render, config.parameters]);\n}\n\n// ─── ToolRenderer component ──────────────────────────────────────────────────\n\ninterface ToolRendererProps {\n /** The agent ID this tool belongs to. */\n agentId: string;\n /** The widget message part to render. */\n part: {\n toolName: string;\n callId: string;\n inputs: any;\n paused?: boolean;\n status?: \"pending\" | \"submitted\";\n result?: any;\n };\n}\n\n/**\n * Renders a registered widget tool.\n * Looks up the tool by name from the registry and renders it with\n * the appropriate props (inputs, submit, status).\n *\n * @example\n * ```tsx\n * {message.parts?.map((part) => {\n * if (part.type === \"widget\") {\n * return <ToolRenderer key={part.callId} agentId=\"agent-123\" part={part} />;\n * }\n * return <Markdown key={part.firstSequence}>{part.text}</Markdown>;\n * })}\n * ```\n */\nexport function ToolRenderer({ agentId, part }: ToolRendererProps) {\n const context = useContext(AgentToolContext);\n const [localStatus, setLocalStatus] = useState<\"pending\" | \"submitted\">(part.status || \"pending\");\n\n // Sync localStatus when part.status changes externally\n // (e.g., messages reloaded from session storage after resume)\n useEffect(() => {\n setLocalStatus(part.status || \"pending\");\n }, [part.status]);\n\n if (!context) {\n throw new Error(\"ToolRenderer must be used within <AgentContextProvider>\");\n }\n\n const tool = context.getTool(agentId, part.toolName);\n\n const handleSubmit = useCallback(\n (result: any) => {\n if (localStatus === \"submitted\") return; // Prevent double-submission\n setLocalStatus(\"submitted\");\n context.resumeTool(agentId, part.callId, result);\n },\n [agentId, part.callId, localStatus, context],\n );\n\n if (!tool?.render) {\n return null; // No registered render function for this tool\n }\n\n return tool.render({\n inputs: part.inputs,\n submit: part.paused ? handleSubmit : () => {},\n status: localStatus,\n result: part.result,\n });\n}\n"],"mappings":"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","names":["useContext","useCallback","useRef","useState","useEffect","useMemo","useCallback","useRef","useContext","useMemo","useCallback","useCallback","useContext","useRef","useMemo","useCallback","options","tryParseJSON","toJSONSchema","resolveParameters","useState","useEffect","useCallback","useRef","useState","useCallback","useMemo","useContext","useEffect","useContext","useEffect","useState","useCallback","useContext","useEffect","useState","useCallback"]}
|
|
1
|
+
{"version":3,"sources":["../../src/react/agent-context.tsx","../../src/react/use-agent.ts","../../src/react/constants.ts","../../src/react/session-utils.ts","../../src/react/debug-handlers.ts","../../src/react/client-tools.ts","../../src/react/utils/schema.ts","../../src/react/utils/message.ts","../../src/react/stream-callbacks.ts","../../src/core/stream.ts","../../src/core/session.ts","../../src/core/agent.ts","../../src/react/utils/use-synced-local-storage.ts","../../src/react/use-client-tool.ts"],"sourcesContent":["import {\n createContext,\n useContext,\n useCallback,\n useRef,\n useState,\n useEffect,\n useMemo,\n ReactNode,\n} from \"react\";\nimport useAgent, { type UseAgentOptions } from \"./use-agent\";\nimport { BuildShipAgent } from \"../core/agent\";\nimport type { Message, Session, DebugDataType } from \"./types\";\nimport type { ClientToolConfig } from \"./use-client-tool\";\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 handleSend: (\n input: string,\n options?: {\n context?: Record<string, unknown>;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n /** @deprecated Use `useClientTool` hook instead. */\n clientTools?: Array<{\n name: string;\n description: string;\n parameters: unknown;\n await?: boolean;\n }>;\n },\n ) => Promise<void>;\n resumeTool: (callId: string, result: any) => Promise<void>;\n switchSession: (sessionId?: string) => void;\n deleteSession: (sessionId: string) => void;\n addOptimisticMessage: (input: string, context?: Record<string, any>) => void;\n abort: () => void;\n}\n\n// ─── Tool Registry Context ──────────────────────────────────────────────────\n\nexport interface AgentToolContextValue {\n registerTool: (agentId: string, config: ClientToolConfig) => void;\n unregisterTool: (agentId: string, toolName: string) => void;\n getTool: (agentId: string, toolName: string) => ClientToolConfig | undefined;\n getToolsForAgent: (agentId: string) => ClientToolConfig[];\n resumeTool: (agentId: string, callId: string, result: any) => void;\n}\n\nexport const AgentToolContext = createContext<AgentToolContextValue | null>(null);\n\n// ─── Agent Context ──────────────────────────────────────────────────────────\n\ninterface AgentContextValue {\n initializeAgent: (\n agentId: string,\n agentUrl: string,\n accessKey?: string,\n options?: UseAgentOptions,\n ) => 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<\n Map<string, { agentUrl: string; accessKey?: string; options?: UseAgentOptions }>\n >(new Map());\n const runnersRef = useRef<Map<string, AgentRunner>>(new Map());\n const listenersRef = useRef<Map<string, Set<() => void>>>(new Map());\n\n // Tool registry: agentId -> Map<toolName, ClientToolConfig>\n const toolRegistryRef = useRef<Map<string, Map<string, ClientToolConfig>>>(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(\n (agentId: string, agentUrl: string, accessKey?: string, options?: UseAgentOptions) => {\n const existing = activeAgentsRef.current.get(agentId);\n\n if (!existing) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey, options });\n forceUpdate({});\n } else if (existing.agentUrl !== agentUrl || existing.accessKey !== accessKey) {\n activeAgentsRef.current.set(agentId, { agentUrl, accessKey, options });\n forceUpdate({});\n } else if (options) {\n // Always update options ref (e.g. textDeltaModifier) without triggering re-render\n existing.options = options;\n }\n },\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 // ─── Tool registry methods ─────────────────────────────────────────\n\n const registerTool = useCallback((agentId: string, config: ClientToolConfig) => {\n if (!toolRegistryRef.current.has(agentId)) {\n toolRegistryRef.current.set(agentId, new Map());\n }\n toolRegistryRef.current.get(agentId)!.set(config.name, config);\n }, []);\n\n const unregisterTool = useCallback((agentId: string, toolName: string) => {\n toolRegistryRef.current.get(agentId)?.delete(toolName);\n }, []);\n\n const getTool = useCallback((agentId: string, toolName: string) => {\n return toolRegistryRef.current.get(agentId)?.get(toolName);\n }, []);\n\n const getToolsForAgent = useCallback((agentId: string) => {\n const toolMap = toolRegistryRef.current.get(agentId);\n return toolMap ? Array.from(toolMap.values()) : [];\n }, []);\n\n const resumeToolFromContext = useCallback((agentId: string, callId: string, result: any) => {\n const runner = runnersRef.current.get(agentId);\n if (runner) {\n runner.resumeTool(callId, result);\n } else {\n console.warn(`Cannot resume tool: no runner found for agent \"${agentId}\"`);\n }\n }, []);\n\n // ─── Context values ────────────────────────────────────────────────\n\n const agentContextValue = 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 const toolContextValue = useMemo(\n () => ({\n registerTool,\n unregisterTool,\n getTool,\n getToolsForAgent,\n resumeTool: resumeToolFromContext,\n }),\n [registerTool, unregisterTool, getTool, getToolsForAgent, resumeToolFromContext],\n );\n\n return (\n <AgentContext.Provider value={agentContextValue}>\n <AgentToolContext.Provider value={toolContextValue}>\n {children}\n {Array.from(activeAgentsRef.current.entries()).map(\n ([agentId, { agentUrl, accessKey, options }]) => (\n <AgentRunnerInstance\n key={agentId}\n agentId={agentId}\n agentUrl={agentUrl}\n accessKey={accessKey}\n options={options}\n />\n ),\n )}\n </AgentToolContext.Provider>\n </AgentContext.Provider>\n );\n}\n\nfunction AgentRunnerInstance({\n agentId,\n agentUrl,\n accessKey,\n options,\n}: {\n agentId: string;\n agentUrl: string;\n accessKey?: string;\n options?: UseAgentOptions;\n}) {\n const agent = useMemo(\n () => new BuildShipAgent({ agentId, baseUrl: agentUrl, accessKey }),\n [agentId, agentUrl, accessKey],\n );\n // Use a ref for options to avoid re-renders when function references change\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const agentRunner = useAgent(agent, optionsRef.current);\n const context = useContext(AgentContext);\n\n useEffect(() => {\n if (context) {\n context.registerRunner(agentId, agentRunner);\n }\n }, [agentId, agentRunner, context]);\n\n if (!context) return null;\n\n return null;\n}\n\nexport function useAgentContext(\n agentId: string,\n agentUrl: string,\n accessKey?: string,\n options?: UseAgentOptions,\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 // Use a ref for options so function identity changes don't trigger re-renders\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n useEffect(() => {\n initializeAgent(agentId, agentUrl, accessKey, optionsRef.current);\n }, [agentId, agentUrl, accessKey, 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 handleSend: async () => {},\n resumeTool: 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, useContext, useMemo } from \"react\";\nimport type { BuildShipAgent } from \"../core/agent\";\nimport type { AgentSession } from \"../core/session\";\nimport { DEFAULT_SESSION_NAME, TEMPORARY_SESSION_ID } from \"./constants\";\nimport { useSessionUtils } from \"./session-utils\";\nimport { createDebugHandlers } from \"./debug-handlers\";\nimport { useAgentGlobalState, AgentToolContext } from \"./agent-context\";\nimport type { Message } from \"./types\";\nimport { useClientToolHelpers } from \"./client-tools\";\nimport { buildStreamCallbacks } from \"./stream-callbacks\";\nimport type { RunOptions } from \"./stream-callbacks\";\n\nexport interface UseAgentOptions {\n textDeltaModifier?: (\n delta: string,\n fullText: string,\n meta: { executionId: string; sequence: number; agentId: string },\n ) => string;\n}\n\nexport default function useAgent(agent: BuildShipAgent, options?: UseAgentOptions) {\n const agentId = agent._agentId;\n\n const { allSessions, setAllSessions, debugData, setDebugData } = useAgentGlobalState();\n const toolContext = useContext(AgentToolContext);\n\n const [inProgress, setInProgress] = useState(false);\n const [messages, setMessages] = useState<Array<Message>>([]);\n const messagesRef = useRef<Array<Message>>([]);\n\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 useEffect(() => {\n const initialSessionId = sessionUtils.getInitialSessionId();\n setCurrentSessionId(initialSessionId);\n }, [agentId]);\n\n const debugHandlers = useMemo(() => createDebugHandlers(setDebugData), [setDebugData]);\n\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n // Reload messages from session storage only on session/agent switch\n useEffect(() => {\n if (inProgress) return;\n const session = sessionUtils.agentSessions[currentSessionId];\n if (session) {\n setMessages(session.messages);\n } else {\n setMessages([]);\n }\n }, [currentSessionId, agentId, sessionUtils.agentSessions, inProgress]);\n\n useEffect(() => {\n const syncRef = sessionUtils.syncSessionRef;\n const msgRef = messagesRef;\n return () => {\n if (msgRef.current.length > 0 && syncRef.current) {\n syncRef.current();\n }\n };\n }, [sessionUtils.syncSessionRef]);\n\n // Make a stable ref to avoid dependency cycles and redefinitions\n const optionsRef = useRef(options);\n useEffect(() => {\n optionsRef.current = options;\n }, [options]);\n\n const lastRunOptionsRef = useRef<{\n context?: object;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n }>({});\n\n const { getClientToolsMap } = useClientToolHelpers(agentId, toolContext);\n\n const activeSessionRef = useRef<AgentSession | null>(null);\n\n const runAgent = useCallback(\n async (input: string | undefined, runOptions?: RunOptions) => {\n const isNewSession = !currentSessionId || currentSessionId === TEMPORARY_SESSION_ID;\n\n setInProgress(true);\n\n const debugKey =\n runOptions?.optimisticExecutionId ||\n messagesRef.current.findLast((m) => m.role === \"user\")?.executionId;\n\n const deps = {\n agentId,\n currentSessionId,\n messagesRef,\n setMessages,\n setInProgress,\n syncSessionRef: sessionUtils.syncSessionRef,\n debugHandlers,\n toolContext,\n textDeltaModifier: optionsRef.current?.textDeltaModifier,\n };\n\n const callbacks = buildStreamCallbacks(deps, debugKey);\n\n const executeOptions = {\n context: runOptions?.context,\n headers: runOptions?.additionalHeaders,\n body: runOptions?.additionalBody,\n };\n\n // Ensure React-registered tools are synced into the core agent's map\n const toolsMap = getClientToolsMap();\n for (const tool of toolsMap.values()) {\n agent.registerClientTool(tool);\n }\n\n // Merge legacy client tool definitions safely\n if (runOptions?.clientTools && runOptions.clientTools.length > 0) {\n executeOptions.body = {\n ...(executeOptions.body || {}),\n clientTools: [\n ...((executeOptions.body?.clientTools as any[]) || []),\n ...runOptions.clientTools,\n ],\n };\n }\n\n try {\n if (runOptions?.resumeToolCallId) {\n if (isNewSession) throw new Error(\"Cannot resume a tool call on a temporary session.\");\n const session = agent.session(currentSessionId);\n activeSessionRef.current = session;\n await session.resumeWithCallId(\n runOptions.resumeToolCallId,\n runOptions.resumeToolResult,\n callbacks,\n executeOptions,\n );\n } else {\n if (isNewSession) {\n const extendedOptions = {\n ...executeOptions,\n onSessionId: (newSessionId: string, sessionName?: string) => {\n sessionUtils.createSessionFromResponse(\n newSessionId,\n sessionName || DEFAULT_SESSION_NAME,\n messagesRef.current,\n );\n setCurrentSessionId(newSessionId);\n },\n };\n const session = await agent.execute(input || \"\", callbacks, extendedOptions);\n activeSessionRef.current = session;\n } else {\n const session = agent.session(currentSessionId);\n activeSessionRef.current = session;\n await session.execute(input || \"\", callbacks, executeOptions);\n }\n }\n } catch (error) {\n console.log(\"Agent execution failed\", error);\n setInProgress(false);\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(messagesRef.current);\n }\n throw error;\n } finally {\n activeSessionRef.current = null;\n }\n },\n [currentSessionId, sessionUtils, debugHandlers, agentId, toolContext, agent, getClientToolsMap],\n );\n\n const handleSend = useCallback(\n async (\n input: string,\n options?: {\n context?: object;\n skipUserMessage?: boolean;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n },\n ) => {\n const userMessage: Message = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n ...(options?.context ? { context: options.context } : {}),\n };\n\n if (!options?.skipUserMessage) {\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n } else if (options?.skipUserMessage && options?.context) {\n // Sync the authoritative context onto the existing optimistic user message.\n // addOptimisticMessage may have stored a different/partial context earlier.\n setMessages((prev) => {\n const lastUserIdx = prev.findLastIndex((m) => m.role === \"user\");\n if (lastUserIdx === -1) return prev;\n const updatedMessages = [...prev];\n updatedMessages[lastUserIdx] = {\n ...updatedMessages[lastUserIdx],\n context: options.context as Record<string, any>,\n };\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n }\n\n const effectiveExecutionId = options?.skipUserMessage\n ? (messagesRef.current.findLast((m) => m.role === \"user\")?.executionId ??\n userMessage.executionId)\n : userMessage.executionId;\n\n // Track options so they can be re-applied during string continuations (like tool resumes)\n lastRunOptionsRef.current = {\n context: options?.context,\n additionalHeaders: options?.additionalHeaders,\n additionalBody: options?.additionalBody,\n };\n\n try {\n await runAgent(input, {\n ...options,\n optimisticExecutionId: effectiveExecutionId,\n });\n } catch (error) {\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 resumeTool = useCallback(\n async (callId: string, result: any) => {\n setMessages((prev) => {\n const updatedMessages = prev.map((msg) => {\n if (msg.parts) {\n const updatedParts = msg.parts.map((part) => {\n if (part.type === \"widget\" && part.callId === callId) {\n return { ...part, status: \"submitted\" as const, result };\n }\n return part;\n });\n return { ...msg, parts: updatedParts };\n }\n return msg;\n });\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n\n const lastUserMessage = messagesRef.current.findLast((m) => m.role === \"user\");\n const debugKey = lastUserMessage?.executionId;\n if (debugKey) {\n debugHandlers.handleStreamEvent({\n type: \"tool_call_end\",\n data: { callId, toolName: \"\", toolType: \"client\" as const, result },\n meta: { executionId: debugKey, sequence: 0 },\n } as any);\n }\n\n await runAgent(undefined, {\n resumeToolCallId: callId,\n resumeToolResult: result,\n ...lastRunOptionsRef.current,\n // Restore context from the persisted user message (survives page refresh)\n context: lastUserMessage?.context ?? lastRunOptionsRef.current.context,\n });\n },\n [runAgent, sessionUtils.syncSessionRef, debugHandlers],\n );\n\n const addOptimisticMessage = useCallback(\n (input: string, context?: Record<string, any>) => {\n const userMessage: Message = {\n role: \"user\" as const,\n content: input,\n executionId: Date.now().toString(),\n ...(context ? { context } : {}),\n };\n\n setMessages((prev) => {\n const updatedMessages = [...prev, userMessage];\n if (sessionUtils.syncSessionRef.current) {\n sessionUtils.syncSessionRef.current(updatedMessages);\n }\n return updatedMessages;\n });\n },\n [sessionUtils.syncSessionRef],\n );\n\n const abort = useCallback(() => {\n if (activeSessionRef.current) {\n activeSessionRef.current.abort();\n }\n setInProgress(false);\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 resumeTool,\n addOptimisticMessage,\n abort,\n sessionId: currentSessionId,\n switchSession: sessionUtils.switchSession,\n deleteSession: sessionUtils.deleteSession,\n sessions: sessionUtils.sessionsList,\n debugData,\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 // If we're deleting the current session, switch to the most recent remaining one\n if (sessionId === currentSessionId) {\n const remainingSessions = Object.values(updatedAgentSessions);\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 return {\n ...prev,\n [agentId]: updatedAgentSessions,\n };\n });\n },\n [agentId, currentSessionId, 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 { StreamEvent } from \"../core/types\";\nimport type {\n DebugDataType,\n ToolExecutionItem,\n ReasoningItem,\n HandoffItem,\n RunErrorItem,\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 handleStreamEvent = (event: StreamEvent) => {\n const executionId = event.meta.executionId;\n\n switch (event.type) {\n case \"tool_call_start\": {\n const { callId, toolName, toolType, inputs, serverName } = event.data;\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"tool_call\",\n toolName,\n callId,\n toolType,\n status: \"progress\",\n inputs,\n serverName,\n } as ToolExecutionItem,\n ],\n }));\n break;\n }\n\n case \"tool_call_end\": {\n const { callId, result, error } = event.data;\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.callId === callId) {\n currentData[i] = {\n ...toolItem,\n status: error ? \"error\" : \"complete\",\n output: result,\n error,\n };\n break;\n }\n }\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n break;\n }\n\n case \"reasoning_delta\": {\n const { delta, index } = event.data;\n setDebugData((prev) => {\n const currentData = [...(prev[executionId] || [])];\n\n let existingItemIndex = -1;\n for (let i = currentData.length - 1; i >= 0; i--) {\n const item = currentData[i];\n if (item.itemType === \"reasoning\" && (item as ReasoningItem).index === index) {\n existingItemIndex = i;\n break;\n }\n }\n\n if (existingItemIndex === -1) {\n currentData.push({ itemType: \"reasoning\", reasoning: delta, index });\n } else {\n currentData[existingItemIndex] = {\n itemType: \"reasoning\",\n reasoning: (currentData[existingItemIndex] as ReasoningItem).reasoning + delta,\n index,\n };\n }\n\n return {\n ...prev,\n [executionId]: currentData,\n };\n });\n break;\n }\n\n case \"agent_handoff\": {\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"handoff\",\n agentName: event.data.agentName,\n } as HandoffItem,\n ],\n }));\n break;\n }\n\n case \"run_error\": {\n setDebugData((prev) => ({\n ...prev,\n [executionId]: [\n ...(prev[executionId] || []),\n {\n itemType: \"run_error\",\n message: event.data.message,\n code: event.data.code,\n } as RunErrorItem,\n ],\n }));\n break;\n }\n }\n };\n\n return {\n handleStreamEvent,\n };\n};\n","import { useCallback, useContext } from \"react\";\nimport { toJSONSchema, type ZodSchema } from \"zod\";\n\nimport type { ExecuteRequestBody, ClientTool } from \"../core/types\";\nimport type { AgentToolContextValue } from \"./agent-context\";\nimport { cleanSchema } from \"./utils/schema\";\n\n/**\n * Resolve parameters — accepts Zod schema or plain JSON Schema object.\n */\nexport function resolveParameters(params: any): Record<string, any> {\n let schema: Record<string, any>;\n\n // Detect Zod schema: ZodType instances have a `_def` property\n if (params && typeof params === \"object\" && \"_def\" in params) {\n schema = toJSONSchema(params as ZodSchema) as Record<string, any>;\n delete schema.$schema;\n } else {\n schema = cleanSchema(params) as Record<string, any>;\n }\n\n // Gemini requires additionalProperties: false and required to include every key\n if (schema.type === \"object\") {\n schema.additionalProperties = false;\n if (schema.properties) {\n schema.required = Object.keys(schema.properties);\n }\n }\n\n return schema;\n}\n\n/**\n * Build the ClientTool map from ALL registered tools (handlers + widgets).\n * These are registered into the core agent's _clientTools so that\n * session._getClientToolDefs() can send their definitions to the server.\n * The core stream.ts handles tools without handlers correctly\n * (pauses for user interaction, or silently skips fire-and-forget).\n * Widget rendering is handled separately via onEvent → handleClientToolCall\n * in stream-callbacks.ts.\n */\nexport function useClientToolHelpers(agentId: string, toolContext: AgentToolContextValue | null) {\n const getClientToolsMap = useCallback((): Map<string, ClientTool> => {\n if (!toolContext) return new Map();\n const tools = toolContext.getToolsForAgent(agentId);\n const map = new Map<string, ClientTool>();\n\n for (const tool of tools) {\n map.set(tool.name, {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n await: tool.await,\n handler: tool.handler,\n });\n }\n\n return map;\n }, [agentId, toolContext]);\n\n /**\n * Build client tool definitions for the request body.\n * Includes ALL registered tools (handlers + widgets).\n */\n const getClientToolDefs = useCallback((): ExecuteRequestBody[\"clientTools\"] => {\n if (!toolContext) return [];\n const tools = toolContext.getToolsForAgent(agentId);\n\n return tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: resolveParameters(tool.parameters),\n await: tool.await,\n }));\n }, [agentId, toolContext]);\n\n return { getClientToolsMap, getClientToolDefs };\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 * appending it and merging with the previous part if both are contiguous text deltas.\n * Parts are kept in arrival order (no sorting) since events stream chronologically.\n */\nexport function updateAgentMessageParts(parts: MessagePart[], newPart: MessagePart): MessagePart[] {\n const last = parts[parts.length - 1];\n\n // Merge contiguous text deltas\n const canMerge =\n last?.type === \"text\" &&\n newPart.type === \"text\" &&\n newPart.firstSequence === last.lastSequence + 1;\n\n if (canMerge) {\n return [\n ...parts.slice(0, -1),\n {\n ...last,\n text: last.text + newPart.text,\n lastSequence: newPart.lastSequence,\n },\n ];\n }\n\n return [...parts, newPart];\n}\n","import type {\n StreamCallbacks,\n StreamEvent,\n TextDeltaEvent,\n ToolCallStartEvent,\n} from \"../core/types\";\n\nimport type { AgentToolContextValue } from \"./agent-context\";\nimport type { createDebugHandlers } from \"./debug-handlers\";\nimport type { Message, MessagePart } from \"./types\";\nimport { tryParseJSON } from \"./utils/schema\";\nimport { updateAgentMessageParts } from \"./utils/message\";\n\n// ── Types ──────────────────────────────────────────────────────────────\n\nexport type RunOptions = {\n context?: object;\n additionalHeaders?: Record<string, string>;\n additionalBody?: Record<string, unknown>;\n optimisticExecutionId?: string;\n /** @deprecated Use `useClientTool` hook instead. */\n clientTools?: Array<{\n name: string;\n description: string;\n parameters: unknown;\n await?: boolean;\n }>;\n // Resume params\n resumeToolCallId?: string;\n resumeToolResult?: any;\n};\n\nexport type StreamDeps = {\n agentId: string;\n currentSessionId: string;\n messagesRef: React.MutableRefObject<Array<Message>>;\n setMessages: React.Dispatch<React.SetStateAction<Array<Message>>>;\n setInProgress: React.Dispatch<React.SetStateAction<boolean>>;\n syncSessionRef: React.MutableRefObject<((messages?: Array<Message>) => void) | undefined>;\n debugHandlers: ReturnType<typeof createDebugHandlers>;\n toolContext: AgentToolContextValue | null;\n textDeltaModifier?: (\n delta: string,\n fullText: string,\n meta: { executionId: string; sequence: number; agentId: string },\n ) => string;\n};\n\n// ── Build callbacks ────────────────────────────────────────────────────\n\n/**\n * Build the StreamCallbacks object from dependencies.\n * Keeps event-handling logic out of the main hook.\n */\nexport function buildStreamCallbacks(\n deps: StreamDeps,\n debugKey: string | undefined,\n): StreamCallbacks {\n const {\n setMessages,\n setInProgress,\n syncSessionRef,\n messagesRef,\n toolContext,\n agentId,\n textDeltaModifier,\n } = deps;\n\n return {\n onComplete: () => {\n console.log(\"Agent closed\");\n setInProgress(false);\n if (syncSessionRef.current) {\n syncSessionRef.current(messagesRef.current);\n }\n },\n onError: (error: Error) => {\n console.log(\"Agent error\", error);\n setInProgress(false);\n if (syncSessionRef.current) {\n syncSessionRef.current(messagesRef.current);\n }\n },\n onEvent: (event: StreamEvent) => {\n if (event.type === \"text_delta\") {\n handleTextDelta(event, setMessages, syncSessionRef, textDeltaModifier, agentId);\n } else if (event.type === \"tool_call_start\" && event.data.toolType === \"client\") {\n // Create a widget part for tools with a render function\n handleClientToolCall(event, setMessages, syncSessionRef, toolContext, agentId);\n // Send to debug so the tool shows in the debug panel\n if (debugKey) {\n const debugMeta = { ...event.meta, executionId: debugKey };\n deps.debugHandlers.handleStreamEvent({\n ...event,\n meta: debugMeta,\n } as StreamEvent);\n\n // Server never sends tool_call_end for client tools.\n // For non-paused (fire-and-forget) tools, immediately mark complete.\n if (!event.data.paused) {\n deps.debugHandlers.handleStreamEvent({\n type: \"tool_call_end\",\n data: {\n callId: event.data.callId,\n toolName: event.data.toolName,\n toolType: event.data.toolType,\n },\n meta: debugMeta,\n } as StreamEvent);\n }\n }\n } else if (debugKey) {\n // All other events (server tools, reasoning, handoffs, etc.)\n deps.debugHandlers.handleStreamEvent({\n ...event,\n meta: { ...event.meta, executionId: debugKey },\n } as StreamEvent);\n }\n },\n };\n}\n\n// ── Event handlers (private) ───────────────────────────────────────────\n\nfunction handleTextDelta(\n event: TextDeltaEvent,\n setMessages: React.Dispatch<React.SetStateAction<Array<Message>>>,\n syncSessionRef: React.MutableRefObject<((messages?: Array<Message>) => void) | undefined>,\n modifier:\n | ((\n delta: string,\n fullText: string,\n meta: { executionId: string; sequence: number; agentId: string },\n ) => string)\n | undefined,\n agentId: string,\n) {\n const sequence = event.meta.sequence;\n const originalText = event.data;\n const eventExecutionId = event.meta.executionId;\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n\n // Calculate the modified text delta using the full text accumulation so far\n let text = originalText;\n if (modifier) {\n const currentFullText = lastMessage?.role === \"agent\" ? lastMessage.content : \"\";\n text = modifier(originalText, currentFullText, {\n executionId: eventExecutionId,\n sequence,\n agentId: event.meta.agentId || agentId,\n });\n }\n\n const newPart: MessagePart = {\n type: \"text\",\n text,\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 + text,\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: text,\n parts: [newPart],\n executionId: eventExecutionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (syncSessionRef.current) {\n syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n}\n\nfunction handleClientToolCall(\n event: ToolCallStartEvent,\n setMessages: React.Dispatch<React.SetStateAction<Array<Message>>>,\n syncSessionRef: React.MutableRefObject<((messages?: Array<Message>) => void) | undefined>,\n toolContext: AgentToolContextValue | null,\n agentId: string,\n) {\n // Only create widget for tools with a registered render function\n const tool = toolContext?.getTool(agentId, event.data.toolName);\n if (!tool?.render) return;\n\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n const newPart: MessagePart = {\n type: \"widget\",\n toolName: event.data.toolName,\n callId: event.data.callId,\n inputs: tryParseJSON(event.data.inputs),\n sequence: event.meta.sequence,\n paused: event.data.paused,\n status: \"pending\",\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: event.meta.executionId,\n };\n updatedMessages = [...prev, updatedMessage];\n }\n\n if (syncSessionRef.current) {\n syncSessionRef.current(updatedMessages);\n }\n\n return updatedMessages;\n });\n}\n","import type { StreamEvent, StreamOptions, SessionId } from \"./types\";\n\n/** Safely parse a value as JSON if it's a string, otherwise return as-is. */\nfunction 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\n/**\n * Fatal error — will NOT be retried.\n */\nclass FatalStreamError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n ) {\n super(message);\n this.name = \"FatalStreamError\";\n }\n}\n\n/**\n * Opens an SSE connection to the BuildShip agent endpoint using native\n * `fetch` + `ReadableStream`, parses events, and dispatches to the\n * appropriate callbacks.\n *\n * Zero runtime dependencies — works in both browser and Node.js.\n *\n * @internal\n */\nexport async function executeStream(options: StreamOptions): Promise<void> {\n const {\n url,\n body,\n headers,\n callbacks,\n clientTools,\n signal,\n onSessionId,\n onPaused,\n onAutoResume,\n onResponse,\n } = options;\n\n let fullText = \"\";\n\n // Track pending auto-resume operations so we don't call onComplete prematurely\n const pendingAutoResumes: Promise<{ callId: string; result: unknown } | null>[] = [];\n\n // ── Make the request ────────────────────────────────────────────────\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n ...headers,\n },\n body: JSON.stringify(body),\n signal,\n });\n\n // ── Extract session ID and name from response headers ──────────────\n const sessionId = response.headers.get(\"X-BuildShip-Agent-Session-ID\");\n if (sessionId && onSessionId) {\n const sessionName = response.headers.get(\"X-BuildShip-Agent-Session-Name\") || undefined;\n onSessionId(sessionId as SessionId, sessionName);\n }\n\n // Expose the raw Response object\n onResponse?.(response);\n\n // ── Handle HTTP errors ─────────────────────────────────────────────\n if (!response.ok) {\n let errorBody = \"\";\n try {\n errorBody = await response.text();\n } catch {\n // ignore\n }\n const error = new FatalStreamError(\n `HTTP ${response.status}: ${errorBody || response.statusText}`,\n response.status,\n );\n callbacks.onError?.(error);\n throw error;\n }\n\n // ── Read the SSE stream ────────────────────────────────────────────\n if (!response.body) {\n callbacks.onComplete?.(fullText);\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // SSE events are separated by double newlines\n const parts = buffer.split(\"\\n\\n\");\n buffer = parts.pop() || \"\";\n\n for (const part of parts) {\n const trimmedPart = part.trim();\n if (!trimmedPart) continue;\n\n // Extract the data field from SSE format\n let jsonStr = \"\";\n for (const line of trimmedPart.split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n jsonStr += line.slice(6);\n } else if (line.startsWith(\"data:\")) {\n jsonStr += line.slice(5);\n }\n }\n\n jsonStr = jsonStr.trim();\n if (!jsonStr) continue;\n\n let raw: any;\n try {\n raw = JSON.parse(jsonStr);\n } catch {\n // Skip malformed events\n continue;\n }\n\n // Normalize backend event type names (llm_text_delta → text_delta, etc.)\n const streamEvent = normalizeEvent(raw) as StreamEvent;\n\n handleEvent(\n streamEvent,\n fullText,\n callbacks,\n clientTools,\n onPaused,\n onAutoResume,\n pendingAutoResumes,\n );\n\n // Accumulate text\n if (streamEvent.type === \"text_delta\") {\n fullText += streamEvent.data;\n }\n }\n }\n\n // Process any remaining data in buffer\n if (buffer.trim()) {\n let jsonStr = \"\";\n for (const line of buffer.trim().split(\"\\n\")) {\n if (line.startsWith(\"data: \")) {\n jsonStr += line.slice(6);\n } else if (line.startsWith(\"data:\")) {\n jsonStr += line.slice(5);\n }\n }\n\n jsonStr = jsonStr.trim();\n if (jsonStr) {\n try {\n const raw = JSON.parse(jsonStr);\n const streamEvent = normalizeEvent(raw) as StreamEvent;\n handleEvent(\n streamEvent,\n fullText,\n callbacks,\n clientTools,\n onPaused,\n onAutoResume,\n pendingAutoResumes,\n );\n if (streamEvent.type === \"text_delta\") {\n fullText += streamEvent.data;\n }\n } catch {\n // Skip malformed trailing data\n }\n }\n }\n } catch (err) {\n // AbortError — re-throw\n if (err instanceof Error && err.name === \"AbortError\") {\n throw err;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n callbacks.onError?.(error);\n throw error;\n }\n\n // Wait for any pending auto-resume handlers before signaling completion\n if (pendingAutoResumes.length > 0) {\n const handlerResults = await Promise.allSettled(pendingAutoResumes);\n for (const settled of handlerResults) {\n if (settled.status === \"fulfilled\" && settled.value) {\n const { callId, result } = settled.value;\n await onAutoResume?.(callId, result);\n }\n }\n }\n\n callbacks.onComplete?.(fullText);\n}\n\n/**\n * Normalize backend event type names.\n * The backend sends `llm_text_delta` / `llm_reasoning_delta` but the SDK\n * exposes them as `text_delta` / `reasoning_delta`.\n * @internal\n */\nfunction normalizeEvent(raw: any): any {\n const typeMap: Record<string, string> = {\n llm_text_delta: \"text_delta\",\n llm_reasoning_delta: \"reasoning_delta\",\n };\n if (raw && typeof raw.type === \"string\" && typeMap[raw.type]) {\n raw.type = typeMap[raw.type];\n }\n return raw;\n}\n\n/**\n * Dispatch a parsed stream event to the appropriate callbacks.\n * @internal\n */\nfunction handleEvent(\n event: StreamEvent,\n _fullText: string,\n callbacks: StreamOptions[\"callbacks\"],\n clientTools: StreamOptions[\"clientTools\"],\n onPaused: StreamOptions[\"onPaused\"],\n onAutoResume: StreamOptions[\"onAutoResume\"],\n pendingAutoResumes: Promise<{ callId: string; result: unknown } | null>[],\n): void {\n // Notify raw event consumers\n callbacks.onEvent?.(event);\n\n switch (event.type) {\n case \"text_delta\": {\n callbacks.onText?.(event.data);\n break;\n }\n\n case \"reasoning_delta\": {\n callbacks.onReasoning?.(event.data.delta, event.data.index);\n break;\n }\n\n case \"agent_handoff\": {\n callbacks.onAgentHandoff?.(event.data.agentName);\n break;\n }\n\n case \"tool_call_start\": {\n const { callId, toolName, toolType, inputs: rawInputs, paused } = event.data;\n // Backend sends toolCall.arguments as a JSON string — parse it\n const inputs = tryParseJSON(rawInputs);\n\n // Notify callback\n callbacks.onToolStart?.(toolName, toolType);\n\n // Handle client tools\n if (toolType === \"client\") {\n const tool = clientTools.get(toolName);\n if (tool) {\n if (paused && tool.handler) {\n // Blocking tool with handler → auto-execute and resume\n const handlerPromise = (async (): Promise<{\n callId: string;\n result: unknown;\n } | null> => {\n try {\n const result = await tool.handler!(inputs);\n\n // Synthesize a tool_call_end event for local observers (like debug panels)\n // since the backend only emits for server-side executed tools\n callbacks.onEvent?.({\n type: \"tool_call_end\",\n data: {\n callId,\n toolName,\n toolType: \"client\",\n result,\n },\n meta: event.meta,\n });\n\n return { callId, result };\n } catch (error) {\n // If handler fails, still call onPaused so user can decide\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n return null;\n }\n })();\n pendingAutoResumes.push(handlerPromise);\n } else if (paused) {\n // Blocking tool without handler → pause for user\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n } else if (tool.handler) {\n // Fire-and-forget tool with handler\n try {\n tool.handler(inputs);\n } catch {\n // Swallow errors on fire-and-forget\n }\n }\n } else if (paused) {\n // No registered tool but paused — notify user\n callbacks.onPaused?.(toolName, inputs);\n onPaused?.({ callId, toolName, args: inputs });\n }\n }\n break;\n }\n\n case \"tool_call_end\": {\n const { toolName, result, error } = event.data;\n callbacks.onToolEnd?.(toolName, result, error);\n break;\n }\n\n case \"run_error\": {\n const { message, code } = event.data;\n const error = new Error(message);\n if (code != null) (error as any).code = code;\n callbacks.onError?.(error);\n break;\n }\n }\n}\n","import type {\n SessionId,\n StreamCallbacks,\n PausedToolInfo,\n ExecuteRequestBody,\n ExecuteOptions,\n} from \"./types\";\nimport type { BuildShipAgent } from \"./agent\";\nimport { executeStream } from \"./stream\";\nimport { toJSONSchema, type ZodSchema } from \"zod\";\n\n/**\n * Represents a conversation session with a BuildShip agent.\n *\n * Sessions maintain history across multiple turns and support\n * pause/resume for blocking client tools.\n */\nexport class AgentSession {\n /** @internal */ private _agent: BuildShipAgent;\n /** @internal */ private _sessionId: SessionId | undefined;\n /** @internal */ private _paused = false;\n /** @internal */ private _pausedToolInfo: PausedToolInfo | null = null;\n /** @internal */ private _abortController: AbortController | null = null;\n\n /** @internal */\n constructor(agent: BuildShipAgent, sessionId?: SessionId) {\n this._agent = agent;\n this._sessionId = sessionId;\n }\n\n // ─── Public API ────────────────────────────────────────────────────\n\n /**\n * Send a message in this session.\n *\n * @param message - The message to send\n * @param callbacks - Event handlers for the stream\n * @param callbacks - Event handlers for the stream\n * @param options - Optional settings like context, headers, or body\n * @returns This session (for chaining)\n */\n async execute(\n message: string,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n this._paused = false;\n this._pausedToolInfo = null;\n\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n input: message,\n stream: true,\n };\n\n // Attach context as top-level properties if provided\n if (options?.context) {\n Object.assign(body, { context: options.context });\n }\n\n // Include client tool definitions\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n await this._run(body, callbacks, options);\n return this;\n }\n\n /**\n * Resume a paused session with a tool result.\n *\n * @param result - The result to send back to the agent\n * @param callbacks - Event handlers for the resumed stream\n * @param options - Optional settings like headers or body\n * @returns This session (for chaining)\n */\n async resume(\n result: any,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n if (!this._paused || !this._pausedToolInfo) {\n throw new Error(\"AgentSession.resume(): session is not paused. Check isPaused() first.\");\n }\n\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: {\n callId: this._pausedToolInfo.callId,\n result,\n },\n };\n\n // Attach context if provided\n if (options?.context) {\n Object.assign(body, { context: options.context });\n }\n\n // Include client tool definitions for resume requests too\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n this._paused = false;\n this._pausedToolInfo = null;\n\n await this._run(body, callbacks, options);\n return this;\n }\n\n /**\n * Resume a session with an explicit tool call ID and result.\n *\n * Unlike `resume()`, this does NOT require the session to be in a paused state,\n * making it suitable for external resume flows (e.g. React widget submissions)\n * where the session object may have been re-created.\n *\n * @param callId - The tool call ID to resume\n * @param result - The result to send back to the agent\n * @param callbacks - Event handlers for the resumed stream\n * @param options - Optional settings like headers or body\n * @returns This session (for chaining)\n */\n async resumeWithCallId(\n callId: string,\n result: any,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n const body: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: { callId, result },\n };\n\n // Attach context if provided\n if (options?.context) {\n Object.assign(body, { context: options.context });\n }\n\n // Include client tool definitions for resume requests too\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n body.clientTools = clientToolDefs;\n }\n\n // Clear any stale pause state\n this._paused = false;\n this._pausedToolInfo = null;\n\n await this._run(body, callbacks, options);\n return this;\n }\n\n /**\n * Check if this session is waiting for a tool result.\n */\n isPaused(): boolean {\n return this._paused;\n }\n\n /**\n * Get information about the paused tool call.\n * Returns `null` if the session is not paused.\n */\n getPausedTool(): PausedToolInfo | null {\n return this._pausedToolInfo;\n }\n\n /**\n * Get the session ID.\n * May be `undefined` if the session hasn't executed yet.\n */\n getSessionId(): SessionId {\n if (!this._sessionId) {\n throw new Error(\n \"AgentSession.getSessionId(): session ID not yet available. Call execute() first.\",\n );\n }\n return this._sessionId;\n }\n\n /**\n * Cancel the current streaming operation.\n */\n abort(): void {\n this._abortController?.abort();\n this._abortController = null;\n }\n\n // ─── Private helpers ───────────────────────────────────────────────\n\n /** @internal */\n private async _run(\n body: ExecuteRequestBody,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<void> {\n // Create a fresh abort controller for this run\n this._abortController = new AbortController();\n\n const baseHeaders = this._agent._buildHeaders(this._sessionId);\n const mergedHeaders = { ...baseHeaders, ...(options?.headers || {}) };\n\n await executeStream({\n url: this._agent._url,\n body,\n headers: mergedHeaders,\n callbacks,\n clientTools: this._agent._clientTools,\n signal: this._abortController.signal,\n\n onSessionId: (id, name) => {\n this._sessionId = id;\n options?.onSessionId?.(id, name);\n },\n\n onPaused: (info) => {\n this._paused = true;\n this._pausedToolInfo = info;\n },\n\n onAutoResume: async (callId, result) => {\n // Auto-resume: send the tool result back immediately\n const resumeBody: ExecuteRequestBody = {\n ...(options?.body || {}),\n stream: true,\n toolCallResult: { callId, result },\n };\n\n // Carry context forward from the original execute options\n if (options?.context) {\n Object.assign(resumeBody, { context: options.context });\n }\n\n const clientToolDefs = this._getClientToolDefs();\n if (clientToolDefs.length > 0) {\n resumeBody.clientTools = clientToolDefs;\n }\n\n await this._run(resumeBody, callbacks, options);\n },\n });\n }\n\n /** @internal */\n private _getClientToolDefs() {\n const defs: ExecuteRequestBody[\"clientTools\"] = [];\n for (const tool of this._agent._clientTools.values()) {\n defs.push({\n name: tool.name,\n description: tool.description,\n parameters: resolveParameters(tool.parameters),\n await: tool.await,\n });\n }\n return defs;\n }\n}\n\n/**\n * Convert tool parameters to a JSON Schema object.\n * - If it's a Zod schema, uses Zod's built-in `toJSONSchema` to convert.\n * - Always ensures `additionalProperties: false` is set (required by the backend).\n * - Always ensures `required` includes every key in `properties` (Gemini requirement).\n * @internal\n */\nfunction resolveParameters(params: any): Record<string, any> {\n let schema: Record<string, any>;\n\n // Detect Zod schema: ZodType instances have a `_def` property\n if (params && typeof params === \"object\" && \"_def\" in params) {\n schema = toJSONSchema(params as ZodSchema) as Record<string, any>;\n // Remove $schema key if present\n delete schema.$schema;\n } else {\n schema = { ...params };\n }\n\n if (schema.type === \"object\") {\n // Backend requires additionalProperties: false\n schema.additionalProperties = false;\n\n // Gemini requires `required` to include every key in `properties`\n if (schema.properties) {\n schema.required = Object.keys(schema.properties);\n }\n }\n\n return schema;\n}\n","import type { AgentConfig, ClientTool, ExecuteOptions, SessionId, StreamCallbacks } from \"./types\";\nimport { AgentSession } from \"./session\";\n\nconst DEFAULT_BASE_URL = \"https://api.buildship.run\";\n\n/**\n * Main entry point for interacting with a BuildShip agent.\n *\n * @example\n * ```ts\n * import { BuildShipAgent } from \"buildship-agent-sdk/core\";\n *\n * const agent = new BuildShipAgent({\n * agentId: \"your-agent-id\",\n * accessKey: \"your-access-key\",\n * });\n *\n * const session = await agent.execute(\"Hello!\", {\n * onText: (text) => console.log(text),\n * onComplete: (fullText) => console.log(\"Done!\", fullText),\n * });\n * ```\n */\nexport class BuildShipAgent {\n /** @internal */ readonly _agentId: string;\n /** @internal */ readonly _accessKey?: string;\n /** @internal */ readonly _baseUrl: string;\n /** @internal */ readonly _clientTools = new Map<string, ClientTool>();\n\n constructor(config: AgentConfig) {\n if (!config.agentId) {\n throw new Error(\"BuildShipAgent: agentId is required\");\n }\n this._agentId = config.agentId;\n this._accessKey = config.accessKey;\n this._baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/$/, \"\");\n }\n\n /**\n * The URL for the agent's execute endpoint.\n * @internal\n */\n get _url(): string {\n return `${this._baseUrl}/executeAgent/${this._agentId}`;\n }\n\n /**\n * Build the authorization / common headers.\n * @internal\n */\n _buildHeaders(sessionId?: SessionId): Record<string, string> {\n const headers: Record<string, string> = {};\n if (this._accessKey) {\n headers[\"Authorization\"] = `Bearer ${this._accessKey}`;\n }\n if (sessionId) {\n headers[\"X-BuildShip-Agent-Session-ID\"] = sessionId;\n }\n return headers;\n }\n\n // ─── Public API ────────────────────────────────────────────────────\n\n /**\n * Start a new conversation.\n *\n * Creates a fresh session and sends the first message.\n *\n * @param message - The message to send\n * @param callbacks - Event handlers for the stream\n * @param options - Optional execution settings (context, headers, body, onSessionId)\n * @returns The new session\n */\n async execute(\n message: string,\n callbacks: StreamCallbacks,\n options?: ExecuteOptions,\n ): Promise<AgentSession> {\n const session = new AgentSession(this);\n await session.execute(message, callbacks, options);\n return session;\n }\n\n /**\n * Get an existing session by ID to continue a conversation.\n *\n * @param sessionId - The session ID from a previous conversation\n * @returns The session object\n */\n session(sessionId: SessionId | string): AgentSession {\n if (!sessionId) {\n throw new Error(\"BuildShipAgent.session(): sessionId is required\");\n }\n return new AgentSession(this, sessionId as SessionId);\n }\n\n /**\n * Register a client-side tool that the agent can call.\n */\n registerClientTool(tool: ClientTool): void {\n if (!tool.name) {\n throw new Error(\"registerClientTool: tool.name is required\");\n }\n this._clientTools.set(tool.name, tool);\n }\n\n /**\n * Remove a registered client tool.\n */\n unregisterClientTool(name: string): void {\n this._clientTools.delete(name);\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","import { useContext, useEffect, useState, useCallback, createElement } from \"react\";\nimport type { ZodSchema } from \"zod\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/**\n * Infer the output type from a Zod schema's structural shape (`_zod.output`).\n * Falls back to `any` for raw JSON Schema objects or untyped parameters.\n * @internal\n */\ntype InferInput<T> = T extends { _zod: { output: infer O } } ? O : any;\n\nexport interface ClientToolRenderProps<T = any> {\n /** Parsed inputs from the agent. */\n inputs: T;\n /** Submit a result back to the agent (only available when `await: true`). */\n submit: (result: any) => void;\n /** Current status of this widget instance. */\n status: \"pending\" | \"submitted\";\n /** The persisted result from a previous submission (available after submit or on reload). */\n result?: any;\n}\n\nexport interface ClientToolConfig<TParams = any> {\n /** Tool name — must match the name the agent knows. */\n name: string;\n /** Description of what the tool does. */\n description: string;\n /**\n * Tool parameters — accepts a **Zod schema** or a raw JSON Schema object.\n * When a Zod schema is provided, `handler` and `render` inputs are\n * automatically typed — no explicit generic needed.\n *\n * @example\n * parameters: z.object({ question: z.string() })\n */\n parameters: TParams;\n /** If true, agent pauses and waits for the tool result before continuing. */\n await?: boolean;\n /**\n * Handler function for headless tools (no UI).\n * If `await: true`, the return value is sent back to the agent.\n * If `await: false`, runs as fire-and-forget.\n * Inputs are automatically typed when `parameters` is a Zod schema.\n */\n handler?: (inputs: InferInput<TParams>) => any | Promise<any>;\n /**\n * Render function for widget tools (with UI).\n * Receives `{ inputs, submit, status }`.\n * - `submit(result)` resumes the agent when `await: true`.\n * - `status` is `\"pending\"` until submitted, then `\"submitted\"`.\n * Inputs are automatically typed when `parameters` is a Zod schema.\n */\n render?: (props: ClientToolRenderProps<InferInput<TParams>>) => any;\n}\n\n// ─── Context import (late-bound to avoid circular deps) ──────────────────────\n\n// We import the context lazily from agent-context\nimport { AgentToolContext } from \"./agent-context\";\n\n// ─── useClientTool hook ──────────────────────────────────────────────────────\n\n/**\n * Register a client tool for a specific agent.\n *\n * @example\n * ```tsx\n * // Headless tool\n * useClientTool(\"agent-123\", {\n * name: \"get_location\",\n * description: \"Gets user location\",\n * parameters: z.object({}),\n * handler: async () => {\n * const pos = await getPosition();\n * return { lat: pos.coords.latitude, lng: pos.coords.longitude };\n * },\n * });\n *\n * // Widget tool with submission\n * useClientTool(\"agent-123\", {\n * name: \"feedback_form\",\n * description: \"Collects feedback\",\n * parameters: z.object({ question: z.string() }),\n * await: true,\n * render: ({ inputs, submit, status }) => (\n * <form onSubmit={() => submit({ answer: \"...\" })}>\n * <p>{inputs.question}</p>\n * <button disabled={status !== \"pending\"}>Submit</button>\n * </form>\n * ),\n * });\n * ```\n */\nexport function useClientTool<TParams>(agentId: string, config: ClientToolConfig<TParams>): void {\n const context = useContext(AgentToolContext);\n\n if (!context) {\n throw new Error(\"useClientTool must be used within <AgentContextProvider>\");\n }\n\n useEffect(() => {\n context.registerTool(agentId, config);\n return () => {\n context.unregisterTool(agentId, config.name);\n };\n // Note: consumers should memoize `config` to avoid unnecessary re-registrations.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agentId, config.name, config.handler, config.render, config.parameters]);\n}\n\n// ─── ToolRenderer component ──────────────────────────────────────────────────\n\ninterface ToolRendererProps {\n /** The agent ID this tool belongs to. */\n agentId: string;\n /** The widget message part to render. */\n part: {\n toolName: string;\n callId: string;\n inputs: any;\n paused?: boolean;\n status?: \"pending\" | \"submitted\";\n result?: any;\n };\n}\n\n/**\n * Renders a registered widget tool.\n * Looks up the tool by name from the registry and renders it with\n * the appropriate props (inputs, submit, status).\n *\n * @example\n * ```tsx\n * {message.parts?.map((part) => {\n * if (part.type === \"widget\") {\n * return <ToolRenderer key={part.callId} agentId=\"agent-123\" part={part} />;\n * }\n * return <Markdown key={part.firstSequence}>{part.text}</Markdown>;\n * })}\n * ```\n */\nexport function ToolRenderer({ agentId, part }: ToolRendererProps) {\n const context = useContext(AgentToolContext);\n const [localStatus, setLocalStatus] = useState<\"pending\" | \"submitted\">(part.status || \"pending\");\n\n // Sync localStatus when part.status changes externally\n // (e.g., messages reloaded from session storage after resume)\n useEffect(() => {\n setLocalStatus(part.status || \"pending\");\n }, [part.status]);\n\n if (!context) {\n throw new Error(\"ToolRenderer must be used within <AgentContextProvider>\");\n }\n\n const tool = context.getTool(agentId, part.toolName);\n\n const handleSubmit = useCallback(\n (result: any) => {\n if (localStatus === \"submitted\") return; // Prevent double-submission\n setLocalStatus(\"submitted\");\n context.resumeTool(agentId, part.callId, result);\n },\n [agentId, part.callId, localStatus, context],\n );\n\n if (!tool?.render) {\n return null; // No registered render function for this tool\n }\n\n return tool.render({\n inputs: part.inputs,\n submit: part.paused ? handleSubmit : () => {},\n status: localStatus,\n result: part.result,\n });\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA,cAAAA;AAAA,EACA,eAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC;AAAA,OAEK;;;ACTP,SAAS,eAAAC,cAAa,UAAAC,SAAQ,UAAU,WAAW,cAAAC,aAAY,WAAAC,gBAAe;;;ACAvE,IAAM,qBAAqB;AAC3B,IAAM,uBAAuB;AAE7B,IAAM,uBAAuB;AAC7B,IAAM,uBAAuB;;;ACJpC,SAAS,aAAa,SAAS,cAAc;AAItC,IAAM,kBAAkB,CAC7B,SACA,aACA,gBAOA,kBACA,qBACA,gBACG;AACH,QAAM,gBAAgB,QAAQ,MAAM,YAAY,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,WAAW,CAAC;AAEtF,QAAM,iBAAiB,OAA4C;AAEnE,iBAAe,UAAU,CAAC,oBAAqC;AAC7D,QAAI,CAAC,oBAAoB,qBAAqB,sBAAsB;AAClE;AAAA,IACF;AAEA,mBAAe,CAAC,UAAU;AAAA,MACxB,GAAG;AAAA,MACH,CAAC,OAAO,GAAG;AAAA,QACT,GAAG,KAAK,OAAO;AAAA,QACf,CAAC,gBAAgB,GAAG;AAAA,UAClB,GAAG,KAAK,OAAO,IAAI,gBAAgB;AAAA,UACnC,UAAU,mBAAmB,YAAY;AAAA,UACzC,WAAW,KAAK,IAAI;AAAA,QACtB;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAEA,QAAM,sBAAsB,MAAM;AAChC,UAAM,WAAW,OAAO,OAAO,aAAa;AAC5C,QAAI,SAAS,SAAS,GAAG;AACvB,aAAO,SAAS,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,EAAE;AAAA,IAC/D;AACA,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB;AAAA,IACpB,CAAC,YAAoB,yBAAyB;AAC5C,0BAAoB,SAAS;AAAA,IAC/B;AAAA,IACA,CAAC,mBAAmB;AAAA,EACtB;AAEA,QAAM,gBAAgB;AAAA,IACpB,CAAC,cAAsB;AACrB,UAAI,CAAC,aAAa,cAAc,sBAAsB;AACpD;AAAA,MACF;AAEA,qBAAe,CAAC,SAAS;AACvB,cAAM,uBAAuB,EAAE,GAAG,KAAK,OAAO,EAAE;AAChD,eAAO,qBAAqB,SAAS;AAGrC,YAAI,cAAc,kBAAkB;AAClC,gBAAM,oBAAoB,OAAO,OAAO,oBAAoB;AAC5D,cAAI,kBAAkB,SAAS,GAAG;AAChC,kBAAM,aAAa,kBAAkB,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AAChF,gCAAoB,WAAW,EAAE;AAAA,UACnC,OAAO;AACL,gCAAoB,oBAAoB;AAAA,UAC1C;AAAA,QACF;AAEA,eAAO;AAAA,UACL,GAAG;AAAA,UACH,CAAC,OAAO,GAAG;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,SAAS,kBAAkB,gBAAgB,mBAAmB;AAAA,EACjE;AAEA,QAAM,eAAe;AAAA,IACnB,MAAM,OAAO,OAAO,aAAa,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAAA,IAC3E,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,4BAA4B,CAChC,WACA,aACA,oBACG;AACH,mBAAe,CAAC,UAAU;AAAA,MACxB,GAAG;AAAA,MACH,CAAC,OAAO,GAAG;AAAA,QACT,GAAG,KAAK,OAAO;AAAA,QACf,CAAC,SAAS,GAAG;AAAA,UACX,IAAI;AAAA,UACJ,WAAW,KAAK,IAAI;AAAA,UACpB,WAAW,KAAK,IAAI;AAAA,UACpB,UAAU;AAAA,UACV,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC9GO,IAAM,sBAAsB,CACjC,iBAKG;AACH,QAAM,oBAAoB,CAAC,UAAuB;AAChD,UAAM,cAAc,MAAM,KAAK;AAE/B,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK,mBAAmB;AACtB,cAAM,EAAE,QAAQ,UAAU,UAAU,QAAQ,WAAW,IAAI,MAAM;AACjE,qBAAa,CAAC,UAAU;AAAA,UACtB,GAAG;AAAA,UACH,CAAC,WAAW,GAAG;AAAA,YACb,GAAI,KAAK,WAAW,KAAK,CAAC;AAAA,YAC1B;AAAA,cACE,UAAU;AAAA,cACV;AAAA,cACA;AAAA,cACA;AAAA,cACA,QAAQ;AAAA,cACR;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF,EAAE;AACF;AAAA,MACF;AAAA,MAEA,KAAK,iBAAiB;AACpB,cAAM,EAAE,QAAQ,QAAQ,MAAM,IAAI,MAAM;AACxC,qBAAa,CAAC,SAAS;AACrB,gBAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,mBAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,gBAAI,YAAY,CAAC,EAAE,aAAa,aAAa;AAC3C,oBAAM,WAAW,YAAY,CAAC;AAC9B,kBAAI,SAAS,WAAW,QAAQ;AAC9B,4BAAY,CAAC,IAAI;AAAA,kBACf,GAAG;AAAA,kBACH,QAAQ,QAAQ,UAAU;AAAA,kBAC1B,QAAQ;AAAA,kBACR;AAAA,gBACF;AACA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAEA,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,CAAC,WAAW,GAAG;AAAA,UACjB;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAAA,MAEA,KAAK,mBAAmB;AACtB,cAAM,EAAE,OAAO,MAAM,IAAI,MAAM;AAC/B,qBAAa,CAAC,SAAS;AACrB,gBAAM,cAAc,CAAC,GAAI,KAAK,WAAW,KAAK,CAAC,CAAE;AAEjD,cAAI,oBAAoB;AACxB,mBAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,kBAAM,OAAO,YAAY,CAAC;AAC1B,gBAAI,KAAK,aAAa,eAAgB,KAAuB,UAAU,OAAO;AAC5E,kCAAoB;AACpB;AAAA,YACF;AAAA,UACF;AAEA,cAAI,sBAAsB,IAAI;AAC5B,wBAAY,KAAK,EAAE,UAAU,aAAa,WAAW,OAAO,MAAM,CAAC;AAAA,UACrE,OAAO;AACL,wBAAY,iBAAiB,IAAI;AAAA,cAC/B,UAAU;AAAA,cACV,WAAY,YAAY,iBAAiB,EAAoB,YAAY;AAAA,cACzE;AAAA,YACF;AAAA,UACF;AAEA,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,CAAC,WAAW,GAAG;AAAA,UACjB;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAAA,MAEA,KAAK,iBAAiB;AACpB,qBAAa,CAAC,UAAU;AAAA,UACtB,GAAG;AAAA,UACH,CAAC,WAAW,GAAG;AAAA,YACb,GAAI,KAAK,WAAW,KAAK,CAAC;AAAA,YAC1B;AAAA,cACE,UAAU;AAAA,cACV,WAAW,MAAM,KAAK;AAAA,YACxB;AAAA,UACF;AAAA,QACF,EAAE;AACF;AAAA,MACF;AAAA,MAEA,KAAK,aAAa;AAChB,qBAAa,CAAC,UAAU;AAAA,UACtB,GAAG;AAAA,UACH,CAAC,WAAW,GAAG;AAAA,YACb,GAAI,KAAK,WAAW,KAAK,CAAC;AAAA,YAC1B;AAAA,cACE,UAAU;AAAA,cACV,SAAS,MAAM,KAAK;AAAA,cACpB,MAAM,MAAM,KAAK;AAAA,YACnB;AAAA,UACF;AAAA,QACF,EAAE;AACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,EACF;AACF;;;ACtIA,SAAS,eAAAC,oBAA+B;AACxC,SAAS,oBAAoC;;;ACItC,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;;;AD5CO,SAAS,kBAAkB,QAAkC;AAClE,MAAI;AAGJ,MAAI,UAAU,OAAO,WAAW,YAAY,UAAU,QAAQ;AAC5D,aAAS,aAAa,MAAmB;AACzC,WAAO,OAAO;AAAA,EAChB,OAAO;AACL,aAAS,YAAY,MAAM;AAAA,EAC7B;AAGA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,uBAAuB;AAC9B,QAAI,OAAO,YAAY;AACrB,aAAO,WAAW,OAAO,KAAK,OAAO,UAAU;AAAA,IACjD;AAAA,EACF;AAEA,SAAO;AACT;AAWO,SAAS,qBAAqB,SAAiB,aAA2C;AAC/F,QAAM,oBAAoBC,aAAY,MAA+B;AACnE,QAAI,CAAC,YAAa,QAAO,oBAAI,IAAI;AACjC,UAAM,QAAQ,YAAY,iBAAiB,OAAO;AAClD,UAAM,MAAM,oBAAI,IAAwB;AAExC,eAAW,QAAQ,OAAO;AACxB,UAAI,IAAI,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK;AAAA,QACX,aAAa,KAAK;AAAA,QAClB,YAAY,KAAK;AAAA,QACjB,OAAO,KAAK;AAAA,QACZ,SAAS,KAAK;AAAA,MAChB,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,SAAS,WAAW,CAAC;AAMzB,QAAM,oBAAoBA,aAAY,MAAyC;AAC7E,QAAI,CAAC,YAAa,QAAO,CAAC;AAC1B,UAAM,QAAQ,YAAY,iBAAiB,OAAO;AAElD,WAAO,MAAM,IAAI,CAAC,UAAU;AAAA,MAC1B,MAAM,KAAK;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,YAAY,kBAAkB,KAAK,UAAU;AAAA,MAC7C,OAAO,KAAK;AAAA,IACd,EAAE;AAAA,EACJ,GAAG,CAAC,SAAS,WAAW,CAAC;AAEzB,SAAO,EAAE,mBAAmB,kBAAkB;AAChD;;;AEtEO,SAAS,wBAAwB,OAAsB,SAAqC;AACjG,QAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AAGnC,QAAM,WACJ,MAAM,SAAS,UACf,QAAQ,SAAS,UACjB,QAAQ,kBAAkB,KAAK,eAAe;AAEhD,MAAI,UAAU;AACZ,WAAO;AAAA,MACL,GAAG,MAAM,MAAM,GAAG,EAAE;AAAA,MACpB;AAAA,QACE,GAAG;AAAA,QACH,MAAM,KAAK,OAAO,QAAQ;AAAA,QAC1B,cAAc,QAAQ;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,OAAO,OAAO;AAC3B;;;AC0BO,SAAS,qBACd,MACA,UACiB;AACjB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,SAAO;AAAA,IACL,YAAY,MAAM;AAChB,cAAQ,IAAI,cAAc;AAC1B,oBAAc,KAAK;AACnB,UAAI,eAAe,SAAS;AAC1B,uBAAe,QAAQ,YAAY,OAAO;AAAA,MAC5C;AAAA,IACF;AAAA,IACA,SAAS,CAAC,UAAiB;AACzB,cAAQ,IAAI,eAAe,KAAK;AAChC,oBAAc,KAAK;AACnB,UAAI,eAAe,SAAS;AAC1B,uBAAe,QAAQ,YAAY,OAAO;AAAA,MAC5C;AAAA,IACF;AAAA,IACA,SAAS,CAAC,UAAuB;AAC/B,UAAI,MAAM,SAAS,cAAc;AAC/B,wBAAgB,OAAO,aAAa,gBAAgB,mBAAmB,OAAO;AAAA,MAChF,WAAW,MAAM,SAAS,qBAAqB,MAAM,KAAK,aAAa,UAAU;AAE/E,6BAAqB,OAAO,aAAa,gBAAgB,aAAa,OAAO;AAE7E,YAAI,UAAU;AACZ,gBAAM,YAAY,EAAE,GAAG,MAAM,MAAM,aAAa,SAAS;AACzD,eAAK,cAAc,kBAAkB;AAAA,YACnC,GAAG;AAAA,YACH,MAAM;AAAA,UACR,CAAgB;AAIhB,cAAI,CAAC,MAAM,KAAK,QAAQ;AACtB,iBAAK,cAAc,kBAAkB;AAAA,cACnC,MAAM;AAAA,cACN,MAAM;AAAA,gBACJ,QAAQ,MAAM,KAAK;AAAA,gBACnB,UAAU,MAAM,KAAK;AAAA,gBACrB,UAAU,MAAM,KAAK;AAAA,cACvB;AAAA,cACA,MAAM;AAAA,YACR,CAAgB;AAAA,UAClB;AAAA,QACF;AAAA,MACF,WAAW,UAAU;AAEnB,aAAK,cAAc,kBAAkB;AAAA,UACnC,GAAG;AAAA,UACH,MAAM,EAAE,GAAG,MAAM,MAAM,aAAa,SAAS;AAAA,QAC/C,CAAgB;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,gBACP,OACA,aACA,gBACA,UAOA,SACA;AACA,QAAM,WAAW,MAAM,KAAK;AAC5B,QAAM,eAAe,MAAM;AAC3B,QAAM,mBAAmB,MAAM,KAAK;AAEpC,cAAY,CAAC,SAAS;AACpB,UAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AAGxC,QAAI,OAAO;AACX,QAAI,UAAU;AACZ,YAAM,kBAAkB,aAAa,SAAS,UAAU,YAAY,UAAU;AAC9E,aAAO,SAAS,cAAc,iBAAiB;AAAA,QAC7C,aAAa;AAAA,QACb;AAAA,QACA,SAAS,MAAM,KAAK,WAAW;AAAA,MACjC,CAAC;AAAA,IACH;AAEA,UAAM,UAAuB;AAAA,MAC3B,MAAM;AAAA,MACN;AAAA,MACA,eAAe;AAAA,MACf,cAAc;AAAA,IAChB;AAEA,QAAI;AAEJ,QAAI,aAAa,SAAS,SAAS;AACjC,YAAM,iBAA0B;AAAA,QAC9B,GAAG;AAAA,QACH,SAAS,YAAY,UAAU;AAAA,QAC/B,OAAO,wBAAwB,YAAY,SAAS,CAAC,GAAG,OAAO;AAAA,MACjE;AACA,wBAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,IACzD,OAAO;AACL,YAAM,iBAA0B;AAAA,QAC9B,MAAM;AAAA,QACN,SAAS;AAAA,QACT,OAAO,CAAC,OAAO;AAAA,QACf,aAAa;AAAA,MACf;AACA,wBAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,IAC5C;AAEA,QAAI,eAAe,SAAS;AAC1B,qBAAe,QAAQ,eAAe;AAAA,IACxC;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,qBACP,OACA,aACA,gBACA,aACA,SACA;AAEA,QAAM,OAAO,aAAa,QAAQ,SAAS,MAAM,KAAK,QAAQ;AAC9D,MAAI,CAAC,MAAM,OAAQ;AAEnB,cAAY,CAAC,SAAS;AACpB,UAAM,cAAc,KAAK,KAAK,SAAS,CAAC;AACxC,UAAM,UAAuB;AAAA,MAC3B,MAAM;AAAA,MACN,UAAU,MAAM,KAAK;AAAA,MACrB,QAAQ,MAAM,KAAK;AAAA,MACnB,QAAQ,aAAa,MAAM,KAAK,MAAM;AAAA,MACtC,UAAU,MAAM,KAAK;AAAA,MACrB,QAAQ,MAAM,KAAK;AAAA,MACnB,QAAQ;AAAA,IACV;AAEA,QAAI;AAEJ,QAAI,aAAa,SAAS,SAAS;AACjC,YAAM,iBAA0B;AAAA,QAC9B,GAAG;AAAA,QACH,OAAO,wBAAwB,YAAY,SAAS,CAAC,GAAG,OAAO;AAAA,MACjE;AACA,wBAAkB,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,cAAc;AAAA,IACzD,OAAO;AACL,YAAM,iBAA0B;AAAA,QAC9B,MAAM;AAAA,QACN,SAAS;AAAA,QACT,OAAO,CAAC,OAAO;AAAA,QACf,aAAa,MAAM,KAAK;AAAA,MAC1B;AACA,wBAAkB,CAAC,GAAG,MAAM,cAAc;AAAA,IAC5C;AAEA,QAAI,eAAe,SAAS;AAC1B,qBAAe,QAAQ,eAAe;AAAA,IACxC;AAEA,WAAO;AAAA,EACT,CAAC;AACH;;;APxNe,SAAR,SAA0B,OAAuB,SAA2B;AACjF,QAAM,UAAU,MAAM;AAEtB,QAAM,EAAE,aAAa,gBAAgB,WAAW,aAAa,IAAI,oBAAoB;AACrF,QAAM,cAAcC,YAAW,gBAAgB;AAE/C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAyB,CAAC,CAAC;AAC3D,QAAM,cAAcC,QAAuB,CAAC,CAAC;AAE7C,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAiB,oBAAoB;AAErF,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,YAAU,MAAM;AACd,UAAM,mBAAmB,aAAa,oBAAoB;AAC1D,wBAAoB,gBAAgB;AAAA,EACtC,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,gBAAgBC,SAAQ,MAAM,oBAAoB,YAAY,GAAG,CAAC,YAAY,CAAC;AAErF,YAAU,MAAM;AACd,gBAAY,UAAU;AAAA,EACxB,GAAG,CAAC,QAAQ,CAAC;AAGb,YAAU,MAAM;AACd,QAAI,WAAY;AAChB,UAAM,UAAU,aAAa,cAAc,gBAAgB;AAC3D,QAAI,SAAS;AACX,kBAAY,QAAQ,QAAQ;AAAA,IAC9B,OAAO;AACL,kBAAY,CAAC,CAAC;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,kBAAkB,SAAS,aAAa,eAAe,UAAU,CAAC;AAEtE,YAAU,MAAM;AACd,UAAM,UAAU,aAAa;AAC7B,UAAM,SAAS;AACf,WAAO,MAAM;AACX,UAAI,OAAO,QAAQ,SAAS,KAAK,QAAQ,SAAS;AAChD,gBAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,aAAa,cAAc,CAAC;AAGhC,QAAM,aAAaD,QAAO,OAAO;AACjC,YAAU,MAAM;AACd,eAAW,UAAU;AAAA,EACvB,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,oBAAoBA,QAIvB,CAAC,CAAC;AAEL,QAAM,EAAE,kBAAkB,IAAI,qBAAqB,SAAS,WAAW;AAEvE,QAAM,mBAAmBA,QAA4B,IAAI;AAEzD,QAAM,WAAWE;AAAA,IACf,OAAO,OAA2B,eAA4B;AAC5D,YAAM,eAAe,CAAC,oBAAoB,qBAAqB;AAE/D,oBAAc,IAAI;AAElB,YAAM,WACJ,YAAY,yBACZ,YAAY,QAAQ,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM,GAAG;AAE1D,YAAM,OAAO;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,aAAa;AAAA,QAC7B;AAAA,QACA;AAAA,QACA,mBAAmB,WAAW,SAAS;AAAA,MACzC;AAEA,YAAM,YAAY,qBAAqB,MAAM,QAAQ;AAErD,YAAM,iBAAiB;AAAA,QACrB,SAAS,YAAY;AAAA,QACrB,SAAS,YAAY;AAAA,QACrB,MAAM,YAAY;AAAA,MACpB;AAGA,YAAM,WAAW,kBAAkB;AACnC,iBAAW,QAAQ,SAAS,OAAO,GAAG;AACpC,cAAM,mBAAmB,IAAI;AAAA,MAC/B;AAGA,UAAI,YAAY,eAAe,WAAW,YAAY,SAAS,GAAG;AAChE,uBAAe,OAAO;AAAA,UACpB,GAAI,eAAe,QAAQ,CAAC;AAAA,UAC5B,aAAa;AAAA,YACX,GAAK,eAAe,MAAM,eAAyB,CAAC;AAAA,YACpD,GAAG,WAAW;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAEA,UAAI;AACF,YAAI,YAAY,kBAAkB;AAChC,cAAI,aAAc,OAAM,IAAI,MAAM,mDAAmD;AACrF,gBAAM,UAAU,MAAM,QAAQ,gBAAgB;AAC9C,2BAAiB,UAAU;AAC3B,gBAAM,QAAQ;AAAA,YACZ,WAAW;AAAA,YACX,WAAW;AAAA,YACX;AAAA,YACA;AAAA,UACF;AAAA,QACF,OAAO;AACL,cAAI,cAAc;AAChB,kBAAM,kBAAkB;AAAA,cACtB,GAAG;AAAA,cACH,aAAa,CAAC,cAAsB,gBAAyB;AAC3D,6BAAa;AAAA,kBACX;AAAA,kBACA,eAAe;AAAA,kBACf,YAAY;AAAA,gBACd;AACA,oCAAoB,YAAY;AAAA,cAClC;AAAA,YACF;AACA,kBAAM,UAAU,MAAM,MAAM,QAAQ,SAAS,IAAI,WAAW,eAAe;AAC3E,6BAAiB,UAAU;AAAA,UAC7B,OAAO;AACL,kBAAM,UAAU,MAAM,QAAQ,gBAAgB;AAC9C,6BAAiB,UAAU;AAC3B,kBAAM,QAAQ,QAAQ,SAAS,IAAI,WAAW,cAAc;AAAA,UAC9D;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,IAAI,0BAA0B,KAAK;AAC3C,sBAAc,KAAK;AACnB,YAAI,aAAa,eAAe,SAAS;AACvC,uBAAa,eAAe,QAAQ,YAAY,OAAO;AAAA,QACzD;AACA,cAAM;AAAA,MACR,UAAE;AACA,yBAAiB,UAAU;AAAA,MAC7B;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,cAAc,eAAe,SAAS,aAAa,OAAO,iBAAiB;AAAA,EAChG;AAEA,QAAM,aAAaA;AAAA,IACjB,OACE,OACAC,aAMG;AACH,YAAM,cAAuB;AAAA,QAC3B,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aAAa,KAAK,IAAI,EAAE,SAAS;AAAA,QACjC,GAAIA,UAAS,UAAU,EAAE,SAASA,SAAQ,QAAQ,IAAI,CAAC;AAAA,MACzD;AAEA,UAAI,CAACA,UAAS,iBAAiB;AAC7B,oBAAY,CAAC,SAAS;AACpB,gBAAM,kBAAkB,CAAC,GAAG,MAAM,WAAW;AAC7C,cAAI,aAAa,eAAe,SAAS;AACvC,yBAAa,eAAe,QAAQ,eAAe;AAAA,UACrD;AACA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH,WAAWA,UAAS,mBAAmBA,UAAS,SAAS;AAGvD,oBAAY,CAAC,SAAS;AACpB,gBAAM,cAAc,KAAK,cAAc,CAAC,MAAM,EAAE,SAAS,MAAM;AAC/D,cAAI,gBAAgB,GAAI,QAAO;AAC/B,gBAAM,kBAAkB,CAAC,GAAG,IAAI;AAChC,0BAAgB,WAAW,IAAI;AAAA,YAC7B,GAAG,gBAAgB,WAAW;AAAA,YAC9B,SAASA,SAAQ;AAAA,UACnB;AACA,cAAI,aAAa,eAAe,SAAS;AACvC,yBAAa,eAAe,QAAQ,eAAe;AAAA,UACrD;AACA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAEA,YAAM,uBAAuBA,UAAS,kBACjC,YAAY,QAAQ,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM,GAAG,eACzD,YAAY,cACZ,YAAY;AAGhB,wBAAkB,UAAU;AAAA,QAC1B,SAASA,UAAS;AAAA,QAClB,mBAAmBA,UAAS;AAAA,QAC5B,gBAAgBA,UAAS;AAAA,MAC3B;AAEA,UAAI;AACF,cAAM,SAAS,OAAO;AAAA,UACpB,GAAGA;AAAA,UACH,uBAAuB;AAAA,QACzB,CAAC;AAAA,MACH,SAAS,OAAO;AACd,YAAI,CAACA,UAAS,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,aAAaD;AAAA,IACjB,OAAO,QAAgB,WAAgB;AACrC,kBAAY,CAAC,SAAS;AACpB,cAAM,kBAAkB,KAAK,IAAI,CAAC,QAAQ;AACxC,cAAI,IAAI,OAAO;AACb,kBAAM,eAAe,IAAI,MAAM,IAAI,CAAC,SAAS;AAC3C,kBAAI,KAAK,SAAS,YAAY,KAAK,WAAW,QAAQ;AACpD,uBAAO,EAAE,GAAG,MAAM,QAAQ,aAAsB,OAAO;AAAA,cACzD;AACA,qBAAO;AAAA,YACT,CAAC;AACD,mBAAO,EAAE,GAAG,KAAK,OAAO,aAAa;AAAA,UACvC;AACA,iBAAO;AAAA,QACT,CAAC;AACD,YAAI,aAAa,eAAe,SAAS;AACvC,uBAAa,eAAe,QAAQ,eAAe;AAAA,QACrD;AACA,eAAO;AAAA,MACT,CAAC;AAED,YAAM,kBAAkB,YAAY,QAAQ,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM;AAC7E,YAAM,WAAW,iBAAiB;AAClC,UAAI,UAAU;AACZ,sBAAc,kBAAkB;AAAA,UAC9B,MAAM;AAAA,UACN,MAAM,EAAE,QAAQ,UAAU,IAAI,UAAU,UAAmB,OAAO;AAAA,UAClE,MAAM,EAAE,aAAa,UAAU,UAAU,EAAE;AAAA,QAC7C,CAAQ;AAAA,MACV;AAEA,YAAM,SAAS,QAAW;AAAA,QACxB,kBAAkB;AAAA,QAClB,kBAAkB;AAAA,QAClB,GAAG,kBAAkB;AAAA;AAAA,QAErB,SAAS,iBAAiB,WAAW,kBAAkB,QAAQ;AAAA,MACjE,CAAC;AAAA,IACH;AAAA,IACA,CAAC,UAAU,aAAa,gBAAgB,aAAa;AAAA,EACvD;AAEA,QAAM,uBAAuBA;AAAA,IAC3B,CAAC,OAAe,YAAkC;AAChD,YAAM,cAAuB;AAAA,QAC3B,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aAAa,KAAK,IAAI,EAAE,SAAS;AAAA,QACjC,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC/B;AAEA,kBAAY,CAAC,SAAS;AACpB,cAAM,kBAAkB,CAAC,GAAG,MAAM,WAAW;AAC7C,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,QAAQA,aAAY,MAAM;AAC9B,QAAI,iBAAiB,SAAS;AAC5B,uBAAiB,QAAQ,MAAM;AAAA,IACjC;AACA,kBAAc,KAAK;AACnB,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,EACF;AACF;;;AQtVA,SAASE,cAAa,OAAqB;AACzC,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI;AACF,aAAO,KAAK,MAAM,KAAK;AAAA,IACzB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAKA,IAAM,mBAAN,cAA+B,MAAM;AAAA,EACnC,YACE,SACO,YACP;AACA,UAAM,OAAO;AAFN;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAWA,eAAsB,cAAc,SAAuC;AACzE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,MAAI,WAAW;AAGf,QAAM,qBAA4E,CAAC;AAGnF,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,GAAG;AAAA,IACL;AAAA,IACA,MAAM,KAAK,UAAU,IAAI;AAAA,IACzB;AAAA,EACF,CAAC;AAGD,QAAM,YAAY,SAAS,QAAQ,IAAI,8BAA8B;AACrE,MAAI,aAAa,aAAa;AAC5B,UAAM,cAAc,SAAS,QAAQ,IAAI,gCAAgC,KAAK;AAC9E,gBAAY,WAAwB,WAAW;AAAA,EACjD;AAGA,eAAa,QAAQ;AAGrB,MAAI,CAAC,SAAS,IAAI;AAChB,QAAI,YAAY;AAChB,QAAI;AACF,kBAAY,MAAM,SAAS,KAAK;AAAA,IAClC,QAAQ;AAAA,IAER;AACA,UAAM,QAAQ,IAAI;AAAA,MAChB,QAAQ,SAAS,MAAM,KAAK,aAAa,SAAS,UAAU;AAAA,MAC5D,SAAS;AAAA,IACX;AACA,cAAU,UAAU,KAAK;AACzB,UAAM;AAAA,EACR;AAGA,MAAI,CAAC,SAAS,MAAM;AAClB,cAAU,aAAa,QAAQ;AAC/B;AAAA,EACF;AAEA,QAAM,SAAS,SAAS,KAAK,UAAU;AACvC,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AAEb,MAAI;AACF,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AAEV,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAGhD,YAAM,QAAQ,OAAO,MAAM,MAAM;AACjC,eAAS,MAAM,IAAI,KAAK;AAExB,iBAAW,QAAQ,OAAO;AACxB,cAAM,cAAc,KAAK,KAAK;AAC9B,YAAI,CAAC,YAAa;AAGlB,YAAI,UAAU;AACd,mBAAW,QAAQ,YAAY,MAAM,IAAI,GAAG;AAC1C,cAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,uBAAW,KAAK,MAAM,CAAC;AAAA,UACzB,WAAW,KAAK,WAAW,OAAO,GAAG;AACnC,uBAAW,KAAK,MAAM,CAAC;AAAA,UACzB;AAAA,QACF;AAEA,kBAAU,QAAQ,KAAK;AACvB,YAAI,CAAC,QAAS;AAEd,YAAI;AACJ,YAAI;AACF,gBAAM,KAAK,MAAM,OAAO;AAAA,QAC1B,QAAQ;AAEN;AAAA,QACF;AAGA,cAAM,cAAc,eAAe,GAAG;AAEtC;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAGA,YAAI,YAAY,SAAS,cAAc;AACrC,sBAAY,YAAY;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,KAAK,GAAG;AACjB,UAAI,UAAU;AACd,iBAAW,QAAQ,OAAO,KAAK,EAAE,MAAM,IAAI,GAAG;AAC5C,YAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,qBAAW,KAAK,MAAM,CAAC;AAAA,QACzB,WAAW,KAAK,WAAW,OAAO,GAAG;AACnC,qBAAW,KAAK,MAAM,CAAC;AAAA,QACzB;AAAA,MACF;AAEA,gBAAU,QAAQ,KAAK;AACvB,UAAI,SAAS;AACX,YAAI;AACF,gBAAM,MAAM,KAAK,MAAM,OAAO;AAC9B,gBAAM,cAAc,eAAe,GAAG;AACtC;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AACA,cAAI,YAAY,SAAS,cAAc;AACrC,wBAAY,YAAY;AAAA,UAC1B;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AAEZ,QAAI,eAAe,SAAS,IAAI,SAAS,cAAc;AACrD,YAAM;AAAA,IACR;AAEA,UAAM,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAChE,cAAU,UAAU,KAAK;AACzB,UAAM;AAAA,EACR;AAGA,MAAI,mBAAmB,SAAS,GAAG;AACjC,UAAM,iBAAiB,MAAM,QAAQ,WAAW,kBAAkB;AAClE,eAAW,WAAW,gBAAgB;AACpC,UAAI,QAAQ,WAAW,eAAe,QAAQ,OAAO;AACnD,cAAM,EAAE,QAAQ,OAAO,IAAI,QAAQ;AACnC,cAAM,eAAe,QAAQ,MAAM;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAEA,YAAU,aAAa,QAAQ;AACjC;AAQA,SAAS,eAAe,KAAe;AACrC,QAAM,UAAkC;AAAA,IACtC,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACA,MAAI,OAAO,OAAO,IAAI,SAAS,YAAY,QAAQ,IAAI,IAAI,GAAG;AAC5D,QAAI,OAAO,QAAQ,IAAI,IAAI;AAAA,EAC7B;AACA,SAAO;AACT;AAMA,SAAS,YACP,OACA,WACA,WACA,aACA,UACA,cACA,oBACM;AAEN,YAAU,UAAU,KAAK;AAEzB,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK,cAAc;AACjB,gBAAU,SAAS,MAAM,IAAI;AAC7B;AAAA,IACF;AAAA,IAEA,KAAK,mBAAmB;AACtB,gBAAU,cAAc,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK;AAC1D;AAAA,IACF;AAAA,IAEA,KAAK,iBAAiB;AACpB,gBAAU,iBAAiB,MAAM,KAAK,SAAS;AAC/C;AAAA,IACF;AAAA,IAEA,KAAK,mBAAmB;AACtB,YAAM,EAAE,QAAQ,UAAU,UAAU,QAAQ,WAAW,OAAO,IAAI,MAAM;AAExE,YAAM,SAASA,cAAa,SAAS;AAGrC,gBAAU,cAAc,UAAU,QAAQ;AAG1C,UAAI,aAAa,UAAU;AACzB,cAAM,OAAO,YAAY,IAAI,QAAQ;AACrC,YAAI,MAAM;AACR,cAAI,UAAU,KAAK,SAAS;AAE1B,kBAAM,kBAAkB,YAGX;AACX,kBAAI;AACF,sBAAM,SAAS,MAAM,KAAK,QAAS,MAAM;AAIzC,0BAAU,UAAU;AAAA,kBAClB,MAAM;AAAA,kBACN,MAAM;AAAA,oBACJ;AAAA,oBACA;AAAA,oBACA,UAAU;AAAA,oBACV;AAAA,kBACF;AAAA,kBACA,MAAM,MAAM;AAAA,gBACd,CAAC;AAED,uBAAO,EAAE,QAAQ,OAAO;AAAA,cAC1B,SAAS,OAAO;AAEd,0BAAU,WAAW,UAAU,MAAM;AACrC,2BAAW,EAAE,QAAQ,UAAU,MAAM,OAAO,CAAC;AAC7C,uBAAO;AAAA,cACT;AAAA,YACF,GAAG;AACH,+BAAmB,KAAK,cAAc;AAAA,UACxC,WAAW,QAAQ;AAEjB,sBAAU,WAAW,UAAU,MAAM;AACrC,uBAAW,EAAE,QAAQ,UAAU,MAAM,OAAO,CAAC;AAAA,UAC/C,WAAW,KAAK,SAAS;AAEvB,gBAAI;AACF,mBAAK,QAAQ,MAAM;AAAA,YACrB,QAAQ;AAAA,YAER;AAAA,UACF;AAAA,QACF,WAAW,QAAQ;AAEjB,oBAAU,WAAW,UAAU,MAAM;AACrC,qBAAW,EAAE,QAAQ,UAAU,MAAM,OAAO,CAAC;AAAA,QAC/C;AAAA,MACF;AACA;AAAA,IACF;AAAA,IAEA,KAAK,iBAAiB;AACpB,YAAM,EAAE,UAAU,QAAQ,MAAM,IAAI,MAAM;AAC1C,gBAAU,YAAY,UAAU,QAAQ,KAAK;AAC7C;AAAA,IACF;AAAA,IAEA,KAAK,aAAa;AAChB,YAAM,EAAE,SAAS,KAAK,IAAI,MAAM;AAChC,YAAM,QAAQ,IAAI,MAAM,OAAO;AAC/B,UAAI,QAAQ,KAAM,CAAC,MAAc,OAAO;AACxC,gBAAU,UAAU,KAAK;AACzB;AAAA,IACF;AAAA,EACF;AACF;;;AC/UA,SAAS,gBAAAC,qBAAoC;AAQtC,IAAM,eAAN,MAAmB;AAAA;AAAA,EACC;AAAA;AAAA,EACA;AAAA;AAAA,EACA,UAAU;AAAA;AAAA,EACV,kBAAyC;AAAA;AAAA,EACzC,mBAA2C;AAAA;AAAA,EAGpE,YAAY,OAAuB,WAAuB;AACxD,SAAK,SAAS;AACd,SAAK,aAAa;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,QACJ,SACA,WACA,SACuB;AACvB,SAAK,UAAU;AACf,SAAK,kBAAkB;AAEvB,UAAM,OAA2B;AAAA,MAC/B,GAAI,SAAS,QAAQ,CAAC;AAAA,MACtB,OAAO;AAAA,MACP,QAAQ;AAAA,IACV;AAGA,QAAI,SAAS,SAAS;AACpB,aAAO,OAAO,MAAM,EAAE,SAAS,QAAQ,QAAQ,CAAC;AAAA,IAClD;AAGA,UAAM,iBAAiB,KAAK,mBAAmB;AAC/C,QAAI,eAAe,SAAS,GAAG;AAC7B,WAAK,cAAc;AAAA,IACrB;AAEA,UAAM,KAAK,KAAK,MAAM,WAAW,OAAO;AACxC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OACJ,QACA,WACA,SACuB;AACvB,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,iBAAiB;AAC1C,YAAM,IAAI,MAAM,uEAAuE;AAAA,IACzF;AAEA,UAAM,OAA2B;AAAA,MAC/B,GAAI,SAAS,QAAQ,CAAC;AAAA,MACtB,QAAQ;AAAA,MACR,gBAAgB;AAAA,QACd,QAAQ,KAAK,gBAAgB;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAGA,QAAI,SAAS,SAAS;AACpB,aAAO,OAAO,MAAM,EAAE,SAAS,QAAQ,QAAQ,CAAC;AAAA,IAClD;AAGA,UAAM,iBAAiB,KAAK,mBAAmB;AAC/C,QAAI,eAAe,SAAS,GAAG;AAC7B,WAAK,cAAc;AAAA,IACrB;AAEA,SAAK,UAAU;AACf,SAAK,kBAAkB;AAEvB,UAAM,KAAK,KAAK,MAAM,WAAW,OAAO;AACxC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,iBACJ,QACA,QACA,WACA,SACuB;AACvB,UAAM,OAA2B;AAAA,MAC/B,GAAI,SAAS,QAAQ,CAAC;AAAA,MACtB,QAAQ;AAAA,MACR,gBAAgB,EAAE,QAAQ,OAAO;AAAA,IACnC;AAGA,QAAI,SAAS,SAAS;AACpB,aAAO,OAAO,MAAM,EAAE,SAAS,QAAQ,QAAQ,CAAC;AAAA,IAClD;AAGA,UAAM,iBAAiB,KAAK,mBAAmB;AAC/C,QAAI,eAAe,SAAS,GAAG;AAC7B,WAAK,cAAc;AAAA,IACrB;AAGA,SAAK,UAAU;AACf,SAAK,kBAAkB;AAEvB,UAAM,KAAK,KAAK,MAAM,WAAW,OAAO;AACxC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,WAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAuC;AACrC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAA0B;AACxB,QAAI,CAAC,KAAK,YAAY;AACpB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,kBAAkB,MAAM;AAC7B,SAAK,mBAAmB;AAAA,EAC1B;AAAA;AAAA;AAAA,EAKA,MAAc,KACZ,MACA,WACA,SACe;AAEf,SAAK,mBAAmB,IAAI,gBAAgB;AAE5C,UAAM,cAAc,KAAK,OAAO,cAAc,KAAK,UAAU;AAC7D,UAAM,gBAAgB,EAAE,GAAG,aAAa,GAAI,SAAS,WAAW,CAAC,EAAG;AAEpE,UAAM,cAAc;AAAA,MAClB,KAAK,KAAK,OAAO;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT;AAAA,MACA,aAAa,KAAK,OAAO;AAAA,MACzB,QAAQ,KAAK,iBAAiB;AAAA,MAE9B,aAAa,CAAC,IAAI,SAAS;AACzB,aAAK,aAAa;AAClB,iBAAS,cAAc,IAAI,IAAI;AAAA,MACjC;AAAA,MAEA,UAAU,CAAC,SAAS;AAClB,aAAK,UAAU;AACf,aAAK,kBAAkB;AAAA,MACzB;AAAA,MAEA,cAAc,OAAO,QAAQ,WAAW;AAEtC,cAAM,aAAiC;AAAA,UACrC,GAAI,SAAS,QAAQ,CAAC;AAAA,UACtB,QAAQ;AAAA,UACR,gBAAgB,EAAE,QAAQ,OAAO;AAAA,QACnC;AAGA,YAAI,SAAS,SAAS;AACpB,iBAAO,OAAO,YAAY,EAAE,SAAS,QAAQ,QAAQ,CAAC;AAAA,QACxD;AAEA,cAAM,iBAAiB,KAAK,mBAAmB;AAC/C,YAAI,eAAe,SAAS,GAAG;AAC7B,qBAAW,cAAc;AAAA,QAC3B;AAEA,cAAM,KAAK,KAAK,YAAY,WAAW,OAAO;AAAA,MAChD;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGQ,qBAAqB;AAC3B,UAAM,OAA0C,CAAC;AACjD,eAAW,QAAQ,KAAK,OAAO,aAAa,OAAO,GAAG;AACpD,WAAK,KAAK;AAAA,QACR,MAAM,KAAK;AAAA,QACX,aAAa,KAAK;AAAA,QAClB,YAAYC,mBAAkB,KAAK,UAAU;AAAA,QAC7C,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AACF;AASA,SAASA,mBAAkB,QAAkC;AAC3D,MAAI;AAGJ,MAAI,UAAU,OAAO,WAAW,YAAY,UAAU,QAAQ;AAC5D,aAASD,cAAa,MAAmB;AAEzC,WAAO,OAAO;AAAA,EAChB,OAAO;AACL,aAAS,EAAE,GAAG,OAAO;AAAA,EACvB;AAEA,MAAI,OAAO,SAAS,UAAU;AAE5B,WAAO,uBAAuB;AAG9B,QAAI,OAAO,YAAY;AACrB,aAAO,WAAW,OAAO,KAAK,OAAO,UAAU;AAAA,IACjD;AAAA,EACF;AAEA,SAAO;AACT;;;ACnSA,IAAM,mBAAmB;AAoBlB,IAAM,iBAAN,MAAqB;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA,eAAe,oBAAI,IAAwB;AAAA,EAErE,YAAY,QAAqB;AAC/B,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AACA,SAAK,WAAW,OAAO;AACvB,SAAK,aAAa,OAAO;AACzB,SAAK,YAAY,OAAO,WAAW,kBAAkB,QAAQ,OAAO,EAAE;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAAe;AACjB,WAAO,GAAG,KAAK,QAAQ,iBAAiB,KAAK,QAAQ;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,WAA+C;AAC3D,UAAM,UAAkC,CAAC;AACzC,QAAI,KAAK,YAAY;AACnB,cAAQ,eAAe,IAAI,UAAU,KAAK,UAAU;AAAA,IACtD;AACA,QAAI,WAAW;AACb,cAAQ,8BAA8B,IAAI;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,QACJ,SACA,WACA,SACuB;AACvB,UAAM,UAAU,IAAI,aAAa,IAAI;AACrC,UAAM,QAAQ,QAAQ,SAAS,WAAW,OAAO;AACjD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQ,WAA6C;AACnD,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AACA,WAAO,IAAI,aAAa,MAAM,SAAsB;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,MAAwB;AACzC,QAAI,CAAC,KAAK,MAAM;AACd,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AACA,SAAK,aAAa,IAAI,KAAK,MAAM,IAAI;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB,MAAoB;AACvC,SAAK,aAAa,OAAO,IAAI;AAAA,EAC/B;AACF;;;AChHA,SAAS,YAAAE,WAAU,aAAAC,YAAW,eAAAC,oBAAmB;AAGjD,SAAS,UAAa,OAAsB,cAAoB;AAC9D,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI;AACF,WAAO,KAAK,MAAM,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,sBACd,KACA,cAC2C;AAE3C,QAAM,CAAC,aAAa,cAAc,IAAIF,UAAY,MAAM;AACtD,QAAI,OAAO,WAAW,aAAa;AACjC,aAAO;AAAA,IACT;AACA,QAAI;AACF,YAAM,OAAO,OAAO,aAAa,QAAQ,GAAG;AAC5C,aAAO,UAAU,MAAM,YAAY;AAAA,IACrC,SAAS,OAAO;AACd,cAAQ,KAAK,mCAAmC,GAAG,MAAM,KAAK;AAC9D,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAGD,QAAM,WAAWE;AAAA,IACf,CAAC,UAA+B;AAC9B,UAAI;AACF,uBAAe,CAAC,SAAS;AACvB,gBAAM,eAAe,iBAAiB,WAAW,MAAM,IAAI,IAAI;AAE/D,cAAI,OAAO,WAAW,aAAa;AACjC,mBAAO,aAAa,QAAQ,KAAK,KAAK,UAAU,YAAY,CAAC;AAE7D,mBAAO;AAAA,cACL,IAAI,aAAa,WAAW,EAAE,KAAK,UAAU,KAAK,UAAU,YAAY,EAAE,CAAC;AAAA,YAC7E;AAAA,UACF;AACA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH,SAAS,OAAO;AACd,gBAAQ,KAAK,mCAAmC,GAAG,MAAM,KAAK;AAAA,MAChE;AAAA,IACF;AAAA,IACA,CAAC,GAAG;AAAA,EACN;AAGA,EAAAD,WAAU,MAAM;AACd,UAAM,sBAAsB,CAAC,UAAwB;AACnD,UAAI,MAAM,QAAQ,KAAK;AACrB,uBAAe,UAAU,MAAM,UAAU,YAAY,CAAC;AAAA,MACxD;AAAA,IACF;AAEA,WAAO,iBAAiB,WAAW,mBAAmB;AACtD,WAAO,MAAM,OAAO,oBAAoB,WAAW,mBAAmB;AAAA,EACxE,GAAG,CAAC,KAAK,YAAY,CAAC;AAEtB,SAAO,CAAC,aAAa,QAAQ;AAC/B;;;AZgJM,SAIM,KAJN;AA1JC,IAAM,mBAAmB,cAA4C,IAAI;AA8BhF,IAAM,eAAe,cAAwC,IAAI;AAE1D,SAAS,qBAAqB,EAAE,SAAS,GAA4B;AAC1E,QAAM,kBAAkBE,QAEtB,oBAAI,IAAI,CAAC;AACX,QAAM,aAAaA,QAAiC,oBAAI,IAAI,CAAC;AAC7D,QAAM,eAAeA,QAAqC,oBAAI,IAAI,CAAC;AAGnE,QAAM,kBAAkBA,QAAmD,oBAAI,IAAI,CAAC;AAEpF,QAAM,CAAC,EAAE,WAAW,IAAIC,UAAS,CAAC,CAAC;AAGnC,QAAM,CAAC,aAAa,cAAc,IAAI,sBAEpC,oBAAoB,CAAC,CAAC;AAExB,QAAM,CAAC,WAAW,YAAY,IAAI;AAAA,IAChC;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,kBAAkBC;AAAA,IACtB,CAAC,SAAiB,UAAkB,WAAoB,YAA8B;AACpF,YAAM,WAAW,gBAAgB,QAAQ,IAAI,OAAO;AAEpD,UAAI,CAAC,UAAU;AACb,wBAAgB,QAAQ,IAAI,SAAS,EAAE,UAAU,WAAW,QAAQ,CAAC;AACrE,oBAAY,CAAC,CAAC;AAAA,MAChB,WAAW,SAAS,aAAa,YAAY,SAAS,cAAc,WAAW;AAC7E,wBAAgB,QAAQ,IAAI,SAAS,EAAE,UAAU,WAAW,QAAQ,CAAC;AACrE,oBAAY,CAAC,CAAC;AAAA,MAChB,WAAW,SAAS;AAElB,iBAAS,UAAU;AAAA,MACrB;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,iBAAiBA,aAAY,CAAC,SAAiB,WAAwB;AAC3E,eAAW,QAAQ,IAAI,SAAS,MAAM;AAEtC,UAAM,YAAY,aAAa,QAAQ,IAAI,OAAO;AAClD,QAAI,WAAW;AACb,gBAAU,QAAQ,CAAC,aAAa,SAAS,CAAC;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,YAAYA,aAAY,CAAC,YAAoB;AACjD,WAAO,WAAW,QAAQ,IAAI,OAAO,KAAK;AAAA,EAC5C,GAAG,CAAC,CAAC;AAIL,QAAM,eAAeA,aAAY,CAAC,SAAiB,WAA6B;AAC9E,QAAI,CAAC,gBAAgB,QAAQ,IAAI,OAAO,GAAG;AACzC,sBAAgB,QAAQ,IAAI,SAAS,oBAAI,IAAI,CAAC;AAAA,IAChD;AACA,oBAAgB,QAAQ,IAAI,OAAO,EAAG,IAAI,OAAO,MAAM,MAAM;AAAA,EAC/D,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAiBA,aAAY,CAAC,SAAiB,aAAqB;AACxE,oBAAgB,QAAQ,IAAI,OAAO,GAAG,OAAO,QAAQ;AAAA,EACvD,GAAG,CAAC,CAAC;AAEL,QAAM,UAAUA,aAAY,CAAC,SAAiB,aAAqB;AACjE,WAAO,gBAAgB,QAAQ,IAAI,OAAO,GAAG,IAAI,QAAQ;AAAA,EAC3D,GAAG,CAAC,CAAC;AAEL,QAAM,mBAAmBA,aAAY,CAAC,YAAoB;AACxD,UAAM,UAAU,gBAAgB,QAAQ,IAAI,OAAO;AACnD,WAAO,UAAU,MAAM,KAAK,QAAQ,OAAO,CAAC,IAAI,CAAC;AAAA,EACnD,GAAG,CAAC,CAAC;AAEL,QAAM,wBAAwBA,aAAY,CAAC,SAAiB,QAAgB,WAAgB;AAC1F,UAAM,SAAS,WAAW,QAAQ,IAAI,OAAO;AAC7C,QAAI,QAAQ;AACV,aAAO,WAAW,QAAQ,MAAM;AAAA,IAClC,OAAO;AACL,cAAQ,KAAK,kDAAkD,OAAO,GAAG;AAAA,IAC3E;AAAA,EACF,GAAG,CAAC,CAAC;AAIL,QAAM,oBAAoBC;AAAA,IACxB,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,QAAM,mBAAmBA;AAAA,IACvB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,IACd;AAAA,IACA,CAAC,cAAc,gBAAgB,SAAS,kBAAkB,qBAAqB;AAAA,EACjF;AAEA,SACE,oBAAC,aAAa,UAAb,EAAsB,OAAO,mBAC5B,+BAAC,iBAAiB,UAAjB,EAA0B,OAAO,kBAC/B;AAAA;AAAA,IACA,MAAM,KAAK,gBAAgB,QAAQ,QAAQ,CAAC,EAAE;AAAA,MAC7C,CAAC,CAAC,SAAS,EAAE,UAAU,WAAW,QAAQ,CAAC,MACzC;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,QAJK;AAAA,MAKP;AAAA,IAEJ;AAAA,KACF,GACF;AAEJ;AAEA,SAAS,oBAAoB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,QAAQA;AAAA,IACZ,MAAM,IAAI,eAAe,EAAE,SAAS,SAAS,UAAU,UAAU,CAAC;AAAA,IAClE,CAAC,SAAS,UAAU,SAAS;AAAA,EAC/B;AAEA,QAAM,aAAaH,QAAO,OAAO;AACjC,aAAW,UAAU;AACrB,QAAM,cAAc,SAAS,OAAO,WAAW,OAAO;AACtD,QAAM,UAAUI,YAAW,YAAY;AAEvC,EAAAC,WAAU,MAAM;AACd,QAAI,SAAS;AACX,cAAQ,eAAe,SAAS,WAAW;AAAA,IAC7C;AAAA,EACF,GAAG,CAAC,SAAS,aAAa,OAAO,CAAC;AAElC,MAAI,CAAC,QAAS,QAAO;AAErB,SAAO;AACT;AAEO,SAAS,gBACd,SACA,UACA,WACA,SACa;AACb,QAAM,UAAUD,YAAW,YAAY;AAEvC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AAEA,QAAM,EAAE,iBAAiB,WAAW,aAAa,IAAI;AAKrD,QAAM,aAAaJ,QAAO,OAAO;AACjC,aAAW,UAAU;AAErB,EAAAK,WAAU,MAAM;AACd,oBAAgB,SAAS,UAAU,WAAW,WAAW,OAAO;AAAA,EAClE,GAAG,CAAC,SAAS,UAAU,WAAW,eAAe,CAAC;AAGlD,QAAM,CAAC,QAAQ,SAAS,IAAIJ,UAA6B,MAAM,UAAU,OAAO,CAAC;AAEjF,EAAAI,WAAU,MAAM;AAEd,UAAM,gBAAgB,UAAU,OAAO;AACvC,QAAI,kBAAkB,QAAQ;AAC5B,gBAAU,aAAa;AAAA,IACzB;AAGA,UAAM,WAAW,MAAM;AACrB,gBAAU,UAAU,OAAO,CAAC;AAAA,IAC9B;AAEA,QAAI,CAAC,aAAa,QAAQ,IAAI,OAAO,GAAG;AACtC,mBAAa,QAAQ,IAAI,SAAS,oBAAI,IAAI,CAAC;AAAA,IAC7C;AACA,iBAAa,QAAQ,IAAI,OAAO,GAAG,IAAI,QAAQ;AAE/C,WAAO,MAAM;AACX,mBAAa,QAAQ,IAAI,OAAO,GAAG,OAAO,QAAQ;AAAA,IACpD;AAAA,EACF,GAAG,CAAC,SAAS,SAAS,CAAC;AAEvB,QAAM,cAAcF;AAAA,IAClB,OAAO;AAAA,MACL,UAAU,CAAC;AAAA,MACX,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,UAAU,CAAC;AAAA,MACX,WAAW,CAAC;AAAA,MACZ,YAAY,YAAY;AAAA,MAAC;AAAA,MACzB,YAAY,YAAY;AAAA,MAAC;AAAA,MACzB,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,UAAUC,YAAW,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;;;AarVA,SAAS,cAAAE,aAAY,aAAAC,YAAW,YAAAC,WAAU,eAAAC,oBAAkC;AA8FrE,SAAS,cAAuB,SAAiB,QAAyC;AAC/F,QAAM,UAAUC,YAAW,gBAAgB;AAE3C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AAEA,EAAAC,WAAU,MAAM;AACd,YAAQ,aAAa,SAAS,MAAM;AACpC,WAAO,MAAM;AACX,cAAQ,eAAe,SAAS,OAAO,IAAI;AAAA,IAC7C;AAAA,EAGF,GAAG,CAAC,SAAS,OAAO,MAAM,OAAO,SAAS,OAAO,QAAQ,OAAO,UAAU,CAAC;AAC7E;AAiCO,SAAS,aAAa,EAAE,SAAS,KAAK,GAAsB;AACjE,QAAM,UAAUD,YAAW,gBAAgB;AAC3C,QAAM,CAAC,aAAa,cAAc,IAAIE,UAAkC,KAAK,UAAU,SAAS;AAIhG,EAAAD,WAAU,MAAM;AACd,mBAAe,KAAK,UAAU,SAAS;AAAA,EACzC,GAAG,CAAC,KAAK,MAAM,CAAC;AAEhB,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AAEA,QAAM,OAAO,QAAQ,QAAQ,SAAS,KAAK,QAAQ;AAEnD,QAAM,eAAeE;AAAA,IACnB,CAAC,WAAgB;AACf,UAAI,gBAAgB,YAAa;AACjC,qBAAe,WAAW;AAC1B,cAAQ,WAAW,SAAS,KAAK,QAAQ,MAAM;AAAA,IACjD;AAAA,IACA,CAAC,SAAS,KAAK,QAAQ,aAAa,OAAO;AAAA,EAC7C;AAEA,MAAI,CAAC,MAAM,QAAQ;AACjB,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,OAAO;AAAA,IACjB,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK,SAAS,eAAe,MAAM;AAAA,IAAC;AAAA,IAC5C,QAAQ;AAAA,IACR,QAAQ,KAAK;AAAA,EACf,CAAC;AACH;","names":["useContext","useCallback","useRef","useState","useEffect","useMemo","useCallback","useRef","useContext","useMemo","useCallback","useCallback","useContext","useRef","useMemo","useCallback","options","tryParseJSON","toJSONSchema","resolveParameters","useState","useEffect","useCallback","useRef","useState","useCallback","useMemo","useContext","useEffect","useContext","useEffect","useState","useCallback","useContext","useEffect","useState","useCallback"]}
|