@standardagents/react 0.8.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/README.md +544 -0
- package/dist/index.d.ts +457 -0
- package/dist/index.js +575 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
import { createContext, useMemo, useEffect, useRef, useState, useCallback, useContext } from 'react';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/context/AgentBuilderProvider.tsx
|
|
5
|
+
|
|
6
|
+
// src/services/client.ts
|
|
7
|
+
var AgentBuilderClient = class {
|
|
8
|
+
endpoint;
|
|
9
|
+
token;
|
|
10
|
+
constructor(endpoint) {
|
|
11
|
+
this.endpoint = endpoint.replace(/\/$/, "");
|
|
12
|
+
this.token = typeof localStorage !== "undefined" ? localStorage.getItem("agentbuilder_auth_token") : null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get thread metadata
|
|
16
|
+
*/
|
|
17
|
+
async getThread(id) {
|
|
18
|
+
const response = await fetch(`${this.endpoint}/threads/${id}`, {
|
|
19
|
+
method: "GET",
|
|
20
|
+
headers: this.getHeaders()
|
|
21
|
+
});
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw new Error(`Failed to get thread: ${response.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
return response.json();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get messages from a thread with optional pagination and filtering
|
|
29
|
+
*/
|
|
30
|
+
async getMessages(id, options = {}) {
|
|
31
|
+
const params = new URLSearchParams();
|
|
32
|
+
if (options.limit !== void 0) params.set("limit", String(options.limit));
|
|
33
|
+
if (options.offset !== void 0) params.set("offset", String(options.offset));
|
|
34
|
+
if (options.depth !== void 0) params.set("depth", String(options.depth));
|
|
35
|
+
if (options.includeSilent !== void 0) params.set("includeSilent", String(options.includeSilent));
|
|
36
|
+
const queryString = params.toString();
|
|
37
|
+
const url = `${this.endpoint}/threads/${id}/messages${queryString ? `?${queryString}` : ""}`;
|
|
38
|
+
const response = await fetch(url, {
|
|
39
|
+
method: "GET",
|
|
40
|
+
headers: this.getHeaders()
|
|
41
|
+
});
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
throw new Error(`Failed to get messages: ${response.statusText}`);
|
|
44
|
+
}
|
|
45
|
+
const data = await response.json();
|
|
46
|
+
return data.messages || [];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Send a message to a thread
|
|
50
|
+
*/
|
|
51
|
+
async sendMessage(id, payload) {
|
|
52
|
+
const response = await fetch(`${this.endpoint}/threads/${id}/message`, {
|
|
53
|
+
method: "POST",
|
|
54
|
+
headers: {
|
|
55
|
+
...this.getHeaders(),
|
|
56
|
+
"Content-Type": "application/json"
|
|
57
|
+
},
|
|
58
|
+
body: JSON.stringify(payload)
|
|
59
|
+
});
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
throw new Error(`Failed to send message: ${response.statusText}`);
|
|
62
|
+
}
|
|
63
|
+
return response.json();
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Stop execution of a thread
|
|
67
|
+
*/
|
|
68
|
+
async stopExecution(id) {
|
|
69
|
+
const response = await fetch(`${this.endpoint}/threads/${id}/stop`, {
|
|
70
|
+
method: "POST",
|
|
71
|
+
headers: this.getHeaders()
|
|
72
|
+
});
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
throw new Error(`Failed to stop execution: ${response.statusText}`);
|
|
75
|
+
}
|
|
76
|
+
await response.json();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Connect to message WebSocket for real-time message updates
|
|
80
|
+
*/
|
|
81
|
+
connectMessageWebSocket(id, callbacks = {}, options = {}) {
|
|
82
|
+
const params = new URLSearchParams();
|
|
83
|
+
if (this.token) params.set("token", this.token);
|
|
84
|
+
if (options.includeSilent !== void 0) params.set("includeSilent", String(options.includeSilent));
|
|
85
|
+
if (options.depth !== void 0) params.set("depth", String(options.depth));
|
|
86
|
+
const wsProtocol = this.endpoint.startsWith("https") ? "wss" : "ws";
|
|
87
|
+
const wsEndpoint = this.endpoint.replace(/^https?/, wsProtocol);
|
|
88
|
+
const url = `${wsEndpoint}/threads/${id}/stream?${params.toString()}`;
|
|
89
|
+
const ws = new WebSocket(url);
|
|
90
|
+
ws.onopen = () => {
|
|
91
|
+
callbacks.onOpen?.();
|
|
92
|
+
};
|
|
93
|
+
ws.onmessage = (event) => {
|
|
94
|
+
try {
|
|
95
|
+
const data = JSON.parse(event.data);
|
|
96
|
+
switch (data.type) {
|
|
97
|
+
case "message_data":
|
|
98
|
+
callbacks.onMessage?.(data);
|
|
99
|
+
break;
|
|
100
|
+
case "message_chunk":
|
|
101
|
+
callbacks.onChunk?.(data);
|
|
102
|
+
break;
|
|
103
|
+
case "event":
|
|
104
|
+
callbacks.onEvent?.(data);
|
|
105
|
+
break;
|
|
106
|
+
case "error":
|
|
107
|
+
callbacks.onError?.(data);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error("Failed to parse WebSocket message:", error);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
ws.onerror = (event) => {
|
|
115
|
+
console.error("WebSocket error:", event);
|
|
116
|
+
};
|
|
117
|
+
ws.onclose = () => {
|
|
118
|
+
callbacks.onClose?.();
|
|
119
|
+
};
|
|
120
|
+
return ws;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Connect to log WebSocket for custom events
|
|
124
|
+
*/
|
|
125
|
+
connectLogWebSocket(id, callbacks = {}) {
|
|
126
|
+
const params = new URLSearchParams();
|
|
127
|
+
if (this.token) params.set("token", this.token);
|
|
128
|
+
const wsProtocol = this.endpoint.startsWith("https") ? "wss" : "ws";
|
|
129
|
+
const wsEndpoint = this.endpoint.replace(/^https?/, wsProtocol);
|
|
130
|
+
const url = `${wsEndpoint}/threads/${id}?${params.toString()}`;
|
|
131
|
+
const ws = new WebSocket(url);
|
|
132
|
+
ws.onopen = () => {
|
|
133
|
+
callbacks.onOpen?.();
|
|
134
|
+
};
|
|
135
|
+
ws.onmessage = (event) => {
|
|
136
|
+
try {
|
|
137
|
+
const data = JSON.parse(event.data);
|
|
138
|
+
switch (data.type) {
|
|
139
|
+
case "log_data":
|
|
140
|
+
callbacks.onLog?.(data);
|
|
141
|
+
break;
|
|
142
|
+
case "custom":
|
|
143
|
+
callbacks.onCustom?.(data);
|
|
144
|
+
break;
|
|
145
|
+
case "stopped_by_user":
|
|
146
|
+
callbacks.onStopped?.(data);
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.error("Failed to parse WebSocket message:", error);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
ws.onerror = (event) => {
|
|
154
|
+
console.error("WebSocket error:", event);
|
|
155
|
+
};
|
|
156
|
+
ws.onclose = () => {
|
|
157
|
+
callbacks.onClose?.();
|
|
158
|
+
};
|
|
159
|
+
return ws;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get headers for HTTP requests
|
|
163
|
+
*/
|
|
164
|
+
getHeaders() {
|
|
165
|
+
const headers = {};
|
|
166
|
+
if (this.token) {
|
|
167
|
+
headers["Authorization"] = `Bearer ${this.token}`;
|
|
168
|
+
}
|
|
169
|
+
return headers;
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// src/services/sendMessage.ts
|
|
174
|
+
var globalEndpoint = null;
|
|
175
|
+
function __setGlobalEndpoint(endpoint) {
|
|
176
|
+
globalEndpoint = endpoint;
|
|
177
|
+
}
|
|
178
|
+
async function sendMessage(id, payload) {
|
|
179
|
+
if (!globalEndpoint) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
"sendMessage requires AgentBuilderProvider to be mounted in your app"
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
const token = typeof localStorage !== "undefined" ? localStorage.getItem("agentbuilder_auth_token") : null;
|
|
185
|
+
const headers = {
|
|
186
|
+
"Content-Type": "application/json"
|
|
187
|
+
};
|
|
188
|
+
if (token) {
|
|
189
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
190
|
+
}
|
|
191
|
+
const response = await fetch(`${globalEndpoint}/threads/${id}/message`, {
|
|
192
|
+
method: "POST",
|
|
193
|
+
headers,
|
|
194
|
+
body: JSON.stringify(payload)
|
|
195
|
+
});
|
|
196
|
+
if (!response.ok) {
|
|
197
|
+
throw new Error(`Failed to send message: ${response.statusText}`);
|
|
198
|
+
}
|
|
199
|
+
return response.json();
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// src/services/stopThread.ts
|
|
203
|
+
var globalEndpoint2 = null;
|
|
204
|
+
function __setGlobalEndpointForStop(endpoint) {
|
|
205
|
+
globalEndpoint2 = endpoint;
|
|
206
|
+
}
|
|
207
|
+
async function stopThread(id, options) {
|
|
208
|
+
const endpoint = options?.endpoint ?? globalEndpoint2;
|
|
209
|
+
if (!endpoint) {
|
|
210
|
+
throw new Error(
|
|
211
|
+
"stopThread requires AgentBuilderProvider to be mounted or endpoint option to be provided"
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
const normalizedEndpoint = endpoint.replace(/\/$/, "");
|
|
215
|
+
const token = typeof localStorage !== "undefined" ? localStorage.getItem("agentbuilder_auth_token") : null;
|
|
216
|
+
const headers = {};
|
|
217
|
+
if (token) {
|
|
218
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
219
|
+
}
|
|
220
|
+
const response = await fetch(`${normalizedEndpoint}/threads/${id}/stop`, {
|
|
221
|
+
method: "POST",
|
|
222
|
+
headers
|
|
223
|
+
});
|
|
224
|
+
if (!response.ok) {
|
|
225
|
+
throw new Error(`Failed to stop thread: ${response.statusText}`);
|
|
226
|
+
}
|
|
227
|
+
await response.json();
|
|
228
|
+
}
|
|
229
|
+
var AgentBuilderContext = createContext(null);
|
|
230
|
+
function AgentBuilderProvider({ config, children }) {
|
|
231
|
+
const client = useMemo(() => {
|
|
232
|
+
return new AgentBuilderClient(config.endpoint);
|
|
233
|
+
}, [config.endpoint]);
|
|
234
|
+
const value = useMemo(
|
|
235
|
+
() => ({
|
|
236
|
+
client,
|
|
237
|
+
config
|
|
238
|
+
}),
|
|
239
|
+
[client, config]
|
|
240
|
+
);
|
|
241
|
+
useEffect(() => {
|
|
242
|
+
__setGlobalEndpoint(config.endpoint);
|
|
243
|
+
__setGlobalEndpointForStop(config.endpoint);
|
|
244
|
+
}, [config.endpoint]);
|
|
245
|
+
return /* @__PURE__ */ jsx(AgentBuilderContext.Provider, { value, children });
|
|
246
|
+
}
|
|
247
|
+
function useAgentBuilderClient() {
|
|
248
|
+
const context = useContext(AgentBuilderContext);
|
|
249
|
+
if (!context) {
|
|
250
|
+
throw new Error("useAgentBuilderClient must be used within AgentBuilderProvider");
|
|
251
|
+
}
|
|
252
|
+
return context.client;
|
|
253
|
+
}
|
|
254
|
+
function useAgentBuilderConfig() {
|
|
255
|
+
const context = useContext(AgentBuilderContext);
|
|
256
|
+
if (!context) {
|
|
257
|
+
throw new Error("useAgentBuilderConfig must be used within AgentBuilderProvider");
|
|
258
|
+
}
|
|
259
|
+
return context.config;
|
|
260
|
+
}
|
|
261
|
+
var ThreadContext = createContext(null);
|
|
262
|
+
function ThreadProvider({
|
|
263
|
+
threadId,
|
|
264
|
+
options = {},
|
|
265
|
+
preload = true,
|
|
266
|
+
live = true,
|
|
267
|
+
depth = 0,
|
|
268
|
+
includeSilent = false,
|
|
269
|
+
endpoint: endpointOverride,
|
|
270
|
+
children
|
|
271
|
+
}) {
|
|
272
|
+
const contextClient = useAgentBuilderClient();
|
|
273
|
+
const contextConfig = useAgentBuilderConfig();
|
|
274
|
+
endpointOverride || contextConfig.endpoint;
|
|
275
|
+
const clientRef = useRef(
|
|
276
|
+
endpointOverride ? new AgentBuilderClient(endpointOverride) : contextClient
|
|
277
|
+
);
|
|
278
|
+
useEffect(() => {
|
|
279
|
+
if (endpointOverride) {
|
|
280
|
+
clientRef.current = new AgentBuilderClient(endpointOverride);
|
|
281
|
+
} else {
|
|
282
|
+
clientRef.current = contextClient;
|
|
283
|
+
}
|
|
284
|
+
}, [endpointOverride, contextClient]);
|
|
285
|
+
const [messages, setMessages] = useState([]);
|
|
286
|
+
const [loading, setLoading] = useState(preload);
|
|
287
|
+
const [error, setError] = useState(null);
|
|
288
|
+
const eventListenersRef = useRef(/* @__PURE__ */ new Map());
|
|
289
|
+
const wsRef = useRef(null);
|
|
290
|
+
const subscribeToEvent = useCallback((eventType, listener) => {
|
|
291
|
+
if (!eventListenersRef.current.has(eventType)) {
|
|
292
|
+
eventListenersRef.current.set(eventType, /* @__PURE__ */ new Set());
|
|
293
|
+
}
|
|
294
|
+
eventListenersRef.current.get(eventType).add(listener);
|
|
295
|
+
return () => {
|
|
296
|
+
const listeners = eventListenersRef.current.get(eventType);
|
|
297
|
+
if (listeners) {
|
|
298
|
+
listeners.delete(listener);
|
|
299
|
+
if (listeners.size === 0) {
|
|
300
|
+
eventListenersRef.current.delete(eventType);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
}, []);
|
|
305
|
+
const dispatchEvent = useCallback((eventType, data) => {
|
|
306
|
+
const listeners = eventListenersRef.current.get(eventType);
|
|
307
|
+
if (listeners) {
|
|
308
|
+
listeners.forEach((listener) => {
|
|
309
|
+
try {
|
|
310
|
+
listener(data);
|
|
311
|
+
} catch (err) {
|
|
312
|
+
console.error(`Error in event listener for "${eventType}":`, err);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}, []);
|
|
317
|
+
useEffect(() => {
|
|
318
|
+
if (!preload || !threadId) return;
|
|
319
|
+
const fetchMessages = async () => {
|
|
320
|
+
setLoading(true);
|
|
321
|
+
setError(null);
|
|
322
|
+
try {
|
|
323
|
+
const fetchedMessages = await clientRef.current.getMessages(threadId, {
|
|
324
|
+
depth,
|
|
325
|
+
includeSilent
|
|
326
|
+
});
|
|
327
|
+
setMessages(fetchedMessages);
|
|
328
|
+
} catch (err) {
|
|
329
|
+
console.error("Failed to fetch messages:", err);
|
|
330
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch messages"));
|
|
331
|
+
setMessages([]);
|
|
332
|
+
} finally {
|
|
333
|
+
setLoading(false);
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
fetchMessages();
|
|
337
|
+
}, [threadId, preload, depth, includeSilent]);
|
|
338
|
+
useEffect(() => {
|
|
339
|
+
if (!live || !threadId) return;
|
|
340
|
+
const ws = clientRef.current.connectMessageWebSocket(
|
|
341
|
+
threadId,
|
|
342
|
+
{
|
|
343
|
+
onMessage: (event) => {
|
|
344
|
+
setMessages((prev) => {
|
|
345
|
+
const exists = prev.some((m) => m.id === event.data.id);
|
|
346
|
+
if (exists) {
|
|
347
|
+
return prev.map((m) => m.id === event.data.id ? event.data : m);
|
|
348
|
+
} else {
|
|
349
|
+
return [...prev, event.data];
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
},
|
|
353
|
+
onChunk: (event) => {
|
|
354
|
+
setMessages((prev) => {
|
|
355
|
+
return prev.map((m) => {
|
|
356
|
+
if (m.id === event.message_id) {
|
|
357
|
+
return {
|
|
358
|
+
...m,
|
|
359
|
+
content: (m.content || "") + event.chunk
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
return m;
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
},
|
|
366
|
+
onEvent: (event) => {
|
|
367
|
+
dispatchEvent(event.eventType, event.data);
|
|
368
|
+
},
|
|
369
|
+
onError: (event) => {
|
|
370
|
+
console.error("WebSocket error:", event.error);
|
|
371
|
+
setError(new Error(event.error));
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
depth,
|
|
376
|
+
includeSilent
|
|
377
|
+
}
|
|
378
|
+
);
|
|
379
|
+
wsRef.current = ws;
|
|
380
|
+
return () => {
|
|
381
|
+
ws.close();
|
|
382
|
+
wsRef.current = null;
|
|
383
|
+
};
|
|
384
|
+
}, [threadId, live, depth, includeSilent, dispatchEvent]);
|
|
385
|
+
const contextValue = useMemo(
|
|
386
|
+
() => ({
|
|
387
|
+
threadId,
|
|
388
|
+
messages,
|
|
389
|
+
loading,
|
|
390
|
+
error,
|
|
391
|
+
subscribeToEvent,
|
|
392
|
+
options: {
|
|
393
|
+
depth,
|
|
394
|
+
includeSilent,
|
|
395
|
+
...options
|
|
396
|
+
}
|
|
397
|
+
}),
|
|
398
|
+
[threadId, messages, loading, error, subscribeToEvent, depth, includeSilent, options]
|
|
399
|
+
);
|
|
400
|
+
return /* @__PURE__ */ jsx(ThreadContext.Provider, { value: contextValue, children });
|
|
401
|
+
}
|
|
402
|
+
function useThreadContext() {
|
|
403
|
+
const context = useContext(ThreadContext);
|
|
404
|
+
if (!context) {
|
|
405
|
+
throw new Error("useThreadContext must be used within a ThreadProvider");
|
|
406
|
+
}
|
|
407
|
+
return context;
|
|
408
|
+
}
|
|
409
|
+
function useThreadId() {
|
|
410
|
+
return useThreadContext().threadId;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// src/utils/workblocks.ts
|
|
414
|
+
function transformToWorkblocks(messages) {
|
|
415
|
+
if (messages.length === 0) {
|
|
416
|
+
return [];
|
|
417
|
+
}
|
|
418
|
+
const result = [];
|
|
419
|
+
let i = 0;
|
|
420
|
+
while (i < messages.length) {
|
|
421
|
+
const message = messages[i];
|
|
422
|
+
if (message.role === "assistant" && message.tool_calls) {
|
|
423
|
+
let toolCalls;
|
|
424
|
+
try {
|
|
425
|
+
toolCalls = JSON.parse(message.tool_calls);
|
|
426
|
+
} catch (error) {
|
|
427
|
+
result.push(message);
|
|
428
|
+
i++;
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
const workItems = [];
|
|
432
|
+
for (const toolCall of toolCalls) {
|
|
433
|
+
workItems.push({
|
|
434
|
+
id: toolCall.id || message.id,
|
|
435
|
+
type: "tool_call",
|
|
436
|
+
name: toolCall.function?.name,
|
|
437
|
+
content: toolCall.function?.arguments || null,
|
|
438
|
+
status: null,
|
|
439
|
+
// Will be updated below based on matching results
|
|
440
|
+
tool_call_id: toolCall.id
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
let j = i + 1;
|
|
444
|
+
while (j < messages.length && messages[j].role === "tool") {
|
|
445
|
+
const toolMessage = messages[j];
|
|
446
|
+
const resultStatus = toolMessage.tool_status || "pending";
|
|
447
|
+
workItems.push({
|
|
448
|
+
id: toolMessage.id,
|
|
449
|
+
type: "tool_result",
|
|
450
|
+
name: toolMessage.name || void 0,
|
|
451
|
+
content: toolMessage.content,
|
|
452
|
+
status: resultStatus,
|
|
453
|
+
tool_call_id: toolMessage.tool_call_id || void 0
|
|
454
|
+
});
|
|
455
|
+
j++;
|
|
456
|
+
}
|
|
457
|
+
for (const item of workItems) {
|
|
458
|
+
if (item.type === "tool_call" && item.tool_call_id) {
|
|
459
|
+
const matchingResult = workItems.find(
|
|
460
|
+
(wi) => wi.type === "tool_result" && wi.tool_call_id === item.tool_call_id
|
|
461
|
+
);
|
|
462
|
+
if (matchingResult) {
|
|
463
|
+
item.status = matchingResult.status;
|
|
464
|
+
} else {
|
|
465
|
+
item.status = "pending";
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
let status = "completed";
|
|
470
|
+
if (message.status === "pending") {
|
|
471
|
+
status = "pending";
|
|
472
|
+
} else if (message.status === "failed") {
|
|
473
|
+
status = "failed";
|
|
474
|
+
}
|
|
475
|
+
const workblock = {
|
|
476
|
+
id: message.id,
|
|
477
|
+
type: "workblock",
|
|
478
|
+
content: message.content,
|
|
479
|
+
reasoning_content: message.reasoning_content,
|
|
480
|
+
workItems,
|
|
481
|
+
status,
|
|
482
|
+
created_at: message.created_at,
|
|
483
|
+
depth: message.depth
|
|
484
|
+
};
|
|
485
|
+
result.push(workblock);
|
|
486
|
+
i = j;
|
|
487
|
+
} else {
|
|
488
|
+
result.push(message);
|
|
489
|
+
i++;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return result;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// src/hooks/useThread.ts
|
|
496
|
+
function useThread(options = {}) {
|
|
497
|
+
const {
|
|
498
|
+
useWorkblocks = true
|
|
499
|
+
} = options;
|
|
500
|
+
const context = useContext(ThreadContext);
|
|
501
|
+
if (!context) {
|
|
502
|
+
throw new Error(
|
|
503
|
+
'useThread must be used within a ThreadProvider. Wrap your component with <ThreadProvider threadId="...">.'
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
const { messages } = context;
|
|
507
|
+
const transformedMessages = useMemo(() => {
|
|
508
|
+
return useWorkblocks ? transformToWorkblocks(messages) : messages;
|
|
509
|
+
}, [messages, useWorkblocks]);
|
|
510
|
+
return transformedMessages;
|
|
511
|
+
}
|
|
512
|
+
function onThreadEvent(type, callback) {
|
|
513
|
+
const context = useContext(ThreadContext);
|
|
514
|
+
if (!context) {
|
|
515
|
+
throw new Error(
|
|
516
|
+
'onThreadEvent must be used within a ThreadProvider. Wrap your component with <ThreadProvider threadId="...">.'
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
const { subscribeToEvent } = context;
|
|
520
|
+
useEffect(() => {
|
|
521
|
+
const unsubscribe = subscribeToEvent(type, callback);
|
|
522
|
+
return unsubscribe;
|
|
523
|
+
}, [subscribeToEvent, type, callback]);
|
|
524
|
+
}
|
|
525
|
+
function useThreadEvent(type) {
|
|
526
|
+
const context = useContext(ThreadContext);
|
|
527
|
+
const [eventData, setEventData] = useState(null);
|
|
528
|
+
if (!context) {
|
|
529
|
+
throw new Error(
|
|
530
|
+
'useThreadEvent must be used within a ThreadProvider. Wrap your component with <ThreadProvider threadId="...">.'
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
const { subscribeToEvent } = context;
|
|
534
|
+
useEffect(() => {
|
|
535
|
+
const unsubscribe = subscribeToEvent(type, (data) => {
|
|
536
|
+
setEventData(data);
|
|
537
|
+
});
|
|
538
|
+
return unsubscribe;
|
|
539
|
+
}, [subscribeToEvent, type]);
|
|
540
|
+
return eventData;
|
|
541
|
+
}
|
|
542
|
+
function useSendMessage() {
|
|
543
|
+
let context;
|
|
544
|
+
try {
|
|
545
|
+
context = useThreadContext();
|
|
546
|
+
} catch {
|
|
547
|
+
throw new Error("useSendMessage must be used within a ThreadProvider");
|
|
548
|
+
}
|
|
549
|
+
const { threadId } = context;
|
|
550
|
+
return useCallback(
|
|
551
|
+
(payload) => {
|
|
552
|
+
return sendMessage(threadId, payload);
|
|
553
|
+
},
|
|
554
|
+
[threadId]
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
function useStopThread() {
|
|
558
|
+
let context;
|
|
559
|
+
try {
|
|
560
|
+
context = useThreadContext();
|
|
561
|
+
} catch {
|
|
562
|
+
throw new Error("useStopThread must be used within a ThreadProvider");
|
|
563
|
+
}
|
|
564
|
+
const { threadId } = context;
|
|
565
|
+
return useCallback(
|
|
566
|
+
() => {
|
|
567
|
+
return stopThread(threadId);
|
|
568
|
+
},
|
|
569
|
+
[threadId]
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
export { AgentBuilderProvider, ThreadProvider, onThreadEvent, sendMessage, stopThread, useSendMessage, useStopThread, useThread, useThreadContext, useThreadEvent, useThreadId };
|
|
574
|
+
//# sourceMappingURL=index.js.map
|
|
575
|
+
//# sourceMappingURL=index.js.map
|