@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.mjs
CHANGED
|
@@ -681,6 +681,17 @@ function convertA2AStatusUpdateToDistri(statusUpdate) {
|
|
|
681
681
|
};
|
|
682
682
|
return hookRequested;
|
|
683
683
|
}
|
|
684
|
+
case "browser_session_started": {
|
|
685
|
+
const browserSessionStarted = {
|
|
686
|
+
type: "browser_session_started",
|
|
687
|
+
data: {
|
|
688
|
+
session_id: metadata.session_id || "",
|
|
689
|
+
viewer_url: metadata.viewer_url,
|
|
690
|
+
stream_url: metadata.stream_url
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
return browserSessionStarted;
|
|
694
|
+
}
|
|
684
695
|
default: {
|
|
685
696
|
console.warn(`Unhandled status update metadata type: ${metadata.type}`, metadata);
|
|
686
697
|
const defaultResult = {
|
|
@@ -860,21 +871,29 @@ var _DistriClient = class _DistriClient {
|
|
|
860
871
|
this.tokenRefreshSkewMs = config.tokenRefreshSkewMs ?? 6e4;
|
|
861
872
|
this.onTokenRefresh = config.onTokenRefresh;
|
|
862
873
|
this.config = {
|
|
863
|
-
baseUrl: config.baseUrl
|
|
874
|
+
baseUrl: config.baseUrl?.replace(/\/$/, "") || DEFAULT_BASE_URL,
|
|
864
875
|
apiVersion: config.apiVersion || "v1",
|
|
865
|
-
timeout: config.timeout
|
|
866
|
-
retryAttempts: config.retryAttempts
|
|
867
|
-
retryDelay: config.retryDelay
|
|
868
|
-
debug: config.debug
|
|
876
|
+
timeout: config.timeout ?? 3e4,
|
|
877
|
+
retryAttempts: config.retryAttempts ?? 3,
|
|
878
|
+
retryDelay: config.retryDelay ?? 1e3,
|
|
879
|
+
debug: config.debug ?? false,
|
|
869
880
|
headers,
|
|
870
|
-
interceptor: config.interceptor
|
|
881
|
+
interceptor: config.interceptor ?? (async (init) => Promise.resolve(init)),
|
|
882
|
+
onTokenRefresh: config.onTokenRefresh,
|
|
883
|
+
clientId: config.clientId
|
|
871
884
|
};
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Get the configured client ID.
|
|
888
|
+
*/
|
|
889
|
+
get clientId() {
|
|
890
|
+
return this.config.clientId;
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* Set the client ID for embed token issuance.
|
|
894
|
+
*/
|
|
895
|
+
set clientId(value) {
|
|
896
|
+
this.config.clientId = value;
|
|
878
897
|
}
|
|
879
898
|
/**
|
|
880
899
|
* Create a client with default cloud configuration.
|
|
@@ -907,7 +926,7 @@ var _DistriClient = class _DistriClient {
|
|
|
907
926
|
if (expiry) {
|
|
908
927
|
body.expiry = typeof expiry === "string" ? expiry : expiry.toISOString();
|
|
909
928
|
}
|
|
910
|
-
const resp = await this.fetch(`/
|
|
929
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values`, {
|
|
911
930
|
method: "POST",
|
|
912
931
|
headers: {
|
|
913
932
|
"Content-Type": "application/json",
|
|
@@ -924,7 +943,7 @@ var _DistriClient = class _DistriClient {
|
|
|
924
943
|
* Session store: get a single value
|
|
925
944
|
*/
|
|
926
945
|
async getSessionValue(sessionId, key) {
|
|
927
|
-
const resp = await this.fetch(`/
|
|
946
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
|
|
928
947
|
method: "GET",
|
|
929
948
|
headers: {
|
|
930
949
|
...this.config.headers
|
|
@@ -941,7 +960,7 @@ var _DistriClient = class _DistriClient {
|
|
|
941
960
|
* Session store: get all values in a session
|
|
942
961
|
*/
|
|
943
962
|
async getSessionValues(sessionId) {
|
|
944
|
-
const resp = await this.fetch(`/
|
|
963
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values`, {
|
|
945
964
|
method: "GET",
|
|
946
965
|
headers: {
|
|
947
966
|
...this.config.headers
|
|
@@ -958,7 +977,7 @@ var _DistriClient = class _DistriClient {
|
|
|
958
977
|
* Session store: delete a single key
|
|
959
978
|
*/
|
|
960
979
|
async deleteSessionValue(sessionId, key) {
|
|
961
|
-
const resp = await this.fetch(`/
|
|
980
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
|
|
962
981
|
method: "DELETE",
|
|
963
982
|
headers: {
|
|
964
983
|
...this.config.headers
|
|
@@ -973,7 +992,7 @@ var _DistriClient = class _DistriClient {
|
|
|
973
992
|
* Session store: clear all keys in a session
|
|
974
993
|
*/
|
|
975
994
|
async clearSession(sessionId) {
|
|
976
|
-
const resp = await this.fetch(`/
|
|
995
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}`, {
|
|
977
996
|
method: "DELETE",
|
|
978
997
|
headers: {
|
|
979
998
|
...this.config.headers
|
|
@@ -984,30 +1003,6 @@ var _DistriClient = class _DistriClient {
|
|
|
984
1003
|
throw new ApiError(errorData.error || "Failed to clear session", resp.status);
|
|
985
1004
|
}
|
|
986
1005
|
}
|
|
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
1006
|
/**
|
|
1012
1007
|
* Issue an access token + refresh token for temporary authentication.
|
|
1013
1008
|
* Requires an existing authenticated session (bearer token).
|
|
@@ -1037,7 +1032,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1037
1032
|
if (!tokens?.access_token || !tokens?.refresh_token || typeof tokens?.expires_at !== "number") {
|
|
1038
1033
|
throw new ApiError("Invalid token response", response.status);
|
|
1039
1034
|
}
|
|
1040
|
-
this.applyTokens(tokens.access_token, tokens.refresh_token
|
|
1035
|
+
this.applyTokens(tokens.access_token, tokens.refresh_token);
|
|
1041
1036
|
return tokens;
|
|
1042
1037
|
}
|
|
1043
1038
|
/**
|
|
@@ -1050,13 +1045,18 @@ var _DistriClient = class _DistriClient {
|
|
|
1050
1045
|
* Update the access/refresh tokens in memory.
|
|
1051
1046
|
*/
|
|
1052
1047
|
setTokens(tokens) {
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
}
|
|
1056
|
-
if (tokens.refreshToken !== void 0) {
|
|
1048
|
+
this.accessToken = tokens.accessToken;
|
|
1049
|
+
if (tokens.refreshToken) {
|
|
1057
1050
|
this.refreshToken = tokens.refreshToken;
|
|
1058
1051
|
}
|
|
1059
1052
|
}
|
|
1053
|
+
/**
|
|
1054
|
+
* Reset all authentication tokens.
|
|
1055
|
+
*/
|
|
1056
|
+
resetTokens() {
|
|
1057
|
+
this.accessToken = void 0;
|
|
1058
|
+
this.refreshToken = void 0;
|
|
1059
|
+
}
|
|
1060
1060
|
/**
|
|
1061
1061
|
* Start streaming speech-to-text transcription via WebSocket
|
|
1062
1062
|
*/
|
|
@@ -1274,6 +1274,31 @@ var _DistriClient = class _DistriClient {
|
|
|
1274
1274
|
throw new DistriError(`Failed to fetch agent ${agentId}`, "FETCH_ERROR", error);
|
|
1275
1275
|
}
|
|
1276
1276
|
}
|
|
1277
|
+
/**
|
|
1278
|
+
* Update an agent's definition (markdown only)
|
|
1279
|
+
*/
|
|
1280
|
+
async updateAgent(agentId, update) {
|
|
1281
|
+
try {
|
|
1282
|
+
const response = await this.fetch(`/agents/${agentId}`, {
|
|
1283
|
+
method: "PUT",
|
|
1284
|
+
headers: {
|
|
1285
|
+
"Content-Type": "application/json",
|
|
1286
|
+
...this.config.headers
|
|
1287
|
+
},
|
|
1288
|
+
body: JSON.stringify(update)
|
|
1289
|
+
});
|
|
1290
|
+
if (!response.ok) {
|
|
1291
|
+
if (response.status === 404) {
|
|
1292
|
+
throw new ApiError(`Agent not found: ${agentId}`, 404);
|
|
1293
|
+
}
|
|
1294
|
+
throw new ApiError(`Failed to update agent: ${response.statusText}`, response.status);
|
|
1295
|
+
}
|
|
1296
|
+
return await response.json();
|
|
1297
|
+
} catch (error) {
|
|
1298
|
+
if (error instanceof ApiError) throw error;
|
|
1299
|
+
throw new DistriError(`Failed to update agent ${agentId}`, "UPDATE_ERROR", error);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1277
1302
|
/**
|
|
1278
1303
|
* Get or create A2AClient for an agent
|
|
1279
1304
|
*/
|
|
@@ -1359,11 +1384,22 @@ var _DistriClient = class _DistriClient {
|
|
|
1359
1384
|
}
|
|
1360
1385
|
}
|
|
1361
1386
|
/**
|
|
1362
|
-
* Get threads from Distri server
|
|
1387
|
+
* Get threads from Distri server with filtering and pagination
|
|
1363
1388
|
*/
|
|
1364
|
-
async getThreads() {
|
|
1389
|
+
async getThreads(params = {}) {
|
|
1365
1390
|
try {
|
|
1366
|
-
const
|
|
1391
|
+
const searchParams = new URLSearchParams();
|
|
1392
|
+
if (params.agent_id) searchParams.set("agent_id", params.agent_id);
|
|
1393
|
+
if (params.external_id) searchParams.set("external_id", params.external_id);
|
|
1394
|
+
if (params.search) searchParams.set("search", params.search);
|
|
1395
|
+
if (params.from_date) searchParams.set("from_date", params.from_date);
|
|
1396
|
+
if (params.to_date) searchParams.set("to_date", params.to_date);
|
|
1397
|
+
if (params.tags?.length) searchParams.set("tags", params.tags.join(","));
|
|
1398
|
+
if (params.limit !== void 0) searchParams.set("limit", params.limit.toString());
|
|
1399
|
+
if (params.offset !== void 0) searchParams.set("offset", params.offset.toString());
|
|
1400
|
+
const queryString = searchParams.toString();
|
|
1401
|
+
const url = queryString ? `/threads?${queryString}` : "/threads";
|
|
1402
|
+
const response = await this.fetch(url);
|
|
1367
1403
|
if (!response.ok) {
|
|
1368
1404
|
throw new ApiError(`Failed to fetch threads: ${response.statusText}`, response.status);
|
|
1369
1405
|
}
|
|
@@ -1373,6 +1409,39 @@ var _DistriClient = class _DistriClient {
|
|
|
1373
1409
|
throw new DistriError("Failed to fetch threads", "FETCH_ERROR", error);
|
|
1374
1410
|
}
|
|
1375
1411
|
}
|
|
1412
|
+
/**
|
|
1413
|
+
* Get agents sorted by thread count (most active first)
|
|
1414
|
+
*/
|
|
1415
|
+
async getAgentsByUsage() {
|
|
1416
|
+
try {
|
|
1417
|
+
const response = await this.fetch("/threads/agents");
|
|
1418
|
+
if (!response.ok) {
|
|
1419
|
+
throw new ApiError(`Failed to fetch agents by usage: ${response.statusText}`, response.status);
|
|
1420
|
+
}
|
|
1421
|
+
return await response.json();
|
|
1422
|
+
} catch (error) {
|
|
1423
|
+
if (error instanceof ApiError) throw error;
|
|
1424
|
+
throw new DistriError("Failed to fetch agents by usage", "FETCH_ERROR", error);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
/**
|
|
1428
|
+
* Create a new browser session
|
|
1429
|
+
* Returns session info including viewer_url and stream_url from browsr
|
|
1430
|
+
*/
|
|
1431
|
+
async createBrowserSession() {
|
|
1432
|
+
try {
|
|
1433
|
+
const response = await this.fetch("/browser/session", {
|
|
1434
|
+
method: "POST"
|
|
1435
|
+
});
|
|
1436
|
+
if (!response.ok) {
|
|
1437
|
+
throw new ApiError(`Failed to create browser session: ${response.statusText}`, response.status);
|
|
1438
|
+
}
|
|
1439
|
+
return await response.json();
|
|
1440
|
+
} catch (error) {
|
|
1441
|
+
if (error instanceof ApiError) throw error;
|
|
1442
|
+
throw new DistriError("Failed to create browser session", "FETCH_ERROR", error);
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1376
1445
|
async getThread(threadId) {
|
|
1377
1446
|
try {
|
|
1378
1447
|
const response = await this.fetch(`/threads/${threadId}`);
|
|
@@ -1472,15 +1541,17 @@ var _DistriClient = class _DistriClient {
|
|
|
1472
1541
|
get baseUrl() {
|
|
1473
1542
|
return this.config.baseUrl;
|
|
1474
1543
|
}
|
|
1475
|
-
applyTokens(accessToken, refreshToken
|
|
1544
|
+
applyTokens(accessToken, refreshToken) {
|
|
1476
1545
|
this.accessToken = accessToken;
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
this.onTokenRefresh({ accessToken, refreshToken });
|
|
1546
|
+
if (refreshToken) {
|
|
1547
|
+
this.refreshToken = refreshToken;
|
|
1480
1548
|
}
|
|
1481
1549
|
}
|
|
1550
|
+
/**
|
|
1551
|
+
* Ensure access token is valid, refreshing if necessary
|
|
1552
|
+
*/
|
|
1482
1553
|
async ensureAccessToken() {
|
|
1483
|
-
if (!this.refreshToken) {
|
|
1554
|
+
if (!this.refreshToken && !this.onTokenRefresh) {
|
|
1484
1555
|
return;
|
|
1485
1556
|
}
|
|
1486
1557
|
if (!this.accessToken || this.isTokenExpiring(this.accessToken)) {
|
|
@@ -1492,7 +1563,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1492
1563
|
}
|
|
1493
1564
|
}
|
|
1494
1565
|
async refreshTokens() {
|
|
1495
|
-
if (!this.refreshToken) {
|
|
1566
|
+
if (!this.refreshToken && !this.onTokenRefresh) {
|
|
1496
1567
|
return;
|
|
1497
1568
|
}
|
|
1498
1569
|
if (!this.refreshPromise) {
|
|
@@ -1503,6 +1574,17 @@ var _DistriClient = class _DistriClient {
|
|
|
1503
1574
|
return this.refreshPromise;
|
|
1504
1575
|
}
|
|
1505
1576
|
async performTokenRefresh() {
|
|
1577
|
+
if (this.onTokenRefresh) {
|
|
1578
|
+
this.accessToken = void 0;
|
|
1579
|
+
const newToken = await this.onTokenRefresh();
|
|
1580
|
+
if (newToken) {
|
|
1581
|
+
this.applyTokens(newToken);
|
|
1582
|
+
return;
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
if (!this.refreshToken) {
|
|
1586
|
+
return;
|
|
1587
|
+
}
|
|
1506
1588
|
const response = await this.fetchAbsolute(
|
|
1507
1589
|
`${this.config.baseUrl}/token`,
|
|
1508
1590
|
{
|
|
@@ -1526,7 +1608,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1526
1608
|
if (!tokens?.access_token || !tokens?.refresh_token) {
|
|
1527
1609
|
throw new ApiError("Invalid token response", response.status);
|
|
1528
1610
|
}
|
|
1529
|
-
this.applyTokens(tokens.access_token, tokens.refresh_token
|
|
1611
|
+
this.applyTokens(tokens.access_token, tokens.refresh_token);
|
|
1530
1612
|
}
|
|
1531
1613
|
isTokenExpiring(token) {
|
|
1532
1614
|
const expiresAt = this.getTokenExpiry(token);
|
|
@@ -1621,7 +1703,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1621
1703
|
headers
|
|
1622
1704
|
});
|
|
1623
1705
|
clearTimeout(timeoutId);
|
|
1624
|
-
if (!skipAuth && retryOnAuth && response.status === 401 && this.refreshToken) {
|
|
1706
|
+
if (!skipAuth && retryOnAuth && response.status === 401 && (this.refreshToken || this.onTokenRefresh)) {
|
|
1625
1707
|
const refreshed = await this.refreshTokens().then(() => true).catch(() => false);
|
|
1626
1708
|
if (refreshed) {
|
|
1627
1709
|
return this.fetchAbsolute(url, initialInit, { skipAuth, retryOnAuth: false });
|
|
@@ -1639,7 +1721,8 @@ var _DistriClient = class _DistriClient {
|
|
|
1639
1721
|
throw lastError;
|
|
1640
1722
|
}
|
|
1641
1723
|
/**
|
|
1642
|
-
* Enhanced fetch with retry logic
|
|
1724
|
+
* Enhanced fetch with retry logic and auth headers.
|
|
1725
|
+
* Exposed publicly for extensions like DistriHomeClient.
|
|
1643
1726
|
*/
|
|
1644
1727
|
async fetch(input, initialInit) {
|
|
1645
1728
|
const url = `${this.config.baseUrl}${input}`;
|
|
@@ -1712,13 +1795,6 @@ var _DistriClient = class _DistriClient {
|
|
|
1712
1795
|
}
|
|
1713
1796
|
};
|
|
1714
1797
|
// ============================================================
|
|
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
1798
|
// Token API
|
|
1723
1799
|
// ============================================================
|
|
1724
1800
|
// Issue access + refresh tokens for temporary authentication (e.g., frontend use)
|
|
@@ -1744,6 +1820,25 @@ function uuidv4() {
|
|
|
1744
1820
|
}
|
|
1745
1821
|
|
|
1746
1822
|
// src/agent.ts
|
|
1823
|
+
var ExternalToolValidationError = class extends DistriError {
|
|
1824
|
+
constructor(agentName, result) {
|
|
1825
|
+
super(
|
|
1826
|
+
result.message || "Missing required external tools for agent invocation.",
|
|
1827
|
+
"EXTERNAL_TOOL_VALIDATION_ERROR",
|
|
1828
|
+
{
|
|
1829
|
+
agentName,
|
|
1830
|
+
missingTools: result.missingTools,
|
|
1831
|
+
requiredTools: result.requiredTools,
|
|
1832
|
+
providedTools: result.providedTools
|
|
1833
|
+
}
|
|
1834
|
+
);
|
|
1835
|
+
this.name = "ExternalToolValidationError";
|
|
1836
|
+
this.agentName = agentName;
|
|
1837
|
+
this.missingTools = result.missingTools;
|
|
1838
|
+
this.requiredTools = result.requiredTools;
|
|
1839
|
+
this.providedTools = result.providedTools;
|
|
1840
|
+
}
|
|
1841
|
+
};
|
|
1747
1842
|
var Agent = class _Agent {
|
|
1748
1843
|
constructor(agentDefinition, client) {
|
|
1749
1844
|
this.hookHandlers = /* @__PURE__ */ new Map();
|
|
@@ -1764,7 +1859,7 @@ var Agent = class _Agent {
|
|
|
1764
1859
|
return this.agentDefinition.description;
|
|
1765
1860
|
}
|
|
1766
1861
|
get agentType() {
|
|
1767
|
-
return this.agentDefinition.agent_type
|
|
1862
|
+
return this.agentDefinition.agent_type;
|
|
1768
1863
|
}
|
|
1769
1864
|
get iconUrl() {
|
|
1770
1865
|
return this.agentDefinition.icon_url;
|
|
@@ -1801,7 +1896,7 @@ var Agent = class _Agent {
|
|
|
1801
1896
|
const enhancedParams = this.enhanceParamsWithTools(params, tools);
|
|
1802
1897
|
const a2aStream = this.client.sendMessageStream(this.agentDefinition.id, enhancedParams);
|
|
1803
1898
|
const self = this;
|
|
1804
|
-
return
|
|
1899
|
+
return async function* () {
|
|
1805
1900
|
for await (const event of a2aStream) {
|
|
1806
1901
|
const converted = decodeA2AStreamEvent(event);
|
|
1807
1902
|
if (converted && converted.type === "inline_hook_requested") {
|
|
@@ -1822,12 +1917,38 @@ var Agent = class _Agent {
|
|
|
1822
1917
|
yield converted;
|
|
1823
1918
|
}
|
|
1824
1919
|
}
|
|
1825
|
-
}
|
|
1920
|
+
}();
|
|
1921
|
+
}
|
|
1922
|
+
/**
|
|
1923
|
+
* Validate that required external tools are registered before invoking.
|
|
1924
|
+
*/
|
|
1925
|
+
validateExternalTools(tools = []) {
|
|
1926
|
+
const requiredTools = this.getRequiredExternalTools();
|
|
1927
|
+
const providedTools = tools.map((tool) => tool.name);
|
|
1928
|
+
if (requiredTools.length === 0) {
|
|
1929
|
+
return {
|
|
1930
|
+
isValid: true,
|
|
1931
|
+
requiredTools: [],
|
|
1932
|
+
providedTools,
|
|
1933
|
+
missingTools: []
|
|
1934
|
+
};
|
|
1935
|
+
}
|
|
1936
|
+
const providedSet = new Set(providedTools);
|
|
1937
|
+
const missingTools = requiredTools.filter((tool) => !providedSet.has(tool));
|
|
1938
|
+
const isValid = missingTools.length === 0;
|
|
1939
|
+
return {
|
|
1940
|
+
isValid,
|
|
1941
|
+
requiredTools,
|
|
1942
|
+
providedTools,
|
|
1943
|
+
missingTools,
|
|
1944
|
+
message: isValid ? void 0 : this.formatExternalToolValidationMessage(requiredTools, missingTools)
|
|
1945
|
+
};
|
|
1826
1946
|
}
|
|
1827
1947
|
/**
|
|
1828
1948
|
* Enhance message params with tool definitions
|
|
1829
1949
|
*/
|
|
1830
1950
|
enhanceParamsWithTools(params, tools) {
|
|
1951
|
+
this.assertExternalTools(tools);
|
|
1831
1952
|
const metadata = {
|
|
1832
1953
|
...params.metadata,
|
|
1833
1954
|
external_tools: tools?.map((tool) => ({
|
|
@@ -1842,6 +1963,39 @@ var Agent = class _Agent {
|
|
|
1842
1963
|
metadata
|
|
1843
1964
|
};
|
|
1844
1965
|
}
|
|
1966
|
+
assertExternalTools(tools) {
|
|
1967
|
+
const result = this.validateExternalTools(tools ?? []);
|
|
1968
|
+
if (!result.isValid) {
|
|
1969
|
+
throw new ExternalToolValidationError(this.agentDefinition.name || this.agentDefinition.id, result);
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
getRequiredExternalTools() {
|
|
1973
|
+
const toolConfig = this.resolveToolConfig();
|
|
1974
|
+
if (!toolConfig?.external || !Array.isArray(toolConfig.external)) {
|
|
1975
|
+
return [];
|
|
1976
|
+
}
|
|
1977
|
+
if (toolConfig.external.includes("*")) {
|
|
1978
|
+
return [];
|
|
1979
|
+
}
|
|
1980
|
+
return toolConfig.external.filter((tool) => typeof tool === "string" && tool.trim().length > 0);
|
|
1981
|
+
}
|
|
1982
|
+
resolveToolConfig() {
|
|
1983
|
+
const root = this.agentDefinition;
|
|
1984
|
+
return this.extractToolConfig(root) || this.extractToolConfig(root?.agent) || this.extractToolConfig(root?.definition);
|
|
1985
|
+
}
|
|
1986
|
+
extractToolConfig(candidate) {
|
|
1987
|
+
if (!candidate) return null;
|
|
1988
|
+
const tools = candidate.tools;
|
|
1989
|
+
if (!tools || Array.isArray(tools) || typeof tools !== "object") {
|
|
1990
|
+
return null;
|
|
1991
|
+
}
|
|
1992
|
+
return tools;
|
|
1993
|
+
}
|
|
1994
|
+
formatExternalToolValidationMessage(requiredTools, missingTools) {
|
|
1995
|
+
const requiredList = requiredTools.join(", ");
|
|
1996
|
+
const missingList = missingTools.join(", ");
|
|
1997
|
+
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}.`;
|
|
1998
|
+
}
|
|
1845
1999
|
/**
|
|
1846
2000
|
* Register multiple hooks at once.
|
|
1847
2001
|
*/
|
|
@@ -1858,12 +2012,13 @@ var Agent = class _Agent {
|
|
|
1858
2012
|
*/
|
|
1859
2013
|
static async create(agentIdOrDef, client) {
|
|
1860
2014
|
const agentDefinition = typeof agentIdOrDef === "string" ? await client.getAgent(agentIdOrDef) : agentIdOrDef;
|
|
2015
|
+
const tools = agentDefinition?.resolved_tools || [];
|
|
1861
2016
|
console.log("\u{1F916} Agent definition loaded:", {
|
|
1862
2017
|
id: agentDefinition.id,
|
|
1863
2018
|
name: agentDefinition.name,
|
|
1864
|
-
tools:
|
|
2019
|
+
tools: tools.map((t) => ({
|
|
1865
2020
|
name: t.name,
|
|
1866
|
-
type:
|
|
2021
|
+
type: "function"
|
|
1867
2022
|
})) || [],
|
|
1868
2023
|
toolCount: agentDefinition.tools?.length || 0
|
|
1869
2024
|
});
|
|
@@ -1891,6 +2046,7 @@ export {
|
|
|
1891
2046
|
DEFAULT_BASE_URL,
|
|
1892
2047
|
DistriClient,
|
|
1893
2048
|
DistriError,
|
|
2049
|
+
ExternalToolValidationError,
|
|
1894
2050
|
convertA2AMessageToDistri,
|
|
1895
2051
|
convertA2APartToDistri,
|
|
1896
2052
|
convertA2AStatusUpdateToDistri,
|