@athenaintel/react 0.10.2 → 0.10.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -486,6 +486,27 @@ export declare interface AthenaTheme {
486
486
  threadMaxWidth?: string;
487
487
  }
488
488
 
489
+ /**
490
+ * Public hook for managing thread state and navigation.
491
+ *
492
+ * Wraps the underlying runtime to provide a clean, Athena-branded API
493
+ * for reading the active thread, listing threads, and switching between them.
494
+ *
495
+ * Must be used inside `<AthenaProvider enableThreadList>`.
496
+ */
497
+ export declare interface AthenaThreadManagerState {
498
+ /** The ID of the currently active thread, or null if not yet available. */
499
+ activeThreadId: string | null;
500
+ /** All available (non-archived) thread IDs, sorted by most recent. */
501
+ threadIds: readonly string[];
502
+ /** Whether the thread list is still loading from the backend. */
503
+ isLoading: boolean;
504
+ /** Switch the chat to a different thread by ID. */
505
+ switchToThread: (threadId: string) => Promise<void>;
506
+ /** Create and switch to a new empty thread. */
507
+ switchToNewThread: () => Promise<void>;
508
+ }
509
+
489
510
  /**
490
511
  * Athena user information — a simplified, PropelAuth-agnostic representation.
491
512
  */
@@ -1171,6 +1192,29 @@ export declare const useAthenaLinkClickHandler: () => AthenaLinkClickHandler;
1171
1192
 
1172
1193
  export declare const useAthenaRuntime: (config: AthenaRuntimeConfig) => AssistantRuntime;
1173
1194
 
