@standardagents/react 0.8.5 → 0.9.1
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.d.ts +7 -1
- package/dist/index.js +83 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -152,6 +152,10 @@ declare function AgentBuilderProvider({ config, children }: AgentBuilderProvider
|
|
|
152
152
|
* Event listener callback type
|
|
153
153
|
*/
|
|
154
154
|
type EventListener<T = unknown> = (data: T) => void;
|
|
155
|
+
/**
|
|
156
|
+
* WebSocket connection status
|
|
157
|
+
*/
|
|
158
|
+
type ConnectionStatus = 'connecting' | 'connected' | 'disconnected';
|
|
155
159
|
/**
|
|
156
160
|
* Thread context value
|
|
157
161
|
*/
|
|
@@ -164,6 +168,8 @@ interface ThreadContextValue {
|
|
|
164
168
|
loading: boolean;
|
|
165
169
|
/** Any error that occurred */
|
|
166
170
|
error: Error | null;
|
|
171
|
+
/** WebSocket connection status */
|
|
172
|
+
connectionStatus: ConnectionStatus;
|
|
167
173
|
/** Subscribe to a specific event type */
|
|
168
174
|
subscribeToEvent: <T = unknown>(eventType: string, listener: EventListener<T>) => () => void;
|
|
169
175
|
/** Options passed to the provider */
|
|
@@ -454,4 +460,4 @@ interface StopThreadOptions {
|
|
|
454
460
|
*/
|
|
455
461
|
declare function stopThread(id: string, options?: StopThreadOptions): Promise<void>;
|
|
456
462
|
|
|
457
|
-
export { type AgentBuilderConfig, AgentBuilderProvider, type CustomEvent, type ErrorEvent, type GetMessagesOptions, type LogDataEvent, type LogStreamEvent, type LogWebSocketCallbacks, type Message, type MessageChunkEvent, type MessageDataEvent, type MessageStreamEvent, type MessageWebSocketCallbacks, type SendMessagePayload, type StoppedByUserEvent, type Thread, type ThreadEvent, type ThreadMessage, ThreadProvider, type ThreadProviderOptions, type UseThreadOptions, type WorkItem, type WorkMessage, onThreadEvent, sendMessage, stopThread, useSendMessage, useStopThread, useThread, useThreadContext, useThreadEvent, useThreadId };
|
|
463
|
+
export { type AgentBuilderConfig, AgentBuilderProvider, type ConnectionStatus, type CustomEvent, type ErrorEvent, type GetMessagesOptions, type LogDataEvent, type LogStreamEvent, type LogWebSocketCallbacks, type Message, type MessageChunkEvent, type MessageDataEvent, type MessageStreamEvent, type MessageWebSocketCallbacks, type SendMessagePayload, type StoppedByUserEvent, type Thread, type ThreadEvent, type ThreadMessage, ThreadProvider, type ThreadProviderOptions, type UseThreadOptions, type WorkItem, type WorkMessage, onThreadEvent, sendMessage, stopThread, useSendMessage, useStopThread, useThread, useThreadContext, useThreadEvent, useThreadId };
|
package/dist/index.js
CHANGED
|
@@ -116,8 +116,10 @@ var AgentBuilderClient = class {
|
|
|
116
116
|
};
|
|
117
117
|
ws.onerror = (event) => {
|
|
118
118
|
console.error("WebSocket error:", event);
|
|
119
|
+
callbacks.onError?.({ type: "error", error: "WebSocket connection error" });
|
|
119
120
|
};
|
|
120
|
-
ws.onclose = () => {
|
|
121
|
+
ws.onclose = (event) => {
|
|
122
|
+
console.log(`[AgentBuilderClient] Message WebSocket closed - code: ${event.code}, reason: ${event.reason || "none"}, wasClean: ${event.wasClean}`);
|
|
121
123
|
callbacks.onClose?.();
|
|
122
124
|
};
|
|
123
125
|
return ws;
|
|
@@ -291,6 +293,9 @@ function ThreadProvider({
|
|
|
291
293
|
const [messages, setMessages] = useState([]);
|
|
292
294
|
const [loading, setLoading] = useState(preload);
|
|
293
295
|
const [error, setError] = useState(null);
|
|
296
|
+
const [connectionStatus, setConnectionStatus] = useState(
|
|
297
|
+
live ? "connecting" : "disconnected"
|
|
298
|
+
);
|
|
294
299
|
const eventListenersRef = useRef(/* @__PURE__ */ new Map());
|
|
295
300
|
const wsRef = useRef(null);
|
|
296
301
|
const reconnectAttempts = useRef(0);
|
|
@@ -298,21 +303,24 @@ function ThreadProvider({
|
|
|
298
303
|
const heartbeatIntervalRef = useRef(null);
|
|
299
304
|
const isReconnectingRef = useRef(false);
|
|
300
305
|
const isMountedRef = useRef(true);
|
|
301
|
-
const subscribeToEvent = useCallback(
|
|
302
|
-
|
|
303
|
-
eventListenersRef.current.
|
|
304
|
-
|
|
305
|
-
eventListenersRef.current.get(eventType).add(listener);
|
|
306
|
-
return () => {
|
|
307
|
-
const listeners = eventListenersRef.current.get(eventType);
|
|
308
|
-
if (listeners) {
|
|
309
|
-
listeners.delete(listener);
|
|
310
|
-
if (listeners.size === 0) {
|
|
311
|
-
eventListenersRef.current.delete(eventType);
|
|
312
|
-
}
|
|
306
|
+
const subscribeToEvent = useCallback(
|
|
307
|
+
(eventType, listener) => {
|
|
308
|
+
if (!eventListenersRef.current.has(eventType)) {
|
|
309
|
+
eventListenersRef.current.set(eventType, /* @__PURE__ */ new Set());
|
|
313
310
|
}
|
|
314
|
-
|
|
315
|
-
|
|
311
|
+
eventListenersRef.current.get(eventType).add(listener);
|
|
312
|
+
return () => {
|
|
313
|
+
const listeners = eventListenersRef.current.get(eventType);
|
|
314
|
+
if (listeners) {
|
|
315
|
+
listeners.delete(listener);
|
|
316
|
+
if (listeners.size === 0) {
|
|
317
|
+
eventListenersRef.current.delete(eventType);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
},
|
|
322
|
+
[]
|
|
323
|
+
);
|
|
316
324
|
const dispatchEvent = useCallback((eventType, data) => {
|
|
317
325
|
const listeners = eventListenersRef.current.get(eventType);
|
|
318
326
|
if (listeners) {
|
|
@@ -345,13 +353,37 @@ function ThreadProvider({
|
|
|
345
353
|
}
|
|
346
354
|
}, 3e4);
|
|
347
355
|
}, []);
|
|
356
|
+
useEffect(() => {
|
|
357
|
+
if (!live || !threadId) return;
|
|
358
|
+
console.log(
|
|
359
|
+
`[ThreadProvider] useEffect running - threadId: ${threadId}, live: ${live}`
|
|
360
|
+
);
|
|
361
|
+
connectWebSocket();
|
|
362
|
+
return () => {
|
|
363
|
+
console.log(
|
|
364
|
+
`[ThreadProvider] useEffect cleanup - threadId: ${threadId}, live: ${live}`
|
|
365
|
+
);
|
|
366
|
+
clearTimers();
|
|
367
|
+
if (wsRef.current) {
|
|
368
|
+
wsRef.current.close();
|
|
369
|
+
wsRef.current = null;
|
|
370
|
+
}
|
|
371
|
+
reconnectAttempts.current = 0;
|
|
372
|
+
isReconnectingRef.current = false;
|
|
373
|
+
};
|
|
374
|
+
}, [threadId, live]);
|
|
348
375
|
const connectWebSocket = useCallback(() => {
|
|
349
376
|
if (!live || !threadId || !isMountedRef.current) return;
|
|
377
|
+
console.log(`[ThreadProvider] Connecting WebSocket for thread ${threadId}`);
|
|
378
|
+
setConnectionStatus("connecting");
|
|
350
379
|
const ws = clientRef.current.connectMessageWebSocket(
|
|
351
380
|
threadId,
|
|
352
381
|
{
|
|
353
382
|
onOpen: () => {
|
|
354
|
-
console.log(
|
|
383
|
+
console.log(
|
|
384
|
+
`[ThreadProvider] WebSocket connected for thread ${threadId}`
|
|
385
|
+
);
|
|
386
|
+
setConnectionStatus("connected");
|
|
355
387
|
reconnectAttempts.current = 0;
|
|
356
388
|
isReconnectingRef.current = false;
|
|
357
389
|
startHeartbeat(ws);
|
|
@@ -385,20 +417,29 @@ function ThreadProvider({
|
|
|
385
417
|
onError: (event) => {
|
|
386
418
|
console.error("[ThreadProvider] WebSocket error:", event.error);
|
|
387
419
|
setError(new Error(event.error));
|
|
420
|
+
setConnectionStatus("disconnected");
|
|
388
421
|
},
|
|
389
422
|
onClose: () => {
|
|
390
423
|
console.log("[ThreadProvider] WebSocket closed");
|
|
391
424
|
clearTimers();
|
|
392
425
|
if (isMountedRef.current && !isReconnectingRef.current) {
|
|
393
426
|
isReconnectingRef.current = true;
|
|
394
|
-
|
|
427
|
+
setConnectionStatus("connecting");
|
|
428
|
+
const delay = Math.min(
|
|
429
|
+
1e3 * Math.pow(2, reconnectAttempts.current),
|
|
430
|
+
3e4
|
|
431
|
+
);
|
|
395
432
|
reconnectAttempts.current++;
|
|
396
|
-
console.log(
|
|
433
|
+
console.log(
|
|
434
|
+
`[ThreadProvider] Reconnecting in ${delay}ms (attempt ${reconnectAttempts.current})`
|
|
435
|
+
);
|
|
397
436
|
reconnectTimeoutRef.current = setTimeout(() => {
|
|
398
437
|
if (isMountedRef.current) {
|
|
399
438
|
connectWebSocket();
|
|
400
439
|
}
|
|
401
440
|
}, delay);
|
|
441
|
+
} else {
|
|
442
|
+
setConnectionStatus("disconnected");
|
|
402
443
|
}
|
|
403
444
|
}
|
|
404
445
|
},
|
|
@@ -408,7 +449,15 @@ function ThreadProvider({
|
|
|
408
449
|
}
|
|
409
450
|
);
|
|
410
451
|
wsRef.current = ws;
|
|
411
|
-
}, [
|
|
452
|
+
}, [
|
|
453
|
+
threadId,
|
|
454
|
+
live,
|
|
455
|
+
depth,
|
|
456
|
+
includeSilent,
|
|
457
|
+
dispatchEvent,
|
|
458
|
+
startHeartbeat,
|
|
459
|
+
clearTimers
|
|
460
|
+
]);
|
|
412
461
|
useEffect(() => {
|
|
413
462
|
if (!preload || !threadId) return;
|
|
414
463
|
const fetchMessages = async () => {
|
|
@@ -422,7 +471,9 @@ function ThreadProvider({
|
|
|
422
471
|
setMessages(fetchedMessages);
|
|
423
472
|
} catch (err) {
|
|
424
473
|
console.error("Failed to fetch messages:", err);
|
|
425
|
-
setError(
|
|
474
|
+
setError(
|
|
475
|
+
err instanceof Error ? err : new Error("Failed to fetch messages")
|
|
476
|
+
);
|
|
426
477
|
setMessages([]);
|
|
427
478
|
} finally {
|
|
428
479
|
setLoading(false);
|
|
@@ -436,25 +487,13 @@ function ThreadProvider({
|
|
|
436
487
|
isMountedRef.current = false;
|
|
437
488
|
};
|
|
438
489
|
}, []);
|
|
439
|
-
useEffect(() => {
|
|
440
|
-
if (!live || !threadId) return;
|
|
441
|
-
connectWebSocket();
|
|
442
|
-
return () => {
|
|
443
|
-
clearTimers();
|
|
444
|
-
if (wsRef.current) {
|
|
445
|
-
wsRef.current.close();
|
|
446
|
-
wsRef.current = null;
|
|
447
|
-
}
|
|
448
|
-
reconnectAttempts.current = 0;
|
|
449
|
-
isReconnectingRef.current = false;
|
|
450
|
-
};
|
|
451
|
-
}, [threadId, live, connectWebSocket, clearTimers]);
|
|
452
490
|
const contextValue = useMemo(
|
|
453
491
|
() => ({
|
|
454
492
|
threadId,
|
|
455
493
|
messages,
|
|
456
494
|
loading,
|
|
457
495
|
error,
|
|
496
|
+
connectionStatus,
|
|
458
497
|
subscribeToEvent,
|
|
459
498
|
options: {
|
|
460
499
|
depth,
|
|
@@ -462,7 +501,17 @@ function ThreadProvider({
|
|
|
462
501
|
...options
|
|
463
502
|
}
|
|
464
503
|
}),
|
|
465
|
-
[
|
|
504
|
+
[
|
|
505
|
+
threadId,
|
|
506
|
+
messages,
|
|
507
|
+
loading,
|
|
508
|
+
error,
|
|
509
|
+
connectionStatus,
|
|
510
|
+
subscribeToEvent,
|
|
511
|
+
depth,
|
|
512
|
+
includeSilent,
|
|
513
|
+
options
|
|
514
|
+
]
|
|
466
515
|
);
|
|
467
516
|
return /* @__PURE__ */ jsx(ThreadContext.Provider, { value: contextValue, children });
|
|
468
517
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/client.ts","../src/services/sendMessage.ts","../src/services/stopThread.ts","../src/context/AgentBuilderProvider.tsx","../src/context/ThreadProvider.tsx","../src/utils/workblocks.ts","../src/hooks/useThread.ts","../src/hooks/onThreadEvent.ts","../src/hooks/useSendMessage.ts","../src/hooks/useStopThread.ts"],"names":["globalEndpoint","createContext","useEffect","useMemo","jsx","useContext","useState","useCallback"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n Message,\n Thread,\n SendMessagePayload,\n GetMessagesOptions,\n MessageWebSocketCallbacks,\n LogWebSocketCallbacks,\n MessageStreamEvent,\n LogStreamEvent,\n ThreadEvent,\n} from '../types'\n\nexport class AgentBuilderClient {\n private endpoint: string\n private token: string | null\n\n constructor(endpoint: string) {\n // Normalize endpoint by removing trailing slash\n this.endpoint = endpoint.replace(/\\/$/, '')\n\n // Read auth token from localStorage\n this.token = typeof localStorage !== 'undefined'\n ? localStorage.getItem('agentbuilder_auth_token')\n : null\n }\n\n /**\n * Get thread metadata\n */\n async getThread(id: string): Promise<Thread> {\n const response = await fetch(`${this.endpoint}/threads/${id}`, {\n method: 'GET',\n headers: this.getHeaders(),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to get thread: ${response.statusText}`)\n }\n\n return response.json()\n }\n\n /**\n * Get messages from a thread with optional pagination and filtering\n */\n async getMessages(\n id: string,\n options: GetMessagesOptions = {}\n ): Promise<Message[]> {\n const params = new URLSearchParams()\n\n if (options.limit !== undefined) params.set('limit', String(options.limit))\n if (options.offset !== undefined) params.set('offset', String(options.offset))\n if (options.depth !== undefined) params.set('depth', String(options.depth))\n if (options.includeSilent !== undefined) params.set('includeSilent', String(options.includeSilent))\n\n const queryString = params.toString()\n const url = `${this.endpoint}/threads/${id}/messages${queryString ? `?${queryString}` : ''}`\n\n const response = await fetch(url, {\n method: 'GET',\n headers: this.getHeaders(),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to get messages: ${response.statusText}`)\n }\n\n const data = await response.json()\n return data.messages || []\n }\n\n /**\n * Send a message to a thread\n */\n async sendMessage(\n id: string,\n payload: SendMessagePayload\n ): Promise<Message> {\n const response = await fetch(`${this.endpoint}/threads/${id}/message`, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json',\n },\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\n /**\n * Stop execution of a thread\n */\n async stopExecution(id: string): Promise<void> {\n const response = await fetch(`${this.endpoint}/threads/${id}/stop`, {\n method: 'POST',\n headers: this.getHeaders(),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to stop execution: ${response.statusText}`)\n }\n\n await response.json()\n }\n\n /**\n * Connect to message WebSocket for real-time message updates\n */\n connectMessageWebSocket(\n id: string,\n callbacks: MessageWebSocketCallbacks = {},\n options: { includeSilent?: boolean; depth?: number } = {}\n ): WebSocket {\n const params = new URLSearchParams()\n\n if (this.token) params.set('token', this.token)\n if (options.includeSilent !== undefined) params.set('includeSilent', String(options.includeSilent))\n if (options.depth !== undefined) params.set('depth', String(options.depth))\n\n const wsProtocol = this.endpoint.startsWith('https') ? 'wss' : 'ws'\n const wsEndpoint = this.endpoint.replace(/^https?/, wsProtocol)\n const url = `${wsEndpoint}/threads/${id}/stream?${params.toString()}`\n\n const ws = new WebSocket(url)\n\n ws.onopen = () => {\n callbacks.onOpen?.()\n }\n\n ws.onmessage = (event) => {\n try {\n // Handle pong response from heartbeat ping\n if (typeof event.data === 'string' && event.data === 'pong') {\n return\n }\n\n const data = JSON.parse(event.data) as MessageStreamEvent\n\n switch (data.type) {\n case 'message_data':\n callbacks.onMessage?.(data)\n break\n case 'message_chunk':\n callbacks.onChunk?.(data)\n break\n case 'event':\n callbacks.onEvent?.(data as ThreadEvent)\n break\n case 'error':\n callbacks.onError?.(data)\n break\n }\n } catch (error) {\n console.error('Failed to parse WebSocket message:', error)\n }\n }\n\n ws.onerror = (event) => {\n console.error('WebSocket error:', event)\n }\n\n ws.onclose = () => {\n callbacks.onClose?.()\n }\n\n return ws\n }\n\n /**\n * Connect to log WebSocket for custom events\n */\n connectLogWebSocket(\n id: string,\n callbacks: LogWebSocketCallbacks = {}\n ): WebSocket {\n const params = new URLSearchParams()\n\n if (this.token) params.set('token', this.token)\n\n const wsProtocol = this.endpoint.startsWith('https') ? 'wss' : 'ws'\n const wsEndpoint = this.endpoint.replace(/^https?/, wsProtocol)\n const url = `${wsEndpoint}/threads/${id}?${params.toString()}`\n\n const ws = new WebSocket(url)\n\n ws.onopen = () => {\n callbacks.onOpen?.()\n }\n\n ws.onmessage = (event) => {\n try {\n // Handle pong response from heartbeat ping\n if (typeof event.data === 'string' && event.data === 'pong') {\n return\n }\n\n const data = JSON.parse(event.data) as LogStreamEvent\n\n switch (data.type) {\n case 'log_data':\n callbacks.onLog?.(data)\n break\n case 'custom':\n callbacks.onCustom?.(data)\n break\n case 'stopped_by_user':\n callbacks.onStopped?.(data)\n break\n }\n } catch (error) {\n console.error('Failed to parse WebSocket message:', error)\n }\n }\n\n ws.onerror = (event) => {\n console.error('WebSocket error:', event)\n }\n\n ws.onclose = () => {\n callbacks.onClose?.()\n }\n\n return ws\n }\n\n /**\n * Get headers for HTTP requests\n */\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {}\n\n if (this.token) {\n headers['Authorization'] = `Bearer ${this.token}`\n }\n\n return headers\n }\n}\n","import type { SendMessagePayload, Message } from '../types'\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}/message`, {\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 } from '../services/client'\nimport { __setGlobalEndpoint } from '../services/sendMessage'\nimport { __setGlobalEndpointForStop } from '../services/stopThread'\nimport type { AgentBuilderConfig } from '../types'\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 { useAgentBuilderClient, useAgentBuilderConfig } from './AgentBuilderProvider'\nimport { AgentBuilderClient } from '../services/client'\nimport type { Message, ThreadEvent, ThreadProviderOptions } from '../types'\n\n/**\n * Event listener callback type\n */\ntype EventListener<T = unknown> = (data: T) => void\n\n/**\n * Thread context value\n */\ninterface ThreadContextValue {\n /** The thread ID */\n threadId: string\n /** Current messages in the thread */\n messages: Message[]\n /** Whether messages are currently loading */\n loading: boolean\n /** Any error that occurred */\n error: Error | null\n /** Subscribe to a specific event type */\n subscribeToEvent: <T = unknown>(eventType: string, listener: EventListener<T>) => () => void\n /** Options passed to the provider */\n options: ThreadProviderOptions\n}\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 /** 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 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 // State\n const [messages, setMessages] = useState<Message[]>([])\n const [loading, setLoading] = useState(preload)\n const [error, setError] = useState<Error | null>(null)\n\n // Event listeners registry\n const eventListenersRef = useRef<Map<string, Set<EventListener>>>(new Map())\n\n // WebSocket ref\n const wsRef = useRef<WebSocket | null>(null)\n\n // Reconnection state\n const reconnectAttempts = useRef<number>(0)\n const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n const heartbeatIntervalRef = useRef<NodeJS.Timeout | null>(null)\n const isReconnectingRef = useRef<boolean>(false)\n const isMountedRef = useRef<boolean>(true)\n\n /**\n * Subscribe to a specific event type\n */\n const subscribeToEvent = useCallback(<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 unsubscribe function\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 * Dispatch event to all registered listeners\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 /**\n * Clear all timers and cleanup\n */\n const clearTimers = useCallback(() => {\n if (reconnectTimeoutRef.current) {\n clearTimeout(reconnectTimeoutRef.current)\n reconnectTimeoutRef.current = null\n }\n if (heartbeatIntervalRef.current) {\n clearInterval(heartbeatIntervalRef.current)\n heartbeatIntervalRef.current = null\n }\n }, [])\n\n /**\n * Start heartbeat to keep connection alive\n */\n const startHeartbeat = useCallback((ws: WebSocket) => {\n // Clear any existing heartbeat\n if (heartbeatIntervalRef.current) {\n clearInterval(heartbeatIntervalRef.current)\n }\n\n // Send ping every 30 seconds\n heartbeatIntervalRef.current = setInterval(() => {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send('ping')\n }\n }, 30000)\n }, [])\n\n /**\n * Connect to WebSocket with error handling\n */\n const connectWebSocket = useCallback(() => {\n if (!live || !threadId || !isMountedRef.current) return\n\n const ws = clientRef.current.connectMessageWebSocket(\n threadId,\n {\n onOpen: () => {\n console.log(`[ThreadProvider] WebSocket connected for thread ${threadId}`)\n reconnectAttempts.current = 0\n isReconnectingRef.current = false\n startHeartbeat(ws)\n },\n onMessage: (event) => {\n setMessages((prev) => {\n // Check if message already exists\n const exists = prev.some((m) => m.id === event.data.id)\n if (exists) {\n // Update existing message\n return prev.map((m) => (m.id === event.data.id ? event.data : m))\n } else {\n // Add new message\n return [...prev, event.data]\n }\n })\n },\n onChunk: (event) => {\n // Handle streaming chunks\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 // Dispatch custom events to subscribers\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 onClose: () => {\n console.log('[ThreadProvider] WebSocket closed')\n clearTimers()\n\n // Only attempt to reconnect if still mounted and not already reconnecting\n if (isMountedRef.current && !isReconnectingRef.current) {\n isReconnectingRef.current = true\n const delay = Math.min(1000 * Math.pow(2, reconnectAttempts.current), 30000)\n reconnectAttempts.current++\n\n console.log(`[ThreadProvider] Reconnecting in ${delay}ms (attempt ${reconnectAttempts.current})`)\n\n reconnectTimeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) {\n connectWebSocket()\n }\n }, delay)\n }\n },\n },\n {\n depth,\n includeSilent,\n }\n )\n\n wsRef.current = ws\n }, [threadId, live, depth, includeSilent, dispatchEvent, startHeartbeat, clearTimers])\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(err instanceof Error ? err : new Error('Failed to fetch messages'))\n setMessages([])\n } finally {\n setLoading(false)\n }\n }\n\n fetchMessages()\n }, [threadId, preload, depth, includeSilent])\n\n // Track component mount state\n useEffect(() => {\n isMountedRef.current = true\n return () => {\n isMountedRef.current = false\n }\n }, [])\n\n // Set up WebSocket connection\n useEffect(() => {\n if (!live || !threadId) return\n\n connectWebSocket()\n\n return () => {\n // Clean up on unmount or thread change\n clearTimers()\n if (wsRef.current) {\n wsRef.current.close()\n wsRef.current = null\n }\n reconnectAttempts.current = 0\n isReconnectingRef.current = false\n }\n }, [threadId, live, connectWebSocket, clearTimers])\n\n // Memoize context value\n const contextValue = useMemo(\n (): ThreadContextValue => ({\n threadId,\n messages,\n loading,\n error,\n subscribeToEvent,\n options: {\n depth,\n includeSilent,\n ...options,\n },\n }),\n [threadId, messages, loading, error, subscribeToEvent, depth, includeSilent, options]\n )\n\n return (\n <ThreadContext.Provider value={contextValue}>\n {children}\n </ThreadContext.Provider>\n )\n}\n\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 const context = useContext(ThreadContext)\n\n if (!context) {\n throw new Error('useThreadContext must be used within a ThreadProvider')\n }\n\n return context\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 useThreadContext().threadId\n}\n","import type { Message, WorkMessage, WorkItem, ThreadMessage } from '../types'\n\n/**\n * Transform a flat list of messages into a list with workblocks.\n * Groups consecutive assistant tool_calls and their tool results into WorkMessage objects.\n *\n * A workblock starts when an assistant message has tool_calls,\n * and includes all subsequent tool messages until:\n * - A non-tool message appears\n * - Another assistant message without tool_calls appears\n */\nexport function transformToWorkblocks(messages: Message[]): ThreadMessage[] {\n if (messages.length === 0) {\n return []\n }\n\n const result: ThreadMessage[] = []\n let i = 0\n\n while (i < messages.length) {\n const message = messages[i]\n\n // Check if this is an assistant message with tool_calls\n if (message.role === 'assistant' && message.tool_calls) {\n // Try to parse tool_calls\n let toolCalls: any[]\n try {\n toolCalls = JSON.parse(message.tool_calls)\n } catch (error) {\n // If we can't parse tool_calls, treat it as a regular message\n result.push(message)\n i++\n continue\n }\n\n // Start building a workblock\n const workItems: WorkItem[] = []\n\n // Add tool calls as work items (status determined after collecting results)\n for (const toolCall of toolCalls) {\n workItems.push({\n id: toolCall.id || message.id,\n type: 'tool_call',\n name: toolCall.function?.name,\n content: toolCall.function?.arguments || null,\n status: null, // Will be updated below based on matching results\n tool_call_id: toolCall.id,\n })\n }\n\n // Collect subsequent tool result messages\n let j = i + 1\n while (j < messages.length && messages[j].role === 'tool') {\n const toolMessage = messages[j]\n // A tool result is pending if it has no tool_status set\n // (tool_status is set to 'success' or 'error' when execution completes)\n const resultStatus = toolMessage.tool_status || 'pending'\n\n workItems.push({\n id: toolMessage.id,\n type: 'tool_result',\n name: toolMessage.name || undefined,\n content: toolMessage.content,\n status: resultStatus,\n tool_call_id: toolMessage.tool_call_id || undefined,\n })\n j++\n }\n\n // Update tool call statuses based on their matching results\n for (const item of workItems) {\n if (item.type === 'tool_call' && item.tool_call_id) {\n // Find matching result\n const matchingResult = workItems.find(\n wi => wi.type === 'tool_result' && wi.tool_call_id === item.tool_call_id\n )\n if (matchingResult) {\n // Tool call inherits status from its result\n item.status = matchingResult.status\n } else {\n // No result yet - tool call is pending\n item.status = 'pending'\n }\n }\n }\n\n // Determine workblock status based on the assistant message status only\n // Individual tool errors are reflected in the work item's status, not the workblock\n let status: 'pending' | 'completed' | 'failed' = 'completed'\n if (message.status === 'pending') {\n status = 'pending'\n } else if (message.status === 'failed') {\n status = 'failed'\n }\n\n // Create the workblock\n const workblock: WorkMessage = {\n id: message.id,\n type: 'workblock',\n content: message.content,\n reasoning_content: message.reasoning_content,\n workItems,\n status,\n created_at: message.created_at,\n depth: message.depth,\n }\n\n result.push(workblock)\n\n // Move index past all consumed messages\n i = j\n } else {\n // Not a workblock, pass through unchanged\n result.push(message)\n i++\n }\n }\n\n return result\n}\n","import { useContext, useMemo } from 'react'\nimport { ThreadContext } from '../context/ThreadProvider'\nimport { transformToWorkblocks } from '../utils/workblocks'\nimport type { ThreadMessage, UseThreadOptions } from '../types'\n\n/**\n * Hook to get messages from a thread.\n *\n * Must be used within a ThreadProvider. The thread ID and WebSocket connection\n * are managed by the ThreadProvider, so this hook simply returns the messages.\n *\n * @param options - Configuration options\n * @returns Array of messages (raw or transformed to workblocks)\n *\n * @example\n * ```tsx\n * function ChatMessages() {\n * // Basic usage - returns messages from context\n * const messages = useThread()\n *\n * return (\n * <div>\n * {messages.map(msg => <Message key={msg.id} message={msg} />)}\n * </div>\n * )\n * }\n *\n * // Wrap with ThreadProvider\n * <ThreadProvider threadId=\"thread-123\">\n * <ChatMessages />\n * </ThreadProvider>\n * ```\n *\n * @example\n * ```tsx\n * // Disable workblocks transformation\n * const messages = useThread({ useWorkblocks: false })\n * ```\n */\nexport function useThread(options: UseThreadOptions = {}): ThreadMessage[] {\n const {\n useWorkblocks = true,\n } = options\n\n const context = useContext(ThreadContext)\n\n if (!context) {\n throw new Error(\n 'useThread must be used within a ThreadProvider. ' +\n 'Wrap your component with <ThreadProvider threadId=\"...\">.'\n )\n }\n\n const { messages } = context\n\n // Transform to workblocks if requested\n const transformedMessages = useMemo(() => {\n return useWorkblocks ? transformToWorkblocks(messages) : messages\n }, [messages, useWorkblocks])\n\n return transformedMessages\n}\n","import { useContext, useEffect, useState } from 'react'\nimport { ThreadContext } 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 const context = useContext(ThreadContext)\n\n if (!context) {\n throw new Error(\n 'onThreadEvent must be used within a ThreadProvider. ' +\n 'Wrap your component with <ThreadProvider threadId=\"...\">.'\n )\n }\n\n const { subscribeToEvent } = context\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 const context = useContext(ThreadContext)\n const [eventData, setEventData] = useState<T | null>(null)\n\n if (!context) {\n throw new Error(\n 'useThreadEvent must be used within a ThreadProvider. ' +\n 'Wrap your component with <ThreadProvider threadId=\"...\">.'\n )\n }\n\n const { subscribeToEvent } = context\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 '../types'\n\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 * function ChatInput() {\n * const sendMessage = useSendMessage()\n *\n * const handleSubmit = async (content: string) => {\n * await sendMessage({\n * role: 'user',\n * content,\n * })\n * }\n *\n * return <input onSubmit={handleSubmit} />\n * }\n * ```\n */\nexport function useSendMessage(): (payload: SendMessagePayload) => Promise<Message> {\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/**\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 * function StopButton() {\n * const stopThread = useStopThread()\n *\n * return (\n * <button onClick={() => stopThread()}>\n * Stop\n * </button>\n * )\n * }\n * ```\n */\nexport function useStopThread(): () => Promise<void> {\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/client.ts","../src/services/sendMessage.ts","../src/services/stopThread.ts","../src/context/AgentBuilderProvider.tsx","../src/context/ThreadProvider.tsx","../src/utils/workblocks.ts","../src/hooks/useThread.ts","../src/hooks/onThreadEvent.ts","../src/hooks/useSendMessage.ts","../src/hooks/useStopThread.ts"],"names":["globalEndpoint","createContext","useEffect","useMemo","jsx","useContext","useState","useCallback"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n Message,\n Thread,\n SendMessagePayload,\n GetMessagesOptions,\n MessageWebSocketCallbacks,\n LogWebSocketCallbacks,\n MessageStreamEvent,\n LogStreamEvent,\n ThreadEvent,\n} from '../types'\n\nexport class AgentBuilderClient {\n private endpoint: string\n private token: string | null\n\n constructor(endpoint: string) {\n // Normalize endpoint by removing trailing slash\n this.endpoint = endpoint.replace(/\\/$/, '')\n\n // Read auth token from localStorage\n this.token = typeof localStorage !== 'undefined'\n ? localStorage.getItem('agentbuilder_auth_token')\n : null\n }\n\n /**\n * Get thread metadata\n */\n async getThread(id: string): Promise<Thread> {\n const response = await fetch(`${this.endpoint}/threads/${id}`, {\n method: 'GET',\n headers: this.getHeaders(),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to get thread: ${response.statusText}`)\n }\n\n return response.json()\n }\n\n /**\n * Get messages from a thread with optional pagination and filtering\n */\n async getMessages(\n id: string,\n options: GetMessagesOptions = {}\n ): Promise<Message[]> {\n const params = new URLSearchParams()\n\n if (options.limit !== undefined) params.set('limit', String(options.limit))\n if (options.offset !== undefined) params.set('offset', String(options.offset))\n if (options.depth !== undefined) params.set('depth', String(options.depth))\n if (options.includeSilent !== undefined) params.set('includeSilent', String(options.includeSilent))\n\n const queryString = params.toString()\n const url = `${this.endpoint}/threads/${id}/messages${queryString ? `?${queryString}` : ''}`\n\n const response = await fetch(url, {\n method: 'GET',\n headers: this.getHeaders(),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to get messages: ${response.statusText}`)\n }\n\n const data = await response.json()\n return data.messages || []\n }\n\n /**\n * Send a message to a thread\n */\n async sendMessage(\n id: string,\n payload: SendMessagePayload\n ): Promise<Message> {\n const response = await fetch(`${this.endpoint}/threads/${id}/message`, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json',\n },\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\n /**\n * Stop execution of a thread\n */\n async stopExecution(id: string): Promise<void> {\n const response = await fetch(`${this.endpoint}/threads/${id}/stop`, {\n method: 'POST',\n headers: this.getHeaders(),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to stop execution: ${response.statusText}`)\n }\n\n await response.json()\n }\n\n /**\n * Connect to message WebSocket for real-time message updates\n */\n connectMessageWebSocket(\n id: string,\n callbacks: MessageWebSocketCallbacks = {},\n options: { includeSilent?: boolean; depth?: number } = {}\n ): WebSocket {\n const params = new URLSearchParams()\n\n if (this.token) params.set('token', this.token)\n if (options.includeSilent !== undefined) params.set('includeSilent', String(options.includeSilent))\n if (options.depth !== undefined) params.set('depth', String(options.depth))\n\n const wsProtocol = this.endpoint.startsWith('https') ? 'wss' : 'ws'\n const wsEndpoint = this.endpoint.replace(/^https?/, wsProtocol)\n const url = `${wsEndpoint}/threads/${id}/stream?${params.toString()}`\n\n const ws = new WebSocket(url)\n\n ws.onopen = () => {\n callbacks.onOpen?.()\n }\n\n ws.onmessage = (event) => {\n try {\n // Handle pong response from heartbeat ping\n if (typeof event.data === 'string' && event.data === 'pong') {\n return\n }\n\n const data = JSON.parse(event.data) as MessageStreamEvent\n\n switch (data.type) {\n case 'message_data':\n callbacks.onMessage?.(data)\n break\n case 'message_chunk':\n callbacks.onChunk?.(data)\n break\n case 'event':\n callbacks.onEvent?.(data as ThreadEvent)\n break\n case 'error':\n callbacks.onError?.(data)\n break\n }\n } catch (error) {\n console.error('Failed to parse WebSocket message:', error)\n }\n }\n\n ws.onerror = (event) => {\n console.error('WebSocket error:', event)\n callbacks.onError?.({ type: 'error', error: 'WebSocket connection error' })\n }\n\n ws.onclose = (event) => {\n console.log(`[AgentBuilderClient] Message WebSocket closed - code: ${event.code}, reason: ${event.reason || 'none'}, wasClean: ${event.wasClean}`)\n callbacks.onClose?.()\n }\n\n return ws\n }\n\n /**\n * Connect to log WebSocket for custom events\n */\n connectLogWebSocket(\n id: string,\n callbacks: LogWebSocketCallbacks = {}\n ): WebSocket {\n const params = new URLSearchParams()\n\n if (this.token) params.set('token', this.token)\n\n const wsProtocol = this.endpoint.startsWith('https') ? 'wss' : 'ws'\n const wsEndpoint = this.endpoint.replace(/^https?/, wsProtocol)\n const url = `${wsEndpoint}/threads/${id}?${params.toString()}`\n\n const ws = new WebSocket(url)\n\n ws.onopen = () => {\n callbacks.onOpen?.()\n }\n\n ws.onmessage = (event) => {\n try {\n // Handle pong response from heartbeat ping\n if (typeof event.data === 'string' && event.data === 'pong') {\n return\n }\n\n const data = JSON.parse(event.data) as LogStreamEvent\n\n switch (data.type) {\n case 'log_data':\n callbacks.onLog?.(data)\n break\n case 'custom':\n callbacks.onCustom?.(data)\n break\n case 'stopped_by_user':\n callbacks.onStopped?.(data)\n break\n }\n } catch (error) {\n console.error('Failed to parse WebSocket message:', error)\n }\n }\n\n ws.onerror = (event) => {\n console.error('WebSocket error:', event)\n }\n\n ws.onclose = () => {\n callbacks.onClose?.()\n }\n\n return ws\n }\n\n /**\n * Get headers for HTTP requests\n */\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {}\n\n if (this.token) {\n headers['Authorization'] = `Bearer ${this.token}`\n }\n\n return headers\n }\n}\n","import type { SendMessagePayload, Message } from '../types'\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}/message`, {\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 } from '../services/client'\nimport { __setGlobalEndpoint } from '../services/sendMessage'\nimport { __setGlobalEndpointForStop } from '../services/stopThread'\nimport type { AgentBuilderConfig } from '../types'\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 { AgentBuilderClient } from \"../services/client\"\nimport type { Message, ThreadEvent, ThreadProviderOptions } from \"../types\"\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 = 'connecting' | 'connected' | 'disconnected'\n\n/**\n * Thread context value\n */\ninterface ThreadContextValue {\n /** The thread ID */\n threadId: string\n /** Current messages in the thread */\n messages: Message[]\n /** Whether messages are currently loading */\n loading: boolean\n /** Any error that occurred */\n error: Error | null\n /** WebSocket connection status */\n connectionStatus: ConnectionStatus\n /** Subscribe to a specific event type */\n subscribeToEvent: <T = unknown>(\n eventType: string,\n listener: EventListener<T>\n ) => () => void\n /** Options passed to the provider */\n options: ThreadProviderOptions\n}\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 /** 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 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 // State\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\n // Event listeners registry\n const eventListenersRef = useRef<Map<string, Set<EventListener>>>(new Map())\n\n // WebSocket ref\n const wsRef = useRef<WebSocket | null>(null)\n\n // Reconnection state\n const reconnectAttempts = useRef<number>(0)\n const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n const heartbeatIntervalRef = useRef<NodeJS.Timeout | null>(null)\n const isReconnectingRef = useRef<boolean>(false)\n const isMountedRef = useRef<boolean>(true)\n\n /**\n * Subscribe to a specific event type\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 unsubscribe function\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 /**\n * Dispatch event to all registered listeners\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 /**\n * Clear all timers and cleanup\n */\n const clearTimers = useCallback(() => {\n if (reconnectTimeoutRef.current) {\n clearTimeout(reconnectTimeoutRef.current)\n reconnectTimeoutRef.current = null\n }\n if (heartbeatIntervalRef.current) {\n clearInterval(heartbeatIntervalRef.current)\n heartbeatIntervalRef.current = null\n }\n }, [])\n\n /**\n * Start heartbeat to keep connection alive\n */\n const startHeartbeat = useCallback((ws: WebSocket) => {\n // Clear any existing heartbeat\n if (heartbeatIntervalRef.current) {\n clearInterval(heartbeatIntervalRef.current)\n }\n\n // Send ping every 30 seconds\n heartbeatIntervalRef.current = setInterval(() => {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(\"ping\")\n }\n }, 30000)\n }, [])\n\n // Set up WebSocket connection\n useEffect(() => {\n if (!live || !threadId) return\n\n console.log(\n `[ThreadProvider] useEffect running - threadId: ${threadId}, live: ${live}`\n )\n connectWebSocket()\n\n return () => {\n // Clean up on unmount or thread change\n console.log(\n `[ThreadProvider] useEffect cleanup - threadId: ${threadId}, live: ${live}`\n )\n clearTimers()\n if (wsRef.current) {\n wsRef.current.close()\n wsRef.current = null\n }\n reconnectAttempts.current = 0\n isReconnectingRef.current = false\n }\n }, [threadId, live]) // Only reconnect when threadId or live changes, not when callbacks change\n\n /**\n * Connect to WebSocket with error handling\n */\n const connectWebSocket = useCallback(() => {\n if (!live || !threadId || !isMountedRef.current) return\n\n console.log(`[ThreadProvider] Connecting WebSocket for thread ${threadId}`)\n setConnectionStatus('connecting')\n\n const ws = clientRef.current.connectMessageWebSocket(\n threadId,\n {\n onOpen: () => {\n console.log(\n `[ThreadProvider] WebSocket connected for thread ${threadId}`\n )\n setConnectionStatus('connected')\n reconnectAttempts.current = 0\n isReconnectingRef.current = false\n startHeartbeat(ws)\n },\n onMessage: (event) => {\n setMessages((prev) => {\n // Check if message already exists\n const exists = prev.some((m) => m.id === event.data.id)\n if (exists) {\n // Update existing message\n return prev.map((m) => (m.id === event.data.id ? event.data : m))\n } else {\n // Add new message\n return [...prev, event.data]\n }\n })\n },\n onChunk: (event) => {\n // Handle streaming chunks\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 // Dispatch custom events to subscribers\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 setConnectionStatus('disconnected')\n },\n onClose: () => {\n console.log(\"[ThreadProvider] WebSocket closed\")\n clearTimers()\n\n // Only attempt to reconnect if still mounted and not already reconnecting\n if (isMountedRef.current && !isReconnectingRef.current) {\n isReconnectingRef.current = true\n setConnectionStatus('connecting')\n const delay = Math.min(\n 1000 * Math.pow(2, reconnectAttempts.current),\n 30000\n )\n reconnectAttempts.current++\n\n console.log(\n `[ThreadProvider] Reconnecting in ${delay}ms (attempt ${reconnectAttempts.current})`\n )\n\n reconnectTimeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) {\n connectWebSocket()\n }\n }, delay)\n } else {\n setConnectionStatus('disconnected')\n }\n },\n },\n {\n depth,\n includeSilent,\n }\n )\n\n wsRef.current = ws\n }, [\n threadId,\n live,\n depth,\n includeSilent,\n dispatchEvent,\n startHeartbeat,\n clearTimers,\n ])\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 // Track component mount state\n useEffect(() => {\n isMountedRef.current = true\n return () => {\n isMountedRef.current = false\n }\n }, [])\n\n // Memoize context value\n const contextValue = useMemo(\n (): ThreadContextValue => ({\n threadId,\n messages,\n loading,\n error,\n connectionStatus,\n subscribeToEvent,\n options: {\n depth,\n includeSilent,\n ...options,\n },\n }),\n [\n threadId,\n messages,\n loading,\n error,\n connectionStatus,\n subscribeToEvent,\n depth,\n includeSilent,\n options,\n ]\n )\n\n return (\n <ThreadContext.Provider value={contextValue}>\n {children}\n </ThreadContext.Provider>\n )\n}\n\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 const context = useContext(ThreadContext)\n\n if (!context) {\n throw new Error(\"useThreadContext must be used within a ThreadProvider\")\n }\n\n return context\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 useThreadContext().threadId\n}\n","import type { Message, WorkMessage, WorkItem, ThreadMessage } from '../types'\n\n/**\n * Transform a flat list of messages into a list with workblocks.\n * Groups consecutive assistant tool_calls and their tool results into WorkMessage objects.\n *\n * A workblock starts when an assistant message has tool_calls,\n * and includes all subsequent tool messages until:\n * - A non-tool message appears\n * - Another assistant message without tool_calls appears\n */\nexport function transformToWorkblocks(messages: Message[]): ThreadMessage[] {\n if (messages.length === 0) {\n return []\n }\n\n const result: ThreadMessage[] = []\n let i = 0\n\n while (i < messages.length) {\n const message = messages[i]\n\n // Check if this is an assistant message with tool_calls\n if (message.role === 'assistant' && message.tool_calls) {\n // Try to parse tool_calls\n let toolCalls: any[]\n try {\n toolCalls = JSON.parse(message.tool_calls)\n } catch (error) {\n // If we can't parse tool_calls, treat it as a regular message\n result.push(message)\n i++\n continue\n }\n\n // Start building a workblock\n const workItems: WorkItem[] = []\n\n // Add tool calls as work items (status determined after collecting results)\n for (const toolCall of toolCalls) {\n workItems.push({\n id: toolCall.id || message.id,\n type: 'tool_call',\n name: toolCall.function?.name,\n content: toolCall.function?.arguments || null,\n status: null, // Will be updated below based on matching results\n tool_call_id: toolCall.id,\n })\n }\n\n // Collect subsequent tool result messages\n let j = i + 1\n while (j < messages.length && messages[j].role === 'tool') {\n const toolMessage = messages[j]\n // A tool result is pending if it has no tool_status set\n // (tool_status is set to 'success' or 'error' when execution completes)\n const resultStatus = toolMessage.tool_status || 'pending'\n\n workItems.push({\n id: toolMessage.id,\n type: 'tool_result',\n name: toolMessage.name || undefined,\n content: toolMessage.content,\n status: resultStatus,\n tool_call_id: toolMessage.tool_call_id || undefined,\n })\n j++\n }\n\n // Update tool call statuses based on their matching results\n for (const item of workItems) {\n if (item.type === 'tool_call' && item.tool_call_id) {\n // Find matching result\n const matchingResult = workItems.find(\n wi => wi.type === 'tool_result' && wi.tool_call_id === item.tool_call_id\n )\n if (matchingResult) {\n // Tool call inherits status from its result\n item.status = matchingResult.status\n } else {\n // No result yet - tool call is pending\n item.status = 'pending'\n }\n }\n }\n\n // Determine workblock status based on the assistant message status only\n // Individual tool errors are reflected in the work item's status, not the workblock\n let status: 'pending' | 'completed' | 'failed' = 'completed'\n if (message.status === 'pending') {\n status = 'pending'\n } else if (message.status === 'failed') {\n status = 'failed'\n }\n\n // Create the workblock\n const workblock: WorkMessage = {\n id: message.id,\n type: 'workblock',\n content: message.content,\n reasoning_content: message.reasoning_content,\n workItems,\n status,\n created_at: message.created_at,\n depth: message.depth,\n }\n\n result.push(workblock)\n\n // Move index past all consumed messages\n i = j\n } else {\n // Not a workblock, pass through unchanged\n result.push(message)\n i++\n }\n }\n\n return result\n}\n","import { useContext, useMemo } from 'react'\nimport { ThreadContext } from '../context/ThreadProvider'\nimport { transformToWorkblocks } from '../utils/workblocks'\nimport type { ThreadMessage, UseThreadOptions } from '../types'\n\n/**\n * Hook to get messages from a thread.\n *\n * Must be used within a ThreadProvider. The thread ID and WebSocket connection\n * are managed by the ThreadProvider, so this hook simply returns the messages.\n *\n * @param options - Configuration options\n * @returns Array of messages (raw or transformed to workblocks)\n *\n * @example\n * ```tsx\n * function ChatMessages() {\n * // Basic usage - returns messages from context\n * const messages = useThread()\n *\n * return (\n * <div>\n * {messages.map(msg => <Message key={msg.id} message={msg} />)}\n * </div>\n * )\n * }\n *\n * // Wrap with ThreadProvider\n * <ThreadProvider threadId=\"thread-123\">\n * <ChatMessages />\n * </ThreadProvider>\n * ```\n *\n * @example\n * ```tsx\n * // Disable workblocks transformation\n * const messages = useThread({ useWorkblocks: false })\n * ```\n */\nexport function useThread(options: UseThreadOptions = {}): ThreadMessage[] {\n const {\n useWorkblocks = true,\n } = options\n\n const context = useContext(ThreadContext)\n\n if (!context) {\n throw new Error(\n 'useThread must be used within a ThreadProvider. ' +\n 'Wrap your component with <ThreadProvider threadId=\"...\">.'\n )\n }\n\n const { messages } = context\n\n // Transform to workblocks if requested\n const transformedMessages = useMemo(() => {\n return useWorkblocks ? transformToWorkblocks(messages) : messages\n }, [messages, useWorkblocks])\n\n return transformedMessages\n}\n","import { useContext, useEffect, useState } from 'react'\nimport { ThreadContext } 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 const context = useContext(ThreadContext)\n\n if (!context) {\n throw new Error(\n 'onThreadEvent must be used within a ThreadProvider. ' +\n 'Wrap your component with <ThreadProvider threadId=\"...\">.'\n )\n }\n\n const { subscribeToEvent } = context\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 const context = useContext(ThreadContext)\n const [eventData, setEventData] = useState<T | null>(null)\n\n if (!context) {\n throw new Error(\n 'useThreadEvent must be used within a ThreadProvider. ' +\n 'Wrap your component with <ThreadProvider threadId=\"...\">.'\n )\n }\n\n const { subscribeToEvent } = context\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 '../types'\n\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 * function ChatInput() {\n * const sendMessage = useSendMessage()\n *\n * const handleSubmit = async (content: string) => {\n * await sendMessage({\n * role: 'user',\n * content,\n * })\n * }\n *\n * return <input onSubmit={handleSubmit} />\n * }\n * ```\n */\nexport function useSendMessage(): (payload: SendMessagePayload) => Promise<Message> {\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/**\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 * function StopButton() {\n * const stopThread = useStopThread()\n *\n * return (\n * <button onClick={() => stopThread()}>\n * Stop\n * </button>\n * )\n * }\n * ```\n */\nexport function useStopThread(): () => Promise<void> {\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"]}
|