@standardagents/react 0.10.1-dev.b8746e9 → 0.10.1-dev.d2d335e

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/LICENSE.txt ADDED
@@ -0,0 +1,48 @@
1
+ PROPRIETARY SOFTWARE LICENSE
2
+
3
+ Copyright (c) 2024-2025 FormKit Inc. All Rights Reserved.
4
+
5
+ UNLICENSED - DO NOT USE
6
+
7
+ This software and associated documentation files (the "Software") are the sole
8
+ and exclusive property of FormKit Inc. ("FormKit").
9
+
10
+ USE RESTRICTIONS
11
+
12
+ The Software is UNLICENSED and proprietary. NO PERMISSION is granted to use,
13
+ copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
14
+ the Software, or to permit persons to whom the Software is furnished to do so,
15
+ under any circumstances, without prior written authorization from FormKit Inc.
16
+
17
+ UNAUTHORIZED USE PROHIBITED
18
+
19
+ Any use of this Software without a valid, written license agreement signed by
20
+ authorized officers of FormKit Inc. is strictly prohibited and constitutes
21
+ unauthorized use and infringement of FormKit's intellectual property rights.
22
+
23
+ LICENSING INQUIRIES
24
+
25
+ Organizations interested in licensing this Software should contact:
26
+ enterprise@formkit.com
27
+
28
+ A written license agreement must be executed before any use of this Software
29
+ is authorized.
30
+
31
+ NO WARRANTY
32
+
33
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
36
+ FORMKIT INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
37
+ AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
38
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39
+
40
+ GOVERNING LAW
41
+
42
+ This license shall be governed by and construed in accordance with the laws
43
+ of the jurisdiction in which FormKit Inc. is incorporated, without regard to
44
+ its conflict of law provisions.
45
+
46
+ FormKit Inc.
47
+ https://formkit.com
48
+ enterprise@formkit.com
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { AgentBuilderConfig, Message, ThreadMessage, ConnectionStatus as ConnectionStatus$1, SendMessagePayload, ThreadFile } from '@standardagents/client';
4
- export { AgentBuilderClient, AgentBuilderConfig, AttachmentRef, CreateThreadPayload, CustomEvent, ErrorEvent, FileUploadManager, GetMessagesOptions, LogDataEvent, LogStreamEvent, LogWebSocketCallbacks, Message, MessageChunkEvent, MessageDataEvent, MessageStreamEvent, MessageWebSocketCallbacks, SendMessagePayload, StoppedByUserEvent, Thread, ThreadConnectionCallbacks, ThreadConnectionManager, ThreadConnectionOptions, ThreadEvent, ThreadFile, ThreadMessage, WorkItem, WorkMessage, generatePendingFileId, isImageMimeType, messagesToFiles, parseAttachments, readFileAsDataUrl, transformToWorkblocks } from '@standardagents/client';
3
+ import { AgentBuilderConfig, Message, ThreadMessage, ConnectionStatus as ConnectionStatus$1, SendMessagePayload, ThreadFile, PendingAttachment } from '@standardagents/client';
4
+ export { AgentBuilderClient, AgentBuilderConfig, AttachmentPayload, AttachmentRef, CreateThreadPayload, CustomEvent, ErrorEvent, FileUploadManager, GetMessagesOptions, LogDataEvent, LogStreamEvent, LogWebSocketCallbacks, Message, MessageChunkEvent, MessageDataEvent, MessageStreamEvent, MessageWebSocketCallbacks, PendingAttachment, SendMessagePayload, StoppedByUserEvent, Thread, ThreadConnectionCallbacks, ThreadConnectionManager, ThreadConnectionOptions, ThreadEvent, ThreadFile, ThreadMessage, WorkItem, WorkMessage, generatePendingFileId, isImageMimeType, messagesToFiles, parseAttachments, readFileAsDataUrl, transformToWorkblocks } from '@standardagents/client';
5
5
 