1195
+ /**
1196
+ * Hook for managing thread navigation.
1197
+ *
1198
+ * Returns `null` when called outside `<AthenaProvider enableThreadList>`
1199
+ * or before the runtime has initialized.
1200
+ *
1201
+ * @example
1202
+ * ```tsx
1203
+ * function MyComponent() {
1204
+ * const threads = useAthenaThreadManager();
1205
+ * if (!threads) return null;
1206
+ *
1207
+ * return (
1208
+ * <div>
1209
+ * <p>Active: {threads.activeThreadId}</p>
1210
+ * <button onClick={() => threads.switchToNewThread()}>New Chat</button>
1211
+ * </div>
1212
+ * );
1213
+ * }
1214
+ * ```
1215
+ */
1216
+ export declare function useAthenaThreadManager(): AthenaThreadManagerState | null;
1217
+
1174
1218
  /**
1175
1219
  * Hook for programmatic composer file attachment control.
1176
1220
  *
package/dist/index.js CHANGED
@@ -1360,8 +1360,8 @@ const createStoreImpl = (createState) => {
1360
1360
  return api;
1361
1361
  };
1362
1362
  const createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);
1363
- const identity = (arg) => arg;
1364
- function useStore$1(api, selector = identity) {
1363
+ const identity$1 = (arg) => arg;
1364
+ function useStore$1(api, selector = identity$1) {
1365
1365
  const slice2 = React__default.useSyncExternalStore(
1366
1366
  api.subscribe,
1367
1367
  React__default.useCallback(() => selector(api.getState()), [api, selector]),
@@ -9571,6 +9571,72 @@ const AssistantRuntimeProviderImpl = ({ children, aui, runtime }) => {
9571
9571
  return jsxs(AssistantProviderBase, { runtime, aui: aui ?? null, children: [jsx(DevToolsRegistration, {}), jsx(ThreadPrimitiveViewportProvider, { children })] });
9572
9572
  };
9573
9573
  const AssistantRuntimeProvider = memo(AssistantRuntimeProviderImpl);
9574
+ const debugVerifyPrototype = (runtime, prototype) => {
9575
+ const unboundMethods = Object.getOwnPropertyNames(prototype).filter((methodStr) => {
9576
+ const descriptor = Object.getOwnPropertyDescriptor(prototype, methodStr);
9577
+ const isMethod = descriptor && typeof descriptor.value === "function";
9578
+ if (!isMethod)
9579
+ return false;
9580
+ const methodName = methodStr;
9581
+ return isMethod && !methodName.startsWith("_") && methodName !== "constructor" && prototype[methodName] === runtime[methodName];
9582
+ });
9583
+ if (unboundMethods.length > 0) {
9584
+ throw new Error(`The following methods are not bound: ${JSON.stringify(unboundMethods)}`);
9585
+ }
9586
+ const prototypePrototype = Object.getPrototypeOf(prototype);
9587
+ if (prototypePrototype && prototypePrototype !== Object.prototype) {
9588
+ debugVerifyPrototype(runtime, prototypePrototype);
9589
+ }
9590
+ };
9591
+ const ensureBinding = (r2) => {
9592
+ var _a2;
9593
+ const runtime = r2;
9594
+ if (runtime.__isBound)
9595
+ return;
9596
+ (_a2 = runtime.__internal_bindMethods) == null ? void 0 : _a2.call(runtime);
9597
+ runtime.__isBound = true;
9598
+ if (process.env.NODE_ENV !== "production") {
9599
+ debugVerifyPrototype(runtime, Object.getPrototypeOf(runtime));
9600
+ }
9601
+ };
9602
+ function useRuntimeStateInternal(runtime, selector = identity) {
9603
+ ensureBinding(runtime);
9604
+ const slice2 = useSyncExternalStore(runtime.subscribe, () => selector(runtime.getState()), () => selector(runtime.getState()));
9605
+ useDebugValue(slice2);
9606
+ return slice2;
9607
+ }
9608
+ const identity = (arg) => arg;
9609
+ function createStateHookForRuntime(useRuntime) {
9610
+ function useStoreHook(param) {
9611
+ let optional = false;
9612
+ let selector;
9613
+ if (typeof param === "function") {
9614
+ selector = param;
9615
+ } else if (param) {
9616
+ optional = !!param.optional;
9617
+ selector = param.selector;
9618
+ }
9619
+ const store = useRuntime({ optional });
9620
+ if (!store)
9621
+ return null;
9622
+ return useRuntimeStateInternal(store, selector);
9623
+ }
9624
+ return useStoreHook;
9625
+ }
9626
+ function useAssistantRuntime(options) {
9627
+ var _a2, _b;
9628
+ const aui = useAui();
9629
+ const runtime = ((_b = (_a2 = aui.threads()).__internal_getAssistantRuntime) == null ? void 0 : _b.call(_a2)) ?? null;
9630
+ if (!runtime && !(options == null ? void 0 : options.optional)) {
9631
+ throw new Error("AssistantRuntime is not available");
9632
+ }
9633
+ return runtime;
9634
+ }
9635
+ const useThreadListRuntime = (opt) => {
9636
+ var _a2;
9637
+ return ((_a2 = useAssistantRuntime(opt)) == null ? void 0 : _a2.threads) ?? null;
9638
+ };
9639
+ const useThreadList = createStateHookForRuntime(useThreadListRuntime);
9574
9640
  function useComposerRuntime(options) {
9575
9641
  const aui = useAui();
9576
9642
  const runtime = useAuiState(() => {
@@ -9582,6 +9648,18 @@ function useComposerRuntime(options) {
9582
9648
  }
9583
9649
  return runtime;
9584
9650
  }
9651
+ function useThreadRuntime(options) {
9652
+ const aui = useAui();
9653
+ const runtime = useAuiState(() => {
9654
+ var _a2, _b;
9655
+ return aui.thread.source ? ((_b = (_a2 = aui.thread()).__internal_getRuntime) == null ? void 0 : _b.call(_a2)) ?? null : null;
9656
+ });
9657
+ if (!runtime && !(options == null ? void 0 : options.optional)) {
9658
+ throw new Error("ThreadRuntime is not available");
9659
+ }
9660
+ return runtime;
9661
+ }
9662
+ const useThread = createStateHookForRuntime(useThreadRuntime);
9585
9663
  function setRef(ref, value) {
9586
9664
  if (typeof ref === "function") {
9587
9665
  return ref(value);
@@ -24957,6 +25035,7 @@ function AthenaWithThreadList({
24957
25035
  linkClicks,
24958
25036
  citationLinks
24959
25037
  }) {
25038
+ var _a2;
24960
25039
  const adapter = useAthenaThreadListAdapter({
24961
25040
  backendUrl,
24962
25041
  apiKey,
@@ -24999,15 +25078,17 @@ function AthenaWithThreadList({
24999
25078
  adapter
25000
25079
  });
25001
25080
  const handleRefresh = useCallback(() => {
25002
- var _a2;
25003
- const core = (_a2 = runtime == null ? void 0 : runtime._core) == null ? void 0 : _a2.threads;
25081
+ var _a3;
25082
+ const core = (_a3 = runtime == null ? void 0 : runtime._core) == null ? void 0 : _a3.threads;
25004
25083
  if (core) {
25005
25084
  core._loadThreadsPromise = void 0;
25006
25085
  core.__internal_load();
25007
25086
  }
25008
25087
  }, [runtime]);
25009
25088
  const previousAuthRefreshKeyRef = useRef(null);
25010
- const authRefreshKey = `${backendUrl}::${apiKey ?? ""}::${token ?? ""}`;
25089
+ const authContext = useContext(AthenaAuthContext);
25090
+ const authUserId = ((_a2 = authContext == null ? void 0 : authContext.user) == null ? void 0 : _a2.userId) ?? "";
25091
+ const authRefreshKey = `${backendUrl}::${apiKey ?? ""}::${authUserId}`;
25011
25092
  useEffect(() => {
25012
25093
  const previousAuthRefreshKey = previousAuthRefreshKeyRef.current;
25013
25094
  previousAuthRefreshKeyRef.current = authRefreshKey;
@@ -64826,11 +64907,24 @@ function highlightSql(code2) {
64826
64907
  i += str.length;
64827
64908
  continue;
64828
64909
  }
64910
+ if (code2.slice(i, i + 2) === "/*") {
64911
+ const end = code2.indexOf("*/", i + 2);
64912
+ const str = end >= 0 ? code2.slice(i, end + 2) : code2.slice(i);
64913
+ result += `<span style="color:var(--aui-syn-comment, #6a9955)">${escapeHtml(str)}</span>`;
64914
+ i += str.length;
64915
+ continue;
64916
+ }
64829
64917
  if (code2[i] === "'" || code2[i] === '"') {
64830
64918
  const q = code2[i];
64831
64919
  let j = i + 1;
64832
- while (j < code2.length && code2[j] !== q) {
64833
- if (code2[j] === "\\") j++;
64920
+ while (j < code2.length) {
64921
+ if (code2[j] === q) {
64922
+ if (j + 1 < code2.length && code2[j + 1] === q) {
64923
+ j += 2;
64924
+ continue;
64925
+ }
64926
+ break;
64927
+ }
64834
64928
  j++;
64835
64929
  }
64836
64930
  const str = code2.slice(i, j + 1);
@@ -64979,9 +65073,11 @@ const RunSqlToolUIImpl = ({
64979
65073
  i
64980
65074
  )) })
