@distri/core 0.3.1 → 0.3.3
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 +168 -40
- package/dist/index.d.ts +168 -40
- package/dist/index.js +289 -71
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +288 -71
- 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 = {
|
|
@@ -759,6 +770,7 @@ function convertDistriMessageToA2A(distriMessage, context) {
|
|
|
759
770
|
break;
|
|
760
771
|
case "system":
|
|
761
772
|
case "tool":
|
|
773
|
+
case "developer":
|
|
762
774
|
role = "user";
|
|
763
775
|
break;
|
|
764
776
|
default:
|
|
@@ -855,26 +867,56 @@ var _DistriClient = class _DistriClient {
|
|
|
855
867
|
constructor(config) {
|
|
856
868
|
this.agentClients = /* @__PURE__ */ new Map();
|
|
857
869
|
const headers = { ...config.headers };
|
|
870
|
+
if (config.workspaceId) {
|
|
871
|
+
headers["X-Workspace-Id"] = config.workspaceId;
|
|
872
|
+
}
|
|
858
873
|
this.accessToken = config.accessToken;
|
|
859
874
|
this.refreshToken = config.refreshToken;
|
|
860
875
|
this.tokenRefreshSkewMs = config.tokenRefreshSkewMs ?? 6e4;
|
|
861
876
|
this.onTokenRefresh = config.onTokenRefresh;
|
|
862
877
|
this.config = {
|
|
863
|
-
baseUrl: config.baseUrl
|
|
878
|
+
baseUrl: config.baseUrl?.replace(/\/$/, "") || DEFAULT_BASE_URL,
|
|
864
879
|
apiVersion: config.apiVersion || "v1",
|
|
865
|
-
timeout: config.timeout
|
|
866
|
-
retryAttempts: config.retryAttempts
|
|
867
|
-
retryDelay: config.retryDelay
|
|
868
|
-
debug: config.debug
|
|
880
|
+
timeout: config.timeout ?? 3e4,
|
|
881
|
+
retryAttempts: config.retryAttempts ?? 3,
|
|
882
|
+
retryDelay: config.retryDelay ?? 1e3,
|
|
883
|
+
debug: config.debug ?? false,
|
|
869
884
|
headers,
|
|
870
|
-
interceptor: config.interceptor
|
|
885
|
+
interceptor: config.interceptor ?? (async (init) => Promise.resolve(init)),
|
|
886
|
+
onTokenRefresh: config.onTokenRefresh,
|
|
887
|
+
clientId: config.clientId,
|
|
888
|
+
workspaceId: config.workspaceId
|
|
871
889
|
};
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* Get the configured client ID.
|
|
893
|
+
*/
|
|
894
|
+
get clientId() {
|
|
895
|
+
return this.config.clientId;
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Set the client ID for embed token issuance.
|
|
899
|
+
*/
|
|
900
|
+
set clientId(value) {
|
|
901
|
+
this.config.clientId = value;
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Get the configured workspace ID.
|
|
905
|
+
*/
|
|
906
|
+
get workspaceId() {
|
|
907
|
+
return this.config.workspaceId;
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* Set the workspace ID for multi-tenant support.
|
|
911
|
+
* Updates the X-Workspace-Id header for all subsequent requests.
|
|
912
|
+
*/
|
|
913
|
+
set workspaceId(value) {
|
|
914
|
+
this.config.workspaceId = value;
|
|
915
|
+
if (value) {
|
|
916
|
+
this.config.headers["X-Workspace-Id"] = value;
|
|
917
|
+
} else {
|
|
918
|
+
delete this.config.headers["X-Workspace-Id"];
|
|
919
|
+
}
|
|
878
920
|
}
|
|
879
921
|
/**
|
|
880
922
|
* Create a client with default cloud configuration.
|
|
@@ -907,7 +949,7 @@ var _DistriClient = class _DistriClient {
|
|
|
907
949
|
if (expiry) {
|
|
908
950
|
body.expiry = typeof expiry === "string" ? expiry : expiry.toISOString();
|
|
909
951
|
}
|
|
910
|
-
const resp = await this.fetch(`/
|
|
952
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values`, {
|
|
911
953
|
method: "POST",
|
|
912
954
|
headers: {
|
|
913
955
|
"Content-Type": "application/json",
|
|
@@ -924,7 +966,7 @@ var _DistriClient = class _DistriClient {
|
|
|
924
966
|
* Session store: get a single value
|
|
925
967
|
*/
|
|
926
968
|
async getSessionValue(sessionId, key) {
|
|
927
|
-
const resp = await this.fetch(`/
|
|
969
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
|
|
928
970
|
method: "GET",
|
|
929
971
|
headers: {
|
|
930
972
|
...this.config.headers
|
|
@@ -941,7 +983,7 @@ var _DistriClient = class _DistriClient {
|
|
|
941
983
|
* Session store: get all values in a session
|
|
942
984
|
*/
|
|
943
985
|
async getSessionValues(sessionId) {
|
|
944
|
-
const resp = await this.fetch(`/
|
|
986
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values`, {
|
|
945
987
|
method: "GET",
|
|
946
988
|
headers: {
|
|
947
989
|
...this.config.headers
|
|
@@ -958,7 +1000,7 @@ var _DistriClient = class _DistriClient {
|
|
|
958
1000
|
* Session store: delete a single key
|
|
959
1001
|
*/
|
|
960
1002
|
async deleteSessionValue(sessionId, key) {
|
|
961
|
-
const resp = await this.fetch(`/
|
|
1003
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
|
|
962
1004
|
method: "DELETE",
|
|
963
1005
|
headers: {
|
|
964
1006
|
...this.config.headers
|
|
@@ -973,7 +1015,7 @@ var _DistriClient = class _DistriClient {
|
|
|
973
1015
|
* Session store: clear all keys in a session
|
|
974
1016
|
*/
|
|
975
1017
|
async clearSession(sessionId) {
|
|
976
|
-
const resp = await this.fetch(`/
|
|
1018
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}`, {
|
|
977
1019
|
method: "DELETE",
|
|
978
1020
|
headers: {
|
|
979
1021
|
...this.config.headers
|
|
@@ -984,30 +1026,6 @@ var _DistriClient = class _DistriClient {
|
|
|
984
1026
|
throw new ApiError(errorData.error || "Failed to clear session", resp.status);
|
|
985
1027
|
}
|
|
986
1028
|
}
|
|
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
1029
|
/**
|
|
1012
1030
|
* Issue an access token + refresh token for temporary authentication.
|
|
1013
1031
|
* Requires an existing authenticated session (bearer token).
|
|
@@ -1037,7 +1055,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1037
1055
|
if (!tokens?.access_token || !tokens?.refresh_token || typeof tokens?.expires_at !== "number") {
|
|
1038
1056
|
throw new ApiError("Invalid token response", response.status);
|
|
1039
1057
|
}
|
|
1040
|
-
this.applyTokens(tokens.access_token, tokens.refresh_token
|
|
1058
|
+
this.applyTokens(tokens.access_token, tokens.refresh_token);
|
|
1041
1059
|
return tokens;
|
|
1042
1060
|
}
|
|
1043
1061
|
/**
|
|
@@ -1050,13 +1068,18 @@ var _DistriClient = class _DistriClient {
|
|
|
1050
1068
|
* Update the access/refresh tokens in memory.
|
|
1051
1069
|
*/
|
|
1052
1070
|
setTokens(tokens) {
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
}
|
|
1056
|
-
if (tokens.refreshToken !== void 0) {
|
|
1071
|
+
this.accessToken = tokens.accessToken;
|
|
1072
|
+
if (tokens.refreshToken) {
|
|
1057
1073
|
this.refreshToken = tokens.refreshToken;
|
|
1058
1074
|
}
|
|
1059
1075
|
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Reset all authentication tokens.
|
|
1078
|
+
*/
|
|
1079
|
+
resetTokens() {
|
|
1080
|
+
this.accessToken = void 0;
|
|
1081
|
+
this.refreshToken = void 0;
|
|
1082
|
+
}
|
|
1060
1083
|
/**
|
|
1061
1084
|
* Start streaming speech-to-text transcription via WebSocket
|
|
1062
1085
|
*/
|
|
@@ -1274,6 +1297,31 @@ var _DistriClient = class _DistriClient {
|
|
|
1274
1297
|
throw new DistriError(`Failed to fetch agent ${agentId}`, "FETCH_ERROR", error);
|
|
1275
1298
|
}
|
|
1276
1299
|
}
|
|
1300
|
+
/**
|
|
1301
|
+
* Update an agent's definition (markdown only)
|
|
1302
|
+
*/
|
|
1303
|
+
async updateAgent(agentId, update) {
|
|
1304
|
+
try {
|
|
1305
|
+
const response = await this.fetch(`/agents/${agentId}`, {
|
|
1306
|
+
method: "PUT",
|
|
1307
|
+
headers: {
|
|
1308
|
+
"Content-Type": "application/json",
|
|
1309
|
+
...this.config.headers
|
|
1310
|
+
},
|
|
1311
|
+
body: JSON.stringify(update)
|
|
1312
|
+
});
|
|
1313
|
+
if (!response.ok) {
|
|
1314
|
+
if (response.status === 404) {
|
|
1315
|
+
throw new ApiError(`Agent not found: ${agentId}`, 404);
|
|
1316
|
+
}
|
|
1317
|
+
throw new ApiError(`Failed to update agent: ${response.statusText}`, response.status);
|
|
1318
|
+
}
|
|
1319
|
+
return await response.json();
|
|
1320
|
+
} catch (error) {
|
|
1321
|
+
if (error instanceof ApiError) throw error;
|
|
1322
|
+
throw new DistriError(`Failed to update agent ${agentId}`, "UPDATE_ERROR", error);
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1277
1325
|
/**
|
|
1278
1326
|
* Get or create A2AClient for an agent
|
|
1279
1327
|
*/
|
|
@@ -1322,8 +1370,46 @@ var _DistriClient = class _DistriClient {
|
|
|
1322
1370
|
yield* await client.sendMessageStream(params);
|
|
1323
1371
|
} catch (error) {
|
|
1324
1372
|
console.error(error);
|
|
1325
|
-
|
|
1373
|
+
const errorMessage = this.extractErrorMessage(error);
|
|
1374
|
+
throw new DistriError(errorMessage, "STREAM_MESSAGE_ERROR", error);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Extract a user-friendly error message from potentially nested errors
|
|
1379
|
+
*/
|
|
1380
|
+
extractErrorMessage(error) {
|
|
1381
|
+
if (!error) return "Unknown error occurred";
|
|
1382
|
+
if (typeof error === "object" && error !== null) {
|
|
1383
|
+
const err = error;
|
|
1384
|
+
if (err.error && typeof err.error === "object") {
|
|
1385
|
+
const jsonRpcError = err.error;
|
|
1386
|
+
if (typeof jsonRpcError.message === "string") {
|
|
1387
|
+
return jsonRpcError.message;
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
if (err.message && typeof err.message === "string") {
|
|
1391
|
+
return err.message;
|
|
1392
|
+
}
|
|
1393
|
+
if (err.details && typeof err.details === "object") {
|
|
1394
|
+
const details = err.details;
|
|
1395
|
+
if (details.message && typeof details.message === "string") {
|
|
1396
|
+
return details.message;
|
|
1397
|
+
}
|
|
1398
|
+
if (details.error && typeof details.error === "object") {
|
|
1399
|
+
const nestedError = details.error;
|
|
1400
|
+
if (typeof nestedError.message === "string") {
|
|
1401
|
+
return nestedError.message;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
if (err.cause && typeof err.cause === "object") {
|
|
1406
|
+
return this.extractErrorMessage(err.cause);
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
if (error instanceof Error) {
|
|
1410
|
+
return error.message;
|
|
1326
1411
|
}
|
|
1412
|
+
return String(error);
|
|
1327
1413
|
}
|
|
1328
1414
|
/**
|
|
1329
1415
|
* Get task details
|
|
@@ -1359,11 +1445,22 @@ var _DistriClient = class _DistriClient {
|
|
|
1359
1445
|
}
|
|
1360
1446
|
}
|
|
1361
1447
|
/**
|
|
1362
|
-
* Get threads from Distri server
|
|
1448
|
+
* Get threads from Distri server with filtering and pagination
|
|
1363
1449
|
*/
|
|
1364
|
-
async getThreads() {
|
|
1450
|
+
async getThreads(params = {}) {
|
|
1365
1451
|
try {
|
|
1366
|
-
const
|
|
1452
|
+
const searchParams = new URLSearchParams();
|
|
1453
|
+
if (params.agent_id) searchParams.set("agent_id", params.agent_id);
|
|
1454
|
+
if (params.external_id) searchParams.set("external_id", params.external_id);
|
|
1455
|
+
if (params.search) searchParams.set("search", params.search);
|
|
1456
|
+
if (params.from_date) searchParams.set("from_date", params.from_date);
|
|
1457
|
+
if (params.to_date) searchParams.set("to_date", params.to_date);
|
|
1458
|
+
if (params.tags?.length) searchParams.set("tags", params.tags.join(","));
|
|
1459
|
+
if (params.limit !== void 0) searchParams.set("limit", params.limit.toString());
|
|
1460
|
+
if (params.offset !== void 0) searchParams.set("offset", params.offset.toString());
|
|
1461
|
+
const queryString = searchParams.toString();
|
|
1462
|
+
const url = queryString ? `/threads?${queryString}` : "/threads";
|
|
1463
|
+
const response = await this.fetch(url);
|
|
1367
1464
|
if (!response.ok) {
|
|
1368
1465
|
throw new ApiError(`Failed to fetch threads: ${response.statusText}`, response.status);
|
|
1369
1466
|
}
|
|
@@ -1373,6 +1470,39 @@ var _DistriClient = class _DistriClient {
|
|
|
1373
1470
|
throw new DistriError("Failed to fetch threads", "FETCH_ERROR", error);
|
|
1374
1471
|
}
|
|
1375
1472
|
}
|
|
1473
|
+
/**
|
|
1474
|
+
* Get agents sorted by thread count (most active first)
|
|
1475
|
+
*/
|
|
1476
|
+
async getAgentsByUsage() {
|
|
1477
|
+
try {
|
|
1478
|
+
const response = await this.fetch("/threads/agents");
|
|
1479
|
+
if (!response.ok) {
|
|
1480
|
+
throw new ApiError(`Failed to fetch agents by usage: ${response.statusText}`, response.status);
|
|
1481
|
+
}
|
|
1482
|
+
return await response.json();
|
|
1483
|
+
} catch (error) {
|
|
1484
|
+
if (error instanceof ApiError) throw error;
|
|
1485
|
+
throw new DistriError("Failed to fetch agents by usage", "FETCH_ERROR", error);
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
/**
|
|
1489
|
+
* Create a new browser session
|
|
1490
|
+
* Returns session info including viewer_url and stream_url from browsr
|
|
1491
|
+
*/
|
|
1492
|
+
async createBrowserSession() {
|
|
1493
|
+
try {
|
|
1494
|
+
const response = await this.fetch("/browser/session", {
|
|
1495
|
+
method: "POST"
|
|
1496
|
+
});
|
|
1497
|
+
if (!response.ok) {
|
|
1498
|
+
throw new ApiError(`Failed to create browser session: ${response.statusText}`, response.status);
|
|
1499
|
+
}
|
|
1500
|
+
return await response.json();
|
|
1501
|
+
} catch (error) {
|
|
1502
|
+
if (error instanceof ApiError) throw error;
|
|
1503
|
+
throw new DistriError("Failed to create browser session", "FETCH_ERROR", error);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1376
1506
|
async getThread(threadId) {
|
|
1377
1507
|
try {
|
|
1378
1508
|
const response = await this.fetch(`/threads/${threadId}`);
|
|
@@ -1472,15 +1602,17 @@ var _DistriClient = class _DistriClient {
|
|
|
1472
1602
|
get baseUrl() {
|
|
1473
1603
|
return this.config.baseUrl;
|
|
1474
1604
|
}
|
|
1475
|
-
applyTokens(accessToken, refreshToken
|
|
1605
|
+
applyTokens(accessToken, refreshToken) {
|
|
1476
1606
|
this.accessToken = accessToken;
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
this.onTokenRefresh({ accessToken, refreshToken });
|
|
1607
|
+
if (refreshToken) {
|
|
1608
|
+
this.refreshToken = refreshToken;
|
|
1480
1609
|
}
|
|
1481
1610
|
}
|
|
1611
|
+
/**
|
|
1612
|
+
* Ensure access token is valid, refreshing if necessary
|
|
1613
|
+
*/
|
|
1482
1614
|
async ensureAccessToken() {
|
|
1483
|
-
if (!this.refreshToken) {
|
|
1615
|
+
if (!this.refreshToken && !this.onTokenRefresh) {
|
|
1484
1616
|
return;
|
|
1485
1617
|
}
|
|
1486
1618
|
if (!this.accessToken || this.isTokenExpiring(this.accessToken)) {
|
|
@@ -1492,7 +1624,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1492
1624
|
}
|
|
1493
1625
|
}
|
|
1494
1626
|
async refreshTokens() {
|
|
1495
|
-
if (!this.refreshToken) {
|
|
1627
|
+
if (!this.refreshToken && !this.onTokenRefresh) {
|
|
1496
1628
|
return;
|
|
1497
1629
|
}
|
|
1498
1630
|
if (!this.refreshPromise) {
|
|
@@ -1503,6 +1635,17 @@ var _DistriClient = class _DistriClient {
|
|
|
1503
1635
|
return this.refreshPromise;
|
|
1504
1636
|
}
|
|
1505
1637
|
async performTokenRefresh() {
|
|
1638
|
+
if (this.onTokenRefresh) {
|
|
1639
|
+
this.accessToken = void 0;
|
|
1640
|
+
const newToken = await this.onTokenRefresh();
|
|
1641
|
+
if (newToken) {
|
|
1642
|
+
this.applyTokens(newToken);
|
|
1643
|
+
return;
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
if (!this.refreshToken) {
|
|
1647
|
+
return;
|
|
1648
|
+
}
|
|
1506
1649
|
const response = await this.fetchAbsolute(
|
|
1507
1650
|
`${this.config.baseUrl}/token`,
|
|
1508
1651
|
{
|
|
@@ -1526,7 +1669,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1526
1669
|
if (!tokens?.access_token || !tokens?.refresh_token) {
|
|
1527
1670
|
throw new ApiError("Invalid token response", response.status);
|
|
1528
1671
|
}
|
|
1529
|
-
this.applyTokens(tokens.access_token, tokens.refresh_token
|
|
1672
|
+
this.applyTokens(tokens.access_token, tokens.refresh_token);
|
|
1530
1673
|
}
|
|
1531
1674
|
isTokenExpiring(token) {
|
|
1532
1675
|
const expiresAt = this.getTokenExpiry(token);
|
|
@@ -1621,7 +1764,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1621
1764
|
headers
|
|
1622
1765
|
});
|
|
1623
1766
|
clearTimeout(timeoutId);
|
|
1624
|
-
if (!skipAuth && retryOnAuth && response.status === 401 && this.refreshToken) {
|
|
1767
|
+
if (!skipAuth && retryOnAuth && response.status === 401 && (this.refreshToken || this.onTokenRefresh)) {
|
|
1625
1768
|
const refreshed = await this.refreshTokens().then(() => true).catch(() => false);
|
|
1626
1769
|
if (refreshed) {
|
|
1627
1770
|
return this.fetchAbsolute(url, initialInit, { skipAuth, retryOnAuth: false });
|
|
@@ -1639,7 +1782,8 @@ var _DistriClient = class _DistriClient {
|
|
|
1639
1782
|
throw lastError;
|
|
1640
1783
|
}
|
|
1641
1784
|
/**
|
|
1642
|
-
* Enhanced fetch with retry logic
|
|
1785
|
+
* Enhanced fetch with retry logic and auth headers.
|
|
1786
|
+
* Exposed publicly for extensions like DistriHomeClient.
|
|
1643
1787
|
*/
|
|
1644
1788
|
async fetch(input, initialInit) {
|
|
1645
1789
|
const url = `${this.config.baseUrl}${input}`;
|
|
@@ -1712,13 +1856,6 @@ var _DistriClient = class _DistriClient {
|
|
|
1712
1856
|
}
|
|
1713
1857
|
};
|
|
1714
1858
|
// ============================================================
|
|
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
1859
|
// Token API
|
|
1723
1860
|
// ============================================================
|
|
1724
1861
|
// Issue access + refresh tokens for temporary authentication (e.g., frontend use)
|
|
@@ -1744,6 +1881,25 @@ function uuidv4() {
|
|
|
1744
1881
|
}
|
|
1745
1882
|
|
|
1746
1883
|
// src/agent.ts
|
|
1884
|
+
var ExternalToolValidationError = class extends DistriError {
|
|
1885
|
+
constructor(agentName, result) {
|
|
1886
|
+
super(
|
|
1887
|
+
result.message || "Missing required external tools for agent invocation.",
|
|
1888
|
+
"EXTERNAL_TOOL_VALIDATION_ERROR",
|
|
1889
|
+
{
|
|
1890
|
+
agentName,
|
|
1891
|
+
missingTools: result.missingTools,
|
|
1892
|
+
requiredTools: result.requiredTools,
|
|
1893
|
+
providedTools: result.providedTools
|
|
1894
|
+
}
|
|
1895
|
+
);
|
|
1896
|
+
this.name = "ExternalToolValidationError";
|
|
1897
|
+
this.agentName = agentName;
|
|
1898
|
+
this.missingTools = result.missingTools;
|
|
1899
|
+
this.requiredTools = result.requiredTools;
|
|
1900
|
+
this.providedTools = result.providedTools;
|
|
1901
|
+
}
|
|
1902
|
+
};
|
|
1747
1903
|
var Agent = class _Agent {
|
|
1748
1904
|
constructor(agentDefinition, client) {
|
|
1749
1905
|
this.hookHandlers = /* @__PURE__ */ new Map();
|
|
@@ -1764,7 +1920,7 @@ var Agent = class _Agent {
|
|
|
1764
1920
|
return this.agentDefinition.description;
|
|
1765
1921
|
}
|
|
1766
1922
|
get agentType() {
|
|
1767
|
-
return this.agentDefinition.agent_type
|
|
1923
|
+
return this.agentDefinition.agent_type;
|
|
1768
1924
|
}
|
|
1769
1925
|
get iconUrl() {
|
|
1770
1926
|
return this.agentDefinition.icon_url;
|
|
@@ -1801,7 +1957,7 @@ var Agent = class _Agent {
|
|
|
1801
1957
|
const enhancedParams = this.enhanceParamsWithTools(params, tools);
|
|
1802
1958
|
const a2aStream = this.client.sendMessageStream(this.agentDefinition.id, enhancedParams);
|
|
1803
1959
|
const self = this;
|
|
1804
|
-
return
|
|
1960
|
+
return async function* () {
|
|
1805
1961
|
for await (const event of a2aStream) {
|
|
1806
1962
|
const converted = decodeA2AStreamEvent(event);
|
|
1807
1963
|
if (converted && converted.type === "inline_hook_requested") {
|
|
@@ -1822,12 +1978,38 @@ var Agent = class _Agent {
|
|
|
1822
1978
|
yield converted;
|
|
1823
1979
|
}
|
|
1824
1980
|
}
|
|
1825
|
-
}
|
|
1981
|
+
}();
|
|
1982
|
+
}
|
|
1983
|
+
/**
|
|
1984
|
+
* Validate that required external tools are registered before invoking.
|
|
1985
|
+
*/
|
|
1986
|
+
validateExternalTools(tools = []) {
|
|
1987
|
+
const requiredTools = this.getRequiredExternalTools();
|
|
1988
|
+
const providedTools = tools.map((tool) => tool.name);
|
|
1989
|
+
if (requiredTools.length === 0) {
|
|
1990
|
+
return {
|
|
1991
|
+
isValid: true,
|
|
1992
|
+
requiredTools: [],
|
|
1993
|
+
providedTools,
|
|
1994
|
+
missingTools: []
|
|
1995
|
+
};
|
|
1996
|
+
}
|
|
1997
|
+
const providedSet = new Set(providedTools);
|
|
1998
|
+
const missingTools = requiredTools.filter((tool) => !providedSet.has(tool));
|
|
1999
|
+
const isValid = missingTools.length === 0;
|
|
2000
|
+
return {
|
|
2001
|
+
isValid,
|
|
2002
|
+
requiredTools,
|
|
2003
|
+
providedTools,
|
|
2004
|
+
missingTools,
|
|
2005
|
+
message: isValid ? void 0 : this.formatExternalToolValidationMessage(requiredTools, missingTools)
|
|
2006
|
+
};
|
|
1826
2007
|
}
|
|
1827
2008
|
/**
|
|
1828
2009
|
* Enhance message params with tool definitions
|
|
1829
2010
|
*/
|
|
1830
2011
|
enhanceParamsWithTools(params, tools) {
|
|
2012
|
+
this.assertExternalTools(tools);
|
|
1831
2013
|
const metadata = {
|
|
1832
2014
|
...params.metadata,
|
|
1833
2015
|
external_tools: tools?.map((tool) => ({
|
|
@@ -1842,6 +2024,39 @@ var Agent = class _Agent {
|
|
|
1842
2024
|
metadata
|
|
1843
2025
|
};
|
|
1844
2026
|
}
|
|
2027
|
+
assertExternalTools(tools) {
|
|
2028
|
+
const result = this.validateExternalTools(tools ?? []);
|
|
2029
|
+
if (!result.isValid) {
|
|
2030
|
+
throw new ExternalToolValidationError(this.agentDefinition.name || this.agentDefinition.id, result);
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
getRequiredExternalTools() {
|
|
2034
|
+
const toolConfig = this.resolveToolConfig();
|
|
2035
|
+
if (!toolConfig?.external || !Array.isArray(toolConfig.external)) {
|
|
2036
|
+
return [];
|
|
2037
|
+
}
|
|
2038
|
+
if (toolConfig.external.includes("*")) {
|
|
2039
|
+
return [];
|
|
2040
|
+
}
|
|
2041
|
+
return toolConfig.external.filter((tool) => typeof tool === "string" && tool.trim().length > 0);
|
|
2042
|
+
}
|
|
2043
|
+
resolveToolConfig() {
|
|
2044
|
+
const root = this.agentDefinition;
|
|
2045
|
+
return this.extractToolConfig(root) || this.extractToolConfig(root?.agent) || this.extractToolConfig(root?.definition);
|
|
2046
|
+
}
|
|
2047
|
+
extractToolConfig(candidate) {
|
|
2048
|
+
if (!candidate) return null;
|
|
2049
|
+
const tools = candidate.tools;
|
|
2050
|
+
if (!tools || Array.isArray(tools) || typeof tools !== "object") {
|
|
2051
|
+
return null;
|
|
2052
|
+
}
|
|
2053
|
+
return tools;
|
|
2054
|
+
}
|
|
2055
|
+
formatExternalToolValidationMessage(requiredTools, missingTools) {
|
|
2056
|
+
const requiredList = requiredTools.join(", ");
|
|
2057
|
+
const missingList = missingTools.join(", ");
|
|
2058
|
+
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}.`;
|
|
2059
|
+
}
|
|
1845
2060
|
/**
|
|
1846
2061
|
* Register multiple hooks at once.
|
|
1847
2062
|
*/
|
|
@@ -1858,12 +2073,13 @@ var Agent = class _Agent {
|
|
|
1858
2073
|
*/
|
|
1859
2074
|
static async create(agentIdOrDef, client) {
|
|
1860
2075
|
const agentDefinition = typeof agentIdOrDef === "string" ? await client.getAgent(agentIdOrDef) : agentIdOrDef;
|
|
2076
|
+
const tools = agentDefinition?.resolved_tools || [];
|
|
1861
2077
|
console.log("\u{1F916} Agent definition loaded:", {
|
|
1862
2078
|
id: agentDefinition.id,
|
|
1863
2079
|
name: agentDefinition.name,
|
|
1864
|
-
tools:
|
|
2080
|
+
tools: tools.map((t) => ({
|
|
1865
2081
|
name: t.name,
|
|
1866
|
-
type:
|
|
2082
|
+
type: "function"
|
|
1867
2083
|
})) || [],
|
|
1868
2084
|
toolCount: agentDefinition.tools?.length || 0
|
|
1869
2085
|
});
|
|
@@ -1891,6 +2107,7 @@ export {
|
|
|
1891
2107
|
DEFAULT_BASE_URL,
|
|
1892
2108
|
DistriClient,
|
|
1893
2109
|
DistriError,
|
|
2110
|
+
ExternalToolValidationError,
|
|
1894
2111
|
convertA2AMessageToDistri,
|
|
1895
2112
|
convertA2APartToDistri,
|
|
1896
2113
|
convertA2AStatusUpdateToDistri,
|