@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.mjs
CHANGED
|
@@ -6,8 +6,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
6
6
|
function isArrayParts(result) {
|
|
7
7
|
return Array.isArray(result) && result[0].part_type;
|
|
8
8
|
}
|
|
9
|
-
function createSuccessfulToolResult(toolCallId, toolName, result) {
|
|
10
|
-
|
|
9
|
+
function createSuccessfulToolResult(toolCallId, toolName, result, explicitPartsMetadata) {
|
|
10
|
+
console.log("[createSuccessfulToolResult] toolName:", toolName);
|
|
11
|
+
console.log("[createSuccessfulToolResult] isArrayParts:", isArrayParts(result));
|
|
12
|
+
console.log("[createSuccessfulToolResult] result type:", typeof result, Array.isArray(result) ? `array[${result.length}]` : "");
|
|
13
|
+
if (isArrayParts(result)) {
|
|
14
|
+
console.log("[createSuccessfulToolResult] parts:", result.map((p) => ({ part_type: p.part_type, hasMetadata: !!p.__metadata })));
|
|
15
|
+
}
|
|
16
|
+
const rawParts = isArrayParts(result) ? result : [{
|
|
11
17
|
part_type: "data",
|
|
12
18
|
data: {
|
|
13
19
|
result,
|
|
@@ -15,10 +21,22 @@ function createSuccessfulToolResult(toolCallId, toolName, result) {
|
|
|
15
21
|
error: void 0
|
|
16
22
|
}
|
|
17
23
|
}];
|
|
24
|
+
const parts_metadata = { ...explicitPartsMetadata };
|
|
25
|
+
const parts = rawParts.map((part, index) => {
|
|
26
|
+
if ("__metadata" in part && part.__metadata) {
|
|
27
|
+
parts_metadata[index] = { ...parts_metadata[index], ...part.__metadata };
|
|
28
|
+
}
|
|
29
|
+
if (part.part_type === "image" && !parts_metadata[index]) {
|
|
30
|
+
parts_metadata[index] = { save: false };
|
|
31
|
+
}
|
|
32
|
+
const { __metadata, ...cleanPart } = part;
|
|
33
|
+
return cleanPart;
|
|
34
|
+
});
|
|
18
35
|
return {
|
|
19
36
|
tool_call_id: toolCallId,
|
|
20
37
|
tool_name: toolName,
|
|
21
|
-
parts
|
|
38
|
+
parts,
|
|
39
|
+
parts_metadata: Object.keys(parts_metadata).length > 0 ? parts_metadata : void 0
|
|
22
40
|
};
|
|
23
41
|
}
|
|
24
42
|
function createFailedToolResult(toolCallId, toolName, error, result) {
|
|
@@ -494,11 +512,22 @@ var A2AClient = class {
|
|
|
494
512
|
// src/encoder.ts
|
|
495
513
|
function convertA2AMessageToDistri(a2aMessage) {
|
|
496
514
|
const role = a2aMessage.role === "agent" ? "assistant" : "user";
|
|
515
|
+
let agent_id;
|
|
516
|
+
let agent_name;
|
|
517
|
+
if (a2aMessage.metadata) {
|
|
518
|
+
const metadata = a2aMessage.metadata;
|
|
519
|
+
if (metadata.agent) {
|
|
520
|
+
agent_id = metadata.agent.agent_id;
|
|
521
|
+
agent_name = metadata.agent.agent_name;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
497
524
|
return {
|
|
498
525
|
id: a2aMessage.messageId,
|
|
499
526
|
role,
|
|
500
527
|
parts: a2aMessage.parts.map(convertA2APartToDistri),
|
|
501
|
-
created_at: a2aMessage.createdAt
|
|
528
|
+
created_at: a2aMessage.createdAt,
|
|
529
|
+
agent_id,
|
|
530
|
+
agent_name
|
|
502
531
|
};
|
|
503
532
|
}
|
|
504
533
|
function convertA2AStatusUpdateToDistri(statusUpdate) {
|
|
@@ -521,8 +550,8 @@ function convertA2AStatusUpdateToDistri(statusUpdate) {
|
|
|
521
550
|
const runErrorResult = {
|
|
522
551
|
type: "run_error",
|
|
523
552
|
data: {
|
|
524
|
-
message: statusUpdate.error,
|
|
525
|
-
code:
|
|
553
|
+
message: metadata.message || statusUpdate.status?.message || "Unknown error",
|
|
554
|
+
code: metadata.code
|
|
526
555
|
}
|
|
527
556
|
};
|
|
528
557
|
return runErrorResult;
|
|
@@ -692,6 +721,19 @@ function convertA2AStatusUpdateToDistri(statusUpdate) {
|
|
|
692
721
|
};
|
|
693
722
|
return browserSessionStarted;
|
|
694
723
|
}
|
|
724
|
+
case "todos_updated": {
|
|
725
|
+
const todos = parseTodosFromFormatted(metadata.formatted_todos || "");
|
|
726
|
+
const todosUpdated = {
|
|
727
|
+
type: "todos_updated",
|
|
728
|
+
data: {
|
|
729
|
+
formatted_todos: metadata.formatted_todos || "",
|
|
730
|
+
action: metadata.action || "write_todos",
|
|
731
|
+
todo_count: metadata.todo_count || 0,
|
|
732
|
+
todos
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
return todosUpdated;
|
|
736
|
+
}
|
|
695
737
|
default: {
|
|
696
738
|
console.warn(`Unhandled status update metadata type: ${metadata.type}`, metadata);
|
|
697
739
|
const defaultResult = {
|
|
@@ -743,7 +785,7 @@ function convertA2APartToDistri(a2aPart) {
|
|
|
743
785
|
const fileUrl = { type: "url", mime_type: a2aPart.file.mimeType || "application/octet-stream", url: a2aPart.file.uri || "" };
|
|
744
786
|
return { part_type: "image", data: fileUrl };
|
|
745
787
|
} else {
|
|
746
|
-
const fileBytes = { type: "bytes", mime_type: a2aPart.file.mimeType || "application/octet-stream",
|
|
788
|
+
const fileBytes = { type: "bytes", mime_type: a2aPart.file.mimeType || "application/octet-stream", bytes: a2aPart.file.bytes || "" };
|
|
747
789
|
return { part_type: "image", data: fileBytes };
|
|
748
790
|
}
|
|
749
791
|
case "data":
|
|
@@ -770,6 +812,7 @@ function convertDistriMessageToA2A(distriMessage, context) {
|
|
|
770
812
|
break;
|
|
771
813
|
case "system":
|
|
772
814
|
case "tool":
|
|
815
|
+
case "developer":
|
|
773
816
|
role = "user";
|
|
774
817
|
break;
|
|
775
818
|
default:
|
|
@@ -781,7 +824,8 @@ function convertDistriMessageToA2A(distriMessage, context) {
|
|
|
781
824
|
parts: distriMessage.parts.map(convertDistriPartToA2A),
|
|
782
825
|
kind: "message",
|
|
783
826
|
contextId: context.thread_id,
|
|
784
|
-
taskId: context.task_id || context.run_id || void 0
|
|
827
|
+
taskId: context.task_id || context.run_id || void 0,
|
|
828
|
+
metadata: distriMessage.metadata
|
|
785
829
|
};
|
|
786
830
|
}
|
|
787
831
|
function convertDistriPartToA2A(distriPart) {
|
|
@@ -795,7 +839,7 @@ function convertDistriPartToA2A(distriPart) {
|
|
|
795
839
|
const fileUri = { mimeType: distriPart.data.mime_type, uri: distriPart.data.url };
|
|
796
840
|
result = { kind: "file", file: fileUri };
|
|
797
841
|
} else {
|
|
798
|
-
const fileBytes = { mimeType: distriPart.data.mime_type, bytes: distriPart.data.
|
|
842
|
+
const fileBytes = { mimeType: distriPart.data.mime_type, bytes: distriPart.data.bytes };
|
|
799
843
|
result = { kind: "file", file: fileBytes };
|
|
800
844
|
}
|
|
801
845
|
break;
|
|
@@ -860,12 +904,41 @@ function extractToolCallsFromDistriMessage(message) {
|
|
|
860
904
|
function extractToolResultsFromDistriMessage(message) {
|
|
861
905
|
return message.parts.filter((part) => part.part_type === "tool_result").map((part) => part.data);
|
|
862
906
|
}
|
|
907
|
+
function parseTodosFromFormatted(formatted) {
|
|
908
|
+
if (!formatted || formatted === "\u25A1 No todos") {
|
|
909
|
+
return [];
|
|
910
|
+
}
|
|
911
|
+
const lines = formatted.split("\n").filter((line) => line.trim());
|
|
912
|
+
return lines.map((line, index) => {
|
|
913
|
+
const trimmed = line.trim();
|
|
914
|
+
let status = "open";
|
|
915
|
+
let content = trimmed;
|
|
916
|
+
if (trimmed.startsWith("\u25A0")) {
|
|
917
|
+
status = "done";
|
|
918
|
+
content = trimmed.slice(1).trim();
|
|
919
|
+
} else if (trimmed.startsWith("\u25D0")) {
|
|
920
|
+
status = "in_progress";
|
|
921
|
+
content = trimmed.slice(1).trim();
|
|
922
|
+
} else if (trimmed.startsWith("\u25A1")) {
|
|
923
|
+
status = "open";
|
|
924
|
+
content = trimmed.slice(1).trim();
|
|
925
|
+
}
|
|
926
|
+
return {
|
|
927
|
+
id: `todo_${index}`,
|
|
928
|
+
content,
|
|
929
|
+
status
|
|
930
|
+
};
|
|
931
|
+
});
|
|
932
|
+
}
|
|
863
933
|
|
|
864
934
|
// src/distri-client.ts
|
|
865
935
|
var _DistriClient = class _DistriClient {
|
|
866
936
|
constructor(config) {
|
|
867
937
|
this.agentClients = /* @__PURE__ */ new Map();
|
|
868
938
|
const headers = { ...config.headers };
|
|
939
|
+
if (config.workspaceId) {
|
|
940
|
+
headers["X-Workspace-Id"] = config.workspaceId;
|
|
941
|
+
}
|
|
869
942
|
this.accessToken = config.accessToken;
|
|
870
943
|
this.refreshToken = config.refreshToken;
|
|
871
944
|
this.tokenRefreshSkewMs = config.tokenRefreshSkewMs ?? 6e4;
|
|
@@ -880,7 +953,8 @@ var _DistriClient = class _DistriClient {
|
|
|
880
953
|
headers,
|
|
881
954
|
interceptor: config.interceptor ?? (async (init) => Promise.resolve(init)),
|
|
882
955
|
onTokenRefresh: config.onTokenRefresh,
|
|
883
|
-
clientId: config.clientId
|
|
956
|
+
clientId: config.clientId,
|
|
957
|
+
workspaceId: config.workspaceId
|
|
884
958
|
};
|
|
885
959
|
}
|
|
886
960
|
/**
|
|
@@ -895,6 +969,24 @@ var _DistriClient = class _DistriClient {
|
|
|
895
969
|
set clientId(value) {
|
|
896
970
|
this.config.clientId = value;
|
|
897
971
|
}
|
|
972
|
+
/**
|
|
973
|
+
* Get the configured workspace ID.
|
|
974
|
+
*/
|
|
975
|
+
get workspaceId() {
|
|
976
|
+
return this.config.workspaceId;
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Set the workspace ID for multi-tenant support.
|
|
980
|
+
* Updates the X-Workspace-Id header for all subsequent requests.
|
|
981
|
+
*/
|
|
982
|
+
set workspaceId(value) {
|
|
983
|
+
this.config.workspaceId = value;
|
|
984
|
+
if (value) {
|
|
985
|
+
this.config.headers["X-Workspace-Id"] = value;
|
|
986
|
+
} else {
|
|
987
|
+
delete this.config.headers["X-Workspace-Id"];
|
|
988
|
+
}
|
|
989
|
+
}
|
|
898
990
|
/**
|
|
899
991
|
* Create a client with default cloud configuration.
|
|
900
992
|
*
|
|
@@ -1347,8 +1439,51 @@ var _DistriClient = class _DistriClient {
|
|
|
1347
1439
|
yield* await client.sendMessageStream(params);
|
|
1348
1440
|
} catch (error) {
|
|
1349
1441
|
console.error(error);
|
|
1350
|
-
|
|
1442
|
+
const errorMessage = this.extractErrorMessage(error);
|
|
1443
|
+
throw new DistriError(errorMessage, "STREAM_MESSAGE_ERROR", error);
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
/**
|
|
1447
|
+
* Extract a user-friendly error message from potentially nested errors
|
|
1448
|
+
*/
|
|
1449
|
+
extractErrorMessage(error) {
|
|
1450
|
+
if (!error) return "Unknown error occurred";
|
|
1451
|
+
if (typeof error === "object" && error !== null) {
|
|
1452
|
+
const err = error;
|
|
1453
|
+
if (err.error && typeof err.error === "object") {
|
|
1454
|
+
const jsonRpcError = err.error;
|
|
1455
|
+
if (typeof jsonRpcError.message === "string") {
|
|
1456
|
+
return jsonRpcError.message;
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
if (err.message && typeof err.message === "string") {
|
|
1460
|
+
return err.message;
|
|
1461
|
+
}
|
|
1462
|
+
if (err.details && typeof err.details === "object") {
|
|
1463
|
+
const details = err.details;
|
|
1464
|
+
if (details.message && typeof details.message === "string") {
|
|
1465
|
+
return details.message;
|
|
1466
|
+
}
|
|
1467
|
+
if (details.error && typeof details.error === "object") {
|
|
1468
|
+
const nestedError = details.error;
|
|
1469
|
+
if (typeof nestedError.message === "string") {
|
|
1470
|
+
return nestedError.message;
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
if (err.cause && typeof err.cause === "object") {
|
|
1475
|
+
return this.extractErrorMessage(err.cause);
|
|
1476
|
+
}
|
|
1351
1477
|
}
|
|
1478
|
+
if (error instanceof Error) {
|
|
1479
|
+
const msg = error.message;
|
|
1480
|
+
const sseMatch = msg.match(/SSE event contained an error:\s*(.+?)\s*\(Code:/);
|
|
1481
|
+
if (sseMatch) return sseMatch[1];
|
|
1482
|
+
const rpcMatch = msg.match(/RPC Error:\s*(.+?)\s*\(Code:/);
|
|
1483
|
+
if (rpcMatch) return rpcMatch[1];
|
|
1484
|
+
return msg;
|
|
1485
|
+
}
|
|
1486
|
+
return String(error);
|
|
1352
1487
|
}
|
|
1353
1488
|
/**
|
|
1354
1489
|
* Get task details
|
|
@@ -1410,11 +1545,19 @@ var _DistriClient = class _DistriClient {
|
|
|
1410
1545
|
}
|
|
1411
1546
|
}
|
|
1412
1547
|
/**
|
|
1413
|
-
* Get agents sorted by thread count (most active first)
|
|
1548
|
+
* Get agents sorted by thread count (most active first).
|
|
1549
|
+
* Includes all registered agents, even those with 0 threads.
|
|
1550
|
+
* Optionally filter by name with search parameter.
|
|
1414
1551
|
*/
|
|
1415
|
-
async getAgentsByUsage() {
|
|
1552
|
+
async getAgentsByUsage(options) {
|
|
1416
1553
|
try {
|
|
1417
|
-
const
|
|
1554
|
+
const params = new URLSearchParams();
|
|
1555
|
+
if (options?.search) {
|
|
1556
|
+
params.set("search", options.search);
|
|
1557
|
+
}
|
|
1558
|
+
const query = params.toString();
|
|
1559
|
+
const url = query ? `/threads/agents?${query}` : "/threads/agents";
|
|
1560
|
+
const response = await this.fetch(url);
|
|
1418
1561
|
if (!response.ok) {
|
|
1419
1562
|
throw new ApiError(`Failed to fetch agents by usage: ${response.statusText}`, response.status);
|
|
1420
1563
|
}
|
|
@@ -1479,6 +1622,138 @@ var _DistriClient = class _DistriClient {
|
|
|
1479
1622
|
const messages = await this.getThreadMessages(threadId);
|
|
1480
1623
|
return messages.map(convertA2AMessageToDistri);
|
|
1481
1624
|
}
|
|
1625
|
+
// ========== Message Read Status Methods ==========
|
|
1626
|
+
/**
|
|
1627
|
+
* Mark a message as read
|
|
1628
|
+
*/
|
|
1629
|
+
async markMessageRead(threadId, messageId) {
|
|
1630
|
+
try {
|
|
1631
|
+
const response = await this.fetch(
|
|
1632
|
+
`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/read`,
|
|
1633
|
+
{ method: "POST" }
|
|
1634
|
+
);
|
|
1635
|
+
if (!response.ok) {
|
|
1636
|
+
throw new ApiError(`Failed to mark message as read: ${response.statusText}`, response.status);
|
|
1637
|
+
}
|
|
1638
|
+
return await response.json();
|
|
1639
|
+
} catch (error) {
|
|
1640
|
+
if (error instanceof ApiError) throw error;
|
|
1641
|
+
throw new DistriError(`Failed to mark message ${messageId} as read`, "MARK_READ_ERROR", error);
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
/**
|
|
1645
|
+
* Get read status for a specific message
|
|
1646
|
+
*/
|
|
1647
|
+
async getMessageReadStatus(threadId, messageId) {
|
|
1648
|
+
try {
|
|
1649
|
+
const response = await this.fetch(
|
|
1650
|
+
`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/read`
|
|
1651
|
+
);
|
|
1652
|
+
if (response.status === 404) {
|
|
1653
|
+
return null;
|
|
1654
|
+
}
|
|
1655
|
+
if (!response.ok) {
|
|
1656
|
+
throw new ApiError(`Failed to get message read status: ${response.statusText}`, response.status);
|
|
1657
|
+
}
|
|
1658
|
+
return await response.json();
|
|
1659
|
+
} catch (error) {
|
|
1660
|
+
if (error instanceof ApiError) throw error;
|
|
1661
|
+
throw new DistriError(`Failed to get read status for message ${messageId}`, "FETCH_ERROR", error);
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
/**
|
|
1665
|
+
* Get read status for all messages in a thread
|
|
1666
|
+
*/
|
|
1667
|
+
async getThreadReadStatus(threadId) {
|
|
1668
|
+
try {
|
|
1669
|
+
const response = await this.fetch(
|
|
1670
|
+
`/threads/${encodeURIComponent(threadId)}/read-status`
|
|
1671
|
+
);
|
|
1672
|
+
if (!response.ok) {
|
|
1673
|
+
throw new ApiError(`Failed to get thread read status: ${response.statusText}`, response.status);
|
|
1674
|
+
}
|
|
1675
|
+
return await response.json();
|
|
1676
|
+
} catch (error) {
|
|
1677
|
+
if (error instanceof ApiError) throw error;
|
|
1678
|
+
throw new DistriError(`Failed to get read status for thread ${threadId}`, "FETCH_ERROR", error);
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
// ========== Message Voting Methods ==========
|
|
1682
|
+
/**
|
|
1683
|
+
* Vote on a message (upvote or downvote)
|
|
1684
|
+
* Downvotes require a comment explaining the issue
|
|
1685
|
+
*/
|
|
1686
|
+
async voteMessage(threadId, messageId, request) {
|
|
1687
|
+
try {
|
|
1688
|
+
const response = await this.fetch(
|
|
1689
|
+
`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/vote`,
|
|
1690
|
+
{
|
|
1691
|
+
method: "POST",
|
|
1692
|
+
headers: { "Content-Type": "application/json" },
|
|
1693
|
+
body: JSON.stringify(request)
|
|
1694
|
+
}
|
|
1695
|
+
);
|
|
1696
|
+
if (!response.ok) {
|
|
1697
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1698
|
+
throw new ApiError(errorData.error || `Failed to vote on message: ${response.statusText}`, response.status);
|
|
1699
|
+
}
|
|
1700
|
+
return await response.json();
|
|
1701
|
+
} catch (error) {
|
|
1702
|
+
if (error instanceof ApiError) throw error;
|
|
1703
|
+
throw new DistriError(`Failed to vote on message ${messageId}`, "VOTE_ERROR", error);
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
/**
|
|
1707
|
+
* Remove vote from a message
|
|
1708
|
+
*/
|
|
1709
|
+
async removeVote(threadId, messageId) {
|
|
1710
|
+
try {
|
|
1711
|
+
const response = await this.fetch(
|
|
1712
|
+
`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/vote`,
|
|
1713
|
+
{ method: "DELETE" }
|
|
1714
|
+
);
|
|
1715
|
+
if (!response.ok && response.status !== 204) {
|
|
1716
|
+
throw new ApiError(`Failed to remove vote: ${response.statusText}`, response.status);
|
|
1717
|
+
}
|
|
1718
|
+
} catch (error) {
|
|
1719
|
+
if (error instanceof ApiError) throw error;
|
|
1720
|
+
throw new DistriError(`Failed to remove vote from message ${messageId}`, "VOTE_ERROR", error);
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
/**
|
|
1724
|
+
* Get vote summary for a message (counts + current user's vote)
|
|
1725
|
+
*/
|
|
1726
|
+
async getMessageVoteSummary(threadId, messageId) {
|
|
1727
|
+
try {
|
|
1728
|
+
const response = await this.fetch(
|
|
1729
|
+
`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/vote`
|
|
1730
|
+
);
|
|
1731
|
+
if (!response.ok) {
|
|
1732
|
+
throw new ApiError(`Failed to get vote summary: ${response.statusText}`, response.status);
|
|
1733
|
+
}
|
|
1734
|
+
return await response.json();
|
|
1735
|
+
} catch (error) {
|
|
1736
|
+
if (error instanceof ApiError) throw error;
|
|
1737
|
+
throw new DistriError(`Failed to get vote summary for message ${messageId}`, "FETCH_ERROR", error);
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
/**
|
|
1741
|
+
* Get all votes for a message (admin/analytics use)
|
|
1742
|
+
*/
|
|
1743
|
+
async getMessageVotes(threadId, messageId) {
|
|
1744
|
+
try {
|
|
1745
|
+
const response = await this.fetch(
|
|
1746
|
+
`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/votes`
|
|
1747
|
+
);
|
|
1748
|
+
if (!response.ok) {
|
|
1749
|
+
throw new ApiError(`Failed to get message votes: ${response.statusText}`, response.status);
|
|
1750
|
+
}
|
|
1751
|
+
return await response.json();
|
|
1752
|
+
} catch (error) {
|
|
1753
|
+
if (error instanceof ApiError) throw error;
|
|
1754
|
+
throw new DistriError(`Failed to get votes for message ${messageId}`, "FETCH_ERROR", error);
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1482
1757
|
/**
|
|
1483
1758
|
* Send a DistriMessage to a thread
|
|
1484
1759
|
*/
|
|
@@ -1504,7 +1779,12 @@ var _DistriClient = class _DistriClient {
|
|
|
1504
1779
|
},
|
|
1505
1780
|
body: JSON.stringify({
|
|
1506
1781
|
tool_call_id: result.tool_call_id,
|
|
1507
|
-
tool_response:
|
|
1782
|
+
tool_response: {
|
|
1783
|
+
tool_call_id: result.tool_call_id,
|
|
1784
|
+
tool_name: result.tool_name,
|
|
1785
|
+
parts: result.parts,
|
|
1786
|
+
parts_metadata: result.parts_metadata
|
|
1787
|
+
}
|
|
1508
1788
|
})
|
|
1509
1789
|
});
|
|
1510
1790
|
if (!response.ok) {
|
|
@@ -1768,9 +2048,17 @@ var _DistriClient = class _DistriClient {
|
|
|
1768
2048
|
};
|
|
1769
2049
|
}
|
|
1770
2050
|
/**
|
|
1771
|
-
* Helper method to create message send parameters
|
|
1772
|
-
|
|
1773
|
-
|
|
2051
|
+
* Helper method to create message send parameters.
|
|
2052
|
+
*
|
|
2053
|
+
* Pass `dynamicMetadata` to inject `dynamic_sections` and/or `dynamic_values`
|
|
2054
|
+
* into the metadata so the server can apply them to prompt templates.
|
|
2055
|
+
*/
|
|
2056
|
+
static initMessageParams(message, configuration, metadata, dynamicMetadata) {
|
|
2057
|
+
const mergedMetadata = {
|
|
2058
|
+
...metadata,
|
|
2059
|
+
...dynamicMetadata?.dynamic_sections ? { dynamic_sections: dynamicMetadata.dynamic_sections } : {},
|
|
2060
|
+
...dynamicMetadata?.dynamic_values ? { dynamic_values: dynamicMetadata.dynamic_values } : {}
|
|
2061
|
+
};
|
|
1774
2062
|
return {
|
|
1775
2063
|
message,
|
|
1776
2064
|
configuration: {
|
|
@@ -1779,18 +2067,26 @@ var _DistriClient = class _DistriClient {
|
|
|
1779
2067
|
// Default to non-blocking for streaming
|
|
1780
2068
|
...configuration
|
|
1781
2069
|
},
|
|
1782
|
-
metadata
|
|
2070
|
+
metadata: Object.keys(mergedMetadata).length > 0 ? mergedMetadata : metadata
|
|
1783
2071
|
};
|
|
1784
2072
|
}
|
|
1785
2073
|
/**
|
|
1786
|
-
* Create MessageSendParams from a DistriMessage using InvokeContext
|
|
2074
|
+
* Create MessageSendParams from a DistriMessage using InvokeContext.
|
|
2075
|
+
*
|
|
2076
|
+
* Pass `dynamicMetadata` to inject `dynamic_sections` and/or `dynamic_values`
|
|
2077
|
+
* into the metadata so the server can apply them to prompt templates.
|
|
1787
2078
|
*/
|
|
1788
|
-
static initDistriMessageParams(message, context) {
|
|
2079
|
+
static initDistriMessageParams(message, context, dynamicMetadata) {
|
|
1789
2080
|
const a2aMessage = convertDistriMessageToA2A(message, context);
|
|
1790
2081
|
const contextMetadata = context.getMetadata?.() || {};
|
|
2082
|
+
const mergedMetadata = {
|
|
2083
|
+
...contextMetadata,
|
|
2084
|
+
...dynamicMetadata?.dynamic_sections ? { dynamic_sections: dynamicMetadata.dynamic_sections } : {},
|
|
2085
|
+
...dynamicMetadata?.dynamic_values ? { dynamic_values: dynamicMetadata.dynamic_values } : {}
|
|
2086
|
+
};
|
|
1791
2087
|
return {
|
|
1792
2088
|
message: a2aMessage,
|
|
1793
|
-
metadata: contextMetadata
|
|
2089
|
+
metadata: Object.keys(mergedMetadata).length > 0 ? mergedMetadata : contextMetadata
|
|
1794
2090
|
};
|
|
1795
2091
|
}
|
|
1796
2092
|
};
|
|
@@ -1896,28 +2192,40 @@ var Agent = class _Agent {
|
|
|
1896
2192
|
const enhancedParams = this.enhanceParamsWithTools(params, tools);
|
|
1897
2193
|
const a2aStream = this.client.sendMessageStream(this.agentDefinition.id, enhancedParams);
|
|
1898
2194
|
const self = this;
|
|
1899
|
-
return async function* () {
|
|
1900
|
-
|
|
1901
|
-
const
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
2195
|
+
return (async function* () {
|
|
2196
|
+
try {
|
|
2197
|
+
for await (const event of a2aStream) {
|
|
2198
|
+
const converted = decodeA2AStreamEvent(event);
|
|
2199
|
+
if (converted && converted.type === "inline_hook_requested") {
|
|
2200
|
+
const hookReq = converted.data;
|
|
2201
|
+
const handler = self.hookHandlers.get(hookReq.hook) || self.defaultHookHandler;
|
|
2202
|
+
if (handler) {
|
|
2203
|
+
try {
|
|
2204
|
+
const mutation = await handler(hookReq);
|
|
2205
|
+
await self.client.completeInlineHook(hookReq.hook_id, mutation);
|
|
2206
|
+
} catch (err) {
|
|
2207
|
+
await self.client.completeInlineHook(hookReq.hook_id, { dynamic_values: {} });
|
|
2208
|
+
}
|
|
2209
|
+
} else {
|
|
1910
2210
|
await self.client.completeInlineHook(hookReq.hook_id, { dynamic_values: {} });
|
|
1911
2211
|
}
|
|
1912
|
-
|
|
1913
|
-
|
|
2212
|
+
yield converted;
|
|
2213
|
+
} else if (converted) {
|
|
2214
|
+
yield converted;
|
|
1914
2215
|
}
|
|
1915
|
-
yield converted;
|
|
1916
|
-
} else if (converted) {
|
|
1917
|
-
yield converted;
|
|
1918
2216
|
}
|
|
2217
|
+
} catch (error) {
|
|
2218
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2219
|
+
const runError = {
|
|
2220
|
+
type: "run_error",
|
|
2221
|
+
data: {
|
|
2222
|
+
message,
|
|
2223
|
+
code: "STREAM_ERROR"
|
|
2224
|
+
}
|
|
2225
|
+
};
|
|
2226
|
+
yield runError;
|
|
1919
2227
|
}
|
|
1920
|
-
}();
|
|
2228
|
+
})();
|
|
1921
2229
|
}
|
|
1922
2230
|
/**
|
|
1923
2231
|
* Validate that required external tools are registered before invoking.
|
|
@@ -1945,12 +2253,16 @@ var Agent = class _Agent {
|
|
|
1945
2253
|
};
|
|
1946
2254
|
}
|
|
1947
2255
|
/**
|
|
1948
|
-
* Enhance message params with tool definitions
|
|
2256
|
+
* Enhance message params with tool definitions and dynamic metadata.
|
|
2257
|
+
*
|
|
2258
|
+
* When `dynamic_sections` or `dynamic_values` are present in `params.metadata`,
|
|
2259
|
+
* they are forwarded so the server injects them into the prompt template.
|
|
1949
2260
|
*/
|
|
1950
2261
|
enhanceParamsWithTools(params, tools) {
|
|
1951
2262
|
this.assertExternalTools(tools);
|
|
2263
|
+
const existingMeta = params.metadata ?? {};
|
|
1952
2264
|
const metadata = {
|
|
1953
|
-
...
|
|
2265
|
+
...existingMeta,
|
|
1954
2266
|
external_tools: tools?.map((tool) => ({
|
|
1955
2267
|
name: tool.name,
|
|
1956
2268
|
description: tool.description,
|