@standardagents/react 0.10.1-dev.8f03957 → 0.10.1-dev.cea2b66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -144,6 +144,30 @@ function ThreadProvider({
144
144
  }, [messages, useWorkblocks]);
145
145
  const eventListenersRef = useRef(/* @__PURE__ */ new Map());
146
146
  const connectionManagerRef = useRef(null);
147
+ const buildOptimisticAttachments = useCallback(
148
+ (attachmentPaths) => {
149
+ if (!attachmentPaths || attachmentPaths.length === 0) return null;
150
+ const refs = attachmentPaths.map((path) => {
151
+ const file = pendingFiles.find((f) => f.path === path);
152
+ const ref = {
153
+ id: path,
154
+ type: "file",
155
+ path,
156
+ name: file?.name || path.split("/").pop() || "file",
157
+ mimeType: file?.mimeType || "application/octet-stream",
158
+ size: file?.size || 0
159
+ };
160
+ if (file?.isImage) {
161
+ if (file.width) ref.width = file.width;
162
+ if (file.height) ref.height = file.height;
163
+ if (file.localPreviewUrl) ref.localPreviewUrl = file.localPreviewUrl;
164
+ }
165
+ return ref;
166
+ });
167
+ return JSON.stringify(refs);
168
+ },
169
+ [pendingFiles]
170
+ );
147
171
  const subscribeToEvent = useCallback(
148
172
  (eventType, listener) => {
149
173
  if (!eventListenersRef.current.has(eventType)) {
@@ -225,14 +249,28 @@ function ThreadProvider({
225
249
  );
226
250
  const sendMessage2 = useCallback(
227
251
  async (payload) => {
252
+ const optimisticId = `optimistic-${crypto.randomUUID()}`;
253
+ const optimisticMessage = {
254
+ id: optimisticId,
255
+ role: payload.role,
256
+ content: payload.content,
257
+ attachments: buildOptimisticAttachments(payload.attachments),
258
+ created_at: Date.now() * 1e3,
259
+ // microseconds
260
+ status: "pending"
261
+ };
262
+ setMessages((prev) => [...prev, optimisticMessage]);
228
263
  try {
229
- return await clientRef.current.sendMessage(threadId, payload);
264
+ const result = await clientRef.current.sendMessage(threadId, payload);
265
+ setMessages((prev) => prev.filter((m) => m.id !== optimisticId));
266
+ return result;
230
267
  } catch (err) {
268
+ setMessages((prev) => prev.filter((m) => m.id !== optimisticId));
231
269
  setError(err instanceof Error ? err : new Error(String(err)));
232
270
  throw err;
233
271
  }
234
272
  },
235
- [threadId]
273
+ [threadId, buildOptimisticAttachments]
236
274
  );
237
275
  const stopExecution = useCallback(async () => {
238
276
  try {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/services/sendMessage.ts","../src/services/stopThread.ts","../src/context/AgentBuilderProvider.tsx","../src/context/ThreadProvider.tsx","../src/hooks/useThread.ts","../src/hooks/onThreadEvent.ts","../src/hooks/useSendMessage.ts","../src/hooks/useStopThread.ts"],"names":["globalEndpoint","createContext","AgentBuilderClient","useEffect","useMemo","sendMessage","jsx","useContext","useState","useCallback","hasWarned"],"mappings":"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","file":"index.js","sourcesContent":["import type { SendMessagePayload, Message } from '@standardagents/client'\n\n// Global client instance (set by AgentBuilderProvider)\nlet globalEndpoint: string | null = null\n\n/**\n * Internal function to set the global endpoint.\n * Called by AgentBuilderProvider when it mounts.\n * @internal\n */\nexport function __setGlobalEndpoint(endpoint: string) {\n globalEndpoint = endpoint\n}\n\n/**\n * Send a message to a specific thread.\n *\n * This is a standalone function that sends messages to threads.\n * It requires that an AgentBuilderProvider is mounted somewhere in your app\n * to set the global endpoint configuration.\n *\n * @param id - The thread ID to send the message to\n * @param payload - The message payload containing role, content, and optional silent flag\n * @returns Promise resolving to the created message\n *\n * @throws Error if called before AgentBuilderProvider is mounted\n *\n * @example\n * ```tsx\n * import { sendMessage } from '@standardagents/react'\n *\n * await sendMessage('thread-123', {\n * role: 'user',\n * content: 'Hello, agent!',\n * })\n *\n * // Send a silent message\n * await sendMessage('thread-123', {\n * role: 'user',\n * content: 'Silent message',\n * silent: true,\n * })\n * ```\n */\nexport async function sendMessage(\n id: string,\n payload: SendMessagePayload\n): Promise<Message> {\n if (!globalEndpoint) {\n throw new Error(\n 'sendMessage requires AgentBuilderProvider to be mounted in your app'\n )\n }\n\n // Read auth token from localStorage\n const token =\n typeof localStorage !== 'undefined'\n ? localStorage.getItem('agentbuilder_auth_token')\n : null\n\n // Build headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (token) {\n headers['Authorization'] = `Bearer ${token}`\n }\n\n // Make the request\n const response = await fetch(`${globalEndpoint}/threads/${id}/messages`, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to send message: ${response.statusText}`)\n }\n\n return response.json()\n}\n","// Global endpoint instance (set by AgentBuilderProvider)\nlet globalEndpoint: string | null = null\n\n/**\n * Internal function to set the global endpoint.\n * Called by AgentBuilderProvider when it mounts.\n * @internal\n */\nexport function __setGlobalEndpointForStop(endpoint: string) {\n globalEndpoint = endpoint\n}\n\nexport interface StopThreadOptions {\n /**\n * Override the endpoint URL for this request.\n * If not provided, uses the endpoint from AgentBuilderProvider.\n */\n endpoint?: string\n}\n\n/**\n * Stop execution of a thread.\n *\n * This is a standalone function that stops a running thread execution.\n * It requires that an AgentBuilderProvider is mounted somewhere in your app\n * to set the global endpoint configuration, or you can provide a custom endpoint.\n *\n * @param id - The thread ID to stop\n * @param options - Optional configuration including custom endpoint\n * @returns Promise that resolves when the thread is stopped\n *\n * @throws Error if called before AgentBuilderProvider is mounted and no endpoint is provided\n *\n * @example\n * ```tsx\n * import { stopThread } from '@standardagents/react'\n *\n * // Using global endpoint from AgentBuilderProvider\n * await stopThread('thread-123')\n *\n * // Using custom endpoint\n * await stopThread('thread-123', {\n * endpoint: 'https://custom.example.com/api'\n * })\n * ```\n */\nexport async function stopThread(\n id: string,\n options?: StopThreadOptions\n): Promise<void> {\n const endpoint = options?.endpoint ?? globalEndpoint\n\n if (!endpoint) {\n throw new Error(\n 'stopThread requires AgentBuilderProvider to be mounted or endpoint option to be provided'\n )\n }\n\n // Normalize endpoint by removing trailing slash\n const normalizedEndpoint = endpoint.replace(/\\/$/, '')\n\n // Read auth token from localStorage\n const token =\n typeof localStorage !== 'undefined'\n ? localStorage.getItem('agentbuilder_auth_token')\n : null\n\n // Build headers\n const headers: Record<string, string> = {}\n\n if (token) {\n headers['Authorization'] = `Bearer ${token}`\n }\n\n // Make the request\n const response = await fetch(`${normalizedEndpoint}/threads/${id}/stop`, {\n method: 'POST',\n headers,\n })\n\n if (!response.ok) {\n throw new Error(`Failed to stop thread: ${response.statusText}`)\n }\n\n await response.json()\n}\n","import React, { createContext, useContext, useMemo, useEffect, type ReactNode } from 'react'\nimport { AgentBuilderClient, type AgentBuilderConfig } from '@standardagents/client'\nimport { __setGlobalEndpoint } from '../services/sendMessage'\nimport { __setGlobalEndpointForStop } from '../services/stopThread'\n\ninterface AgentBuilderContextValue {\n client: AgentBuilderClient\n config: AgentBuilderConfig\n}\n\nexport const AgentBuilderContext = createContext<AgentBuilderContextValue | null>(null)\n\nexport interface AgentBuilderProviderProps {\n config: AgentBuilderConfig\n children: ReactNode\n}\n\n/**\n * AgentBuilderProvider provides the AgentBuilder client instance to all child components.\n * This should wrap the part of your app where you want to use AgentBuilder functionality.\n *\n * @example\n * ```tsx\n * <AgentBuilderProvider config={{ endpoint: 'https://api.example.com' }}>\n * <YourApp />\n * </AgentBuilderProvider>\n * ```\n */\nexport function AgentBuilderProvider({ config, children }: AgentBuilderProviderProps) {\n // Create client instance only once using useMemo\n const client = useMemo(() => {\n return new AgentBuilderClient(config.endpoint)\n }, [config.endpoint])\n\n const value = useMemo(\n () => ({\n client,\n config,\n }),\n [client, config]\n )\n\n // Set global endpoint for standalone functions like sendMessage and stopThread\n useEffect(() => {\n __setGlobalEndpoint(config.endpoint)\n __setGlobalEndpointForStop(config.endpoint)\n }, [config.endpoint])\n\n return <AgentBuilderContext.Provider value={value}>{children}</AgentBuilderContext.Provider>\n}\n\n/**\n * Hook to access the AgentBuilder client instance.\n * Must be used within an AgentBuilderProvider.\n *\n * @throws Error if used outside of AgentBuilderProvider\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const client = useAgentBuilderClient()\n * // Use client.getThread(), client.sendMessage(), etc.\n * }\n * ```\n */\nexport function useAgentBuilderClient(): AgentBuilderClient {\n const context = useContext(AgentBuilderContext)\n\n if (!context) {\n throw new Error('useAgentBuilderClient must be used within AgentBuilderProvider')\n }\n\n return context.client\n}\n\n/**\n * Hook to access the AgentBuilder config.\n * Must be used within an AgentBuilderProvider.\n *\n * @throws Error if used outside of AgentBuilderProvider\n */\nexport function useAgentBuilderConfig(): AgentBuilderConfig {\n const context = useContext(AgentBuilderContext)\n\n if (!context) {\n throw new Error('useAgentBuilderConfig must be used within AgentBuilderProvider')\n }\n\n return context.config\n}\n","import React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n type ReactNode,\n} from \"react\"\nimport {\n useAgentBuilderClient,\n useAgentBuilderConfig,\n} from \"./AgentBuilderProvider\"\nimport {\n AgentBuilderClient,\n ThreadConnectionManager,\n FileUploadManager,\n messagesToFiles,\n transformToWorkblocks,\n type Message,\n type ThreadMessage,\n type ThreadFile,\n type SendMessagePayload,\n type ConnectionStatus as ClientConnectionStatus,\n} from \"@standardagents/client\"\nimport type { ThreadProviderOptions } from \"../types\"\n\n// Shared file upload manager instance\nconst uploadManager = new FileUploadManager()\n\n/**\n * Event listener callback type\n */\ntype EventListener<T = unknown> = (data: T) => void\n\n/**\n * WebSocket connection status\n */\nexport type ConnectionStatus = ClientConnectionStatus\n\n// =============================================================================\n// INTERNAL CONTEXTS (not exported - implementation detail)\n// =============================================================================\n\n/**\n * Static context - things that don't change or are memoized callbacks\n */\ninterface StaticContextValue {\n threadId: string\n options: ThreadProviderOptions\n sendMessage: (payload: SendMessagePayload) => Promise<Message>\n stopExecution: () => Promise<void>\n subscribeToEvent: <T = unknown>(\n eventType: string,\n listener: EventListener<T>\n ) => () => void\n addFiles: (files: File[] | FileList) => void\n removeFile: (id: string) => void\n getFileUrl: (file: ThreadFile) => string\n getThumbnailUrl: (file: ThreadFile) => string\n getPreviewUrl: (file: ThreadFile) => string | null\n}\n\n/**\n * Messages context - changes when messages update\n */\ninterface MessagesContextValue {\n messages: Message[]\n workblocks: ThreadMessage[]\n loading: boolean\n}\n\n/**\n * Files context - changes when files update\n */\ninterface FilesContextValue {\n files: ThreadFile[]\n}\n\n/**\n * Connection context - changes when connection status changes\n */\ninterface ConnectionContextValue {\n connectionStatus: ConnectionStatus\n error: Error | null\n}\n\nconst StaticContext = createContext<StaticContextValue | null>(null)\nconst MessagesContext = createContext<MessagesContextValue | null>(null)\nconst FilesContext = createContext<FilesContextValue | null>(null)\nconst ConnectionContext = createContext<ConnectionContextValue | null>(null)\n\n// =============================================================================\n// PUBLIC TYPES AND CONTEXT\n// =============================================================================\n\n/**\n * Thread context value - the public interface returned by useThread()\n */\nexport interface ThreadContextValue {\n /** The thread ID */\n threadId: string\n /** Current messages in the thread */\n messages: Message[]\n /** Messages transformed to workblocks (if useWorkblocks is true) */\n workblocks: ThreadMessage[]\n /** Whether messages are currently loading (alias: isLoading) */\n loading: boolean\n /** Whether messages are currently loading (alias for loading) */\n isLoading: boolean\n /** Any error that occurred */\n error: Error | null\n /** WebSocket connection status (alias: status) */\n connectionStatus: ConnectionStatus\n /** WebSocket connection status (alias for connectionStatus) */\n status: ConnectionStatus\n /** Subscribe to a specific event type (alias: onEvent) */\n subscribeToEvent: <T = unknown>(\n eventType: string,\n listener: EventListener<T>\n ) => () => void\n /** Subscribe to a specific event type (alias for subscribeToEvent) */\n onEvent: <T = unknown>(\n eventType: string,\n listener: EventListener<T>\n ) => () => void\n /** Options passed to the provider */\n options: ThreadProviderOptions\n\n // Actions\n /** Send a message to the thread */\n sendMessage: (payload: SendMessagePayload) => Promise<Message>\n /** Stop the current execution */\n stopExecution: () => Promise<void>\n\n // File management\n /** All files in the thread (pending uploads + committed from messages) */\n files: ThreadFile[]\n /** Add files and start uploading immediately */\n addFiles: (files: File[] | FileList) => void\n /** Remove a pending file (cannot remove committed files) */\n removeFile: (id: string) => void\n /** Get the full URL for a file */\n getFileUrl: (file: ThreadFile) => string\n /** Get the thumbnail URL for an image file */\n getThumbnailUrl: (file: ThreadFile) => string\n /** Get preview URL - localPreviewUrl for pending images, thumbnail for committed */\n getPreviewUrl: (file: ThreadFile) => string | null\n}\n\n/**\n * Legacy context export for useThread() - combines all internal contexts\n * @internal\n */\nexport const ThreadContext = createContext<ThreadContextValue | null>(null)\n\nexport interface ThreadProviderProps {\n /** The thread ID to connect to */\n threadId: string\n /** Provider options */\n options?: ThreadProviderOptions\n /** Whether to preload messages on mount (default: true) */\n preload?: boolean\n /** Whether to enable live updates via WebSocket (default: true) */\n live?: boolean\n /** Transform messages to workblocks (default: false) */\n useWorkblocks?: boolean\n /** Maximum message depth to fetch/stream (default: 0 for top-level only) */\n depth?: number\n /** Whether to include silent messages (default: false) */\n includeSilent?: boolean\n /** Optional endpoint override */\n endpoint?: string\n children: ReactNode\n}\n\n/**\n * ThreadProvider establishes a WebSocket connection to a thread and provides\n * context for child components to access messages and events.\n *\n * Must be nested inside AgentBuilderProvider.\n *\n * @example\n * ```tsx\n * <AgentBuilderProvider config={{ endpoint: 'https://api.example.com' }}>\n * <ThreadProvider threadId=\"thread-123\">\n * <ChatMessages />\n * </ThreadProvider>\n * </AgentBuilderProvider>\n * ```\n */\nexport function ThreadProvider({\n threadId,\n options = {},\n preload = true,\n live = true,\n useWorkblocks = false,\n depth = 0,\n includeSilent = false,\n endpoint: endpointOverride,\n children,\n}: ThreadProviderProps) {\n const contextClient = useAgentBuilderClient()\n const contextConfig = useAgentBuilderConfig()\n\n // Use override endpoint if provided, otherwise use context endpoint\n const effectiveEndpoint = endpointOverride || contextConfig.endpoint\n\n // Create a client instance\n const clientRef = useRef<AgentBuilderClient>(\n endpointOverride ? new AgentBuilderClient(endpointOverride) : contextClient\n )\n\n // Update client if endpoint override changes\n useEffect(() => {\n if (endpointOverride) {\n clientRef.current = new AgentBuilderClient(endpointOverride)\n } else {\n clientRef.current = contextClient\n }\n }, [endpointOverride, contextClient])\n\n // =============================================================================\n // STATE\n // =============================================================================\n\n const [messages, setMessages] = useState<Message[]>([])\n const [loading, setLoading] = useState(preload)\n const [error, setError] = useState<Error | null>(null)\n const [connectionStatus, setConnectionStatus] = useState<ConnectionStatus>(\n live ? \"connecting\" : \"disconnected\"\n )\n const [pendingFiles, setPendingFiles] = useState<ThreadFile[]>([])\n\n // =============================================================================\n // DERIVED STATE\n // =============================================================================\n\n const committedFiles = useMemo(() => {\n return messagesToFiles(messages)\n }, [messages])\n\n const files = useMemo(() => {\n return [...pendingFiles, ...committedFiles]\n }, [pendingFiles, committedFiles])\n\n const workblocks = useMemo(() => {\n if (!useWorkblocks) {\n return messages as ThreadMessage[]\n }\n return transformToWorkblocks(messages)\n }, [messages, useWorkblocks])\n\n // =============================================================================\n // REFS\n // =============================================================================\n\n const eventListenersRef = useRef<Map<string, Set<EventListener>>>(new Map())\n const connectionManagerRef = useRef<ThreadConnectionManager | null>(null)\n\n // =============================================================================\n // CALLBACKS (stable - memoized)\n // =============================================================================\n\n const subscribeToEvent = useCallback(\n <T = unknown,>(\n eventType: string,\n listener: EventListener<T>\n ): (() => void) => {\n if (!eventListenersRef.current.has(eventType)) {\n eventListenersRef.current.set(eventType, new Set())\n }\n eventListenersRef.current.get(eventType)!.add(listener as EventListener)\n\n return () => {\n const listeners = eventListenersRef.current.get(eventType)\n if (listeners) {\n listeners.delete(listener as EventListener)\n if (listeners.size === 0) {\n eventListenersRef.current.delete(eventType)\n }\n }\n }\n },\n []\n )\n\n const dispatchEvent = useCallback((eventType: string, data: unknown) => {\n const listeners = eventListenersRef.current.get(eventType)\n if (listeners) {\n listeners.forEach((listener) => {\n try {\n listener(data)\n } catch (err) {\n console.error(`Error in event listener for \"${eventType}\":`, err)\n }\n })\n }\n }, [])\n\n const addFiles = useCallback(\n (filesToAdd: File[] | FileList) => {\n // Queue files for immediate UI display\n const items = uploadManager.queueFiles(filesToAdd)\n\n // Add pending files to state\n setPendingFiles((prev) => [...prev, ...items.map((i) => i.pending)])\n\n // Start uploads in parallel\n for (const { pending, file } of items) {\n uploadManager\n .executeUpload(\n threadId,\n file,\n pending.id,\n clientRef.current,\n (updates) => {\n setPendingFiles((prev) =>\n prev.map((f) =>\n f.id === pending.id ? { ...f, ...updates } : f\n )\n )\n }\n )\n .catch(() => {\n // Error already handled via onUpdate callback\n })\n }\n },\n [threadId]\n )\n\n const removeFile = useCallback((id: string) => {\n setPendingFiles((prev) => prev.filter((f) => f.id !== id))\n }, [])\n\n const getFileUrl = useCallback(\n (file: ThreadFile): string => {\n if (!file.path) return \"\"\n return clientRef.current.getFileUrl(threadId, file.path)\n },\n [threadId]\n )\n\n const getThumbnailUrl = useCallback(\n (file: ThreadFile): string => {\n if (!file.path) return \"\"\n return clientRef.current.getThumbnailUrl(threadId, file.path)\n },\n [threadId]\n )\n\n const getPreviewUrl = useCallback(\n (file: ThreadFile): string | null => {\n if (!file.isImage) return null\n if (file.localPreviewUrl) return file.localPreviewUrl\n if (file.path) return clientRef.current.getThumbnailUrl(threadId, file.path)\n return null\n },\n [threadId]\n )\n\n const sendMessage = useCallback(\n async (payload: SendMessagePayload): Promise<Message> => {\n try {\n return await clientRef.current.sendMessage(threadId, payload)\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)))\n throw err\n }\n },\n [threadId]\n )\n\n const stopExecution = useCallback(async () => {\n try {\n await clientRef.current.stopExecution(threadId)\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)))\n throw err\n }\n }, [threadId])\n\n // =============================================================================\n // WEBSOCKET CONNECTION (via ThreadConnectionManager)\n // =============================================================================\n\n useEffect(() => {\n if (!live || !threadId) return\n\n console.log(`[ThreadProvider] Connecting WebSocket for thread ${threadId}`)\n\n const manager = new ThreadConnectionManager(\n clientRef.current,\n threadId,\n {\n onStatusChange: (status) => {\n console.log(`[ThreadProvider] Connection status: ${status}`)\n setConnectionStatus(status)\n },\n onMessage: (event) => {\n setMessages((prev) => {\n const exists = prev.some((m) => m.id === event.data.id)\n if (exists) {\n return prev.map((m) => (m.id === event.data.id ? event.data : m))\n } else {\n return [...prev, event.data]\n }\n })\n },\n onChunk: (event) => {\n setMessages((prev) => {\n return prev.map((m) => {\n if (m.id === event.message_id) {\n return {\n ...m,\n content: (m.content || \"\") + event.chunk,\n }\n }\n return m\n })\n })\n },\n onEvent: (event) => {\n dispatchEvent(event.eventType, event.data)\n },\n onError: (event) => {\n console.error(\"[ThreadProvider] WebSocket error:\", event.error)\n setError(new Error(event.error))\n },\n },\n {\n depth,\n includeSilent,\n }\n )\n\n connectionManagerRef.current = manager\n manager.connect()\n\n return () => {\n manager.disconnect()\n connectionManagerRef.current = null\n }\n }, [threadId, live, depth, includeSilent, dispatchEvent])\n\n // Fetch initial messages\n useEffect(() => {\n if (!preload || !threadId) return\n\n const fetchMessages = async () => {\n setLoading(true)\n setError(null)\n\n try {\n const fetchedMessages = await clientRef.current.getMessages(threadId, {\n depth,\n includeSilent,\n })\n setMessages(fetchedMessages)\n } catch (err) {\n console.error(\"Failed to fetch messages:\", err)\n setError(\n err instanceof Error ? err : new Error(\"Failed to fetch messages\")\n )\n setMessages([])\n } finally {\n setLoading(false)\n }\n }\n\n fetchMessages()\n }, [threadId, preload, depth, includeSilent])\n\n // =============================================================================\n // MEMOIZED CONTEXT VALUES (split for performance)\n // =============================================================================\n\n const staticValue = useMemo(\n (): StaticContextValue => ({\n threadId,\n options: { preload, live, useWorkblocks, depth, includeSilent },\n sendMessage,\n stopExecution,\n subscribeToEvent,\n addFiles,\n removeFile,\n getFileUrl,\n getThumbnailUrl,\n getPreviewUrl,\n }),\n [\n threadId,\n preload,\n live,\n useWorkblocks,\n depth,\n includeSilent,\n sendMessage,\n stopExecution,\n subscribeToEvent,\n addFiles,\n removeFile,\n getFileUrl,\n getThumbnailUrl,\n getPreviewUrl,\n ]\n )\n\n const messagesValue = useMemo(\n (): MessagesContextValue => ({\n messages,\n workblocks,\n loading,\n }),\n [messages, workblocks, loading]\n )\n\n const filesValue = useMemo(\n (): FilesContextValue => ({\n files,\n }),\n [files]\n )\n\n const connectionValue = useMemo(\n (): ConnectionContextValue => ({\n connectionStatus,\n error,\n }),\n [connectionStatus, error]\n )\n\n // =============================================================================\n // RENDER\n // =============================================================================\n\n return (\n <StaticContext.Provider value={staticValue}>\n <MessagesContext.Provider value={messagesValue}>\n <FilesContext.Provider value={filesValue}>\n <ConnectionContext.Provider value={connectionValue}>\n {children}\n </ConnectionContext.Provider>\n </FilesContext.Provider>\n </MessagesContext.Provider>\n </StaticContext.Provider>\n )\n}\n\n// =============================================================================\n// INTERNAL HOOKS (used by useThread)\n// =============================================================================\n\nfunction useStaticContext(): StaticContextValue {\n const context = useContext(StaticContext)\n if (!context) {\n throw new Error(\"useThread must be used within a ThreadProvider\")\n }\n return context\n}\n\nfunction useMessagesContext(): MessagesContextValue {\n const context = useContext(MessagesContext)\n if (!context) {\n throw new Error(\"useThread must be used within a ThreadProvider\")\n }\n return context\n}\n\nfunction useFilesContext(): FilesContextValue {\n const context = useContext(FilesContext)\n if (!context) {\n throw new Error(\"useThread must be used within a ThreadProvider\")\n }\n return context\n}\n\nfunction useConnectionContext(): ConnectionContextValue {\n const context = useContext(ConnectionContext)\n if (!context) {\n throw new Error(\"useThread must be used within a ThreadProvider\")\n }\n return context\n}\n\n// =============================================================================\n// PUBLIC HOOKS\n// =============================================================================\n\n/**\n * Hook to access thread context with optimized re-renders.\n * Components only re-render when the specific data they use changes.\n *\n * @internal Used by useThread() in hooks/useThread.ts\n */\nexport function useThreadContextInternal(): ThreadContextValue {\n const static_ = useStaticContext()\n const messages_ = useMessagesContext()\n const files_ = useFilesContext()\n const connection_ = useConnectionContext()\n\n // Note: This object is recreated on every render of a consumer,\n // but the individual context subscriptions are optimized.\n // A component using only `sendMessage` won't re-render when messages change.\n return {\n threadId: static_.threadId,\n options: static_.options,\n sendMessage: static_.sendMessage,\n stopExecution: static_.stopExecution,\n subscribeToEvent: static_.subscribeToEvent,\n onEvent: static_.subscribeToEvent,\n addFiles: static_.addFiles,\n removeFile: static_.removeFile,\n getFileUrl: static_.getFileUrl,\n getThumbnailUrl: static_.getThumbnailUrl,\n getPreviewUrl: static_.getPreviewUrl,\n messages: messages_.messages,\n workblocks: messages_.workblocks,\n loading: messages_.loading,\n isLoading: messages_.loading,\n files: files_.files,\n connectionStatus: connection_.connectionStatus,\n status: connection_.connectionStatus,\n error: connection_.error,\n }\n}\n\n// Track if we've already warned to avoid spam\nlet hasWarnedAboutUseThreadContext = false\n\n/**\n * @deprecated Use `useThread()` instead.\n *\n * Hook to access the thread context.\n * Must be used within a ThreadProvider.\n *\n * @throws Error if used outside of ThreadProvider\n */\nexport function useThreadContext(): ThreadContextValue {\n if (\n !hasWarnedAboutUseThreadContext &&\n process.env.NODE_ENV !== \"production\"\n ) {\n hasWarnedAboutUseThreadContext = true\n console.warn(\n \"[DEPRECATED] useThreadContext() is deprecated.\\n\" +\n \"Use: const { messages, sendMessage, ... } = useThread()\"\n )\n }\n\n return useThreadContextInternal()\n}\n\n/**\n * Hook to get the current thread ID from context.\n * Must be used within a ThreadProvider.\n */\nexport function useThreadId(): string {\n return useStaticContext().threadId\n}\n","import { useThreadContextInternal, type ThreadContextValue } from '../context/ThreadProvider'\n\n// Track if we've already warned to avoid spam\nlet hasWarnedAboutArrayUsage = false\n\n/**\n * Hook to access the thread context.\n *\n * Must be used within a ThreadProvider. Returns the full thread context\n * including messages, actions, and file management.\n *\n * @returns The thread context value\n *\n * @example\n * ```tsx\n * function ChatMessages() {\n * const { messages, sendMessage, files } = useThread()\n *\n * return (\n * <div>\n * {messages.map(msg => <Message key={msg.id} message={msg} />)}\n * <button onClick={() => sendMessage({ role: 'user', content: 'Hello!' })}>\n * Send\n * </button>\n * </div>\n * )\n * }\n *\n * // Wrap with ThreadProvider\n * <ThreadProvider threadId=\"thread-123\">\n * <ChatMessages />\n * </ThreadProvider>\n * ```\n */\nexport function useThread(): ThreadContextValue {\n // useThreadContextInternal throws if not within ThreadProvider\n const context = useThreadContextInternal()\n\n // In development, wrap in Proxy to detect old usage pattern\n if (process.env.NODE_ENV !== 'production') {\n const arrayMethods = ['map', 'filter', 'forEach', 'find', 'some', 'every', 'reduce', 'length', 'push', 'pop', 'slice', 'splice']\n\n return new Proxy(context, {\n get(target, prop) {\n if (arrayMethods.includes(prop as string) && !hasWarnedAboutArrayUsage) {\n hasWarnedAboutArrayUsage = true\n console.warn(\n '[BREAKING CHANGE] useThread() now returns an object, not an array.\\n' +\n 'Change: const messages = useThread()\\n' +\n 'To: const { messages } = useThread()\\n\\n' +\n 'The returned object includes: messages, sendMessage, stopExecution, files, and more.'\n )\n }\n return target[prop as keyof typeof target]\n }\n })\n }\n\n return context\n}\n","import { useEffect, useState } from 'react'\nimport { useThreadContextInternal } from '../context/ThreadProvider'\n\n/**\n * Hook to listen for custom events emitted from a thread via the stream WebSocket.\n * Calls the provided callback whenever an event of the specified type is received.\n *\n * Must be used within a ThreadProvider. Events are emitted from the backend\n * using `emitThreadEvent(flow, 'event-type', data)`.\n *\n * @param type - The custom event type to filter for\n * @param callback - Function to call when an event of this type is received\n *\n * @example\n * ```tsx\n * function GamePreview() {\n * const [gameHtml, setGameHtml] = useState<string | null>(null)\n *\n * onThreadEvent('game_built', (data: { success: boolean }) => {\n * if (data.success) {\n * fetchGameHtml()\n * }\n * })\n *\n * return <iframe srcDoc={gameHtml} />\n * }\n * ```\n *\n * @example\n * ```tsx\n * function ProgressIndicator() {\n * const [progress, setProgress] = useState(0)\n *\n * onThreadEvent('progress', (data: { step: number; total: number }) => {\n * setProgress(data.step / data.total * 100)\n * })\n *\n * return <ProgressBar value={progress} />\n * }\n * ```\n */\nexport function onThreadEvent<T = unknown>(\n type: string,\n callback: (data: T) => void\n): void {\n // useThreadContextInternal throws if not within ThreadProvider\n const { subscribeToEvent } = useThreadContextInternal()\n\n useEffect(() => {\n // Subscribe to events of the specified type\n const unsubscribe = subscribeToEvent<T>(type, callback)\n\n // Cleanup subscription on unmount\n return unsubscribe\n }, [subscribeToEvent, type, callback])\n}\n\n/**\n * Hook to get the latest event data for a specific event type as React state.\n * Returns the most recent event data, or null if no event has been received.\n *\n * Must be used within a ThreadProvider. Events are emitted from the backend\n * using `emitThreadEvent(flow, 'event-type', data)`.\n *\n * @param type - The custom event type to filter for\n * @returns The latest event data matching the specified type, or null if none received\n *\n * @example\n * ```tsx\n * function ProgressIndicator() {\n * const progress = useThreadEvent<{ step: number; total: number }>('progress')\n *\n * if (!progress) return null\n *\n * return (\n * <div>\n * Step {progress.step} of {progress.total}\n * </div>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * function StatusDisplay() {\n * const status = useThreadEvent<{ message: string }>('status')\n *\n * useEffect(() => {\n * if (status) {\n * console.log('Status updated:', status.message)\n * }\n * }, [status])\n *\n * return <div>{status?.message ?? 'No status'}</div>\n * }\n * ```\n */\nexport function useThreadEvent<T = unknown>(type: string): T | null {\n // useThreadContextInternal throws if not within ThreadProvider\n const { subscribeToEvent } = useThreadContextInternal()\n const [eventData, setEventData] = useState<T | null>(null)\n\n useEffect(() => {\n // Subscribe to events of the specified type\n const unsubscribe = subscribeToEvent<T>(type, (data) => {\n setEventData(data)\n })\n\n // Cleanup subscription on unmount\n return unsubscribe\n }, [subscribeToEvent, type])\n\n return eventData\n}\n","import { useCallback } from 'react'\nimport { useThreadContext } from '../context/ThreadProvider'\nimport { sendMessage as sendMessageService } from '../services/sendMessage'\nimport type { SendMessagePayload, Message } from '@standardagents/client'\n\n// Track if we've already warned to avoid spam\nlet hasWarned = false\n\n/**\n * @deprecated Use `const { sendMessage } = useThread()` instead.\n *\n * Hook that returns a function to send messages to the current thread.\n * Must be used within a ThreadProvider.\n *\n * This hook automatically uses the thread ID from the ThreadProvider context,\n * so you don't need to pass it manually.\n *\n * @returns A function that sends a message to the current thread\n *\n * @throws Error if used outside of ThreadProvider\n *\n * @example\n * ```tsx\n * // NEW - Recommended\n * const { sendMessage } = useThread()\n * await sendMessage({ role: 'user', content: 'Hello!' })\n *\n * // OLD - Deprecated\n * const sendMessage = useSendMessage()\n * await sendMessage({ role: 'user', content: 'Hello!' })\n * ```\n */\nexport function useSendMessage(): (payload: SendMessagePayload) => Promise<Message> {\n if (!hasWarned && process.env.NODE_ENV !== 'production') {\n hasWarned = true\n console.warn(\n '[DEPRECATED] useSendMessage() is deprecated.\\n' +\n 'Use: const { sendMessage } = useThread()\\n' +\n 'Then: await sendMessage({ role: \"user\", content: \"Hello!\" })'\n )\n }\n let context: ReturnType<typeof useThreadContext>\n\n try {\n context = useThreadContext()\n } catch {\n throw new Error('useSendMessage must be used within a ThreadProvider')\n }\n\n const { threadId } = context\n\n return useCallback(\n (payload: SendMessagePayload) => {\n return sendMessageService(threadId, payload)\n },\n [threadId]\n )\n}\n","import { useCallback } from 'react'\nimport { useThreadContext } from '../context/ThreadProvider'\nimport { stopThread as stopThreadService } from '../services/stopThread'\n\n// Track if we've already warned to avoid spam\nlet hasWarned = false\n\n/**\n * @deprecated Use `const { stopExecution } = useThread()` instead.\n *\n * Hook that returns a function to stop the current thread's execution.\n * Must be used within a ThreadProvider.\n *\n * This hook automatically uses the thread ID from the ThreadProvider context,\n * so you don't need to pass it manually.\n *\n * @returns A function that stops the current thread's execution\n *\n * @throws Error if used outside of ThreadProvider\n *\n * @example\n * ```tsx\n * // NEW - Recommended\n * const { stopExecution } = useThread()\n * await stopExecution()\n *\n * // OLD - Deprecated\n * const stopThread = useStopThread()\n * await stopThread()\n * ```\n */\nexport function useStopThread(): () => Promise<void> {\n if (!hasWarned && process.env.NODE_ENV !== 'production') {\n hasWarned = true\n console.warn(\n '[DEPRECATED] useStopThread() is deprecated.\\n' +\n 'Use: const { stopExecution } = useThread()'\n )\n }\n let context: ReturnType<typeof useThreadContext>\n\n try {\n context = useThreadContext()\n } catch {\n throw new Error('useStopThread must be used within a ThreadProvider')\n }\n\n const { threadId } = context\n\n return useCallback(\n () => {\n return stopThreadService(threadId)\n },\n [threadId]\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/services/sendMessage.ts","../src/services/stopThread.ts","../src/context/AgentBuilderProvider.tsx","../src/context/ThreadProvider.tsx","../src/hooks/useThread.ts","../src/hooks/onThreadEvent.ts","../src/hooks/useSendMessage.ts","../src/hooks/useStopThread.ts"],"names":["globalEndpoint","createContext","AgentBuilderClient","useEffect","useMemo","sendMessage","jsx","useContext","useState","useCallback","hasWarned"],"mappings":"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","file":"index.js","sourcesContent":["import type { SendMessagePayload, Message } from '@standardagents/client'\n\n// Global client instance (set by AgentBuilderProvider)\nlet globalEndpoint: string | null = null\n\n/**\n * Internal function to set the global endpoint.\n * Called by AgentBuilderProvider when it mounts.\n * @internal\n */\nexport function __setGlobalEndpoint(endpoint: string) {\n globalEndpoint = endpoint\n}\n\n/**\n * Send a message to a specific thread.\n *\n * This is a standalone function that sends messages to threads.\n * It requires that an AgentBuilderProvider is mounted somewhere in your app\n * to set the global endpoint configuration.\n *\n * @param id - The thread ID to send the message to\n * @param payload - The message payload containing role, content, and optional silent flag\n * @returns Promise resolving to the created message\n *\n * @throws Error if called before AgentBuilderProvider is mounted\n *\n * @example\n * ```tsx\n * import { sendMessage } from '@standardagents/react'\n *\n * await sendMessage('thread-123', {\n * role: 'user',\n * content: 'Hello, agent!',\n * })\n *\n * // Send a silent message\n * await sendMessage('thread-123', {\n * role: 'user',\n * content: 'Silent message',\n * silent: true,\n * })\n * ```\n */\nexport async function sendMessage(\n id: string,\n payload: SendMessagePayload\n): Promise<Message> {\n if (!globalEndpoint) {\n throw new Error(\n 'sendMessage requires AgentBuilderProvider to be mounted in your app'\n )\n }\n\n // Read auth token from localStorage\n const token =\n typeof localStorage !== 'undefined'\n ? localStorage.getItem('agentbuilder_auth_token')\n : null\n\n // Build headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (token) {\n headers['Authorization'] = `Bearer ${token}`\n }\n\n // Make the request\n const response = await fetch(`${globalEndpoint}/threads/${id}/messages`, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to send message: ${response.statusText}`)\n }\n\n return response.json()\n}\n","// Global endpoint instance (set by AgentBuilderProvider)\nlet globalEndpoint: string | null = null\n\n/**\n * Internal function to set the global endpoint.\n * Called by AgentBuilderProvider when it mounts.\n * @internal\n */\nexport function __setGlobalEndpointForStop(endpoint: string) {\n globalEndpoint = endpoint\n}\n\nexport interface StopThreadOptions {\n /**\n * Override the endpoint URL for this request.\n * If not provided, uses the endpoint from AgentBuilderProvider.\n */\n endpoint?: string\n}\n\n/**\n * Stop execution of a thread.\n *\n * This is a standalone function that stops a running thread execution.\n * It requires that an AgentBuilderProvider is mounted somewhere in your app\n * to set the global endpoint configuration, or you can provide a custom endpoint.\n *\n * @param id - The thread ID to stop\n * @param options - Optional configuration including custom endpoint\n * @returns Promise that resolves when the thread is stopped\n *\n * @throws Error if called before AgentBuilderProvider is mounted and no endpoint is provided\n *\n * @example\n * ```tsx\n * import { stopThread } from '@standardagents/react'\n *\n * // Using global endpoint from AgentBuilderProvider\n * await stopThread('thread-123')\n *\n * // Using custom endpoint\n * await stopThread('thread-123', {\n * endpoint: 'https://custom.example.com/api'\n * })\n * ```\n */\nexport async function stopThread(\n id: string,\n options?: StopThreadOptions\n): Promise<void> {\n const endpoint = options?.endpoint ?? globalEndpoint\n\n if (!endpoint) {\n throw new Error(\n 'stopThread requires AgentBuilderProvider to be mounted or endpoint option to be provided'\n )\n }\n\n // Normalize endpoint by removing trailing slash\n const normalizedEndpoint = endpoint.replace(/\\/$/, '')\n\n // Read auth token from localStorage\n const token =\n typeof localStorage !== 'undefined'\n ? localStorage.getItem('agentbuilder_auth_token')\n : null\n\n // Build headers\n const headers: Record<string, string> = {}\n\n if (token) {\n headers['Authorization'] = `Bearer ${token}`\n }\n\n // Make the request\n const response = await fetch(`${normalizedEndpoint}/threads/${id}/stop`, {\n method: 'POST',\n headers,\n })\n\n if (!response.ok) {\n throw new Error(`Failed to stop thread: ${response.statusText}`)\n }\n\n await response.json()\n}\n","import React, { createContext, useContext, useMemo, useEffect, type ReactNode } from 'react'\nimport { AgentBuilderClient, type AgentBuilderConfig } from '@standardagents/client'\nimport { __setGlobalEndpoint } from '../services/sendMessage'\nimport { __setGlobalEndpointForStop } from '../services/stopThread'\n\ninterface AgentBuilderContextValue {\n client: AgentBuilderClient\n config: AgentBuilderConfig\n}\n\nexport const AgentBuilderContext = createContext<AgentBuilderContextValue | null>(null)\n\nexport interface AgentBuilderProviderProps {\n config: AgentBuilderConfig\n children: ReactNode\n}\n\n/**\n * AgentBuilderProvider provides the AgentBuilder client instance to all child components.\n * This should wrap the part of your app where you want to use AgentBuilder functionality.\n *\n * @example\n * ```tsx\n * <AgentBuilderProvider config={{ endpoint: 'https://api.example.com' }}>\n * <YourApp />\n * </AgentBuilderProvider>\n * ```\n */\nexport function AgentBuilderProvider({ config, children }: AgentBuilderProviderProps) {\n // Create client instance only once using useMemo\n const client = useMemo(() => {\n return new AgentBuilderClient(config.endpoint)\n }, [config.endpoint])\n\n const value = useMemo(\n () => ({\n client,\n config,\n }),\n [client, config]\n )\n\n // Set global endpoint for standalone functions like sendMessage and stopThread\n useEffect(() => {\n __setGlobalEndpoint(config.endpoint)\n __setGlobalEndpointForStop(config.endpoint)\n }, [config.endpoint])\n\n return <AgentBuilderContext.Provider value={value}>{children}</AgentBuilderContext.Provider>\n}\n\n/**\n * Hook to access the AgentBuilder client instance.\n * Must be used within an AgentBuilderProvider.\n *\n * @throws Error if used outside of AgentBuilderProvider\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const client = useAgentBuilderClient()\n * // Use client.getThread(), client.sendMessage(), etc.\n * }\n * ```\n */\nexport function useAgentBuilderClient(): AgentBuilderClient {\n const context = useContext(AgentBuilderContext)\n\n if (!context) {\n throw new Error('useAgentBuilderClient must be used within AgentBuilderProvider')\n }\n\n return context.client\n}\n\n/**\n * Hook to access the AgentBuilder config.\n * Must be used within an AgentBuilderProvider.\n *\n * @throws Error if used outside of AgentBuilderProvider\n */\nexport function useAgentBuilderConfig(): AgentBuilderConfig {\n const context = useContext(AgentBuilderContext)\n\n if (!context) {\n throw new Error('useAgentBuilderConfig must be used within AgentBuilderProvider')\n }\n\n return context.config\n}\n","import React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n type ReactNode,\n} from \"react\"\nimport {\n useAgentBuilderClient,\n useAgentBuilderConfig,\n} from \"./AgentBuilderProvider\"\nimport {\n AgentBuilderClient,\n ThreadConnectionManager,\n FileUploadManager,\n messagesToFiles,\n transformToWorkblocks,\n type Message,\n type ThreadMessage,\n type ThreadFile,\n type SendMessagePayload,\n type ConnectionStatus as ClientConnectionStatus,\n} from \"@standardagents/client\"\nimport type { ThreadProviderOptions } from \"../types\"\n\n// Shared file upload manager instance\nconst uploadManager = new FileUploadManager()\n\n/**\n * Event listener callback type\n */\ntype EventListener<T = unknown> = (data: T) => void\n\n/**\n * WebSocket connection status\n */\nexport type ConnectionStatus = ClientConnectionStatus\n\n// =============================================================================\n// INTERNAL CONTEXTS (not exported - implementation detail)\n// =============================================================================\n\n/**\n * Static context - things that don't change or are memoized callbacks\n */\ninterface StaticContextValue {\n threadId: string\n options: ThreadProviderOptions\n sendMessage: (payload: SendMessagePayload) => Promise<Message>\n stopExecution: () => Promise<void>\n subscribeToEvent: <T = unknown>(\n eventType: string,\n listener: EventListener<T>\n ) => () => void\n addFiles: (files: File[] | FileList) => void\n removeFile: (id: string) => void\n getFileUrl: (file: ThreadFile) => string\n getThumbnailUrl: (file: ThreadFile) => string\n getPreviewUrl: (file: ThreadFile) => string | null\n}\n\n/**\n * Messages context - changes when messages update\n */\ninterface MessagesContextValue {\n messages: Message[]\n workblocks: ThreadMessage[]\n loading: boolean\n}\n\n/**\n * Files context - changes when files update\n */\ninterface FilesContextValue {\n files: ThreadFile[]\n}\n\n/**\n * Connection context - changes when connection status changes\n */\ninterface ConnectionContextValue {\n connectionStatus: ConnectionStatus\n error: Error | null\n}\n\nconst StaticContext = createContext<StaticContextValue | null>(null)\nconst MessagesContext = createContext<MessagesContextValue | null>(null)\nconst FilesContext = createContext<FilesContextValue | null>(null)\nconst ConnectionContext = createContext<ConnectionContextValue | null>(null)\n\n// =============================================================================\n// PUBLIC TYPES AND CONTEXT\n// =============================================================================\n\n/**\n * Thread context value - the public interface returned by useThread()\n */\nexport interface ThreadContextValue {\n /** The thread ID */\n threadId: string\n /** Current messages in the thread */\n messages: Message[]\n /** Messages transformed to workblocks (if useWorkblocks is true) */\n workblocks: ThreadMessage[]\n /** Whether messages are currently loading (alias: isLoading) */\n loading: boolean\n /** Whether messages are currently loading (alias for loading) */\n isLoading: boolean\n /** Any error that occurred */\n error: Error | null\n /** WebSocket connection status (alias: status) */\n connectionStatus: ConnectionStatus\n /** WebSocket connection status (alias for connectionStatus) */\n status: ConnectionStatus\n /** Subscribe to a specific event type (alias: onEvent) */\n subscribeToEvent: <T = unknown>(\n eventType: string,\n listener: EventListener<T>\n ) => () => void\n /** Subscribe to a specific event type (alias for subscribeToEvent) */\n onEvent: <T = unknown>(\n eventType: string,\n listener: EventListener<T>\n ) => () => void\n /** Options passed to the provider */\n options: ThreadProviderOptions\n\n // Actions\n /** Send a message to the thread */\n sendMessage: (payload: SendMessagePayload) => Promise<Message>\n /** Stop the current execution */\n stopExecution: () => Promise<void>\n\n // File management\n /** All files in the thread (pending uploads + committed from messages) */\n files: ThreadFile[]\n /** Add files and start uploading immediately */\n addFiles: (files: File[] | FileList) => void\n /** Remove a pending file (cannot remove committed files) */\n removeFile: (id: string) => void\n /** Get the full URL for a file */\n getFileUrl: (file: ThreadFile) => string\n /** Get the thumbnail URL for an image file */\n getThumbnailUrl: (file: ThreadFile) => string\n /** Get preview URL - localPreviewUrl for pending images, thumbnail for committed */\n getPreviewUrl: (file: ThreadFile) => string | null\n}\n\n/**\n * Legacy context export for useThread() - combines all internal contexts\n * @internal\n */\nexport const ThreadContext = createContext<ThreadContextValue | null>(null)\n\nexport interface ThreadProviderProps {\n /** The thread ID to connect to */\n threadId: string\n /** Provider options */\n options?: ThreadProviderOptions\n /** Whether to preload messages on mount (default: true) */\n preload?: boolean\n /** Whether to enable live updates via WebSocket (default: true) */\n live?: boolean\n /** Transform messages to workblocks (default: false) */\n useWorkblocks?: boolean\n /** Maximum message depth to fetch/stream (default: 0 for top-level only) */\n depth?: number\n /** Whether to include silent messages (default: false) */\n includeSilent?: boolean\n /** Optional endpoint override */\n endpoint?: string\n children: ReactNode\n}\n\n/**\n * ThreadProvider establishes a WebSocket connection to a thread and provides\n * context for child components to access messages and events.\n *\n * Must be nested inside AgentBuilderProvider.\n *\n * @example\n * ```tsx\n * <AgentBuilderProvider config={{ endpoint: 'https://api.example.com' }}>\n * <ThreadProvider threadId=\"thread-123\">\n * <ChatMessages />\n * </ThreadProvider>\n * </AgentBuilderProvider>\n * ```\n */\nexport function ThreadProvider({\n threadId,\n options = {},\n preload = true,\n live = true,\n useWorkblocks = false,\n depth = 0,\n includeSilent = false,\n endpoint: endpointOverride,\n children,\n}: ThreadProviderProps) {\n const contextClient = useAgentBuilderClient()\n const contextConfig = useAgentBuilderConfig()\n\n // Use override endpoint if provided, otherwise use context endpoint\n const effectiveEndpoint = endpointOverride || contextConfig.endpoint\n\n // Create a client instance\n const clientRef = useRef<AgentBuilderClient>(\n endpointOverride ? new AgentBuilderClient(endpointOverride) : contextClient\n )\n\n // Update client if endpoint override changes\n useEffect(() => {\n if (endpointOverride) {\n clientRef.current = new AgentBuilderClient(endpointOverride)\n } else {\n clientRef.current = contextClient\n }\n }, [endpointOverride, contextClient])\n\n // =============================================================================\n // STATE\n // =============================================================================\n\n const [messages, setMessages] = useState<Message[]>([])\n const [loading, setLoading] = useState(preload)\n const [error, setError] = useState<Error | null>(null)\n const [connectionStatus, setConnectionStatus] = useState<ConnectionStatus>(\n live ? \"connecting\" : \"disconnected\"\n )\n const [pendingFiles, setPendingFiles] = useState<ThreadFile[]>([])\n\n // =============================================================================\n // DERIVED STATE\n // =============================================================================\n\n const committedFiles = useMemo(() => {\n return messagesToFiles(messages)\n }, [messages])\n\n const files = useMemo(() => {\n return [...pendingFiles, ...committedFiles]\n }, [pendingFiles, committedFiles])\n\n const workblocks = useMemo(() => {\n if (!useWorkblocks) {\n return messages as ThreadMessage[]\n }\n return transformToWorkblocks(messages)\n }, [messages, useWorkblocks])\n\n // =============================================================================\n // REFS\n // =============================================================================\n\n const eventListenersRef = useRef<Map<string, Set<EventListener>>>(new Map())\n const connectionManagerRef = useRef<ThreadConnectionManager | null>(null)\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n\n /**\n * Build optimistic attachments from pending files for immediate UI display.\n * Includes localPreviewUrl for images so they can be previewed before server confirmation.\n */\n const buildOptimisticAttachments = useCallback(\n (attachmentPaths?: string[]): string | null => {\n if (!attachmentPaths || attachmentPaths.length === 0) return null\n\n const refs = attachmentPaths.map((path) => {\n const file = pendingFiles.find((f) => f.path === path)\n\n const ref: Record<string, unknown> = {\n id: path,\n type: \"file\",\n path,\n name: file?.name || path.split(\"/\").pop() || \"file\",\n mimeType: file?.mimeType || \"application/octet-stream\",\n size: file?.size || 0,\n }\n\n // Only add image-specific fields for images\n if (file?.isImage) {\n if (file.width) ref.width = file.width\n if (file.height) ref.height = file.height\n // localPreviewUrl for optimistic image preview (data URL)\n if (file.localPreviewUrl) ref.localPreviewUrl = file.localPreviewUrl\n }\n\n return ref\n })\n\n return JSON.stringify(refs)\n },\n [pendingFiles]\n )\n\n // =============================================================================\n // CALLBACKS (stable - memoized)\n // =============================================================================\n\n const subscribeToEvent = useCallback(\n <T = unknown,>(\n eventType: string,\n listener: EventListener<T>\n ): (() => void) => {\n if (!eventListenersRef.current.has(eventType)) {\n eventListenersRef.current.set(eventType, new Set())\n }\n eventListenersRef.current.get(eventType)!.add(listener as EventListener)\n\n return () => {\n const listeners = eventListenersRef.current.get(eventType)\n if (listeners) {\n listeners.delete(listener as EventListener)\n if (listeners.size === 0) {\n eventListenersRef.current.delete(eventType)\n }\n }\n }\n },\n []\n )\n\n const dispatchEvent = useCallback((eventType: string, data: unknown) => {\n const listeners = eventListenersRef.current.get(eventType)\n if (listeners) {\n listeners.forEach((listener) => {\n try {\n listener(data)\n } catch (err) {\n console.error(`Error in event listener for \"${eventType}\":`, err)\n }\n })\n }\n }, [])\n\n const addFiles = useCallback(\n (filesToAdd: File[] | FileList) => {\n // Queue files for immediate UI display\n const items = uploadManager.queueFiles(filesToAdd)\n\n // Add pending files to state\n setPendingFiles((prev) => [...prev, ...items.map((i) => i.pending)])\n\n // Start uploads in parallel\n for (const { pending, file } of items) {\n uploadManager\n .executeUpload(\n threadId,\n file,\n pending.id,\n clientRef.current,\n (updates) => {\n setPendingFiles((prev) =>\n prev.map((f) =>\n f.id === pending.id ? { ...f, ...updates } : f\n )\n )\n }\n )\n .catch(() => {\n // Error already handled via onUpdate callback\n })\n }\n },\n [threadId]\n )\n\n const removeFile = useCallback((id: string) => {\n setPendingFiles((prev) => prev.filter((f) => f.id !== id))\n }, [])\n\n const getFileUrl = useCallback(\n (file: ThreadFile): string => {\n if (!file.path) return \"\"\n return clientRef.current.getFileUrl(threadId, file.path)\n },\n [threadId]\n )\n\n const getThumbnailUrl = useCallback(\n (file: ThreadFile): string => {\n if (!file.path) return \"\"\n return clientRef.current.getThumbnailUrl(threadId, file.path)\n },\n [threadId]\n )\n\n const getPreviewUrl = useCallback(\n (file: ThreadFile): string | null => {\n if (!file.isImage) return null\n if (file.localPreviewUrl) return file.localPreviewUrl\n if (file.path) return clientRef.current.getThumbnailUrl(threadId, file.path)\n return null\n },\n [threadId]\n )\n\n const sendMessage = useCallback(\n async (payload: SendMessagePayload): Promise<Message> => {\n // Create optimistic message for immediate UI display\n const optimisticId = `optimistic-${crypto.randomUUID()}`\n const optimisticMessage: Message = {\n id: optimisticId,\n role: payload.role,\n content: payload.content,\n attachments: buildOptimisticAttachments(payload.attachments),\n created_at: Date.now() * 1000, // microseconds\n status: \"pending\",\n }\n\n // Add optimistic message immediately\n setMessages((prev) => [...prev, optimisticMessage])\n\n try {\n const result = await clientRef.current.sendMessage(threadId, payload)\n // Remove optimistic message - real one will come via WebSocket\n setMessages((prev) => prev.filter((m) => m.id !== optimisticId))\n return result\n } catch (err) {\n // Remove optimistic message on error\n setMessages((prev) => prev.filter((m) => m.id !== optimisticId))\n setError(err instanceof Error ? err : new Error(String(err)))\n throw err\n }\n },\n [threadId, buildOptimisticAttachments]\n )\n\n const stopExecution = useCallback(async () => {\n try {\n await clientRef.current.stopExecution(threadId)\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)))\n throw err\n }\n }, [threadId])\n\n // =============================================================================\n // WEBSOCKET CONNECTION (via ThreadConnectionManager)\n // =============================================================================\n\n useEffect(() => {\n if (!live || !threadId) return\n\n console.log(`[ThreadProvider] Connecting WebSocket for thread ${threadId}`)\n\n const manager = new ThreadConnectionManager(\n clientRef.current,\n threadId,\n {\n onStatusChange: (status) => {\n console.log(`[ThreadProvider] Connection status: ${status}`)\n setConnectionStatus(status)\n },\n onMessage: (event) => {\n setMessages((prev) => {\n const exists = prev.some((m) => m.id === event.data.id)\n if (exists) {\n return prev.map((m) => (m.id === event.data.id ? event.data : m))\n } else {\n return [...prev, event.data]\n }\n })\n },\n onChunk: (event) => {\n setMessages((prev) => {\n return prev.map((m) => {\n if (m.id === event.message_id) {\n return {\n ...m,\n content: (m.content || \"\") + event.chunk,\n }\n }\n return m\n })\n })\n },\n onEvent: (event) => {\n dispatchEvent(event.eventType, event.data)\n },\n onError: (event) => {\n console.error(\"[ThreadProvider] WebSocket error:\", event.error)\n setError(new Error(event.error))\n },\n },\n {\n depth,\n includeSilent,\n }\n )\n\n connectionManagerRef.current = manager\n manager.connect()\n\n return () => {\n manager.disconnect()\n connectionManagerRef.current = null\n }\n }, [threadId, live, depth, includeSilent, dispatchEvent])\n\n // Fetch initial messages\n useEffect(() => {\n if (!preload || !threadId) return\n\n const fetchMessages = async () => {\n setLoading(true)\n setError(null)\n\n try {\n const fetchedMessages = await clientRef.current.getMessages(threadId, {\n depth,\n includeSilent,\n })\n setMessages(fetchedMessages)\n } catch (err) {\n console.error(\"Failed to fetch messages:\", err)\n setError(\n err instanceof Error ? err : new Error(\"Failed to fetch messages\")\n )\n setMessages([])\n } finally {\n setLoading(false)\n }\n }\n\n fetchMessages()\n }, [threadId, preload, depth, includeSilent])\n\n // =============================================================================\n // MEMOIZED CONTEXT VALUES (split for performance)\n // =============================================================================\n\n const staticValue = useMemo(\n (): StaticContextValue => ({\n threadId,\n options: { preload, live, useWorkblocks, depth, includeSilent },\n sendMessage,\n stopExecution,\n subscribeToEvent,\n addFiles,\n removeFile,\n getFileUrl,\n getThumbnailUrl,\n getPreviewUrl,\n }),\n [\n threadId,\n preload,\n live,\n useWorkblocks,\n depth,\n includeSilent,\n sendMessage,\n stopExecution,\n subscribeToEvent,\n addFiles,\n removeFile,\n getFileUrl,\n getThumbnailUrl,\n getPreviewUrl,\n ]\n )\n\n const messagesValue = useMemo(\n (): MessagesContextValue => ({\n messages,\n workblocks,\n loading,\n }),\n [messages, workblocks, loading]\n )\n\n const filesValue = useMemo(\n (): FilesContextValue => ({\n files,\n }),\n [files]\n )\n\n const connectionValue = useMemo(\n (): ConnectionContextValue => ({\n connectionStatus,\n error,\n }),\n [connectionStatus, error]\n )\n\n // =============================================================================\n // RENDER\n // =============================================================================\n\n return (\n <StaticContext.Provider value={staticValue}>\n <MessagesContext.Provider value={messagesValue}>\n <FilesContext.Provider value={filesValue}>\n <ConnectionContext.Provider value={connectionValue}>\n {children}\n </ConnectionContext.Provider>\n </FilesContext.Provider>\n </MessagesContext.Provider>\n </StaticContext.Provider>\n )\n}\n\n// =============================================================================\n// INTERNAL HOOKS (used by useThread)\n// =============================================================================\n\nfunction useStaticContext(): StaticContextValue {\n const context = useContext(StaticContext)\n if (!context) {\n throw new Error(\"useThread must be used within a ThreadProvider\")\n }\n return context\n}\n\nfunction useMessagesContext(): MessagesContextValue {\n const context = useContext(MessagesContext)\n if (!context) {\n throw new Error(\"useThread must be used within a ThreadProvider\")\n }\n return context\n}\n\nfunction useFilesContext(): FilesContextValue {\n const context = useContext(FilesContext)\n if (!context) {\n throw new Error(\"useThread must be used within a ThreadProvider\")\n }\n return context\n}\n\nfunction useConnectionContext(): ConnectionContextValue {\n const context = useContext(ConnectionContext)\n if (!context) {\n throw new Error(\"useThread must be used within a ThreadProvider\")\n }\n return context\n}\n\n// =============================================================================\n// PUBLIC HOOKS\n// =============================================================================\n\n/**\n * Hook to access thread context with optimized re-renders.\n * Components only re-render when the specific data they use changes.\n *\n * @internal Used by useThread() in hooks/useThread.ts\n */\nexport function useThreadContextInternal(): ThreadContextValue {\n const static_ = useStaticContext()\n const messages_ = useMessagesContext()\n const files_ = useFilesContext()\n const connection_ = useConnectionContext()\n\n // Note: This object is recreated on every render of a consumer,\n // but the individual context subscriptions are optimized.\n // A component using only `sendMessage` won't re-render when messages change.\n return {\n threadId: static_.threadId,\n options: static_.options,\n sendMessage: static_.sendMessage,\n stopExecution: static_.stopExecution,\n subscribeToEvent: static_.subscribeToEvent,\n onEvent: static_.subscribeToEvent,\n addFiles: static_.addFiles,\n removeFile: static_.removeFile,\n getFileUrl: static_.getFileUrl,\n getThumbnailUrl: static_.getThumbnailUrl,\n getPreviewUrl: static_.getPreviewUrl,\n messages: messages_.messages,\n workblocks: messages_.workblocks,\n loading: messages_.loading,\n isLoading: messages_.loading,\n files: files_.files,\n connectionStatus: connection_.connectionStatus,\n status: connection_.connectionStatus,\n error: connection_.error,\n }\n}\n\n// Track if we've already warned to avoid spam\nlet hasWarnedAboutUseThreadContext = false\n\n/**\n * @deprecated Use `useThread()` instead.\n *\n * Hook to access the thread context.\n * Must be used within a ThreadProvider.\n *\n * @throws Error if used outside of ThreadProvider\n */\nexport function useThreadContext(): ThreadContextValue {\n if (\n !hasWarnedAboutUseThreadContext &&\n process.env.NODE_ENV !== \"production\"\n ) {\n hasWarnedAboutUseThreadContext = true\n console.warn(\n \"[DEPRECATED] useThreadContext() is deprecated.\\n\" +\n \"Use: const { messages, sendMessage, ... } = useThread()\"\n )\n }\n\n return useThreadContextInternal()\n}\n\n/**\n * Hook to get the current thread ID from context.\n * Must be used within a ThreadProvider.\n */\nexport function useThreadId(): string {\n return useStaticContext().threadId\n}\n","import { useThreadContextInternal, type ThreadContextValue } from '../context/ThreadProvider'\n\n// Track if we've already warned to avoid spam\nlet hasWarnedAboutArrayUsage = false\n\n/**\n * Hook to access the thread context.\n *\n * Must be used within a ThreadProvider. Returns the full thread context\n * including messages, actions, and file management.\n *\n * @returns The thread context value\n *\n * @example\n * ```tsx\n * function ChatMessages() {\n * const { messages, sendMessage, files } = useThread()\n *\n * return (\n * <div>\n * {messages.map(msg => <Message key={msg.id} message={msg} />)}\n * <button onClick={() => sendMessage({ role: 'user', content: 'Hello!' })}>\n * Send\n * </button>\n * </div>\n * )\n * }\n *\n * // Wrap with ThreadProvider\n * <ThreadProvider threadId=\"thread-123\">\n * <ChatMessages />\n * </ThreadProvider>\n * ```\n */\nexport function useThread(): ThreadContextValue {\n // useThreadContextInternal throws if not within ThreadProvider\n const context = useThreadContextInternal()\n\n // In development, wrap in Proxy to detect old usage pattern\n if (process.env.NODE_ENV !== 'production') {\n const arrayMethods = ['map', 'filter', 'forEach', 'find', 'some', 'every', 'reduce', 'length', 'push', 'pop', 'slice', 'splice']\n\n return new Proxy(context, {\n get(target, prop) {\n if (arrayMethods.includes(prop as string) && !hasWarnedAboutArrayUsage) {\n hasWarnedAboutArrayUsage = true\n console.warn(\n '[BREAKING CHANGE] useThread() now returns an object, not an array.\\n' +\n 'Change: const messages = useThread()\\n' +\n 'To: const { messages } = useThread()\\n\\n' +\n 'The returned object includes: messages, sendMessage, stopExecution, files, and more.'\n )\n }\n return target[prop as keyof typeof target]\n }\n })\n }\n\n return context\n}\n","import { useEffect, useState } from 'react'\nimport { useThreadContextInternal } from '../context/ThreadProvider'\n\n/**\n * Hook to listen for custom events emitted from a thread via the stream WebSocket.\n * Calls the provided callback whenever an event of the specified type is received.\n *\n * Must be used within a ThreadProvider. Events are emitted from the backend\n * using `emitThreadEvent(flow, 'event-type', data)`.\n *\n * @param type - The custom event type to filter for\n * @param callback - Function to call when an event of this type is received\n *\n * @example\n * ```tsx\n * function GamePreview() {\n * const [gameHtml, setGameHtml] = useState<string | null>(null)\n *\n * onThreadEvent('game_built', (data: { success: boolean }) => {\n * if (data.success) {\n * fetchGameHtml()\n * }\n * })\n *\n * return <iframe srcDoc={gameHtml} />\n * }\n * ```\n *\n * @example\n * ```tsx\n * function ProgressIndicator() {\n * const [progress, setProgress] = useState(0)\n *\n * onThreadEvent('progress', (data: { step: number; total: number }) => {\n * setProgress(data.step / data.total * 100)\n * })\n *\n * return <ProgressBar value={progress} />\n * }\n * ```\n */\nexport function onThreadEvent<T = unknown>(\n type: string,\n callback: (data: T) => void\n): void {\n // useThreadContextInternal throws if not within ThreadProvider\n const { subscribeToEvent } = useThreadContextInternal()\n\n useEffect(() => {\n // Subscribe to events of the specified type\n const unsubscribe = subscribeToEvent<T>(type, callback)\n\n // Cleanup subscription on unmount\n return unsubscribe\n }, [subscribeToEvent, type, callback])\n}\n\n/**\n * Hook to get the latest event data for a specific event type as React state.\n * Returns the most recent event data, or null if no event has been received.\n *\n * Must be used within a ThreadProvider. Events are emitted from the backend\n * using `emitThreadEvent(flow, 'event-type', data)`.\n *\n * @param type - The custom event type to filter for\n * @returns The latest event data matching the specified type, or null if none received\n *\n * @example\n * ```tsx\n * function ProgressIndicator() {\n * const progress = useThreadEvent<{ step: number; total: number }>('progress')\n *\n * if (!progress) return null\n *\n * return (\n * <div>\n * Step {progress.step} of {progress.total}\n * </div>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * function StatusDisplay() {\n * const status = useThreadEvent<{ message: string }>('status')\n *\n * useEffect(() => {\n * if (status) {\n * console.log('Status updated:', status.message)\n * }\n * }, [status])\n *\n * return <div>{status?.message ?? 'No status'}</div>\n * }\n * ```\n */\nexport function useThreadEvent<T = unknown>(type: string): T | null {\n // useThreadContextInternal throws if not within ThreadProvider\n const { subscribeToEvent } = useThreadContextInternal()\n const [eventData, setEventData] = useState<T | null>(null)\n\n useEffect(() => {\n // Subscribe to events of the specified type\n const unsubscribe = subscribeToEvent<T>(type, (data) => {\n setEventData(data)\n })\n\n // Cleanup subscription on unmount\n return unsubscribe\n }, [subscribeToEvent, type])\n\n return eventData\n}\n","import { useCallback } from 'react'\nimport { useThreadContext } from '../context/ThreadProvider'\nimport { sendMessage as sendMessageService } from '../services/sendMessage'\nimport type { SendMessagePayload, Message } from '@standardagents/client'\n\n// Track if we've already warned to avoid spam\nlet hasWarned = false\n\n/**\n * @deprecated Use `const { sendMessage } = useThread()` instead.\n *\n * Hook that returns a function to send messages to the current thread.\n * Must be used within a ThreadProvider.\n *\n * This hook automatically uses the thread ID from the ThreadProvider context,\n * so you don't need to pass it manually.\n *\n * @returns A function that sends a message to the current thread\n *\n * @throws Error if used outside of ThreadProvider\n *\n * @example\n * ```tsx\n * // NEW - Recommended\n * const { sendMessage } = useThread()\n * await sendMessage({ role: 'user', content: 'Hello!' })\n *\n * // OLD - Deprecated\n * const sendMessage = useSendMessage()\n * await sendMessage({ role: 'user', content: 'Hello!' })\n * ```\n */\nexport function useSendMessage(): (payload: SendMessagePayload) => Promise<Message> {\n if (!hasWarned && process.env.NODE_ENV !== 'production') {\n hasWarned = true\n console.warn(\n '[DEPRECATED] useSendMessage() is deprecated.\\n' +\n 'Use: const { sendMessage } = useThread()\\n' +\n 'Then: await sendMessage({ role: \"user\", content: \"Hello!\" })'\n )\n }\n let context: ReturnType<typeof useThreadContext>\n\n try {\n context = useThreadContext()\n } catch {\n throw new Error('useSendMessage must be used within a ThreadProvider')\n }\n\n const { threadId } = context\n\n return useCallback(\n (payload: SendMessagePayload) => {\n return sendMessageService(threadId, payload)\n },\n [threadId]\n )\n}\n","import { useCallback } from 'react'\nimport { useThreadContext } from '../context/ThreadProvider'\nimport { stopThread as stopThreadService } from '../services/stopThread'\n\n// Track if we've already warned to avoid spam\nlet hasWarned = false\n\n/**\n * @deprecated Use `const { stopExecution } = useThread()` instead.\n *\n * Hook that returns a function to stop the current thread's execution.\n * Must be used within a ThreadProvider.\n *\n * This hook automatically uses the thread ID from the ThreadProvider context,\n * so you don't need to pass it manually.\n *\n * @returns A function that stops the current thread's execution\n *\n * @throws Error if used outside of ThreadProvider\n *\n * @example\n * ```tsx\n * // NEW - Recommended\n * const { stopExecution } = useThread()\n * await stopExecution()\n *\n * // OLD - Deprecated\n * const stopThread = useStopThread()\n * await stopThread()\n * ```\n */\nexport function useStopThread(): () => Promise<void> {\n if (!hasWarned && process.env.NODE_ENV !== 'production') {\n hasWarned = true\n console.warn(\n '[DEPRECATED] useStopThread() is deprecated.\\n' +\n 'Use: const { stopExecution } = useThread()'\n )\n }\n let context: ReturnType<typeof useThreadContext>\n\n try {\n context = useThreadContext()\n } catch {\n throw new Error('useStopThread must be used within a ThreadProvider')\n }\n\n const { threadId } = context\n\n return useCallback(\n () => {\n return stopThreadService(threadId)\n },\n [threadId]\n )\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@standardagents/react",
3
- "version": "0.10.1-dev.8f03957",
3
+ "version": "0.10.1-dev.cea2b66",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "restricted",
@@ -21,7 +21,7 @@
21
21
  "README.md"
22
22
  ],
23
23
  "dependencies": {
24
- "@standardagents/client": "0.10.1-dev.8f03957"
24
+ "@standardagents/client": "0.10.1-dev.cea2b66"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "react": "^18.0.0 || ^19.0.0"