@distri/react 0.2.1 → 0.2.3

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.cjs CHANGED
@@ -6,7 +6,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
9
  var __export = (target, all) => {
11
10
  for (var name in all)
12
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -28,7 +27,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
27
  mod
29
28
  ));
30
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
32
30
 
33
31
  // src/index.ts
34
32
  var index_exports = {};
@@ -37,76 +35,16 @@ __export(index_exports, {
37
35
  ApprovalToolCall: () => ApprovalToolCall,
38
36
  AssistantMessage: () => AssistantMessage,
39
37
  AssistantWithToolCalls: () => AssistantWithToolCalls,
40
- Badge: () => Badge,
41
- Button: () => Button,
42
- Card: () => Card,
43
- CardContent: () => CardContent,
44
- CardDescription: () => CardDescription,
45
- CardFooter: () => CardFooter,
46
- CardHeader: () => CardHeader,
47
- CardTitle: () => CardTitle,
48
38
  ChatInput: () => ChatInput,
49
39
  DebugMessage: () => DebugMessage,
50
- Dialog: () => DialogRoot,
51
- DialogContent: () => DialogContent,
52
- DialogHeader: () => DialogHeader,
53
- DialogTitle: () => DialogTitle,
54
- DialogTrigger: () => DialogTrigger,
55
40
  DistriProvider: () => DistriProvider,
56
41
  EmbeddableChat: () => EmbeddableChat,
57
42
  FullChat: () => FullChat_default,
58
- Input: () => Input,
59
43
  PlanMessage: () => PlanMessage,
60
- Select: () => Select,
61
- SelectContent: () => SelectContent,
62
- SelectGroup: () => SelectGroup,
63
- SelectItem: () => SelectItem,
64
- SelectLabel: () => SelectLabel,
65
- SelectScrollDownButton: () => SelectScrollDownButton,
66
- SelectScrollUpButton: () => SelectScrollUpButton,
67
- SelectSeparator: () => SelectSeparator,
68
- SelectTrigger: () => SelectTrigger,
69
- SelectValue: () => SelectValue,
70
- Separator: () => Separator2,
71
- Sheet: () => Sheet,
72
- SheetContent: () => SheetContent,
73
- SheetDescription: () => SheetDescription,
74
- SheetFooter: () => SheetFooter,
75
- SheetHeader: () => SheetHeader,
76
- SheetTitle: () => SheetTitle,
77
- Sidebar: () => Sidebar,
78
- SidebarContent: () => SidebarContent,
79
- SidebarFooter: () => SidebarFooter,
80
- SidebarGroup: () => SidebarGroup,
81
- SidebarGroupAction: () => SidebarGroupAction,
82
- SidebarGroupContent: () => SidebarGroupContent,
83
- SidebarGroupLabel: () => SidebarGroupLabel,
84
- SidebarHeader: () => SidebarHeader,
85
- SidebarInset: () => SidebarInset,
86
- SidebarMenu: () => SidebarMenu,
87
- SidebarMenuAction: () => SidebarMenuAction,
88
- SidebarMenuBadge: () => SidebarMenuBadge,
89
- SidebarMenuButton: () => SidebarMenuButton,
90
- SidebarMenuItem: () => SidebarMenuItem,
91
- SidebarMenuSkeleton: () => SidebarMenuSkeleton,
92
- SidebarMenuSub: () => SidebarMenuSub,
93
- SidebarMenuSubButton: () => SidebarMenuSubButton,
94
- SidebarMenuSubItem: () => SidebarMenuSubItem,
95
- SidebarProvider: () => SidebarProvider,
96
- SidebarRail: () => SidebarRail,
97
- SidebarSeparator: () => SidebarSeparator,
98
- SidebarTrigger: () => SidebarTrigger,
99
- Skeleton: () => Skeleton,
100
- Textarea: () => Textarea,
101
44
  ThemeProvider: () => ThemeProvider,
102
45
  ThemeToggle: () => ThemeToggle,
103
46
  ToastToolCall: () => ToastToolCall,
104
- Tooltip: () => Tooltip,
105
- TooltipContent: () => TooltipContent,
106
- TooltipProvider: () => TooltipProvider,
107
- TooltipTrigger: () => TooltipTrigger,
108
47
  UserMessage: () => UserMessage,
109
- cn: () => cn,
110
48
  extractTextFromMessage: () => extractTextFromMessage,
111
49
  registerTools: () => registerTools,
112
50
  shouldDisplayMessage: () => shouldDisplayMessage,
@@ -114,7 +52,6 @@ __export(index_exports, {
114
52
  useAgents: () => useAgents,
115
53
  useChat: () => useChat,
116
54
  useDistri: () => useDistri,
117
- useSidebar: () => useSidebar,
118
55
  useTheme: () => useTheme,
119
56
  useThreads: () => useThreads,
120
57
  useToolCallState: () => useToolCallState
@@ -123,953 +60,7 @@ module.exports = __toCommonJS(index_exports);
123
60
 
124
61
  // src/DistriProvider.tsx
125
62
  var import_react2 = require("react");
126
-
127
- // ../../node_modules/.pnpm/@a2a-js+sdk@https+++codeload.github.com+v3g42+a2a-js+tar.gz+51444c9/node_modules/@a2a-js/sdk/dist/chunk-CUGIRVQB.js
128
- var A2AClient = class {
129
- /**
130
- * Constructs an A2AClient instance.
131
- * It initiates fetching the agent card from the provided agent baseUrl.
132
- * The Agent Card is expected at `${agentBaseUrl}/.well-known/agent.json`.
133
- * The `url` field from the Agent Card will be used as the RPC service endpoint.
134
- * @param agentBaseUrl The base URL of the A2A agent (e.g., https://agent.example.com).
135
- */
136
- constructor(agentBaseUrl, fetchFn) {
137
- __publicField(this, "agentBaseUrl");
138
- __publicField(this, "agentCardPromise");
139
- __publicField(this, "requestIdCounter", 1);
140
- __publicField(this, "serviceEndpointUrl");
141
- // To be populated from AgentCard after fetching
142
- __publicField(this, "fetchFn");
143
- this.agentBaseUrl = agentBaseUrl.replace(/\/$/, "");
144
- this.fetchFn = fetchFn || globalThis.fetch;
145
- this.agentCardPromise = this._fetchAndCacheAgentCard();
146
- }
147
- /**
148
- * Fetches the Agent Card from the agent's well-known URI and caches its service endpoint URL.
149
- * This method is called by the constructor.
150
- * @returns A Promise that resolves to the AgentCard.
151
- */
152
- async _fetchAndCacheAgentCard() {
153
- const agentCardUrl = `${this.agentBaseUrl}/.well-known/agent.json`;
154
- try {
155
- const response = await this.fetchFn(agentCardUrl, {
156
- headers: { "Accept": "application/json" }
157
- });
158
- if (!response.ok) {
159
- throw new Error(`Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`);
160
- }
161
- const agentCard = await response.json();
162
- if (!agentCard.url) {
163
- throw new Error("Fetched Agent Card does not contain a valid 'url' for the service endpoint.");
164
- }
165
- this.serviceEndpointUrl = agentCard.url;
166
- return agentCard;
167
- } catch (error) {
168
- console.error("Error fetching or parsing Agent Card:");
169
- throw error;
170
- }
171
- }
172
- /**
173
- * Retrieves the Agent Card.
174
- * If an `agentBaseUrl` is provided, it fetches the card from that specific URL.
175
- * Otherwise, it returns the card fetched and cached during client construction.
176
- * @param agentBaseUrl Optional. The base URL of the agent to fetch the card from.
177
- * If provided, this will fetch a new card, not use the cached one from the constructor's URL.
178
- * @returns A Promise that resolves to the AgentCard.
179
- */
180
- async getAgentCard(agentBaseUrl) {
181
- if (agentBaseUrl) {
182
- const specificAgentBaseUrl = agentBaseUrl.replace(/\/$/, "");
183
- const agentCardUrl = `${specificAgentBaseUrl}/.well-known/agent.json`;
184
- const response = await this.fetchFn(agentCardUrl, {
185
- headers: { "Accept": "application/json" }
186
- });
187
- if (!response.ok) {
188
- throw new Error(`Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`);
189
- }
190
- return await response.json();
191
- }
192
- return this.agentCardPromise;
193
- }
194
- /**
195
- * Gets the RPC service endpoint URL. Ensures the agent card has been fetched first.
196
- * @returns A Promise that resolves to the service endpoint URL string.
197
- */
198
- async _getServiceEndpoint() {
199
- if (this.serviceEndpointUrl) {
200
- return this.serviceEndpointUrl;
201
- }
202
- await this.agentCardPromise;
203
- if (!this.serviceEndpointUrl) {
204
- throw new Error("Agent Card URL for RPC endpoint is not available. Fetching might have failed.");
205
- }
206
- return this.serviceEndpointUrl;
207
- }
208
- /**
209
- * Helper method to make a generic JSON-RPC POST request.
210
- * @param method The RPC method name.
211
- * @param params The parameters for the RPC method.
212
- * @returns A Promise that resolves to the RPC response.
213
- */
214
- async _postRpcRequest(method, params) {
215
- const endpoint = await this._getServiceEndpoint();
216
- const requestId = this.requestIdCounter++;
217
- const rpcRequest = {
218
- jsonrpc: "2.0",
219
- method,
220
- params,
221
- // Cast because TParams structure varies per method
222
- id: requestId
223
- };
224
- const httpResponse = await this.fetchFn(endpoint, {
225
- method: "POST",
226
- headers: {
227
- "Content-Type": "application/json",
228
- "Accept": "application/json"
229
- // Expect JSON response for non-streaming requests
230
- },
231
- body: JSON.stringify(rpcRequest)
232
- });
233
- if (!httpResponse.ok) {
234
- let errorBodyText = "(empty or non-JSON response)";
235
- try {
236
- errorBodyText = await httpResponse.text();
237
- const errorJson = JSON.parse(errorBodyText);
238
- if (!errorJson.jsonrpc && errorJson.error) {
239
- throw new Error(`RPC error for ${method}: ${errorJson.error.message} (Code: ${errorJson.error.code}, HTTP Status: ${httpResponse.status}) Data: ${JSON.stringify(errorJson.error.data)}`);
240
- } else if (!errorJson.jsonrpc) {
241
- throw new Error(`HTTP error for ${method}! Status: ${httpResponse.status} ${httpResponse.statusText}. Response: ${errorBodyText}`);
242
- }
243
- } catch (e) {
244
- if (e.message.startsWith("RPC error for") || e.message.startsWith("HTTP error for")) throw e;
245
- throw new Error(`HTTP error for ${method}! Status: ${httpResponse.status} ${httpResponse.statusText}. Response: ${errorBodyText}`);
246
- }
247
- }
248
- const rpcResponse = await httpResponse.json();
249
- if (rpcResponse.id !== requestId) {
250
- console.error(`CRITICAL: RPC response ID mismatch for method ${method}. Expected ${requestId}, got ${rpcResponse.id}. This may lead to incorrect response handling.`);
251
- }
252
- return rpcResponse;
253
- }
254
- /**
255
- * Sends a message to the agent.
256
- * The behavior (blocking/non-blocking) and push notification configuration
257
- * are specified within the `params.configuration` object.
258
- * Optionally, `params.message.contextId` or `params.message.taskId` can be provided.
259
- * @param params The parameters for sending the message, including the message content and configuration.
260
- * @returns A Promise resolving to SendMessageResponse, which can be a Message, Task, or an error.
261
- */
262
- async sendMessage(params) {
263
- return this._postRpcRequest("message/send", params);
264
- }
265
- /**
266
- * Sends a message to the agent and streams back responses using Server-Sent Events (SSE).
267
- * Push notification configuration can be specified in `params.configuration`.
268
- * Optionally, `params.message.contextId` or `params.message.taskId` can be provided.
269
- * Requires the agent to support streaming (`capabilities.streaming: true` in AgentCard).
270
- * @param params The parameters for sending the message.
271
- * @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
272
- * The generator throws an error if streaming is not supported or if an HTTP/SSE error occurs.
273
- */
274
- async *sendMessageStream(params) {
275
- const agentCard = await this.agentCardPromise;
276
- if (!agentCard.capabilities?.streaming) {
277
- throw new Error("Agent does not support streaming (AgentCard.capabilities.streaming is not true).");
278
- }
279
- const endpoint = await this._getServiceEndpoint();
280
- const clientRequestId = this.requestIdCounter++;
281
- const rpcRequest = {
282
- // This is the initial JSON-RPC request to establish the stream
283
- jsonrpc: "2.0",
284
- method: "message/stream",
285
- params,
286
- id: clientRequestId
287
- };
288
- const response = await this.fetchFn(endpoint, {
289
- method: "POST",
290
- headers: {
291
- "Content-Type": "application/json",
292
- "Accept": "text/event-stream"
293
- // Crucial for SSE
294
- },
295
- body: JSON.stringify(rpcRequest)
296
- });
297
- if (!response.ok) {
298
- let errorBody = "";
299
- try {
300
- errorBody = await response.text();
301
- const errorJson = JSON.parse(errorBody);
302
- if (errorJson.error) {
303
- throw new Error(`HTTP error establishing stream for message/stream: ${response.status} ${response.statusText}. RPC Error: ${errorJson.error.message} (Code: ${errorJson.error.code})`);
304
- }
305
- } catch (e) {
306
- if (e.message.startsWith("HTTP error establishing stream")) throw e;
307
- throw new Error(`HTTP error establishing stream for message/stream: ${response.status} ${response.statusText}. Response: ${errorBody || "(empty)"}`);
308
- }
309
- throw new Error(`HTTP error establishing stream for message/stream: ${response.status} ${response.statusText}`);
310
- }
311
- if (!response.headers.get("Content-Type")?.startsWith("text/event-stream")) {
312
- throw new Error("Invalid response Content-Type for SSE stream. Expected 'text/event-stream'.");
313
- }
314
- yield* this._parseA2ASseStream(response, clientRequestId);
315
- }
316
- /**
317
- * Sets or updates the push notification configuration for a given task.
318
- * Requires the agent to support push notifications (`capabilities.pushNotifications: true` in AgentCard).
319
- * @param params Parameters containing the taskId and the TaskPushNotificationConfig.
320
- * @returns A Promise resolving to SetTaskPushNotificationConfigResponse.
321
- */
322
- async setTaskPushNotificationConfig(params) {
323
- const agentCard = await this.agentCardPromise;
324
- if (!agentCard.capabilities?.pushNotifications) {
325
- throw new Error("Agent does not support push notifications (AgentCard.capabilities.pushNotifications is not true).");
326
- }
327
- return this._postRpcRequest(
328
- "tasks/pushNotificationConfig/set",
329
- params
330
- );
331
- }
332
- /**
333
- * Gets the push notification configuration for a given task.
334
- * @param params Parameters containing the taskId.
335
- * @returns A Promise resolving to GetTaskPushNotificationConfigResponse.
336
- */
337
- async getTaskPushNotificationConfig(params) {
338
- return this._postRpcRequest(
339
- "tasks/pushNotificationConfig/get",
340
- params
341
- );
342
- }
343
- /**
344
- * Retrieves a task by its ID.
345
- * @param params Parameters containing the taskId and optional historyLength.
346
- * @returns A Promise resolving to GetTaskResponse, which contains the Task object or an error.
347
- */
348
- async getTask(params) {
349
- return this._postRpcRequest("tasks/get", params);
350
- }
351
- /**
352
- * Cancels a task by its ID.
353
- * @param params Parameters containing the taskId.
354
- * @returns A Promise resolving to CancelTaskResponse, which contains the updated Task object or an error.
355
- */
356
- async cancelTask(params) {
357
- return this._postRpcRequest("tasks/cancel", params);
358
- }
359
- /**
360
- * Resubscribes to a task's event stream using Server-Sent Events (SSE).
361
- * This is used if a previous SSE connection for an active task was broken.
362
- * Requires the agent to support streaming (`capabilities.streaming: true` in AgentCard).
363
- * @param params Parameters containing the taskId.
364
- * @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
365
- */
366
- async *resubscribeTask(params) {
367
- const agentCard = await this.agentCardPromise;
368
- if (!agentCard.capabilities?.streaming) {
369
- throw new Error("Agent does not support streaming (required for tasks/resubscribe).");
370
- }
371
- const endpoint = await this._getServiceEndpoint();
372
- const clientRequestId = this.requestIdCounter++;
373
- const rpcRequest = {
374
- // Initial JSON-RPC request to establish the stream
375
- jsonrpc: "2.0",
376
- method: "tasks/resubscribe",
377
- params,
378
- id: clientRequestId
379
- };
380
- const response = await this.fetchFn(endpoint, {
381
- method: "POST",
382
- headers: {
383
- "Content-Type": "application/json",
384
- "Accept": "text/event-stream"
385
- },
386
- body: JSON.stringify(rpcRequest)
387
- });
388
- if (!response.ok) {
389
- let errorBody = "";
390
- try {
391
- errorBody = await response.text();
392
- const errorJson = JSON.parse(errorBody);
393
- if (errorJson.error) {
394
- throw new Error(`HTTP error establishing stream for tasks/resubscribe: ${response.status} ${response.statusText}. RPC Error: ${errorJson.error.message} (Code: ${errorJson.error.code})`);
395
- }
396
- } catch (e) {
397
- if (e.message.startsWith("HTTP error establishing stream")) throw e;
398
- throw new Error(`HTTP error establishing stream for tasks/resubscribe: ${response.status} ${response.statusText}. Response: ${errorBody || "(empty)"}`);
399
- }
400
- throw new Error(`HTTP error establishing stream for tasks/resubscribe: ${response.status} ${response.statusText}`);
401
- }
402
- if (!response.headers.get("Content-Type")?.startsWith("text/event-stream")) {
403
- throw new Error("Invalid response Content-Type for SSE stream on resubscribe. Expected 'text/event-stream'.");
404
- }
405
- yield* this._parseA2ASseStream(response, clientRequestId);
406
- }
407
- /**
408
- * Parses an HTTP response body as an A2A Server-Sent Event stream.
409
- * Each 'data' field of an SSE event is expected to be a JSON-RPC 2.0 Response object,
410
- * specifically a SendStreamingMessageResponse (or similar structure for resubscribe).
411
- * @param response The HTTP Response object whose body is the SSE stream.
412
- * @param originalRequestId The ID of the client's JSON-RPC request that initiated this stream.
413
- * Used to validate the `id` in the streamed JSON-RPC responses.
414
- * @returns An AsyncGenerator yielding the `result` field of each valid JSON-RPC success response from the stream.
415
- */
416
- async *_parseA2ASseStream(response, originalRequestId) {
417
- if (!response.body) {
418
- throw new Error("SSE response body is undefined. Cannot read stream.");
419
- }
420
- const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
421
- let buffer = "";
422
- let eventDataBuffer = "";
423
- try {
424
- while (true) {
425
- const { done, value } = await reader.read();
426
- if (done) {
427
- if (eventDataBuffer.trim()) {
428
- const result = this._processSseEventData(eventDataBuffer, originalRequestId);
429
- yield result;
430
- }
431
- break;
432
- }
433
- buffer += value;
434
- let lineEndIndex;
435
- while ((lineEndIndex = buffer.indexOf("\n")) >= 0) {
436
- const line = buffer.substring(0, lineEndIndex).trim();
437
- buffer = buffer.substring(lineEndIndex + 1);
438
- if (line === "") {
439
- if (eventDataBuffer) {
440
- const result = this._processSseEventData(eventDataBuffer, originalRequestId);
441
- yield result;
442
- eventDataBuffer = "";
443
- }
444
- } else if (line.startsWith("data:")) {
445
- eventDataBuffer += line.substring(5).trimStart() + "\n";
446
- } else if (line.startsWith(":")) {
447
- } else if (line.includes(":")) {
448
- }
449
- }
450
- }
451
- } catch (error) {
452
- console.error("Error reading or parsing SSE stream:", error.message);
453
- throw error;
454
- } finally {
455
- reader.releaseLock();
456
- }
457
- }
458
- /**
459
- * Processes a single SSE event's data string, expecting it to be a JSON-RPC response.
460
- * @param jsonData The string content from one or more 'data:' lines of an SSE event.
461
- * @param originalRequestId The ID of the client's request that initiated the stream.
462
- * @returns The `result` field of the parsed JSON-RPC success response.
463
- * @throws Error if data is not valid JSON, not a valid JSON-RPC response, an error response, or ID mismatch.
464
- */
465
- _processSseEventData(jsonData, originalRequestId) {
466
- if (!jsonData.trim()) {
467
- throw new Error("Attempted to process empty SSE event data.");
468
- }
469
- try {
470
- const sseJsonRpcResponse = JSON.parse(jsonData.replace(/\n$/, ""));
471
- const a2aStreamResponse = sseJsonRpcResponse;
472
- if (a2aStreamResponse.id !== originalRequestId) {
473
- console.warn(`SSE Event's JSON-RPC response ID mismatch. Client request ID: ${originalRequestId}, event response ID: ${a2aStreamResponse.id}.`);
474
- }
475
- if (this.isErrorResponse(a2aStreamResponse)) {
476
- const err = a2aStreamResponse.error;
477
- throw new Error(`SSE event contained an error: ${err.message} (Code: ${err.code}) Data: ${JSON.stringify(err.data)}`);
478
- }
479
- if (!("result" in a2aStreamResponse) || typeof a2aStreamResponse.result === "undefined") {
480
- throw new Error(`SSE event JSON-RPC response is missing 'result' field. Data: ${jsonData}`);
481
- }
482
- const successResponse = a2aStreamResponse;
483
- return successResponse.result;
484
- } catch (e) {
485
- if (e.message.startsWith("SSE event contained an error") || e.message.startsWith("SSE event JSON-RPC response is missing 'result' field")) {
486
- throw e;
487
- }
488
- console.error("Failed to parse SSE event data string or unexpected JSON-RPC structure:", jsonData, e);
489
- throw new Error(`Failed to parse SSE event data: "${jsonData.substring(0, 100)}...". Original error: ${e.message}`);
490
- }
491
- }
492
- isErrorResponse(response) {
493
- return "error" in response;
494
- }
495
- };
496
-
497
- // ../core/src/types.ts
498
- var DistriError = class extends Error {
499
- constructor(message, code, details) {
500
- super(message);
501
- this.code = code;
502
- this.details = details;
503
- this.name = "DistriError";
504
- }
505
- };
506
- var A2AProtocolError = class extends DistriError {
507
- constructor(message, details) {
508
- super(message, "A2A_PROTOCOL_ERROR", details);
509
- this.name = "A2AProtocolError";
510
- }
511
- };
512
- var ApiError = class extends DistriError {
513
- constructor(message, statusCode, details) {
514
- super(message, "API_ERROR", details);
515
- this.statusCode = statusCode;
516
- this.name = "ApiError";
517
- }
518
- };
519
- function isDistriMessage(event) {
520
- return "id" in event && "role" in event && "parts" in event;
521
- }
522
-
523
- // ../core/src/encoder.ts
524
- function convertA2AMessageToDistri(a2aMessage) {
525
- const role = a2aMessage.role === "agent" ? "assistant" : "user";
526
- return {
527
- id: a2aMessage.messageId,
528
- role,
529
- parts: a2aMessage.parts.map(convertA2APartToDistri),
530
- created_at: a2aMessage.createdAt
531
- };
532
- }
533
- function decodeA2AStreamEvent(event) {
534
- if (event.kind === "message") {
535
- return convertA2AMessageToDistri(event);
536
- } else if (event.kind === "status-update") {
537
- return event;
538
- } else if (event.kind === "artifact-update") {
539
- return event;
540
- }
541
- return event;
542
- }
543
- function convertA2APartToDistri(a2aPart) {
544
- switch (a2aPart.kind) {
545
- case "text":
546
- return { type: "text", text: a2aPart.text };
547
- case "file":
548
- if ("uri" in a2aPart.file) {
549
- return { type: "image_url", image: { mime_type: a2aPart.file.mimeType, url: a2aPart.file.uri } };
550
- } else {
551
- return { type: "image_bytes", image: { mime_type: a2aPart.file.mimeType, data: a2aPart.file.bytes } };
552
- }
553
- case "data":
554
- switch (a2aPart.data.part_type) {
555
- case "tool_call":
556
- return { type: "tool_call", tool_call: a2aPart.data };
557
- case "tool_result":
558
- return { type: "tool_result", tool_result: a2aPart.data };
559
- case "code_observation":
560
- return { type: "code_observation", thought: a2aPart.data.thought, code: a2aPart.data.code };
561
- case "plan":
562
- return { type: "plan", plan: a2aPart.data.plan };
563
- default:
564
- return { type: "data", data: a2aPart.data };
565
- }
566
- default:
567
- return { type: "text", text: JSON.stringify(a2aPart) };
568
- }
569
- }
570
- function convertDistriMessageToA2A(distriMessage, context) {
571
- let role;
572
- switch (distriMessage.role) {
573
- case "assistant":
574
- role = "agent";
575
- break;
576
- case "user":
577
- role = "user";
578
- break;
579
- case "system":
580
- case "tool":
581
- role = "user";
582
- break;
583
- default:
584
- role = "user";
585
- }
586
- return {
587
- messageId: distriMessage.id,
588
- role,
589
- parts: distriMessage.parts.map(convertDistriPartToA2A),
590
- kind: "message",
591
- contextId: context.thread_id,
592
- taskId: context.run_id
593
- };
594
- }
595
- function convertDistriPartToA2A(distriPart) {
596
- switch (distriPart.type) {
597
- case "text":
598
- return { kind: "text", text: distriPart.text };
599
- case "image_url":
600
- return { kind: "file", file: { mimeType: distriPart.image.mime_type, uri: distriPart.image.url } };
601
- case "image_bytes":
602
- return { kind: "file", file: { mimeType: distriPart.image.mime_type, bytes: distriPart.image.data } };
603
- case "tool_call":
604
- return { kind: "data", data: { part_type: "tool_call", tool_call: distriPart.tool_call } };
605
- case "tool_result":
606
- let val = {
607
- kind: "data",
608
- data: {
609
- tool_call_id: distriPart.tool_result.tool_call_id,
610
- result: distriPart.tool_result.result,
611
- part_type: "tool_result"
612
- }
613
- };
614
- console.log("<> val", val);
615
- return val;
616
- case "code_observation":
617
- return { kind: "data", data: { ...distriPart, part_type: "code_observation" } };
618
- case "plan":
619
- return { kind: "data", data: { ...distriPart, part_type: "plan" } };
620
- case "data":
621
- return { kind: "data", ...distriPart.data };
622
- }
623
- }
624
-
625
- // ../core/src/distri-client.ts
626
- var DistriClient = class {
627
- constructor(config) {
628
- this.agentClients = /* @__PURE__ */ new Map();
629
- this.config = {
630
- baseUrl: config.baseUrl.replace(/\/$/, ""),
631
- apiVersion: config.apiVersion || "v1",
632
- timeout: config.timeout || 3e4,
633
- retryAttempts: config.retryAttempts || 3,
634
- retryDelay: config.retryDelay || 1e3,
635
- debug: config.debug || false,
636
- headers: config.headers || {},
637
- interceptor: config.interceptor || ((init) => Promise.resolve(init))
638
- };
639
- this.debug("DistriClient initialized with config:", this.config);
640
- }
641
- /**
642
- * Get all available agents from the Distri server
643
- */
644
- async getAgents() {
645
- try {
646
- const response = await this.fetch(`/agents`, {
647
- headers: {
648
- ...this.config.headers
649
- }
650
- });
651
- if (!response.ok) {
652
- throw new ApiError(`Failed to fetch agents: ${response.statusText}`, response.status);
653
- }
654
- const agents = await response.json();
655
- agents.forEach((agent) => {
656
- if (!agent.id) {
657
- agent.id = agent.name;
658
- }
659
- });
660
- return agents;
661
- } catch (error) {
662
- if (error instanceof ApiError) throw error;
663
- throw new DistriError("Failed to fetch agents", "FETCH_ERROR", error);
664
- }
665
- }
666
- /**
667
- * Get specific agent by ID
668
- */
669
- async getAgent(agentId) {
670
- try {
671
- const response = await this.fetch(`/agents/${agentId}`, {
672
- headers: {
673
- ...this.config.headers
674
- }
675
- });
676
- if (!response.ok) {
677
- if (response.status === 404) {
678
- throw new ApiError(`Agent not found: ${agentId}`, 404);
679
- }
680
- throw new ApiError(`Failed to fetch agent: ${response.statusText}`, response.status);
681
- }
682
- const agent = await response.json();
683
- if (!agent.id) {
684
- agent.id = agentId;
685
- }
686
- return agent;
687
- } catch (error) {
688
- if (error instanceof ApiError) throw error;
689
- throw new DistriError(`Failed to fetch agent ${agentId}`, "FETCH_ERROR", error);
690
- }
691
- }
692
- /**
693
- * Get or create A2AClient for an agent
694
- */
695
- getA2AClient(agentId) {
696
- if (!this.agentClients.has(agentId)) {
697
- const fetchFn = this.fetchAbsolute.bind(this);
698
- const agentUrl = `${this.config.baseUrl}/agents/${agentId}`;
699
- const client = new A2AClient(agentUrl, fetchFn);
700
- this.agentClients.set(agentId, client);
701
- this.debug(`Created A2AClient for agent ${agentId} at ${agentUrl}`);
702
- }
703
- return this.agentClients.get(agentId);
704
- }
705
- /**
706
- * Send a message to an agent
707
- */
708
- async sendMessage(agentId, params) {
709
- try {
710
- const client = this.getA2AClient(agentId);
711
- const response = await client.sendMessage(params);
712
- if ("error" in response && response.error) {
713
- throw new A2AProtocolError(response.error.message, response.error);
714
- }
715
- if ("result" in response) {
716
- const result = response.result;
717
- this.debug(`Message sent to ${agentId}, got ${result.kind}:`, result);
718
- return result;
719
- }
720
- throw new DistriError("Invalid response format", "INVALID_RESPONSE");
721
- } catch (error) {
722
- if (error instanceof A2AProtocolError || error instanceof DistriError) throw error;
723
- throw new DistriError(`Failed to send message to agent ${agentId}`, "SEND_MESSAGE_ERROR", error);
724
- }
725
- }
726
- /**
727
- * Send a streaming message to an agent
728
- */
729
- async *sendMessageStream(agentId, params) {
730
- try {
731
- const client = this.getA2AClient(agentId);
732
- yield* await client.sendMessageStream(params);
733
- } catch (error) {
734
- throw new DistriError(`Failed to stream message to agent ${agentId}`, "STREAM_MESSAGE_ERROR", error);
735
- }
736
- }
737
- /**
738
- * Get task details
739
- */
740
- async getTask(agentId, taskId) {
741
- try {
742
- const client = this.getA2AClient(agentId);
743
- const response = await client.getTask({ id: taskId });
744
- if ("error" in response && response.error) {
745
- throw new A2AProtocolError(response.error.message, response.error);
746
- }
747
- if ("result" in response) {
748
- const result = response.result;
749
- this.debug(`Got task ${taskId} from ${agentId}:`, result);
750
- return result;
751
- }
752
- throw new DistriError("Invalid response format", "INVALID_RESPONSE");
753
- } catch (error) {
754
- if (error instanceof A2AProtocolError || error instanceof DistriError) throw error;
755
- throw new DistriError(`Failed to get task ${taskId} from agent ${agentId}`, "GET_TASK_ERROR", error);
756
- }
757
- }
758
- /**
759
- * Cancel a task
760
- */
761
- async cancelTask(agentId, taskId) {
762
- try {
763
- const client = this.getA2AClient(agentId);
764
- await client.cancelTask({ id: taskId });
765
- this.debug(`Cancelled task ${taskId} on agent ${agentId}`);
766
- } catch (error) {
767
- throw new DistriError(`Failed to cancel task ${taskId} on agent ${agentId}`, "CANCEL_TASK_ERROR", error);
768
- }
769
- }
770
- /**
771
- * Get threads from Distri server
772
- */
773
- async getThreads() {
774
- try {
775
- const response = await this.fetch(`/threads`);
776
- if (!response.ok) {
777
- throw new ApiError(`Failed to fetch threads: ${response.statusText}`, response.status);
778
- }
779
- return await response.json();
780
- } catch (error) {
781
- if (error instanceof ApiError) throw error;
782
- throw new DistriError("Failed to fetch threads", "FETCH_ERROR", error);
783
- }
784
- }
785
- async getThread(threadId) {
786
- try {
787
- const response = await this.fetch(`/threads/${threadId}`);
788
- if (!response.ok) {
789
- throw new ApiError(`Failed to fetch thread: ${response.statusText}`, response.status);
790
- }
791
- return await response.json();
792
- } catch (error) {
793
- if (error instanceof ApiError) throw error;
794
- throw new DistriError(`Failed to fetch thread ${threadId}`, "FETCH_ERROR", error);
795
- }
796
- }
797
- /**
798
- * Get thread messages
799
- */
800
- async getThreadMessages(threadId) {
801
- try {
802
- const response = await this.fetch(`/threads/${threadId}/messages`);
803
- if (!response.ok) {
804
- if (response.status === 404) {
805
- return [];
806
- }
807
- throw new ApiError(`Failed to fetch thread messages: ${response.statusText}`, response.status);
808
- }
809
- return await response.json();
810
- } catch (error) {
811
- if (error instanceof ApiError) throw error;
812
- throw new DistriError(`Failed to fetch messages for thread ${threadId}`, "FETCH_ERROR", error);
813
- }
814
- }
815
- /**
816
- * Get messages from a thread as DistriMessage format
817
- */
818
- async getThreadMessagesAsDistri(threadId) {
819
- const messages = await this.getThreadMessages(threadId);
820
- return messages.map(convertA2AMessageToDistri);
821
- }
822
- /**
823
- * Send a DistriMessage to a thread
824
- */
825
- async sendDistriMessage(threadId, message, context) {
826
- const a2aMessage = convertDistriMessageToA2A(message, context);
827
- const params = {
828
- message: a2aMessage,
829
- metadata: context.metadata
830
- };
831
- await this.sendMessage(threadId, params);
832
- }
833
- /**
834
- * Get the base URL for making direct requests
835
- */
836
- get baseUrl() {
837
- return this.config.baseUrl;
838
- }
839
- /**
840
- * Enhanced fetch with retry logic
841
- */
842
- async fetchAbsolute(url, initialInit) {
843
- const init = await this.config.interceptor(initialInit);
844
- let lastError;
845
- for (let attempt = 0; attempt <= this.config.retryAttempts; attempt++) {
846
- try {
847
- const controller = new AbortController();
848
- const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
849
- const response = await fetch(url, {
850
- ...init,
851
- signal: controller.signal,
852
- headers: {
853
- ...this.config.headers,
854
- ...init?.headers
855
- }
856
- });
857
- clearTimeout(timeoutId);
858
- return response;
859
- } catch (error) {
860
- lastError = error instanceof Error ? error : new Error(String(error));
861
- if (attempt < this.config.retryAttempts) {
862
- this.debug(`Request failed (attempt ${attempt + 1}), retrying in ${this.config.retryDelay}ms...`);
863
- await this.delay(this.config.retryDelay);
864
- }
865
- }
866
- }
867
- throw lastError;
868
- }
869
- /**
870
- * Enhanced fetch with retry logic
871
- */
872
- async fetch(input, initialInit) {
873
- const url = `${this.config.baseUrl}${input}`;
874
- return this.fetchAbsolute(url, initialInit);
875
- }
876
- /**
877
- * Delay utility
878
- */
879
- delay(ms) {
880
- return new Promise((resolve) => setTimeout(resolve, ms));
881
- }
882
- /**
883
- * Debug logging
884
- */
885
- debug(...args) {
886
- if (this.config.debug) {
887
- console.log("[DistriClient]", ...args);
888
- }
889
- }
890
- /**
891
- * Helper method to create A2A messages
892
- */
893
- static initMessage(parts, role = "user", message) {
894
- return {
895
- messageId: message.messageId || uuidv4(),
896
- taskId: message.taskId || uuidv4(),
897
- contextId: message.contextId,
898
- role,
899
- parts: Array.isArray(parts) ? parts : [{ kind: "text", text: parts.trim() }],
900
- ...message,
901
- kind: "message"
902
- };
903
- }
904
- /**
905
- * Create a DistriMessage instance
906
- */
907
- static initDistriMessage(role, parts, id, created_at) {
908
- return {
909
- id: id || uuidv4(),
910
- role,
911
- parts,
912
- created_at
913
- };
914
- }
915
- /**
916
- * Helper method to create message send parameters
917
- */
918
- static initMessageParams(message, configuration, metadata) {
919
- return {
920
- message,
921
- configuration: {
922
- acceptedOutputModes: ["text/plain"],
923
- blocking: false,
924
- // Default to non-blocking for streaming
925
- ...configuration
926
- },
927
- metadata
928
- };
929
- }
930
- /**
931
- * Create MessageSendParams from a DistriMessage using InvokeContext
932
- */
933
- static initDistriMessageParams(message, context) {
934
- const a2aMessage = convertDistriMessageToA2A(message, context);
935
- return {
936
- message: a2aMessage,
937
- metadata: context.metadata
938
- };
939
- }
940
- };
941
- function uuidv4() {
942
- if (typeof crypto?.randomUUID === "function") {
943
- return crypto.randomUUID();
944
- }
945
- const array = new Uint8Array(16);
946
- crypto.getRandomValues(array);
947
- array[6] = array[6] & 15 | 64;
948
- array[8] = array[8] & 63 | 128;
949
- return [...array].map(
950
- (b, i) => ([4, 6, 8, 10].includes(i) ? "-" : "") + b.toString(16).padStart(2, "0")
951
- ).join("");
952
- }
953
-
954
- // ../core/src/agent.ts
955
- var Agent = class _Agent {
956
- constructor(agentDefinition, client) {
957
- this.tools = /* @__PURE__ */ new Map();
958
- this.agentDefinition = agentDefinition;
959
- this.client = client;
960
- }
961
- /**
962
- * Add a tool to the agent (AG-UI style)
963
- */
964
- registerTool(tool) {
965
- this.tools.set(tool.name, tool);
966
- }
967
- /**
968
- * Add multiple tools at once
969
- */
970
- registerTools(tools) {
971
- tools.forEach((tool) => this.registerTool(tool));
972
- }
973
- /**
974
- * Remove a tool
975
- */
976
- unregisterTool(toolName) {
977
- this.tools.delete(toolName);
978
- }
979
- /**
980
- * Get all registered tools
981
- */
982
- getTools() {
983
- return Array.from(this.tools.values());
984
- }
985
- /**
986
- * Check if a tool is registered
987
- */
988
- hasTool(toolName) {
989
- return this.tools.has(toolName);
990
- }
991
- /**
992
- * Get agent information
993
- */
994
- get id() {
995
- return this.agentDefinition.id;
996
- }
997
- get name() {
998
- return this.agentDefinition.name;
999
- }
1000
- get description() {
1001
- return this.agentDefinition.description;
1002
- }
1003
- get iconUrl() {
1004
- return this.agentDefinition.icon_url;
1005
- }
1006
- /**
1007
- * Fetch messages for a thread (public method for useChat)
1008
- */
1009
- async getThreadMessages(threadId) {
1010
- return this.client.getThreadMessages(threadId);
1011
- }
1012
- /**
1013
- * Direct (non-streaming) invoke
1014
- */
1015
- async invoke(params) {
1016
- const enhancedParams = this.enhanceParamsWithTools(params);
1017
- console.log("enhancedParams", enhancedParams);
1018
- return await this.client.sendMessage(this.agentDefinition.id, enhancedParams);
1019
- }
1020
- /**
1021
- * Streaming invoke
1022
- */
1023
- async invokeStream(params) {
1024
- const enhancedParams = this.enhanceParamsWithTools(params);
1025
- console.log("enhancedParams", enhancedParams);
1026
- const a2aStream = this.client.sendMessageStream(this.agentDefinition.id, enhancedParams);
1027
- return async function* () {
1028
- for await (const event of a2aStream) {
1029
- if (event.kind === "message") {
1030
- yield convertA2AMessageToDistri(event);
1031
- } else if (event.kind === "status-update") {
1032
- yield event;
1033
- } else if (event.kind === "artifact-update") {
1034
- yield event;
1035
- } else {
1036
- yield event;
1037
- }
1038
- }
1039
- }();
1040
- }
1041
- /**
1042
- * Enhance message params with tool definitions
1043
- */
1044
- enhanceParamsWithTools(params) {
1045
- const tools = this.getTools();
1046
- return {
1047
- ...params,
1048
- metadata: {
1049
- ...params.metadata,
1050
- tools: tools.map((tool) => ({
1051
- name: tool.name,
1052
- description: tool.description,
1053
- input_schema: tool.input_schema
1054
- }))
1055
- }
1056
- };
1057
- }
1058
- /**
1059
- * Create an agent instance from an agent ID
1060
- */
1061
- static async create(agentId, client) {
1062
- const agentDefinition = await client.getAgent(agentId);
1063
- return new _Agent(agentDefinition, client);
1064
- }
1065
- /**
1066
- * List all available agents
1067
- */
1068
- static async list(client) {
1069
- const agentDefinitions = await client.getAgents();
1070
- return agentDefinitions.map((def) => new _Agent(def, client));
1071
- }
1072
- };
63
+ var import_core = require("@distri/core");
1073
64
 
1074
65
  // src/components/ThemeProvider.tsx
1075
66
  var import_react = require("react");
@@ -1138,7 +129,7 @@ function DistriProvider({ config, children, defaultTheme = "dark" }) {
1138
129
  let currentClient = null;
1139
130
  try {
1140
131
  debug(config, "[DistriProvider] Initializing client with config:", config);
1141
- currentClient = new DistriClient(config);
132
+ currentClient = new import_core.DistriClient(config);
1142
133
  setClient(currentClient);
1143
134
  setError(null);
1144
135
  setIsLoading(false);
@@ -1177,6 +168,7 @@ function useDistri() {
1177
168
 
1178
169
  // src/useAgent.ts
1179
170
  var import_react3 = __toESM(require("react"), 1);
171
+ var import_core2 = require("@distri/core");
1180
172
  function useAgent({
1181
173
  agentId,
1182
174
  autoCreateAgent = true
@@ -1199,7 +191,7 @@ function useAgent({
1199
191
  agentRef.current = null;
1200
192
  setAgent(null);
1201
193
  }
1202
- const newAgent = await Agent.create(agentId, client);
194
+ const newAgent = await import_core2.Agent.create(agentId, client);
1203
195
  agentRef.current = newAgent;
1204
196
  currentAgentIdRef.current = agentId;
1205
197
  setAgent(newAgent);
@@ -1296,6 +288,61 @@ function useAgents() {
1296
288
 
1297
289
  // src/useChat.ts
1298
290
  var import_react9 = require("react");
291
+ var import_core3 = require("@distri/core");
292
+ var import_core4 = require("@distri/core");
293
+
294
+ // ../core/src/encoder.ts
295
+ function convertA2AMessageToDistri(a2aMessage) {
296
+ const role = a2aMessage.role === "agent" ? "assistant" : "user";
297
+ return {
298
+ id: a2aMessage.messageId,
299
+ role,
300
+ parts: a2aMessage.parts.map(convertA2APartToDistri),
301
+ created_at: a2aMessage.createdAt
302
+ };
303
+ }
304
+ function decodeA2AStreamEvent(event) {
305
+ if (event.kind === "message") {
306
+ return convertA2AMessageToDistri(event);
307
+ } else if (event.kind === "status-update") {
308
+ return event;
309
+ } else if (event.kind === "artifact-update") {
310
+ return event;
311
+ }
312
+ return event;
313
+ }
314
+ function convertA2APartToDistri(a2aPart) {
315
+ switch (a2aPart.kind) {
316
+ case "text":
317
+ return { type: "text", text: a2aPart.text };
318
+ case "file":
319
+ if ("uri" in a2aPart.file) {
320
+ return { type: "image_url", image: { mime_type: a2aPart.file.mimeType, url: a2aPart.file.uri } };
321
+ } else {
322
+ return { type: "image_bytes", image: { mime_type: a2aPart.file.mimeType, data: a2aPart.file.bytes } };
323
+ }
324
+ case "data":
325
+ switch (a2aPart.data.part_type) {
326
+ case "tool_call":
327
+ return { type: "tool_call", tool_call: a2aPart.data };
328
+ case "tool_result":
329
+ return { type: "tool_result", tool_result: a2aPart.data };
330
+ case "code_observation":
331
+ return { type: "code_observation", thought: a2aPart.data.thought, code: a2aPart.data.code };
332
+ case "plan":
333
+ return { type: "plan", plan: a2aPart.data.plan };
334
+ default:
335
+ return { type: "data", data: a2aPart.data };
336
+ }
337
+ default:
338
+ return { type: "text", text: JSON.stringify(a2aPart) };
339
+ }
340
+ }
341
+
342
+ // ../core/src/types.ts
343
+ function isDistriMessage(event) {
344
+ return "id" in event && "role" in event && "parts" in event;
345
+ }
1299
346
 
1300
347
  // src/hooks/registerTools.tsx
1301
348
  var import_react7 = require("react");
@@ -1646,7 +693,7 @@ function useChat({
1646
693
  threadId,
1647
694
  onMessage,
1648
695
  onError,
1649
- metadata,
696
+ getMetadata,
1650
697
  onMessagesUpdate,
1651
698
  agent,
1652
699
  tools
@@ -1659,8 +706,8 @@ function useChat({
1659
706
  const createInvokeContext = (0, import_react9.useCallback)(() => ({
1660
707
  thread_id: threadId,
1661
708
  run_id: void 0,
1662
- metadata
1663
- }), [threadId, metadata]);
709
+ getMetadata
710
+ }), [threadId, getMetadata]);
1664
711
  registerTools({ agent, tools });
1665
712
  const toolStateHandler = useToolCallState({
1666
713
  agent,
@@ -1765,13 +812,14 @@ function useChat({
1765
812
  abortControllerRef.current = new AbortController();
1766
813
  try {
1767
814
  const parts = typeof content === "string" ? [{ type: "text", text: content }] : content;
1768
- const distriMessage = DistriClient.initDistriMessage("user", parts);
815
+ const distriMessage = import_core3.DistriClient.initDistriMessage("user", parts);
1769
816
  const context = createInvokeContext();
1770
- const a2aMessage = convertDistriMessageToA2A(distriMessage, context);
817
+ const a2aMessage = (0, import_core4.convertDistriMessageToA2A)(distriMessage, context);
1771
818
  setMessages((prev) => [...prev, distriMessage]);
819
+ const contextMetadata = await getMetadata?.() || {};
1772
820
  const stream = await agent.invokeStream({
1773
821
  message: a2aMessage,
1774
- metadata: context.metadata
822
+ metadata: contextMetadata
1775
823
  });
1776
824
  for await (const event of stream) {
1777
825
  if (abortControllerRef.current?.signal.aborted) {
@@ -1803,13 +851,14 @@ function useChat({
1803
851
  abortControllerRef.current = new AbortController();
1804
852
  try {
1805
853
  const parts = typeof content === "string" ? [{ type: "text", text: content }] : content;
1806
- const distriMessage = DistriClient.initDistriMessage(role, parts);
854
+ const distriMessage = import_core3.DistriClient.initDistriMessage(role, parts);
1807
855
  const context = createInvokeContext();
1808
- const a2aMessage = convertDistriMessageToA2A(distriMessage, context);
856
+ const a2aMessage = (0, import_core4.convertDistriMessageToA2A)(distriMessage, context);
1809
857
  setMessages((prev) => [...prev, distriMessage]);
858
+ const contextMetadata = await getMetadata?.() || {};
1810
859
  const stream = await agent.invokeStream({
1811
860
  message: a2aMessage,
1812
- metadata: context.metadata
861
+ metadata: { ...contextMetadata }
1813
862
  });
1814
863
  for await (const event of stream) {
1815
864
  if (abortControllerRef.current?.signal.aborted) {
@@ -1875,6 +924,9 @@ function useThreads() {
1875
924
  const [error, setError] = (0, import_react10.useState)(null);
1876
925
  const fetchThreads = (0, import_react10.useCallback)(async () => {
1877
926
  if (!client) {
927
+ console.error("[useThreads] Client not available");
928
+ setError(new Error("Client not available"));
929
+ setLoading(false);
1878
930
  return;
1879
931
  }
1880
932
  try {
@@ -1906,7 +958,7 @@ function useThreads() {
1906
958
  throw new Error("Client not available");
1907
959
  }
1908
960
  try {
1909
- const response = await fetch(`${client.baseUrl}/api/v1/threads/${threadId}`, {
961
+ const response = await fetch(`${client.baseUrl}/threads/${threadId}`, {
1910
962
  method: "DELETE"
1911
963
  });
1912
964
  if (!response.ok) {
@@ -1923,7 +975,7 @@ function useThreads() {
1923
975
  return;
1924
976
  }
1925
977
  try {
1926
- const response = await fetch(`${client.baseUrl}/api/v1/threads/${threadId}`);
978
+ const response = await fetch(`${client.baseUrl}/threads/${threadId}`);
1927
979
  if (response.ok) {
1928
980
  const updatedThread = await response.json();
1929
981
  setThreads((prev) => {
@@ -1982,6 +1034,7 @@ var import_react18 = require("react");
1982
1034
  // src/components/EmbeddableChat.tsx
1983
1035
  var import_react15 = require("react");
1984
1036
  var import_lucide_react7 = require("lucide-react");
1037
+ var import_core7 = require("@distri/core");
1985
1038
 
1986
1039
  // src/components/Components.tsx
1987
1040
  var import_react13 = __toESM(require("react"), 1);
@@ -2019,6 +1072,7 @@ var useChatConfig = () => {
2019
1072
  };
2020
1073
 
2021
1074
  // src/components/MessageRenderer.tsx
1075
+ var import_core5 = require("@distri/core");
2022
1076
  var import_jsx_runtime8 = require("react/jsx-runtime");
2023
1077
  var CodeBlock = ({ language, children, inline = false }) => {
2024
1078
  const [copied, setCopied] = import_react12.default.useState(false);
@@ -2237,7 +1291,7 @@ var MessageRenderer = ({
2237
1291
  theme: "chatgpt"
2238
1292
  };
2239
1293
  }
2240
- if (message && isDistriMessage(message)) {
1294
+ if (message && (0, import_core5.isDistriMessage)(message)) {
2241
1295
  const hasToolCalls = message.parts.some((part) => part.type === "tool_call");
2242
1296
  const filteredParts = hasToolCalls ? message.parts.filter((part) => part.type !== "tool_result") : message.parts;
2243
1297
  const groupedParts = [];
@@ -2646,8 +1700,9 @@ var DebugMessage = ({
2646
1700
  };
2647
1701
 
2648
1702
  // src/utils/messageUtils.ts
1703
+ var import_core6 = require("@distri/core");
2649
1704
  var extractTextFromMessage = (message) => {
2650
- if (isDistriMessage(message)) {
1705
+ if ((0, import_core6.isDistriMessage)(message)) {
2651
1706
  if (!message?.parts || !Array.isArray(message.parts)) {
2652
1707
  return "";
2653
1708
  }
@@ -2659,7 +1714,7 @@ var extractTextFromMessage = (message) => {
2659
1714
  };
2660
1715
  var shouldDisplayMessage = (message, showDebugMessages = false) => {
2661
1716
  if (!message) return false;
2662
- if (isDistriMessage(message)) {
1717
+ if ((0, import_core6.isDistriMessage)(message)) {
2663
1718
  if (message.role === "user") {
2664
1719
  const textContent2 = extractTextFromMessage(message);
2665
1720
  return textContent2.trim().length > 0;
@@ -2679,7 +1734,6 @@ var SelectPrimitive = __toESM(require("@radix-ui/react-select"), 1);
2679
1734
  var import_lucide_react4 = require("lucide-react");
2680
1735
  var import_jsx_runtime10 = require("react/jsx-runtime");
2681
1736
  var Select = SelectPrimitive.Root;
2682
- var SelectGroup = SelectPrimitive.Group;
2683
1737
  var SelectValue = SelectPrimitive.Value;
2684
1738
  var SelectTrigger = React9.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2685
1739
  SelectPrimitive.Trigger,
@@ -2903,6 +1957,20 @@ var ChatInput = ({
2903
1957
  ] }) }) });
2904
1958
  };
2905
1959
 
1960
+ // ../core/src/distri-client.ts
1961
+ function uuidv4() {
1962
+ if (typeof crypto?.randomUUID === "function") {
1963
+ return crypto.randomUUID();
1964
+ }
1965
+ const array = new Uint8Array(16);
1966
+ crypto.getRandomValues(array);
1967
+ array[6] = array[6] & 15 | 64;
1968
+ array[8] = array[8] & 63 | 128;
1969
+ return [...array].map(
1970
+ (b, i) => ([4, 6, 8, 10].includes(i) ? "-" : "") + b.toString(16).padStart(2, "0")
1971
+ ).join("");
1972
+ }
1973
+
2906
1974
  // src/components/EmbeddableChat.tsx
2907
1975
  var import_jsx_runtime14 = require("react/jsx-runtime");
2908
1976
  var EmbeddableChat = ({
@@ -2910,7 +1978,7 @@ var EmbeddableChat = ({
2910
1978
  agent,
2911
1979
  className = "",
2912
1980
  style = {},
2913
- metadata,
1981
+ getMetadata,
2914
1982
  tools,
2915
1983
  availableAgents = [],
2916
1984
  UserMessageComponent = UserMessage,
@@ -2940,7 +2008,7 @@ var EmbeddableChat = ({
2940
2008
  threadId,
2941
2009
  agent: agent || void 0,
2942
2010
  tools,
2943
- metadata,
2011
+ getMetadata,
2944
2012
  onMessagesUpdate
2945
2013
  });
2946
2014
  (0, import_react15.useEffect)(() => {
@@ -2973,7 +2041,7 @@ var EmbeddableChat = ({
2973
2041
  const messageContent = extractTextFromMessage(message);
2974
2042
  const key = `message-${index}`;
2975
2043
  const timestamp = message.created_at ? new Date(message.created_at) : void 0;
2976
- if (isDistriMessage(message)) {
2044
+ if ((0, import_core7.isDistriMessage)(message)) {
2977
2045
  switch (getMessageType(message)) {
2978
2046
  case "user":
2979
2047
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
@@ -4010,17 +3078,11 @@ var badgeVariants = (0, import_class_variance_authority3.cva)(
4010
3078
  }
4011
3079
  }
4012
3080
  );
4013
- function Badge({ className, variant, ...props }) {
4014
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
4015
- }
4016
3081
 
4017
3082
  // src/components/ui/dialog.tsx
4018
3083
  var React19 = __toESM(require("react"), 1);
4019
3084
  var import_jsx_runtime25 = require("react/jsx-runtime");
4020
3085
  var Dialog = React19.createContext({});
4021
- var DialogRoot = ({ open, onOpenChange, children }) => {
4022
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Dialog.Provider, { value: { open, onOpenChange }, children });
4023
- };
4024
3086
  var DialogTrigger = React19.forwardRef(({ className, children, ...props }, ref) => {
4025
3087
  const context = React19.useContext(Dialog);
4026
3088
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
@@ -4460,7 +3522,7 @@ function AppSidebar({
4460
3522
  var import_jsx_runtime29 = require("react/jsx-runtime");
4461
3523
  var FullChat = ({
4462
3524
  agentId: initialAgentId,
4463
- metadata,
3525
+ getMetadata,
4464
3526
  className = "",
4465
3527
  UserMessageComponent,
4466
3528
  AssistantMessageComponent,
@@ -4484,7 +3546,8 @@ var FullChat = ({
4484
3546
  const currentThread = threads.find((t) => t.id === selectedThreadId);
4485
3547
  const { messages } = useChat({
4486
3548
  threadId: selectedThreadId,
4487
- agent: agent || void 0
3549
+ agent: agent || void 0,
3550
+ getMetadata
4488
3551
  });
4489
3552
  const threadHasStarted = messages.length > 0;
4490
3553
  (0, import_react18.useEffect)(() => {
@@ -4551,7 +3614,7 @@ var FullChat = ({
4551
3614
  threadId: selectedThreadId,
4552
3615
  showAgentSelector: false,
4553
3616
  agent,
4554
- metadata,
3617
+ getMetadata,
4555
3618
  height: "calc(100vh - 4rem)",
4556
3619
  availableAgents,
4557
3620
  UserMessageComponent,
@@ -4640,76 +3703,16 @@ function ThemeToggle() {
4640
3703
  ApprovalToolCall,
4641
3704
  AssistantMessage,
4642
3705
  AssistantWithToolCalls,
4643
- Badge,
4644
- Button,
4645
- Card,
4646
- CardContent,
4647
- CardDescription,
4648
- CardFooter,
4649
- CardHeader,
4650
- CardTitle,
4651
3706
  ChatInput,
4652
3707
  DebugMessage,
4653
- Dialog,
4654
- DialogContent,
4655
- DialogHeader,
4656
- DialogTitle,
4657
- DialogTrigger,
4658
3708
  DistriProvider,
4659
3709
  EmbeddableChat,
4660
3710
  FullChat,
4661
- Input,
4662
3711
  PlanMessage,
4663
- Select,
4664
- SelectContent,
4665
- SelectGroup,
4666
- SelectItem,
4667
- SelectLabel,
4668
- SelectScrollDownButton,
4669
- SelectScrollUpButton,
4670
- SelectSeparator,
4671
- SelectTrigger,
4672
- SelectValue,
4673
- Separator,
4674
- Sheet,
4675
- SheetContent,
4676
- SheetDescription,
4677
- SheetFooter,
4678
- SheetHeader,
4679
- SheetTitle,
4680
- Sidebar,
4681
- SidebarContent,
4682
- SidebarFooter,
4683
- SidebarGroup,
4684
- SidebarGroupAction,
4685
- SidebarGroupContent,
4686
- SidebarGroupLabel,
4687
- SidebarHeader,
4688
- SidebarInset,
4689
- SidebarMenu,
4690
- SidebarMenuAction,
4691
- SidebarMenuBadge,
4692
- SidebarMenuButton,
4693
- SidebarMenuItem,
4694
- SidebarMenuSkeleton,
4695
- SidebarMenuSub,
4696
- SidebarMenuSubButton,
4697
- SidebarMenuSubItem,
4698
- SidebarProvider,
4699
- SidebarRail,
4700
- SidebarSeparator,
4701
- SidebarTrigger,
4702
- Skeleton,
4703
- Textarea,
4704
3712
  ThemeProvider,
4705
3713
  ThemeToggle,
4706
3714
  ToastToolCall,
4707
- Tooltip,
4708
- TooltipContent,
4709
- TooltipProvider,
4710
- TooltipTrigger,
4711
3715
  UserMessage,
4712
- cn,
4713
3716
  extractTextFromMessage,
4714
3717
  registerTools,
4715
3718
  shouldDisplayMessage,
@@ -4717,7 +3720,6 @@ function ThemeToggle() {
4717
3720
  useAgents,
4718
3721
  useChat,
4719
3722
  useDistri,
4720
- useSidebar,
4721
3723
  useTheme,
4722
3724
  useThreads,
4723
3725
  useToolCallState