@athenaintel/react 0.32.0 → 0.35.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.
Files changed (134) hide show
  1. package/README.md +99 -9
  2. package/dist/agent-runtime/src/composer-markdown.cjs.map +1 -1
  3. package/dist/agent-runtime/src/composer-markdown.js.map +1 -1
  4. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs +2 -3
  5. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -1
  6. package/dist/agent-runtime/src/deep-agent-transport-recipe.js +3 -4
  7. package/dist/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -1
  8. package/dist/agent-runtime/src/edit-command.cjs.map +1 -1
  9. package/dist/agent-runtime/src/edit-command.js.map +1 -1
  10. package/dist/agent-runtime/src/messages.cjs +57 -2
  11. package/dist/agent-runtime/src/messages.cjs.map +1 -1
  12. package/dist/agent-runtime/src/messages.js +57 -2
  13. package/dist/agent-runtime/src/messages.js.map +1 -1
  14. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +24 -3
  15. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  16. package/dist/agent-runtime/src/quota-safe-local-storage-session.js +24 -3
  17. package/dist/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -1
  18. package/dist/agent-runtime/src/statewire-transport.cjs +4 -13
  19. package/dist/agent-runtime/src/statewire-transport.cjs.map +1 -1
  20. package/dist/agent-runtime/src/statewire-transport.js +5 -14
  21. package/dist/agent-runtime/src/statewire-transport.js.map +1 -1
  22. package/dist/agent-runtime/src/tool-metadata.cjs +1 -1
  23. package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
  24. package/dist/agent-runtime/src/tool-metadata.js +1 -1
  25. package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
  26. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  27. package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
  28. package/dist/assets/AthenaAssetEmbed.cjs +3 -1
  29. package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
  30. package/dist/assets/AthenaAssetEmbed.d.ts +7 -0
  31. package/dist/assets/AthenaAssetEmbed.js +4 -2
  32. package/dist/assets/AthenaAssetEmbed.js.map +1 -1
  33. package/dist/assets/use-asset-embed.cjs +71 -71
  34. package/dist/assets/use-asset-embed.cjs.map +1 -1
  35. package/dist/assets/use-asset-embed.d.ts +20 -7
  36. package/dist/assets/use-asset-embed.js +72 -72
  37. package/dist/assets/use-asset-embed.js.map +1 -1
  38. package/dist/catalog/agent-model-options.cjs +122 -0
  39. package/dist/catalog/agent-model-options.cjs.map +1 -0
  40. package/dist/catalog/agent-model-options.d.ts +115 -0
  41. package/dist/catalog/agent-model-options.js +122 -0
  42. package/dist/catalog/agent-model-options.js.map +1 -0
  43. package/dist/catalog/chat-pickers.cjs +184 -4
  44. package/dist/catalog/chat-pickers.cjs.map +1 -1
  45. package/dist/catalog/chat-pickers.d.ts +27 -3
  46. package/dist/catalog/chat-pickers.js +187 -7
  47. package/dist/catalog/chat-pickers.js.map +1 -1
  48. package/dist/catalog/runtime-catalog.cjs +117 -3
  49. package/dist/catalog/runtime-catalog.cjs.map +1 -1
  50. package/dist/catalog/runtime-catalog.d.ts +104 -0
  51. package/dist/catalog/runtime-catalog.js +119 -5
  52. package/dist/catalog/runtime-catalog.js.map +1 -1
  53. package/dist/chat/AthenaChat.cjs.map +1 -1
  54. package/dist/chat/AthenaChat.d.ts +8 -7
  55. package/dist/chat/AthenaChat.js.map +1 -1
  56. package/dist/chat/super-grouping/SuperGroupingCard.cjs +30 -3
  57. package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
  58. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +12 -9
  59. package/dist/chat/super-grouping/SuperGroupingCard.js +31 -4
  60. package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
  61. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -1
  62. package/dist/chat/super-grouping/SuperGroupingTranscript.d.ts +8 -8
  63. package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -1
  64. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  65. package/dist/chat/super-grouping/activity-timeline.d.ts +4 -4
  66. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  67. package/dist/chat/super-grouping/index.d.ts +6 -5
  68. package/dist/chat/super-grouping/toolkit-map.cjs +3 -1
  69. package/dist/chat/super-grouping/toolkit-map.cjs.map +1 -1
  70. package/dist/chat/super-grouping/toolkit-map.js +3 -1
  71. package/dist/chat/super-grouping/toolkit-map.js.map +1 -1
  72. package/dist/chat-ui/index.cjs +1 -0
  73. package/dist/chat-ui/index.cjs.map +1 -1
  74. package/dist/chat-ui/index.d.ts +1 -1
  75. package/dist/chat-ui/index.js +2 -1
  76. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +33 -2
  77. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  78. package/dist/chat-ui/mentions/suggestions/data/api-client.d.ts +14 -0
  79. package/dist/chat-ui/mentions/suggestions/data/api-client.js +33 -2
  80. package/dist/chat-ui/mentions/suggestions/data/api-client.js.map +1 -1
  81. package/dist/index.cjs +1 -0
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.d.ts +3 -2
  84. package/dist/index.js +2 -1
  85. package/dist/lib/use-athena-rest-query.cjs +4 -0
  86. package/dist/lib/use-athena-rest-query.cjs.map +1 -1
  87. package/dist/lib/use-athena-rest-query.d.ts +6 -0
  88. package/dist/lib/use-athena-rest-query.js +4 -0
  89. package/dist/lib/use-athena-rest-query.js.map +1 -1
  90. package/dist/provider/AthenaProvider.cjs +29 -8
  91. package/dist/provider/AthenaProvider.cjs.map +1 -1
  92. package/dist/provider/AthenaProvider.d.ts +14 -4
  93. package/dist/provider/AthenaProvider.js +31 -10
  94. package/dist/provider/AthenaProvider.js.map +1 -1
  95. package/dist/provider/agent-selection-context.cjs +6 -0
  96. package/dist/provider/agent-selection-context.cjs.map +1 -0
  97. package/dist/provider/agent-selection-context.d.ts +14 -0
  98. package/dist/provider/agent-selection-context.js +6 -0
  99. package/dist/provider/agent-selection-context.js.map +1 -0
  100. package/dist/react/package.json.cjs +1 -1
  101. package/dist/react/package.json.js +1 -1
  102. package/dist/runtime/StatewireThreadConfigLaneSync.cjs +125 -0
  103. package/dist/runtime/StatewireThreadConfigLaneSync.cjs.map +1 -0
  104. package/dist/runtime/StatewireThreadConfigLaneSync.d.ts +54 -0
  105. package/dist/runtime/StatewireThreadConfigLaneSync.js +125 -0
  106. package/dist/runtime/StatewireThreadConfigLaneSync.js.map +1 -0
  107. package/dist/runtime/statewire-model-lane.cjs +0 -12
  108. package/dist/runtime/statewire-model-lane.cjs.map +1 -1
  109. package/dist/runtime/statewire-model-lane.d.ts +3 -1
  110. package/dist/runtime/statewire-model-lane.js +0 -12
  111. package/dist/runtime/statewire-model-lane.js.map +1 -1
  112. package/dist/runtime/statewire-server-lane-context.cjs.map +1 -1
  113. package/dist/runtime/statewire-server-lane-context.d.ts +2 -2
  114. package/dist/runtime/statewire-server-lane-context.js.map +1 -1
  115. package/dist/runtime/statewire-thread-config-lane.cjs +84 -0
  116. package/dist/runtime/statewire-thread-config-lane.cjs.map +1 -0
  117. package/dist/runtime/statewire-thread-config-lane.d.ts +94 -0
  118. package/dist/runtime/statewire-thread-config-lane.js +84 -0
  119. package/dist/runtime/statewire-thread-config-lane.js.map +1 -0
  120. package/dist/runtime/useAthenaStatewireRuntime.cjs +2 -2
  121. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  122. package/dist/runtime/useAthenaStatewireRuntime.js +2 -2
  123. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  124. package/dist/threads/use-athena-thread-model.cjs +11 -3
  125. package/dist/threads/use-athena-thread-model.cjs.map +1 -1
  126. package/dist/threads/use-athena-thread-model.d.ts +5 -0
  127. package/dist/threads/use-athena-thread-model.js +12 -4
  128. package/dist/threads/use-athena-thread-model.js.map +1 -1
  129. package/package.json +3 -3
  130. package/dist/runtime/StatewireModelLaneSync.cjs +0 -96
  131. package/dist/runtime/StatewireModelLaneSync.cjs.map +0 -1
  132. package/dist/runtime/StatewireModelLaneSync.d.ts +0 -45
  133. package/dist/runtime/StatewireModelLaneSync.js +0 -96
  134. package/dist/runtime/StatewireModelLaneSync.js.map +0 -1
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
2
5
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
6
  const react = require("react");
4
7
  function mentionRequestInit(auth) {
@@ -15,6 +18,27 @@ function useMentionAuth() {
15
18
  if (!ctx) throw new Error("MentionAuthCtx not provided");
16
19
  return ctx;
17
20
  }
21
+ class AthenaGraphQLError extends Error {
22
+ constructor({
23
+ message,
24
+ status = null,
25
+ code = null
26
+ }) {
27
+ super(message);
28
+ __publicField(this, "status");
29
+ __publicField(this, "code");
30
+ this.name = "AthenaGraphQLError";
31
+ this.status = status;
32
+ this.code = code;
33
+ }
34
+ }
35
+ function graphQLErrorCode(entry) {
36
+ if (typeof entry !== "object" || entry === null) return null;
37
+ const extensions = Reflect.get(entry, "extensions");
38
+ if (typeof extensions !== "object" || extensions === null) return null;
39
+ const code = Reflect.get(extensions, "code");
40
+ return typeof code === "string" ? code : null;
41
+ }
18
42
  async function fetchGraphQL(auth, query, variables = {}) {
19
43
  var _a;
20
44
  const url = `${auth.backendUrl.replace(/\/+$/, "")}/graphql`;
@@ -39,11 +63,17 @@ async function fetchGraphQL(auth, query, variables = {}) {
39
63
  }
40
64
  }
41
65
  if (!response.ok) {
42
- throw new Error(`GraphQL HTTP ${response.status}: ${response.statusText}`);
66
+ throw new AthenaGraphQLError({
67
+ message: `GraphQL HTTP ${response.status}: ${response.statusText}`,
68
+ status: response.status
69
+ });
43
70
  }
44
71
  const result = await response.json();
45
72
  if ((_a = result.errors) == null ? void 0 : _a.length) {
46
- throw new Error(`GraphQL error: ${result.errors[0].message}`);
73
+ throw new AthenaGraphQLError({
74
+ message: `GraphQL error: ${result.errors[0].message}`,
75
+ code: graphQLErrorCode(result.errors[0])
76
+ });
47
77
  }
48
78
  return result.data;
49
79
  }
