mirror of
https://github.com/Heretek-AI/ompweb.git
synced 2026-11-10 05:41:34 -10:00
Verbatim extractions, no behavior change: - hooks/useAgentSession (3442->2998) + stream/queue/notices helpers - SessionSidebar (3112->1599) + helpers/chrome/rows - ChatInput (2814->2560) + model-options/slash-commands/draft-attachments/banners - AppShell (2436->2283) + app-update/provider-usage/layout - ModelsConfig (2385->1736) + types/panels - MessageView (1827->1409) + tool-format/task-panel/diff-view Contract test points the archive flow at SessionSidebar-rows.
69 lines
2.4 KiB
TypeScript
69 lines
2.4 KiB
TypeScript
// Queued-prompt tracking and sessionStorage persistence helpers
|
|
// extracted from useAgentSession (pure logic only — no hook state).
|
|
|
|
export interface QueuedMessages {
|
|
steering: string[];
|
|
followUp: string[];
|
|
}
|
|
|
|
export const EMPTY_QUEUE: QueuedMessages = { steering: [], followUp: [] };
|
|
|
|
// omp reports only queuedMessageCount over RPC; the queued texts live in React
|
|
// state and would vanish on reload. Mirror them into sessionStorage (per
|
|
// session, best-effort, size-bounded) so a reload can restore the queue panel.
|
|
export const QUEUE_STORAGE_PREFIX = "omp-queue-";
|
|
export const QUEUE_STORAGE_MAX_CHARS = 50_000;
|
|
|
|
export function isEmptyQueue(queue: QueuedMessages): boolean {
|
|
return queue.steering.length === 0 && queue.followUp.length === 0;
|
|
}
|
|
|
|
export function readPersistedQueue(sessionId: string): QueuedMessages | null {
|
|
try {
|
|
const raw = sessionStorage.getItem(QUEUE_STORAGE_PREFIX + sessionId);
|
|
if (!raw) return null;
|
|
const parsed = JSON.parse(raw) as Partial<QueuedMessages> | null;
|
|
const onlyStrings = (value: unknown): string[] =>
|
|
Array.isArray(value) ? value.filter((item): item is string => typeof item === "string") : [];
|
|
const queue = { steering: onlyStrings(parsed?.steering), followUp: onlyStrings(parsed?.followUp) };
|
|
return isEmptyQueue(queue) ? null : queue;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function persistQueue(sessionId: string, queue: QueuedMessages): void {
|
|
try {
|
|
const key = QUEUE_STORAGE_PREFIX + sessionId;
|
|
if (isEmptyQueue(queue)) {
|
|
sessionStorage.removeItem(key);
|
|
return;
|
|
}
|
|
// Size bound: drop oldest texts until the payload fits.
|
|
let bounded = queue;
|
|
let raw = JSON.stringify(bounded);
|
|
while (raw.length > QUEUE_STORAGE_MAX_CHARS && bounded.steering.length + bounded.followUp.length > 1) {
|
|
bounded = bounded.steering.length >= bounded.followUp.length
|
|
? { ...bounded, steering: bounded.steering.slice(1) }
|
|
: { ...bounded, followUp: bounded.followUp.slice(1) };
|
|
raw = JSON.stringify(bounded);
|
|
}
|
|
if (raw.length > QUEUE_STORAGE_MAX_CHARS) {
|
|
sessionStorage.removeItem(key);
|
|
return;
|
|
}
|
|
sessionStorage.setItem(key, raw);
|
|
} catch {
|
|
// Best-effort only (quota exceeded, private mode, SSR).
|
|
}
|
|
}
|
|
|
|
export function clearPersistedQueue(sessionId: string | null): void {
|
|
if (!sessionId) return;
|
|
try {
|
|
sessionStorage.removeItem(QUEUE_STORAGE_PREFIX + sessionId);
|
|
} catch {
|
|
// ignore storage errors
|
|
}
|
|
}
|