@standardagents/client 0.11.0-next.ab7e1ea → 0.11.0-next.c3b4490

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 CHANGED
@@ -16,7 +16,7 @@ interface Message {
16
16
  reasoning_details?: string | null;
17
17
  parent_id?: string | null;
18
18
  depth?: number;
19
- attachments?: string | null;
19
+ attachments?: string | AttachmentRef[] | null;
20
20
  }
21
21
  /**
22
22
  * Attachment reference stored in messages.attachments (JSON array)
@@ -95,6 +95,7 @@ interface WorkMessage {
95
95
  status: "pending" | "completed" | "failed";
96
96
  created_at: number;
97
97
  depth?: number;
98
+ attachments?: AttachmentRef[];
98
99
  }
99
100
  type ThreadMessage = Message | WorkMessage;
100
101
  interface AgentBuilderConfig {
@@ -185,6 +186,7 @@ interface ThreadConnectionCallbacks {
185
186
  }
186
187
  interface CreateThreadPayload {
187
188
  agent_id: string;
189
+ user_id?: string;
188
190
  metadata?: Record<string, any>;
189
191
  }
190
192
 
@@ -216,6 +218,15 @@ declare class AgentBuilderClient {
216
218
  * Stop execution of a thread
217
219
  */
218
220
  stopExecution(id: string): Promise<void>;
221
+ /**
222
+ * Delete a message from a thread
223
+ * @param threadId - The thread ID
224
+ * @param messageId - The message ID to delete
225
+ * @returns Object with success status
226
+ */
227
+ deleteMessage(threadId: string, messageId: string): Promise<{
228
+ success: boolean;
229
+ }>;
219
230
  /**
220
231
  * Options for file upload
221
232
  */
