@athenaintel/react 0.40.0 → 0.40.2
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/README.md +36 -2
- package/dist/chat/AthenaChat.cjs +25 -11
- package/dist/chat/AthenaChat.cjs.map +1 -1
- package/dist/chat/AthenaChat.js +26 -12
- package/dist/chat/AthenaChat.js.map +1 -1
- package/dist/chat/run-activity.cjs +58 -13
- package/dist/chat/run-activity.cjs.map +1 -1
- package/dist/chat/run-activity.d.ts +52 -6
- package/dist/chat/run-activity.js +59 -14
- package/dist/chat/run-activity.js.map +1 -1
- package/dist/lib/use-document-active.cjs +40 -0
- package/dist/lib/use-document-active.cjs.map +1 -0
- package/dist/lib/use-document-active.d.ts +9 -0
- package/dist/lib/use-document-active.js +40 -0
- package/dist/lib/use-document-active.js.map +1 -0
- package/dist/react/package.json.cjs +1 -1
- package/dist/react/package.json.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/threads/Inbox.cjs +6 -2
- package/dist/threads/Inbox.cjs.map +1 -1
- package/dist/threads/Inbox.js +6 -2
- package/dist/threads/Inbox.js.map +1 -1
- package/dist/threads/mark-viewed-thread-read.cjs +97 -0
- package/dist/threads/mark-viewed-thread-read.cjs.map +1 -0
- package/dist/threads/mark-viewed-thread-read.d.ts +7 -0
- package/dist/threads/mark-viewed-thread-read.js +97 -0
- package/dist/threads/mark-viewed-thread-read.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -561,7 +561,25 @@ the loaded unread rows; **Dismiss** uses
|
|
|
561
561
|
session — a dismissed session comes back with its next message).
|
|
562
562
|
`InboxButton` is a bell with the unread count (`useAthenaInboxUnreadCount`,
|
|
563
563
|
the Unread tab's first page: `50+` past one page) that opens the inbox in a
|
|
564
|
-
popover.
|
|
564
|
+
popover. Each tab shows its count once its list has answered, and nothing
|
|
565
|
+
before.
|
|
566
|
+
|
|
567
|
+
### What counts as read
|
|
568
|
+
|
|
569
|
+
`AthenaChat` marks the session it shows read for the viewer, as Athena's own
|
|
570
|
+
chat does, wherever the session was opened from (`SessionList`, the inbox, a
|
|
571
|
+
`?session_id=` link): once the chat is in front of the person (its window,
|
|
572
|
+
a pop-out's included, visible and focused, and the chat itself on screen, not
|
|
573
|
+
hidden behind a maximized workbench), the session's history is on screen, no
|
|
574
|
+
run is going and its row is unread, for a second.
|
|
575
|
+
The write is the provider's `setReadState` with the row's `updatedAt`, so
|
|
576
|
+
every list under the provider flips at once and the next message shows the
|
|
577
|
+
session unread again. A message that arrives while the person watches is
|
|
578
|
+
marked too (a running session is marked when its run ends, never per
|
|
579
|
+
streamed chunk); a read session is never written; and a session the person
|
|
580
|
+
marks unread from a list stays unread until something new arrives or they
|
|
581
|
+
open it again. A host that draws its own transcript instead of `AthenaChat`
|
|
582
|
+
calls `setReadState` itself.
|
|
565
583
|
|
|
566
584
|
### Server filters and older servers
|
|
567
585
|
|
|
@@ -789,6 +807,22 @@ Both use the same bearer / API key as session creation. The full recipe
|
|
|
789
807
|
template skill `voice-session-guide.md`. `createAthenaVoiceSession` is also
|
|
790
808
|
exported if you hold the bridge state yourself.
|
|
791
809
|
|
|
810
|
+
## What's new in 0.40.2
|
|
811
|
+
|
|
812
|
+
**An answer that is still arriving is never called stalled.** The grouped turn header said "Nothing new for 31s" in amber whenever a turn's answer, or the agent's thinking, had streamed for more than thirty seconds, because its stall clock restarted only when a new part or tool step arrived. It now restarts whenever anything streams, an answer or thinking growing included, so the stall tone keeps its meaning: nothing has streamed for thirty seconds while the run waits on the model. A running tool still never gets the stall tone (0.40.1).
|
|
813
|
+
|
|
814
|
+
Nothing to change in your app.
|
|
815
|
+
|
|
816
|
+
## What's new in 0.40.1
|
|
817
|
+
|
|
818
|
+
**The session you are looking at is marked read.** In `enableThreadList` mode, `AthenaChat` now writes the viewer's read receipt for the session it shows, as Athena's own chat does: once the chat is in front of the person (its window, a pop-out's included, visible and focused, and the chat itself on screen, not hidden behind a maximized workbench), the session's history is on screen, no run is going and its row is unread, for a second. A session opened from `SessionList`, the inbox or a `?session_id=` link used to stay unread for good (only the inbox's own open, its Mark all read and the sessions page toggle wrote the receipt), so unread dots and the inbox's Unread count only grew. The write is the provider's `setReadState` (`POST /api/conversations/threads/read-state`, the route the inbox already used) with the row's `updatedAt`, so every list flips at once and the next message shows the session unread again. A message that arrives while the person watches is marked too, with at most one write per message; nothing polls, a read session is never written, and a session the person marks unread stays unread until something new arrives or they open it again. See [What counts as read](#what-counts-as-read).
|
|
819
|
+
|
|
820
|
+
**The inbox shows a tab's count once it has one.** The All and Unread tabs counted their rows before their first page answered ("All 0 · Unread 14" for a moment). A tab now shows no count until its list has answered.
|
|
821
|
+
|
|
822
|
+
**A running tool is never called stalled.** While the agent runs a long command, a build or a test suite (or a tool such as Python execution that shows only its streaming placeholder while it works), the turn header no longer adds "Nothing new for 1m 00s" in amber, and the line under an ungrouped turn keeps the tool's verb with a neutral counter ("Running a command… · 1m 04s") instead of "Still working — nothing new". The stall tone stays for a quiet stream that waits on the model.
|
|
823
|
+
|
|
824
|
+
Nothing to change in your app.
|
|
825
|
+
|
|
792
826
|
## What's new in 0.40.0
|
|
793
827
|
|
|
794
828
|
**`AthenaChat` shows an agent's UI test recording.** When an agent with the UI Testing toolkit checks a change in its computer's browser, `test_recording_stop` now renders a report card: the recording's title, "N passed · M failed" (with "· K untested" when a test was never checked), each test with its ✓ / ✗ assertions and what the agent saw (a failed assertion is tinted red, a test with no assertion reads "Not checked"), the summary, and the edited video. Every test's start time is a chapter: click it and the video plays from there (an assertion's time works the same way). A **Watch in Athena** link opens the asset in Athena. The card stays in the conversation instead of folding into the turn's collapsed steps. `test_recording_start` and `test_recording_mark` each render one compact row ("Recording started", "Test", "Pass", "Fail", "Note" with the time in the recording), and their collapsed steps read "Started recording "…"", "Started test: It should …", "Passed: …", "Failed: …".
|
|
@@ -1934,7 +1968,7 @@ Your own portals can read the same context: `usePortalContainer()` returns the p
|
|
|
1934
1968
|
|
|
1935
1969
|
- **The agent's sentences stay visible.** Every text part the agent writes before its last tool call ("I'll find your workstation, then check origin/staging.", "Started. Now I'll compare.") renders in the transcript, in order, as it streams. Only the work between two sentences folds: each run of tool calls and reasoning becomes one collapsed step row. The answer (the text after the last tool call) renders below, as before; no text renders twice.
|
|
1936
1970
|
- **Each step says what it did.** A collapsed row names the step in progress, else the last one it took — "Ran `git log -1 origin/staging`", "Read `live_audio.py`", "Edited `upstream.py`" with "+4 −1", "Found 3 assets for "workstation"", "jevin-box is running", "Viewed pull request #43093", "Updated plan (3/7 done)" — with "+2 more" when the row folds several. Opening it lists every step, and "Show tool details" reveals that row's tool UIs.
|
|
1937
|
-
- **The header counts the turn.** "Working for 1m 12s" while it runs, "Worked for 2m 30s · Used 7 tools" once done (from the messages' own server stamps), "Waiting for you" on an approval. After thirty seconds
|
|
1971
|
+
- **The header counts the turn.** "Working for 1m 12s" while it runs, "Worked for 2m 30s · Used 7 tools" once done (from the messages' own server stamps), "Waiting for you" on an approval. After thirty seconds in which the model has streamed nothing the header adds "Nothing new for 42s" in amber — but never while a tool call is still running: a command, a build or a test run streams nothing for minutes while it works, so its step row says it is running and the header goes on counting the turn. With `groupToolCalls={false}` the line under the turn keeps the running tool's verb and a neutral counter ("Running a command… · 1m 04s") the same way.
|
|
1938
1972
|
|
|
1939
1973
|
The transcript is `SuperGroupingTranscript` from `@athenaintel/react/super-grouping`; it takes the same renderer and host slots as `SuperGroupingCard` (which keeps the single-card layout for hosts that mount it). `splitTurnSegments`, `readTurnTiming` and `formatWorkDuration` are exported for hosts that lay a turn out themselves.
|
|
1940
1974
|
|
package/dist/chat/AthenaChat.cjs
CHANGED
|
@@ -49,6 +49,7 @@ const lucideReact = require("lucide-react");
|
|
|
49
49
|
const react$1 = require("react");
|
|
50
50
|
const threadIdContext = require("../threads/thread-id-context.cjs");
|
|
51
51
|
const statewireThreadList = require("../threads/statewire-thread-list.cjs");
|
|
52
|
+
const markViewedThreadRead = require("../threads/mark-viewed-thread-read.cjs");
|
|
52
53
|
const FileUploadButton = require("../composer/FileUploadButton.cjs");
|
|
53
54
|
const ComposerQuotePreview = require("../composer/ComposerQuotePreview.cjs");
|
|
54
55
|
const ComposerAttachmentPreview = require("../composer/ComposerAttachmentPreview.cjs");
|
|
@@ -252,7 +253,10 @@ const AthenaChat = ({
|
|
|
252
253
|
return /* @__PURE__ */ jsxRuntime.jsx(AthenaChatDefaultComponentsContext.Provider, { value: defaultComponentsContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(AthenaChatErrorBoundary.AthenaChatErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(toolFallback.ToolFallbackAppearanceProvider, { appearance: "thread", children: /* @__PURE__ */ jsxRuntime.jsx(apiClient.MentionAuthCtx.Provider, { value: mentionAuth, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
253
254
|
chatThreadShell.ChatThreadShell,
|
|
254
255
|
{
|
|
255
|
-
overlay: /* @__PURE__ */ jsxRuntime.
|
|
256
|
+
overlay: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
257
|
+
/* @__PURE__ */ jsxRuntime.jsx(threadLoadingOverlay.ThreadLoadingOverlay, {}),
|
|
258
|
+
/* @__PURE__ */ jsxRuntime.jsx(markViewedThreadRead.MarkViewedThreadRead, {})
|
|
259
|
+
] }),
|
|
256
260
|
panelClassName: cnfast.cn(
|
|
257
261
|
"aui-root aui-thread-root @container relative flex h-full flex-col bg-background",
|
|
258
262
|
className
|
|
@@ -598,21 +602,22 @@ const MessageError = () => /* @__PURE__ */ jsxRuntime.jsx(react.MessagePrimitive
|
|
|
598
602
|
}
|
|
599
603
|
) })
|
|
600
604
|
] }) });
|
|
601
|
-
function useSecondsSince(resetKey) {
|
|
605
|
+
function useSecondsSince({ resetKey, ticking = true }) {
|
|
602
606
|
const [seconds, setSeconds] = react$1.useState(0);
|
|
603
607
|
react$1.useEffect(() => {
|
|
604
608
|
setSeconds(0);
|
|
609
|
+
if (!ticking) return;
|
|
605
610
|
const startedAt = Date.now();
|
|
606
611
|
const timer = setInterval(() => {
|
|
607
612
|
setSeconds(Math.floor((Date.now() - startedAt) / 1e3));
|
|
608
613
|
}, 1e3);
|
|
609
614
|
return () => clearInterval(timer);
|
|
610
|
-
}, [resetKey]);
|
|
615
|
+
}, [resetKey, ticking]);
|
|
611
616
|
return seconds;
|
|
612
617
|
}
|
|
613
|
-
const RunStatusLine = ({ verb, resetKey, className }) => {
|
|
614
|
-
const seconds = useSecondsSince(resetKey);
|
|
615
|
-
const stalled = seconds
|
|
618
|
+
const RunStatusLine = ({ verb, resetKey, toolCallInFlight = false, className }) => {
|
|
619
|
+
const seconds = useSecondsSince({ resetKey });
|
|
620
|
+
const stalled = runActivity.isRunActivityStalled({ seconds, toolCallInFlight });
|
|
616
621
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
617
622
|
"div",
|
|
618
623
|
{
|
|
@@ -638,7 +643,7 @@ const RunStatusLine = ({ verb, resetKey, className }) => {
|
|
|
638
643
|
{
|
|
639
644
|
"aria-hidden": "true",
|
|
640
645
|
className: cnfast.cn("tabular-nums", stalled && "text-amber-600 dark:text-amber-400"),
|
|
641
|
-
children: runActivity.runActivityLabel(seconds, verb)
|
|
646
|
+
children: runActivity.runActivityLabel({ seconds, verb, stalled })
|
|
642
647
|
}
|
|
643
648
|
),
|
|
644
649
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-live": "polite", className: "sr-only", children: stalled ? "Assistant is still working; nothing new for over thirty seconds." : `${verb}…` })
|
|
@@ -668,13 +673,22 @@ const AthenaMessageActivityIndicator = () => {
|
|
|
668
673
|
});
|
|
669
674
|
const activityKey = react.useAuiState((s) => runActivity.runActivityKey(s.message.parts));
|
|
670
675
|
const verb = react.useAuiState((s) => runActivity.runActivityVerb(s.message.parts));
|
|
676
|
+
const toolCallInFlight = react.useAuiState((s) => runActivity.isToolCallInFlight(s.message.parts));
|
|
671
677
|
if (!isRunning || activityKey === null) return null;
|
|
672
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
678
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
679
|
+
RunStatusLine,
|
|
680
|
+
{
|
|
681
|
+
verb: verb ?? "Working",
|
|
682
|
+
resetKey: activityKey,
|
|
683
|
+
toolCallInFlight
|
|
684
|
+
}
|
|
685
|
+
);
|
|
673
686
|
};
|
|
674
687
|
const AthenaGroupedRunMeta = () => {
|
|
675
|
-
const
|
|
676
|
-
const
|
|
677
|
-
const
|
|
688
|
+
const progressKey = react.useAuiState((s) => runActivity.runProgressKey(s.message.parts));
|
|
689
|
+
const toolCallInFlight = react.useAuiState((s) => runActivity.isToolCallInFlight(s.message.parts));
|
|
690
|
+
const seconds = useSecondsSince({ resetKey: progressKey, ticking: !toolCallInFlight });
|
|
691
|
+
const stalled = runActivity.isRunActivityStalled({ seconds, toolCallInFlight });
|
|
678
692
|
if (!stalled) return null;
|
|
679
693
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
680
694
|
"span",
|