@distri/core 0.3.1 → 0.3.2
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 +149 -39
- package/dist/index.d.ts +149 -39
- package/dist/index.js +227 -70
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +226 -70
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ __export(index_exports, {
|
|
|
29
29
|
DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
|
|
30
30
|
DistriClient: () => DistriClient,
|
|
31
31
|
DistriError: () => DistriError,
|
|
32
|
+
ExternalToolValidationError: () => ExternalToolValidationError,
|
|
32
33
|
convertA2AMessageToDistri: () => convertA2AMessageToDistri,
|
|
33
34
|
convertA2APartToDistri: () => convertA2APartToDistri,
|
|
34
35
|
convertA2AStatusUpdateToDistri: () => convertA2AStatusUpdateToDistri,
|
|
@@ -729,6 +730,17 @@ function convertA2AStatusUpdateToDistri(statusUpdate) {
|
|
|
729
730
|
};
|
|
730
731
|
return hookRequested;
|
|
731
732
|
}
|
|
733
|
+
case "browser_session_started": {
|
|
734
|
+
const browserSessionStarted = {
|
|
735
|
+
type: "browser_session_started",
|
|
736
|
+
data: {
|
|
737
|
+
session_id: metadata.session_id || "",
|
|
738
|
+
viewer_url: metadata.viewer_url,
|
|
739
|
+
stream_url: metadata.stream_url
|
|
740
|
+
}
|
|
741
|
+
};
|
|
742
|
+
return browserSessionStarted;
|
|
743
|
+
}
|
|
732
744
|
default: {
|
|
733
745
|
console.warn(`Unhandled status update metadata type: ${metadata.type}`, metadata);
|
|
734
746
|
const defaultResult = {
|
|
@@ -908,21 +920,29 @@ var _DistriClient = class _DistriClient {
|
|
|
908
920
|
this.tokenRefreshSkewMs = config.tokenRefreshSkewMs ?? 6e4;
|
|
909
921
|
this.onTokenRefresh = config.onTokenRefresh;
|
|
910
922
|
this.config = {
|
|
911
|
-
baseUrl: config.baseUrl
|
|
923
|
+
baseUrl: config.baseUrl?.replace(/\/$/, "") || DEFAULT_BASE_URL,
|
|
912
924
|
apiVersion: config.apiVersion || "v1",
|
|
913
|
-
timeout: config.timeout
|
|
914
|
-
retryAttempts: config.retryAttempts
|
|
915
|
-
retryDelay: config.retryDelay
|
|
916
|
-
debug: config.debug
|
|
925
|
+
timeout: config.timeout ?? 3e4,
|
|
926
|
+
retryAttempts: config.retryAttempts ?? 3,
|
|
927
|
+
retryDelay: config.retryDelay ?? 1e3,
|
|
928
|
+
debug: config.debug ?? false,
|
|
917
929
|
headers,
|
|
918
|
-
interceptor: config.interceptor
|
|
930
|
+
interceptor: config.interceptor ?? (async (init) => Promise.resolve(init)),
|
|
931
|
+
onTokenRefresh: config.onTokenRefresh,
|
|
932
|
+
clientId: config.clientId
|
|
919
933
|
};
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* Get the configured client ID.
|
|
937
|
+
*/
|
|
938
|
+
get clientId() {
|
|
939
|
+
return this.config.clientId;
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Set the client ID for embed token issuance.
|
|
943
|
+
*/
|
|
944
|
+
set clientId(value) {
|
|
945
|
+
this.config.clientId = value;
|
|
926
946
|
}
|
|
927
947
|
/**
|
|
928
948
|
* Create a client with default cloud configuration.
|
|
@@ -955,7 +975,7 @@ var _DistriClient = class _DistriClient {
|
|
|
955
975
|
if (expiry) {
|
|
956
976
|
body.expiry = typeof expiry === "string" ? expiry : expiry.toISOString();
|
|
957
977
|
}
|
|
958
|
-
const resp = await this.fetch(`/
|
|
978
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values`, {
|
|
959
979
|
method: "POST",
|
|
960
980
|
headers: {
|
|
961
981
|
"Content-Type": "application/json",
|
|
@@ -972,7 +992,7 @@ var _DistriClient = class _DistriClient {
|
|
|
972
992
|
* Session store: get a single value
|
|
973
993
|
*/
|
|
974
994
|
async getSessionValue(sessionId, key) {
|
|
975
|
-
const resp = await this.fetch(`/
|
|
995
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
|
|
976
996
|
method: "GET",
|
|
977
997
|
headers: {
|
|
978
998
|
...this.config.headers
|
|
@@ -989,7 +1009,7 @@ var _DistriClient = class _DistriClient {
|
|
|
989
1009
|
* Session store: get all values in a session
|
|
990
1010
|
*/
|
|
991
1011
|
async getSessionValues(sessionId) {
|
|
992
|
-
const resp = await this.fetch(`/
|
|
1012
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values`, {
|
|
993
1013
|
method: "GET",
|
|
994
1014
|
headers: {
|
|
995
1015
|
...this.config.headers
|
|
@@ -1006,7 +1026,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1006
1026
|
* Session store: delete a single key
|
|
1007
1027
|
*/
|
|
1008
1028
|
async deleteSessionValue(sessionId, key) {
|
|
1009
|
-
const resp = await this.fetch(`/
|
|
1029
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
|
|
1010
1030
|
method: "DELETE",
|
|
1011
1031
|
headers: {
|
|
1012
1032
|
...this.config.headers
|
|
@@ -1021,7 +1041,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1021
1041
|
* Session store: clear all keys in a session
|
|
1022
1042
|
*/
|
|
1023
1043
|
async clearSession(sessionId) {
|
|
1024
|
-
const resp = await this.fetch(`/
|
|
1044
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}`, {
|
|
1025
1045
|
method: "DELETE",
|
|
1026
1046
|
headers: {
|
|
1027
1047
|
...this.config.headers
|
|
@@ -1032,30 +1052,6 @@ var _DistriClient = class _DistriClient {
|
|
|
1032
1052
|
throw new ApiError(errorData.error || "Failed to clear session", resp.status);
|
|
1033
1053
|
}
|
|
1034
1054
|
}
|
|
1035
|
-
/**
|
|
1036
|
-
* Set additional user message parts for the next agent iteration.
|
|
1037
|
-
* These parts will be appended to the user message in the prompt.
|
|
1038
|
-
* @param sessionId - The thread/session ID
|
|
1039
|
-
* @param parts - Array of DistriPart objects to append to user message
|
|
1040
|
-
*/
|
|
1041
|
-
async setAdditionalUserParts(sessionId, parts) {
|
|
1042
|
-
await this.setSessionValue(sessionId, _DistriClient.ADDITIONAL_PARTS_KEY, parts);
|
|
1043
|
-
}
|
|
1044
|
-
/**
|
|
1045
|
-
* Get the current additional user message parts.
|
|
1046
|
-
* @param sessionId - The thread/session ID
|
|
1047
|
-
* @returns Array of DistriPart objects or null if not set
|
|
1048
|
-
*/
|
|
1049
|
-
async getAdditionalUserParts(sessionId) {
|
|
1050
|
-
return this.getSessionValue(sessionId, _DistriClient.ADDITIONAL_PARTS_KEY);
|
|
1051
|
-
}
|
|
1052
|
-
/**
|
|
1053
|
-
* Clear/delete the additional user message parts.
|
|
1054
|
-
* @param sessionId - The thread/session ID
|
|
1055
|
-
*/
|
|
1056
|
-
async clearAdditionalUserParts(sessionId) {
|
|
1057
|
-
await this.deleteSessionValue(sessionId, _DistriClient.ADDITIONAL_PARTS_KEY);
|
|
1058
|
-
}
|
|
1059
1055
|
/**
|
|
1060
1056
|
* Issue an access token + refresh token for temporary authentication.
|
|
1061
1057
|
* Requires an existing authenticated session (bearer token).
|
|
@@ -1085,7 +1081,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1085
1081
|
if (!tokens?.access_token || !tokens?.refresh_token || typeof tokens?.expires_at !== "number") {
|
|
1086
1082
|
throw new ApiError("Invalid token response", response.status);
|
|
1087
1083
|
}
|
|
1088
|
-
this.applyTokens(tokens.access_token, tokens.refresh_token
|
|
1084
|
+
this.applyTokens(tokens.access_token, tokens.refresh_token);
|
|
1089
1085
|
return tokens;
|
|
1090
1086
|
}
|
|
1091
1087
|
/**
|
|
@@ -1098,13 +1094,18 @@ var _DistriClient = class _DistriClient {
|
|
|
1098
1094
|
* Update the access/refresh tokens in memory.
|
|
1099
1095
|
*/
|
|
1100
1096
|
setTokens(tokens) {
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
}
|
|
1104
|
-
if (tokens.refreshToken !== void 0) {
|
|
1097
|
+
this.accessToken = tokens.accessToken;
|
|
1098
|
+
if (tokens.refreshToken) {
|
|
1105
1099
|
this.refreshToken = tokens.refreshToken;
|
|
1106
1100
|
}
|
|
1107
1101
|
}
|
|
1102
|
+
/**
|
|
1103
|
+
* Reset all authentication tokens.
|
|
1104
|
+
*/
|
|
1105
|
+
resetTokens() {
|
|
1106
|
+
this.accessToken = void 0;
|
|
1107
|
+
this.refreshToken = void 0;
|
|
1108
|
+
}
|
|
1108
1109
|
/**
|
|
1109
1110
|
* Start streaming speech-to-text transcription via WebSocket
|
|
1110
1111
|
*/
|
|
@@ -1322,6 +1323,31 @@ var _DistriClient = class _DistriClient {
|
|
|
1322
1323
|
throw new DistriError(`Failed to fetch agent ${agentId}`, "FETCH_ERROR", error);
|
|
1323
1324
|
}
|
|
1324
1325
|
}
|
|
1326
|
+
/**
|
|
1327
|
+
* Update an agent's definition (markdown only)
|
|
1328
|
+
*/
|
|
1329
|
+
async updateAgent(agentId, update) {
|
|
1330
|
+
try {
|
|
1331
|
+
const response = await this.fetch(`/agents/${agentId}`, {
|
|
1332
|
+
method: "PUT",
|
|
1333
|
+
headers: {
|
|
1334
|
+
"Content-Type": "application/json",
|
|
1335
|
+
...this.config.headers
|
|
1336
|
+
},
|
|
1337
|
+
body: JSON.stringify(update)
|
|
1338
|
+
});
|
|
1339
|
+
if (!response.ok) {
|
|
1340
|
+
if (response.status === 404) {
|
|
1341
|
+
throw new ApiError(`Agent not found: ${agentId}`, 404);
|
|
1342
|
+
}
|
|
1343
|
+
throw new ApiError(`Failed to update agent: ${response.statusText}`, response.status);
|
|
1344
|
+
}
|
|
1345
|
+
return await response.json();
|
|
1346
|
+
} catch (error) {
|
|
1347
|
+
if (error instanceof ApiError) throw error;
|
|
1348
|
+
throw new DistriError(`Failed to update agent ${agentId}`, "UPDATE_ERROR", error);
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1325
1351
|
/**
|
|
1326
1352
|
* Get or create A2AClient for an agent
|
|
1327
1353
|
*/
|
|
@@ -1407,11 +1433,22 @@ var _DistriClient = class _DistriClient {
|
|
|
1407
1433
|
}
|
|
1408
1434
|
}
|
|
1409
1435
|
/**
|
|
1410
|
-
* Get threads from Distri server
|
|
1436
|
+
* Get threads from Distri server with filtering and pagination
|
|
1411
1437
|
*/
|
|
1412
|
-
async getThreads() {
|
|
1438
|
+
async getThreads(params = {}) {
|
|
1413
1439
|
try {
|
|
1414
|
-
const
|
|
1440
|
+
const searchParams = new URLSearchParams();
|
|
1441
|
+
if (params.agent_id) searchParams.set("agent_id", params.agent_id);
|
|
1442
|
+
if (params.external_id) searchParams.set("external_id", params.external_id);
|
|
1443
|
+
if (params.search) searchParams.set("search", params.search);
|
|
1444
|
+
if (params.from_date) searchParams.set("from_date", params.from_date);
|
|
1445
|
+
if (params.to_date) searchParams.set("to_date", params.to_date);
|
|
1446
|
+
if (params.tags?.length) searchParams.set("tags", params.tags.join(","));
|
|
1447
|
+
if (params.limit !== void 0) searchParams.set("limit", params.limit.toString());
|
|
1448
|
+
if (params.offset !== void 0) searchParams.set("offset", params.offset.toString());
|
|
1449
|
+
const queryString = searchParams.toString();
|
|
1450
|
+
const url = queryString ? `/threads?${queryString}` : "/threads";
|
|
1451
|
+
const response = await this.fetch(url);
|
|
1415
1452
|
if (!response.ok) {
|
|
1416
1453
|
throw new ApiError(`Failed to fetch threads: ${response.statusText}`, response.status);
|
|
1417
1454
|
}
|
|
@@ -1421,6 +1458,39 @@ var _DistriClient = class _DistriClient {
|
|
|
1421
1458
|
throw new DistriError("Failed to fetch threads", "FETCH_ERROR", error);
|
|
1422
1459
|
}
|
|
1423
1460
|
}
|
|
1461
|
+
/**
|
|
1462
|
+
* Get agents sorted by thread count (most active first)
|
|
1463
|
+
*/
|
|
1464
|
+
async getAgentsByUsage() {
|
|
1465
|
+
try {
|
|
1466
|
+
const response = await this.fetch("/threads/agents");
|
|
1467
|
+
if (!response.ok) {
|
|
1468
|
+
throw new ApiError(`Failed to fetch agents by usage: ${response.statusText}`, response.status);
|
|
1469
|
+
}
|
|
1470
|
+
return await response.json();
|
|
1471
|
+
} catch (error) {
|
|
1472
|
+
if (error instanceof ApiError) throw error;
|
|
1473
|
+
throw new DistriError("Failed to fetch agents by usage", "FETCH_ERROR", error);
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
/**
|
|
1477
|
+
* Create a new browser session
|
|
1478
|
+
* Returns session info including viewer_url and stream_url from browsr
|
|
1479
|
+
*/
|
|
1480
|
+
async createBrowserSession() {
|
|
1481
|
+
try {
|
|
1482
|
+
const response = await this.fetch("/browser/session", {
|
|
1483
|
+
method: "POST"
|
|
1484
|
+
});
|
|
1485
|
+
if (!response.ok) {
|
|
1486
|
+
throw new ApiError(`Failed to create browser session: ${response.statusText}`, response.status);
|
|
1487
|
+
}
|
|
1488
|
+
return await response.json();
|
|
1489
|
+
} catch (error) {
|
|
1490
|
+
if (error instanceof ApiError) throw error;
|
|
1491
|
+
throw new DistriError("Failed to create browser session", "FETCH_ERROR", error);
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1424
1494
|
async getThread(threadId) {
|
|
1425
1495
|
try {
|
|
1426
1496
|
const response = await this.fetch(`/threads/${threadId}`);
|
|
@@ -1520,15 +1590,17 @@ var _DistriClient = class _DistriClient {
|
|
|
1520
1590
|
get baseUrl() {
|
|
1521
1591
|
return this.config.baseUrl;
|
|
1522
1592
|
}
|
|
1523
|
-
applyTokens(accessToken, refreshToken
|
|
1593
|
+
applyTokens(accessToken, refreshToken) {
|
|
1524
1594
|
this.accessToken = accessToken;
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
this.onTokenRefresh({ accessToken, refreshToken });
|
|
1595
|
+
if (refreshToken) {
|
|
1596
|
+
this.refreshToken = refreshToken;
|
|
1528
1597
|
}
|
|
1529
1598
|
}
|
|
1599
|
+
/**
|
|
1600
|
+
* Ensure access token is valid, refreshing if necessary
|
|
1601
|
+
*/
|
|
1530
1602
|
async ensureAccessToken() {
|
|
1531
|
-
if (!this.refreshToken) {
|
|
1603
|
+
if (!this.refreshToken && !this.onTokenRefresh) {
|
|
1532
1604
|
return;
|
|
1533
1605
|
}
|
|
1534
1606
|
if (!this.accessToken || this.isTokenExpiring(this.accessToken)) {
|
|
@@ -1540,7 +1612,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1540
1612
|
}
|
|
1541
1613
|
}
|
|
1542
1614
|
async refreshTokens() {
|
|
1543
|
-
if (!this.refreshToken) {
|
|
1615
|
+
if (!this.refreshToken && !this.onTokenRefresh) {
|
|
1544
1616
|
return;
|
|
1545
1617
|
}
|
|
1546
1618
|
if (!this.refreshPromise) {
|
|
@@ -1551,6 +1623,17 @@ var _DistriClient = class _DistriClient {
|
|
|
1551
1623
|
return this.refreshPromise;
|
|
1552
1624
|
}
|
|
1553
1625
|
async performTokenRefresh() {
|
|
1626
|
+
if (this.onTokenRefresh) {
|
|
1627
|
+
this.accessToken = void 0;
|
|
1628
|
+
const newToken = await this.onTokenRefresh();
|
|
1629
|
+
if (newToken) {
|
|
1630
|
+
this.applyTokens(newToken);
|
|
1631
|
+
return;
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
if (!this.refreshToken) {
|
|
1635
|
+
return;
|
|
1636
|
+
}
|
|
1554
1637
|
const response = await this.fetchAbsolute(
|
|
1555
1638
|
`${this.config.baseUrl}/token`,
|
|
1556
1639
|
{
|
|
@@ -1574,7 +1657,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1574
1657
|
if (!tokens?.access_token || !tokens?.refresh_token) {
|
|
1575
1658
|
throw new ApiError("Invalid token response", response.status);
|
|
1576
1659
|
}
|
|
1577
|
-
this.applyTokens(tokens.access_token, tokens.refresh_token
|
|
1660
|
+
this.applyTokens(tokens.access_token, tokens.refresh_token);
|
|
1578
1661
|
}
|
|
1579
1662
|
isTokenExpiring(token) {
|
|
1580
1663
|
const expiresAt = this.getTokenExpiry(token);
|
|
@@ -1669,7 +1752,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1669
1752
|
headers
|
|
1670
1753
|
});
|
|
1671
1754
|
clearTimeout(timeoutId);
|
|
1672
|
-
if (!skipAuth && retryOnAuth && response.status === 401 && this.refreshToken) {
|
|
1755
|
+
if (!skipAuth && retryOnAuth && response.status === 401 && (this.refreshToken || this.onTokenRefresh)) {
|
|
1673
1756
|
const refreshed = await this.refreshTokens().then(() => true).catch(() => false);
|
|
1674
1757
|
if (refreshed) {
|
|
1675
1758
|
return this.fetchAbsolute(url, initialInit, { skipAuth, retryOnAuth: false });
|
|
@@ -1687,7 +1770,8 @@ var _DistriClient = class _DistriClient {
|
|
|
1687
1770
|
throw lastError;
|
|
1688
1771
|
}
|
|
1689
1772
|
/**
|
|
1690
|
-
* Enhanced fetch with retry logic
|
|
1773
|
+
* Enhanced fetch with retry logic and auth headers.
|
|
1774
|
+
* Exposed publicly for extensions like DistriHomeClient.
|
|
1691
1775
|
*/
|
|
1692
1776
|
async fetch(input, initialInit) {
|
|
1693
1777
|
const url = `${this.config.baseUrl}${input}`;
|
|
@@ -1760,13 +1844,6 @@ var _DistriClient = class _DistriClient {
|
|
|
1760
1844
|
}
|
|
1761
1845
|
};
|
|
1762
1846
|
// ============================================================
|
|
1763
|
-
// Additional User Message Parts API
|
|
1764
|
-
// ============================================================
|
|
1765
|
-
// These methods allow external tools to append parts (text, images)
|
|
1766
|
-
// to the user message in the next agent iteration.
|
|
1767
|
-
// The parts are stored under the key "__additional_user_parts".
|
|
1768
|
-
_DistriClient.ADDITIONAL_PARTS_KEY = "__additional_user_parts";
|
|
1769
|
-
// ============================================================
|
|
1770
1847
|
// Token API
|
|
1771
1848
|
// ============================================================
|
|
1772
1849
|
// Issue access + refresh tokens for temporary authentication (e.g., frontend use)
|
|
@@ -1792,6 +1869,25 @@ function uuidv4() {
|
|
|
1792
1869
|
}
|
|
1793
1870
|
|
|
1794
1871
|
// src/agent.ts
|
|
1872
|
+
var ExternalToolValidationError = class extends DistriError {
|
|
1873
|
+
constructor(agentName, result) {
|
|
1874
|
+
super(
|
|
1875
|
+
result.message || "Missing required external tools for agent invocation.",
|
|
1876
|
+
"EXTERNAL_TOOL_VALIDATION_ERROR",
|
|
1877
|
+
{
|
|
1878
|
+
agentName,
|
|
1879
|
+
missingTools: result.missingTools,
|
|
1880
|
+
requiredTools: result.requiredTools,
|
|
1881
|
+
providedTools: result.providedTools
|
|
1882
|
+
}
|
|
1883
|
+
);
|
|
1884
|
+
this.name = "ExternalToolValidationError";
|
|
1885
|
+
this.agentName = agentName;
|
|
1886
|
+
this.missingTools = result.missingTools;
|
|
1887
|
+
this.requiredTools = result.requiredTools;
|
|
1888
|
+
this.providedTools = result.providedTools;
|
|
1889
|
+
}
|
|
1890
|
+
};
|
|
1795
1891
|
var Agent = class _Agent {
|
|
1796
1892
|
constructor(agentDefinition, client) {
|
|
1797
1893
|
this.hookHandlers = /* @__PURE__ */ new Map();
|
|
@@ -1812,7 +1908,7 @@ var Agent = class _Agent {
|
|
|
1812
1908
|
return this.agentDefinition.description;
|
|
1813
1909
|
}
|
|
1814
1910
|
get agentType() {
|
|
1815
|
-
return this.agentDefinition.agent_type
|
|
1911
|
+
return this.agentDefinition.agent_type;
|
|
1816
1912
|
}
|
|
1817
1913
|
get iconUrl() {
|
|
1818
1914
|
return this.agentDefinition.icon_url;
|
|
@@ -1849,7 +1945,7 @@ var Agent = class _Agent {
|
|
|
1849
1945
|
const enhancedParams = this.enhanceParamsWithTools(params, tools);
|
|
1850
1946
|
const a2aStream = this.client.sendMessageStream(this.agentDefinition.id, enhancedParams);
|
|
1851
1947
|
const self = this;
|
|
1852
|
-
return
|
|
1948
|
+
return async function* () {
|
|
1853
1949
|
for await (const event of a2aStream) {
|
|
1854
1950
|
const converted = decodeA2AStreamEvent(event);
|
|
1855
1951
|
if (converted && converted.type === "inline_hook_requested") {
|
|
@@ -1870,12 +1966,38 @@ var Agent = class _Agent {
|
|
|
1870
1966
|
yield converted;
|
|
1871
1967
|
}
|
|
1872
1968
|
}
|
|
1873
|
-
}
|
|
1969
|
+
}();
|
|
1970
|
+
}
|
|
1971
|
+
/**
|
|
1972
|
+
* Validate that required external tools are registered before invoking.
|
|
1973
|
+
*/
|
|
1974
|
+
validateExternalTools(tools = []) {
|
|
1975
|
+
const requiredTools = this.getRequiredExternalTools();
|
|
1976
|
+
const providedTools = tools.map((tool) => tool.name);
|
|
1977
|
+
if (requiredTools.length === 0) {
|
|
1978
|
+
return {
|
|
1979
|
+
isValid: true,
|
|
1980
|
+
requiredTools: [],
|
|
1981
|
+
providedTools,
|
|
1982
|
+
missingTools: []
|
|
1983
|
+
};
|
|
1984
|
+
}
|
|
1985
|
+
const providedSet = new Set(providedTools);
|
|
1986
|
+
const missingTools = requiredTools.filter((tool) => !providedSet.has(tool));
|
|
1987
|
+
const isValid = missingTools.length === 0;
|
|
1988
|
+
return {
|
|
1989
|
+
isValid,
|
|
1990
|
+
requiredTools,
|
|
1991
|
+
providedTools,
|
|
1992
|
+
missingTools,
|
|
1993
|
+
message: isValid ? void 0 : this.formatExternalToolValidationMessage(requiredTools, missingTools)
|
|
1994
|
+
};
|
|
1874
1995
|
}
|
|
1875
1996
|
/**
|
|
1876
1997
|
* Enhance message params with tool definitions
|
|
1877
1998
|
*/
|
|
1878
1999
|
enhanceParamsWithTools(params, tools) {
|
|
2000
|
+
this.assertExternalTools(tools);
|
|
1879
2001
|
const metadata = {
|
|
1880
2002
|
...params.metadata,
|
|
1881
2003
|
external_tools: tools?.map((tool) => ({
|
|
@@ -1890,6 +2012,39 @@ var Agent = class _Agent {
|
|
|
1890
2012
|
metadata
|
|
1891
2013
|
};
|
|
1892
2014
|
}
|
|
2015
|
+
assertExternalTools(tools) {
|
|
2016
|
+
const result = this.validateExternalTools(tools ?? []);
|
|
2017
|
+
if (!result.isValid) {
|
|
2018
|
+
throw new ExternalToolValidationError(this.agentDefinition.name || this.agentDefinition.id, result);
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
getRequiredExternalTools() {
|
|
2022
|
+
const toolConfig = this.resolveToolConfig();
|
|
2023
|
+
if (!toolConfig?.external || !Array.isArray(toolConfig.external)) {
|
|
2024
|
+
return [];
|
|
2025
|
+
}
|
|
2026
|
+
if (toolConfig.external.includes("*")) {
|
|
2027
|
+
return [];
|
|
2028
|
+
}
|
|
2029
|
+
return toolConfig.external.filter((tool) => typeof tool === "string" && tool.trim().length > 0);
|
|
2030
|
+
}
|
|
2031
|
+
resolveToolConfig() {
|
|
2032
|
+
const root = this.agentDefinition;
|
|
2033
|
+
return this.extractToolConfig(root) || this.extractToolConfig(root?.agent) || this.extractToolConfig(root?.definition);
|
|
2034
|
+
}
|
|
2035
|
+
extractToolConfig(candidate) {
|
|
2036
|
+
if (!candidate) return null;
|
|
2037
|
+
const tools = candidate.tools;
|
|
2038
|
+
if (!tools || Array.isArray(tools) || typeof tools !== "object") {
|
|
2039
|
+
return null;
|
|
2040
|
+
}
|
|
2041
|
+
return tools;
|
|
2042
|
+
}
|
|
2043
|
+
formatExternalToolValidationMessage(requiredTools, missingTools) {
|
|
2044
|
+
const requiredList = requiredTools.join(", ");
|
|
2045
|
+
const missingList = missingTools.join(", ");
|
|
2046
|
+
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}.`;
|
|
2047
|
+
}
|
|
1893
2048
|
/**
|
|
1894
2049
|
* Register multiple hooks at once.
|
|
1895
2050
|
*/
|
|
@@ -1906,12 +2061,13 @@ var Agent = class _Agent {
|
|
|
1906
2061
|
*/
|
|
1907
2062
|
static async create(agentIdOrDef, client) {
|
|
1908
2063
|
const agentDefinition = typeof agentIdOrDef === "string" ? await client.getAgent(agentIdOrDef) : agentIdOrDef;
|
|
2064
|
+
const tools = agentDefinition?.resolved_tools || [];
|
|
1909
2065
|
console.log("\u{1F916} Agent definition loaded:", {
|
|
1910
2066
|
id: agentDefinition.id,
|
|
1911
2067
|
name: agentDefinition.name,
|
|
1912
|
-
tools:
|
|
2068
|
+
tools: tools.map((t) => ({
|
|
1913
2069
|
name: t.name,
|
|
1914
|
-
type:
|
|
2070
|
+
type: "function"
|
|
1915
2071
|
})) || [],
|
|
1916
2072
|
toolCount: agentDefinition.tools?.length || 0
|
|
1917
2073
|
});
|
|
@@ -1940,6 +2096,7 @@ var Agent = class _Agent {
|
|
|
1940
2096
|
DEFAULT_BASE_URL,
|
|
1941
2097
|
DistriClient,
|
|
1942
2098
|
DistriError,
|
|
2099
|
+
ExternalToolValidationError,
|
|
1943
2100
|
convertA2AMessageToDistri,
|
|
1944
2101
|
convertA2APartToDistri,
|
|
1945
2102
|
convertA2AStatusUpdateToDistri,
|