@@ -246,6 +257,20 @@ declare class AgentBuilderClient {
246
257
  * Get the thumbnail URL for an image in a thread's filesystem
247
258
  */
248
259
  getThumbnailUrl(threadId: string, path: string): string;
260
+ /**
261
+ * List all files in a thread's filesystem
262
+ * @param threadId - The thread ID
263
+ * @returns Array of file records
264
+ */
265
+ listFiles(threadId: string): Promise<Array<{
266
+ path: string;
267
+ name: string;
268
+ mimeType: string;
269
+ size: number;
270
+ isDirectory: boolean;
271
+ createdAt?: number;
272
+ updatedAt?: number;
273
+ }>>;
249
274
  /**
250
275
  * Connect to message WebSocket for real-time message updates
251
276
  */
@@ -439,15 +464,19 @@ declare class FileUploadManager {
439
464
  * Groups consecutive assistant tool_calls and their tool results into WorkMessage objects.
440
465
  *
441
466
  * A workblock starts when an assistant message has tool_calls,
442
- * and includes all subsequent tool messages until:
443
- * - A non-tool message appears
444
- * - Another assistant message without tool_calls appears
467
+ * and continues to include ALL subsequent messages until:
468
+ * - A user message appears
469
+ * - An assistant message without tool_calls appears
470
+ *
471
+ * This means multiple assistant messages with tool_calls in a row
472
+ * (with their tool results in between) are merged into a single workblock.
445
473
  */
446
474
  declare function transformToWorkblocks(messages: Message[]): ThreadMessage[];
447
475
 
448
476
  /**
449
- * Parse attachments JSON from a message
450
- * Returns empty array if no attachments or invalid JSON
477
+ * Parse attachments from a message
478
+ * Handles both JSON string and already-parsed array formats
479
+ * Returns empty array if no attachments or invalid data
451
480
  */
452
481
  declare function parseAttachments(message: Message): AttachmentRef[];
453
482
  /**
package/dist/index.js CHANGED
@@ -93,6 +93,25 @@ var AgentBuilderClient = class {
93
93
  }
94
94
  await response.json();
95
95
  }
96
+ /**
97
+ * Delete a message from a thread
98
+ * @param threadId - The thread ID
99
+ * @param messageId - The message ID to delete
100
+ * @returns Object with success status
101
+ */
102
+ async deleteMessage(threadId, messageId) {
103
+ const response = await fetch(
104
+ `${this.endpoint}/threads/${threadId}/messages/${messageId}`,
105
+ {
106
+ method: "DELETE",
107
+ headers: this.getHeaders()
108
+ }
109
+ );
110
+ if (!response.ok) {
111
+ throw new Error(`Failed to delete message: ${response.statusText}`);
112
+ }
113
+ return response.json();
114
+ }
96
115
  /**
97
116
  * Options for file upload
98
117
  */
@@ -112,7 +131,7 @@ var AgentBuilderClient = class {
112
131
  if (options?.thumbnail) {
113
132
  const base64Data = await this.fileToBase64(file);
114
133
  const response2 = await fetch(url, {
115
- method: "PUT",
134
+ method: "POST",
116
135
  headers: {
117
136
  ...this.getHeaders(),
118
137
  "Content-Type": "application/json"
@@ -133,7 +152,7 @@ var AgentBuilderClient = class {
133
152
  return response2.json();
134
153
  }
135
154
  const response = await fetch(url, {
136
- method: "PUT",
155
+ method: "POST",
137
156
  headers: {
138
157
  ...this.getHeaders(),
139
158
  "Content-Type": file.type
@@ -174,6 +193,25 @@ var AgentBuilderClient = class {
174
193
  getThumbnailUrl(threadId, path) {
175
194
  return `${this.getFileUrl(threadId, path)}?thumbnail=true`;
176
195
  }
196
+ /**
197
+ * List all files in a thread's filesystem
198
+ * @param threadId - The thread ID
199
+ * @returns Array of file records
200
+ */
201
+ async listFiles(threadId) {
202
+ const response = await fetch(
203
+ `${this.endpoint}/threads/${threadId}/fs?find=**/*&type=file`,
204
+ {
205
+ method: "GET",
206
+ headers: this.getHeaders()
207
+ }
208
+ );
209
+ if (!response.ok) {
210
+ throw new Error(`Failed to list files: ${response.statusText}`);
211
+ }
212
+ const data = await response.json();
213
+ return data.files || [];
214
+ }
177
215
  /**
178
216
  * Connect to message WebSocket for real-time message updates
179
217
  */
@@ -436,6 +474,9 @@ function parseAttachments(message) {
436
474
  if (!message.attachments) {
437
475
  return [];
438
476
  }
477
+ if (Array.isArray(message.attachments)) {
478
+ return message.attachments;
479
+ }
439
480
  try {
440
481
  const parsed = JSON.parse(message.attachments);
441
482
  if (!Array.isArray(parsed)) {
@@ -668,6 +709,21 @@ function transformToWorkblocks(messages) {
668
709
  continue;
669
710
  }
670
711
  const workItems = [];
712
+ const contentParts = [];
713
+ const collectedAttachments = [];
714
+ let reasoningContent = message.reasoning_content || null;
715
+ let workblockStatus = "completed";
716
+ const firstMessageId = message.id;
717
+ const firstCreatedAt = message.created_at;
718
+ const depth = message.depth;
719
+ if (message.status === "pending") {
720
+ workblockStatus = "pending";
721
+ } else if (message.status === "failed") {
722
+ workblockStatus = "failed";
723
+ }
724
+ if (message.content) {
725
+ contentParts.push(message.content);
726
+ }
671
727
  for (const toolCall of toolCalls) {
672
728
  workItems.push({
673
729
  id: toolCall.id || message.id,
@@ -680,21 +736,85 @@ function transformToWorkblocks(messages) {
680
736
  });
681
737
  }
682
738
  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++;
739
+ while (j < messages.length) {
740
+ const nextMessage = messages[j];
741
+ if (nextMessage.role === "tool") {
742
+ const resultStatus = nextMessage.tool_status || "pending";
743
+ workItems.push({
744
+ id: nextMessage.id,
745
+ type: "tool_result",
746
+ name: nextMessage.name || void 0,
747
+ content: nextMessage.content,
748
+ status: resultStatus,
749
+ tool_call_id: nextMessage.tool_call_id || void 0
750
+ });
751
+ if (nextMessage.attachments) {
752
+ try {
753
+ let attachments;
754
+ if (typeof nextMessage.attachments === "string") {
755
+ attachments = JSON.parse(nextMessage.attachments);
756
+ } else if (Array.isArray(nextMessage.attachments)) {
757
+ attachments = nextMessage.attachments;
758
+ } else {
759
+ attachments = [];
760
+ }
761
+ collectedAttachments.push(...attachments);
762
+ } catch {
763
+ }
764
+ }
765
+ j++;
766
+ } else if (nextMessage.role === "assistant" && nextMessage.tool_calls) {
767
+ let nextToolCalls;
768
+ try {
769
+ nextToolCalls = JSON.parse(nextMessage.tool_calls);
770
+ } catch (error) {
771
+ break;
772
+ }
773
+ if (nextMessage.status === "pending") {
774
+ workblockStatus = "pending";
775
+ } else if (nextMessage.status === "failed" && workblockStatus !== "pending") {
776
+ workblockStatus = "failed";
777
+ }
778
+ if (nextMessage.content) {
779
+ contentParts.push(nextMessage.content);
780
+ }
781
+ if (!reasoningContent && nextMessage.reasoning_content) {
782
+ reasoningContent = nextMessage.reasoning_content;
783
+ }
784
+ for (const toolCall of nextToolCalls) {
785
+ workItems.push({
786
+ id: toolCall.id || nextMessage.id,
787
+ type: "tool_call",
788
+ name: toolCall.function?.name,
789
+ content: toolCall.function?.arguments || null,
790
+ status: null,
791
+ tool_call_id: toolCall.id
792
+ });
793
+ }
794
+ j++;
795
+ } else {
796
+ break;
797
+ }
798
+ }
799
+ const toolCallIds = new Set(workItems.filter((w) => w.type === "tool_call").map((w) => w.tool_call_id));
800
+ const orphanedResults = workItems.filter(
801
+ (w) => w.type === "tool_result" && w.tool_call_id && !toolCallIds.has(w.tool_call_id)
802
+ );
803
+ for (const orphan of orphanedResults) {
804
+ const orphanIndex = workItems.indexOf(orphan);
805
+ const toolName = orphan.content?.match(/Tool not found: (\w+)/)?.[1] || "unknown_tool";
806
+ const syntheticCall = {
807
+ id: `synthetic-${orphan.tool_call_id}`,
808
+ type: "tool_call",
809
+ name: toolName,
810
+ content: null,
811
+ status: orphan.status,
812
+ tool_call_id: orphan.tool_call_id
813
+ };
814
+ workItems.splice(orphanIndex, 0, syntheticCall);
695
815
  }
696
816
  for (const item of workItems) {
697
- if (item.type === "tool_call" && item.tool_call_id) {
817
+ if (item.type === "tool_call" && item.tool_call_id && item.status === null) {
698
818
  const matchingResult = workItems.find(
699
819
  (wi) => wi.type === "tool_result" && wi.tool_call_id === item.tool_call_id
700
820
  );
@@ -705,21 +825,17 @@ function transformToWorkblocks(messages) {
705
825
  }
706
826
  }
707
827
  }
708
- let status = "completed";
709
- if (message.status === "pending") {
710
- status = "pending";
711
- } else if (message.status === "failed") {
712
- status = "failed";
713
- }
828
+ const combinedContent = contentParts.length > 0 ? contentParts.join("") : null;
714
829
  const workblock = {
715
- id: message.id,
830
+ id: firstMessageId,
716
831
  type: "workblock",
717
- content: message.content,
718
- reasoning_content: message.reasoning_content,
832
+ content: combinedContent,
833
+ reasoning_content: reasoningContent,
719
834
  workItems,
720
- status,
721
- created_at: message.created_at,
722
- depth: message.depth
835
+ status: workblockStatus,
836
+ created_at: firstCreatedAt,
837
+ depth,
838
+ attachments: collectedAttachments.length > 0 ? collectedAttachments : void 0
723
839
  };
724
840
  result.push(workblock);
725
841
  i = j;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/AgentBuilderClient.ts","../src/connection/ThreadConnectionManager.ts","../src/utils/attachments.ts","../src/utils/imageProcessing.ts","../src/utils/fileHelpers.ts","../src/uploads/FileUploadManager.ts","../src/utils/workblocks.ts"],"sourcesContent":["import type {\n Message,\n Thread,\n SendMessagePayload,\n GetMessagesOptions,\n MessageWebSocketCallbacks,\n LogWebSocketCallbacks,\n MessageStreamEvent,\n LogStreamEvent,\n ThreadEvent,\n CreateThreadPayload,\n AttachmentRef,\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 the current endpoint\n */\n getEndpoint(): string {\n return this.endpoint\n }\n\n /**\n * Create a new thread\n */\n async createThread(payload: CreateThreadPayload): Promise<Thread> {\n const response = await fetch(`${this.endpoint}/threads`, {\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 create thread: ${response.statusText}`)\n }\n\n return response.json()\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}/messages`, {\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 * Options for file upload\n */\n /**\n * Upload a file to a thread's filesystem\n * @param threadId - The thread ID\n * @param file - The file to upload\n * @param options - Optional upload options\n * @param options.thumbnail - Base64-encoded thumbnail data (for images)\n * @param options.width - Image width in pixels\n * @param options.height - Image height in pixels\n * @returns AttachmentRef with file metadata\n */\n async uploadFile(\n threadId: string,\n file: File,\n options?: {\n thumbnail?: string\n width?: number\n height?: number\n }\n ): Promise<AttachmentRef> {\n const encodedFilename = encodeURIComponent(file.name)\n const url = `${this.endpoint}/threads/${threadId}/fs/${encodedFilename}`\n\n // If thumbnail provided, use JSON format with base64 data\n if (options?.thumbnail) {\n const base64Data = await this.fileToBase64(file)\n\n const response = await fetch(url, {\n method: 'PUT',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n data: base64Data,\n mimeType: file.type,\n thumbnail: options.thumbnail,\n metadata: {\n width: options.width,\n height: options.height,\n },\n }),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to upload file: ${response.statusText}`)\n }\n\n return response.json()\n }\n\n // For non-image files or when no thumbnail, use raw binary upload\n const response = await fetch(url, {\n method: 'PUT',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': file.type,\n },\n body: file,\n })\n\n if (!response.ok) {\n throw new Error(`Failed to upload file: ${response.statusText}`)\n }\n\n return response.json()\n }\n\n /**\n * Convert a File to base64 string\n */\n private fileToBase64(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => {\n const result = reader.result as string\n // Remove data URL prefix (e.g., \"data:image/jpeg;base64,\")\n const base64 = result.split(',')[1]\n resolve(base64)\n }\n reader.onerror = () => reject(new Error('Failed to read file'))\n reader.readAsDataURL(file)\n })\n }\n\n /**\n * Get the full URL for a file in a thread's filesystem\n */\n getFileUrl(threadId: string, path: string): string {\n // Normalize path - remove leading slash and encode special characters\n const normalizedPath = path.startsWith('/') ? path.slice(1) : path\n const encodedPath = normalizedPath\n .split('/')\n .map(segment => encodeURIComponent(segment))\n .join('/')\n\n return `${this.endpoint}/threads/${threadId}/fs/${encodedPath}`\n }\n\n /**\n * Get the thumbnail URL for an image in a thread's filesystem\n */\n getThumbnailUrl(threadId: string, path: string): string {\n return `${this.getFileUrl(threadId, path)}?thumbnail=true`\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 { AgentBuilderClient } from '../client/AgentBuilderClient'\nimport type {\n ConnectionStatus,\n ThreadConnectionCallbacks,\n MessageDataEvent,\n MessageChunkEvent,\n ThreadEvent,\n ErrorEvent,\n} from '../types'\n\nexport interface ThreadConnectionOptions {\n /** Maximum message depth to stream (default: 0 for top-level only) */\n depth?: number\n /** Whether to include silent messages (default: false) */\n includeSilent?: boolean\n /** Heartbeat interval in milliseconds (default: 30000) */\n heartbeatInterval?: number\n /** Maximum reconnection delay in milliseconds (default: 30000) */\n maxReconnectDelay?: number\n}\n\n/**\n * ThreadConnectionManager handles WebSocket connection lifecycle for a thread.\n * Provides automatic reconnection with exponential backoff and heartbeat keep-alive.\n *\n * This class is framework-agnostic. React and Vue SDKs use this internally\n * and handle their own reactive state management.\n *\n * @example\n * ```typescript\n * const manager = new ThreadConnectionManager(client, 'thread-123', {\n * onMessage: (event) => updateMessages(event.data),\n * onChunk: (event) => appendChunk(event.chunk),\n * onStatusChange: (status) => setConnectionStatus(status),\n * })\n *\n * manager.connect()\n * // ... later\n * manager.disconnect()\n * ```\n */\nexport class ThreadConnectionManager {\n private client: AgentBuilderClient\n private threadId: string\n private callbacks: ThreadConnectionCallbacks\n private options: Required<ThreadConnectionOptions>\n\n private ws: WebSocket | null = null\n private status: ConnectionStatus = 'disconnected'\n private reconnectAttempts: number = 0\n private reconnectTimeout: ReturnType<typeof setTimeout> | null = null\n private heartbeatInterval: ReturnType<typeof setInterval> | null = null\n private isReconnecting: boolean = false\n private shouldReconnect: boolean = true\n\n constructor(\n client: AgentBuilderClient,\n threadId: string,\n callbacks: ThreadConnectionCallbacks = {},\n options: ThreadConnectionOptions = {}\n ) {\n this.client = client\n this.threadId = threadId\n this.callbacks = callbacks\n this.options = {\n depth: options.depth ?? 0,\n includeSilent: options.includeSilent ?? false,\n heartbeatInterval: options.heartbeatInterval ?? 30000,\n maxReconnectDelay: options.maxReconnectDelay ?? 30000,\n }\n }\n\n /**\n * Get current connection status\n */\n getStatus(): ConnectionStatus {\n return this.status\n }\n\n /**\n * Get the thread ID this manager is connected to\n */\n getThreadId(): string {\n return this.threadId\n }\n\n /**\n * Connect to the thread WebSocket\n */\n connect(): void {\n if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {\n // Already connected or connecting\n return\n }\n\n this.shouldReconnect = true\n this.isReconnecting = false\n this.setStatus('connecting')\n\n this.ws = this.client.connectMessageWebSocket(\n this.threadId,\n {\n onOpen: () => {\n this.setStatus('connected')\n this.reconnectAttempts = 0\n this.isReconnecting = false\n this.startHeartbeat()\n },\n onMessage: (event: MessageDataEvent) => {\n this.callbacks.onMessage?.(event)\n },\n onChunk: (event: MessageChunkEvent) => {\n this.callbacks.onChunk?.(event)\n },\n onEvent: (event: ThreadEvent) => {\n this.callbacks.onEvent?.(event)\n },\n onError: (event: ErrorEvent) => {\n this.callbacks.onError?.(event)\n },\n onClose: () => {\n this.clearTimers()\n this.scheduleReconnect()\n },\n },\n {\n depth: this.options.depth,\n includeSilent: this.options.includeSilent,\n }\n )\n }\n\n /**\n * Disconnect from the thread WebSocket\n */\n disconnect(): void {\n this.shouldReconnect = false\n this.clearTimers()\n\n if (this.ws) {\n this.ws.close()\n this.ws = null\n }\n\n this.reconnectAttempts = 0\n this.isReconnecting = false\n this.setStatus('disconnected')\n }\n\n /**\n * Update callbacks without reconnecting\n */\n updateCallbacks(callbacks: Partial<ThreadConnectionCallbacks>): void {\n this.callbacks = { ...this.callbacks, ...callbacks }\n }\n\n /**\n * Update options (requires reconnect to take effect for depth/includeSilent)\n */\n updateOptions(options: Partial<ThreadConnectionOptions>): void {\n this.options = { ...this.options, ...options }\n }\n\n private setStatus(status: ConnectionStatus): void {\n if (this.status !== status) {\n this.status = status\n this.callbacks.onStatusChange?.(status)\n }\n }\n\n private startHeartbeat(): void {\n this.clearHeartbeat()\n\n this.heartbeatInterval = setInterval(() => {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send('ping')\n }\n }, this.options.heartbeatInterval)\n }\n\n private clearHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval)\n this.heartbeatInterval = null\n }\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout)\n this.reconnectTimeout = null\n }\n }\n\n private clearTimers(): void {\n this.clearHeartbeat()\n this.clearReconnectTimeout()\n }\n\n private scheduleReconnect(): void {\n if (!this.shouldReconnect || this.isReconnecting) {\n this.setStatus('disconnected')\n return\n }\n\n this.isReconnecting = true\n this.setStatus('reconnecting')\n\n // Exponential backoff: 1s, 2s, 4s, 8s, 16s, 30s (max)\n const delay = Math.min(\n 1000 * Math.pow(2, this.reconnectAttempts),\n this.options.maxReconnectDelay\n )\n this.reconnectAttempts++\n\n this.reconnectTimeout = setTimeout(() => {\n if (this.shouldReconnect) {\n this.connect()\n }\n }, delay)\n }\n}\n","import type { Message, AttachmentRef, ThreadFile } from '../types'\n\n/**\n * Parse attachments JSON from a message\n * Returns empty array if no attachments or invalid JSON\n */\nexport function parseAttachments(message: Message): AttachmentRef[] {\n if (!message.attachments) {\n return []\n }\n\n try {\n const parsed = JSON.parse(message.attachments)\n if (!Array.isArray(parsed)) {\n return []\n }\n return parsed\n } catch {\n return []\n }\n}\n\n/**\n * Check if a MIME type represents an image\n */\nexport function isImageMimeType(mimeType: string): boolean {\n return mimeType.toLowerCase().startsWith('image/')\n}\n\n/**\n * Convert messages to ThreadFile array\n * Extracts all committed files from message attachments\n */\nexport function messagesToFiles(messages: Message[]): ThreadFile[] {\n const files: ThreadFile[] = []\n\n for (const message of messages) {\n const attachments = parseAttachments(message)\n\n for (const attachment of attachments) {\n files.push({\n id: attachment.id,\n name: attachment.name,\n mimeType: attachment.mimeType,\n size: attachment.size,\n isImage: isImageMimeType(attachment.mimeType),\n localPreviewUrl: null, // Committed files don't have local preview\n status: 'committed',\n path: attachment.path,\n width: attachment.width,\n height: attachment.height,\n messageId: message.id,\n })\n }\n }\n\n return files\n}\n","/**\n * Image processing utilities for thumbnail generation\n * These functions require a browser environment with Canvas support\n */\n\nconst THUMBNAIL_SIZE = 256\n\n/**\n * Result of processing an image file\n */\nexport interface ImageProcessingResult {\n /** Base64-encoded thumbnail data (without data URL prefix) */\n thumbnail: string\n /** Original image width */\n width: number\n /** Original image height */\n height: number\n}\n\n/**\n * Load an image from a File object\n */\nfunction loadImage(file: File): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image()\n const objectUrl = URL.createObjectURL(file)\n\n img.onload = () => {\n URL.revokeObjectURL(objectUrl)\n resolve(img)\n }\n img.onerror = () => {\n URL.revokeObjectURL(objectUrl)\n reject(new Error('Failed to load image'))\n }\n img.src = objectUrl\n })\n}\n\n/**\n * Create a thumbnail from an image element\n * Returns base64 data without the data URL prefix\n */\nfunction createThumbnailFromImage(img: HTMLImageElement): string {\n const { width, height } = img\n const aspectRatio = width / height\n\n let thumbWidth: number\n let thumbHeight: number\n\n if (aspectRatio > 1) {\n thumbWidth = Math.min(THUMBNAIL_SIZE, width)\n thumbHeight = Math.floor(thumbWidth / aspectRatio)\n } else {\n thumbHeight = Math.min(THUMBNAIL_SIZE, height)\n thumbWidth = Math.floor(thumbHeight * aspectRatio)\n }\n\n const canvas = document.createElement('canvas')\n canvas.width = thumbWidth\n canvas.height = thumbHeight\n\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n throw new Error('Failed to get canvas context')\n }\n\n ctx.drawImage(img, 0, 0, thumbWidth, thumbHeight)\n\n // Return WebP for smaller size, strip data URL prefix\n const dataUrl = canvas.toDataURL('image/webp', 0.8)\n return dataUrl.split(',')[1]\n}\n\n/**\n * Process an image file to generate a thumbnail\n * @param file - The image file to process\n * @returns Promise with thumbnail data and dimensions\n */\nexport async function generateImageThumbnail(file: File): Promise<ImageProcessingResult> {\n const img = await loadImage(file)\n\n return {\n thumbnail: createThumbnailFromImage(img),\n width: img.width,\n height: img.height,\n }\n}\n\n/**\n * Check if the current environment supports Canvas (for thumbnail generation)\n */\nexport function canGenerateThumbnails(): boolean {\n return typeof document !== 'undefined' && typeof document.createElement === 'function'\n}\n","/**\n * File upload helper utilities\n */\n\n/**\n * Generate a unique ID for pending file uploads.\n * Uses timestamp + random string to ensure uniqueness.\n */\nexport function generatePendingFileId(): string {\n return `pending-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n}\n\n/**\n * Read a file as a data URL for image preview.\n * Returns a base64-encoded data URL that can be used as an image src.\n */\nexport function readFileAsDataUrl(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => resolve(reader.result as string)\n reader.onerror = reject\n reader.readAsDataURL(file)\n })\n}\n","/**\n * FileUploadManager - Framework-agnostic file upload management\n *\n * Handles the common logic for file uploads across Vue and React packages.\n * Each framework integrates this manager with its own state management.\n */\n\nimport type { ThreadFile, AttachmentRef } from '../types'\nimport type { AgentBuilderClient } from '../client/AgentBuilderClient'\nimport { isImageMimeType } from '../utils/attachments'\nimport { generateImageThumbnail } from '../utils/imageProcessing'\nimport { generatePendingFileId, readFileAsDataUrl } from '../utils/fileHelpers'\n\n/**\n * Callback for receiving file state updates during upload\n */\nexport type FileUpdateCallback = (updates: Partial<ThreadFile>) => void\n\n/**\n * Options for upload execution\n */\nexport interface UploadOptions {\n /** Generate and upload thumbnail for images (default: true) */\n generateThumbnail?: boolean\n /** Generate local preview URL for images (default: true) */\n generatePreview?: boolean\n}\n\n/**\n * FileUploadManager handles the upload lifecycle for files.\n *\n * Usage:\n * 1. Call queueFiles() to create pending file objects for immediate UI display\n * 2. Call executeUpload() for each file to start the actual upload\n * 3. Receive state updates via the callback to update your framework's state\n *\n * @example\n * ```typescript\n * const manager = new FileUploadManager()\n *\n * // Queue files for UI display\n * const pendingFiles = manager.queueFiles(selectedFiles)\n * setState(prev => [...prev, ...pendingFiles])\n *\n * // Start uploads\n * for (const pending of pendingFiles) {\n * manager.executeUpload(threadId, file, pending.id, client, (updates) => {\n * setState(prev => prev.map(f =>\n * f.id === pending.id ? { ...f, ...updates } : f\n * ))\n * })\n * }\n * ```\n */\nexport class FileUploadManager {\n /**\n * Create a pending file object from a File.\n * The returned object can be immediately added to state for UI feedback.\n */\n createPendingFile(file: File): ThreadFile {\n return {\n id: generatePendingFileId(),\n name: file.name,\n mimeType: file.type,\n size: file.size,\n isImage: isImageMimeType(file.type),\n localPreviewUrl: null,\n status: 'uploading',\n }\n }\n\n /**\n * Queue multiple files for upload.\n * Returns an array of pending file objects paired with their source File objects.\n *\n * @param files - Files to queue (File array or FileList)\n * @returns Array of [ThreadFile, File] tuples\n */\n queueFiles(files: File[] | FileList): Array<{ pending: ThreadFile; file: File }> {\n return Array.from(files).map(file => ({\n pending: this.createPendingFile(file),\n file,\n }))\n }\n\n /**\n * Execute the upload for a file.\n *\n * This method:\n * 1. Generates a local preview for images (async, non-blocking)\n * 2. Generates a thumbnail for images (if supported)\n * 3. Uploads the file to the server\n * 4. Calls onUpdate with state changes at each step\n *\n * @param threadId - The thread to upload to\n * @param file - The file to upload\n * @param pendingId - The ID of the pending file (from queueFiles)\n * @param client - The AgentBuilderClient instance\n * @param onUpdate - Callback for state updates\n * @param options - Upload options\n */\n async executeUpload(\n threadId: string,\n file: File,\n pendingId: string,\n client: AgentBuilderClient,\n onUpdate: FileUpdateCallback,\n options: UploadOptions = {}\n ): Promise<AttachmentRef> {\n const {\n generateThumbnail = true,\n generatePreview = true,\n } = options\n\n const isImage = isImageMimeType(file.type)\n\n // Generate local preview for images (async, doesn't block upload)\n if (isImage && generatePreview) {\n readFileAsDataUrl(file)\n .then(dataUrl => onUpdate({ localPreviewUrl: dataUrl }))\n .catch(err => console.error('Failed to generate preview:', err))\n }\n\n try {\n // Prepare upload options for images\n let uploadOptions: Parameters<typeof client.uploadFile>[2] | undefined\n\n if (isImage && generateThumbnail) {\n try {\n const result = await generateImageThumbnail(file)\n uploadOptions = {\n thumbnail: result.thumbnail,\n width: result.width,\n height: result.height,\n }\n } catch (err) {\n // If thumbnail generation fails, continue without it\n console.warn('Failed to generate thumbnail:', err)\n }\n }\n\n // Upload the file\n const attachment = await client.uploadFile(threadId, file, uploadOptions)\n\n // Update with server response\n onUpdate({\n id: attachment.id,\n status: 'ready',\n path: attachment.path,\n width: attachment.width,\n height: attachment.height,\n })\n\n return attachment\n } catch (err) {\n // Update with error state\n onUpdate({\n status: 'error',\n error: err instanceof Error ? err.message : 'Failed to upload file',\n })\n throw err\n }\n }\n\n /**\n * Execute uploads for multiple files in parallel.\n *\n * @param threadId - The thread to upload to\n * @param items - Array of pending/file pairs from queueFiles()\n * @param client - The AgentBuilderClient instance\n * @param onUpdate - Callback receiving (pendingId, updates) for each file\n * @param options - Upload options\n * @returns Array of upload results (AttachmentRef or Error for each file)\n */\n async executeUploads(\n threadId: string,\n items: Array<{ pending: ThreadFile; file: File }>,\n client: AgentBuilderClient,\n onUpdate: (pendingId: string, updates: Partial<ThreadFile>) => void,\n options: UploadOptions = {}\n ): Promise<Array<AttachmentRef | Error>> {\n const promises = items.map(({ pending, file }) =>\n this.executeUpload(\n threadId,\n file,\n pending.id,\n client,\n (updates) => onUpdate(pending.id, updates),\n options\n ).catch(err => err instanceof Error ? err : new Error(String(err)))\n )\n\n return Promise.all(promises)\n }\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"],"mappings":"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","names":["response"]}
1
+ {"version":3,"sources":["../src/client/AgentBuilderClient.ts","../src/connection/ThreadConnectionManager.ts","../src/utils/attachments.ts","../src/utils/imageProcessing.ts","../src/utils/fileHelpers.ts","../src/uploads/FileUploadManager.ts","../src/utils/workblocks.ts"],"sourcesContent":["import type {\n Message,\n Thread,\n SendMessagePayload,\n GetMessagesOptions,\n MessageWebSocketCallbacks,\n LogWebSocketCallbacks,\n MessageStreamEvent,\n LogStreamEvent,\n ThreadEvent,\n CreateThreadPayload,\n AttachmentRef,\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 the current endpoint\n */\n getEndpoint(): string {\n return this.endpoint\n }\n\n /**\n * Create a new thread\n */\n async createThread(payload: CreateThreadPayload): Promise<Thread> {\n const response = await fetch(`${this.endpoint}/threads`, {\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 create thread: ${response.statusText}`)\n }\n\n return response.json()\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}/messages`, {\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 * Delete a message from a thread\n * @param threadId - The thread ID\n * @param messageId - The message ID to delete\n * @returns Object with success status\n */\n async deleteMessage(\n threadId: string,\n messageId: string\n ): Promise<{ success: boolean }> {\n const response = await fetch(\n `${this.endpoint}/threads/${threadId}/messages/${messageId}`,\n {\n method: 'DELETE',\n headers: this.getHeaders(),\n }\n )\n\n if (!response.ok) {\n throw new Error(`Failed to delete message: ${response.statusText}`)\n }\n\n return response.json()\n }\n\n /**\n * Options for file upload\n */\n /**\n * Upload a file to a thread's filesystem\n * @param threadId - The thread ID\n * @param file - The file to upload\n * @param options - Optional upload options\n * @param options.thumbnail - Base64-encoded thumbnail data (for images)\n * @param options.width - Image width in pixels\n * @param options.height - Image height in pixels\n * @returns AttachmentRef with file metadata\n */\n async uploadFile(\n threadId: string,\n file: File,\n options?: {\n thumbnail?: string\n width?: number\n height?: number\n }\n ): Promise<AttachmentRef> {\n const encodedFilename = encodeURIComponent(file.name)\n const url = `${this.endpoint}/threads/${threadId}/fs/${encodedFilename}`\n\n // If thumbnail provided, use JSON format with base64 data\n if (options?.thumbnail) {\n const base64Data = await this.fileToBase64(file)\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n data: base64Data,\n mimeType: file.type,\n thumbnail: options.thumbnail,\n metadata: {\n width: options.width,\n height: options.height,\n },\n }),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to upload file: ${response.statusText}`)\n }\n\n return response.json()\n }\n\n // For non-image files or when no thumbnail, use raw binary upload\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': file.type,\n },\n body: file,\n })\n\n if (!response.ok) {\n throw new Error(`Failed to upload file: ${response.statusText}`)\n }\n\n return response.json()\n }\n\n /**\n * Convert a File to base64 string\n */\n private fileToBase64(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => {\n const result = reader.result as string\n // Remove data URL prefix (e.g., \"data:image/jpeg;base64,\")\n const base64 = result.split(',')[1]\n resolve(base64)\n }\n reader.onerror = () => reject(new Error('Failed to read file'))\n reader.readAsDataURL(file)\n })\n }\n\n /**\n * Get the full URL for a file in a thread's filesystem\n */\n getFileUrl(threadId: string, path: string): string {\n // Normalize path - remove leading slash and encode special characters\n const normalizedPath = path.startsWith('/') ? path.slice(1) : path\n const encodedPath = normalizedPath\n .split('/')\n .map(segment => encodeURIComponent(segment))\n .join('/')\n\n return `${this.endpoint}/threads/${threadId}/fs/${encodedPath}`\n }\n\n /**\n * Get the thumbnail URL for an image in a thread's filesystem\n */\n getThumbnailUrl(threadId: string, path: string): string {\n return `${this.getFileUrl(threadId, path)}?thumbnail=true`\n }\n\n /**\n * List all files in a thread's filesystem\n * @param threadId - The thread ID\n * @returns Array of file records\n */\n async listFiles(threadId: string): Promise<Array<{\n path: string\n name: string\n mimeType: string\n size: number\n isDirectory: boolean\n createdAt?: number\n updatedAt?: number\n }>> {\n // Use find API to recursively list all files\n const response = await fetch(\n `${this.endpoint}/threads/${threadId}/fs?find=**/*&type=file`,\n {\n method: 'GET',\n headers: this.getHeaders(),\n }\n )\n\n if (!response.ok) {\n throw new Error(`Failed to list files: ${response.statusText}`)\n }\n\n const data = await response.json()\n return data.files || []\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 { AgentBuilderClient } from '../client/AgentBuilderClient'\nimport type {\n ConnectionStatus,\n ThreadConnectionCallbacks,\n MessageDataEvent,\n MessageChunkEvent,\n ThreadEvent,\n ErrorEvent,\n} from '../types'\n\nexport interface ThreadConnectionOptions {\n /** Maximum message depth to stream (default: 0 for top-level only) */\n depth?: number\n /** Whether to include silent messages (default: false) */\n includeSilent?: boolean\n /** Heartbeat interval in milliseconds (default: 30000) */\n heartbeatInterval?: number\n /** Maximum reconnection delay in milliseconds (default: 30000) */\n maxReconnectDelay?: number\n}\n\n/**\n * ThreadConnectionManager handles WebSocket connection lifecycle for a thread.\n * Provides automatic reconnection with exponential backoff and heartbeat keep-alive.\n *\n * This class is framework-agnostic. React and Vue SDKs use this internally\n * and handle their own reactive state management.\n *\n * @example\n * ```typescript\n * const manager = new ThreadConnectionManager(client, 'thread-123', {\n * onMessage: (event) => updateMessages(event.data),\n * onChunk: (event) => appendChunk(event.chunk),\n * onStatusChange: (status) => setConnectionStatus(status),\n * })\n *\n * manager.connect()\n * // ... later\n * manager.disconnect()\n * ```\n */\nexport class ThreadConnectionManager {\n private client: AgentBuilderClient\n private threadId: string\n private callbacks: ThreadConnectionCallbacks\n private options: Required<ThreadConnectionOptions>\n\n private ws: WebSocket | null = null\n private status: ConnectionStatus = 'disconnected'\n private reconnectAttempts: number = 0\n private reconnectTimeout: ReturnType<typeof setTimeout> | null = null\n private heartbeatInterval: ReturnType<typeof setInterval> | null = null\n private isReconnecting: boolean = false\n private shouldReconnect: boolean = true\n\n constructor(\n client: AgentBuilderClient,\n threadId: string,\n callbacks: ThreadConnectionCallbacks = {},\n options: ThreadConnectionOptions = {}\n ) {\n this.client = client\n this.threadId = threadId\n this.callbacks = callbacks\n this.options = {\n depth: options.depth ?? 0,\n includeSilent: options.includeSilent ?? false,\n heartbeatInterval: options.heartbeatInterval ?? 30000,\n maxReconnectDelay: options.maxReconnectDelay ?? 30000,\n }\n }\n\n /**\n * Get current connection status\n */\n getStatus(): ConnectionStatus {\n return this.status\n }\n\n /**\n * Get the thread ID this manager is connected to\n */\n getThreadId(): string {\n return this.threadId\n }\n\n /**\n * Connect to the thread WebSocket\n */\n connect(): void {\n if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {\n // Already connected or connecting\n return\n }\n\n this.shouldReconnect = true\n this.isReconnecting = false\n this.setStatus('connecting')\n\n this.ws = this.client.connectMessageWebSocket(\n this.threadId,\n {\n onOpen: () => {\n this.setStatus('connected')\n this.reconnectAttempts = 0\n this.isReconnecting = false\n this.startHeartbeat()\n },\n onMessage: (event: MessageDataEvent) => {\n this.callbacks.onMessage?.(event)\n },\n onChunk: (event: MessageChunkEvent) => {\n this.callbacks.onChunk?.(event)\n },\n onEvent: (event: ThreadEvent) => {\n this.callbacks.onEvent?.(event)\n },\n onError: (event: ErrorEvent) => {\n this.callbacks.onError?.(event)\n },\n onClose: () => {\n this.clearTimers()\n this.scheduleReconnect()\n },\n },\n {\n depth: this.options.depth,\n includeSilent: this.options.includeSilent,\n }\n )\n }\n\n /**\n * Disconnect from the thread WebSocket\n */\n disconnect(): void {\n this.shouldReconnect = false\n this.clearTimers()\n\n if (this.ws) {\n this.ws.close()\n this.ws = null\n }\n\n this.reconnectAttempts = 0\n this.isReconnecting = false\n this.setStatus('disconnected')\n }\n\n /**\n * Update callbacks without reconnecting\n */\n updateCallbacks(callbacks: Partial<ThreadConnectionCallbacks>): void {\n this.callbacks = { ...this.callbacks, ...callbacks }\n }\n\n /**\n * Update options (requires reconnect to take effect for depth/includeSilent)\n */\n updateOptions(options: Partial<ThreadConnectionOptions>): void {\n this.options = { ...this.options, ...options }\n }\n\n private setStatus(status: ConnectionStatus): void {\n if (this.status !== status) {\n this.status = status\n this.callbacks.onStatusChange?.(status)\n }\n }\n\n private startHeartbeat(): void {\n this.clearHeartbeat()\n\n this.heartbeatInterval = setInterval(() => {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send('ping')\n }\n }, this.options.heartbeatInterval)\n }\n\n private clearHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval)\n this.heartbeatInterval = null\n }\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout)\n this.reconnectTimeout = null\n }\n }\n\n private clearTimers(): void {\n this.clearHeartbeat()\n this.clearReconnectTimeout()\n }\n\n private scheduleReconnect(): void {\n if (!this.shouldReconnect || this.isReconnecting) {\n this.setStatus('disconnected')\n return\n }\n\n this.isReconnecting = true\n this.setStatus('reconnecting')\n\n // Exponential backoff: 1s, 2s, 4s, 8s, 16s, 30s (max)\n const delay = Math.min(\n 1000 * Math.pow(2, this.reconnectAttempts),\n this.options.maxReconnectDelay\n )\n this.reconnectAttempts++\n\n this.reconnectTimeout = setTimeout(() => {\n if (this.shouldReconnect) {\n this.connect()\n }\n }, delay)\n }\n}\n","import type { Message, AttachmentRef, ThreadFile } from '../types'\n\n/**\n * Parse attachments from a message\n * Handles both JSON string and already-parsed array formats\n * Returns empty array if no attachments or invalid data\n */\nexport function parseAttachments(message: Message): AttachmentRef[] {\n if (!message.attachments) {\n return []\n }\n\n // If already an array, return it directly\n if (Array.isArray(message.attachments)) {\n return message.attachments\n }\n\n // Otherwise try to parse as JSON string\n try {\n const parsed = JSON.parse(message.attachments)\n if (!Array.isArray(parsed)) {\n return []\n }\n return parsed\n } catch {\n return []\n }\n}\n\n/**\n * Check if a MIME type represents an image\n */\nexport function isImageMimeType(mimeType: string): boolean {\n return mimeType.toLowerCase().startsWith('image/')\n}\n\n/**\n * Convert messages to ThreadFile array\n * Extracts all committed files from message attachments\n */\nexport function messagesToFiles(messages: Message[]): ThreadFile[] {\n const files: ThreadFile[] = []\n\n for (const message of messages) {\n const attachments = parseAttachments(message)\n\n for (const attachment of attachments) {\n files.push({\n id: attachment.id,\n name: attachment.name,\n mimeType: attachment.mimeType,\n size: attachment.size,\n isImage: isImageMimeType(attachment.mimeType),\n localPreviewUrl: null, // Committed files don't have local preview\n status: 'committed',\n path: attachment.path,\n width: attachment.width,\n height: attachment.height,\n messageId: message.id,\n })\n }\n }\n\n return files\n}\n","/**\n * Image processing utilities for thumbnail generation\n * These functions require a browser environment with Canvas support\n */\n\nconst THUMBNAIL_SIZE = 256\n\n/**\n * Result of processing an image file\n */\nexport interface ImageProcessingResult {\n /** Base64-encoded thumbnail data (without data URL prefix) */\n thumbnail: string\n /** Original image width */\n width: number\n /** Original image height */\n height: number\n}\n\n/**\n * Load an image from a File object\n */\nfunction loadImage(file: File): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image()\n const objectUrl = URL.createObjectURL(file)\n\n img.onload = () => {\n URL.revokeObjectURL(objectUrl)\n resolve(img)\n }\n img.onerror = () => {\n URL.revokeObjectURL(objectUrl)\n reject(new Error('Failed to load image'))\n }\n img.src = objectUrl\n })\n}\n\n/**\n * Create a thumbnail from an image element\n * Returns base64 data without the data URL prefix\n */\nfunction createThumbnailFromImage(img: HTMLImageElement): string {\n const { width, height } = img\n const aspectRatio = width / height\n\n let thumbWidth: number\n let thumbHeight: number\n\n if (aspectRatio > 1) {\n thumbWidth = Math.min(THUMBNAIL_SIZE, width)\n thumbHeight = Math.floor(thumbWidth / aspectRatio)\n } else {\n thumbHeight = Math.min(THUMBNAIL_SIZE, height)\n thumbWidth = Math.floor(thumbHeight * aspectRatio)\n }\n\n const canvas = document.createElement('canvas')\n canvas.width = thumbWidth\n canvas.height = thumbHeight\n\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n throw new Error('Failed to get canvas context')\n }\n\n ctx.drawImage(img, 0, 0, thumbWidth, thumbHeight)\n\n // Return WebP for smaller size, strip data URL prefix\n const dataUrl = canvas.toDataURL('image/webp', 0.8)\n return dataUrl.split(',')[1]\n}\n\n/**\n * Process an image file to generate a thumbnail\n * @param file - The image file to process\n * @returns Promise with thumbnail data and dimensions\n */\nexport async function generateImageThumbnail(file: File): Promise<ImageProcessingResult> {\n const img = await loadImage(file)\n\n return {\n thumbnail: createThumbnailFromImage(img),\n width: img.width,\n height: img.height,\n }\n}\n\n/**\n * Check if the current environment supports Canvas (for thumbnail generation)\n */\nexport function canGenerateThumbnails(): boolean {\n return typeof document !== 'undefined' && typeof document.createElement === 'function'\n}\n","/**\n * File upload helper utilities\n */\n\n/**\n * Generate a unique ID for pending file uploads.\n * Uses timestamp + random string to ensure uniqueness.\n */\nexport function generatePendingFileId(): string {\n return `pending-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n}\n\n/**\n * Read a file as a data URL for image preview.\n * Returns a base64-encoded data URL that can be used as an image src.\n */\nexport function readFileAsDataUrl(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => resolve(reader.result as string)\n reader.onerror = reject\n reader.readAsDataURL(file)\n })\n}\n","/**\n * FileUploadManager - Framework-agnostic file upload management\n *\n * Handles the common logic for file uploads across Vue and React packages.\n * Each framework integrates this manager with its own state management.\n */\n\nimport type { ThreadFile, AttachmentRef } from '../types'\nimport type { AgentBuilderClient } from '../client/AgentBuilderClient'\nimport { isImageMimeType } from '../utils/attachments'\nimport { generateImageThumbnail } from '../utils/imageProcessing'\nimport { generatePendingFileId, readFileAsDataUrl } from '../utils/fileHelpers'\n\n/**\n * Callback for receiving file state updates during upload\n */\nexport type FileUpdateCallback = (updates: Partial<ThreadFile>) => void\n\n/**\n * Options for upload execution\n */\nexport interface UploadOptions {\n /** Generate and upload thumbnail for images (default: true) */\n generateThumbnail?: boolean\n /** Generate local preview URL for images (default: true) */\n generatePreview?: boolean\n}\n\n/**\n * FileUploadManager handles the upload lifecycle for files.\n *\n * Usage:\n * 1. Call queueFiles() to create pending file objects for immediate UI display\n * 2. Call executeUpload() for each file to start the actual upload\n * 3. Receive state updates via the callback to update your framework's state\n *\n * @example\n * ```typescript\n * const manager = new FileUploadManager()\n *\n * // Queue files for UI display\n * const pendingFiles = manager.queueFiles(selectedFiles)\n * setState(prev => [...prev, ...pendingFiles])\n *\n * // Start uploads\n * for (const pending of pendingFiles) {\n * manager.executeUpload(threadId, file, pending.id, client, (updates) => {\n * setState(prev => prev.map(f =>\n * f.id === pending.id ? { ...f, ...updates } : f\n * ))\n * })\n * }\n * ```\n */\nexport class FileUploadManager {\n /**\n * Create a pending file object from a File.\n * The returned object can be immediately added to state for UI feedback.\n */\n createPendingFile(file: File): ThreadFile {\n return {\n id: generatePendingFileId(),\n name: file.name,\n mimeType: file.type,\n size: file.size,\n isImage: isImageMimeType(file.type),\n localPreviewUrl: null,\n status: 'uploading',\n }\n }\n\n /**\n * Queue multiple files for upload.\n * Returns an array of pending file objects paired with their source File objects.\n *\n * @param files - Files to queue (File array or FileList)\n * @returns Array of [ThreadFile, File] tuples\n */\n queueFiles(files: File[] | FileList): Array<{ pending: ThreadFile; file: File }> {\n return Array.from(files).map(file => ({\n pending: this.createPendingFile(file),\n file,\n }))\n }\n\n /**\n * Execute the upload for a file.\n *\n * This method:\n * 1. Generates a local preview for images (async, non-blocking)\n * 2. Generates a thumbnail for images (if supported)\n * 3. Uploads the file to the server\n * 4. Calls onUpdate with state changes at each step\n *\n * @param threadId - The thread to upload to\n * @param file - The file to upload\n * @param pendingId - The ID of the pending file (from queueFiles)\n * @param client - The AgentBuilderClient instance\n * @param onUpdate - Callback for state updates\n * @param options - Upload options\n */\n async executeUpload(\n threadId: string,\n file: File,\n pendingId: string,\n client: AgentBuilderClient,\n onUpdate: FileUpdateCallback,\n options: UploadOptions = {}\n ): Promise<AttachmentRef> {\n const {\n generateThumbnail = true,\n generatePreview = true,\n } = options\n\n const isImage = isImageMimeType(file.type)\n\n // Generate local preview for images (async, doesn't block upload)\n if (isImage && generatePreview) {\n readFileAsDataUrl(file)\n .then(dataUrl => onUpdate({ localPreviewUrl: dataUrl }))\n .catch(err => console.error('Failed to generate preview:', err))\n }\n\n try {\n // Prepare upload options for images\n let uploadOptions: Parameters<typeof client.uploadFile>[2] | undefined\n\n if (isImage && generateThumbnail) {\n try {\n const result = await generateImageThumbnail(file)\n uploadOptions = {\n thumbnail: result.thumbnail,\n width: result.width,\n height: result.height,\n }\n } catch (err) {\n // If thumbnail generation fails, continue without it\n console.warn('Failed to generate thumbnail:', err)\n }\n }\n\n // Upload the file\n const attachment = await client.uploadFile(threadId, file, uploadOptions)\n\n // Update with server response\n onUpdate({\n id: attachment.id,\n status: 'ready',\n path: attachment.path,\n width: attachment.width,\n height: attachment.height,\n })\n\n return attachment\n } catch (err) {\n // Update with error state\n onUpdate({\n status: 'error',\n error: err instanceof Error ? err.message : 'Failed to upload file',\n })\n throw err\n }\n }\n\n /**\n * Execute uploads for multiple files in parallel.\n *\n * @param threadId - The thread to upload to\n * @param items - Array of pending/file pairs from queueFiles()\n * @param client - The AgentBuilderClient instance\n * @param onUpdate - Callback receiving (pendingId, updates) for each file\n * @param options - Upload options\n * @returns Array of upload results (AttachmentRef or Error for each file)\n */\n async executeUploads(\n threadId: string,\n items: Array<{ pending: ThreadFile; file: File }>,\n client: AgentBuilderClient,\n onUpdate: (pendingId: string, updates: Partial<ThreadFile>) => void,\n options: UploadOptions = {}\n ): Promise<Array<AttachmentRef | Error>> {\n const promises = items.map(({ pending, file }) =>\n this.executeUpload(\n threadId,\n file,\n pending.id,\n client,\n (updates) => onUpdate(pending.id, updates),\n options\n ).catch(err => err instanceof Error ? err : new Error(String(err)))\n )\n\n return Promise.all(promises)\n }\n}\n","import type { Message, WorkMessage, WorkItem, ThreadMessage, AttachmentRef } 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 continues to include ALL subsequent messages until:\n * - A user message appears\n * - An assistant message without tool_calls appears\n *\n * This means multiple assistant messages with tool_calls in a row\n * (with their tool results in between) are merged into a single workblock.\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 const contentParts: string[] = []\n const collectedAttachments: AttachmentRef[] = []\n let reasoningContent: string | null = message.reasoning_content || null\n let workblockStatus: 'pending' | 'completed' | 'failed' = 'completed'\n const firstMessageId = message.id\n const firstCreatedAt = message.created_at\n const depth = message.depth\n\n // Track if the current assistant message is pending\n if (message.status === 'pending') {\n workblockStatus = 'pending'\n } else if (message.status === 'failed') {\n workblockStatus = 'failed'\n }\n\n // Collect content from the first assistant message\n if (message.content) {\n contentParts.push(message.content)\n }\n\n // Add tool calls as work items\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 // Continue collecting messages while we see tool results or more assistant tool_calls\n let j = i + 1\n while (j < messages.length) {\n const nextMessage = messages[j]\n\n if (nextMessage.role === 'tool') {\n // Tool result - add to workblock\n const resultStatus = nextMessage.tool_status || 'pending'\n\n workItems.push({\n id: nextMessage.id,\n type: 'tool_result',\n name: nextMessage.name || undefined,\n content: nextMessage.content,\n status: resultStatus,\n tool_call_id: nextMessage.tool_call_id || undefined,\n })\n\n // Collect attachments from tool results\n // Handle both JSON string and already-parsed array formats\n if (nextMessage.attachments) {\n try {\n let attachments: AttachmentRef[]\n if (typeof nextMessage.attachments === 'string') {\n attachments = JSON.parse(nextMessage.attachments) as AttachmentRef[]\n } else if (Array.isArray(nextMessage.attachments)) {\n attachments = nextMessage.attachments as unknown as AttachmentRef[]\n } else {\n attachments = []\n }\n collectedAttachments.push(...attachments)\n } catch {\n // Ignore parse errors\n }\n }\n\n j++\n } else if (nextMessage.role === 'assistant' && nextMessage.tool_calls) {\n // Another assistant message with tool_calls - merge into same workblock\n let nextToolCalls: any[]\n try {\n nextToolCalls = JSON.parse(nextMessage.tool_calls)\n } catch (error) {\n // Can't parse, stop merging here\n break\n }\n\n // Update status if this message is pending/failed\n if (nextMessage.status === 'pending') {\n workblockStatus = 'pending'\n } else if (nextMessage.status === 'failed' && workblockStatus !== 'pending') {\n workblockStatus = 'failed'\n }\n\n // Collect content\n if (nextMessage.content) {\n contentParts.push(nextMessage.content)\n }\n\n // Collect reasoning content (use first non-null)\n if (!reasoningContent && nextMessage.reasoning_content) {\n reasoningContent = nextMessage.reasoning_content\n }\n\n // Add tool calls\n for (const toolCall of nextToolCalls) {\n workItems.push({\n id: toolCall.id || nextMessage.id,\n type: 'tool_call',\n name: toolCall.function?.name,\n content: toolCall.function?.arguments || null,\n status: null,\n tool_call_id: toolCall.id,\n })\n }\n j++\n } else {\n // User message or assistant without tool_calls - stop collecting\n break\n }\n }\n\n // Find orphaned tool_results (results without matching tool_calls) and create synthetic tool_calls\n const toolCallIds = new Set(workItems.filter(w => w.type === 'tool_call').map(w => w.tool_call_id))\n const orphanedResults = workItems.filter(\n w => w.type === 'tool_result' && w.tool_call_id && !toolCallIds.has(w.tool_call_id)\n )\n\n // Insert synthetic tool_calls for orphaned results\n for (const orphan of orphanedResults) {\n // Find the position of this orphan in workItems\n const orphanIndex = workItems.indexOf(orphan)\n // Extract tool name from error message or use generic\n const toolName = orphan.content?.match(/Tool not found: (\\w+)/)?.[1] || 'unknown_tool'\n\n // Insert a synthetic tool_call before the result\n const syntheticCall: WorkItem = {\n id: `synthetic-${orphan.tool_call_id}`,\n type: 'tool_call',\n name: toolName,\n content: null,\n status: orphan.status,\n tool_call_id: orphan.tool_call_id,\n }\n workItems.splice(orphanIndex, 0, syntheticCall)\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 && item.status === null) {\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 // Combine content parts\n const combinedContent = contentParts.length > 0 ? contentParts.join('') : null\n\n // Create the workblock\n const workblock: WorkMessage = {\n id: firstMessageId,\n type: 'workblock',\n content: combinedContent,\n reasoning_content: reasoningContent,\n workItems,\n status: workblockStatus,\n created_at: firstCreatedAt,\n depth,\n attachments: collectedAttachments.length > 0 ? collectedAttachments : undefined,\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"],"mappings":"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","names":["response"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@standardagents/client",
3
- "version": "0.11.0-next.ab7e1ea",
3
+ "version": "0.11.0-next.c3b4490",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "restricted",