返回 DeepSeek-Reasonix
readPause.ts
根目录 / desktop / frontend / src / lib / readPause.ts
1 import type { Item } from "./useController";
2 import { t } from "./i18n";
3
4 export interface WireReadPause {
5 code?: string;
6 id: string;
7 reads: { readId: string; path: string; snapshot?: string; intent?: string; covered?: [number, number][]; missing?: [number, number][]; reason: string }[];
8 omitted?: number;
9 }
10
11 function rangesLabel(ranges: [number, number][] | undefined): string {
12 return (Array.isArray(ranges) ? ranges : []).slice(0, 64)
13 .filter(r => Array.isArray(r) && Number.isInteger(r[0]) && Number.isInteger(r[1]) && r[0] >= 0 && r[1] > r[0])
14 .map(([start, end]) => `${start + 1}–${end}`).join(", ");
15 }
16
17 export function readPauseItem(pause: WireReadPause | undefined, fallbackID: string): Item {
18 const reasons = new Set<string>();
19 const details = (Array.isArray(pause?.reads) ? pause.reads : []).slice(0, 32).map(read => {
20 const reasonKey = read.reason === "no_progress" ? "composer.readStatusStalled"
21 : ["page_budget", "time_budget", "no_headroom", "unknown_window"].includes(read.reason) ? "composer.readStatusBudget" : "composer.readStatusSource";
22 const covered = rangesLabel(read.covered);
23 const missing = rangesLabel(read.missing);
24 reasons.add(t(reasonKey));
25 return [read.path, t(reasonKey), covered && t("notice.readPauseCovered", { range: covered }), missing && t("notice.readPauseMissing", { range: missing })].filter(Boolean).join(" · ");
26 });
27 if (pause?.omitted) details.push(t("notice.readPauseOmitted", { count: pause.omitted }));
28 return { kind: "notice", id: pause?.id ? `read-pause-${pause.id}` : fallbackID, level: "info", code: "incomplete_read", title: t("notice.readPauseTitle"), text: [...reasons, t("notice.readPauseBody")].join(" "), detail: details.join("\n") };
29 }
30
31 export function upsertReadPause(items: Item[], pause: WireReadPause | undefined, fallbackID: string): Item[] {
32 const item = readPauseItem(pause, fallbackID);
33 const index = items.findIndex(existing => existing.id === item.id);
34 if (index < 0) return [...items, item];
35 return items.map((existing, i) => i === index ? item : existing);
36 }
37
37 lines TYPESCRIPT