返回 DeepSeek-Reasonix
composerInboxQueue.ts
根目录 / desktop / frontend / src / lib / composerInboxQueue.ts
1 import type { PendingGuidance } from "../components/ComposerGuidanceShelf";
2 import { asArray } from "./array";
3
4 export type InboxSnapshotLike = {
5 paused?: boolean;
6 recovered?: boolean;
7 recoveredCount?: number;
8 revision?: number;
9 sessionPath?: string;
10 items?: Array<{
11 id: string;
12 preview?: string;
13 state?: string;
14 intent?: string;
15 source?: string;
16 }>;
17 };
18
19 export function inboxScopeKey(sessionPath?: string, workspaceScopeKey?: string): string {
20 return (sessionPath || "").trim() || workspaceScopeKey || "";
21 }
22
23 export function inboxSnapshotBelongsToScope(snapshotPath: string | undefined, scopeKey: string): boolean {
24 const path = (snapshotPath || "").trim();
25 if (!path || !scopeKey) return true;
26 if (scopeKey === path) return true;
27 return scopeKey.split("\u0000").includes(path);
28 }
29
30 export function localGuidanceFallback(previewKey: string): PendingGuidance[] {
31 return previewKey
32 .split("\n")
33 .filter(Boolean)
34 .map((text, i) => ({ id: `local-${i}`, text, submitText: text }));
35 }
36
37 export function guidanceFromInboxSnapshot(snap: InboxSnapshotLike | null | undefined): PendingGuidance[] {
38 const visible = asArray(snap?.items).filter((it) => it.state !== "steer_consumed" && it.state !== "running");
39 return visible.map((it) => ({
40 id: it.id,
41 text: it.preview || "",
42 submitText: "",
43 state: it.state,
44 intent: it.intent,
45 source: it.source,
46 paused: Boolean(snap?.paused),
47 recoveredCount: snap?.paused && snap?.recovered
48 ? visible.length
49 : undefined,
50 }));
51 }
52
53 export async function hydrateEmptyGuidancePreviews(
54 items: PendingGuidance[],
55 readItem: (id: string) => Promise<{ displayText?: string; submitText?: string; rawText?: string }>,
56 ): Promise<PendingGuidance[]> {
57 const missing = items.filter((item) => !item.text.trim() && !item.id.startsWith("local-"));
58 if (missing.length === 0) return items;
59 await Promise.all(missing.map(async (item) => {
60 try {
61 const env = await readItem(item.id);
62 const text = (env.displayText || env.submitText || env.rawText || "").trim();
63 if (text) item.text = text;
64 } catch {
65 // Preview-only snapshot remains if the body cannot be read.
66 }
67 }));
68 return items;
69 }
70
71 export function mergeGuidanceSnapshot(durable: PendingGuidance[], fallback: PendingGuidance[]): PendingGuidance[] {
72 return durable.length > 0 ? durable : fallback;
73 }
74
74 lines TYPESCRIPT