64981
65075
  ] }) }),
64982
- parsed.rows.length > 50 && /* @__PURE__ */ jsxs("div", { className: "border-t border-border/30 px-4 py-1.5 text-[10px] text-muted-foreground", children: [
64983
- "Showing first 50 of ",
64984
- parsed.rows.length,
65076
+ (parsed.rows.length > 50 || parsed.rowCount !== null && parsed.rowCount > parsed.rows.length) && /* @__PURE__ */ jsxs("div", { className: "border-t border-border/30 px-4 py-1.5 text-[10px] text-muted-foreground", children: [
65077
+ "Showing first ",
65078
+ Math.min(50, parsed.rows.length),
65079
+ " of ",
65080
+ parsed.rowCount ?? parsed.rows.length,
64985
65081
  " rows"
64986
65082
  ] })
64987
65083
  ] }),
@@ -66490,6 +66586,21 @@ function ThreadListItem() {
66490
66586
  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-left", children: /* @__PURE__ */ jsx(ThreadListItemPrimitiveTitle, { fallback: "Untitled" }) })
66491
66587
  ] }) });
66492
66588
  }
66589
+ function useAthenaThreadManager() {
66590
+ const runtime = useAssistantRuntime({ optional: true });
66591
+ const threadId = useThread({ optional: true, selector: (s) => s.threadId });
66592
+ const threadList = useThreadList({ optional: true });
66593
+ if (!runtime || !threadList) {
66594
+ return null;
66595
+ }
66596
+ return {
66597
+ activeThreadId: threadId ?? null,
66598
+ threadIds: threadList.threadIds,
66599
+ isLoading: threadList.isLoading,
66600
+ switchToThread: (id) => runtime.threads.switchToThread(id),
66601
+ switchToNewThread: () => runtime.threads.switchToNewThread()
66602
+ };
66603
+ }
66493
66604
  function useAppendToComposer() {
66494
66605
  const aui = useAui();
66495
66606
  return useCallback(
@@ -66668,6 +66779,7 @@ export {
66668
66779
  useAthenaConfig,
66669
66780
  useAthenaLinkClickHandler,
66670
66781
  useAthenaRuntime,
66782
+ useAthenaThreadManager,
66671
66783
  useComposerAttachment,
66672
66784
  useFileUpload,
66673
66785
  useMentionSuggestions,