@athenaintel/react 0.10.41-rc.2 → 0.10.41

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.cjs CHANGED
@@ -11393,7 +11393,9 @@ function athenaStatewireErrorNotice(error2) {
11393
11393
  return {
11394
11394
  kind: "command",
11395
11395
  title: "Message was not sent",
11396
- message: error2 instanceof Error && error2.message.length > 0 ? error2.message : "The chat runtime rejected the command. Please try again."
11396
+ // The server's own detail names the actionable reason; the Error message is
11397
+ // generic client-side text like `command rejected (500)`.
11398
+ message: readDetailMessage(rejection == null ? void 0 : rejection.detail) ?? (error2 instanceof Error && error2.message.length > 0 ? error2.message : "The chat runtime rejected the command. Please try again.")
11397
11399
  };
11398
11400
  }
11399
11401
  const AthenaStatewireLifecycleContext = React.createContext(null);
@@ -11421,6 +11423,20 @@ function StatewireClientToolBridge({
11421
11423
  const toolsRef = React.useRef(tools);
11422
11424
  toolsRef.current = tools;
11423
11425
  const pendingRequest = inputRequests == null ? void 0 : inputRequests.find(isPendingClientToolRequest);
11426
+ const ownedClaimsRef = React.useRef(/* @__PURE__ */ new Set());
11427
+ const activeRef = React.useRef(true);
11428
+ const releaseClaim = React.useCallback((claim) => {
11429
+ ownedClaimsRef.current.delete(claim);
11430
+ clientToolRequests.release(claim);
11431
+ }, []);
11432
+ React.useEffect(() => {
11433
+ activeRef.current = true;
11434
+ return () => {
11435
+ activeRef.current = false;
11436
+ for (const claim of ownedClaimsRef.current) clientToolRequests.release(claim);
11437
+ ownedClaimsRef.current.clear();
11438
+ };
11439
+ }, []);
11424
11440
  const liveRequestIdsRef = React.useRef(/* @__PURE__ */ new Set());
11425
11441
  liveRequestIdsRef.current = new Set((inputRequests ?? []).map((request) => request.id));
11426
11442
  const executeRequest = React.useCallback(
@@ -11431,8 +11447,8 @@ function StatewireClientToolBridge({
11431
11447
  const registry2 = new Map(toolsRef.current.map((tool) => [tool.name, tool]));
11432
11448
  const results = {};
11433
11449
  for (const call of calls) {
11434
- if (!liveRequestIdsRef.current.has(request.id)) {
11435
- clientToolRequests.release(requestKey(threadId, request.id));
11450
+ if (!activeRef.current || !liveRequestIdsRef.current.has(request.id)) {
11451
+ releaseClaim(requestKey(threadId, request.id));
11436
11452
  return;
11437
11453
  }
11438
11454
  const tool = registry2.get(call.tool_name);
@@ -11454,8 +11470,8 @@ function StatewireClientToolBridge({
11454
11470
  results[call.interrupt_id] = clientToolErrorEnvelope(error2);
11455
11471
  }
11456
11472
  }
11457
- if (!liveRequestIdsRef.current.has(request.id)) {
11458
- clientToolRequests.release(requestKey(threadId, request.id));
11473
+ if (!activeRef.current || !liveRequestIdsRef.current.has(request.id)) {
11474
+ releaseClaim(requestKey(threadId, request.id));
11459
11475
  return;
11460
11476
  }
11461
11477
  try {
@@ -11465,16 +11481,19 @@ function StatewireClientToolBridge({
11465
11481
  requestId: request.id,
11466
11482
  response: { type: "resume", value: wireValue }
11467
11483
  });
11484
+ ownedClaimsRef.current.delete(requestKey(threadId, request.id));
11468
11485
  } catch (error2) {
11469
- clientToolRequests.release(requestKey(threadId, request.id));
11486
+ releaseClaim(requestKey(threadId, request.id));
11470
11487
  console.error("[AthenaSDK] failed to resume client tool results:", error2);
11471
11488
  }
11472
11489
  },
11473
- [sendCommand, threadId]
11490
+ [releaseClaim, sendCommand, threadId]
11474
11491
  );
11475
11492
  React.useEffect(() => {
11476
11493
  if (!pendingRequest) return;
11477
- if (!clientToolRequests.claim(requestKey(threadId, pendingRequest.id))) return;
11494
+ const claim = requestKey(threadId, pendingRequest.id);
11495
+ if (!clientToolRequests.claim(claim)) return;
11496
+ ownedClaimsRef.current.add(claim);
11478
11497
  void executeRequest(pendingRequest);
11479
11498
  }, [executeRequest, pendingRequest, threadId]);
11480
11499
  return null;
@@ -11489,6 +11508,9 @@ function resolveAthenaTransport({
11489
11508
  }) {
11490
11509
  return { transport: transport ?? DEFAULT_ATHENA_TRANSPORT, fallbackReason: null };
11491
11510
  }
11511
+ function allowsMidRunSend(transport) {
11512
+ return transport === ATHENA_TRANSPORTS.statewire;
11513
+ }
11492
11514
  var __defProp$i = Object.defineProperty;
11493
11515
  var __name$h = (target, value) => __defProp$i(target, "name", { value, configurable: true });
11494
11516
  function setRef$1(ref, value) {
@@ -18824,16 +18846,19 @@ function StatewireThreadListState({
18824
18846
  initialThreadId,
18825
18847
  children
18826
18848
  }) {
18849
+ var _a3;
18827
18850
  const [active, setActive] = React.useState(
18828
18851
  () => initialThreadId ? { id: initialThreadId, isNew: false } : { id: mintThreadId(), isNew: true }
18829
18852
  );
18830
18853
  const tokenRef = React.useRef(token);
18831
18854
  tokenRef.current = token;
18855
+ const authContext = React.useContext(AthenaAuthContext.AthenaAuthContext);
18856
+ const principal = ((_a3 = authContext == null ? void 0 : authContext.user) == null ? void 0 : _a3.userId) ?? "";
18832
18857
  const hasAuth = !!(apiKey || token);
18833
18858
  const { data, isLoading, refetch } = useQuery({
18834
- // Keyed on the user identity surface, not the raw token — token rotation
18835
- // for the same session must not refetch the whole list.
18836
- queryKey: [THREADS_QUERY_KEY, backendUrl, appId ?? "", apiKey ?? "", hasAuth],
18859
+ queryKey: [THREADS_QUERY_KEY, backendUrl, appId ?? "", principal, hasAuth],
18860
+ // Never serve another principal's list while the new one loads.
18861
+ placeholderData: void 0,
18837
18862
  queryFn: async () => {
18838
18863
  const { threads } = await listThreads(
18839
18864
  backendUrl,
@@ -18851,6 +18876,7 @@ function StatewireThreadListState({
18851
18876
  void refetch();
18852
18877
  }, [refetch]);
18853
18878
  const selectThread = React.useCallback((threadId) => {
18879
+ if (!threadId) return;
18854
18880
  setActive(
18855
18881
  (current) => current.id === threadId ? current : { id: threadId, isNew: false }
18856
18882
  );
@@ -18858,6 +18884,12 @@ function StatewireThreadListState({
18858
18884
  const newThread = React.useCallback(() => {
18859
18885
  setActive({ id: mintThreadId(), isNew: true });
18860
18886
  }, []);
18887
+ const isPersisted = !!(data == null ? void 0 : data.some((thread) => thread.id === active.id));
18888
+ React.useEffect(() => {
18889
+ if (isPersisted) {
18890
+ setActive((current) => current.isNew ? { ...current, isNew: false } : current);
18891
+ }
18892
+ }, [isPersisted]);
18861
18893
  const value = React.useMemo(
18862
18894
  () => ({
18863
18895
  threads: data ?? [],
@@ -19027,8 +19059,6 @@ function useAthenaThreadManager() {
19027
19059
  const statewireManager = React.useMemo(() => {
19028
19060
  if (!statewireList) return null;
19029
19061
  return {
19030
- // A never-started local chat stays out of the URL, mirroring the
19031
- // legacy manager's local-placeholder handling.
19032
19062
  activeThreadId: statewireList.isNewChat ? null : statewireList.activeThreadId,
19033
19063
  isListLoading: statewireList.isLoading,
19034
19064
  isThreadLoading: statewireIsThreadLoading,
@@ -19858,9 +19888,16 @@ const initialStatewireLifecycle = {
19858
19888
  reconnect: null
19859
19889
  };
19860
19890
  function statewireLifecycleReducer(state, action) {
19891
+ var _a3, _b2;
19861
19892
  switch (action.type) {
19862
- case "connection":
19863
- return { ...state, connection: action.connection };
19893
+ case "connection": {
19894
+ const healthy = ((_a3 = action.connection) == null ? void 0 : _a3.status) === "live" || ((_b2 = action.connection) == null ? void 0 : _b2.status) === "idle";
19895
+ return {
19896
+ ...state,
19897
+ connection: action.connection,
19898
+ error: healthy ? null : state.error
19899
+ };
19900
+ }
19864
19901
  case "error":
19865
19902
  return { ...state, error: action.error };
19866
19903
  case "legacy-read-only":
@@ -20226,6 +20263,8 @@ function AthenaProvider({
20226
20263
  const configuredAppUrl = (config2 == null ? void 0 : config2.appUrl) ?? appUrl;
20227
20264
  const configuredTransport = (config2 == null ? void 0 : config2.transport) ?? transport;
20228
20265
  const configuredStatewireSyncUrl = (config2 == null ? void 0 : config2.statewireSyncUrl) ?? statewireSyncUrl;
20266
+ const configuredGetToken = (config2 == null ? void 0 : config2.getToken) ?? getToken;
20267
+ const configuredExtraRunConfig = (config2 == null ? void 0 : config2.extraRunConfig) ?? extraRunConfig;
20229
20268
  const configuredTrustedParentOrigins = config2 == null ? void 0 : config2.trustedParentOrigins;
20230
20269
  const posthogConfig = (config2 == null ? void 0 : config2.posthog) ?? posthogProp;
20231
20270
  const { transport: effectiveTransport, fallbackReason: transportFallbackReason } = resolveAthenaTransport({
@@ -20260,7 +20299,7 @@ function AthenaProvider({
20260
20299
  appUrl: effectiveAppUrl,
20261
20300
  apiKey: configuredApiKey,
20262
20301
  token: effectiveToken,
20263
- getToken,
20302
+ getToken: configuredGetToken,
20264
20303
  model,
20265
20304
  tools,
20266
20305
  frontendToolIds: frontendToolNames,
@@ -20270,7 +20309,7 @@ function AthenaProvider({
20270
20309
  systemPrompt,
20271
20310
  customToolConfigs,
20272
20311
  appId,
20273
- extraRunConfig,
20312
+ extraRunConfig: configuredExtraRunConfig,
20274
20313
  linkClicks,
20275
20314
  citationLinks
20276
20315
  };
@@ -55323,7 +55362,7 @@ const TiptapComposer = ({ tools = [], rootCategories }) => {
55323
55362
  const isUploadingRef = React.useRef(isUploading);
55324
55363
  isUploadingRef.current = isUploading;
55325
55364
  const isRunningThread = react$1.useAuiState((s) => s.thread.isRunning);
55326
- const isThreadRunning = transport === "statewire" ? false : isRunningThread;
55365
+ const isThreadRunning = allowsMidRunSend(transport) ? false : isRunningThread;
55327
55366
  const isThreadRunningRef = React.useRef(isThreadRunning);
55328
55367
  isThreadRunningRef.current = isThreadRunning;
55329
55368
  const handleSubmit = React.useCallback(() => {
@@ -55345,10 +55384,8 @@ const TiptapComposer = ({ tools = [], rootCategories }) => {
55345
55384
  appUrl
55346
55385
  });
55347
55386
  if (fullMessage) {
55348
- aui.thread.append({
55349
- role: "user",
55350
- content: [{ type: "text", text: fullMessage }]
55351
- });
55387
+ aui.composer.setText(fullMessage);
55388
+ aui.composer.send();
55352
55389
  clearAttachments();
55353
55390
  clearQuote();
55354
55391
  }
@@ -55597,14 +55634,20 @@ const StatewireApprovalCardInner = () => {
55597
55634
  }
55598
55635
  const isRunning = react$1.useAuiState((s) => s.thread.isRunning);
55599
55636
  const sawResumeRunRef = React.useRef(false);
55600
- if (pending && isRunning) {
55601
- sawResumeRunRef.current = true;
55602
- } else if (pending && sawResumeRunRef.current && !isRunning) {
55603
- sawResumeRunRef.current = false;
55604
- setPending(false);
55605
- } else if (!pending) {
55606
- sawResumeRunRef.current = false;
55607
- }
55637
+ React.useEffect(() => {
55638
+ if (!pending) {
55639
+ sawResumeRunRef.current = false;
55640
+ return;
55641
+ }
55642
+ if (isRunning) {
55643
+ sawResumeRunRef.current = true;
55644
+ return;
55645
+ }
55646
+ if (sawResumeRunRef.current) {
55647
+ sawResumeRunRef.current = false;
55648
+ setPending(false);
55649
+ }
55650
+ }, [pending, isRunning]);
55608
55651
  React.useEffect(() => {
55609
55652
  if (!pending) return;
55610
55653
  const timer = setTimeout(() => {
@@ -55895,7 +55938,7 @@ const StatewireLegacyReadOnlyBanner = () => {
55895
55938
  /* @__PURE__ */ jsxRuntime.jsx(Archive, { className: "mt-0.5 size-4 shrink-0" }),
55896
55939
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
55897
55940
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-xs", children: "Read-only conversation" }),
55898
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pt-0.5 text-xs leading-snug text-amber-800", children: "Its history remains available, but new messages cannot be added. Start a new chat to continue." })
55941
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pt-0.5 text-xs leading-snug text-amber-800", children: "This conversation’s history remains available, but new messages cannot be added. Start a new chat to continue." })
55899
55942
  ] })
55900
55943
  ] });
55901
55944
  };
@@ -61134,7 +61177,7 @@ const ThreadScrollToBottom = () => /* @__PURE__ */ jsxRuntime.jsx(react$1.Thread
61134
61177
  ) });
61135
61178
  const ComposerAction = () => {
61136
61179
  const { transport } = useAthenaConfig();
61137
- const queuesWhileRunning = transport === "statewire";
61180
+ const queuesWhileRunning = allowsMidRunSend(transport);
61138
61181
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aui-composer-action-wrapper relative mx-2 mb-2 flex items-center justify-between", children: [
61139
61182
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ jsxRuntime.jsx(FileUploadButton, {}) }),
61140
61183
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
@@ -61161,7 +61204,7 @@ const ComposerSendWithQuote = () => {
61161
61204
  const editorRef = useComposerEditorRef();
61162
61205
  const editorEmpty = useComposerEditorEmpty();
61163
61206
  const isRunningThread = react$1.useAuiState((s) => s.thread.isRunning);
61164
- const isThreadRunning = transport === "statewire" ? false : isRunningThread;
61207
+ const isThreadRunning = allowsMidRunSend(transport) ? false : isRunningThread;
61165
61208
  const hasExtras = !!quote || attachments.length > 0;
61166
61209
  const handleSend = React.useCallback(() => {
61167
61210
  var _a3;
@@ -61177,10 +61220,8 @@ const ComposerSendWithQuote = () => {
61177
61220
  appUrl
61178
61221
  });
61179
61222
  if (!fullMessage) return;
61180
- aui.thread.append({
61181
- role: "user",
61182
- content: [{ type: "text", text: fullMessage }]
61183
- });
61223
+ aui.composer.setText(fullMessage);
61224
+ aui.composer.send();
61184
61225
  clearQuote();
61185
61226
  clearAttachments();
61186
61227
  } else {
@@ -62486,6 +62527,7 @@ exports.TooltipProvider = TooltipProvider;
62486
62527
  exports.TooltipTrigger = TooltipTrigger;
62487
62528
  exports.UpdateSheetRangeToolUI = UpdateSheetRangeToolUI;
62488
62529
  exports.WebSearchToolUI = WebSearchToolUI;
62530
+ exports.allowsMidRunSend = allowsMidRunSend;
62489
62531
  exports.archiveThread = archiveThread;
62490
62532
  exports.asHitlApproval = asHitlApproval;
62491
62533
  exports.athenaStatewireErrorNotice = athenaStatewireErrorNotice;