6
6
  interface AgentBuilderProviderProps {
7
7
  config: AgentBuilderConfig;
@@ -67,13 +67,13 @@ interface ThreadContextValue {
67
67
  onEvent: <T = unknown>(eventType: string, listener: EventListener<T>) => () => void;
68
68
  /** Options passed to the provider */
69
69
  options: ThreadProviderOptions;
70
- /** Send a message to the thread */
71
- sendMessage: (payload: SendMessagePayload) => Promise<Message>;
70
+ /** Send a message to the thread (auto-includes pending attachments) */
71
+ sendMessage: (payload: Omit<SendMessagePayload, 'attachments'>) => Promise<Message>;
72
72
  /** Stop the current execution */
73
73
  stopExecution: () => Promise<void>;
74
74
  /** All files in the thread (pending uploads + committed from messages) */
75
75
  files: ThreadFile[];
76
- /** Add files and start uploading immediately */
76
+ /** Add files and start uploading immediately to filesystem */
77
77
  addFiles: (files: File[] | FileList) => void;
78
78
  /** Remove a pending file (cannot remove committed files) */
79
79
  removeFile: (id: string) => void;
@@ -83,6 +83,14 @@ interface ThreadContextValue {
83
83
  getThumbnailUrl: (file: ThreadFile) => string;
84
84
  /** Get preview URL - localPreviewUrl for pending images, thumbnail for committed */
85
85
  getPreviewUrl: (file: ThreadFile) => string | null;
86
+ /** Pending attachments to be sent with next message */
87
+ attachments: PendingAttachment[];
88
+ /** Add attachment(s) to be sent with next message (no upload, stored locally) */
89
+ addAttachment: (files: File | File[] | FileList) => void;
90
+ /** Remove a pending attachment */
91
+ removeAttachment: (id: string) => void;
92
+ /** Clear all pending attachments */
93
+ clearAttachments: () => void;
86
94
  }
87
95
  interface ThreadProviderProps {
88
96
  /** The thread ID to connect to */
package/dist/index.js CHANGED
@@ -97,6 +97,7 @@ var uploadManager = new FileUploadManager();
97
97
  var StaticContext = createContext(null);
98
98
  var MessagesContext = createContext(null);
99
99
  var FilesContext = createContext(null);
100
+ var AttachmentsContext = createContext(null);
100
101
  var ConnectionContext = createContext(null);
101
102
  createContext(null);
102
103
  function ThreadProvider({
@@ -130,6 +131,7 @@ function ThreadProvider({
130
131
  live ? "connecting" : "disconnected"
131
132
  );
132
133
  const [pendingFiles, setPendingFiles] = useState([]);
134
+ const [attachments, setAttachments] = useState([]);
133
135
  const committedFiles = useMemo(() => {
134
136
  return messagesToFiles(messages);
135
137
  }, [messages]);
@@ -144,6 +146,18 @@ function ThreadProvider({
144
146
  }, [messages, useWorkblocks]);
145
147
  const eventListenersRef = useRef(/* @__PURE__ */ new Map());
146
148
  const connectionManagerRef = useRef(null);
149
+ const fileToBase64 = useCallback((file) => {
150
+ return new Promise((resolve, reject) => {
151
+ const reader = new FileReader();
152
+ reader.onload = () => {
153
+ const result = reader.result;
154
+ const base64 = result.split(",")[1];
155
+ resolve(base64);
156
+ };
157
+ reader.onerror = () => reject(new Error("Failed to read file"));
158
+ reader.readAsDataURL(file);
159
+ });
160
+ }, []);
147
161
  const subscribeToEvent = useCallback(
148
162
  (eventType, listener) => {
149
163
  if (!eventListenersRef.current.has(eventType)) {
@@ -223,16 +237,93 @@ function ThreadProvider({
223
237
  },
224
238
  [threadId]
225
239
  );
240
+ const addAttachment = useCallback((input) => {
241
+ const files2 = input instanceof FileList ? Array.from(input) : Array.isArray(input) ? input : [input];
242
+ const newAttachments = files2.map((file) => {
243
+ const isImage = file.type.startsWith("image/");
244
+ return {
245
+ id: crypto.randomUUID(),
246
+ file,
247
+ name: file.name,
248
+ mimeType: file.type,
249
+ size: file.size,
250
+ isImage,
251
+ previewUrl: isImage ? URL.createObjectURL(file) : null
252
+ };
253
+ });
254
+ setAttachments((prev) => [...prev, ...newAttachments]);
255
+ }, []);
256
+ const removeAttachment = useCallback((id) => {
257
+ setAttachments((prev) => {
258
+ const attachment = prev.find((a) => a.id === id);
259
+ if (attachment?.previewUrl) {
260
+ URL.revokeObjectURL(attachment.previewUrl);
261
+ }
262
+ return prev.filter((a) => a.id !== id);
263
+ });
264
+ }, []);
265
+ const clearAttachments = useCallback(() => {
266
+ setAttachments((prev) => {
267
+ prev.forEach((a) => {
268
+ if (a.previewUrl) URL.revokeObjectURL(a.previewUrl);
269
+ });
270
+ return [];
271
+ });
272
+ }, []);
226
273
  const sendMessage2 = useCallback(
227
274
  async (payload) => {
275
+ const optimisticId = `optimistic-${crypto.randomUUID()}`;
276
+ const optimisticAttachments = attachments.map((a) => ({
277
+ id: a.id,
278
+ type: "file",
279
+ path: "",
280
+ // No path yet - will be assigned by server
281
+ name: a.name,
282
+ mimeType: a.mimeType,
283
+ size: a.size,
284
+ width: a.width,
285
+ height: a.height,
286
+ localPreviewUrl: a.previewUrl || void 0
287
+ }));
288
+ const optimisticMessage = {
289
+ id: optimisticId,
290
+ role: payload.role,
291
+ content: payload.content,
292
+ attachments: optimisticAttachments.length > 0 ? JSON.stringify(optimisticAttachments) : null,
293
+ created_at: Date.now() * 1e3,
294
+ // microseconds
295
+ status: "pending"
296
+ };
297
+ setMessages((prev) => [...prev, optimisticMessage]);
298
+ const currentAttachments = [...attachments];
299
+ setAttachments([]);
228
300
  try {
229
- return await clientRef.current.sendMessage(threadId, payload);
301
+ const attachmentPayloads = await Promise.all(
302
+ currentAttachments.map(async (a) => ({
303
+ name: a.name,
304
+ mimeType: a.mimeType,
305
+ data: await fileToBase64(a.file),
306
+ width: a.width,
307
+ height: a.height
308
+ }))
309
+ );
310
+ const result = await clientRef.current.sendMessage(threadId, {
311
+ ...payload,
312
+ attachments: attachmentPayloads.length > 0 ? attachmentPayloads : void 0
313
+ });
314
+ setMessages((prev) => prev.filter((m) => m.id !== optimisticId));
315
+ currentAttachments.forEach((a) => {
316
+ if (a.previewUrl) URL.revokeObjectURL(a.previewUrl);
317
+ });
318
+ return result;
230
319
  } catch (err) {
320
+ setAttachments(currentAttachments);
321
+ setMessages((prev) => prev.filter((m) => m.id !== optimisticId));
231
322
  setError(err instanceof Error ? err : new Error(String(err)));
232
323
  throw err;
233
324
  }
234
325
  },
235
- [threadId]
326
+ [threadId, attachments, fileToBase64]
236
327
  );
237
328
  const stopExecution = useCallback(async () => {
238
329
  try {
@@ -330,7 +421,10 @@ function ThreadProvider({
330
421
  removeFile,
331
422
  getFileUrl,
332
423
  getThumbnailUrl,
333
- getPreviewUrl
424
+ getPreviewUrl,
425
+ addAttachment,
426
+ removeAttachment,
427
+ clearAttachments
334
428
  }),
335
429
  [
336
430
  threadId,
@@ -346,7 +440,10 @@ function ThreadProvider({
346
440
  removeFile,
347
441
  getFileUrl,
348
442
  getThumbnailUrl,
349
- getPreviewUrl
443
+ getPreviewUrl,
444
+ addAttachment,
445
+ removeAttachment,
446
+ clearAttachments
350
447
  ]
351
448
  );
352
449
  const messagesValue = useMemo(
@@ -370,7 +467,13 @@ function ThreadProvider({
370
467
  }),
371
468
  [connectionStatus, error]
372
469
  );
373
- return /* @__PURE__ */ jsx(StaticContext.Provider, { value: staticValue, children: /* @__PURE__ */ jsx(MessagesContext.Provider, { value: messagesValue, children: /* @__PURE__ */ jsx(FilesContext.Provider, { value: filesValue, children: /* @__PURE__ */ jsx(ConnectionContext.Provider, { value: connectionValue, children }) }) }) });
470
+ const attachmentsValue = useMemo(
471
+ () => ({
472
+ attachments
473
+ }),
474
+ [attachments]
475
+ );
476
+ return /* @__PURE__ */ jsx(StaticContext.Provider, { value: staticValue, children: /* @__PURE__ */ jsx(MessagesContext.Provider, { value: messagesValue, children: /* @__PURE__ */ jsx(FilesContext.Provider, { value: filesValue, children: /* @__PURE__ */ jsx(AttachmentsContext.Provider, { value: attachmentsValue, children: /* @__PURE__ */ jsx(ConnectionContext.Provider, { value: connectionValue, children }) }) }) }) });
374
477
  }
375
478
  function useStaticContext() {
376
479
  const context = useContext(StaticContext);
@@ -400,10 +503,18 @@ function useConnectionContext() {
400
503
  }
401
504
  return context;
402
505
  }
506
+ function useAttachmentsContext() {
507
+ const context = useContext(AttachmentsContext);
508
+ if (!context) {
509
+ throw new Error("useThread must be used within a ThreadProvider");
510
+ }
511
+ return context;
512
+ }
403
513
  function useThreadContextInternal() {
404
514
  const static_ = useStaticContext();
405
515
  const messages_ = useMessagesContext();
406
516
  const files_ = useFilesContext();
517
+ const attachments_ = useAttachmentsContext();
407
518
  const connection_ = useConnectionContext();
408
519
  return {
409
520
  threadId: static_.threadId,
@@ -412,11 +523,18 @@ function useThreadContextInternal() {
412
523
  stopExecution: static_.stopExecution,
413
524
  subscribeToEvent: static_.subscribeToEvent,
414
525
  onEvent: static_.subscribeToEvent,
526
+ // File management (uploads to filesystem)
415
527
  addFiles: static_.addFiles,
416
528
  removeFile: static_.removeFile,
417
529
  getFileUrl: static_.getFileUrl,
418
530
  getThumbnailUrl: static_.getThumbnailUrl,
419
531
  getPreviewUrl: static_.getPreviewUrl,
532
+ // Attachment management (sent inline with messages)
533
+ addAttachment: static_.addAttachment,
534
+ removeAttachment: static_.removeAttachment,
535
+ clearAttachments: static_.clearAttachments,
536
+ attachments: attachments_.attachments,
537
+ // Messages
420
538
  messages: messages_.messages,
421
539
  workblocks: messages_.workblocks,
422
540
  loading: messages_.loading,
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","files","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 PendingAttachment,\n type AttachmentPayload,\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: Omit<SendMessagePayload, 'attachments'>) => Promise<Message>\n stopExecution: () => Promise<void>\n subscribeToEvent: <T = unknown>(\n eventType: string,\n listener: EventListener<T>\n ) => () => void\n // File management (uploads to filesystem)\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 // Attachment management (sent inline with messages)\n addAttachment: (files: File | File[] | FileList) => void\n removeAttachment: (id: string) => void\n clearAttachments: () => void\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 * Attachments context - pending attachments to send with next message\n */\ninterface AttachmentsContextValue {\n attachments: PendingAttachment[]\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 AttachmentsContext = createContext<AttachmentsContextValue | 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 (auto-includes pending attachments) */\n sendMessage: (payload: Omit<SendMessagePayload, 'attachments'>) => Promise<Message>\n /** Stop the current execution */\n stopExecution: () => Promise<void>\n\n // File management (uploads to filesystem, NOT sent to LLM)\n /** All files in the thread (pending uploads + committed from messages) */\n files: ThreadFile[]\n /** Add files and start uploading immediately to filesystem */\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 // Attachment management (sent inline with messages to LLM)\n /** Pending attachments to be sent with next message */\n attachments: PendingAttachment[]\n /** Add attachment(s) to be sent with next message (no upload, stored locally) */\n addAttachment: (files: File | File[] | FileList) => void\n /** Remove a pending attachment */\n removeAttachment: (id: string) => void\n /** Clear all pending attachments */\n clearAttachments: () => void\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 const [attachments, setAttachments] = useState<PendingAttachment[]>([])\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 * Convert a File to base64 string\n */\n const fileToBase64 = useCallback((file: File): Promise<string> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => {\n const result = reader.result as string\n // Remove data URL prefix (e.g., \"data:image/jpeg;base64,\")\n const base64 = result.split(\",\")[1]\n resolve(base64)\n }\n reader.onerror = () => reject(new Error(\"Failed to read file\"))\n reader.readAsDataURL(file)\n })\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 // Attachment management (for sending with messages, NOT uploaded to filesystem)\n const addAttachment = useCallback((input: File | File[] | FileList) => {\n const files =\n input instanceof FileList\n ? Array.from(input)\n : Array.isArray(input)\n ? input\n : [input]\n\n const newAttachments: PendingAttachment[] = files.map((file) => {\n const isImage = file.type.startsWith(\"image/\")\n return {\n id: crypto.randomUUID(),\n file,\n name: file.name,\n mimeType: file.type,\n size: file.size,\n isImage,\n previewUrl: isImage ? URL.createObjectURL(file) : null,\n }\n })\n\n setAttachments((prev) => [...prev, ...newAttachments])\n }, [])\n\n const removeAttachment = useCallback((id: string) => {\n setAttachments((prev) => {\n const attachment = prev.find((a) => a.id === id)\n if (attachment?.previewUrl) {\n URL.revokeObjectURL(attachment.previewUrl)\n }\n return prev.filter((a) => a.id !== id)\n })\n }, [])\n\n const clearAttachments = useCallback(() => {\n setAttachments((prev) => {\n // Revoke all preview URLs\n prev.forEach((a) => {\n if (a.previewUrl) URL.revokeObjectURL(a.previewUrl)\n })\n return []\n })\n }, [])\n\n const sendMessage = useCallback(\n async (payload: Omit<SendMessagePayload, \"attachments\">): Promise<Message> => {\n // Build optimistic message with attachment previews\n const optimisticId = `optimistic-${crypto.randomUUID()}`\n const optimisticAttachments = attachments.map((a) => ({\n id: a.id,\n type: \"file\" as const,\n path: \"\", // No path yet - will be assigned by server\n name: a.name,\n mimeType: a.mimeType,\n size: a.size,\n width: a.width,\n height: a.height,\n localPreviewUrl: a.previewUrl || undefined,\n }))\n\n const optimisticMessage: Message = {\n id: optimisticId,\n role: payload.role,\n content: payload.content,\n attachments:\n optimisticAttachments.length > 0\n ? JSON.stringify(optimisticAttachments)\n : null,\n created_at: Date.now() * 1000, // microseconds\n status: \"pending\",\n }\n\n // Add optimistic message immediately\n setMessages((prev) => [...prev, optimisticMessage])\n\n // Capture current attachments before clearing\n const currentAttachments = [...attachments]\n\n // Clear attachments immediately (optimistic)\n setAttachments([])\n\n try {\n // Convert attachments to base64 for API\n const attachmentPayloads: AttachmentPayload[] = await Promise.all(\n currentAttachments.map(async (a) => ({\n name: a.name,\n mimeType: a.mimeType,\n data: await fileToBase64(a.file),\n width: a.width,\n height: a.height,\n }))\n )\n\n const result = await clientRef.current.sendMessage(threadId, {\n ...payload,\n attachments: attachmentPayloads.length > 0 ? attachmentPayloads : undefined,\n })\n\n // Remove optimistic message - real one will come via WebSocket\n setMessages((prev) => prev.filter((m) => m.id !== optimisticId))\n\n // Revoke object URLs now that we're done\n currentAttachments.forEach((a) => {\n if (a.previewUrl) URL.revokeObjectURL(a.previewUrl)\n })\n\n return result\n } catch (err) {\n // Restore attachments on error\n setAttachments(currentAttachments)\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, attachments, fileToBase64]\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 addAttachment,\n removeAttachment,\n clearAttachments,\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 addAttachment,\n removeAttachment,\n clearAttachments,\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 const attachmentsValue = useMemo(\n (): AttachmentsContextValue => ({\n attachments,\n }),\n [attachments]\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 <AttachmentsContext.Provider value={attachmentsValue}>\n <ConnectionContext.Provider value={connectionValue}>\n {children}\n </ConnectionContext.Provider>\n </AttachmentsContext.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\nfunction useAttachmentsContext(): AttachmentsContextValue {\n const context = useContext(AttachmentsContext)\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 attachments_ = useAttachmentsContext()\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 // File management (uploads to filesystem)\n addFiles: static_.addFiles,\n removeFile: static_.removeFile,\n getFileUrl: static_.getFileUrl,\n getThumbnailUrl: static_.getThumbnailUrl,\n getPreviewUrl: static_.getPreviewUrl,\n // Attachment management (sent inline with messages)\n addAttachment: static_.addAttachment,\n removeAttachment: static_.removeAttachment,\n clearAttachments: static_.clearAttachments,\n attachments: attachments_.attachments,\n // Messages\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.b8746e9",
3
+ "version": "0.10.1-dev.d2d335e",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "restricted",
@@ -20,16 +20,8 @@
20
20
  "dist",
21
21
  "README.md"
22
22
  ],
23
- "scripts": {
24
- "build": "tsup",
25
- "dev": "tsup --watch",
26
- "typecheck": "tsc --noEmit",
27
- "test": "cd ../.. && vitest --dir packages/react",
28
- "test:run": "cd ../.. && vitest run --dir packages/react",
29
- "test:ui": "cd ../.. && vitest --ui --dir packages/react"
30
- },
31
23
  "dependencies": {
32
- "@standardagents/client": "workspace:*"
24
+ "@standardagents/client": "0.10.1-dev.d2d335e"
33
25
  },
34
26
  "peerDependencies": {
35
27
  "react": "^18.0.0 || ^19.0.0"
@@ -50,5 +42,13 @@
50
42
  "agent"
51
43
  ],
52
44
  "author": "FormKit Inc.",
53
- "license": "UNLICENSED"
54
- }
45
+ "license": "UNLICENSED",
46
+ "scripts": {
47
+ "build": "tsup",
48
+ "dev": "tsup --watch",
49
+ "typecheck": "tsc --noEmit",
50
+ "test": "cd ../.. && vitest --dir packages/react",
51
+ "test:run": "cd ../.. && vitest run --dir packages/react",
52
+ "test:ui": "cd ../.. && vitest --ui --dir packages/react"
53
+ }
54
+ }