@distri/core 0.3.0 → 0.3.1

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.mjs CHANGED
@@ -681,17 +681,6 @@ 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
- }
695
684
  default: {
696
685
  console.warn(`Unhandled status update metadata type: ${metadata.type}`, metadata);
697
686
  const defaultResult = {
@@ -871,29 +860,21 @@ var _DistriClient = class _DistriClient {
871
860
  this.tokenRefreshSkewMs = config.tokenRefreshSkewMs ?? 6e4;
872
861
  this.onTokenRefresh = config.onTokenRefresh;
873
862
  this.config = {
874
- baseUrl: config.baseUrl?.replace(/\/$/, "") || DEFAULT_BASE_URL,
863
+ baseUrl: config.baseUrl.replace(/\/$/, ""),
875
864
  apiVersion: config.apiVersion || "v1",
876
- timeout: config.timeout ?? 3e4,
877
- retryAttempts: config.retryAttempts ?? 3,
878
- retryDelay: config.retryDelay ?? 1e3,
879
- debug: config.debug ?? false,
865
+ timeout: config.timeout || 3e4,
866
+ retryAttempts: config.retryAttempts || 3,
867
+ retryDelay: config.retryDelay || 1e3,
868
+ debug: config.debug || false,
880
869
  headers,
881
- interceptor: config.interceptor ?? (async (init) => Promise.resolve(init)),
882
- onTokenRefresh: config.onTokenRefresh,
883
- clientId: config.clientId
870
+ interceptor: config.interceptor || ((init) => Promise.resolve(init))
884
871
  };
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;
872
+ this.debug("DistriClient initialized with config:", {
873
+ baseUrl: this.config.baseUrl,
874
+ hasAccessToken: !!this.accessToken,
875
+ hasRefreshToken: !!this.refreshToken,
876
+ timeout: this.config.timeout
877
+ });
897
878
  }
898
879
  /**
899
880
  * Create a client with default cloud configuration.
@@ -926,7 +907,7 @@ var _DistriClient = class _DistriClient {
926
907
  if (expiry) {
927
908
  body.expiry = typeof expiry === "string" ? expiry : expiry.toISOString();
928
909
  }
929
- const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values`, {
910
+ const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}/values`, {
930
911
  method: "POST",
931
912
  headers: {
932
913
  "Content-Type": "application/json",
@@ -943,7 +924,7 @@ var _DistriClient = class _DistriClient {
943
924
  * Session store: get a single value
944
925
  */
945
926
  async getSessionValue(sessionId, key) {
946
- const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
927
+ const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
947
928
  method: "GET",
948
929
  headers: {
949
930
  ...this.config.headers
@@ -960,7 +941,7 @@ var _DistriClient = class _DistriClient {
960
941
  * Session store: get all values in a session
961
942
  */
962
943
  async getSessionValues(sessionId) {
963
- const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values`, {
944
+ const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}/values`, {
964
945
  method: "GET",
965
946
  headers: {
966
947
  ...this.config.headers
@@ -977,7 +958,7 @@ var _DistriClient = class _DistriClient {
977
958
  * Session store: delete a single key
978
959
  */
979
960
  async deleteSessionValue(sessionId, key) {
980
- const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
961
+ const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}/values/${encodeURIComponent(key)}`, {
981
962
  method: "DELETE",
982
963
  headers: {
983
964
  ...this.config.headers
@@ -992,7 +973,7 @@ var _DistriClient = class _DistriClient {
992
973
  * Session store: clear all keys in a session
993
974
  */
994
975
  async clearSession(sessionId) {
995
- const resp = await this.fetch(`/sessions/${encodeURIComponent(sessionId)}`, {
976
+ const resp = await this.fetch(`/session/${encodeURIComponent(sessionId)}`, {
996
977
  method: "DELETE",
997
978
  headers: {
998
979
  ...this.config.headers
@@ -1003,6 +984,30 @@ var _DistriClient = class _DistriClient {
1003
984
  throw new ApiError(errorData.error || "Failed to clear session", resp.status);
1004
985
  }
1005
986
  }
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
+ }
1006
1011
  /**
1007
1012
  * Issue an access token + refresh token for temporary authentication.
1008
1013
  * Requires an existing authenticated session (bearer token).
@@ -1032,7 +1037,7 @@ var _DistriClient = class _DistriClient {
1032
1037
  if (!tokens?.access_token || !tokens?.refresh_token || typeof tokens?.expires_at !== "number") {
1033
1038
  throw new ApiError("Invalid token response", response.status);
1034
1039
  }
1035
- this.applyTokens(tokens.access_token, tokens.refresh_token);
1040
+ this.applyTokens(tokens.access_token, tokens.refresh_token, false);
1036
1041
  return tokens;
1037
1042
  }
1038
1043
  /**
@@ -1045,18 +1050,13 @@ var _DistriClient = class _DistriClient {
1045
1050
  * Update the access/refresh tokens in memory.
1046
1051
  */
1047
1052
  setTokens(tokens) {
1048
- this.accessToken = tokens.accessToken;
1049
- if (tokens.refreshToken) {
1053
+ if (tokens.accessToken !== void 0) {
1054
+ this.accessToken = tokens.accessToken;
1055
+ }
1056
+ if (tokens.refreshToken !== void 0) {
1050
1057
  this.refreshToken = tokens.refreshToken;
1051
1058
  }
1052
1059
  }
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,31 +1274,6 @@ 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
- }
1302
1277
  /**
1303
1278
  * Get or create A2AClient for an agent
1304
1279
  */
@@ -1384,22 +1359,11 @@ var _DistriClient = class _DistriClient {
1384
1359
  }
1385
1360
  }
1386
1361
  /**
1387
- * Get threads from Distri server with filtering and pagination
1362
+ * Get threads from Distri server
1388
1363
  */
1389
- async getThreads(params = {}) {
1364
+ async getThreads() {
1390
1365
  try {
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);
1366
+ const response = await this.fetch(`/threads`);
1403
1367
  if (!response.ok) {
1404
1368
  throw new ApiError(`Failed to fetch threads: ${response.statusText}`, response.status);
1405
1369
  }
@@ -1409,39 +1373,6 @@ var _DistriClient = class _DistriClient {
1409
1373
  throw new DistriError("Failed to fetch threads", "FETCH_ERROR", error);
1410
1374
  }
1411
1375
  }
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
- }
1445
1376
  async getThread(threadId) {
1446
1377
  try {
1447
1378
  const response = await this.fetch(`/threads/${threadId}`);
@@ -1541,17 +1472,15 @@ var _DistriClient = class _DistriClient {
1541
1472
  get baseUrl() {
1542
1473
  return this.config.baseUrl;
1543
1474
  }
1544
- applyTokens(accessToken, refreshToken) {
1475
+ applyTokens(accessToken, refreshToken, notify) {
1545
1476
  this.accessToken = accessToken;
1546
- if (refreshToken) {
1547
- this.refreshToken = refreshToken;
1477
+ this.refreshToken = refreshToken;
1478
+ if (notify && this.onTokenRefresh) {
1479
+ this.onTokenRefresh({ accessToken, refreshToken });
1548
1480
  }
1549
1481
  }
1550
- /**
1551
- * Ensure access token is valid, refreshing if necessary
1552
- */
1553
1482
  async ensureAccessToken() {
1554
- if (!this.refreshToken && !this.onTokenRefresh) {
1483
+ if (!this.refreshToken) {
1555
1484
  return;
1556
1485
  }
1557
1486
  if (!this.accessToken || this.isTokenExpiring(this.accessToken)) {
@@ -1563,7 +1492,7 @@ var _DistriClient = class _DistriClient {
1563
1492
  }
1564
1493
  }
1565
1494
  async refreshTokens() {
1566
- if (!this.refreshToken && !this.onTokenRefresh) {
1495
+ if (!this.refreshToken) {
1567
1496
  return;
1568
1497
  }
1569
1498
  if (!this.refreshPromise) {
@@ -1574,17 +1503,6 @@ var _DistriClient = class _DistriClient {
1574
1503
  return this.refreshPromise;
1575
1504
  }
1576
1505
  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
- }
1588
1506
  const response = await this.fetchAbsolute(
1589
1507
  `${this.config.baseUrl}/token`,
1590
1508
  {
@@ -1608,7 +1526,7 @@ var _DistriClient = class _DistriClient {
1608
1526
  if (!tokens?.access_token || !tokens?.refresh_token) {
1609
1527
  throw new ApiError("Invalid token response", response.status);
1610
1528
  }
1611
- this.applyTokens(tokens.access_token, tokens.refresh_token);
1529
+ this.applyTokens(tokens.access_token, tokens.refresh_token, true);
1612
1530
  }
1613
1531
  isTokenExpiring(token) {
1614
1532
  const expiresAt = this.getTokenExpiry(token);
@@ -1703,7 +1621,7 @@ var _DistriClient = class _DistriClient {
1703
1621
  headers
1704
1622
  });
1705
1623
  clearTimeout(timeoutId);
1706
- if (!skipAuth && retryOnAuth && response.status === 401 && (this.refreshToken || this.onTokenRefresh)) {
1624
+ if (!skipAuth && retryOnAuth && response.status === 401 && this.refreshToken) {
1707
1625
  const refreshed = await this.refreshTokens().then(() => true).catch(() => false);
1708
1626
  if (refreshed) {
1709
1627
  return this.fetchAbsolute(url, initialInit, { skipAuth, retryOnAuth: false });
@@ -1721,8 +1639,7 @@ var _DistriClient = class _DistriClient {
1721
1639
  throw lastError;
1722
1640
  }
1723
1641
  /**
1724
- * Enhanced fetch with retry logic and auth headers.
1725
- * Exposed publicly for extensions like DistriHomeClient.
1642
+ * Enhanced fetch with retry logic
1726
1643
  */
1727
1644
  async fetch(input, initialInit) {
1728
1645
  const url = `${this.config.baseUrl}${input}`;
@@ -1795,6 +1712,13 @@ var _DistriClient = class _DistriClient {
1795
1712
  }
1796
1713
  };
1797
1714
  // ============================================================
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
+ // ============================================================
1798
1722
  // Token API
1799
1723
  // ============================================================
1800
1724
  // Issue access + refresh tokens for temporary authentication (e.g., frontend use)
@@ -1820,25 +1744,6 @@ function uuidv4() {
1820
1744
  }
1821
1745
 
1822
1746
  // 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
- };
1842
1747
  var Agent = class _Agent {
1843
1748
  constructor(agentDefinition, client) {
1844
1749
  this.hookHandlers = /* @__PURE__ */ new Map();
@@ -1859,7 +1764,7 @@ var Agent = class _Agent {
1859
1764
  return this.agentDefinition.description;
1860
1765
  }
1861
1766
  get agentType() {
1862
- return this.agentDefinition.agent_type;
1767
+ return this.agentDefinition.agent_type ?? this.agentDefinition.agentType;
1863
1768
  }
1864
1769
  get iconUrl() {
1865
1770
  return this.agentDefinition.icon_url;
@@ -1919,36 +1824,10 @@ var Agent = class _Agent {
1919
1824
  }
1920
1825
  })();
1921
1826
  }
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
- };
1946
- }
1947
1827
  /**
1948
1828
  * Enhance message params with tool definitions
1949
1829
  */
1950
1830
  enhanceParamsWithTools(params, tools) {
1951
- this.assertExternalTools(tools);
1952
1831
  const metadata = {
1953
1832
  ...params.metadata,
1954
1833
  external_tools: tools?.map((tool) => ({
@@ -1963,36 +1842,6 @@ var Agent = class _Agent {
1963
1842
  metadata
1964
1843
  };
1965
1844
  }
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
- return toolConfig.external.filter((tool) => typeof tool === "string" && tool.trim().length > 0);
1978
- }
1979
- resolveToolConfig() {
1980
- const root = this.agentDefinition;
1981
- return this.extractToolConfig(root) || this.extractToolConfig(root?.agent) || this.extractToolConfig(root?.definition);
1982
- }
1983
- extractToolConfig(candidate) {
1984
- if (!candidate) return null;
1985
- const tools = candidate.tools;
1986
- if (!tools || Array.isArray(tools) || typeof tools !== "object") {
1987
- return null;
1988
- }
1989
- return tools;
1990
- }
1991
- formatExternalToolValidationMessage(requiredTools, missingTools) {
1992
- const requiredList = requiredTools.join(", ");
1993
- const missingList = missingTools.join(", ");
1994
- 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}.`;
1995
- }
1996
1845
  /**
1997
1846
  * Register multiple hooks at once.
1998
1847
  */
@@ -2009,13 +1858,12 @@ var Agent = class _Agent {
2009
1858
  */
2010
1859
  static async create(agentIdOrDef, client) {
2011
1860
  const agentDefinition = typeof agentIdOrDef === "string" ? await client.getAgent(agentIdOrDef) : agentIdOrDef;
2012
- const tools = agentDefinition?.resolved_tools || [];
2013
1861
  console.log("\u{1F916} Agent definition loaded:", {
2014
1862
  id: agentDefinition.id,
2015
1863
  name: agentDefinition.name,
2016
- tools: tools.map((t) => ({
1864
+ tools: agentDefinition.tools?.map((t) => ({
2017
1865
  name: t.name,
2018
- type: "function"
1866
+ type: t.type || "function"
2019
1867
  })) || [],
2020
1868
  toolCount: agentDefinition.tools?.length || 0
2021
1869
  });
@@ -2043,7 +1891,6 @@ export {
2043
1891
  DEFAULT_BASE_URL,
2044
1892
  DistriClient,
2045
1893
  DistriError,
2046
- ExternalToolValidationError,
2047
1894
  convertA2AMessageToDistri,
2048
1895
  convertA2APartToDistri,
2049
1896
  convertA2AStatusUpdateToDistri,