@standardagents/client 0.1.0-dev.ffffff

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,746 @@
1
+ // src/client/AgentBuilderClient.ts
2
+ var AgentBuilderClient = class {
3
+ endpoint;
4
+ token;
5
+ constructor(endpoint) {
6
+ this.endpoint = endpoint.replace(/\/$/, "");
7
+ this.token = typeof localStorage !== "undefined" ? localStorage.getItem("agentbuilder_auth_token") : null;
8
+ }
9
+ /**
10
+ * Get the current endpoint
11
+ */
12
+ getEndpoint() {
13
+ return this.endpoint;
14
+ }
15
+ /**
16
+ * Create a new thread
17
+ */
18
+ async createThread(payload) {
19
+ const response = await fetch(`${this.endpoint}/threads`, {
20
+ method: "POST",
21
+ headers: {
22
+ ...this.getHeaders(),
23
+ "Content-Type": "application/json"
24
+ },
25
+ body: JSON.stringify(payload)
26
+ });
27
+ if (!response.ok) {
28
+ throw new Error(`Failed to create thread: ${response.statusText}`);
29
+ }
30
+ return response.json();
31
+ }
32
+ /**
33
+ * Get thread metadata
34
+ */
35
+ async getThread(id) {
36
+ const response = await fetch(`${this.endpoint}/threads/${id}`, {
37
+ method: "GET",
38
+ headers: this.getHeaders()
39
+ });
40
+ if (!response.ok) {
41
+ throw new Error(`Failed to get thread: ${response.statusText}`);
42
+ }
43
+ return response.json();
44
+ }
45
+ /**
46
+ * Get messages from a thread with optional pagination and filtering
47
+ */
48
+ async getMessages(id, options = {}) {
49
+ const params = new URLSearchParams();
50
+ if (options.limit !== void 0) params.set("limit", String(options.limit));
51
+ if (options.offset !== void 0) params.set("offset", String(options.offset));
52
+ if (options.depth !== void 0) params.set("depth", String(options.depth));
53
+ if (options.includeSilent !== void 0) params.set("includeSilent", String(options.includeSilent));
54
+ const queryString = params.toString();
55
+ const url = `${this.endpoint}/threads/${id}/messages${queryString ? `?${queryString}` : ""}`;
56
+ const response = await fetch(url, {
57
+ method: "GET",
58
+ headers: this.getHeaders()
59
+ });
60
+ if (!response.ok) {
61
+ throw new Error(`Failed to get messages: ${response.statusText}`);
62
+ }
63
+ const data = await response.json();
64
+ return data.messages || [];
65
+ }
66
+ /**
67
+ * Send a message to a thread
68
+ */
69
+ async sendMessage(id, payload) {
70
+ const response = await fetch(`${this.endpoint}/threads/${id}/messages`, {
71
+ method: "POST",
72
+ headers: {
73
+ ...this.getHeaders(),
74
+ "Content-Type": "application/json"
75
+ },
76
+ body: JSON.stringify(payload)
77
+ });
78
+ if (!response.ok) {
79
+ throw new Error(`Failed to send message: ${response.statusText}`);
80
+ }
81
+ return response.json();
82
+ }
83
+ /**
84
+ * Stop execution of a thread
85
+ */
86
+ async stopExecution(id) {
87
+ const response = await fetch(`${this.endpoint}/threads/${id}/stop`, {
88
+ method: "POST",
89
+ headers: this.getHeaders()
90
+ });
91
+ if (!response.ok) {
92
+ throw new Error(`Failed to stop execution: ${response.statusText}`);
93
+ }
94
+ await response.json();
95
+ }
96
+ /**
97
+ * Options for file upload
98
+ */
99
+ /**
100
+ * Upload a file to a thread's filesystem
101
+ * @param threadId - The thread ID
102
+ * @param file - The file to upload
103
+ * @param options - Optional upload options
104
+ * @param options.thumbnail - Base64-encoded thumbnail data (for images)
105
+ * @param options.width - Image width in pixels
106
+ * @param options.height - Image height in pixels
107
+ * @returns AttachmentRef with file metadata
108
+ */
109
+ async uploadFile(threadId, file, options) {
110
+ const encodedFilename = encodeURIComponent(file.name);
111
+ const url = `${this.endpoint}/threads/${threadId}/fs/${encodedFilename}`;
112
+ if (options?.thumbnail) {
113
+ const base64Data = await this.fileToBase64(file);
114
+ const response2 = await fetch(url, {
115
+ method: "PUT",
116
+ headers: {
117
+ ...this.getHeaders(),
118
+ "Content-Type": "application/json"
119
+ },
120
+ body: JSON.stringify({
121
+ data: base64Data,
122
+ mimeType: file.type,
123
+ thumbnail: options.thumbnail,
124
+ metadata: {
125
+ width: options.width,
126
+ height: options.height
127
+ }
128
+ })
129
+ });
130
+ if (!response2.ok) {
131
+ throw new Error(`Failed to upload file: ${response2.statusText}`);
132
+ }
133
+ return response2.json();
134
+ }
135
+ const response = await fetch(url, {
136
+ method: "PUT",
137
+ headers: {
138
+ ...this.getHeaders(),
139
+ "Content-Type": file.type
140
+ },
141
+ body: file
142
+ });
143
+ if (!response.ok) {
144
+ throw new Error(`Failed to upload file: ${response.statusText}`);
145
+ }
146
+ return response.json();
147
+ }
148
+ /**
149
+ * Convert a File to base64 string
150
+ */
151
+ fileToBase64(file) {
152
+ return new Promise((resolve, reject) => {
153
+ const reader = new FileReader();
154
+ reader.onload = () => {
155
+ const result = reader.result;
156
+ const base64 = result.split(",")[1];
157
+ resolve(base64);
158
+ };
159
+ reader.onerror = () => reject(new Error("Failed to read file"));
160
+ reader.readAsDataURL(file);
161
+ });
162
+ }
163
+ /**
164
+ * Get the full URL for a file in a thread's filesystem
165
+ */
166
+ getFileUrl(threadId, path) {
167
+ const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
168
+ const encodedPath = normalizedPath.split("/").map((segment) => encodeURIComponent(segment)).join("/");
169
+ return `${this.endpoint}/threads/${threadId}/fs/${encodedPath}`;
170
+ }
171
+ /**
172
+ * Get the thumbnail URL for an image in a thread's filesystem
173
+ */
174
+ getThumbnailUrl(threadId, path) {
175
+ return `${this.getFileUrl(threadId, path)}?thumbnail=true`;
176
+ }
177
+ /**
178
+ * Connect to message WebSocket for real-time message updates
179
+ */
180
+ connectMessageWebSocket(id, callbacks = {}, options = {}) {
181
+ const params = new URLSearchParams();
182
+ if (this.token) params.set("token", this.token);
183
+ if (options.includeSilent !== void 0) params.set("includeSilent", String(options.includeSilent));
184
+ if (options.depth !== void 0) params.set("depth", String(options.depth));
185
+ const wsProtocol = this.endpoint.startsWith("https") ? "wss" : "ws";
186
+ const wsEndpoint = this.endpoint.replace(/^https?/, wsProtocol);
187
+ const url = `${wsEndpoint}/threads/${id}/stream?${params.toString()}`;
188
+ const ws = new WebSocket(url);
189
+ ws.onopen = () => {
190
+ callbacks.onOpen?.();
191
+ };
192
+ ws.onmessage = (event) => {
193
+ try {
194
+ if (typeof event.data === "string" && event.data === "pong") {
195
+ return;
196
+ }
197
+ const data = JSON.parse(event.data);
198
+ switch (data.type) {
199
+ case "message_data":
200
+ callbacks.onMessage?.(data);
201
+ break;
202
+ case "message_chunk":
203
+ callbacks.onChunk?.(data);
204
+ break;
205
+ case "event":
206
+ callbacks.onEvent?.(data);
207
+ break;
208
+ case "error":
209
+ callbacks.onError?.(data);
210
+ break;
211
+ }
212
+ } catch (error) {
213
+ console.error("Failed to parse WebSocket message:", error);
214
+ }
215
+ };
216
+ ws.onerror = (event) => {
217
+ console.error("WebSocket error:", event);
218
+ callbacks.onError?.({ type: "error", error: "WebSocket connection error" });
219
+ };
220
+ ws.onclose = (event) => {
221
+ console.log(`[AgentBuilderClient] Message WebSocket closed - code: ${event.code}, reason: ${event.reason || "none"}, wasClean: ${event.wasClean}`);
222
+ callbacks.onClose?.();
223
+ };
224
+ return ws;
225
+ }
226
+ /**
227
+ * Connect to log WebSocket for custom events
228
+ */
229
+ connectLogWebSocket(id, callbacks = {}) {
230
+ const params = new URLSearchParams();
231
+ if (this.token) params.set("token", this.token);
232
+ const wsProtocol = this.endpoint.startsWith("https") ? "wss" : "ws";
233
+ const wsEndpoint = this.endpoint.replace(/^https?/, wsProtocol);
234
+ const url = `${wsEndpoint}/threads/${id}?${params.toString()}`;
235
+ const ws = new WebSocket(url);
236
+ ws.onopen = () => {
237
+ callbacks.onOpen?.();
238
+ };
239
+ ws.onmessage = (event) => {
240
+ try {
241
+ if (typeof event.data === "string" && event.data === "pong") {
242
+ return;
243
+ }
244
+ const data = JSON.parse(event.data);
245
+ switch (data.type) {
246
+ case "log_data":
247
+ callbacks.onLog?.(data);
248
+ break;
249
+ case "custom":
250
+ callbacks.onCustom?.(data);
251
+ break;
252
+ case "stopped_by_user":
253
+ callbacks.onStopped?.(data);
254
+ break;
255
+ }
256
+ } catch (error) {
257
+ console.error("Failed to parse WebSocket message:", error);
258
+ }
259
+ };
260
+ ws.onerror = (event) => {
261
+ console.error("WebSocket error:", event);
262
+ };
263
+ ws.onclose = () => {
264
+ callbacks.onClose?.();
265
+ };
266
+ return ws;
267
+ }
268
+ /**
269
+ * Get headers for HTTP requests
270
+ */
271
+ getHeaders() {
272
+ const headers = {};
273
+ if (this.token) {
274
+ headers["Authorization"] = `Bearer ${this.token}`;
275
+ }
276
+ return headers;
277
+ }
278
+ };
279
+
280
+ // src/connection/ThreadConnectionManager.ts
281
+ var ThreadConnectionManager = class {
282
+ client;
283
+ threadId;
284
+ callbacks;
285
+ options;
286
+ ws = null;
287
+ status = "disconnected";
288
+ reconnectAttempts = 0;
289
+ reconnectTimeout = null;
290
+ heartbeatInterval = null;
291
+ isReconnecting = false;
292
+ shouldReconnect = true;
293
+ constructor(client, threadId, callbacks = {}, options = {}) {
294
+ this.client = client;
295
+ this.threadId = threadId;
296
+ this.callbacks = callbacks;
297
+ this.options = {
298
+ depth: options.depth ?? 0,
299
+ includeSilent: options.includeSilent ?? false,
300
+ heartbeatInterval: options.heartbeatInterval ?? 3e4,
301
+ maxReconnectDelay: options.maxReconnectDelay ?? 3e4
302
+ };
303
+ }
304
+ /**
305
+ * Get current connection status
306
+ */
307
+ getStatus() {
308
+ return this.status;
309
+ }
310
+ /**
311
+ * Get the thread ID this manager is connected to
312
+ */
313
+ getThreadId() {
314
+ return this.threadId;
315
+ }
316
+ /**
317
+ * Connect to the thread WebSocket
318
+ */
319
+ connect() {
320
+ if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {
321
+ return;
322
+ }
323
+ this.shouldReconnect = true;
324
+ this.isReconnecting = false;
325
+ this.setStatus("connecting");
326
+ this.ws = this.client.connectMessageWebSocket(
327
+ this.threadId,
328
+ {
329
+ onOpen: () => {
330
+ this.setStatus("connected");
331
+ this.reconnectAttempts = 0;
332
+ this.isReconnecting = false;
333
+ this.startHeartbeat();
334
+ },
335
+ onMessage: (event) => {
336
+ this.callbacks.onMessage?.(event);
337
+ },
338
+ onChunk: (event) => {
339
+ this.callbacks.onChunk?.(event);
340
+ },
341
+ onEvent: (event) => {
342
+ this.callbacks.onEvent?.(event);
343
+ },
344
+ onError: (event) => {
345
+ this.callbacks.onError?.(event);
346
+ },
347
+ onClose: () => {
348
+ this.clearTimers();
349
+ this.scheduleReconnect();
350
+ }
351
+ },
352
+ {
353
+ depth: this.options.depth,
354
+ includeSilent: this.options.includeSilent
355
+ }
356
+ );
357
+ }
358
+ /**
359
+ * Disconnect from the thread WebSocket
360
+ */
361
+ disconnect() {
362
+ this.shouldReconnect = false;
363
+ this.clearTimers();
364
+ if (this.ws) {
365
+ this.ws.close();
366
+ this.ws = null;
367
+ }
368
+ this.reconnectAttempts = 0;
369
+ this.isReconnecting = false;
370
+ this.setStatus("disconnected");
371
+ }
372
+ /**
373
+ * Update callbacks without reconnecting
374
+ */
375
+ updateCallbacks(callbacks) {
376
+ this.callbacks = { ...this.callbacks, ...callbacks };
377
+ }
378
+ /**
379
+ * Update options (requires reconnect to take effect for depth/includeSilent)
380
+ */
381
+ updateOptions(options) {
382
+ this.options = { ...this.options, ...options };
383
+ }
384
+ setStatus(status) {
385
+ if (this.status !== status) {
386
+ this.status = status;
387
+ this.callbacks.onStatusChange?.(status);
388
+ }
389
+ }
390
+ startHeartbeat() {
391
+ this.clearHeartbeat();
392
+ this.heartbeatInterval = setInterval(() => {
393
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
394
+ this.ws.send("ping");
395
+ }
396
+ }, this.options.heartbeatInterval);
397
+ }
398
+ clearHeartbeat() {
399
+ if (this.heartbeatInterval) {
400
+ clearInterval(this.heartbeatInterval);
401
+ this.heartbeatInterval = null;
402
+ }
403
+ }
404
+ clearReconnectTimeout() {
405
+ if (this.reconnectTimeout) {
406
+ clearTimeout(this.reconnectTimeout);
407
+ this.reconnectTimeout = null;
408
+ }
409
+ }
410
+ clearTimers() {
411
+ this.clearHeartbeat();
412
+ this.clearReconnectTimeout();
413
+ }
414
+ scheduleReconnect() {
415
+ if (!this.shouldReconnect || this.isReconnecting) {
416
+ this.setStatus("disconnected");
417
+ return;
418
+ }
419
+ this.isReconnecting = true;
420
+ this.setStatus("reconnecting");
421
+ const delay = Math.min(
422
+ 1e3 * Math.pow(2, this.reconnectAttempts),
423
+ this.options.maxReconnectDelay
424
+ );
425
+ this.reconnectAttempts++;
426
+ this.reconnectTimeout = setTimeout(() => {
427
+ if (this.shouldReconnect) {
428
+ this.connect();
429
+ }
430
+ }, delay);
431
+ }
432
+ };
433
+
434
+ // src/utils/attachments.ts
435
+ function parseAttachments(message) {
436
+ if (!message.attachments) {
437
+ return [];
438
+ }
439
+ try {
440
+ const parsed = JSON.parse(message.attachments);
441
+ if (!Array.isArray(parsed)) {
442
+ return [];
443
+ }
444
+ return parsed;
445
+ } catch {
446
+ return [];
447
+ }
448
+ }
449
+ function isImageMimeType(mimeType) {
450
+ return mimeType.toLowerCase().startsWith("image/");
451
+ }
452
+ function messagesToFiles(messages) {
453
+ const files = [];
454
+ for (const message of messages) {
455
+ const attachments = parseAttachments(message);
456
+ for (const attachment of attachments) {
457
+ files.push({
458
+ id: attachment.id,
459
+ name: attachment.name,
460
+ mimeType: attachment.mimeType,
461
+ size: attachment.size,
462
+ isImage: isImageMimeType(attachment.mimeType),
463
+ localPreviewUrl: null,
464
+ // Committed files don't have local preview
465
+ status: "committed",
466
+ path: attachment.path,
467
+ width: attachment.width,
468
+ height: attachment.height,
469
+ messageId: message.id
470
+ });
471
+ }
472
+ }
473
+ return files;
474
+ }
475
+
476
+ // src/utils/imageProcessing.ts
477
+ var THUMBNAIL_SIZE = 256;
478
+ function loadImage(file) {
479
+ return new Promise((resolve, reject) => {
480
+ const img = new Image();
481
+ const objectUrl = URL.createObjectURL(file);
482
+ img.onload = () => {
483
+ URL.revokeObjectURL(objectUrl);
484
+ resolve(img);
485
+ };
486
+ img.onerror = () => {
487
+ URL.revokeObjectURL(objectUrl);
488
+ reject(new Error("Failed to load image"));
489
+ };
490
+ img.src = objectUrl;
491
+ });
492
+ }
493
+ function createThumbnailFromImage(img) {
494
+ const { width, height } = img;
495
+ const aspectRatio = width / height;
496
+ let thumbWidth;
497
+ let thumbHeight;
498
+ if (aspectRatio > 1) {
499
+ thumbWidth = Math.min(THUMBNAIL_SIZE, width);
500
+ thumbHeight = Math.floor(thumbWidth / aspectRatio);
501
+ } else {
502
+ thumbHeight = Math.min(THUMBNAIL_SIZE, height);
503
+ thumbWidth = Math.floor(thumbHeight * aspectRatio);
504
+ }
505
+ const canvas = document.createElement("canvas");
506
+ canvas.width = thumbWidth;
507
+ canvas.height = thumbHeight;
508
+ const ctx = canvas.getContext("2d");
509
+ if (!ctx) {
510
+ throw new Error("Failed to get canvas context");
511
+ }
512
+ ctx.drawImage(img, 0, 0, thumbWidth, thumbHeight);
513
+ const dataUrl = canvas.toDataURL("image/webp", 0.8);
514
+ return dataUrl.split(",")[1];
515
+ }
516
+ async function generateImageThumbnail(file) {
517
+ const img = await loadImage(file);
518
+ return {
519
+ thumbnail: createThumbnailFromImage(img),
520
+ width: img.width,
521
+ height: img.height
522
+ };
523
+ }
524
+ function canGenerateThumbnails() {
525
+ return typeof document !== "undefined" && typeof document.createElement === "function";
526
+ }
527
+
528
+ // src/utils/fileHelpers.ts
529
+ function generatePendingFileId() {
530
+ return `pending-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
531
+ }
532
+ function readFileAsDataUrl(file) {
533
+ return new Promise((resolve, reject) => {
534
+ const reader = new FileReader();
535
+ reader.onload = () => resolve(reader.result);
536
+ reader.onerror = reject;
537
+ reader.readAsDataURL(file);
538
+ });
539
+ }
540
+
541
+ // src/uploads/FileUploadManager.ts
542
+ var FileUploadManager = class {
543
+ /**
544
+ * Create a pending file object from a File.
545
+ * The returned object can be immediately added to state for UI feedback.
546
+ */
547
+ createPendingFile(file) {
548
+ return {
549
+ id: generatePendingFileId(),
550
+ name: file.name,
551
+ mimeType: file.type,
552
+ size: file.size,
553
+ isImage: isImageMimeType(file.type),
554
+ localPreviewUrl: null,
555
+ status: "uploading"
556
+ };
557
+ }
558
+ /**
559
+ * Queue multiple files for upload.
560
+ * Returns an array of pending file objects paired with their source File objects.
561
+ *
562
+ * @param files - Files to queue (File array or FileList)
563
+ * @returns Array of [ThreadFile, File] tuples
564
+ */
565
+ queueFiles(files) {
566
+ return Array.from(files).map((file) => ({
567
+ pending: this.createPendingFile(file),
568
+ file
569
+ }));
570
+ }
571
+ /**
572
+ * Execute the upload for a file.
573
+ *
574
+ * This method:
575
+ * 1. Generates a local preview for images (async, non-blocking)
576
+ * 2. Generates a thumbnail for images (if supported)
577
+ * 3. Uploads the file to the server
578
+ * 4. Calls onUpdate with state changes at each step
579
+ *
580
+ * @param threadId - The thread to upload to
581
+ * @param file - The file to upload
582
+ * @param pendingId - The ID of the pending file (from queueFiles)
583
+ * @param client - The AgentBuilderClient instance
584
+ * @param onUpdate - Callback for state updates
585
+ * @param options - Upload options
586
+ */
587
+ async executeUpload(threadId, file, pendingId, client, onUpdate, options = {}) {
588
+ const {
589
+ generateThumbnail = true,
590
+ generatePreview = true
591
+ } = options;
592
+ const isImage = isImageMimeType(file.type);
593
+ if (isImage && generatePreview) {
594
+ readFileAsDataUrl(file).then((dataUrl) => onUpdate({ localPreviewUrl: dataUrl })).catch((err) => console.error("Failed to generate preview:", err));
595
+ }
596
+ try {
597
+ let uploadOptions;
598
+ if (isImage && generateThumbnail) {
599
+ try {
600
+ const result = await generateImageThumbnail(file);
601
+ uploadOptions = {
602
+ thumbnail: result.thumbnail,
603
+ width: result.width,
604
+ height: result.height
605
+ };
606
+ } catch (err) {
607
+ console.warn("Failed to generate thumbnail:", err);
608
+ }
609
+ }
610
+ const attachment = await client.uploadFile(threadId, file, uploadOptions);
611
+ onUpdate({
612
+ id: attachment.id,
613
+ status: "ready",
614
+ path: attachment.path,
615
+ width: attachment.width,
616
+ height: attachment.height
617
+ });
618
+ return attachment;
619
+ } catch (err) {
620
+ onUpdate({
621
+ status: "error",
622
+ error: err instanceof Error ? err.message : "Failed to upload file"
623
+ });
624
+ throw err;
625
+ }
626
+ }
627
+ /**
628
+ * Execute uploads for multiple files in parallel.
629
+ *
630
+ * @param threadId - The thread to upload to
631
+ * @param items - Array of pending/file pairs from queueFiles()
632
+ * @param client - The AgentBuilderClient instance
633
+ * @param onUpdate - Callback receiving (pendingId, updates) for each file
634
+ * @param options - Upload options
635
+ * @returns Array of upload results (AttachmentRef or Error for each file)
636
+ */
637
+ async executeUploads(threadId, items, client, onUpdate, options = {}) {
638
+ const promises = items.map(
639
+ ({ pending, file }) => this.executeUpload(
640
+ threadId,
641
+ file,
642
+ pending.id,
643
+ client,
644
+ (updates) => onUpdate(pending.id, updates),
645
+ options
646
+ ).catch((err) => err instanceof Error ? err : new Error(String(err)))
647
+ );
648
+ return Promise.all(promises);
649
+ }
650
+ };
651
+
652
+ // src/utils/workblocks.ts
653
+ function transformToWorkblocks(messages) {
654
+ if (messages.length === 0) {
655
+ return [];
656
+ }
657
+ const result = [];
658
+ let i = 0;
659
+ while (i < messages.length) {
660
+ const message = messages[i];
661
+ if (message.role === "assistant" && message.tool_calls) {
662
+ let toolCalls;
663
+ try {
664
+ toolCalls = JSON.parse(message.tool_calls);
665
+ } catch (error) {
666
+ result.push(message);
667
+ i++;
668
+ continue;
669
+ }
670
+ const workItems = [];
671
+ for (const toolCall of toolCalls) {
672
+ workItems.push({
673
+ id: toolCall.id || message.id,
674
+ type: "tool_call",
675
+ name: toolCall.function?.name,
676
+ content: toolCall.function?.arguments || null,
677
+ status: null,
678
+ // Will be updated below based on matching results
679
+ tool_call_id: toolCall.id
680
+ });
681
+ }
682
+ let j = i + 1;
683
+ while (j < messages.length && messages[j].role === "tool") {
684
+ const toolMessage = messages[j];
685
+ const resultStatus = toolMessage.tool_status || "pending";
686
+ workItems.push({
687
+ id: toolMessage.id,
688
+ type: "tool_result",
689
+ name: toolMessage.name || void 0,
690
+ content: toolMessage.content,
691
+ status: resultStatus,
692
+ tool_call_id: toolMessage.tool_call_id || void 0
693
+ });
694
+ j++;
695
+ }
696
+ for (const item of workItems) {
697
+ if (item.type === "tool_call" && item.tool_call_id) {
698
+ const matchingResult = workItems.find(
699
+ (wi) => wi.type === "tool_result" && wi.tool_call_id === item.tool_call_id
700
+ );
701
+ if (matchingResult) {
702
+ item.status = matchingResult.status;
703
+ } else {
704
+ item.status = "pending";
705
+ }
706
+ }
707
+ }
708
+ let status = "completed";
709
+ if (message.status === "pending") {
710
+ status = "pending";
711
+ } else if (message.status === "failed") {
712
+ status = "failed";
713
+ }
714
+ const workblock = {
715
+ id: message.id,
716
+ type: "workblock",
717
+ content: message.content,
718
+ reasoning_content: message.reasoning_content,
719
+ workItems,
720
+ status,
721
+ created_at: message.created_at,
722
+ depth: message.depth
723
+ };
724
+ result.push(workblock);
725
+ i = j;
726
+ } else {
727
+ result.push(message);
728
+ i++;
729
+ }
730
+ }
731
+ return result;
732
+ }
733
+ export {
734
+ AgentBuilderClient,
735
+ FileUploadManager,
736
+ ThreadConnectionManager,
737
+ canGenerateThumbnails,
738
+ generateImageThumbnail,
739
+ generatePendingFileId,
740
+ isImageMimeType,
741
+ messagesToFiles,
742
+ parseAttachments,
743
+ readFileAsDataUrl,
744
+ transformToWorkblocks
745
+ };
746
+ //# sourceMappingURL=index.js.map