mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
feat(dashboard): add resume loading overlay helpers
Extract overlay visibility helpers so the chat resume wait notice can be tested without mounting ChatPage.
This commit is contained in:
parent
c31c27e03a
commit
490f7048dd
2 changed files with 116 additions and 0 deletions
69
web/src/lib/pty-resume-loading.test.ts
Normal file
69
web/src/lib/pty-resume-loading.test.ts
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
PTY_RESUME_LOADING_MAX_MS,
|
||||
shouldFinishResumeHydrationOnChunk,
|
||||
shouldShowResumeLoadingOverlay,
|
||||
} from "./pty-resume-loading";
|
||||
|
||||
describe("shouldFinishResumeHydrationOnChunk", () => {
|
||||
it("finishes on the first non-empty chunk", () => {
|
||||
expect(shouldFinishResumeHydrationOnChunk("")).toBe(false);
|
||||
expect(shouldFinishResumeHydrationOnChunk("hello")).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps a positive hard-cap timeout for wedged resumes", () => {
|
||||
expect(PTY_RESUME_LOADING_MAX_MS).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("shouldShowResumeLoadingOverlay", () => {
|
||||
it("shows while a resume target is connecting or open and still hydrating", () => {
|
||||
expect(
|
||||
shouldShowResumeLoadingOverlay({
|
||||
hasResumeTarget: true,
|
||||
ptyState: "connecting",
|
||||
hydrating: true,
|
||||
}),
|
||||
).toBe(true);
|
||||
expect(
|
||||
shouldShowResumeLoadingOverlay({
|
||||
hasResumeTarget: true,
|
||||
ptyState: "open",
|
||||
hydrating: true,
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("hides when there is no resume target", () => {
|
||||
expect(
|
||||
shouldShowResumeLoadingOverlay({
|
||||
hasResumeTarget: false,
|
||||
ptyState: "connecting",
|
||||
hydrating: true,
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("hides once hydration finishes", () => {
|
||||
expect(
|
||||
shouldShowResumeLoadingOverlay({
|
||||
hasResumeTarget: true,
|
||||
ptyState: "open",
|
||||
hydrating: false,
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("defers to reconnect / closed / ended overlays", () => {
|
||||
for (const ptyState of ["reconnecting", "closed", "ended"] as const) {
|
||||
expect(
|
||||
shouldShowResumeLoadingOverlay({
|
||||
hasResumeTarget: true,
|
||||
ptyState,
|
||||
hydrating: true,
|
||||
}),
|
||||
).toBe(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
47
web/src/lib/pty-resume-loading.ts
Normal file
47
web/src/lib/pty-resume-loading.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import type { PtyConnectionState } from "@/lib/pty-reconnect";
|
||||
|
||||
/**
|
||||
* Hard cap so a wedged resume (never gets PTY payload) cannot leave the
|
||||
* wait notice up forever.
|
||||
*/
|
||||
export const PTY_RESUME_LOADING_MAX_MS = 30000;
|
||||
|
||||
export const PTY_RESUME_LOADING_MESSAGE =
|
||||
"Please wait while the conversation loads…";
|
||||
|
||||
export interface ResumeLoadingOverlayInput {
|
||||
hasResumeTarget: boolean;
|
||||
ptyState: PtyConnectionState;
|
||||
hydrating: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a wait notice only while a resumed chat is still blank. Once the
|
||||
* first real PTY payload arrives the terminal has something to show, so
|
||||
* the notice hides and history can stream in underneath.
|
||||
*
|
||||
* Reconnect / ended / closed states keep their own overlays and must not
|
||||
* stack this one on top.
|
||||
*/
|
||||
export function shouldShowResumeLoadingOverlay({
|
||||
hasResumeTarget,
|
||||
ptyState,
|
||||
hydrating,
|
||||
}: ResumeLoadingOverlayInput): boolean {
|
||||
if (!hasResumeTarget || !hydrating) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
ptyState === "reconnecting" ||
|
||||
ptyState === "closed" ||
|
||||
ptyState === "ended"
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return ptyState === "connecting" || ptyState === "open";
|
||||
}
|
||||
|
||||
/** First non-empty PTY chunk means the blank window is over. */
|
||||
export function shouldFinishResumeHydrationOnChunk(chunkText: string): boolean {
|
||||
return chunkText.length > 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue