@distri/core 0.2.3 → 0.2.5
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.mts +797 -216
- package/dist/index.d.ts +797 -216
- package/dist/index.js +1171 -138
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1157 -138
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,126 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
|
|
5
|
-
//
|
|
5
|
+
// src/types.ts
|
|
6
|
+
function isArrayParts(result) {
|
|
7
|
+
return Array.isArray(result) && result[0].part_type;
|
|
8
|
+
}
|
|
9
|
+
function createSuccessfulToolResult(toolCallId, toolName, result) {
|
|
10
|
+
const parts = isArrayParts(result) ? result : [{
|
|
11
|
+
part_type: "data",
|
|
12
|
+
data: {
|
|
13
|
+
result,
|
|
14
|
+
success: true,
|
|
15
|
+
error: void 0
|
|
16
|
+
}
|
|
17
|
+
}];
|
|
18
|
+
return {
|
|
19
|
+
tool_call_id: toolCallId,
|
|
20
|
+
tool_name: toolName,
|
|
21
|
+
parts
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function createFailedToolResult(toolCallId, toolName, error, result) {
|
|
25
|
+
return {
|
|
26
|
+
tool_call_id: toolCallId,
|
|
27
|
+
tool_name: toolName,
|
|
28
|
+
parts: [{
|
|
29
|
+
part_type: "data",
|
|
30
|
+
data: {
|
|
31
|
+
result: result ?? `Tool execution failed: ${error}`,
|
|
32
|
+
success: false,
|
|
33
|
+
error
|
|
34
|
+
}
|
|
35
|
+
}]
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function isDataPart(part) {
|
|
39
|
+
return typeof part === "object" && part !== null && "part_type" in part && part.part_type === "data" && "data" in part;
|
|
40
|
+
}
|
|
41
|
+
function isToolResultData(data) {
|
|
42
|
+
return typeof data === "object" && data !== null && "success" in data && typeof data.success === "boolean";
|
|
43
|
+
}
|
|
44
|
+
function extractToolResultData(toolResult) {
|
|
45
|
+
if (!toolResult.parts || !Array.isArray(toolResult.parts) || toolResult.parts.length === 0) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const firstPart = toolResult.parts[0];
|
|
49
|
+
if (isDataPart(firstPart)) {
|
|
50
|
+
const data = firstPart.data;
|
|
51
|
+
if (isToolResultData(data)) {
|
|
52
|
+
return {
|
|
53
|
+
result: data.result,
|
|
54
|
+
success: data.success,
|
|
55
|
+
error: data.error
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (typeof data === "string") {
|
|
59
|
+
try {
|
|
60
|
+
const parsed = JSON.parse(data);
|
|
61
|
+
if (isToolResultData(parsed)) {
|
|
62
|
+
return {
|
|
63
|
+
result: parsed.result,
|
|
64
|
+
success: parsed.success,
|
|
65
|
+
error: parsed.error
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
result: parsed,
|
|
70
|
+
success: true,
|
|
71
|
+
error: void 0
|
|
72
|
+
};
|
|
73
|
+
} catch {
|
|
74
|
+
return {
|
|
75
|
+
result: data,
|
|
76
|
+
success: true,
|
|
77
|
+
error: void 0
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
result: data,
|
|
83
|
+
success: true,
|
|
84
|
+
error: void 0
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
var DEFAULT_BASE_URL = "https://api.distri.dev";
|
|
90
|
+
var DistriError = class extends Error {
|
|
91
|
+
constructor(message, code, details) {
|
|
92
|
+
super(message);
|
|
93
|
+
this.code = code;
|
|
94
|
+
this.details = details;
|
|
95
|
+
this.name = "DistriError";
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
var A2AProtocolError = class extends DistriError {
|
|
99
|
+
constructor(message, details) {
|
|
100
|
+
super(message, "A2A_PROTOCOL_ERROR", details);
|
|
101
|
+
this.name = "A2AProtocolError";
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
var ApiError = class extends DistriError {
|
|
105
|
+
constructor(message, statusCode, details) {
|
|
106
|
+
super(message, "API_ERROR", details);
|
|
107
|
+
this.statusCode = statusCode;
|
|
108
|
+
this.name = "ApiError";
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
var ConnectionError = class extends DistriError {
|
|
112
|
+
constructor(message, details) {
|
|
113
|
+
super(message, "CONNECTION_ERROR", details);
|
|
114
|
+
this.name = "ConnectionError";
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
function isDistriMessage(event) {
|
|
118
|
+
return "id" in event && "role" in event && "parts" in event;
|
|
119
|
+
}
|
|
120
|
+
function isDistriEvent(event) {
|
|
121
|
+
return "type" in event && "data" in event;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ../../../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
|
|
6
125
|
var A2AClient = class {
|
|
7
126
|
/**
|
|
8
127
|
* Constructs an A2AClient instance.
|
|
@@ -372,35 +491,6 @@ var A2AClient = class {
|
|
|
372
491
|
}
|
|
373
492
|
};
|
|
374
493
|
|
|
375
|
-
// src/types.ts
|
|
376
|
-
var DistriError = class extends Error {
|
|
377
|
-
constructor(message, code, details) {
|
|
378
|
-
super(message);
|
|
379
|
-
this.code = code;
|
|
380
|
-
this.details = details;
|
|
381
|
-
this.name = "DistriError";
|
|
382
|
-
}
|
|
383
|
-
};
|
|
384
|
-
var A2AProtocolError = class extends DistriError {
|
|
385
|
-
constructor(message, details) {
|
|
386
|
-
super(message, "A2A_PROTOCOL_ERROR", details);
|
|
387
|
-
this.name = "A2AProtocolError";
|
|
388
|
-
}
|
|
389
|
-
};
|
|
390
|
-
var ApiError = class extends DistriError {
|
|
391
|
-
constructor(message, statusCode, details) {
|
|
392
|
-
super(message, "API_ERROR", details);
|
|
393
|
-
this.statusCode = statusCode;
|
|
394
|
-
this.name = "ApiError";
|
|
395
|
-
}
|
|
396
|
-
};
|
|
397
|
-
function isDistriMessage(event) {
|
|
398
|
-
return "id" in event && "role" in event && "parts" in event;
|
|
399
|
-
}
|
|
400
|
-
function isDistriEvent(event) {
|
|
401
|
-
return "type" in event && "metadata" in event;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
494
|
// src/encoder.ts
|
|
405
495
|
function convertA2AMessageToDistri(a2aMessage) {
|
|
406
496
|
const role = a2aMessage.role === "agent" ? "assistant" : "user";
|
|
@@ -411,31 +501,251 @@ function convertA2AMessageToDistri(a2aMessage) {
|
|
|
411
501
|
created_at: a2aMessage.createdAt
|
|
412
502
|
};
|
|
413
503
|
}
|
|
504
|
+
function convertA2AStatusUpdateToDistri(statusUpdate) {
|
|
505
|
+
if (!statusUpdate.metadata || !statusUpdate.metadata.type) {
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
const metadata = statusUpdate.metadata;
|
|
509
|
+
switch (metadata.type) {
|
|
510
|
+
case "run_started": {
|
|
511
|
+
const runStartedResult = {
|
|
512
|
+
type: "run_started",
|
|
513
|
+
data: {
|
|
514
|
+
runId: statusUpdate.runId,
|
|
515
|
+
taskId: statusUpdate.taskId
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
return runStartedResult;
|
|
519
|
+
}
|
|
520
|
+
case "run_error": {
|
|
521
|
+
const runErrorResult = {
|
|
522
|
+
type: "run_error",
|
|
523
|
+
data: {
|
|
524
|
+
message: statusUpdate.error,
|
|
525
|
+
code: statusUpdate.code
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
return runErrorResult;
|
|
529
|
+
}
|
|
530
|
+
case "run_finished": {
|
|
531
|
+
const runFinishedResult = {
|
|
532
|
+
type: "run_finished",
|
|
533
|
+
data: {
|
|
534
|
+
runId: statusUpdate.runId,
|
|
535
|
+
taskId: statusUpdate.taskId
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
return runFinishedResult;
|
|
539
|
+
}
|
|
540
|
+
case "plan_started": {
|
|
541
|
+
const planStartedResult = {
|
|
542
|
+
type: "plan_started",
|
|
543
|
+
data: {
|
|
544
|
+
initial_plan: metadata.initial_plan
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
return planStartedResult;
|
|
548
|
+
}
|
|
549
|
+
case "plan_finished": {
|
|
550
|
+
const planFinishedResult = {
|
|
551
|
+
type: "plan_finished",
|
|
552
|
+
data: {
|
|
553
|
+
total_steps: metadata.total_steps
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
return planFinishedResult;
|
|
557
|
+
}
|
|
558
|
+
case "step_started": {
|
|
559
|
+
const stepStartedResult = {
|
|
560
|
+
type: "step_started",
|
|
561
|
+
data: {
|
|
562
|
+
step_id: metadata.step_id,
|
|
563
|
+
step_title: metadata.step_title || "Processing",
|
|
564
|
+
step_index: metadata.step_index || 0
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
return stepStartedResult;
|
|
568
|
+
}
|
|
569
|
+
case "step_completed": {
|
|
570
|
+
const stepCompletedResult = {
|
|
571
|
+
type: "step_completed",
|
|
572
|
+
data: {
|
|
573
|
+
step_id: metadata.step_id,
|
|
574
|
+
step_title: metadata.step_title || "Processing",
|
|
575
|
+
step_index: metadata.step_index || 0
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
return stepCompletedResult;
|
|
579
|
+
}
|
|
580
|
+
case "tool_execution_start": {
|
|
581
|
+
const toolStartResult = {
|
|
582
|
+
type: "tool_execution_start",
|
|
583
|
+
data: {
|
|
584
|
+
tool_call_id: metadata.tool_call_id,
|
|
585
|
+
tool_call_name: metadata.tool_call_name || "Tool",
|
|
586
|
+
parent_message_id: statusUpdate.taskId
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
return toolStartResult;
|
|
590
|
+
}
|
|
591
|
+
case "tool_execution_end": {
|
|
592
|
+
const toolEndResult = {
|
|
593
|
+
type: "tool_execution_end",
|
|
594
|
+
data: {
|
|
595
|
+
tool_call_id: metadata.tool_call_id
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
return toolEndResult;
|
|
599
|
+
}
|
|
600
|
+
case "text_message_start": {
|
|
601
|
+
const textStartResult = {
|
|
602
|
+
type: "text_message_start",
|
|
603
|
+
data: {
|
|
604
|
+
message_id: metadata.message_id,
|
|
605
|
+
step_id: metadata.step_id || "",
|
|
606
|
+
role: metadata.role === "assistant" ? "assistant" : "user"
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
return textStartResult;
|
|
610
|
+
}
|
|
611
|
+
case "text_message_content": {
|
|
612
|
+
const textContentResult = {
|
|
613
|
+
type: "text_message_content",
|
|
614
|
+
data: {
|
|
615
|
+
message_id: metadata.message_id,
|
|
616
|
+
step_id: metadata.step_id || "",
|
|
617
|
+
delta: metadata.delta || ""
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
return textContentResult;
|
|
621
|
+
}
|
|
622
|
+
case "text_message_end": {
|
|
623
|
+
const textEndResult = {
|
|
624
|
+
type: "text_message_end",
|
|
625
|
+
data: {
|
|
626
|
+
message_id: metadata.message_id,
|
|
627
|
+
step_id: metadata.step_id || ""
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
return textEndResult;
|
|
631
|
+
}
|
|
632
|
+
case "tool_calls": {
|
|
633
|
+
const toolCallsResult = {
|
|
634
|
+
type: "tool_calls",
|
|
635
|
+
data: {
|
|
636
|
+
tool_calls: metadata.tool_calls || []
|
|
637
|
+
}
|
|
638
|
+
};
|
|
639
|
+
return toolCallsResult;
|
|
640
|
+
}
|
|
641
|
+
case "tool_results": {
|
|
642
|
+
const toolResultsResult = {
|
|
643
|
+
type: "tool_results",
|
|
644
|
+
data: {
|
|
645
|
+
results: metadata.results || []
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
return toolResultsResult;
|
|
649
|
+
}
|
|
650
|
+
case "browser_screenshot": {
|
|
651
|
+
const browserScreenshotResult = {
|
|
652
|
+
type: "browser_screenshot",
|
|
653
|
+
data: {
|
|
654
|
+
image: metadata.image || "",
|
|
655
|
+
format: metadata.format,
|
|
656
|
+
filename: metadata.filename,
|
|
657
|
+
size: metadata.size,
|
|
658
|
+
timestamp_ms: metadata.timestamp_ms
|
|
659
|
+
}
|
|
660
|
+
};
|
|
661
|
+
return browserScreenshotResult;
|
|
662
|
+
}
|
|
663
|
+
case "inline_hook_requested": {
|
|
664
|
+
const hookRequested = {
|
|
665
|
+
type: "inline_hook_requested",
|
|
666
|
+
data: {
|
|
667
|
+
hook_id: metadata.request?.hook_id || metadata.hook_id || "",
|
|
668
|
+
hook: metadata.request?.hook || metadata.hook || "",
|
|
669
|
+
context: metadata.request?.context || metadata.context || {
|
|
670
|
+
agent_id: statusUpdate.agentId,
|
|
671
|
+
thread_id: statusUpdate.contextId,
|
|
672
|
+
task_id: statusUpdate.taskId,
|
|
673
|
+
run_id: statusUpdate.agentId
|
|
674
|
+
},
|
|
675
|
+
timeout_ms: metadata.request?.timeout_ms || metadata.timeout_ms,
|
|
676
|
+
fire_and_forget: metadata.request?.fire_and_forget ?? metadata.fire_and_forget,
|
|
677
|
+
message: metadata.request?.message || metadata.message,
|
|
678
|
+
plan: metadata.request?.plan || metadata.plan,
|
|
679
|
+
result: metadata.request?.result || metadata.result
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
return hookRequested;
|
|
683
|
+
}
|
|
684
|
+
default: {
|
|
685
|
+
console.warn(`Unhandled status update metadata type: ${metadata.type}`, metadata);
|
|
686
|
+
const defaultResult = {
|
|
687
|
+
type: "run_started",
|
|
688
|
+
data: {
|
|
689
|
+
runId: statusUpdate.runId,
|
|
690
|
+
taskId: statusUpdate.taskId
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
return defaultResult;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
function decodeA2AStreamEvent(event) {
|
|
698
|
+
if (event.kind === "message") {
|
|
699
|
+
return convertA2AMessageToDistri(event);
|
|
700
|
+
}
|
|
701
|
+
if (event.kind === "status-update") {
|
|
702
|
+
return convertA2AStatusUpdateToDistri(event);
|
|
703
|
+
}
|
|
704
|
+
return null;
|
|
705
|
+
}
|
|
706
|
+
function processA2AStreamData(streamData) {
|
|
707
|
+
const results = [];
|
|
708
|
+
for (const item of streamData) {
|
|
709
|
+
const converted = decodeA2AStreamEvent(item);
|
|
710
|
+
if (converted) {
|
|
711
|
+
results.push(converted);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
return results;
|
|
715
|
+
}
|
|
716
|
+
function processA2AMessagesData(data) {
|
|
717
|
+
const results = [];
|
|
718
|
+
for (const item of data) {
|
|
719
|
+
if (item.kind === "message") {
|
|
720
|
+
const distriMessage = convertA2AMessageToDistri(item);
|
|
721
|
+
results.push(distriMessage);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
return results;
|
|
725
|
+
}
|
|
414
726
|
function convertA2APartToDistri(a2aPart) {
|
|
415
727
|
switch (a2aPart.kind) {
|
|
416
728
|
case "text":
|
|
417
|
-
return {
|
|
729
|
+
return { part_type: "text", data: a2aPart.text };
|
|
418
730
|
case "file":
|
|
419
731
|
if ("uri" in a2aPart.file) {
|
|
420
|
-
|
|
732
|
+
const fileUrl = { type: "url", mime_type: a2aPart.file.mimeType || "application/octet-stream", url: a2aPart.file.uri || "" };
|
|
733
|
+
return { part_type: "image", data: fileUrl };
|
|
421
734
|
} else {
|
|
422
|
-
|
|
735
|
+
const fileBytes = { type: "bytes", mime_type: a2aPart.file.mimeType || "application/octet-stream", data: a2aPart.file.bytes || "" };
|
|
736
|
+
return { part_type: "image", data: fileBytes };
|
|
423
737
|
}
|
|
424
738
|
case "data":
|
|
425
739
|
switch (a2aPart.data.part_type) {
|
|
426
740
|
case "tool_call":
|
|
427
|
-
return {
|
|
741
|
+
return { part_type: "tool_call", data: a2aPart.data };
|
|
428
742
|
case "tool_result":
|
|
429
|
-
return {
|
|
430
|
-
case "code_observation":
|
|
431
|
-
return { type: "code_observation", thought: a2aPart.data.thought, code: a2aPart.data.code };
|
|
432
|
-
case "plan":
|
|
433
|
-
return { type: "plan", plan: a2aPart.data.plan };
|
|
743
|
+
return { part_type: "tool_result", data: a2aPart.data };
|
|
434
744
|
default:
|
|
435
|
-
return {
|
|
745
|
+
return { part_type: "data", data: a2aPart.data };
|
|
436
746
|
}
|
|
437
747
|
default:
|
|
438
|
-
return {
|
|
748
|
+
return { part_type: "text", data: JSON.stringify(a2aPart) };
|
|
439
749
|
}
|
|
440
750
|
}
|
|
441
751
|
function convertDistriMessageToA2A(distriMessage, context) {
|
|
@@ -460,52 +770,95 @@ function convertDistriMessageToA2A(distriMessage, context) {
|
|
|
460
770
|
parts: distriMessage.parts.map(convertDistriPartToA2A),
|
|
461
771
|
kind: "message",
|
|
462
772
|
contextId: context.thread_id,
|
|
463
|
-
taskId: context.run_id
|
|
773
|
+
taskId: context.task_id || context.run_id || void 0
|
|
464
774
|
};
|
|
465
775
|
}
|
|
466
776
|
function convertDistriPartToA2A(distriPart) {
|
|
467
|
-
|
|
777
|
+
let result;
|
|
778
|
+
switch (distriPart.part_type) {
|
|
468
779
|
case "text":
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
780
|
+
result = { kind: "text", text: distriPart.data };
|
|
781
|
+
break;
|
|
782
|
+
case "image":
|
|
783
|
+
if ("url" in distriPart.data) {
|
|
784
|
+
const fileUri = { mimeType: distriPart.data.mime_type, uri: distriPart.data.url };
|
|
785
|
+
result = { kind: "file", file: fileUri };
|
|
786
|
+
} else {
|
|
787
|
+
const fileBytes = { mimeType: distriPart.data.mime_type, bytes: distriPart.data.data };
|
|
788
|
+
result = { kind: "file", file: fileBytes };
|
|
789
|
+
}
|
|
790
|
+
break;
|
|
474
791
|
case "tool_call":
|
|
475
|
-
|
|
476
|
-
case "tool_result":
|
|
477
|
-
let val = {
|
|
792
|
+
result = {
|
|
478
793
|
kind: "data",
|
|
479
794
|
data: {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
part_type: "tool_result"
|
|
795
|
+
part_type: "tool_call",
|
|
796
|
+
data: distriPart.data
|
|
483
797
|
}
|
|
484
798
|
};
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
799
|
+
break;
|
|
800
|
+
case "tool_result": {
|
|
801
|
+
const toolResult = distriPart.data;
|
|
802
|
+
const parts = toolResult.parts.map((part) => {
|
|
803
|
+
if ("type" in part && part.type === "data") {
|
|
804
|
+
return {
|
|
805
|
+
part_type: "data",
|
|
806
|
+
data: part.data
|
|
807
|
+
};
|
|
808
|
+
} else if ("part_type" in part) {
|
|
809
|
+
return part;
|
|
810
|
+
} else {
|
|
811
|
+
return {
|
|
812
|
+
part_type: "data",
|
|
813
|
+
data: part
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
});
|
|
817
|
+
result = {
|
|
818
|
+
kind: "data",
|
|
819
|
+
data: {
|
|
820
|
+
part_type: "tool_result",
|
|
821
|
+
data: {
|
|
822
|
+
tool_call_id: toolResult.tool_call_id,
|
|
823
|
+
tool_name: toolResult.tool_name,
|
|
824
|
+
parts
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
};
|
|
828
|
+
break;
|
|
829
|
+
}
|
|
830
|
+
case "data": {
|
|
831
|
+
const dataValue = distriPart.data;
|
|
832
|
+
if (dataValue === null || typeof dataValue !== "object" || Array.isArray(dataValue)) {
|
|
833
|
+
result = { kind: "data", data: { value: dataValue } };
|
|
834
|
+
} else {
|
|
835
|
+
const dataObj = dataValue;
|
|
836
|
+
result = { kind: "data", data: dataObj };
|
|
837
|
+
}
|
|
838
|
+
break;
|
|
839
|
+
}
|
|
493
840
|
}
|
|
841
|
+
return result;
|
|
494
842
|
}
|
|
495
843
|
function extractTextFromDistriMessage(message) {
|
|
496
|
-
return message.parts.filter((part) => part.
|
|
844
|
+
return message.parts.filter((part) => part.part_type === "text").map((part) => part.data).join("\n");
|
|
497
845
|
}
|
|
498
846
|
function extractToolCallsFromDistriMessage(message) {
|
|
499
|
-
return message.parts.filter((part) => part.
|
|
847
|
+
return message.parts.filter((part) => part.part_type === "tool_call").map((part) => part.data);
|
|
500
848
|
}
|
|
501
849
|
function extractToolResultsFromDistriMessage(message) {
|
|
502
|
-
return message.parts.filter((part) => part.
|
|
850
|
+
return message.parts.filter((part) => part.part_type === "tool_result").map((part) => part.data);
|
|
503
851
|
}
|
|
504
852
|
|
|
505
853
|
// src/distri-client.ts
|
|
506
|
-
var
|
|
854
|
+
var _DistriClient = class _DistriClient {
|
|
507
855
|
constructor(config) {
|
|
508
856
|
this.agentClients = /* @__PURE__ */ new Map();
|
|
857
|
+
const headers = { ...config.headers };
|
|
858
|
+
this.accessToken = config.accessToken;
|
|
859
|
+
this.refreshToken = config.refreshToken;
|
|
860
|
+
this.tokenRefreshSkewMs = config.tokenRefreshSkewMs ?? 6e4;
|
|
861
|
+
this.onTokenRefresh = config.onTokenRefresh;
|
|
509
862
|
this.config = {
|
|
510
863
|
baseUrl: config.baseUrl.replace(/\/$/, ""),
|
|
511
864
|
apiVersion: config.apiVersion || "v1",
|
|
@@ -513,10 +866,362 @@ var DistriClient = class {
|
|
|
513
866
|
retryAttempts: config.retryAttempts || 3,
|
|
514
867
|
retryDelay: config.retryDelay || 1e3,
|
|
515
868
|
debug: config.debug || false,
|
|
516
|
-
headers
|
|
869
|
+
headers,
|
|
517
870
|
interceptor: config.interceptor || ((init) => Promise.resolve(init))
|
|
518
871
|
};
|
|
519
|
-
this.debug("DistriClient initialized with config:",
|
|
872
|
+
this.debug("DistriClient initialized with config:", {
|
|
873
|
+
baseUrl: this.config.baseUrl,
|
|
874
|
+
hasAccessToken: !!this.accessToken,
|
|
875
|
+
hasRefreshToken: !!this.refreshToken,
|
|
876
|
+
timeout: this.config.timeout
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Create a client with default cloud configuration.
|
|
881
|
+
*
|
|
882
|
+
* @param overrides - Optional overrides for the default config
|
|
883
|
+
*/
|
|
884
|
+
static create(overrides = {}) {
|
|
885
|
+
return new _DistriClient({
|
|
886
|
+
baseUrl: DEFAULT_BASE_URL,
|
|
887
|
+
...overrides
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Check if this client has authentication configured.
|
|
892
|
+
*/
|
|
893
|
+
hasAuth() {
|
|
894
|
+
return !!this.accessToken || !!this.refreshToken;
|
|
895
|
+
}
|
|
896
|
+
/**
|
|
897
|
+
* Check if this client is configured for local development.
|
|
898
|
+
*/
|
|
899
|
+
isLocal() {
|
|
900
|
+
return this.config.baseUrl.includes("localhost") || this.config.baseUrl.includes("127.0.0.1");
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* Session store: set a value (optionally with expiry)
|
|
904
|
+
*/
|
|
905
|
+
async setSessionValue(sessionId, key, value, expiry) {
|
|
906
|
+
const body = { key, value };
|
|
907
|
+
if (expiry) {
|
|
908
|
+
body.expiry = typeof expiry === "string" ? expiry : expiry.toISOString();
|
|
909
|
+
}
|
|
910
|
+
const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}/values`, {
|
|
911
|
+
method: "POST",
|
|
912
|
+
headers: {
|
|
913
|
+
"Content-Type": "application/json",
|
|
914
|
+
...this.config.headers
|
|
915
|
+
},
|
|
916
|
+
body: JSON.stringify(body)
|
|
917
|
+
});
|
|
918
|
+
if (!resp.ok && resp.status !== 204) {
|
|
919
|
+
const errorData = await resp.json().catch(() => ({}));
|
|
920
|
+
throw new ApiError(errorData.error || "Failed to set session value", resp.status);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Session store: get a single value
|
|
925
|
+
*/
|
|
926
|
+
async getSessionValue(sessionId, key) {
|
|
927
|
+
const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
|
|
928
|
+
method: "GET",
|
|
929
|
+
headers: {
|
|
930
|
+
...this.config.headers
|
|
931
|
+
}
|
|
932
|
+
});
|
|
933
|
+
if (!resp.ok) {
|
|
934
|
+
const errorData = await resp.json().catch(() => ({}));
|
|
935
|
+
throw new ApiError(errorData.error || "Failed to get session value", resp.status);
|
|
936
|
+
}
|
|
937
|
+
const data = await resp.json().catch(() => ({ value: null }));
|
|
938
|
+
return data?.value ?? null;
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Session store: get all values in a session
|
|
942
|
+
*/
|
|
943
|
+
async getSessionValues(sessionId) {
|
|
944
|
+
const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}/values`, {
|
|
945
|
+
method: "GET",
|
|
946
|
+
headers: {
|
|
947
|
+
...this.config.headers
|
|
948
|
+
}
|
|
949
|
+
});
|
|
950
|
+
if (!resp.ok) {
|
|
951
|
+
const errorData = await resp.json().catch(() => ({}));
|
|
952
|
+
throw new ApiError(errorData.error || "Failed to get session values", resp.status);
|
|
953
|
+
}
|
|
954
|
+
const data = await resp.json().catch(() => ({ values: {} }));
|
|
955
|
+
return data?.values ?? {};
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Session store: delete a single key
|
|
959
|
+
*/
|
|
960
|
+
async deleteSessionValue(sessionId, key) {
|
|
961
|
+
const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
|
|
962
|
+
method: "DELETE",
|
|
963
|
+
headers: {
|
|
964
|
+
...this.config.headers
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
if (!resp.ok && resp.status !== 204) {
|
|
968
|
+
const errorData = await resp.json().catch(() => ({}));
|
|
969
|
+
throw new ApiError(errorData.error || "Failed to delete session value", resp.status);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
/**
|
|
973
|
+
* Session store: clear all keys in a session
|
|
974
|
+
*/
|
|
975
|
+
async clearSession(sessionId) {
|
|
976
|
+
const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}`, {
|
|
977
|
+
method: "DELETE",
|
|
978
|
+
headers: {
|
|
979
|
+
...this.config.headers
|
|
980
|
+
}
|
|
981
|
+
});
|
|
982
|
+
if (!resp.ok && resp.status !== 204) {
|
|
983
|
+
const errorData = await resp.json().catch(() => ({}));
|
|
984
|
+
throw new ApiError(errorData.error || "Failed to clear session", resp.status);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Set additional user message parts for the next agent iteration.
|
|
989
|
+
* These parts will be appended to the user message in the prompt.
|
|
990
|
+
* @param sessionId - The thread/session ID
|
|
991
|
+
* @param parts - Array of DistriPart objects to append to user message
|
|
992
|
+
*/
|
|
993
|
+
async setAdditionalUserParts(sessionId, parts) {
|
|
994
|
+
await this.setSessionValue(sessionId, _DistriClient.ADDITIONAL_PARTS_KEY, parts);
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* Get the current additional user message parts.
|
|
998
|
+
* @param sessionId - The thread/session ID
|
|
999
|
+
* @returns Array of DistriPart objects or null if not set
|
|
1000
|
+
*/
|
|
1001
|
+
async getAdditionalUserParts(sessionId) {
|
|
1002
|
+
return this.getSessionValue(sessionId, _DistriClient.ADDITIONAL_PARTS_KEY);
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Clear/delete the additional user message parts.
|
|
1006
|
+
* @param sessionId - The thread/session ID
|
|
1007
|
+
*/
|
|
1008
|
+
async clearAdditionalUserParts(sessionId) {
|
|
1009
|
+
await this.deleteSessionValue(sessionId, _DistriClient.ADDITIONAL_PARTS_KEY);
|
|
1010
|
+
}
|
|
1011
|
+
/**
|
|
1012
|
+
* Issue an access token + refresh token for temporary authentication.
|
|
1013
|
+
* Requires an existing authenticated session (bearer token).
|
|
1014
|
+
*
|
|
1015
|
+
* @returns Token response with access/refresh token strings
|
|
1016
|
+
* @throws ApiError if not authenticated or token issuance fails
|
|
1017
|
+
*
|
|
1018
|
+
* @example
|
|
1019
|
+
* ```typescript
|
|
1020
|
+
* const { access_token, refresh_token } = await client.issueToken();
|
|
1021
|
+
* // Persist the refresh token and use access_token for requests
|
|
1022
|
+
* ```
|
|
1023
|
+
*/
|
|
1024
|
+
async issueToken() {
|
|
1025
|
+
const response = await this.fetch("/token", {
|
|
1026
|
+
method: "POST",
|
|
1027
|
+
headers: {
|
|
1028
|
+
"Content-Type": "application/json",
|
|
1029
|
+
...this.config.headers
|
|
1030
|
+
}
|
|
1031
|
+
});
|
|
1032
|
+
if (!response.ok) {
|
|
1033
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1034
|
+
throw new ApiError(errorData.error || "Failed to issue token", response.status);
|
|
1035
|
+
}
|
|
1036
|
+
const tokens = await response.json();
|
|
1037
|
+
if (!tokens?.access_token || !tokens?.refresh_token || typeof tokens?.expires_at !== "number") {
|
|
1038
|
+
throw new ApiError("Invalid token response", response.status);
|
|
1039
|
+
}
|
|
1040
|
+
this.applyTokens(tokens.access_token, tokens.refresh_token, false);
|
|
1041
|
+
return tokens;
|
|
1042
|
+
}
|
|
1043
|
+
/**
|
|
1044
|
+
* Get the current access/refresh tokens.
|
|
1045
|
+
*/
|
|
1046
|
+
getTokens() {
|
|
1047
|
+
return { accessToken: this.accessToken, refreshToken: this.refreshToken };
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Update the access/refresh tokens in memory.
|
|
1051
|
+
*/
|
|
1052
|
+
setTokens(tokens) {
|
|
1053
|
+
if (tokens.accessToken !== void 0) {
|
|
1054
|
+
this.accessToken = tokens.accessToken;
|
|
1055
|
+
}
|
|
1056
|
+
if (tokens.refreshToken !== void 0) {
|
|
1057
|
+
this.refreshToken = tokens.refreshToken;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Start streaming speech-to-text transcription via WebSocket
|
|
1062
|
+
*/
|
|
1063
|
+
async streamingTranscription(options = {}) {
|
|
1064
|
+
const baseUrl = this.config.baseUrl;
|
|
1065
|
+
const wsUrl = baseUrl.replace("http://", "ws://").replace("https://", "wss://") + "/voice/stream";
|
|
1066
|
+
return new Promise((resolve, reject) => {
|
|
1067
|
+
const ws = new WebSocket(wsUrl);
|
|
1068
|
+
let isResolved = false;
|
|
1069
|
+
ws.onopen = () => {
|
|
1070
|
+
ws.send(JSON.stringify({ type: "start_session" }));
|
|
1071
|
+
options.onStart?.();
|
|
1072
|
+
if (!isResolved) {
|
|
1073
|
+
isResolved = true;
|
|
1074
|
+
resolve({
|
|
1075
|
+
sendAudio: (audioData) => {
|
|
1076
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
1077
|
+
ws.send(audioData);
|
|
1078
|
+
}
|
|
1079
|
+
},
|
|
1080
|
+
sendText: (text) => {
|
|
1081
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
1082
|
+
ws.send(JSON.stringify({ type: "text_chunk", text }));
|
|
1083
|
+
}
|
|
1084
|
+
},
|
|
1085
|
+
stop: () => {
|
|
1086
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
1087
|
+
ws.send(JSON.stringify({ type: "end_session" }));
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
1090
|
+
close: () => {
|
|
1091
|
+
ws.close();
|
|
1092
|
+
}
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
ws.onmessage = (event) => {
|
|
1097
|
+
try {
|
|
1098
|
+
const data = JSON.parse(event.data);
|
|
1099
|
+
switch (data.type) {
|
|
1100
|
+
case "text_chunk":
|
|
1101
|
+
options.onTranscript?.(data.text || "", data.is_final || false);
|
|
1102
|
+
break;
|
|
1103
|
+
case "session_started":
|
|
1104
|
+
this.debug("Speech-to-text session started");
|
|
1105
|
+
break;
|
|
1106
|
+
case "session_ended":
|
|
1107
|
+
this.debug("Speech-to-text session ended");
|
|
1108
|
+
options.onEnd?.();
|
|
1109
|
+
break;
|
|
1110
|
+
case "error": {
|
|
1111
|
+
const error = new Error(data.message || "WebSocket error");
|
|
1112
|
+
this.debug("Speech-to-text error:", error);
|
|
1113
|
+
options.onError?.(error);
|
|
1114
|
+
break;
|
|
1115
|
+
}
|
|
1116
|
+
default:
|
|
1117
|
+
this.debug("Unknown message type:", data.type);
|
|
1118
|
+
}
|
|
1119
|
+
} catch (error) {
|
|
1120
|
+
const parseError = new Error("Failed to parse WebSocket message");
|
|
1121
|
+
this.debug("Parse error:", parseError);
|
|
1122
|
+
options.onError?.(parseError);
|
|
1123
|
+
}
|
|
1124
|
+
};
|
|
1125
|
+
ws.onerror = (event) => {
|
|
1126
|
+
const error = new Error("WebSocket connection error");
|
|
1127
|
+
this.debug("WebSocket error:", event);
|
|
1128
|
+
options.onError?.(error);
|
|
1129
|
+
if (!isResolved) {
|
|
1130
|
+
isResolved = true;
|
|
1131
|
+
reject(error);
|
|
1132
|
+
}
|
|
1133
|
+
};
|
|
1134
|
+
ws.onclose = (event) => {
|
|
1135
|
+
this.debug("WebSocket closed:", event.code, event.reason);
|
|
1136
|
+
options.onEnd?.();
|
|
1137
|
+
};
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Transcribe audio blob to text using speech-to-text API
|
|
1142
|
+
*/
|
|
1143
|
+
async transcribe(audioBlob, config = {}) {
|
|
1144
|
+
try {
|
|
1145
|
+
const arrayBuffer = await audioBlob.arrayBuffer();
|
|
1146
|
+
const uint8Array = new Uint8Array(arrayBuffer);
|
|
1147
|
+
const base64String = btoa(String.fromCharCode(...uint8Array));
|
|
1148
|
+
const requestBody = {
|
|
1149
|
+
audio: base64String,
|
|
1150
|
+
model: config.model || "whisper-1",
|
|
1151
|
+
...config.language && { language: config.language },
|
|
1152
|
+
...config.temperature !== void 0 && { temperature: config.temperature }
|
|
1153
|
+
};
|
|
1154
|
+
this.debug("Transcribing audio:", {
|
|
1155
|
+
model: requestBody.model,
|
|
1156
|
+
language: config.language,
|
|
1157
|
+
audioSize: audioBlob.size
|
|
1158
|
+
});
|
|
1159
|
+
const response = await this.fetch(`/tts/transcribe`, {
|
|
1160
|
+
method: "POST",
|
|
1161
|
+
headers: {
|
|
1162
|
+
"Content-Type": "application/json",
|
|
1163
|
+
...this.config.headers
|
|
1164
|
+
},
|
|
1165
|
+
body: JSON.stringify(requestBody)
|
|
1166
|
+
});
|
|
1167
|
+
if (!response.ok) {
|
|
1168
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1169
|
+
const errorMessage = errorData.error || `Transcription failed: ${response.status}`;
|
|
1170
|
+
throw new ApiError(errorMessage, response.status);
|
|
1171
|
+
}
|
|
1172
|
+
const result = await response.json();
|
|
1173
|
+
const transcription = result.text || "";
|
|
1174
|
+
this.debug("Transcription result:", { text: transcription });
|
|
1175
|
+
return transcription;
|
|
1176
|
+
} catch (error) {
|
|
1177
|
+
if (error instanceof ApiError) throw error;
|
|
1178
|
+
throw new DistriError("Failed to transcribe audio", "TRANSCRIPTION_ERROR", error);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
async getConfiguration() {
|
|
1182
|
+
const response = await this.fetch(`/configuration`, {
|
|
1183
|
+
method: "GET",
|
|
1184
|
+
headers: {
|
|
1185
|
+
...this.config.headers
|
|
1186
|
+
}
|
|
1187
|
+
});
|
|
1188
|
+
if (!response.ok) {
|
|
1189
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1190
|
+
throw new ApiError(errorData.error || "Failed to load configuration", response.status);
|
|
1191
|
+
}
|
|
1192
|
+
return response.json();
|
|
1193
|
+
}
|
|
1194
|
+
async updateConfiguration(configuration) {
|
|
1195
|
+
const response = await this.fetch(`/configuration`, {
|
|
1196
|
+
method: "PUT",
|
|
1197
|
+
headers: {
|
|
1198
|
+
"Content-Type": "application/json",
|
|
1199
|
+
...this.config.headers
|
|
1200
|
+
},
|
|
1201
|
+
body: JSON.stringify(configuration)
|
|
1202
|
+
});
|
|
1203
|
+
if (!response.ok) {
|
|
1204
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1205
|
+
throw new ApiError(errorData.error || "Failed to update configuration", response.status);
|
|
1206
|
+
}
|
|
1207
|
+
return response.json();
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Minimal LLM helper that proxies to the Distri server using Distri messages.
|
|
1211
|
+
*/
|
|
1212
|
+
async llm(messages, tools = [], options) {
|
|
1213
|
+
const headers = { "Content-Type": "application/json" };
|
|
1214
|
+
const response = await this.fetch(`/llm/execute`, {
|
|
1215
|
+
method: "POST",
|
|
1216
|
+
headers,
|
|
1217
|
+
body: JSON.stringify({ messages, tools, ...options })
|
|
1218
|
+
});
|
|
1219
|
+
if (!response.ok) {
|
|
1220
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1221
|
+
const message = errorData?.error || response.statusText || "LLM request failed";
|
|
1222
|
+
throw new ApiError(`LLM request failed: ${message}`, response.status);
|
|
1223
|
+
}
|
|
1224
|
+
return response.json();
|
|
520
1225
|
}
|
|
521
1226
|
/**
|
|
522
1227
|
* Get all available agents from the Distri server
|
|
@@ -573,14 +1278,18 @@ var DistriClient = class {
|
|
|
573
1278
|
* Get or create A2AClient for an agent
|
|
574
1279
|
*/
|
|
575
1280
|
getA2AClient(agentId) {
|
|
576
|
-
|
|
1281
|
+
const agentUrl = `${this.config.baseUrl}/agents/${agentId}`;
|
|
1282
|
+
const existing = this.agentClients.get(agentId);
|
|
1283
|
+
if (!existing || existing.url !== agentUrl) {
|
|
577
1284
|
const fetchFn = this.fetchAbsolute.bind(this);
|
|
578
|
-
const agentUrl = `${this.config.baseUrl}/agents/${agentId}`;
|
|
579
1285
|
const client = new A2AClient(agentUrl, fetchFn);
|
|
580
|
-
this.agentClients.set(agentId, client);
|
|
581
|
-
this.debug(
|
|
1286
|
+
this.agentClients.set(agentId, { url: agentUrl, client });
|
|
1287
|
+
this.debug(
|
|
1288
|
+
existing ? `Recreated A2AClient for agent ${agentId} with new URL ${agentUrl}` : `Created A2AClient for agent ${agentId} at ${agentUrl}`
|
|
1289
|
+
);
|
|
1290
|
+
return client;
|
|
582
1291
|
}
|
|
583
|
-
return
|
|
1292
|
+
return existing.client;
|
|
584
1293
|
}
|
|
585
1294
|
/**
|
|
586
1295
|
* Send a message to an agent
|
|
@@ -607,6 +1316,7 @@ var DistriClient = class {
|
|
|
607
1316
|
* Send a streaming message to an agent
|
|
608
1317
|
*/
|
|
609
1318
|
async *sendMessageStream(agentId, params) {
|
|
1319
|
+
console.log("sendMessageStream", agentId, params);
|
|
610
1320
|
try {
|
|
611
1321
|
const client = this.getA2AClient(agentId);
|
|
612
1322
|
yield* await client.sendMessageStream(params);
|
|
@@ -712,18 +1422,195 @@ var DistriClient = class {
|
|
|
712
1422
|
};
|
|
713
1423
|
await this.sendMessage(threadId, params);
|
|
714
1424
|
}
|
|
1425
|
+
/**
|
|
1426
|
+
* Complete an external tool call
|
|
1427
|
+
*/
|
|
1428
|
+
async completeTool(agentId, result) {
|
|
1429
|
+
try {
|
|
1430
|
+
const response = await this.fetch(`/agents/${agentId}/complete-tool`, {
|
|
1431
|
+
method: "POST",
|
|
1432
|
+
headers: {
|
|
1433
|
+
"Content-Type": "application/json",
|
|
1434
|
+
...this.config.headers
|
|
1435
|
+
},
|
|
1436
|
+
body: JSON.stringify({
|
|
1437
|
+
tool_call_id: result.tool_call_id,
|
|
1438
|
+
tool_response: result
|
|
1439
|
+
})
|
|
1440
|
+
});
|
|
1441
|
+
if (!response.ok) {
|
|
1442
|
+
throw new ApiError(`Failed to complete tool: ${response.statusText}`, response.status);
|
|
1443
|
+
}
|
|
1444
|
+
this.debug(`Tool completed: ${result.tool_name} (${result.tool_call_id}) for agent ${agentId}`);
|
|
1445
|
+
} catch (error) {
|
|
1446
|
+
if (error instanceof ApiError) throw error;
|
|
1447
|
+
throw new DistriError(`Failed to complete tool ${result.tool_name} (${result.tool_call_id}) for agent ${agentId}`, "COMPLETE_TOOL_ERROR", error);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
/**
|
|
1451
|
+
* Complete an inline hook with a mutation payload.
|
|
1452
|
+
*/
|
|
1453
|
+
async completeInlineHook(hookId, mutation) {
|
|
1454
|
+
const response = await this.fetch(`/event/hooks`, {
|
|
1455
|
+
method: "POST",
|
|
1456
|
+
headers: {
|
|
1457
|
+
"Content-Type": "application/json",
|
|
1458
|
+
...this.config.headers
|
|
1459
|
+
},
|
|
1460
|
+
body: JSON.stringify({
|
|
1461
|
+
hook_id: hookId,
|
|
1462
|
+
mutation
|
|
1463
|
+
})
|
|
1464
|
+
});
|
|
1465
|
+
if (!response.ok) {
|
|
1466
|
+
throw new ApiError(`Failed to complete inline hook: ${response.statusText}`, response.status);
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
715
1469
|
/**
|
|
716
1470
|
* Get the base URL for making direct requests
|
|
717
1471
|
*/
|
|
718
1472
|
get baseUrl() {
|
|
719
1473
|
return this.config.baseUrl;
|
|
720
1474
|
}
|
|
1475
|
+
applyTokens(accessToken, refreshToken, notify) {
|
|
1476
|
+
this.accessToken = accessToken;
|
|
1477
|
+
this.refreshToken = refreshToken;
|
|
1478
|
+
if (notify && this.onTokenRefresh) {
|
|
1479
|
+
this.onTokenRefresh({ accessToken, refreshToken });
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
async ensureAccessToken() {
|
|
1483
|
+
if (!this.refreshToken) {
|
|
1484
|
+
return;
|
|
1485
|
+
}
|
|
1486
|
+
if (!this.accessToken || this.isTokenExpiring(this.accessToken)) {
|
|
1487
|
+
try {
|
|
1488
|
+
await this.refreshTokens();
|
|
1489
|
+
} catch (error) {
|
|
1490
|
+
this.debug("Token refresh failed:", error);
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
async refreshTokens() {
|
|
1495
|
+
if (!this.refreshToken) {
|
|
1496
|
+
return;
|
|
1497
|
+
}
|
|
1498
|
+
if (!this.refreshPromise) {
|
|
1499
|
+
this.refreshPromise = this.performTokenRefresh().finally(() => {
|
|
1500
|
+
this.refreshPromise = void 0;
|
|
1501
|
+
});
|
|
1502
|
+
}
|
|
1503
|
+
return this.refreshPromise;
|
|
1504
|
+
}
|
|
1505
|
+
async performTokenRefresh() {
|
|
1506
|
+
const response = await this.fetchAbsolute(
|
|
1507
|
+
`${this.config.baseUrl}/token`,
|
|
1508
|
+
{
|
|
1509
|
+
method: "POST",
|
|
1510
|
+
headers: {
|
|
1511
|
+
"Content-Type": "application/json",
|
|
1512
|
+
...this.config.headers
|
|
1513
|
+
},
|
|
1514
|
+
body: JSON.stringify({
|
|
1515
|
+
grant_type: "refresh_token",
|
|
1516
|
+
refresh_token: this.refreshToken
|
|
1517
|
+
})
|
|
1518
|
+
},
|
|
1519
|
+
{ skipAuth: true, retryOnAuth: false }
|
|
1520
|
+
);
|
|
1521
|
+
if (!response.ok) {
|
|
1522
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1523
|
+
throw new ApiError(errorData.error || "Failed to refresh token", response.status);
|
|
1524
|
+
}
|
|
1525
|
+
const tokens = await response.json();
|
|
1526
|
+
if (!tokens?.access_token || !tokens?.refresh_token) {
|
|
1527
|
+
throw new ApiError("Invalid token response", response.status);
|
|
1528
|
+
}
|
|
1529
|
+
this.applyTokens(tokens.access_token, tokens.refresh_token, true);
|
|
1530
|
+
}
|
|
1531
|
+
isTokenExpiring(token) {
|
|
1532
|
+
const expiresAt = this.getTokenExpiry(token);
|
|
1533
|
+
if (!expiresAt) {
|
|
1534
|
+
return false;
|
|
1535
|
+
}
|
|
1536
|
+
return expiresAt <= Date.now() + this.tokenRefreshSkewMs;
|
|
1537
|
+
}
|
|
1538
|
+
getTokenExpiry(token) {
|
|
1539
|
+
const payload = this.decodeJwtPayload(token);
|
|
1540
|
+
const exp = payload?.exp;
|
|
1541
|
+
if (typeof exp !== "number") {
|
|
1542
|
+
return null;
|
|
1543
|
+
}
|
|
1544
|
+
return exp * 1e3;
|
|
1545
|
+
}
|
|
1546
|
+
decodeJwtPayload(token) {
|
|
1547
|
+
const parts = token.split(".");
|
|
1548
|
+
if (parts.length < 2) {
|
|
1549
|
+
return null;
|
|
1550
|
+
}
|
|
1551
|
+
const decoded = this.decodeBase64Url(parts[1]);
|
|
1552
|
+
if (!decoded) {
|
|
1553
|
+
return null;
|
|
1554
|
+
}
|
|
1555
|
+
try {
|
|
1556
|
+
return JSON.parse(decoded);
|
|
1557
|
+
} catch {
|
|
1558
|
+
return null;
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
decodeBase64Url(value) {
|
|
1562
|
+
const base64 = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
1563
|
+
const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, "=");
|
|
1564
|
+
try {
|
|
1565
|
+
if (typeof atob === "function") {
|
|
1566
|
+
return atob(padded);
|
|
1567
|
+
}
|
|
1568
|
+
const buffer = globalThis.Buffer;
|
|
1569
|
+
if (typeof buffer !== "undefined") {
|
|
1570
|
+
return buffer.from(padded, "base64").toString("utf8");
|
|
1571
|
+
}
|
|
1572
|
+
} catch {
|
|
1573
|
+
return null;
|
|
1574
|
+
}
|
|
1575
|
+
return null;
|
|
1576
|
+
}
|
|
1577
|
+
applyAuthHeader(headers) {
|
|
1578
|
+
if (this.accessToken && !headers.has("authorization")) {
|
|
1579
|
+
headers.set("Authorization", `Bearer ${this.accessToken}`);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
721
1582
|
/**
|
|
722
1583
|
* Enhanced fetch with retry logic
|
|
723
1584
|
*/
|
|
724
|
-
async fetchAbsolute(url, initialInit) {
|
|
1585
|
+
async fetchAbsolute(url, initialInit, options) {
|
|
1586
|
+
const { skipAuth = false, retryOnAuth = true } = options ?? {};
|
|
725
1587
|
const init = await this.config.interceptor(initialInit);
|
|
726
1588
|
let lastError;
|
|
1589
|
+
const headers = new Headers();
|
|
1590
|
+
const applyHeaders = (src) => {
|
|
1591
|
+
if (!src) return;
|
|
1592
|
+
if (src instanceof Headers) {
|
|
1593
|
+
src.forEach((value, key) => headers.set(key, value));
|
|
1594
|
+
} else if (Array.isArray(src)) {
|
|
1595
|
+
src.forEach(([key, value]) => headers.set(key, value));
|
|
1596
|
+
} else if (typeof src === "object") {
|
|
1597
|
+
Object.entries(src).forEach(([key, value]) => {
|
|
1598
|
+
if (typeof value === "string") {
|
|
1599
|
+
headers.set(key, value);
|
|
1600
|
+
}
|
|
1601
|
+
});
|
|
1602
|
+
}
|
|
1603
|
+
};
|
|
1604
|
+
applyHeaders(this.config.headers);
|
|
1605
|
+
applyHeaders(init?.headers);
|
|
1606
|
+
const hasBody = init?.body !== void 0 && !(init.body instanceof FormData) && !(init.body instanceof Blob);
|
|
1607
|
+
if (!headers.has("content-type") && hasBody) {
|
|
1608
|
+
headers.set("Content-Type", "application/json");
|
|
1609
|
+
}
|
|
1610
|
+
if (!skipAuth) {
|
|
1611
|
+
await this.ensureAccessToken();
|
|
1612
|
+
this.applyAuthHeader(headers);
|
|
1613
|
+
}
|
|
727
1614
|
for (let attempt = 0; attempt <= this.config.retryAttempts; attempt++) {
|
|
728
1615
|
try {
|
|
729
1616
|
const controller = new AbortController();
|
|
@@ -731,12 +1618,15 @@ var DistriClient = class {
|
|
|
731
1618
|
const response = await fetch(url, {
|
|
732
1619
|
...init,
|
|
733
1620
|
signal: controller.signal,
|
|
734
|
-
headers
|
|
735
|
-
...this.config.headers,
|
|
736
|
-
...init?.headers
|
|
737
|
-
}
|
|
1621
|
+
headers
|
|
738
1622
|
});
|
|
739
1623
|
clearTimeout(timeoutId);
|
|
1624
|
+
if (!skipAuth && retryOnAuth && response.status === 401 && this.refreshToken) {
|
|
1625
|
+
const refreshed = await this.refreshTokens().then(() => true).catch(() => false);
|
|
1626
|
+
if (refreshed) {
|
|
1627
|
+
return this.fetchAbsolute(url, initialInit, { skipAuth, retryOnAuth: false });
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
740
1630
|
return response;
|
|
741
1631
|
} catch (error) {
|
|
742
1632
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
@@ -791,7 +1681,7 @@ var DistriClient = class {
|
|
|
791
1681
|
id: id || uuidv4(),
|
|
792
1682
|
role,
|
|
793
1683
|
parts,
|
|
794
|
-
created_at
|
|
1684
|
+
created_at: created_at || (/* @__PURE__ */ new Date()).getTime()
|
|
795
1685
|
};
|
|
796
1686
|
}
|
|
797
1687
|
/**
|
|
@@ -821,6 +1711,25 @@ var DistriClient = class {
|
|
|
821
1711
|
};
|
|
822
1712
|
}
|
|
823
1713
|
};
|
|
1714
|
+
// ============================================================
|
|
1715
|
+
// Additional User Message Parts API
|
|
1716
|
+
// ============================================================
|
|
1717
|
+
// These methods allow external tools to append parts (text, images)
|
|
1718
|
+
// to the user message in the next agent iteration.
|
|
1719
|
+
// The parts are stored under the key "__additional_user_parts".
|
|
1720
|
+
_DistriClient.ADDITIONAL_PARTS_KEY = "__additional_user_parts";
|
|
1721
|
+
// ============================================================
|
|
1722
|
+
// Token API
|
|
1723
|
+
// ============================================================
|
|
1724
|
+
// Issue access + refresh tokens for temporary authentication (e.g., frontend use)
|
|
1725
|
+
/**
|
|
1726
|
+
* Response from the token endpoint
|
|
1727
|
+
*/
|
|
1728
|
+
_DistriClient.TokenType = {
|
|
1729
|
+
Main: "main",
|
|
1730
|
+
Short: "short"
|
|
1731
|
+
};
|
|
1732
|
+
var DistriClient = _DistriClient;
|
|
824
1733
|
function uuidv4() {
|
|
825
1734
|
if (typeof crypto?.randomUUID === "function") {
|
|
826
1735
|
return crypto.randomUUID();
|
|
@@ -835,42 +1744,32 @@ function uuidv4() {
|
|
|
835
1744
|
}
|
|
836
1745
|
|
|
837
1746
|
// src/agent.ts
|
|
1747
|
+
var ExternalToolValidationError = class extends DistriError {
|
|
1748
|
+
constructor(agentName, result) {
|
|
1749
|
+
super(
|
|
1750
|
+
result.message || "Missing required external tools for agent invocation.",
|
|
1751
|
+
"EXTERNAL_TOOL_VALIDATION_ERROR",
|
|
1752
|
+
{
|
|
1753
|
+
agentName,
|
|
1754
|
+
missingTools: result.missingTools,
|
|
1755
|
+
requiredTools: result.requiredTools,
|
|
1756
|
+
providedTools: result.providedTools
|
|
1757
|
+
}
|
|
1758
|
+
);
|
|
1759
|
+
this.name = "ExternalToolValidationError";
|
|
1760
|
+
this.agentName = agentName;
|
|
1761
|
+
this.missingTools = result.missingTools;
|
|
1762
|
+
this.requiredTools = result.requiredTools;
|
|
1763
|
+
this.providedTools = result.providedTools;
|
|
1764
|
+
}
|
|
1765
|
+
};
|
|
838
1766
|
var Agent = class _Agent {
|
|
839
1767
|
constructor(agentDefinition, client) {
|
|
840
|
-
this.
|
|
1768
|
+
this.hookHandlers = /* @__PURE__ */ new Map();
|
|
1769
|
+
this.defaultHookHandler = null;
|
|
841
1770
|
this.agentDefinition = agentDefinition;
|
|
842
1771
|
this.client = client;
|
|
843
1772
|
}
|
|
844
|
-
/**
|
|
845
|
-
* Add a tool to the agent (AG-UI style)
|
|
846
|
-
*/
|
|
847
|
-
registerTool(tool) {
|
|
848
|
-
this.tools.set(tool.name, tool);
|
|
849
|
-
}
|
|
850
|
-
/**
|
|
851
|
-
* Add multiple tools at once
|
|
852
|
-
*/
|
|
853
|
-
registerTools(tools) {
|
|
854
|
-
tools.forEach((tool) => this.registerTool(tool));
|
|
855
|
-
}
|
|
856
|
-
/**
|
|
857
|
-
* Remove a tool
|
|
858
|
-
*/
|
|
859
|
-
unregisterTool(toolName) {
|
|
860
|
-
this.tools.delete(toolName);
|
|
861
|
-
}
|
|
862
|
-
/**
|
|
863
|
-
* Get all registered tools
|
|
864
|
-
*/
|
|
865
|
-
getTools() {
|
|
866
|
-
return Array.from(this.tools.values());
|
|
867
|
-
}
|
|
868
|
-
/**
|
|
869
|
-
* Check if a tool is registered
|
|
870
|
-
*/
|
|
871
|
-
hasTool(toolName) {
|
|
872
|
-
return this.tools.has(toolName);
|
|
873
|
-
}
|
|
874
1773
|
/**
|
|
875
1774
|
* Get agent information
|
|
876
1775
|
*/
|
|
@@ -883,9 +1782,18 @@ var Agent = class _Agent {
|
|
|
883
1782
|
get description() {
|
|
884
1783
|
return this.agentDefinition.description;
|
|
885
1784
|
}
|
|
1785
|
+
get agentType() {
|
|
1786
|
+
return this.agentDefinition.agent_type ?? this.agentDefinition.agentType;
|
|
1787
|
+
}
|
|
886
1788
|
get iconUrl() {
|
|
887
1789
|
return this.agentDefinition.icon_url;
|
|
888
1790
|
}
|
|
1791
|
+
/**
|
|
1792
|
+
* Get the full agent definition (including backend tools)
|
|
1793
|
+
*/
|
|
1794
|
+
getDefinition() {
|
|
1795
|
+
return this.agentDefinition;
|
|
1796
|
+
}
|
|
889
1797
|
/**
|
|
890
1798
|
* Fetch messages for a thread (public method for useChat)
|
|
891
1799
|
*/
|
|
@@ -895,56 +1803,153 @@ var Agent = class _Agent {
|
|
|
895
1803
|
/**
|
|
896
1804
|
* Direct (non-streaming) invoke
|
|
897
1805
|
*/
|
|
898
|
-
async invoke(params) {
|
|
899
|
-
|
|
900
|
-
|
|
1806
|
+
async invoke(params, tools, hooks) {
|
|
1807
|
+
if (hooks) {
|
|
1808
|
+
this.registerHooks(hooks);
|
|
1809
|
+
}
|
|
1810
|
+
const enhancedParams = this.enhanceParamsWithTools(params, tools);
|
|
901
1811
|
return await this.client.sendMessage(this.agentDefinition.id, enhancedParams);
|
|
902
1812
|
}
|
|
903
1813
|
/**
|
|
904
1814
|
* Streaming invoke
|
|
905
1815
|
*/
|
|
906
|
-
async invokeStream(params) {
|
|
907
|
-
|
|
908
|
-
|
|
1816
|
+
async invokeStream(params, tools, hooks) {
|
|
1817
|
+
if (hooks) {
|
|
1818
|
+
this.registerHooks(hooks);
|
|
1819
|
+
}
|
|
1820
|
+
const enhancedParams = this.enhanceParamsWithTools(params, tools);
|
|
909
1821
|
const a2aStream = this.client.sendMessageStream(this.agentDefinition.id, enhancedParams);
|
|
910
|
-
|
|
1822
|
+
const self = this;
|
|
1823
|
+
return (async function* () {
|
|
911
1824
|
for await (const event of a2aStream) {
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
1825
|
+
const converted = decodeA2AStreamEvent(event);
|
|
1826
|
+
if (converted && converted.type === "inline_hook_requested") {
|
|
1827
|
+
const hookReq = converted.data;
|
|
1828
|
+
const handler = self.hookHandlers.get(hookReq.hook) || self.defaultHookHandler;
|
|
1829
|
+
if (handler) {
|
|
1830
|
+
try {
|
|
1831
|
+
const mutation = await handler(hookReq);
|
|
1832
|
+
await self.client.completeInlineHook(hookReq.hook_id, mutation);
|
|
1833
|
+
} catch (err) {
|
|
1834
|
+
await self.client.completeInlineHook(hookReq.hook_id, { dynamic_values: {} });
|
|
1835
|
+
}
|
|
1836
|
+
} else {
|
|
1837
|
+
await self.client.completeInlineHook(hookReq.hook_id, { dynamic_values: {} });
|
|
1838
|
+
}
|
|
1839
|
+
yield converted;
|
|
1840
|
+
} else if (converted) {
|
|
1841
|
+
yield converted;
|
|
920
1842
|
}
|
|
921
1843
|
}
|
|
922
|
-
}();
|
|
1844
|
+
})();
|
|
1845
|
+
}
|
|
1846
|
+
/**
|
|
1847
|
+
* Validate that required external tools are registered before invoking.
|
|
1848
|
+
*/
|
|
1849
|
+
validateExternalTools(tools = []) {
|
|
1850
|
+
const requiredTools = this.getRequiredExternalTools();
|
|
1851
|
+
const providedTools = tools.map((tool) => tool.name);
|
|
1852
|
+
if (requiredTools.length === 0) {
|
|
1853
|
+
return {
|
|
1854
|
+
isValid: true,
|
|
1855
|
+
requiredTools: [],
|
|
1856
|
+
providedTools,
|
|
1857
|
+
missingTools: []
|
|
1858
|
+
};
|
|
1859
|
+
}
|
|
1860
|
+
const providedSet = new Set(providedTools);
|
|
1861
|
+
const missingTools = requiredTools.filter((tool) => !providedSet.has(tool));
|
|
1862
|
+
const isValid = missingTools.length === 0;
|
|
1863
|
+
return {
|
|
1864
|
+
isValid,
|
|
1865
|
+
requiredTools,
|
|
1866
|
+
providedTools,
|
|
1867
|
+
missingTools,
|
|
1868
|
+
message: isValid ? void 0 : this.formatExternalToolValidationMessage(requiredTools, missingTools)
|
|
1869
|
+
};
|
|
923
1870
|
}
|
|
924
1871
|
/**
|
|
925
1872
|
* Enhance message params with tool definitions
|
|
926
1873
|
*/
|
|
927
|
-
enhanceParamsWithTools(params) {
|
|
928
|
-
|
|
1874
|
+
enhanceParamsWithTools(params, tools) {
|
|
1875
|
+
this.assertExternalTools(tools);
|
|
1876
|
+
const metadata = {
|
|
1877
|
+
...params.metadata,
|
|
1878
|
+
external_tools: tools?.map((tool) => ({
|
|
1879
|
+
name: tool.name,
|
|
1880
|
+
description: tool.description,
|
|
1881
|
+
parameters: tool.parameters,
|
|
1882
|
+
is_final: tool.is_final
|
|
1883
|
+
})) || []
|
|
1884
|
+
};
|
|
929
1885
|
return {
|
|
930
1886
|
...params,
|
|
931
|
-
metadata
|
|
932
|
-
...params.metadata,
|
|
933
|
-
tools: tools.map((tool) => ({
|
|
934
|
-
name: tool.name,
|
|
935
|
-
description: tool.description,
|
|
936
|
-
input_schema: tool.input_schema
|
|
937
|
-
}))
|
|
938
|
-
}
|
|
1887
|
+
metadata
|
|
939
1888
|
};
|
|
940
1889
|
}
|
|
1890
|
+
assertExternalTools(tools) {
|
|
1891
|
+
const result = this.validateExternalTools(tools ?? []);
|
|
1892
|
+
if (!result.isValid) {
|
|
1893
|
+
throw new ExternalToolValidationError(this.agentDefinition.name || this.agentDefinition.id, result);
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
getRequiredExternalTools() {
|
|
1897
|
+
const toolConfig = this.resolveToolConfig();
|
|
1898
|
+
if (!toolConfig?.external || !Array.isArray(toolConfig.external)) {
|
|
1899
|
+
return [];
|
|
1900
|
+
}
|
|
1901
|
+
return toolConfig.external.filter((tool) => typeof tool === "string" && tool.trim().length > 0);
|
|
1902
|
+
}
|
|
1903
|
+
resolveToolConfig() {
|
|
1904
|
+
const root = this.agentDefinition;
|
|
1905
|
+
return this.extractToolConfig(root) || this.extractToolConfig(root?.agent) || this.extractToolConfig(root?.definition);
|
|
1906
|
+
}
|
|
1907
|
+
extractToolConfig(candidate) {
|
|
1908
|
+
if (!candidate) return null;
|
|
1909
|
+
const tools = candidate.tools;
|
|
1910
|
+
if (!tools || Array.isArray(tools) || typeof tools !== "object") {
|
|
1911
|
+
return null;
|
|
1912
|
+
}
|
|
1913
|
+
return tools;
|
|
1914
|
+
}
|
|
1915
|
+
formatExternalToolValidationMessage(requiredTools, missingTools) {
|
|
1916
|
+
const requiredList = requiredTools.join(", ");
|
|
1917
|
+
const missingList = missingTools.join(", ");
|
|
1918
|
+
return `Agent has external tools that are not registered: ${missingList}. This is an embedded agent that can run within the parent application. Register DistriWidget for embedding the parent component. Required tools: ${requiredList}.`;
|
|
1919
|
+
}
|
|
1920
|
+
/**
|
|
1921
|
+
* Register multiple hooks at once.
|
|
1922
|
+
*/
|
|
1923
|
+
registerHooks(hooks, defaultHandler) {
|
|
1924
|
+
Object.entries(hooks).forEach(([hook, handler]) => {
|
|
1925
|
+
this.hookHandlers.set(hook, handler);
|
|
1926
|
+
});
|
|
1927
|
+
if (defaultHandler) {
|
|
1928
|
+
this.defaultHookHandler = defaultHandler;
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
941
1931
|
/**
|
|
942
1932
|
* Create an agent instance from an agent ID
|
|
943
1933
|
*/
|
|
944
|
-
static async create(
|
|
945
|
-
const agentDefinition = await client.getAgent(
|
|
1934
|
+
static async create(agentIdOrDef, client) {
|
|
1935
|
+
const agentDefinition = typeof agentIdOrDef === "string" ? await client.getAgent(agentIdOrDef) : agentIdOrDef;
|
|
1936
|
+
console.log("\u{1F916} Agent definition loaded:", {
|
|
1937
|
+
id: agentDefinition.id,
|
|
1938
|
+
name: agentDefinition.name,
|
|
1939
|
+
tools: agentDefinition.tools?.map((t) => ({
|
|
1940
|
+
name: t.name,
|
|
1941
|
+
type: t.type || "function"
|
|
1942
|
+
})) || [],
|
|
1943
|
+
toolCount: agentDefinition.tools?.length || 0
|
|
1944
|
+
});
|
|
946
1945
|
return new _Agent(agentDefinition, client);
|
|
947
1946
|
}
|
|
1947
|
+
/**
|
|
1948
|
+
* Complete an external tool call by sending the result back to the server
|
|
1949
|
+
*/
|
|
1950
|
+
async completeTool(result) {
|
|
1951
|
+
await this.client.completeTool(this.agentDefinition.id, result);
|
|
1952
|
+
}
|
|
948
1953
|
/**
|
|
949
1954
|
* List all available agents
|
|
950
1955
|
*/
|
|
@@ -954,17 +1959,31 @@ var Agent = class _Agent {
|
|
|
954
1959
|
}
|
|
955
1960
|
};
|
|
956
1961
|
export {
|
|
1962
|
+
A2AProtocolError,
|
|
957
1963
|
Agent,
|
|
1964
|
+
ApiError,
|
|
1965
|
+
ConnectionError,
|
|
1966
|
+
DEFAULT_BASE_URL,
|
|
958
1967
|
DistriClient,
|
|
1968
|
+
DistriError,
|
|
1969
|
+
ExternalToolValidationError,
|
|
959
1970
|
convertA2AMessageToDistri,
|
|
960
1971
|
convertA2APartToDistri,
|
|
1972
|
+
convertA2AStatusUpdateToDistri,
|
|
961
1973
|
convertDistriMessageToA2A,
|
|
962
1974
|
convertDistriPartToA2A,
|
|
1975
|
+
createFailedToolResult,
|
|
1976
|
+
createSuccessfulToolResult,
|
|
1977
|
+
decodeA2AStreamEvent,
|
|
963
1978
|
extractTextFromDistriMessage,
|
|
964
1979
|
extractToolCallsFromDistriMessage,
|
|
1980
|
+
extractToolResultData,
|
|
965
1981
|
extractToolResultsFromDistriMessage,
|
|
1982
|
+
isArrayParts,
|
|
966
1983
|
isDistriEvent,
|
|
967
1984
|
isDistriMessage,
|
|
1985
|
+
processA2AMessagesData,
|
|
1986
|
+
processA2AStreamData,
|
|
968
1987
|
uuidv4
|
|
969
1988
|
};
|
|
970
1989
|
//# sourceMappingURL=index.mjs.map
|