@distri/core 0.3.2 → 0.3.4
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 +215 -14
- package/dist/index.d.ts +215 -14
- package/dist/index.js +353 -41
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +353 -41
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -55,8 +55,14 @@ module.exports = __toCommonJS(index_exports);
|
|
|
55
55
|
function isArrayParts(result) {
|
|
56
56
|
return Array.isArray(result) && result[0].part_type;
|
|
57
57
|
}
|
|
58
|
-
function createSuccessfulToolResult(toolCallId, toolName, result) {
|
|
59
|
-
|
|
58
|
+
function createSuccessfulToolResult(toolCallId, toolName, result, explicitPartsMetadata) {
|
|
59
|
+
console.log("[createSuccessfulToolResult] toolName:", toolName);
|
|
60
|
+
console.log("[createSuccessfulToolResult] isArrayParts:", isArrayParts(result));
|
|
61
|
+
console.log("[createSuccessfulToolResult] result type:", typeof result, Array.isArray(result) ? `array[${result.length}]` : "");
|
|
62
|
+
if (isArrayParts(result)) {
|
|
63
|
+
console.log("[createSuccessfulToolResult] parts:", result.map((p) => ({ part_type: p.part_type, hasMetadata: !!p.__metadata })));
|
|
64
|
+
}
|
|
65
|
+
const rawParts = isArrayParts(result) ? result : [{
|
|
60
66
|
part_type: "data",
|
|
61
67
|
data: {
|
|
62
68
|
result,
|
|
@@ -64,10 +70,22 @@ function createSuccessfulToolResult(toolCallId, toolName, result) {
|
|
|
64
70
|
error: void 0
|
|
65
71
|
}
|
|
66
72
|
}];
|
|
73
|
+
const parts_metadata = { ...explicitPartsMetadata };
|
|
74
|
+
const parts = rawParts.map((part, index) => {
|
|
75
|
+
if ("__metadata" in part && part.__metadata) {
|
|
76
|
+
parts_metadata[index] = { ...parts_metadata[index], ...part.__metadata };
|
|
77
|
+
}
|
|
78
|
+
if (part.part_type === "image" && !parts_metadata[index]) {
|
|
79
|
+
parts_metadata[index] = { save: false };
|
|
80
|
+
}
|
|
81
|
+
const { __metadata, ...cleanPart } = part;
|
|
82
|
+
return cleanPart;
|
|
83
|
+
});
|
|
67
84
|
return {
|
|
68
85
|
tool_call_id: toolCallId,
|
|
69
86
|
tool_name: toolName,
|
|
70
|
-
parts
|
|
87
|
+
parts,
|
|
88
|
+
parts_metadata: Object.keys(parts_metadata).length > 0 ? parts_metadata : void 0
|
|
71
89
|
};
|
|
72
90
|
}
|
|
73
91
|
function createFailedToolResult(toolCallId, toolName, error, result) {
|
|
@@ -543,11 +561,22 @@ var A2AClient = class {
|
|
|
543
561
|
// src/encoder.ts
|
|
544
562
|
function convertA2AMessageToDistri(a2aMessage) {
|
|
545
563
|
const role = a2aMessage.role === "agent" ? "assistant" : "user";
|
|
564
|
+
let agent_id;
|
|
565
|
+
let agent_name;
|
|
566
|
+
if (a2aMessage.metadata) {
|
|
567
|
+
const metadata = a2aMessage.metadata;
|
|
568
|
+
if (metadata.agent) {
|
|
569
|
+
agent_id = metadata.agent.agent_id;
|
|
570
|
+
agent_name = metadata.agent.agent_name;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
546
573
|
return {
|
|
547
574
|
id: a2aMessage.messageId,
|
|
548
575
|
role,
|
|
549
576
|
parts: a2aMessage.parts.map(convertA2APartToDistri),
|
|
550
|
-
created_at: a2aMessage.createdAt
|
|
577
|
+
created_at: a2aMessage.createdAt,
|
|
578
|
+
agent_id,
|
|
579
|
+
agent_name
|
|
551
580
|
};
|
|
552
581
|
}
|
|
553
582
|
function convertA2AStatusUpdateToDistri(statusUpdate) {
|
|
@@ -570,8 +599,8 @@ function convertA2AStatusUpdateToDistri(statusUpdate) {
|
|
|
570
599
|
const runErrorResult = {
|
|
571
600
|
type: "run_error",
|
|
572
601
|
data: {
|
|
573
|
-
message: statusUpdate.error,
|
|
574
|
-
code:
|
|
602
|
+
message: metadata.message || statusUpdate.status?.message || "Unknown error",
|
|
603
|
+
code: metadata.code
|
|
575
604
|
}
|
|
576
605
|
};
|
|
577
606
|
return runErrorResult;
|
|
@@ -741,6 +770,19 @@ function convertA2AStatusUpdateToDistri(statusUpdate) {
|
|
|
741
770
|
};
|
|
742
771
|
return browserSessionStarted;
|
|
743
772
|
}
|
|
773
|
+
case "todos_updated": {
|
|
774
|
+
const todos = parseTodosFromFormatted(metadata.formatted_todos || "");
|
|
775
|
+
const todosUpdated = {
|
|
776
|
+
type: "todos_updated",
|
|
777
|
+
data: {
|
|
778
|
+
formatted_todos: metadata.formatted_todos || "",
|
|
779
|
+
action: metadata.action || "write_todos",
|
|
780
|
+
todo_count: metadata.todo_count || 0,
|
|
781
|
+
todos
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
return todosUpdated;
|
|
785
|
+
}
|
|
744
786
|
default: {
|
|
745
787
|
console.warn(`Unhandled status update metadata type: ${metadata.type}`, metadata);
|
|
746
788
|
const defaultResult = {
|
|
@@ -792,7 +834,7 @@ function convertA2APartToDistri(a2aPart) {
|
|
|
792
834
|
const fileUrl = { type: "url", mime_type: a2aPart.file.mimeType || "application/octet-stream", url: a2aPart.file.uri || "" };
|
|
793
835
|
return { part_type: "image", data: fileUrl };
|
|
794
836
|
} else {
|
|
795
|
-
const fileBytes = { type: "bytes", mime_type: a2aPart.file.mimeType || "application/octet-stream",
|
|
837
|
+
const fileBytes = { type: "bytes", mime_type: a2aPart.file.mimeType || "application/octet-stream", bytes: a2aPart.file.bytes || "" };
|
|
796
838
|
return { part_type: "image", data: fileBytes };
|
|
797
839
|
}
|
|
798
840
|
case "data":
|
|
@@ -819,6 +861,7 @@ function convertDistriMessageToA2A(distriMessage, context) {
|
|
|
819
861
|
break;
|
|
820
862
|
case "system":
|
|
821
863
|
case "tool":
|
|
864
|
+
case "developer":
|
|
822
865
|
role = "user";
|
|
823
866
|
break;
|
|
824
867
|
default:
|
|
@@ -830,7 +873,8 @@ function convertDistriMessageToA2A(distriMessage, context) {
|
|
|
830
873
|
parts: distriMessage.parts.map(convertDistriPartToA2A),
|
|
831
874
|
kind: "message",
|
|
832
875
|
contextId: context.thread_id,
|
|
833
|
-
taskId: context.task_id || context.run_id || void 0
|
|
876
|
+
taskId: context.task_id || context.run_id || void 0,
|
|
877
|
+
metadata: distriMessage.metadata
|
|
834
878
|
};
|
|
835
879
|
}
|
|
836
880
|
function convertDistriPartToA2A(distriPart) {
|
|
@@ -844,7 +888,7 @@ function convertDistriPartToA2A(distriPart) {
|
|
|
844
888
|
const fileUri = { mimeType: distriPart.data.mime_type, uri: distriPart.data.url };
|
|
845
889
|
result = { kind: "file", file: fileUri };
|
|
846
890
|
} else {
|
|
847
|
-
const fileBytes = { mimeType: distriPart.data.mime_type, bytes: distriPart.data.
|
|
891
|
+
const fileBytes = { mimeType: distriPart.data.mime_type, bytes: distriPart.data.bytes };
|
|
848
892
|
result = { kind: "file", file: fileBytes };
|
|
849
893
|
}
|
|
850
894
|
break;
|
|
@@ -909,12 +953,41 @@ function extractToolCallsFromDistriMessage(message) {
|
|
|
909
953
|
function extractToolResultsFromDistriMessage(message) {
|
|
910
954
|
return message.parts.filter((part) => part.part_type === "tool_result").map((part) => part.data);
|
|
911
955
|
}
|
|
956
|
+
function parseTodosFromFormatted(formatted) {
|
|
957
|
+
if (!formatted || formatted === "\u25A1 No todos") {
|
|
958
|
+
return [];
|
|
959
|
+
}
|
|
960
|
+
const lines = formatted.split("\n").filter((line) => line.trim());
|
|
961
|
+
return lines.map((line, index) => {
|
|
962
|
+
const trimmed = line.trim();
|
|
963
|
+
let status = "open";
|
|
964
|
+
let content = trimmed;
|
|
965
|
+
if (trimmed.startsWith("\u25A0")) {
|
|
966
|
+
status = "done";
|
|
967
|
+
content = trimmed.slice(1).trim();
|
|
968
|
+
} else if (trimmed.startsWith("\u25D0")) {
|
|
969
|
+
status = "in_progress";
|
|
970
|
+
content = trimmed.slice(1).trim();
|
|
971
|
+
} else if (trimmed.startsWith("\u25A1")) {
|
|
972
|
+
status = "open";
|
|
973
|
+
content = trimmed.slice(1).trim();
|
|
974
|
+
}
|
|
975
|
+
return {
|
|
976
|
+
id: `todo_${index}`,
|
|
977
|
+
content,
|
|
978
|
+
status
|
|
979
|
+
};
|
|
980
|
+
});
|
|
981
|
+
}
|
|
912
982
|
|
|
913
983
|
// src/distri-client.ts
|
|
914
984
|
var _DistriClient = class _DistriClient {
|
|
915
985
|
constructor(config) {
|
|
916
986
|
this.agentClients = /* @__PURE__ */ new Map();
|
|
917
987
|
const headers = { ...config.headers };
|
|
988
|
+
if (config.workspaceId) {
|
|
989
|
+
headers["X-Workspace-Id"] = config.workspaceId;
|
|
990
|
+
}
|
|
918
991
|
this.accessToken = config.accessToken;
|
|
919
992
|
this.refreshToken = config.refreshToken;
|
|
920
993
|
this.tokenRefreshSkewMs = config.tokenRefreshSkewMs ?? 6e4;
|
|
@@ -929,7 +1002,8 @@ var _DistriClient = class _DistriClient {
|
|
|
929
1002
|
headers,
|
|
930
1003
|
interceptor: config.interceptor ?? (async (init) => Promise.resolve(init)),
|
|
931
1004
|
onTokenRefresh: config.onTokenRefresh,
|
|
932
|
-
clientId: config.clientId
|
|
1005
|
+
clientId: config.clientId,
|
|
1006
|
+
workspaceId: config.workspaceId
|
|
933
1007
|
};
|
|
934
1008
|
}
|
|
935
1009
|
/**
|
|
@@ -944,6 +1018,24 @@ var _DistriClient = class _DistriClient {
|
|
|
944
1018
|
set clientId(value) {
|
|
945
1019
|
this.config.clientId = value;
|
|
946
1020
|
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Get the configured workspace ID.
|
|
1023
|
+
*/
|
|
1024
|
+
get workspaceId() {
|
|
1025
|
+
return this.config.workspaceId;
|
|
1026
|
+
}
|
|
1027
|
+
/**
|
|
1028
|
+
* Set the workspace ID for multi-tenant support.
|
|
1029
|
+
* Updates the X-Workspace-Id header for all subsequent requests.
|
|
1030
|
+
*/
|
|
1031
|
+
set workspaceId(value) {
|
|
1032
|
+
this.config.workspaceId = value;
|
|
1033
|
+
if (value) {
|
|
1034
|
+
this.config.headers["X-Workspace-Id"] = value;
|
|
1035
|
+
} else {
|
|
1036
|
+
delete this.config.headers["X-Workspace-Id"];
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
947
1039
|
/**
|
|
948
1040
|
* Create a client with default cloud configuration.
|
|
949
1041
|
*
|
|
@@ -1396,8 +1488,51 @@ var _DistriClient = class _DistriClient {
|
|
|
1396
1488
|
yield* await client.sendMessageStream(params);
|
|
1397
1489
|
} catch (error) {
|
|
1398
1490
|
console.error(error);
|
|
1399
|
-
|
|
1491
|
+
const errorMessage = this.extractErrorMessage(error);
|
|
1492
|
+
throw new DistriError(errorMessage, "STREAM_MESSAGE_ERROR", error);
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
/**
|
|
1496
|
+
* Extract a user-friendly error message from potentially nested errors
|
|
1497
|
+
*/
|
|
1498
|
+
extractErrorMessage(error) {
|
|
1499
|
+
if (!error) return "Unknown error occurred";
|
|
1500
|
+
if (typeof error === "object" && error !== null) {
|
|
1501
|
+
const err = error;
|
|
1502
|
+
if (err.error && typeof err.error === "object") {
|
|
1503
|
+
const jsonRpcError = err.error;
|
|
1504
|
+
if (typeof jsonRpcError.message === "string") {
|
|
1505
|
+
return jsonRpcError.message;
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
if (err.message && typeof err.message === "string") {
|
|
1509
|
+
return err.message;
|
|
1510
|
+
}
|
|
1511
|
+
if (err.details && typeof err.details === "object") {
|
|
1512
|
+
const details = err.details;
|
|
1513
|
+
if (details.message && typeof details.message === "string") {
|
|
1514
|
+
return details.message;
|
|
1515
|
+
}
|
|
1516
|
+
if (details.error && typeof details.error === "object") {
|
|
1517
|
+
const nestedError = details.error;
|
|
1518
|
+
if (typeof nestedError.message === "string") {
|
|
1519
|
+
return nestedError.message;
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
if (err.cause && typeof err.cause === "object") {
|
|
1524
|
+
return this.extractErrorMessage(err.cause);
|
|
1525
|
+
}
|
|
1400
1526
|
}
|
|
1527
|
+
if (error instanceof Error) {
|
|
1528
|
+
const msg = error.message;
|
|
1529
|
+
const sseMatch = msg.match(/SSE event contained an error:\s*(.+?)\s*\(Code:/);
|
|
1530
|
+
if (sseMatch) return sseMatch[1];
|
|
1531
|
+
const rpcMatch = msg.match(/RPC Error:\s*(.+?)\s*\(Code:/);
|
|
1532
|
+
if (rpcMatch) return rpcMatch[1];
|
|
1533
|
+
return msg;
|
|
1534
|
+
}
|
|
1535
|
+
return String(error);
|
|
1401
1536
|
}
|
|
1402
1537
|
/**
|
|
1403
1538
|
* Get task details
|
|
@@ -1459,11 +1594,19 @@ var _DistriClient = class _DistriClient {
|
|
|
1459
1594
|
}
|
|
1460
1595
|
}
|
|
1461
1596
|
/**
|
|
1462
|
-
* Get agents sorted by thread count (most active first)
|
|
1597
|
+
* Get agents sorted by thread count (most active first).
|
|
1598
|
+
* Includes all registered agents, even those with 0 threads.
|
|
1599
|
+
* Optionally filter by name with search parameter.
|
|
1463
1600
|
*/
|
|
1464
|
-
async getAgentsByUsage() {
|
|
1601
|
+
async getAgentsByUsage(options) {
|
|
1465
1602
|
try {
|
|
1466
|
-
const
|
|
1603
|
+
const params = new URLSearchParams();
|
|
1604
|
+
if (options?.search) {
|
|
1605
|
+
params.set("search", options.search);
|
|
1606
|
+
}
|
|
1607
|
+
const query = params.toString();
|
|
1608
|
+
const url = query ? `/threads/agents?${query}` : "/threads/agents";
|
|
1609
|
+
const response = await this.fetch(url);
|
|
1467
1610
|
if (!response.ok) {
|
|
1468
1611
|
throw new ApiError(`Failed to fetch agents by usage: ${response.statusText}`, response.status);
|
|
1469
1612
|
}
|
|
@@ -1528,6 +1671,138 @@ var _DistriClient = class _DistriClient {
|
|
|
1528
1671
|
const messages = await this.getThreadMessages(threadId);
|
|
1529
1672
|
return messages.map(convertA2AMessageToDistri);
|
|
1530
1673
|
}
|
|
1674
|
+
// ========== Message Read Status Methods ==========
|
|
1675
|
+
/**
|
|
1676
|
+
* Mark a message as read
|
|
1677
|
+
*/
|
|
1678
|
+
async markMessageRead(threadId, messageId) {
|
|
1679
|
+
try {
|
|
1680
|
+
const response = await this.fetch(
|
|
1681
|
+
`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/read`,
|
|
1682
|
+
{ method: "POST" }
|
|
1683
|
+
);
|
|
1684
|
+
if (!response.ok) {
|
|
1685
|
+
throw new ApiError(`Failed to mark message as read: ${response.statusText}`, response.status);
|
|
1686
|
+
}
|
|
1687
|
+
return await response.json();
|
|
1688
|
+
} catch (error) {
|
|
1689
|
+
if (error instanceof ApiError) throw error;
|
|
1690
|
+
throw new DistriError(`Failed to mark message ${messageId} as read`, "MARK_READ_ERROR", error);
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
/**
|
|
1694
|
+
* Get read status for a specific message
|
|
1695
|
+
*/
|
|
1696
|
+
async getMessageReadStatus(threadId, messageId) {
|
|
1697
|
+
try {
|
|
1698
|
+
const response = await this.fetch(
|
|
1699
|
+
`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/read`
|
|
1700
|
+
);
|
|
1701
|
+
if (response.status === 404) {
|
|
1702
|
+
return null;
|
|
1703
|
+
}
|
|
1704
|
+
if (!response.ok) {
|
|
1705
|
+
throw new ApiError(`Failed to get message read status: ${response.statusText}`, response.status);
|
|
1706
|
+
}
|
|
1707
|
+
return await response.json();
|
|
1708
|
+
} catch (error) {
|
|
1709
|
+
if (error instanceof ApiError) throw error;
|
|
1710
|
+
throw new DistriError(`Failed to get read status for message ${messageId}`, "FETCH_ERROR", error);
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
/**
|
|
1714
|
+
* Get read status for all messages in a thread
|
|
1715
|
+
*/
|
|
1716
|
+
async getThreadReadStatus(threadId) {
|
|
1717
|
+
try {
|
|
1718
|
+
const response = await this.fetch(
|
|
1719
|
+
`/threads/${encodeURIComponent(threadId)}/read-status`
|
|
1720
|
+
);
|
|
1721
|
+
if (!response.ok) {
|
|
1722
|
+
throw new ApiError(`Failed to get thread read status: ${response.statusText}`, response.status);
|
|
1723
|
+
}
|
|
1724
|
+
return await response.json();
|
|
1725
|
+
} catch (error) {
|
|
1726
|
+
if (error instanceof ApiError) throw error;
|
|
1727
|
+
throw new DistriError(`Failed to get read status for thread ${threadId}`, "FETCH_ERROR", error);
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
// ========== Message Voting Methods ==========
|
|
1731
|
+
/**
|
|
1732
|
+
* Vote on a message (upvote or downvote)
|
|
1733
|
+
* Downvotes require a comment explaining the issue
|
|
1734
|
+
*/
|
|
1735
|
+
async voteMessage(threadId, messageId, request) {
|
|
1736
|
+
try {
|
|
1737
|
+
const response = await this.fetch(
|
|
1738
|
+
`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/vote`,
|
|
1739
|
+
{
|
|
1740
|
+
method: "POST",
|
|
1741
|
+
headers: { "Content-Type": "application/json" },
|
|
1742
|
+
body: JSON.stringify(request)
|
|
1743
|
+
}
|
|
1744
|
+
);
|
|
1745
|
+
if (!response.ok) {
|
|
1746
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1747
|
+
throw new ApiError(errorData.error || `Failed to vote on message: ${response.statusText}`, response.status);
|
|
1748
|
+
}
|
|
1749
|
+
return await response.json();
|
|
1750
|
+
} catch (error) {
|
|
1751
|
+
if (error instanceof ApiError) throw error;
|
|
1752
|
+
throw new DistriError(`Failed to vote on message ${messageId}`, "VOTE_ERROR", error);
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
/**
|
|
1756
|
+
* Remove vote from a message
|
|
1757
|
+
*/
|
|
1758
|
+
async removeVote(threadId, messageId) {
|
|
1759
|
+
try {
|
|
1760
|
+
const response = await this.fetch(
|
|
1761
|
+
`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/vote`,
|
|
1762
|
+
{ method: "DELETE" }
|
|
1763
|
+
);
|
|
1764
|
+
if (!response.ok && response.status !== 204) {
|
|
1765
|
+
throw new ApiError(`Failed to remove vote: ${response.statusText}`, response.status);
|
|
1766
|
+
}
|
|
1767
|
+
} catch (error) {
|
|
1768
|
+
if (error instanceof ApiError) throw error;
|
|
1769
|
+
throw new DistriError(`Failed to remove vote from message ${messageId}`, "VOTE_ERROR", error);
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
/**
|
|
1773
|
+
* Get vote summary for a message (counts + current user's vote)
|
|
1774
|
+
*/
|
|
1775
|
+
async getMessageVoteSummary(threadId, messageId) {
|
|
1776
|
+
try {
|
|
1777
|
+
const response = await this.fetch(
|
|
1778
|
+
`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/vote`
|
|
1779
|
+
);
|
|
1780
|
+
if (!response.ok) {
|
|
1781
|
+
throw new ApiError(`Failed to get vote summary: ${response.statusText}`, response.status);
|
|
1782
|
+
}
|
|
1783
|
+
return await response.json();
|
|
1784
|
+
} catch (error) {
|
|
1785
|
+
if (error instanceof ApiError) throw error;
|
|
1786
|
+
throw new DistriError(`Failed to get vote summary for message ${messageId}`, "FETCH_ERROR", error);
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
/**
|
|
1790
|
+
* Get all votes for a message (admin/analytics use)
|
|
1791
|
+
*/
|
|
1792
|
+
async getMessageVotes(threadId, messageId) {
|
|
1793
|
+
try {
|
|
1794
|
+
const response = await this.fetch(
|
|
1795
|
+
`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/votes`
|
|
1796
|
+
);
|
|
1797
|
+
if (!response.ok) {
|
|
1798
|
+
throw new ApiError(`Failed to get message votes: ${response.statusText}`, response.status);
|
|
1799
|
+
}
|
|
1800
|
+
return await response.json();
|
|
1801
|
+
} catch (error) {
|
|
1802
|
+
if (error instanceof ApiError) throw error;
|
|
1803
|
+
throw new DistriError(`Failed to get votes for message ${messageId}`, "FETCH_ERROR", error);
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1531
1806
|
/**
|
|
1532
1807
|
* Send a DistriMessage to a thread
|
|
1533
1808
|
*/
|
|
@@ -1553,7 +1828,12 @@ var _DistriClient = class _DistriClient {
|
|
|
1553
1828
|
},
|
|
1554
1829
|
body: JSON.stringify({
|
|
1555
1830
|
tool_call_id: result.tool_call_id,
|
|
1556
|
-
tool_response:
|
|
1831
|
+
tool_response: {
|
|
1832
|
+
tool_call_id: result.tool_call_id,
|
|
1833
|
+
tool_name: result.tool_name,
|
|
1834
|
+
parts: result.parts,
|
|
1835
|
+
parts_metadata: result.parts_metadata
|
|
1836
|
+
}
|
|
1557
1837
|
})
|
|
1558
1838
|
});
|
|
1559
1839
|
if (!response.ok) {
|
|
@@ -1817,9 +2097,17 @@ var _DistriClient = class _DistriClient {
|
|
|
1817
2097
|
};
|
|
1818
2098
|
}
|
|
1819
2099
|
/**
|
|
1820
|
-
* Helper method to create message send parameters
|
|
1821
|
-
|
|
1822
|
-
|
|
2100
|
+
* Helper method to create message send parameters.
|
|
2101
|
+
*
|
|
2102
|
+
* Pass `dynamicMetadata` to inject `dynamic_sections` and/or `dynamic_values`
|
|
2103
|
+
* into the metadata so the server can apply them to prompt templates.
|
|
2104
|
+
*/
|
|
2105
|
+
static initMessageParams(message, configuration, metadata, dynamicMetadata) {
|
|
2106
|
+
const mergedMetadata = {
|
|
2107
|
+
...metadata,
|
|
2108
|
+
...dynamicMetadata?.dynamic_sections ? { dynamic_sections: dynamicMetadata.dynamic_sections } : {},
|
|
2109
|
+
...dynamicMetadata?.dynamic_values ? { dynamic_values: dynamicMetadata.dynamic_values } : {}
|
|
2110
|
+
};
|
|
1823
2111
|
return {
|
|
1824
2112
|
message,
|
|
1825
2113
|
configuration: {
|
|
@@ -1828,18 +2116,26 @@ var _DistriClient = class _DistriClient {
|
|
|
1828
2116
|
// Default to non-blocking for streaming
|
|
1829
2117
|
...configuration
|
|
1830
2118
|
},
|
|
1831
|
-
metadata
|
|
2119
|
+
metadata: Object.keys(mergedMetadata).length > 0 ? mergedMetadata : metadata
|
|
1832
2120
|
};
|
|
1833
2121
|
}
|
|
1834
2122
|
/**
|
|
1835
|
-
* Create MessageSendParams from a DistriMessage using InvokeContext
|
|
2123
|
+
* Create MessageSendParams from a DistriMessage using InvokeContext.
|
|
2124
|
+
*
|
|
2125
|
+
* Pass `dynamicMetadata` to inject `dynamic_sections` and/or `dynamic_values`
|
|
2126
|
+
* into the metadata so the server can apply them to prompt templates.
|
|
1836
2127
|
*/
|
|
1837
|
-
static initDistriMessageParams(message, context) {
|
|
2128
|
+
static initDistriMessageParams(message, context, dynamicMetadata) {
|
|
1838
2129
|
const a2aMessage = convertDistriMessageToA2A(message, context);
|
|
1839
2130
|
const contextMetadata = context.getMetadata?.() || {};
|
|
2131
|
+
const mergedMetadata = {
|
|
2132
|
+
...contextMetadata,
|
|
2133
|
+
...dynamicMetadata?.dynamic_sections ? { dynamic_sections: dynamicMetadata.dynamic_sections } : {},
|
|
2134
|
+
...dynamicMetadata?.dynamic_values ? { dynamic_values: dynamicMetadata.dynamic_values } : {}
|
|
2135
|
+
};
|
|
1840
2136
|
return {
|
|
1841
2137
|
message: a2aMessage,
|
|
1842
|
-
metadata: contextMetadata
|
|
2138
|
+
metadata: Object.keys(mergedMetadata).length > 0 ? mergedMetadata : contextMetadata
|
|
1843
2139
|
};
|
|
1844
2140
|
}
|
|
1845
2141
|
};
|
|
@@ -1945,28 +2241,40 @@ var Agent = class _Agent {
|
|
|
1945
2241
|
const enhancedParams = this.enhanceParamsWithTools(params, tools);
|
|
1946
2242
|
const a2aStream = this.client.sendMessageStream(this.agentDefinition.id, enhancedParams);
|
|
1947
2243
|
const self = this;
|
|
1948
|
-
return async function* () {
|
|
1949
|
-
|
|
1950
|
-
const
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
2244
|
+
return (async function* () {
|
|
2245
|
+
try {
|
|
2246
|
+
for await (const event of a2aStream) {
|
|
2247
|
+
const converted = decodeA2AStreamEvent(event);
|
|
2248
|
+
if (converted && converted.type === "inline_hook_requested") {
|
|
2249
|
+
const hookReq = converted.data;
|
|
2250
|
+
const handler = self.hookHandlers.get(hookReq.hook) || self.defaultHookHandler;
|
|
2251
|
+
if (handler) {
|
|
2252
|
+
try {
|
|
2253
|
+
const mutation = await handler(hookReq);
|
|
2254
|
+
await self.client.completeInlineHook(hookReq.hook_id, mutation);
|
|
2255
|
+
} catch (err) {
|
|
2256
|
+
await self.client.completeInlineHook(hookReq.hook_id, { dynamic_values: {} });
|
|
2257
|
+
}
|
|
2258
|
+
} else {
|
|
1959
2259
|
await self.client.completeInlineHook(hookReq.hook_id, { dynamic_values: {} });
|
|
1960
2260
|
}
|
|
1961
|
-
|
|
1962
|
-
|
|
2261
|
+
yield converted;
|
|
2262
|
+
} else if (converted) {
|
|
2263
|
+
yield converted;
|
|
1963
2264
|
}
|
|
1964
|
-
yield converted;
|
|
1965
|
-
} else if (converted) {
|
|
1966
|
-
yield converted;
|
|
1967
2265
|
}
|
|
2266
|
+
} catch (error) {
|
|
2267
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2268
|
+
const runError = {
|
|
2269
|
+
type: "run_error",
|
|
2270
|
+
data: {
|
|
2271
|
+
message,
|
|
2272
|
+
code: "STREAM_ERROR"
|
|
2273
|
+
}
|
|
2274
|
+
};
|
|
2275
|
+
yield runError;
|
|
1968
2276
|
}
|
|
1969
|
-
}();
|
|
2277
|
+
})();
|
|
1970
2278
|
}
|
|
1971
2279
|
/**
|
|
1972
2280
|
* Validate that required external tools are registered before invoking.
|
|
@@ -1994,12 +2302,16 @@ var Agent = class _Agent {
|
|
|
1994
2302
|
};
|
|
1995
2303
|
}
|
|
1996
2304
|
/**
|
|
1997
|
-
* Enhance message params with tool definitions
|
|
2305
|
+
* Enhance message params with tool definitions and dynamic metadata.
|
|
2306
|
+
*
|
|
2307
|
+
* When `dynamic_sections` or `dynamic_values` are present in `params.metadata`,
|
|
2308
|
+
* they are forwarded so the server injects them into the prompt template.
|
|
1998
2309
|
*/
|
|
1999
2310
|
enhanceParamsWithTools(params, tools) {
|
|
2000
2311
|
this.assertExternalTools(tools);
|
|
2312
|
+
const existingMeta = params.metadata ?? {};
|
|
2001
2313
|
const metadata = {
|
|
2002
|
-
...
|
|
2314
|
+
...existingMeta,
|
|
2003
2315
|
external_tools: tools?.map((tool) => ({
|
|
2004
2316
|
name: tool.name,
|
|
2005
2317
|
description: tool.description,
|