@distri/core 0.2.7 → 0.3.0

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.js CHANGED
@@ -170,7 +170,7 @@ function isDistriEvent(event) {
170
170
  return "type" in event && "data" in event;
171
171
  }
172
172
 
173
- // ../../../node_modules/.pnpm/@a2a-js+sdk@https+++codeload.github.com+v3g42+a2a-js+tar.gz+51444c9/node_modules/@a2a-js/sdk/dist/chunk-CUGIRVQB.js
173
+ // ../../node_modules/.pnpm/@a2a-js+sdk@https+++codeload.github.com+v3g42+a2a-js+tar.gz+51444c9/node_modules/@a2a-js/sdk/dist/chunk-CUGIRVQB.js
174
174
  var A2AClient = class {
175
175
  /**
176
176
  * Constructs an A2AClient instance.
@@ -730,6 +730,17 @@ function convertA2AStatusUpdateToDistri(statusUpdate) {
730
730
  };
731
731
  return hookRequested;
732
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
+ }
733
744
  default: {
734
745
  console.warn(`Unhandled status update metadata type: ${metadata.type}`, metadata);
735
746
  const defaultResult = {
@@ -909,21 +920,29 @@ var _DistriClient = class _DistriClient {
909
920
  this.tokenRefreshSkewMs = config.tokenRefreshSkewMs ?? 6e4;
910
921
  this.onTokenRefresh = config.onTokenRefresh;
911
922
  this.config = {
912
- baseUrl: config.baseUrl.replace(/\/$/, ""),
923
+ baseUrl: config.baseUrl?.replace(/\/$/, "") || DEFAULT_BASE_URL,
913
924
  apiVersion: config.apiVersion || "v1",
914
- timeout: config.timeout || 3e4,
915
- retryAttempts: config.retryAttempts || 3,
916
- retryDelay: config.retryDelay || 1e3,
917
- debug: config.debug || false,
925
+ timeout: config.timeout ?? 3e4,
926
+ retryAttempts: config.retryAttempts ?? 3,
927
+ retryDelay: config.retryDelay ?? 1e3,
928
+ debug: config.debug ?? false,
918
929
  headers,
919
- interceptor: config.interceptor || ((init) => Promise.resolve(init))
930
+ interceptor: config.interceptor ?? (async (init) => Promise.resolve(init)),
931
+ onTokenRefresh: config.onTokenRefresh,
932
+ clientId: config.clientId
920
933
  };
921
- this.debug("DistriClient initialized with config:", {
922
- baseUrl: this.config.baseUrl,
923
- hasAccessToken: !!this.accessToken,
924
- hasRefreshToken: !!this.refreshToken,
925
- timeout: this.config.timeout
926
- });
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;
927
946
  }
928
947
  /**
929
948
  * Create a client with default cloud configuration.
@@ -956,7 +975,7 @@ var _DistriClient = class _DistriClient {
956
975
  if (expiry) {
957
976
  body.expiry = typeof expiry === "string" ? expiry : expiry.toISOString();
958
977
  }
959
- const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}/values`, {
978
+ const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values`, {
960
979
  method: "POST",
961
980
  headers: {
962
981
  "Content-Type": "application/json",
@@ -973,7 +992,7 @@ var _DistriClient = class _DistriClient {
973
992
  * Session store: get a single value
974
993
  */
975
994
  async getSessionValue(sessionId, key) {
976
- const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
995
+ const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
977
996
  method: "GET",
978
997
  headers: {
979
998
  ...this.config.headers
@@ -990,7 +1009,7 @@ var _DistriClient = class _DistriClient {
990
1009
  * Session store: get all values in a session
991
1010
  */
992
1011
  async getSessionValues(sessionId) {
993
- const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}/values`, {
1012
+ const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values`, {
994
1013
  method: "GET",
995
1014
  headers: {
996
1015
  ...this.config.headers
@@ -1007,7 +1026,7 @@ var _DistriClient = class _DistriClient {
1007
1026
  * Session store: delete a single key
1008
1027
  */
1009
1028
  async deleteSessionValue(sessionId, key) {
1010
- const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
1029
+ const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
1011
1030
  method: "DELETE",
1012
1031
  headers: {
1013
1032
  ...this.config.headers
@@ -1022,7 +1041,7 @@ var _DistriClient = class _DistriClient {
1022
1041
  * Session store: clear all keys in a session
1023
1042
  */
1024
1043
  async clearSession(sessionId) {
1025
- const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}`, {
1044
+ const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}`, {
1026
1045
  method: "DELETE",
1027
1046
  headers: {
1028
1047
  ...this.config.headers
@@ -1033,30 +1052,6 @@ var _DistriClient = class _DistriClient {
1033
1052
  throw new ApiError(errorData.error || "Failed to clear session", resp.status);
1034
1053
  }
1035
1054
  }
1036
- /**
1037
- * Set additional user message parts for the next agent iteration.
1038
- * These parts will be appended to the user message in the prompt.
1039
- * @param sessionId - The thread/session ID
1040
- * @param parts - Array of DistriPart objects to append to user message
1041
- */
1042
- async setAdditionalUserParts(sessionId, parts) {
1043
- await this.setSessionValue(sessionId, _DistriClient.ADDITIONAL_PARTS_KEY, parts);
1044
- }
1045
- /**
1046
- * Get the current additional user message parts.
1047
- * @param sessionId - The thread/session ID
1048
- * @returns Array of DistriPart objects or null if not set
1049
- */
1050
- async getAdditionalUserParts(sessionId) {
1051
- return this.getSessionValue(sessionId, _DistriClient.ADDITIONAL_PARTS_KEY);
1052
- }
1053
- /**
1054
- * Clear/delete the additional user message parts.
1055
- * @param sessionId - The thread/session ID
1056
- */
1057
- async clearAdditionalUserParts(sessionId) {
1058
- await this.deleteSessionValue(sessionId, _DistriClient.ADDITIONAL_PARTS_KEY);
1059
- }
1060
1055
  /**
1061
1056
  * Issue an access token + refresh token for temporary authentication.
1062
1057
  * Requires an existing authenticated session (bearer token).
@@ -1086,7 +1081,7 @@ var _DistriClient = class _DistriClient {
1086
1081
  if (!tokens?.access_token || !tokens?.refresh_token || typeof tokens?.expires_at !== "number") {
1087
1082
  throw new ApiError("Invalid token response", response.status);
1088
1083
  }
1089
- this.applyTokens(tokens.access_token, tokens.refresh_token, false);
1084
+ this.applyTokens(tokens.access_token, tokens.refresh_token);
1090
1085
  return tokens;
1091
1086
  }
1092
1087
  /**
@@ -1099,13 +1094,18 @@ var _DistriClient = class _DistriClient {
1099
1094
  * Update the access/refresh tokens in memory.
1100
1095
  */
1101
1096
  setTokens(tokens) {
1102
- if (tokens.accessToken !== void 0) {
1103
- this.accessToken = tokens.accessToken;
1104
- }
1105
- if (tokens.refreshToken !== void 0) {
1097
+ this.accessToken = tokens.accessToken;
1098
+ if (tokens.refreshToken) {
1106
1099
  this.refreshToken = tokens.refreshToken;
1107
1100
  }
1108
1101
  }
1102
+ /**
1103
+ * Reset all authentication tokens.
1104
+ */
1105
+ resetTokens() {
1106
+ this.accessToken = void 0;
1107
+ this.refreshToken = void 0;
1108
+ }
1109
1109
  /**
1110
1110
  * Start streaming speech-to-text transcription via WebSocket
1111
1111
  */
@@ -1323,6 +1323,31 @@ var _DistriClient = class _DistriClient {
1323
1323
  throw new DistriError(`Failed to fetch agent ${agentId}`, "FETCH_ERROR", error);
1324
1324
  }
1325
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
+ }
1326
1351
  /**
1327
1352
  * Get or create A2AClient for an agent
1328
1353
  */
@@ -1408,11 +1433,22 @@ var _DistriClient = class _DistriClient {
1408
1433
  }
1409
1434
  }
1410
1435
  /**
1411
- * Get threads from Distri server
1436
+ * Get threads from Distri server with filtering and pagination
1412
1437
  */
1413
- async getThreads() {
1438
+ async getThreads(params = {}) {
1414
1439
  try {
1415
- const response = await this.fetch(`/threads`);
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);
1416
1452
  if (!response.ok) {
1417
1453
  throw new ApiError(`Failed to fetch threads: ${response.statusText}`, response.status);
1418
1454
  }
@@ -1422,6 +1458,39 @@ var _DistriClient = class _DistriClient {
1422
1458
  throw new DistriError("Failed to fetch threads", "FETCH_ERROR", error);
1423
1459
  }
1424
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
+ }
1425
1494
  async getThread(threadId) {
1426
1495
  try {
1427
1496
  const response = await this.fetch(`/threads/${threadId}`);
@@ -1521,15 +1590,17 @@ var _DistriClient = class _DistriClient {
1521
1590
  get baseUrl() {
1522
1591
  return this.config.baseUrl;
1523
1592
  }
1524
- applyTokens(accessToken, refreshToken, notify) {
1593
+ applyTokens(accessToken, refreshToken) {
1525
1594
  this.accessToken = accessToken;
1526
- this.refreshToken = refreshToken;
1527
- if (notify && this.onTokenRefresh) {
1528
- this.onTokenRefresh({ accessToken, refreshToken });
1595
+ if (refreshToken) {
1596
+ this.refreshToken = refreshToken;
1529
1597
  }
1530
1598
  }
1599
+ /**
1600
+ * Ensure access token is valid, refreshing if necessary
1601
+ */
1531
1602
  async ensureAccessToken() {
1532
- if (!this.refreshToken) {
1603
+ if (!this.refreshToken && !this.onTokenRefresh) {
1533
1604
  return;
1534
1605
  }
1535
1606
  if (!this.accessToken || this.isTokenExpiring(this.accessToken)) {
@@ -1541,7 +1612,7 @@ var _DistriClient = class _DistriClient {
1541
1612
  }
1542
1613
  }
1543
1614
  async refreshTokens() {
1544
- if (!this.refreshToken) {
1615
+ if (!this.refreshToken && !this.onTokenRefresh) {
1545
1616
  return;
1546
1617
  }
1547
1618
  if (!this.refreshPromise) {
@@ -1552,6 +1623,17 @@ var _DistriClient = class _DistriClient {
1552
1623
  return this.refreshPromise;
1553
1624
  }
1554
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
+ }
1555
1637
  const response = await this.fetchAbsolute(
1556
1638
  `${this.config.baseUrl}/token`,
1557
1639
  {
@@ -1575,7 +1657,7 @@ var _DistriClient = class _DistriClient {
1575
1657
  if (!tokens?.access_token || !tokens?.refresh_token) {
1576
1658
  throw new ApiError("Invalid token response", response.status);
1577
1659
  }
1578
- this.applyTokens(tokens.access_token, tokens.refresh_token, true);
1660
+ this.applyTokens(tokens.access_token, tokens.refresh_token);
1579
1661
  }
1580
1662
  isTokenExpiring(token) {
1581
1663
  const expiresAt = this.getTokenExpiry(token);
@@ -1670,7 +1752,7 @@ var _DistriClient = class _DistriClient {
1670
1752
  headers
1671
1753
  });
1672
1754
  clearTimeout(timeoutId);
1673
- if (!skipAuth && retryOnAuth && response.status === 401 && this.refreshToken) {
1755
+ if (!skipAuth && retryOnAuth && response.status === 401 && (this.refreshToken || this.onTokenRefresh)) {
1674
1756
  const refreshed = await this.refreshTokens().then(() => true).catch(() => false);
1675
1757
  if (refreshed) {
1676
1758
  return this.fetchAbsolute(url, initialInit, { skipAuth, retryOnAuth: false });
@@ -1762,13 +1844,6 @@ var _DistriClient = class _DistriClient {
1762
1844
  }
1763
1845
  };
1764
1846
  // ============================================================
1765
- // Additional User Message Parts API
1766
- // ============================================================
1767
- // These methods allow external tools to append parts (text, images)
1768
- // to the user message in the next agent iteration.
1769
- // The parts are stored under the key "__additional_user_parts".
1770
- _DistriClient.ADDITIONAL_PARTS_KEY = "__additional_user_parts";
1771
- // ============================================================
1772
1847
  // Token API
1773
1848
  // ============================================================
1774
1849
  // Issue access + refresh tokens for temporary authentication (e.g., frontend use)