@@ -122,6 +152,7 @@ const TOOL_CATALOG_QUERY = `
122
152
  }
123
153
  }
124
154
  `;
155
+ exports.AthenaGraphQLError = AthenaGraphQLError;
125
156
  exports.MentionAuthCtx = MentionAuthCtx;
126
157
  exports.PAGINATED_ASSETS_QUERY = PAGINATED_ASSETS_QUERY;
127
158
  exports.SIMPLE_SEARCH_QUERY = SIMPLE_SEARCH_QUERY;
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.cjs","sources":["../../../../../src/chat-ui/mentions/suggestions/data/api-client.ts"],"sourcesContent":["/**\n * API client for mention data fetching.\n *\n * Wraps raw fetch() with GraphQL support. Hosts authenticate with either a\n * bearer token or a workspace API key; agora's /graphql accepts both.\n */\n\nimport { createContext, useContext } from \"react\";\n\n// ── Auth context ──\n\nexport interface MentionAuthContext {\n backendUrl: string;\n appUrl?: string;\n /** Bearer credential; hosts without one authenticate with `apiKey`. */\n accessToken?: string;\n /**\n * Resolve a current bearer before each query (for rotating Office sessions).\n * Resolving nothing falls back to `accessToken`, then the API key.\n */\n getAccessToken?: () => Promise<string | null | undefined>;\n /**\n * Renew the bearer after the backend refused it (401), for one resend of\n * the query. Without it, or when it resolves nothing, a refused query fails\n * as before.\n */\n renewAccessToken?: () => Promise<string | null | undefined>;\n apiKey?: string;\n /**\n * With neither credential, ride the browser's same-origin session cookie\n * instead of failing — the SDK's AthenaChat, whose REST helpers make the\n * same choice for a host that configured no token and no API key. Hosts\n * that always hold a credential leave this unset so an accidental anonymous\n * query fails loudly.\n */\n credentials?: \"include\";\n workspaceId?: string;\n userId?: string;\n}\n\n/** Credential headers (or the cookie lane) for a mention fetch. */\nexport function mentionRequestInit(\n auth: MentionAuthContext,\n): Pick<RequestInit, \"headers\" | \"credentials\"> {\n if (auth.accessToken) {\n return { headers: { Authorization: `Bearer ${auth.accessToken}` } };\n }\n if (auth.apiKey) return { headers: { \"X-API-KEY\": auth.apiKey } };\n if (auth.credentials) return { headers: {}, credentials: auth.credentials };\n throw new Error(\"MentionAuthCtx needs either an accessToken or an apiKey\");\n}\n\nexport const MentionAuthCtx = createContext<MentionAuthContext | null>(null);\n\nexport function useMentionAuth(): MentionAuthContext {\n const ctx = useContext(MentionAuthCtx);\n if (!ctx) throw new Error(\"MentionAuthCtx not provided\");\n return ctx;\n}\n\n// ── GraphQL client ──\n\nexport async function fetchGraphQL<T = any>(\n auth: MentionAuthContext,\n query: string,\n variables: Record<string, any> = {},\n): Promise<T> {\n const url = `${auth.backendUrl.replace(/\\/+$/, \"\")}/graphql`;\n const send = (requestAuth: MentionAuthContext) => {\n const { headers, credentials } = mentionRequestInit(requestAuth);\n return fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...headers,\n },\n ...(credentials ? { credentials } : {}),\n body: JSON.stringify({ query, variables }),\n });\n };\n const requestAuth = auth.getAccessToken\n ? { ...auth, accessToken: (await auth.getAccessToken()) ?? auth.accessToken }\n : auth;\n let response = await send(requestAuth);\n // A refused bearer gets one renewal and a resend (the statewire transport's\n // `staleAuth` contract); an API-key or cookie request has nothing to renew.\n if (response.status === 401 && requestAuth.accessToken && auth.renewAccessToken) {\n const renewed = await auth.renewAccessToken();\n // The same token again (a static one) would only be refused again.\n if (renewed && renewed !== requestAuth.accessToken) {\n response = await send({ ...auth, accessToken: renewed });\n }\n }\n\n if (!response.ok) {\n throw new Error(`GraphQL HTTP ${response.status}: ${response.statusText}`);\n }\n\n const result = await response.json();\n if (result.errors?.length) {\n throw new Error(`GraphQL error: ${result.errors[0].message}`);\n }\n\n return result.data as T;\n}\n\n// ── GraphQL Queries ──\n\n/**\n * Lightweight asset fragment for mention menu items.\n * Only fetches fields needed for display + navigation.\n */\nconst MENTION_ASSET_FIELDS = `\n id\n title\n athenaOriginalType\n athenaConvertedType\n parentFolderId\n updatedAt\n isFavorited\n isArchived\n isHidden\n`;\n\nexport const SIMPLE_SEARCH_QUERY = `\n query SimpleSearch($input: SimpleSearchRequestInput!) {\n simpleSearch(input: $input) {\n assets {\n ${MENTION_ASSET_FIELDS}\n }\n totalCount\n }\n }\n`;\n\nexport const PAGINATED_ASSETS_QUERY = `\n query GetPaginatedAssetsForWorkspace(\n $limit: Int!\n $offset: Int!\n $parentFolderId: String\n $filterTypes: [String!]\n $filterColumns: ColumnFilter\n ) {\n getPaginatedAssetsForWorkspace(\n limit: $limit\n offset: $offset\n parentFolderId: $parentFolderId\n filterTypes: $filterTypes\n filterColumns: $filterColumns\n ) {\n ${MENTION_ASSET_FIELDS}\n }\n }\n`;\n\nexport const WORKSPACE_MEMBERS_QUERY = `\n query GetUsersInWorkspace($workspaceId: String!) {\n getUsersInWorkspace(workspaceId: $workspaceId) {\n id\n email\n firstName\n lastName\n isAdmin\n avatarUrl\n }\n }\n`;\n\nexport const TOOL_CATALOG_QUERY = `\n query MentionToolCatalog {\n getToolkitToToolsMapping {\n tools {\n id\n name\n description\n icon\n adminOnly\n isMentionable\n }\n toolkits {\n name\n displayName\n description\n icon\n onlyAdmin\n hideFromMenu\n isMentionable\n }\n }\n }\n`;\n\n// ── Response types ──\n\nexport interface ToolCatalogTool {\n id: string;\n name: string;\n description: string | null;\n icon: string;\n adminOnly: boolean;\n isMentionable: boolean;\n}\n\nexport interface ToolCatalogToolkit {\n name: string;\n displayName: string;\n description: string;\n icon: string;\n onlyAdmin: boolean;\n hideFromMenu: boolean;\n isMentionable: boolean;\n}\n\nexport interface ToolCatalogResult {\n getToolkitToToolsMapping: {\n tools: ToolCatalogTool[];\n toolkits: ToolCatalogToolkit[];\n };\n}\n\nexport interface AssetResult {\n id: string;\n title: string | null;\n athenaOriginalType: string | null;\n athenaConvertedType: string | null;\n parentFolderId: string | null;\n updatedAt: string | null;\n isFavorited: boolean | null;\n isArchived: boolean | null;\n isHidden: boolean | null;\n}\n\nexport interface WorkspaceMember {\n id: string;\n email: string | null;\n firstName: string | null;\n lastName: string | null;\n isAdmin: boolean;\n avatarUrl: string | null;\n}\n"],"names":["createContext","useContext","requestAuth"],"mappings":";;;AAyCO,SAAS,mBACd,MAC8C;AAC9C,MAAI,KAAK,aAAa;AACpB,WAAO,EAAE,SAAS,EAAE,eAAe,UAAU,KAAK,WAAW,KAAG;AAAA,EAClE;AACA,MAAI,KAAK,OAAQ,QAAO,EAAE,SAAS,EAAE,aAAa,KAAK,SAAO;AAC9D,MAAI,KAAK,YAAa,QAAO,EAAE,SAAS,CAAA,GAAI,aAAa,KAAK,YAAA;AAC9D,QAAM,IAAI,MAAM,yDAAyD;AAC3E;AAEO,MAAM,iBAAiBA,MAAAA,cAAyC,IAAI;AAEpE,SAAS,iBAAqC;AACnD,QAAM,MAAMC,MAAAA,WAAW,cAAc;AACrC,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,6BAA6B;AACvD,SAAO;AACT;AAIA,eAAsB,aACpB,MACA,OACA,YAAiC,CAAA,GACrB;;AACZ,QAAM,MAAM,GAAG,KAAK,WAAW,QAAQ,QAAQ,EAAE,CAAC;AAClD,QAAM,OAAO,CAACC,iBAAoC;AAChD,UAAM,EAAE,SAAS,gBAAgB,mBAAmBA,YAAW;AAC/D,WAAO,MAAM,KAAK;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG;AAAA,MAAA;AAAA,MAEL,GAAI,cAAc,EAAE,YAAA,IAAgB,CAAA;AAAA,MACpC,MAAM,KAAK,UAAU,EAAE,OAAO,WAAW;AAAA,IAAA,CAC1C;AAAA,EACH;AACA,QAAM,cAAc,KAAK,iBACrB,EAAE,GAAG,MAAM,aAAc,MAAM,KAAK,eAAA,KAAqB,KAAK,gBAC9D;AACJ,MAAI,WAAW,MAAM,KAAK,WAAW;AAGrC,MAAI,SAAS,WAAW,OAAO,YAAY,eAAe,KAAK,kBAAkB;AAC/E,UAAM,UAAU,MAAM,KAAK,iBAAA;AAE3B,QAAI,WAAW,YAAY,YAAY,aAAa;AAClD,iBAAW,MAAM,KAAK,EAAE,GAAG,MAAM,aAAa,SAAS;AAAA,IACzD;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,gBAAgB,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,EAC3E;AAEA,QAAM,SAAS,MAAM,SAAS,KAAA;AAC9B,OAAI,YAAO,WAAP,mBAAe,QAAQ;AACzB,UAAM,IAAI,MAAM,kBAAkB,OAAO,OAAO,CAAC,EAAE,OAAO,EAAE;AAAA,EAC9D;AAEA,SAAO,OAAO;AAChB;AAQA,MAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYtB,MAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA,UAIzB,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAOvB,MAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAe9B,oBAAoB;AAAA;AAAA;AAAA;AAKrB,MAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAahC,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;"}
1
+ {"version":3,"file":"api-client.cjs","sources":["../../../../../src/chat-ui/mentions/suggestions/data/api-client.ts"],"sourcesContent":["/**\n * API client for mention data fetching.\n *\n * Wraps raw fetch() with GraphQL support. Hosts authenticate with either a\n * bearer token or a workspace API key; agora's /graphql accepts both.\n */\n\nimport { createContext, useContext } from \"react\";\n\n// ── Auth context ──\n\nexport interface MentionAuthContext {\n backendUrl: string;\n appUrl?: string;\n /** Bearer credential; hosts without one authenticate with `apiKey`. */\n accessToken?: string;\n /**\n * Resolve a current bearer before each query (for rotating Office sessions).\n * Resolving nothing falls back to `accessToken`, then the API key.\n */\n getAccessToken?: () => Promise<string | null | undefined>;\n /**\n * Renew the bearer after the backend refused it (401), for one resend of\n * the query. Without it, or when it resolves nothing, a refused query fails\n * as before.\n */\n renewAccessToken?: () => Promise<string | null | undefined>;\n apiKey?: string;\n /**\n * With neither credential, ride the browser's same-origin session cookie\n * instead of failing — the SDK's AthenaChat, whose REST helpers make the\n * same choice for a host that configured no token and no API key. Hosts\n * that always hold a credential leave this unset so an accidental anonymous\n * query fails loudly.\n */\n credentials?: \"include\";\n workspaceId?: string;\n userId?: string;\n}\n\n/** Credential headers (or the cookie lane) for a mention fetch. */\nexport function mentionRequestInit(\n auth: MentionAuthContext,\n): Pick<RequestInit, \"headers\" | \"credentials\"> {\n if (auth.accessToken) {\n return { headers: { Authorization: `Bearer ${auth.accessToken}` } };\n }\n if (auth.apiKey) return { headers: { \"X-API-KEY\": auth.apiKey } };\n if (auth.credentials) return { headers: {}, credentials: auth.credentials };\n throw new Error(\"MentionAuthCtx needs either an accessToken or an apiKey\");\n}\n\nexport const MentionAuthCtx = createContext<MentionAuthContext | null>(null);\n\nexport function useMentionAuth(): MentionAuthContext {\n const ctx = useContext(MentionAuthCtx);\n if (!ctx) throw new Error(\"MentionAuthCtx not provided\");\n return ctx;\n}\n\n// ── GraphQL client ──\n\n/**\n * What {@link fetchGraphQL} throws: an HTTP failure (`status`) or the first\n * GraphQL error of the response (`code`, its `extensions.code`, e.g. agora's\n * `UNAUTHORIZED` for an asset the caller cannot read).\n */\nexport class AthenaGraphQLError extends Error {\n readonly status: number | null;\n readonly code: string | null;\n\n constructor({\n message,\n status = null,\n code = null,\n }: {\n message: string;\n status?: number | null;\n code?: string | null;\n }) {\n super(message);\n this.name = \"AthenaGraphQLError\";\n this.status = status;\n this.code = code;\n }\n}\n\n/** The `extensions.code` of a GraphQL error entry, when it carries a string one. */\nfunction graphQLErrorCode(entry: unknown): string | null {\n if (typeof entry !== \"object\" || entry === null) return null;\n const extensions: unknown = Reflect.get(entry, \"extensions\");\n if (typeof extensions !== \"object\" || extensions === null) return null;\n const code: unknown = Reflect.get(extensions, \"code\");\n return typeof code === \"string\" ? code : null;\n}\n\nexport async function fetchGraphQL<T = any>(\n auth: MentionAuthContext,\n query: string,\n variables: Record<string, any> = {},\n): Promise<T> {\n const url = `${auth.backendUrl.replace(/\\/+$/, \"\")}/graphql`;\n const send = (requestAuth: MentionAuthContext) => {\n const { headers, credentials } = mentionRequestInit(requestAuth);\n return fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...headers,\n },\n ...(credentials ? { credentials } : {}),\n body: JSON.stringify({ query, variables }),\n });\n };\n const requestAuth = auth.getAccessToken\n ? { ...auth, accessToken: (await auth.getAccessToken()) ?? auth.accessToken }\n : auth;\n let response = await send(requestAuth);\n // A refused bearer gets one renewal and a resend (the statewire transport's\n // `staleAuth` contract); an API-key or cookie request has nothing to renew.\n if (response.status === 401 && requestAuth.accessToken && auth.renewAccessToken) {\n const renewed = await auth.renewAccessToken();\n // The same token again (a static one) would only be refused again.\n if (renewed && renewed !== requestAuth.accessToken) {\n response = await send({ ...auth, accessToken: renewed });\n }\n }\n\n if (!response.ok) {\n throw new AthenaGraphQLError({\n message: `GraphQL HTTP ${response.status}: ${response.statusText}`,\n status: response.status,\n });\n }\n\n const result = await response.json();\n if (result.errors?.length) {\n throw new AthenaGraphQLError({\n message: `GraphQL error: ${result.errors[0].message}`,\n code: graphQLErrorCode(result.errors[0]),\n });\n }\n\n return result.data as T;\n}\n\n// ── GraphQL Queries ──\n\n/**\n * Lightweight asset fragment for mention menu items.\n * Only fetches fields needed for display + navigation.\n */\nconst MENTION_ASSET_FIELDS = `\n id\n title\n athenaOriginalType\n athenaConvertedType\n parentFolderId\n updatedAt\n isFavorited\n isArchived\n isHidden\n`;\n\nexport const SIMPLE_SEARCH_QUERY = `\n query SimpleSearch($input: SimpleSearchRequestInput!) {\n simpleSearch(input: $input) {\n assets {\n ${MENTION_ASSET_FIELDS}\n }\n totalCount\n }\n }\n`;\n\nexport const PAGINATED_ASSETS_QUERY = `\n query GetPaginatedAssetsForWorkspace(\n $limit: Int!\n $offset: Int!\n $parentFolderId: String\n $filterTypes: [String!]\n $filterColumns: ColumnFilter\n ) {\n getPaginatedAssetsForWorkspace(\n limit: $limit\n offset: $offset\n parentFolderId: $parentFolderId\n filterTypes: $filterTypes\n filterColumns: $filterColumns\n ) {\n ${MENTION_ASSET_FIELDS}\n }\n }\n`;\n\nexport const WORKSPACE_MEMBERS_QUERY = `\n query GetUsersInWorkspace($workspaceId: String!) {\n getUsersInWorkspace(workspaceId: $workspaceId) {\n id\n email\n firstName\n lastName\n isAdmin\n avatarUrl\n }\n }\n`;\n\nexport const TOOL_CATALOG_QUERY = `\n query MentionToolCatalog {\n getToolkitToToolsMapping {\n tools {\n id\n name\n description\n icon\n adminOnly\n isMentionable\n }\n toolkits {\n name\n displayName\n description\n icon\n onlyAdmin\n hideFromMenu\n isMentionable\n }\n }\n }\n`;\n\n// ── Response types ──\n\nexport interface ToolCatalogTool {\n id: string;\n name: string;\n description: string | null;\n icon: string;\n adminOnly: boolean;\n isMentionable: boolean;\n}\n\nexport interface ToolCatalogToolkit {\n name: string;\n displayName: string;\n description: string;\n icon: string;\n onlyAdmin: boolean;\n hideFromMenu: boolean;\n isMentionable: boolean;\n}\n\nexport interface ToolCatalogResult {\n getToolkitToToolsMapping: {\n tools: ToolCatalogTool[];\n toolkits: ToolCatalogToolkit[];\n };\n}\n\nexport interface AssetResult {\n id: string;\n title: string | null;\n athenaOriginalType: string | null;\n athenaConvertedType: string | null;\n parentFolderId: string | null;\n updatedAt: string | null;\n isFavorited: boolean | null;\n isArchived: boolean | null;\n isHidden: boolean | null;\n}\n\nexport interface WorkspaceMember {\n id: string;\n email: string | null;\n firstName: string | null;\n lastName: string | null;\n isAdmin: boolean;\n avatarUrl: string | null;\n}\n"],"names":["createContext","useContext","requestAuth"],"mappings":"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"}
@@ -36,6 +36,20 @@ export interface MentionAuthContext {
36
36
  export declare function mentionRequestInit(auth: MentionAuthContext): Pick<RequestInit, "headers" | "credentials">;
37
37
  export declare const MentionAuthCtx: import("react").Context<MentionAuthContext | null>;
38
38
  export declare function useMentionAuth(): MentionAuthContext;
39
+ /**
40
+ * What {@link fetchGraphQL} throws: an HTTP failure (`status`) or the first
41
+ * GraphQL error of the response (`code`, its `extensions.code`, e.g. agora's
42
+ * `UNAUTHORIZED` for an asset the caller cannot read).
43
+ */
44
+ export declare class AthenaGraphQLError extends Error {
45
+ readonly status: number | null;
46
+ readonly code: string | null;
47
+ constructor({ message, status, code, }: {
48
+ message: string;
49
+ status?: number | null;
50
+ code?: string | null;
51
+ });
52
+ }
39
53
  export declare function fetchGraphQL<T = any>(auth: MentionAuthContext, query: string, variables?: Record<string, any>): Promise<T>;
40
54
  export declare const SIMPLE_SEARCH_QUERY = "\n query SimpleSearch($input: SimpleSearchRequestInput!) {\n simpleSearch(input: $input) {\n assets {\n \n id\n title\n athenaOriginalType\n athenaConvertedType\n parentFolderId\n updatedAt\n isFavorited\n isArchived\n isHidden\n\n }\n totalCount\n }\n }\n";
41
55
  export declare const PAGINATED_ASSETS_QUERY = "\n query GetPaginatedAssetsForWorkspace(\n $limit: Int!\n $offset: Int!\n $parentFolderId: String\n $filterTypes: [String!]\n $filterColumns: ColumnFilter\n ) {\n getPaginatedAssetsForWorkspace(\n limit: $limit\n offset: $offset\n parentFolderId: $parentFolderId\n filterTypes: $filterTypes\n filterColumns: $filterColumns\n ) {\n \n id\n title\n athenaOriginalType\n athenaConvertedType\n parentFolderId\n updatedAt\n isFavorited\n isArchived\n isHidden\n\n }\n }\n";
@@ -1,3 +1,6 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1
4
  import { createContext, useContext } from "react";
2
5
  function mentionRequestInit(auth) {
3
6
  if (auth.accessToken) {
@@ -13,6 +16,27 @@ function useMentionAuth() {
13
16
  if (!ctx) throw new Error("MentionAuthCtx not provided");
14
17
  return ctx;
15
18
  }
19
+ class AthenaGraphQLError extends Error {
20
+ constructor({
21
+ message,
22
+ status = null,
23
+ code = null
24
+ }) {
25
+ super(message);
26
+ __publicField(this, "status");
27
+ __publicField(this, "code");
28
+ this.name = "AthenaGraphQLError";
29
+ this.status = status;
30
+ this.code = code;
31
+ }
32
+ }
33
+ function graphQLErrorCode(entry) {
34
+ if (typeof entry !== "object" || entry === null) return null;
35
+ const extensions = Reflect.get(entry, "extensions");
36
+ if (typeof extensions !== "object" || extensions === null) return null;
37
+ const code = Reflect.get(extensions, "code");
38
+ return typeof code === "string" ? code : null;
39
+ }
16
40
  async function fetchGraphQL(auth, query, variables = {}) {
17
41
  var _a;
18
42
  const url = `${auth.backendUrl.replace(/\/+$/, "")}/graphql`;
@@ -37,11 +61,17 @@ async function fetchGraphQL(auth, query, variables = {}) {
37
61
  }
38
62
  }
39
63
  if (!response.ok) {
40
- throw new Error(`GraphQL HTTP ${response.status}: ${response.statusText}`);
64
+ throw new AthenaGraphQLError({
65
+ message: `GraphQL HTTP ${response.status}: ${response.statusText}`,
66
+ status: response.status
67
+ });
41
68
  }
42
69
  const result = await response.json();
43
70
  if ((_a = result.errors) == null ? void 0 : _a.length) {
44
- throw new Error(`GraphQL error: ${result.errors[0].message}`);
71
+ throw new AthenaGraphQLError({
72
+ message: `GraphQL error: ${result.errors[0].message}`,
73
+ code: graphQLErrorCode(result.errors[0])
74
+ });
45
75
  }
46
76
  return result.data;
47
77
  }
@@ -121,6 +151,7 @@ const TOOL_CATALOG_QUERY = `
121
151
  }
122
152
  `;
123
153
  export {
154
+ AthenaGraphQLError,
124
155
  MentionAuthCtx,
125
156
  PAGINATED_ASSETS_QUERY,
126
157
  SIMPLE_SEARCH_QUERY,
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.js","sources":["../../../../../src/chat-ui/mentions/suggestions/data/api-client.ts"],"sourcesContent":["/**\n * API client for mention data fetching.\n *\n * Wraps raw fetch() with GraphQL support. Hosts authenticate with either a\n * bearer token or a workspace API key; agora's /graphql accepts both.\n */\n\nimport { createContext, useContext } from \"react\";\n\n// ── Auth context ──\n\nexport interface MentionAuthContext {\n backendUrl: string;\n appUrl?: string;\n /** Bearer credential; hosts without one authenticate with `apiKey`. */\n accessToken?: string;\n /**\n * Resolve a current bearer before each query (for rotating Office sessions).\n * Resolving nothing falls back to `accessToken`, then the API key.\n */\n getAccessToken?: () => Promise<string | null | undefined>;\n /**\n * Renew the bearer after the backend refused it (401), for one resend of\n * the query. Without it, or when it resolves nothing, a refused query fails\n * as before.\n */\n renewAccessToken?: () => Promise<string | null | undefined>;\n apiKey?: string;\n /**\n * With neither credential, ride the browser's same-origin session cookie\n * instead of failing — the SDK's AthenaChat, whose REST helpers make the\n * same choice for a host that configured no token and no API key. Hosts\n * that always hold a credential leave this unset so an accidental anonymous\n * query fails loudly.\n */\n credentials?: \"include\";\n workspaceId?: string;\n userId?: string;\n}\n\n/** Credential headers (or the cookie lane) for a mention fetch. */\nexport function mentionRequestInit(\n auth: MentionAuthContext,\n): Pick<RequestInit, \"headers\" | \"credentials\"> {\n if (auth.accessToken) {\n return { headers: { Authorization: `Bearer ${auth.accessToken}` } };\n }\n if (auth.apiKey) return { headers: { \"X-API-KEY\": auth.apiKey } };\n if (auth.credentials) return { headers: {}, credentials: auth.credentials };\n throw new Error(\"MentionAuthCtx needs either an accessToken or an apiKey\");\n}\n\nexport const MentionAuthCtx = createContext<MentionAuthContext | null>(null);\n\nexport function useMentionAuth(): MentionAuthContext {\n const ctx = useContext(MentionAuthCtx);\n if (!ctx) throw new Error(\"MentionAuthCtx not provided\");\n return ctx;\n}\n\n// ── GraphQL client ──\n\nexport async function fetchGraphQL<T = any>(\n auth: MentionAuthContext,\n query: string,\n variables: Record<string, any> = {},\n): Promise<T> {\n const url = `${auth.backendUrl.replace(/\\/+$/, \"\")}/graphql`;\n const send = (requestAuth: MentionAuthContext) => {\n const { headers, credentials } = mentionRequestInit(requestAuth);\n return fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...headers,\n },\n ...(credentials ? { credentials } : {}),\n body: JSON.stringify({ query, variables }),\n });\n };\n const requestAuth = auth.getAccessToken\n ? { ...auth, accessToken: (await auth.getAccessToken()) ?? auth.accessToken }\n : auth;\n let response = await send(requestAuth);\n // A refused bearer gets one renewal and a resend (the statewire transport's\n // `staleAuth` contract); an API-key or cookie request has nothing to renew.\n if (response.status === 401 && requestAuth.accessToken && auth.renewAccessToken) {\n const renewed = await auth.renewAccessToken();\n // The same token again (a static one) would only be refused again.\n if (renewed && renewed !== requestAuth.accessToken) {\n response = await send({ ...auth, accessToken: renewed });\n }\n }\n\n if (!response.ok) {\n throw new Error(`GraphQL HTTP ${response.status}: ${response.statusText}`);\n }\n\n const result = await response.json();\n if (result.errors?.length) {\n throw new Error(`GraphQL error: ${result.errors[0].message}`);\n }\n\n return result.data as T;\n}\n\n// ── GraphQL Queries ──\n\n/**\n * Lightweight asset fragment for mention menu items.\n * Only fetches fields needed for display + navigation.\n */\nconst MENTION_ASSET_FIELDS = `\n id\n title\n athenaOriginalType\n athenaConvertedType\n parentFolderId\n updatedAt\n isFavorited\n isArchived\n isHidden\n`;\n\nexport const SIMPLE_SEARCH_QUERY = `\n query SimpleSearch($input: SimpleSearchRequestInput!) {\n simpleSearch(input: $input) {\n assets {\n ${MENTION_ASSET_FIELDS}\n }\n totalCount\n }\n }\n`;\n\nexport const PAGINATED_ASSETS_QUERY = `\n query GetPaginatedAssetsForWorkspace(\n $limit: Int!\n $offset: Int!\n $parentFolderId: String\n $filterTypes: [String!]\n $filterColumns: ColumnFilter\n ) {\n getPaginatedAssetsForWorkspace(\n limit: $limit\n offset: $offset\n parentFolderId: $parentFolderId\n filterTypes: $filterTypes\n filterColumns: $filterColumns\n ) {\n ${MENTION_ASSET_FIELDS}\n }\n }\n`;\n\nexport const WORKSPACE_MEMBERS_QUERY = `\n query GetUsersInWorkspace($workspaceId: String!) {\n getUsersInWorkspace(workspaceId: $workspaceId) {\n id\n email\n firstName\n lastName\n isAdmin\n avatarUrl\n }\n }\n`;\n\nexport const TOOL_CATALOG_QUERY = `\n query MentionToolCatalog {\n getToolkitToToolsMapping {\n tools {\n id\n name\n description\n icon\n adminOnly\n isMentionable\n }\n toolkits {\n name\n displayName\n description\n icon\n onlyAdmin\n hideFromMenu\n isMentionable\n }\n }\n }\n`;\n\n// ── Response types ──\n\nexport interface ToolCatalogTool {\n id: string;\n name: string;\n description: string | null;\n icon: string;\n adminOnly: boolean;\n isMentionable: boolean;\n}\n\nexport interface ToolCatalogToolkit {\n name: string;\n displayName: string;\n description: string;\n icon: string;\n onlyAdmin: boolean;\n hideFromMenu: boolean;\n isMentionable: boolean;\n}\n\nexport interface ToolCatalogResult {\n getToolkitToToolsMapping: {\n tools: ToolCatalogTool[];\n toolkits: ToolCatalogToolkit[];\n };\n}\n\nexport interface AssetResult {\n id: string;\n title: string | null;\n athenaOriginalType: string | null;\n athenaConvertedType: string | null;\n parentFolderId: string | null;\n updatedAt: string | null;\n isFavorited: boolean | null;\n isArchived: boolean | null;\n isHidden: boolean | null;\n}\n\nexport interface WorkspaceMember {\n id: string;\n email: string | null;\n firstName: string | null;\n lastName: string | null;\n isAdmin: boolean;\n avatarUrl: string | null;\n}\n"],"names":["requestAuth"],"mappings":";AAyCO,SAAS,mBACd,MAC8C;AAC9C,MAAI,KAAK,aAAa;AACpB,WAAO,EAAE,SAAS,EAAE,eAAe,UAAU,KAAK,WAAW,KAAG;AAAA,EAClE;AACA,MAAI,KAAK,OAAQ,QAAO,EAAE,SAAS,EAAE,aAAa,KAAK,SAAO;AAC9D,MAAI,KAAK,YAAa,QAAO,EAAE,SAAS,CAAA,GAAI,aAAa,KAAK,YAAA;AAC9D,QAAM,IAAI,MAAM,yDAAyD;AAC3E;AAEO,MAAM,iBAAiB,cAAyC,IAAI;AAEpE,SAAS,iBAAqC;AACnD,QAAM,MAAM,WAAW,cAAc;AACrC,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,6BAA6B;AACvD,SAAO;AACT;AAIA,eAAsB,aACpB,MACA,OACA,YAAiC,CAAA,GACrB;;AACZ,QAAM,MAAM,GAAG,KAAK,WAAW,QAAQ,QAAQ,EAAE,CAAC;AAClD,QAAM,OAAO,CAACA,iBAAoC;AAChD,UAAM,EAAE,SAAS,gBAAgB,mBAAmBA,YAAW;AAC/D,WAAO,MAAM,KAAK;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG;AAAA,MAAA;AAAA,MAEL,GAAI,cAAc,EAAE,YAAA,IAAgB,CAAA;AAAA,MACpC,MAAM,KAAK,UAAU,EAAE,OAAO,WAAW;AAAA,IAAA,CAC1C;AAAA,EACH;AACA,QAAM,cAAc,KAAK,iBACrB,EAAE,GAAG,MAAM,aAAc,MAAM,KAAK,eAAA,KAAqB,KAAK,gBAC9D;AACJ,MAAI,WAAW,MAAM,KAAK,WAAW;AAGrC,MAAI,SAAS,WAAW,OAAO,YAAY,eAAe,KAAK,kBAAkB;AAC/E,UAAM,UAAU,MAAM,KAAK,iBAAA;AAE3B,QAAI,WAAW,YAAY,YAAY,aAAa;AAClD,iBAAW,MAAM,KAAK,EAAE,GAAG,MAAM,aAAa,SAAS;AAAA,IACzD;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,gBAAgB,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,EAC3E;AAEA,QAAM,SAAS,MAAM,SAAS,KAAA;AAC9B,OAAI,YAAO,WAAP,mBAAe,QAAQ;AACzB,UAAM,IAAI,MAAM,kBAAkB,OAAO,OAAO,CAAC,EAAE,OAAO,EAAE;AAAA,EAC9D;AAEA,SAAO,OAAO;AAChB;AAQA,MAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYtB,MAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA,UAIzB,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAOvB,MAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAe9B,oBAAoB;AAAA;AAAA;AAAA;AAKrB,MAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAahC,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
1
+ {"version":3,"file":"api-client.js","sources":["../../../../../src/chat-ui/mentions/suggestions/data/api-client.ts"],"sourcesContent":["/**\n * API client for mention data fetching.\n *\n * Wraps raw fetch() with GraphQL support. Hosts authenticate with either a\n * bearer token or a workspace API key; agora's /graphql accepts both.\n */\n\nimport { createContext, useContext } from \"react\";\n\n// ── Auth context ──\n\nexport interface MentionAuthContext {\n backendUrl: string;\n appUrl?: string;\n /** Bearer credential; hosts without one authenticate with `apiKey`. */\n accessToken?: string;\n /**\n * Resolve a current bearer before each query (for rotating Office sessions).\n * Resolving nothing falls back to `accessToken`, then the API key.\n */\n getAccessToken?: () => Promise<string | null | undefined>;\n /**\n * Renew the bearer after the backend refused it (401), for one resend of\n * the query. Without it, or when it resolves nothing, a refused query fails\n * as before.\n */\n renewAccessToken?: () => Promise<string | null | undefined>;\n apiKey?: string;\n /**\n * With neither credential, ride the browser's same-origin session cookie\n * instead of failing — the SDK's AthenaChat, whose REST helpers make the\n * same choice for a host that configured no token and no API key. Hosts\n * that always hold a credential leave this unset so an accidental anonymous\n * query fails loudly.\n */\n credentials?: \"include\";\n workspaceId?: string;\n userId?: string;\n}\n\n/** Credential headers (or the cookie lane) for a mention fetch. */\nexport function mentionRequestInit(\n auth: MentionAuthContext,\n): Pick<RequestInit, \"headers\" | \"credentials\"> {\n if (auth.accessToken) {\n return { headers: { Authorization: `Bearer ${auth.accessToken}` } };\n }\n if (auth.apiKey) return { headers: { \"X-API-KEY\": auth.apiKey } };\n if (auth.credentials) return { headers: {}, credentials: auth.credentials };\n throw new Error(\"MentionAuthCtx needs either an accessToken or an apiKey\");\n}\n\nexport const MentionAuthCtx = createContext<MentionAuthContext | null>(null);\n\nexport function useMentionAuth(): MentionAuthContext {\n const ctx = useContext(MentionAuthCtx);\n if (!ctx) throw new Error(\"MentionAuthCtx not provided\");\n return ctx;\n}\n\n// ── GraphQL client ──\n\n/**\n * What {@link fetchGraphQL} throws: an HTTP failure (`status`) or the first\n * GraphQL error of the response (`code`, its `extensions.code`, e.g. agora's\n * `UNAUTHORIZED` for an asset the caller cannot read).\n */\nexport class AthenaGraphQLError extends Error {\n readonly status: number | null;\n readonly code: string | null;\n\n constructor({\n message,\n status = null,\n code = null,\n }: {\n message: string;\n status?: number | null;\n code?: string | null;\n }) {\n super(message);\n this.name = \"AthenaGraphQLError\";\n this.status = status;\n this.code = code;\n }\n}\n\n/** The `extensions.code` of a GraphQL error entry, when it carries a string one. */\nfunction graphQLErrorCode(entry: unknown): string | null {\n if (typeof entry !== \"object\" || entry === null) return null;\n const extensions: unknown = Reflect.get(entry, \"extensions\");\n if (typeof extensions !== \"object\" || extensions === null) return null;\n const code: unknown = Reflect.get(extensions, \"code\");\n return typeof code === \"string\" ? code : null;\n}\n\nexport async function fetchGraphQL<T = any>(\n auth: MentionAuthContext,\n query: string,\n variables: Record<string, any> = {},\n): Promise<T> {\n const url = `${auth.backendUrl.replace(/\\/+$/, \"\")}/graphql`;\n const send = (requestAuth: MentionAuthContext) => {\n const { headers, credentials } = mentionRequestInit(requestAuth);\n return fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...headers,\n },\n ...(credentials ? { credentials } : {}),\n body: JSON.stringify({ query, variables }),\n });\n };\n const requestAuth = auth.getAccessToken\n ? { ...auth, accessToken: (await auth.getAccessToken()) ?? auth.accessToken }\n : auth;\n let response = await send(requestAuth);\n // A refused bearer gets one renewal and a resend (the statewire transport's\n // `staleAuth` contract); an API-key or cookie request has nothing to renew.\n if (response.status === 401 && requestAuth.accessToken && auth.renewAccessToken) {\n const renewed = await auth.renewAccessToken();\n // The same token again (a static one) would only be refused again.\n if (renewed && renewed !== requestAuth.accessToken) {\n response = await send({ ...auth, accessToken: renewed });\n }\n }\n\n if (!response.ok) {\n throw new AthenaGraphQLError({\n message: `GraphQL HTTP ${response.status}: ${response.statusText}`,\n status: response.status,\n });\n }\n\n const result = await response.json();\n if (result.errors?.length) {\n throw new AthenaGraphQLError({\n message: `GraphQL error: ${result.errors[0].message}`,\n code: graphQLErrorCode(result.errors[0]),\n });\n }\n\n return result.data as T;\n}\n\n// ── GraphQL Queries ──\n\n/**\n * Lightweight asset fragment for mention menu items.\n * Only fetches fields needed for display + navigation.\n */\nconst MENTION_ASSET_FIELDS = `\n id\n title\n athenaOriginalType\n athenaConvertedType\n parentFolderId\n updatedAt\n isFavorited\n isArchived\n isHidden\n`;\n\nexport const SIMPLE_SEARCH_QUERY = `\n query SimpleSearch($input: SimpleSearchRequestInput!) {\n simpleSearch(input: $input) {\n assets {\n ${MENTION_ASSET_FIELDS}\n }\n totalCount\n }\n }\n`;\n\nexport const PAGINATED_ASSETS_QUERY = `\n query GetPaginatedAssetsForWorkspace(\n $limit: Int!\n $offset: Int!\n $parentFolderId: String\n $filterTypes: [String!]\n $filterColumns: ColumnFilter\n ) {\n getPaginatedAssetsForWorkspace(\n limit: $limit\n offset: $offset\n parentFolderId: $parentFolderId\n filterTypes: $filterTypes\n filterColumns: $filterColumns\n ) {\n ${MENTION_ASSET_FIELDS}\n }\n }\n`;\n\nexport const WORKSPACE_MEMBERS_QUERY = `\n query GetUsersInWorkspace($workspaceId: String!) {\n getUsersInWorkspace(workspaceId: $workspaceId) {\n id\n email\n firstName\n lastName\n isAdmin\n avatarUrl\n }\n }\n`;\n\nexport const TOOL_CATALOG_QUERY = `\n query MentionToolCatalog {\n getToolkitToToolsMapping {\n tools {\n id\n name\n description\n icon\n adminOnly\n isMentionable\n }\n toolkits {\n name\n displayName\n description\n icon\n onlyAdmin\n hideFromMenu\n isMentionable\n }\n }\n }\n`;\n\n// ── Response types ──\n\nexport interface ToolCatalogTool {\n id: string;\n name: string;\n description: string | null;\n icon: string;\n adminOnly: boolean;\n isMentionable: boolean;\n}\n\nexport interface ToolCatalogToolkit {\n name: string;\n displayName: string;\n description: string;\n icon: string;\n onlyAdmin: boolean;\n hideFromMenu: boolean;\n isMentionable: boolean;\n}\n\nexport interface ToolCatalogResult {\n getToolkitToToolsMapping: {\n tools: ToolCatalogTool[];\n toolkits: ToolCatalogToolkit[];\n };\n}\n\nexport interface AssetResult {\n id: string;\n title: string | null;\n athenaOriginalType: string | null;\n athenaConvertedType: string | null;\n parentFolderId: string | null;\n updatedAt: string | null;\n isFavorited: boolean | null;\n isArchived: boolean | null;\n isHidden: boolean | null;\n}\n\nexport interface WorkspaceMember {\n id: string;\n email: string | null;\n firstName: string | null;\n lastName: string | null;\n isAdmin: boolean;\n avatarUrl: string | null;\n}\n"],"names":["requestAuth"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -416,6 +416,7 @@ exports.normalizeAgentCatalog = runtimeCatalog.normalizeAgentCatalog;
416
416
  exports.normalizeModelCatalog = runtimeCatalog.normalizeModelCatalog;
417
417
  exports.resolveCatalogModelId = runtimeCatalog.resolveCatalogModelId;
418
418
  exports.useAthenaAgentCatalog = runtimeCatalog.useAthenaAgentCatalog;
419
+ exports.useAthenaAgentModelOptions = runtimeCatalog.useAthenaAgentModelOptions;
419
420
  exports.useAthenaModelCatalog = runtimeCatalog.useAthenaModelCatalog;
420
421
  exports.useFileUpload = useFileUpload.useFileUpload;
421
422
  exports.FileUploadButton = FileUploadButton.FileUploadButton;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -166,8 +166,9 @@ export type { SendMessageOptions } from './composer/useSendMessage';
166
166
  export { useComposerAttachment } from './composer/useComposerAttachment';
167
167
  export { ChatAgentPicker, ChatModelPicker } from './catalog/chat-pickers';
168
168
  export type { ChatAgentPickerProps, ChatModelPickerProps } from './catalog/chat-pickers';
169
- export { credentialFingerprint, groupModelsByProvider, MODEL_PROVIDER_LABELS, normalizeAgentCatalog, normalizeModelCatalog, resolveCatalogModelId, useAthenaAgentCatalog, useAthenaModelCatalog, } from './catalog/runtime-catalog';
170
- export type { AthenaAgentOption, AthenaModelOption, AthenaModelStatus, } from './catalog/runtime-catalog';
169
+ export { credentialFingerprint, groupModelsByProvider, MODEL_PROVIDER_LABELS, normalizeAgentCatalog, normalizeModelCatalog, resolveCatalogModelId, useAthenaAgentCatalog, useAthenaAgentModelOptions, useAthenaModelCatalog, } from './catalog/runtime-catalog';
170
+ export type { AthenaAgentModelOptions, AthenaAgentModelOptionsStatus, AthenaAgentOption, AthenaModelOption, AthenaModelStatus, } from './catalog/runtime-catalog';
171
+ export type { AthenaAgentModelOption } from './catalog/agent-model-options';
171
172
  export { useFileUpload } from './composer/useFileUpload';
172
173
  export type { UploadedAsset, UploadProgress, UseFileUploadReturn } from './composer/useFileUpload';
173
174
  export { FileUploadButton } from './composer/FileUploadButton';
package/dist/index.js CHANGED
@@ -95,7 +95,7 @@ import { useReadComposerDraft } from "./composer/useReadComposerDraft.js";
95
95
  import { useSendMessage } from "./composer/useSendMessage.js";
96
96
  import { useComposerAttachment } from "./composer/useComposerAttachment.js";
97
97
  import { ChatAgentPicker, ChatModelPicker } from "./catalog/chat-pickers.js";
98
- import { MODEL_PROVIDER_LABELS, credentialFingerprint, groupModelsByProvider, normalizeAgentCatalog, normalizeModelCatalog, resolveCatalogModelId, useAthenaAgentCatalog, useAthenaModelCatalog } from "./catalog/runtime-catalog.js";
98
+ import { MODEL_PROVIDER_LABELS, credentialFingerprint, groupModelsByProvider, normalizeAgentCatalog, normalizeModelCatalog, resolveCatalogModelId, useAthenaAgentCatalog, useAthenaAgentModelOptions, useAthenaModelCatalog } from "./catalog/runtime-catalog.js";
99
99
  import { useFileUpload } from "./composer/useFileUpload.js";
100
100
  import { FileUploadButton } from "./composer/FileUploadButton.js";
101
101
  import { ComposerDropZone } from "./composer/ComposerDropZone.js";
@@ -440,6 +440,7 @@ export {
440
440
  useAssetEmbed,
441
441
  useAssetPanelStore,
442
442
  useAthenaAgentCatalog,
443
+ useAthenaAgentModelOptions,
443
444
  useAthenaCitationLinkHandler,
444
445
  useAthenaComputerSshAccess,
445
446
  useAthenaComputerStatus,
@@ -18,6 +18,9 @@ function fnv1a(text) {
18
18
  }
19
19
  return (hash >>> 0).toString(16).padStart(8, "0");
20
20
  }
21
+ function keyPartFingerprint(text) {
22
+ return fnv1a(text);
23
+ }
21
24
  function credentialFingerprint(auth) {
22
25
  return fnv1a(
23
26
  [auth.apiKey ?? "", auth.token ?? "", auth.getToken === void 0 ? "0" : "1"].join("\0")
@@ -29,6 +32,7 @@ function useAthenaQueryIdentity(auth) {
29
32
  return [principal, credentialFingerprint(auth)];
30
33
  }
31
34
  exports.credentialFingerprint = credentialFingerprint;
35
+ exports.keyPartFingerprint = keyPartFingerprint;
32
36
  exports.useAthenaQueryClient = useAthenaQueryClient;
33
37
  exports.useAthenaQueryIdentity = useAthenaQueryIdentity;
34
38
  //# sourceMappingURL=use-athena-rest-query.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-athena-rest-query.cjs","sources":["../../src/lib/use-athena-rest-query.ts"],"sourcesContent":["/**\n * The two pieces every SDK hook that reads an Agora REST route through\n * TanStack Query needs: a `QueryClient` under any `<AthenaProvider>`, and a\n * query-key component naming who the read is made as — without ever putting\n * the credential itself in a key.\n */\nimport { QueryClient, QueryClientContext } from '@tanstack/react-query';\nimport { useContext, useRef } from 'react';\nimport { AthenaAuthContext } from '../auth/AthenaAuthContext';\nimport type { StatewireAuthSource } from '../runtime/statewire-auth-headers';\n\n/**\n * The host's `QueryClient` when one is in context (`enableThreadList` mounts\n * the SDK's own), else a client scoped to the calling hook's component.\n */\nexport function useAthenaQueryClient(): QueryClient {\n const contextClient = useContext(QueryClientContext);\n const fallbackRef = useRef<QueryClient | null>(null);\n if (contextClient) return contextClient;\n fallbackRef.current ??= new QueryClient();\n return fallbackRef.current;\n}\n\n/** 32-bit FNV-1a of `text`, as hex. */\nfunction fnv1a(text: string): string {\n let hash = 0x811c9dc5;\n for (let index = 0; index < text.length; index += 1) {\n hash ^= text.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\n/**\n * A short, one-way fingerprint of the credential a request presents (the API\n * key, the token the host holds, whether a live `getToken` resolves it). It is\n * the same for every hook and every mount that reads with the same\n * credential, and different once the credential changes, so a cache entry\n * written with one credential is never read with another — while the key\n * itself carries 32 bits of hash, never the secret.\n */\nexport function credentialFingerprint(auth: StatewireAuthSource): string {\n return fnv1a(\n [auth.apiKey ?? '', auth.token ?? '', auth.getToken === undefined ? '0' : '1'].join('\\u0000'),\n );\n}\n\n/**\n * Who a query reads as, for its key: the signed-in principal (`''` when the\n * provider knows none) and the credential fingerprint. The principal covers\n * an identity switch the credential cannot show — a stable `getToken`, or a\n * same-origin cookie; the fingerprint covers a swapped API key or token. Both\n * are stable across mounts, so a pane mounted after a switch never reads the\n * previous account's cached answer.\n */\nexport function useAthenaQueryIdentity(auth: StatewireAuthSource): readonly [string, string] {\n const principal = useContext(AthenaAuthContext)?.user?.userId ?? '';\n return [principal, credentialFingerprint(auth)];\n}\n"],"names":["useContext","QueryClientContext","useRef","QueryClient","AthenaAuthContext"],"mappings":";;;;;AAeO,SAAS,uBAAoC;AAClD,QAAM,gBAAgBA,MAAAA,WAAWC,6BAAkB;AACnD,QAAM,cAAcC,MAAAA,OAA2B,IAAI;AACnD,MAAI,cAAe,QAAO;AAC1B,cAAY,YAAZ,YAAY,UAAY,IAAIC,uBAAA;AAC5B,SAAO,YAAY;AACrB;AAGA,SAAS,MAAM,MAAsB;AACnC,MAAI,OAAO;AACX,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,YAAQ,KAAK,WAAW,KAAK;AAC7B,WAAO,KAAK,KAAK,MAAM,QAAU;AAAA,EACnC;AACA,UAAQ,SAAS,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAClD;AAUO,SAAS,sBAAsB,MAAmC;AACvE,SAAO;AAAA,IACL,CAAC,KAAK,UAAU,IAAI,KAAK,SAAS,IAAI,KAAK,aAAa,SAAY,MAAM,GAAG,EAAE,KAAK,IAAQ;AAAA,EAAA;AAEhG;AAUO,SAAS,uBAAuB,MAAsD;;AAC3F,QAAM,cAAYH,iBAAAA,WAAWI,kBAAAA,iBAAiB,MAA5BJ,mBAA+B,SAA/BA,mBAAqC,WAAU;AACjE,SAAO,CAAC,WAAW,sBAAsB,IAAI,CAAC;AAChD;;;;"}
1
+ {"version":3,"file":"use-athena-rest-query.cjs","sources":["../../src/lib/use-athena-rest-query.ts"],"sourcesContent":["/**\n * The two pieces every SDK hook that reads an Agora REST route through\n * TanStack Query needs: a `QueryClient` under any `<AthenaProvider>`, and a\n * query-key component naming who the read is made as — without ever putting\n * the credential itself in a key.\n */\nimport { QueryClient, QueryClientContext } from '@tanstack/react-query';\nimport { useContext, useRef } from 'react';\nimport { AthenaAuthContext } from '../auth/AthenaAuthContext';\nimport type { StatewireAuthSource } from '../runtime/statewire-auth-headers';\n\n/**\n * The host's `QueryClient` when one is in context (`enableThreadList` mounts\n * the SDK's own), else a client scoped to the calling hook's component.\n */\nexport function useAthenaQueryClient(): QueryClient {\n const contextClient = useContext(QueryClientContext);\n const fallbackRef = useRef<QueryClient | null>(null);\n if (contextClient) return contextClient;\n fallbackRef.current ??= new QueryClient();\n return fallbackRef.current;\n}\n\n/** 32-bit FNV-1a of `text`, as hex. */\nfunction fnv1a(text: string): string {\n let hash = 0x811c9dc5;\n for (let index = 0; index < text.length; index += 1) {\n hash ^= text.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\n/**\n * A one-way fingerprint of a query-key part that can carry a credential (an\n * opaque token or an API key inside an identity string), so the key names\n * whose it is without holding the secret.\n */\nexport function keyPartFingerprint(text: string): string {\n return fnv1a(text);\n}\n\n/**\n * A short, one-way fingerprint of the credential a request presents (the API\n * key, the token the host holds, whether a live `getToken` resolves it). It is\n * the same for every hook and every mount that reads with the same\n * credential, and different once the credential changes, so a cache entry\n * written with one credential is never read with another — while the key\n * itself carries 32 bits of hash, never the secret.\n */\nexport function credentialFingerprint(auth: StatewireAuthSource): string {\n return fnv1a(\n [auth.apiKey ?? '', auth.token ?? '', auth.getToken === undefined ? '0' : '1'].join('\\u0000'),\n );\n}\n\n/**\n * Who a query reads as, for its key: the signed-in principal (`''` when the\n * provider knows none) and the credential fingerprint. The principal covers\n * an identity switch the credential cannot show — a stable `getToken`, or a\n * same-origin cookie; the fingerprint covers a swapped API key or token. Both\n * are stable across mounts, so a pane mounted after a switch never reads the\n * previous account's cached answer.\n */\nexport function useAthenaQueryIdentity(auth: StatewireAuthSource): readonly [string, string] {\n const principal = useContext(AthenaAuthContext)?.user?.userId ?? '';\n return [principal, credentialFingerprint(auth)];\n}\n"],"names":["useContext","QueryClientContext","useRef","QueryClient","AthenaAuthContext"],"mappings":";;;;;AAeO,SAAS,uBAAoC;AAClD,QAAM,gBAAgBA,MAAAA,WAAWC,6BAAkB;AACnD,QAAM,cAAcC,MAAAA,OAA2B,IAAI;AACnD,MAAI,cAAe,QAAO;AAC1B,cAAY,YAAZ,YAAY,UAAY,IAAIC,uBAAA;AAC5B,SAAO,YAAY;AACrB;AAGA,SAAS,MAAM,MAAsB;AACnC,MAAI,OAAO;AACX,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,YAAQ,KAAK,WAAW,KAAK;AAC7B,WAAO,KAAK,KAAK,MAAM,QAAU;AAAA,EACnC;AACA,UAAQ,SAAS,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAClD;AAOO,SAAS,mBAAmB,MAAsB;AACvD,SAAO,MAAM,IAAI;AACnB;AAUO,SAAS,sBAAsB,MAAmC;AACvE,SAAO;AAAA,IACL,CAAC,KAAK,UAAU,IAAI,KAAK,SAAS,IAAI,KAAK,aAAa,SAAY,MAAM,GAAG,EAAE,KAAK,IAAQ;AAAA,EAAA;AAEhG;AAUO,SAAS,uBAAuB,MAAsD;;AAC3F,QAAM,cAAYH,iBAAAA,WAAWI,kBAAAA,iBAAiB,MAA5BJ,mBAA+B,SAA/BA,mBAAqC,WAAU;AACjE,SAAO,CAAC,WAAW,sBAAsB,IAAI,CAAC;AAChD;;;;;"}
@@ -11,6 +11,12 @@ import type { StatewireAuthSource } from '../runtime/statewire-auth-headers';
11
11
  * the SDK's own), else a client scoped to the calling hook's component.
12
12
  */
13
13
  export declare function useAthenaQueryClient(): QueryClient;
14
+ /**
15
+ * A one-way fingerprint of a query-key part that can carry a credential (an
16
+ * opaque token or an API key inside an identity string), so the key names
17
+ * whose it is without holding the secret.
18
+ */
19
+ export declare function keyPartFingerprint(text: string): string;
14
20
  /**
15
21
  * A short, one-way fingerprint of the credential a request presents (the API
16
22
  * key, the token the host holds, whether a live `getToken` resolves it). It is
@@ -16,6 +16,9 @@ function fnv1a(text) {
16
16
  }
17
17
  return (hash >>> 0).toString(16).padStart(8, "0");
18
18
  }
19
+ function keyPartFingerprint(text) {
20
+ return fnv1a(text);
21
+ }
19
22
  function credentialFingerprint(auth) {
20
23
  return fnv1a(
21
24
  [auth.apiKey ?? "", auth.token ?? "", auth.getToken === void 0 ? "0" : "1"].join("\0")
@@ -28,6 +31,7 @@ function useAthenaQueryIdentity(auth) {
28
31
  }
29
32
  export {
30
33
  credentialFingerprint,
34
+ keyPartFingerprint,
31
35
  useAthenaQueryClient,
32
36
  useAthenaQueryIdentity
33
37
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use-athena-rest-query.js","sources":["../../src/lib/use-athena-rest-query.ts"],"sourcesContent":["/**\n * The two pieces every SDK hook that reads an Agora REST route through\n * TanStack Query needs: a `QueryClient` under any `<AthenaProvider>`, and a\n * query-key component naming who the read is made as — without ever putting\n * the credential itself in a key.\n */\nimport { QueryClient, QueryClientContext } from '@tanstack/react-query';\nimport { useContext, useRef } from 'react';\nimport { AthenaAuthContext } from '../auth/AthenaAuthContext';\nimport type { StatewireAuthSource } from '../runtime/statewire-auth-headers';\n\n/**\n * The host's `QueryClient` when one is in context (`enableThreadList` mounts\n * the SDK's own), else a client scoped to the calling hook's component.\n */\nexport function useAthenaQueryClient(): QueryClient {\n const contextClient = useContext(QueryClientContext);\n const fallbackRef = useRef<QueryClient | null>(null);\n if (contextClient) return contextClient;\n fallbackRef.current ??= new QueryClient();\n return fallbackRef.current;\n}\n\n/** 32-bit FNV-1a of `text`, as hex. */\nfunction fnv1a(text: string): string {\n let hash = 0x811c9dc5;\n for (let index = 0; index < text.length; index += 1) {\n hash ^= text.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\n/**\n * A short, one-way fingerprint of the credential a request presents (the API\n * key, the token the host holds, whether a live `getToken` resolves it). It is\n * the same for every hook and every mount that reads with the same\n * credential, and different once the credential changes, so a cache entry\n * written with one credential is never read with another — while the key\n * itself carries 32 bits of hash, never the secret.\n */\nexport function credentialFingerprint(auth: StatewireAuthSource): string {\n return fnv1a(\n [auth.apiKey ?? '', auth.token ?? '', auth.getToken === undefined ? '0' : '1'].join('\\u0000'),\n );\n}\n\n/**\n * Who a query reads as, for its key: the signed-in principal (`''` when the\n * provider knows none) and the credential fingerprint. The principal covers\n * an identity switch the credential cannot show — a stable `getToken`, or a\n * same-origin cookie; the fingerprint covers a swapped API key or token. Both\n * are stable across mounts, so a pane mounted after a switch never reads the\n * previous account's cached answer.\n */\nexport function useAthenaQueryIdentity(auth: StatewireAuthSource): readonly [string, string] {\n const principal = useContext(AthenaAuthContext)?.user?.userId ?? '';\n return [principal, credentialFingerprint(auth)];\n}\n"],"names":[],"mappings":";;;AAeO,SAAS,uBAAoC;AAClD,QAAM,gBAAgB,WAAW,kBAAkB;AACnD,QAAM,cAAc,OAA2B,IAAI;AACnD,MAAI,cAAe,QAAO;AAC1B,cAAY,YAAZ,YAAY,UAAY,IAAI,YAAA;AAC5B,SAAO,YAAY;AACrB;AAGA,SAAS,MAAM,MAAsB;AACnC,MAAI,OAAO;AACX,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,YAAQ,KAAK,WAAW,KAAK;AAC7B,WAAO,KAAK,KAAK,MAAM,QAAU;AAAA,EACnC;AACA,UAAQ,SAAS,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAClD;AAUO,SAAS,sBAAsB,MAAmC;AACvE,SAAO;AAAA,IACL,CAAC,KAAK,UAAU,IAAI,KAAK,SAAS,IAAI,KAAK,aAAa,SAAY,MAAM,GAAG,EAAE,KAAK,IAAQ;AAAA,EAAA;AAEhG;AAUO,SAAS,uBAAuB,MAAsD;;AAC3F,QAAM,cAAY,sBAAW,iBAAiB,MAA5B,mBAA+B,SAA/B,mBAAqC,WAAU;AACjE,SAAO,CAAC,WAAW,sBAAsB,IAAI,CAAC;AAChD;"}
1
+ {"version":3,"file":"use-athena-rest-query.js","sources":["../../src/lib/use-athena-rest-query.ts"],"sourcesContent":["/**\n * The two pieces every SDK hook that reads an Agora REST route through\n * TanStack Query needs: a `QueryClient` under any `<AthenaProvider>`, and a\n * query-key component naming who the read is made as — without ever putting\n * the credential itself in a key.\n */\nimport { QueryClient, QueryClientContext } from '@tanstack/react-query';\nimport { useContext, useRef } from 'react';\nimport { AthenaAuthContext } from '../auth/AthenaAuthContext';\nimport type { StatewireAuthSource } from '../runtime/statewire-auth-headers';\n\n/**\n * The host's `QueryClient` when one is in context (`enableThreadList` mounts\n * the SDK's own), else a client scoped to the calling hook's component.\n */\nexport function useAthenaQueryClient(): QueryClient {\n const contextClient = useContext(QueryClientContext);\n const fallbackRef = useRef<QueryClient | null>(null);\n if (contextClient) return contextClient;\n fallbackRef.current ??= new QueryClient();\n return fallbackRef.current;\n}\n\n/** 32-bit FNV-1a of `text`, as hex. */\nfunction fnv1a(text: string): string {\n let hash = 0x811c9dc5;\n for (let index = 0; index < text.length; index += 1) {\n hash ^= text.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\n/**\n * A one-way fingerprint of a query-key part that can carry a credential (an\n * opaque token or an API key inside an identity string), so the key names\n * whose it is without holding the secret.\n */\nexport function keyPartFingerprint(text: string): string {\n return fnv1a(text);\n}\n\n/**\n * A short, one-way fingerprint of the credential a request presents (the API\n * key, the token the host holds, whether a live `getToken` resolves it). It is\n * the same for every hook and every mount that reads with the same\n * credential, and different once the credential changes, so a cache entry\n * written with one credential is never read with another — while the key\n * itself carries 32 bits of hash, never the secret.\n */\nexport function credentialFingerprint(auth: StatewireAuthSource): string {\n return fnv1a(\n [auth.apiKey ?? '', auth.token ?? '', auth.getToken === undefined ? '0' : '1'].join('\\u0000'),\n );\n}\n\n/**\n * Who a query reads as, for its key: the signed-in principal (`''` when the\n * provider knows none) and the credential fingerprint. The principal covers\n * an identity switch the credential cannot show — a stable `getToken`, or a\n * same-origin cookie; the fingerprint covers a swapped API key or token. Both\n * are stable across mounts, so a pane mounted after a switch never reads the\n * previous account's cached answer.\n */\nexport function useAthenaQueryIdentity(auth: StatewireAuthSource): readonly [string, string] {\n const principal = useContext(AthenaAuthContext)?.user?.userId ?? '';\n return [principal, credentialFingerprint(auth)];\n}\n"],"names":[],"mappings":";;;AAeO,SAAS,uBAAoC;AAClD,QAAM,gBAAgB,WAAW,kBAAkB;AACnD,QAAM,cAAc,OAA2B,IAAI;AACnD,MAAI,cAAe,QAAO;AAC1B,cAAY,YAAZ,YAAY,UAAY,IAAI,YAAA;AAC5B,SAAO,YAAY;AACrB;AAGA,SAAS,MAAM,MAAsB;AACnC,MAAI,OAAO;AACX,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,YAAQ,KAAK,WAAW,KAAK;AAC7B,WAAO,KAAK,KAAK,MAAM,QAAU;AAAA,EACnC;AACA,UAAQ,SAAS,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAClD;AAOO,SAAS,mBAAmB,MAAsB;AACvD,SAAO,MAAM,IAAI;AACnB;AAUO,SAAS,sBAAsB,MAAmC;AACvE,SAAO;AAAA,IACL,CAAC,KAAK,UAAU,IAAI,KAAK,SAAS,IAAI,KAAK,aAAa,SAAY,MAAM,GAAG,EAAE,KAAK,IAAQ;AAAA,EAAA;AAEhG;AAUO,SAAS,uBAAuB,MAAsD;;AAC3F,QAAM,cAAY,sBAAW,iBAAiB,MAA5B,mBAA+B,SAA/B,mBAAqC,WAAU;AACjE,SAAO,CAAC,WAAW,sBAAsB,IAAI,CAAC;AAChD;"}
@@ -13,12 +13,13 @@ const authRefusalRestart = require("../runtime/auth-refusal-restart.cjs");
13
13
  const useAthenaStatewireRuntime = require("../runtime/useAthenaStatewireRuntime.cjs");
14
14
  const statewireLifecycle = require("../runtime/statewire-lifecycle.cjs");
15
15
  const statewireRunConfig = require("../runtime/statewire-run-config.cjs");
16
+ const statewireThreadConfigLane = require("../runtime/statewire-thread-config-lane.cjs");
16
17
  const mintThreadId = require("../threads/mint-thread-id.cjs");
17
18
  const statewireLifecycleContext = require("./statewire-lifecycle-context.cjs");
18
19
  const composerHandoff = require("../composer/composer-handoff.cjs");
19
20
  const statewireWindowContext = require("./statewire-window-context.cjs");
20
21
  const StatewireClientToolBridge = require("../chat/StatewireClientToolBridge.cjs");
21
- const StatewireModelLaneSync = require("../runtime/StatewireModelLaneSync.cjs");
22
+ const StatewireThreadConfigLaneSync = require("../runtime/StatewireThreadConfigLaneSync.cjs");
22
23
  const statewireServerLaneContext = require("../runtime/statewire-server-lane-context.cjs");
23
24
  const athenaDiagnostics = require("../diagnostics/athena-diagnostics.cjs");
24
25
  const errors = require("../diagnostics/errors.cjs");
@@ -26,6 +27,7 @@ const statewireClientTools = require("../chat/statewire-client-tools.cjs");
26
27
  const tooltip = require("../ui/tooltip.cjs");
27
28
  const autoOpenTools = require("../tools/auto-open-tools.cjs");
28
29
  const AthenaContext = require("./AthenaContext.cjs");
30
+ const agentSelectionContext = require("./agent-selection-context.cjs");
29
31
  const threadIdContext = require("../threads/thread-id-context.cjs");
30
32
  const statewireThreadList = require("../threads/statewire-thread-list.cjs");
31
33
  const assetPanelStore = require("../assets/asset-panel-store.cjs");
@@ -96,6 +98,11 @@ function ComposerHandoffDrain() {
96
98
  }, [aui, ready, store, threadId]);
97
99
  return null;
98
100
  }
101
+ function useProviderThreadConfig(inputs) {
102
+ const value = statewireThreadConfigLane.providerThreadConfig(inputs);
103
+ const key = JSON.stringify(value);
104
+ return react.useMemo(() => value, [key]);
105
+ }
99
106
  function AthenaStatewireRuntimeMount({
100
107
  threadId,
101
108
  isNewChat,
@@ -182,7 +189,15 @@ function AthenaStatewireRuntimeMount({
182
189
  }),
183
190
  [lifecycle, dismissError]
184
191
  );
185
- const sendModel = statewireRunConfig.effectiveStatewireModel({ model, extraRunConfig });
192
+ const threadConfig = useProviderThreadConfig({
193
+ model,
194
+ systemPrompt,
195
+ tools,
196
+ frontendToolIds,
197
+ workbench,
198
+ knowledgeBase,
199
+ extraRunConfig
200
+ });
186
201
  const snapshot = react.useMemo(
187
202
  () => ({
188
203
  threadId,
@@ -190,9 +205,9 @@ function AthenaStatewireRuntimeMount({
190
205
  client,
191
206
  lifecycle: lifecycleValue,
192
207
  serverLane,
193
- model: sendModel
208
+ threadConfig
194
209
  }),
195
- [threadId, isNewChat, client, lifecycleValue, serverLane, sendModel]
210
+ [threadId, isNewChat, client, lifecycleValue, serverLane, threadConfig]
196
211
  );
197
212
  react.useLayoutEffect(() => {
198
213
  onPublish(snapshot);
@@ -246,10 +261,10 @@ function AthenaStatewireStandalone({
246
261
  const scope = published && /* @__PURE__ */ jsxRuntime.jsx(react$1.AuiProvider, { value: published.client, children: /* @__PURE__ */ jsxRuntime.jsx(AthenaContext.AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsxRuntime.jsx(threadIdContext.AthenaStatewireThreadIdContext.Provider, { value: published.threadId, children: /* @__PURE__ */ jsxRuntime.jsx(statewireLifecycleContext.AthenaStatewireLifecycleContext.Provider, { value: published.lifecycle, children: /* @__PURE__ */ jsxRuntime.jsx(threadStatus.DeepAgentConnectionContext.Provider, { value: published.lifecycle.connection, children: /* @__PURE__ */ jsxRuntime.jsx(statewireServerLaneContext.AthenaStatewireServerLaneContext.Provider, { value: published.serverLane, children: /* @__PURE__ */ jsxRuntime.jsx(statewireWindowContext.StatewireToolOutputsContext.Provider, { value: runtimeProps.toolOutputs, children: /* @__PURE__ */ jsxRuntime.jsxs(tooltip.TooltipProvider, { children: [
247
262
  /* @__PURE__ */ jsxRuntime.jsx(StatewireClientToolBridge.StatewireClientToolBridge, { tools: clientTools, threadId: published.threadId }),
248
263
  /* @__PURE__ */ jsxRuntime.jsx(
249
- StatewireModelLaneSync.StatewireModelLaneSync,
264
+ StatewireThreadConfigLaneSync.StatewireThreadConfigLaneSync,
250
265
  {
251
266
  threadId: published.threadId,
252
- model: published.model,
267
+ config: published.threadConfig,
253
268
  lane: published.serverLane,
254
269
  channelLive: statewireLifecycle.isStatewireChannelLive(published.lifecycle.connection)
255
270
  },
@@ -385,7 +400,13 @@ function AthenaProvider({
385
400
  onError
386
401
  }) {
387
402
  var _a;
388
- statewireRunConfig.resolveAgentProp({ agent });
403
+ const agentAssetId = statewireRunConfig.resolveAgentProp({ agent });
404
+ const trimmedChannel = (channel == null ? void 0 : channel.trim()) ?? "";
405
+ const agentChannel = agentAssetId && trimmedChannel !== "" ? trimmedChannel : null;
406
+ const agentSelection = react.useMemo(
407
+ () => ({ agentAssetId, channel: agentChannel }),
408
+ [agentAssetId, agentChannel]
409
+ );
389
410
  const onDiagnosticRef = react.useRef(onDiagnostic);
390
411
  onDiagnosticRef.current = onDiagnostic;
391
412
  const onErrorRef = react.useRef(onError);
@@ -554,7 +575,7 @@ function AthenaProvider({
554
575
  {
555
576
  className: themeStyleVars ? "athena-sdk athena-themed" : "athena-sdk",
556
577
  style: themeStyleVars,
557
- children: /* @__PURE__ */ jsxRuntime.jsx(PostHogProvider.PostHogProvider, { config: posthogConfig, children: /* @__PURE__ */ jsxRuntime.jsx(composerHandoff.ComposerHandoffContext.Provider, { value: composerHandoff$1, children: /* @__PURE__ */ jsxRuntime.jsx(themeStyleContext.AthenaThemeStyleContext.Provider, { value: themeStyleVars, children: /* @__PURE__ */ jsxRuntime.jsx(AthenaCredentialSourceContext.AthenaCredentialSourceContext.Provider, { value: credentials, children: inner }) }) }) })
578
+ children: /* @__PURE__ */ jsxRuntime.jsx(PostHogProvider.PostHogProvider, { config: posthogConfig, children: /* @__PURE__ */ jsxRuntime.jsx(composerHandoff.ComposerHandoffContext.Provider, { value: composerHandoff$1, children: /* @__PURE__ */ jsxRuntime.jsx(themeStyleContext.AthenaThemeStyleContext.Provider, { value: themeStyleVars, children: /* @__PURE__ */ jsxRuntime.jsx(AthenaCredentialSourceContext.AthenaCredentialSourceContext.Provider, { value: credentials, children: /* @__PURE__ */ jsxRuntime.jsx(agentSelectionContext.AthenaAgentSelectionContext.Provider, { value: agentSelection, children: inner }) }) }) }) })
558
579
  }
559
580
  );
560
581
  }