@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.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 = {
|
|
@@ -807,6 +819,7 @@ function convertDistriMessageToA2A(distriMessage, context) {
|
|
|
807
819
|
break;
|
|
808
820
|
case "system":
|
|
809
821
|
case "tool":
|
|
822
|
+
case "developer":
|
|
810
823
|
role = "user";
|
|
811
824
|
break;
|
|
812
825
|
default:
|
|
@@ -903,26 +916,56 @@ var _DistriClient = class _DistriClient {
|
|
|
903
916
|
constructor(config) {
|
|
904
917
|
this.agentClients = /* @__PURE__ */ new Map();
|
|
905
918
|
const headers = { ...config.headers };
|
|
919
|
+
if (config.workspaceId) {
|
|
920
|
+
headers["X-Workspace-Id"] = config.workspaceId;
|
|
921
|
+
}
|
|
906
922
|
this.accessToken = config.accessToken;
|
|
907
923
|
this.refreshToken = config.refreshToken;
|
|
908
924
|
this.tokenRefreshSkewMs = config.tokenRefreshSkewMs ?? 6e4;
|
|
909
925
|
this.onTokenRefresh = config.onTokenRefresh;
|
|
910
926
|
this.config = {
|
|
911
|
-
baseUrl: config.baseUrl
|
|
927
|
+
baseUrl: config.baseUrl?.replace(/\/$/, "") || DEFAULT_BASE_URL,
|
|
912
928
|
apiVersion: config.apiVersion || "v1",
|
|
913
|
-
timeout: config.timeout
|
|
914
|
-
retryAttempts: config.retryAttempts
|
|
915
|
-
retryDelay: config.retryDelay
|
|
916
|
-
debug: config.debug
|
|
929
|
+
timeout: config.timeout ?? 3e4,
|
|
930
|
+
retryAttempts: config.retryAttempts ?? 3,
|
|
931
|
+
retryDelay: config.retryDelay ?? 1e3,
|
|
932
|
+
debug: config.debug ?? false,
|
|
917
933
|
headers,
|
|
918
|
-
interceptor: config.interceptor
|
|
934
|
+
interceptor: config.interceptor ?? (async (init) => Promise.resolve(init)),
|
|
935
|
+
onTokenRefresh: config.onTokenRefresh,
|
|
936
|
+
clientId: config.clientId,
|
|
937
|
+
workspaceId: config.workspaceId
|
|
919
938
|
};
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Get the configured client ID.
|
|
942
|
+
*/
|
|
943
|
+
get clientId() {
|
|
944
|
+
return this.config.clientId;
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
* Set the client ID for embed token issuance.
|
|
948
|
+
*/
|
|
949
|
+
set clientId(value) {
|
|
950
|
+
this.config.clientId = value;
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* Get the configured workspace ID.
|
|
954
|
+
*/
|
|
955
|
+
get workspaceId() {
|
|
956
|
+
return this.config.workspaceId;
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Set the workspace ID for multi-tenant support.
|
|
960
|
+
* Updates the X-Workspace-Id header for all subsequent requests.
|
|
961
|
+
*/
|
|
962
|
+
set workspaceId(value) {
|
|
963
|
+
this.config.workspaceId = value;
|
|
964
|
+
if (value) {
|
|
965
|
+
this.config.headers["X-Workspace-Id"] = value;
|
|
966
|
+
} else {
|
|
967
|
+
delete this.config.headers["X-Workspace-Id"];
|
|
968
|
+
}
|
|
926
969
|
}
|
|
927
970
|
/**
|
|
928
971
|
* Create a client with default cloud configuration.
|
|
@@ -955,7 +998,7 @@ var _DistriClient = class _DistriClient {
|
|
|
955
998
|
if (expiry) {
|
|
956
999
|
body.expiry = typeof expiry === "string" ? expiry : expiry.toISOString();
|
|
957
1000
|
}
|
|
958
|
-
const resp = await this.fetch(`/
|
|
1001
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values`, {
|
|
959
1002
|
method: "POST",
|
|
960
1003
|
headers: {
|
|
961
1004
|
"Content-Type": "application/json",
|
|
@@ -972,7 +1015,7 @@ var _DistriClient = class _DistriClient {
|
|
|
972
1015
|
* Session store: get a single value
|
|
973
1016
|
*/
|
|
974
1017
|
async getSessionValue(sessionId, key) {
|
|
975
|
-
const resp = await this.fetch(`/
|
|
1018
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
|
|
976
1019
|
method: "GET",
|
|
977
1020
|
headers: {
|
|
978
1021
|
...this.config.headers
|
|
@@ -989,7 +1032,7 @@ var _DistriClient = class _DistriClient {
|
|
|
989
1032
|
* Session store: get all values in a session
|
|
990
1033
|
*/
|
|
991
1034
|
async getSessionValues(sessionId) {
|
|
992
|
-
const resp = await this.fetch(`/
|
|
1035
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values`, {
|
|
993
1036
|
method: "GET",
|
|
994
1037
|
headers: {
|
|
995
1038
|
...this.config.headers
|
|
@@ -1006,7 +1049,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1006
1049
|
* Session store: delete a single key
|
|
1007
1050
|
*/
|
|
1008
1051
|
async deleteSessionValue(sessionId, key) {
|
|
1009
|
-
const resp = await this.fetch(`/
|
|
1052
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
|
|
1010
1053
|
method: "DELETE",
|
|
1011
1054
|
headers: {
|
|
1012
1055
|
...this.config.headers
|
|
@@ -1021,7 +1064,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1021
1064
|
* Session store: clear all keys in a session
|
|
1022
1065
|
*/
|
|
1023
1066
|
async clearSession(sessionId) {
|
|
1024
|
-
const resp = await this.fetch(`/
|
|
1067
|
+
const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}`, {
|
|
1025
1068
|
method: "DELETE",
|
|
1026
1069
|
headers: {
|
|
1027
1070
|
...this.config.headers
|
|
@@ -1032,30 +1075,6 @@ var _DistriClient = class _DistriClient {
|
|
|
1032
1075
|
throw new ApiError(errorData.error || "Failed to clear session", resp.status);
|
|
1033
1076
|
}
|
|
1034
1077
|
}
|
|
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
1078
|
/**
|
|
1060
1079
|
* Issue an access token + refresh token for temporary authentication.
|
|
1061
1080
|
* Requires an existing authenticated session (bearer token).
|
|
@@ -1085,7 +1104,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1085
1104
|
if (!tokens?.access_token || !tokens?.refresh_token || typeof tokens?.expires_at !== "number") {
|
|
1086
1105
|
throw new ApiError("Invalid token response", response.status);
|
|
1087
1106
|
}
|
|
1088
|
-
this.applyTokens(tokens.access_token, tokens.refresh_token
|
|
1107
|
+
this.applyTokens(tokens.access_token, tokens.refresh_token);
|
|
1089
1108
|
return tokens;
|
|
1090
1109
|
}
|
|
1091
1110
|
/**
|
|
@@ -1098,13 +1117,18 @@ var _DistriClient = class _DistriClient {
|
|
|
1098
1117
|
* Update the access/refresh tokens in memory.
|
|
1099
1118
|
*/
|
|
1100
1119
|
setTokens(tokens) {
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
}
|
|
1104
|
-
if (tokens.refreshToken !== void 0) {
|
|
1120
|
+
this.accessToken = tokens.accessToken;
|
|
1121
|
+
if (tokens.refreshToken) {
|
|
1105
1122
|
this.refreshToken = tokens.refreshToken;
|
|
1106
1123
|
}
|
|
1107
1124
|
}
|
|
1125
|
+
/**
|
|
1126
|
+
* Reset all authentication tokens.
|
|
1127
|
+
*/
|
|
1128
|
+
resetTokens() {
|
|
1129
|
+
this.accessToken = void 0;
|
|
1130
|
+
this.refreshToken = void 0;
|
|
1131
|
+
}
|
|
1108
1132
|
/**
|
|
1109
1133
|
* Start streaming speech-to-text transcription via WebSocket
|
|
1110
1134
|
*/
|
|
@@ -1322,6 +1346,31 @@ var _DistriClient = class _DistriClient {
|
|
|
1322
1346
|
throw new DistriError(`Failed to fetch agent ${agentId}`, "FETCH_ERROR", error);
|
|
1323
1347
|
}
|
|
1324
1348
|
}
|
|
1349
|
+
/**
|
|
1350
|
+
* Update an agent's definition (markdown only)
|
|
1351
|
+
*/
|
|
1352
|
+
async updateAgent(agentId, update) {
|
|
1353
|
+
try {
|
|
1354
|
+
const response = await this.fetch(`/agents/${agentId}`, {
|
|
1355
|
+
method: "PUT",
|
|
1356
|
+
headers: {
|
|
1357
|
+
"Content-Type": "application/json",
|
|
1358
|
+
...this.config.headers
|
|
1359
|
+
},
|
|
1360
|
+
body: JSON.stringify(update)
|
|
1361
|
+
});
|
|
1362
|
+
if (!response.ok) {
|
|
1363
|
+
if (response.status === 404) {
|
|
1364
|
+
throw new ApiError(`Agent not found: ${agentId}`, 404);
|
|
1365
|
+
}
|
|
1366
|
+
throw new ApiError(`Failed to update agent: ${response.statusText}`, response.status);
|
|
1367
|
+
}
|
|
1368
|
+
return await response.json();
|
|
1369
|
+
} catch (error) {
|
|
1370
|
+
if (error instanceof ApiError) throw error;
|
|
1371
|
+
throw new DistriError(`Failed to update agent ${agentId}`, "UPDATE_ERROR", error);
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1325
1374
|
/**
|
|
1326
1375
|
* Get or create A2AClient for an agent
|
|
1327
1376
|
*/
|
|
@@ -1370,8 +1419,46 @@ var _DistriClient = class _DistriClient {
|
|
|
1370
1419
|
yield* await client.sendMessageStream(params);
|
|
1371
1420
|
} catch (error) {
|
|
1372
1421
|
console.error(error);
|
|
1373
|
-
|
|
1422
|
+
const errorMessage = this.extractErrorMessage(error);
|
|
1423
|
+
throw new DistriError(errorMessage, "STREAM_MESSAGE_ERROR", error);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
/**
|
|
1427
|
+
* Extract a user-friendly error message from potentially nested errors
|
|
1428
|
+
*/
|
|
1429
|
+
extractErrorMessage(error) {
|
|
1430
|
+
if (!error) return "Unknown error occurred";
|
|
1431
|
+
if (typeof error === "object" && error !== null) {
|
|
1432
|
+
const err = error;
|
|
1433
|
+
if (err.error && typeof err.error === "object") {
|
|
1434
|
+
const jsonRpcError = err.error;
|
|
1435
|
+
if (typeof jsonRpcError.message === "string") {
|
|
1436
|
+
return jsonRpcError.message;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
if (err.message && typeof err.message === "string") {
|
|
1440
|
+
return err.message;
|
|
1441
|
+
}
|
|
1442
|
+
if (err.details && typeof err.details === "object") {
|
|
1443
|
+
const details = err.details;
|
|
1444
|
+
if (details.message && typeof details.message === "string") {
|
|
1445
|
+
return details.message;
|
|
1446
|
+
}
|
|
1447
|
+
if (details.error && typeof details.error === "object") {
|
|
1448
|
+
const nestedError = details.error;
|
|
1449
|
+
if (typeof nestedError.message === "string") {
|
|
1450
|
+
return nestedError.message;
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
if (err.cause && typeof err.cause === "object") {
|
|
1455
|
+
return this.extractErrorMessage(err.cause);
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
if (error instanceof Error) {
|
|
1459
|
+
return error.message;
|
|
1374
1460
|
}
|
|
1461
|
+
return String(error);
|
|
1375
1462
|
}
|
|
1376
1463
|
/**
|
|
1377
1464
|
* Get task details
|
|
@@ -1407,11 +1494,22 @@ var _DistriClient = class _DistriClient {
|
|
|
1407
1494
|
}
|
|
1408
1495
|
}
|
|
1409
1496
|
/**
|
|
1410
|
-
* Get threads from Distri server
|
|
1497
|
+
* Get threads from Distri server with filtering and pagination
|
|
1411
1498
|
*/
|
|
1412
|
-
async getThreads() {
|
|
1499
|
+
async getThreads(params = {}) {
|
|
1413
1500
|
try {
|
|
1414
|
-
const
|
|
1501
|
+
const searchParams = new URLSearchParams();
|
|
1502
|
+
if (params.agent_id) searchParams.set("agent_id", params.agent_id);
|
|
1503
|
+
if (params.external_id) searchParams.set("external_id", params.external_id);
|
|
1504
|
+
if (params.search) searchParams.set("search", params.search);
|
|
1505
|
+
if (params.from_date) searchParams.set("from_date", params.from_date);
|
|
1506
|
+
if (params.to_date) searchParams.set("to_date", params.to_date);
|
|
1507
|
+
if (params.tags?.length) searchParams.set("tags", params.tags.join(","));
|
|
1508
|
+
if (params.limit !== void 0) searchParams.set("limit", params.limit.toString());
|
|
1509
|
+
if (params.offset !== void 0) searchParams.set("offset", params.offset.toString());
|
|
1510
|
+
const queryString = searchParams.toString();
|
|
1511
|
+
const url = queryString ? `/threads?${queryString}` : "/threads";
|
|
1512
|
+
const response = await this.fetch(url);
|
|
1415
1513
|
if (!response.ok) {
|
|
1416
1514
|
throw new ApiError(`Failed to fetch threads: ${response.statusText}`, response.status);
|
|
1417
1515
|
}
|
|
@@ -1421,6 +1519,39 @@ var _DistriClient = class _DistriClient {
|
|
|
1421
1519
|
throw new DistriError("Failed to fetch threads", "FETCH_ERROR", error);
|
|
1422
1520
|
}
|
|
1423
1521
|
}
|
|
1522
|
+
/**
|
|
1523
|
+
* Get agents sorted by thread count (most active first)
|
|
1524
|
+
*/
|
|
1525
|
+
async getAgentsByUsage() {
|
|
1526
|
+
try {
|
|
1527
|
+
const response = await this.fetch("/threads/agents");
|
|
1528
|
+
if (!response.ok) {
|
|
1529
|
+
throw new ApiError(`Failed to fetch agents by usage: ${response.statusText}`, response.status);
|
|
1530
|
+
}
|
|
1531
|
+
return await response.json();
|
|
1532
|
+
} catch (error) {
|
|
1533
|
+
if (error instanceof ApiError) throw error;
|
|
1534
|
+
throw new DistriError("Failed to fetch agents by usage", "FETCH_ERROR", error);
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
/**
|
|
1538
|
+
* Create a new browser session
|
|
1539
|
+
* Returns session info including viewer_url and stream_url from browsr
|
|
1540
|
+
*/
|
|
1541
|
+
async createBrowserSession() {
|
|
1542
|
+
try {
|
|
1543
|
+
const response = await this.fetch("/browser/session", {
|
|
1544
|
+
method: "POST"
|
|
1545
|
+
});
|
|
1546
|
+
if (!response.ok) {
|
|
1547
|
+
throw new ApiError(`Failed to create browser session: ${response.statusText}`, response.status);
|
|
1548
|
+
}
|
|
1549
|
+
return await response.json();
|
|
1550
|
+
} catch (error) {
|
|
1551
|
+
if (error instanceof ApiError) throw error;
|
|
1552
|
+
throw new DistriError("Failed to create browser session", "FETCH_ERROR", error);
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1424
1555
|
async getThread(threadId) {
|
|
1425
1556
|
try {
|
|
1426
1557
|
const response = await this.fetch(`/threads/${threadId}`);
|
|
@@ -1520,15 +1651,17 @@ var _DistriClient = class _DistriClient {
|
|
|
1520
1651
|
get baseUrl() {
|
|
1521
1652
|
return this.config.baseUrl;
|
|
1522
1653
|
}
|
|
1523
|
-
applyTokens(accessToken, refreshToken
|
|
1654
|
+
applyTokens(accessToken, refreshToken) {
|
|
1524
1655
|
this.accessToken = accessToken;
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
this.onTokenRefresh({ accessToken, refreshToken });
|
|
1656
|
+
if (refreshToken) {
|
|
1657
|
+
this.refreshToken = refreshToken;
|
|
1528
1658
|
}
|
|
1529
1659
|
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Ensure access token is valid, refreshing if necessary
|
|
1662
|
+
*/
|
|
1530
1663
|
async ensureAccessToken() {
|
|
1531
|
-
if (!this.refreshToken) {
|
|
1664
|
+
if (!this.refreshToken && !this.onTokenRefresh) {
|
|
1532
1665
|
return;
|
|
1533
1666
|
}
|
|
1534
1667
|
if (!this.accessToken || this.isTokenExpiring(this.accessToken)) {
|
|
@@ -1540,7 +1673,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1540
1673
|
}
|
|
1541
1674
|
}
|
|
1542
1675
|
async refreshTokens() {
|
|
1543
|
-
if (!this.refreshToken) {
|
|
1676
|
+
if (!this.refreshToken && !this.onTokenRefresh) {
|
|
1544
1677
|
return;
|
|
1545
1678
|
}
|
|
1546
1679
|
if (!this.refreshPromise) {
|
|
@@ -1551,6 +1684,17 @@ var _DistriClient = class _DistriClient {
|
|
|
1551
1684
|
return this.refreshPromise;
|
|
1552
1685
|
}
|
|
1553
1686
|
async performTokenRefresh() {
|
|
1687
|
+
if (this.onTokenRefresh) {
|
|
1688
|
+
this.accessToken = void 0;
|
|
1689
|
+
const newToken = await this.onTokenRefresh();
|
|
1690
|
+
if (newToken) {
|
|
1691
|
+
this.applyTokens(newToken);
|
|
1692
|
+
return;
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
if (!this.refreshToken) {
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1554
1698
|
const response = await this.fetchAbsolute(
|
|
1555
1699
|
`${this.config.baseUrl}/token`,
|
|
1556
1700
|
{
|
|
@@ -1574,7 +1718,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1574
1718
|
if (!tokens?.access_token || !tokens?.refresh_token) {
|
|
1575
1719
|
throw new ApiError("Invalid token response", response.status);
|
|
1576
1720
|
}
|
|
1577
|
-
this.applyTokens(tokens.access_token, tokens.refresh_token
|
|
1721
|
+
this.applyTokens(tokens.access_token, tokens.refresh_token);
|
|
1578
1722
|
}
|
|
1579
1723
|
isTokenExpiring(token) {
|
|
1580
1724
|
const expiresAt = this.getTokenExpiry(token);
|
|
@@ -1669,7 +1813,7 @@ var _DistriClient = class _DistriClient {
|
|
|
1669
1813
|
headers
|
|
1670
1814
|
});
|
|
1671
1815
|
clearTimeout(timeoutId);
|
|
1672
|
-
if (!skipAuth && retryOnAuth && response.status === 401 && this.refreshToken) {
|
|
1816
|
+
if (!skipAuth && retryOnAuth && response.status === 401 && (this.refreshToken || this.onTokenRefresh)) {
|
|
1673
1817
|
const refreshed = await this.refreshTokens().then(() => true).catch(() => false);
|
|
1674
1818
|
if (refreshed) {
|
|
1675
1819
|
return this.fetchAbsolute(url, initialInit, { skipAuth, retryOnAuth: false });
|
|
@@ -1687,7 +1831,8 @@ var _DistriClient = class _DistriClient {
|
|
|
1687
1831
|
throw lastError;
|
|
1688
1832
|
}
|
|
1689
1833
|
/**
|
|
1690
|
-
* Enhanced fetch with retry logic
|
|
1834
|
+
* Enhanced fetch with retry logic and auth headers.
|
|
1835
|
+
* Exposed publicly for extensions like DistriHomeClient.
|
|
1691
1836
|
*/
|
|
1692
1837
|
async fetch(input, initialInit) {
|
|
1693
1838
|
const url = `${this.config.baseUrl}${input}`;
|
|
@@ -1760,13 +1905,6 @@ var _DistriClient = class _DistriClient {
|
|
|
1760
1905
|
}
|
|
1761
1906
|
};
|
|
1762
1907
|
// ============================================================
|
|
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
1908
|
// Token API
|
|
1771
1909
|
// ============================================================
|
|
1772
1910
|
// Issue access + refresh tokens for temporary authentication (e.g., frontend use)
|
|
@@ -1792,6 +1930,25 @@ function uuidv4() {
|
|
|
1792
1930
|
}
|
|
1793
1931
|
|
|
1794
1932
|
// src/agent.ts
|
|
1933
|
+
var ExternalToolValidationError = class extends DistriError {
|
|
1934
|
+
constructor(agentName, result) {
|
|
1935
|
+
super(
|
|
1936
|
+
result.message || "Missing required external tools for agent invocation.",
|
|
1937
|
+
"EXTERNAL_TOOL_VALIDATION_ERROR",
|
|
1938
|
+
{
|
|
1939
|
+
agentName,
|
|
1940
|
+
missingTools: result.missingTools,
|
|
1941
|
+
requiredTools: result.requiredTools,
|
|
1942
|
+
providedTools: result.providedTools
|
|
1943
|
+
}
|
|
1944
|
+
);
|
|
1945
|
+
this.name = "ExternalToolValidationError";
|
|
1946
|
+
this.agentName = agentName;
|
|
1947
|
+
this.missingTools = result.missingTools;
|
|
1948
|
+
this.requiredTools = result.requiredTools;
|
|
1949
|
+
this.providedTools = result.providedTools;
|
|
1950
|
+
}
|
|
1951
|
+
};
|
|
1795
1952
|
var Agent = class _Agent {
|
|
1796
1953
|
constructor(agentDefinition, client) {
|
|
1797
1954
|
this.hookHandlers = /* @__PURE__ */ new Map();
|
|
@@ -1812,7 +1969,7 @@ var Agent = class _Agent {
|
|
|
1812
1969
|
return this.agentDefinition.description;
|
|
1813
1970
|
}
|
|
1814
1971
|
get agentType() {
|
|
1815
|
-
return this.agentDefinition.agent_type
|
|
1972
|
+
return this.agentDefinition.agent_type;
|
|
1816
1973
|
}
|
|
1817
1974
|
get iconUrl() {
|
|
1818
1975
|
return this.agentDefinition.icon_url;
|
|
@@ -1849,7 +2006,7 @@ var Agent = class _Agent {
|
|
|
1849
2006
|
const enhancedParams = this.enhanceParamsWithTools(params, tools);
|
|
1850
2007
|
const a2aStream = this.client.sendMessageStream(this.agentDefinition.id, enhancedParams);
|
|
1851
2008
|
const self = this;
|
|
1852
|
-
return
|
|
2009
|
+
return async function* () {
|
|
1853
2010
|
for await (const event of a2aStream) {
|
|
1854
2011
|
const converted = decodeA2AStreamEvent(event);
|
|
1855
2012
|
if (converted && converted.type === "inline_hook_requested") {
|
|
@@ -1870,12 +2027,38 @@ var Agent = class _Agent {
|
|
|
1870
2027
|
yield converted;
|
|
1871
2028
|
}
|
|
1872
2029
|
}
|
|
1873
|
-
}
|
|
2030
|
+
}();
|
|
2031
|
+
}
|
|
2032
|
+
/**
|
|
2033
|
+
* Validate that required external tools are registered before invoking.
|
|
2034
|
+
*/
|
|
2035
|
+
validateExternalTools(tools = []) {
|
|
2036
|
+
const requiredTools = this.getRequiredExternalTools();
|
|
2037
|
+
const providedTools = tools.map((tool) => tool.name);
|
|
2038
|
+
if (requiredTools.length === 0) {
|
|
2039
|
+
return {
|
|
2040
|
+
isValid: true,
|
|
2041
|
+
requiredTools: [],
|
|
2042
|
+
providedTools,
|
|
2043
|
+
missingTools: []
|
|
2044
|
+
};
|
|
2045
|
+
}
|
|
2046
|
+
const providedSet = new Set(providedTools);
|
|
2047
|
+
const missingTools = requiredTools.filter((tool) => !providedSet.has(tool));
|
|
2048
|
+
const isValid = missingTools.length === 0;
|
|
2049
|
+
return {
|
|
2050
|
+
isValid,
|
|
2051
|
+
requiredTools,
|
|
2052
|
+
providedTools,
|
|
2053
|
+
missingTools,
|
|
2054
|
+
message: isValid ? void 0 : this.formatExternalToolValidationMessage(requiredTools, missingTools)
|
|
2055
|
+
};
|
|
1874
2056
|
}
|
|
1875
2057
|
/**
|
|
1876
2058
|
* Enhance message params with tool definitions
|
|
1877
2059
|
*/
|
|
1878
2060
|
enhanceParamsWithTools(params, tools) {
|
|
2061
|
+
this.assertExternalTools(tools);
|
|
1879
2062
|
const metadata = {
|
|
1880
2063
|
...params.metadata,
|
|
1881
2064
|
external_tools: tools?.map((tool) => ({
|
|
@@ -1890,6 +2073,39 @@ var Agent = class _Agent {
|
|
|
1890
2073
|
metadata
|
|
1891
2074
|
};
|
|
1892
2075
|
}
|
|
2076
|
+
assertExternalTools(tools) {
|
|
2077
|
+
const result = this.validateExternalTools(tools ?? []);
|
|
2078
|
+
if (!result.isValid) {
|
|
2079
|
+
throw new ExternalToolValidationError(this.agentDefinition.name || this.agentDefinition.id, result);
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
getRequiredExternalTools() {
|
|
2083
|
+
const toolConfig = this.resolveToolConfig();
|
|
2084
|
+
if (!toolConfig?.external || !Array.isArray(toolConfig.external)) {
|
|
2085
|
+
return [];
|
|
2086
|
+
}
|
|
2087
|
+
if (toolConfig.external.includes("*")) {
|
|
2088
|
+
return [];
|
|
2089
|
+
}
|
|
2090
|
+
return toolConfig.external.filter((tool) => typeof tool === "string" && tool.trim().length > 0);
|
|
2091
|
+
}
|
|
2092
|
+
resolveToolConfig() {
|
|
2093
|
+
const root = this.agentDefinition;
|
|
2094
|
+
return this.extractToolConfig(root) || this.extractToolConfig(root?.agent) || this.extractToolConfig(root?.definition);
|
|
2095
|
+
}
|
|
2096
|
+
extractToolConfig(candidate) {
|
|
2097
|
+
if (!candidate) return null;
|
|
2098
|
+
const tools = candidate.tools;
|
|
2099
|
+
if (!tools || Array.isArray(tools) || typeof tools !== "object") {
|
|
2100
|
+
return null;
|
|
2101
|
+
}
|
|
2102
|
+
return tools;
|
|
2103
|
+
}
|
|
2104
|
+
formatExternalToolValidationMessage(requiredTools, missingTools) {
|
|
2105
|
+
const requiredList = requiredTools.join(", ");
|
|
2106
|
+
const missingList = missingTools.join(", ");
|
|
2107
|
+
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}.`;
|
|
2108
|
+
}
|
|
1893
2109
|
/**
|
|
1894
2110
|
* Register multiple hooks at once.
|
|
1895
2111
|
*/
|
|
@@ -1906,12 +2122,13 @@ var Agent = class _Agent {
|
|
|
1906
2122
|
*/
|
|
1907
2123
|
static async create(agentIdOrDef, client) {
|
|
1908
2124
|
const agentDefinition = typeof agentIdOrDef === "string" ? await client.getAgent(agentIdOrDef) : agentIdOrDef;
|
|
2125
|
+
const tools = agentDefinition?.resolved_tools || [];
|
|
1909
2126
|
console.log("\u{1F916} Agent definition loaded:", {
|
|
1910
2127
|
id: agentDefinition.id,
|
|
1911
2128
|
name: agentDefinition.name,
|
|
1912
|
-
tools:
|
|
2129
|
+
tools: tools.map((t) => ({
|
|
1913
2130
|
name: t.name,
|
|
1914
|
-
type:
|
|
2131
|
+
type: "function"
|
|
1915
2132
|
})) || [],
|
|
1916
2133
|
toolCount: agentDefinition.tools?.length || 0
|
|
1917
2134
|
});
|
|
@@ -1940,6 +2157,7 @@ var Agent = class _Agent {
|
|
|
1940
2157
|
DEFAULT_BASE_URL,
|
|
1941
2158
|
DistriClient,
|
|
1942
2159
|
DistriError,
|
|
2160
|
+
ExternalToolValidationError,
|
|
1943
2161
|
convertA2AMessageToDistri,
|
|
1944
2162
|
convertA2APartToDistri,
|
|
1945
2163
|
convertA2AStatusUpdateToDistri,
|