返回 DeepSeek-Reasonix
controllerSwitchNotices.ts
根目录 / desktop / frontend / src / lib / controllerSwitchNotices.ts
1 import { t, type DictKey } from "./i18n";
2 import { errorMessage } from "./controllerNotices";
3 import type { MessageActionScope } from "./messageActions";
4 import { app } from "./bridge";
5 import type { TabMeta } from "./types";
6 export { settleForkConversationForTab } from "./forkWorktree";
7
8 export async function restoreNavigationBackend(sourceTabId: string, targetTabId: string, sourceTab?: TabMeta): Promise<{
9 restoredTabId: string;
10 restoredMeta?: TabMeta;
11 } | null> {
12 if (sourceTabId !== targetTabId && await app.SetActiveTab(sourceTabId).then(() => true).catch(() => false)) {
13 return { restoredTabId: sourceTabId };
14 }
15 if (!sourceTab?.topicId) return null;
16 try {
17 const restoredMeta = sourceTab.sessionPath
18 ? await app.OpenTopicSession(sourceTab.scope, sourceTab.workspaceRoot, sourceTab.topicId, sourceTab.sessionPath)
19 : await app.ActivateTopic(sourceTab.scope, sourceTab.workspaceRoot, sourceTab.topicId, "");
20 return { restoredTabId: restoredMeta.id, restoredMeta };
21 } catch {
22 return null;
23 }
24 }
25
26 export function messageActionBusyText(scope: MessageActionScope): string {
27 switch (scope) {
28 case "fork":
29 case "fork-worktree": return t("rewind.busyFork");
30 case "summ-from": return t("rewind.busySummFrom");
31 case "summ-upto": return t("rewind.busySummUpto");
32 case "conversation": return t("rewind.busyConversation");
33 case "code": return t("rewind.busyCode");
34 default: return t("rewind.busyBoth");
35 }
36 }
37
38 type SettingNoticeKeys = {
39 busy: DictKey;
40 busyRunning: DictKey;
41 busyPrompt: DictKey;
42 busyJobs: DictKey;
43 leaseHeld: DictKey;
44 starting: DictKey;
45 startupFailed: DictKey;
46 retry: DictKey;
47 failed: DictKey;
48 };
49
50 function settingSwitchNoticeText(err: unknown, setting: "effort" | "model" | "token mode", keys: SettingNoticeKeys): string {
51 const msg = errorMessage(err).trim() || "unknown error";
52 const lower = msg.toLowerCase();
53 if (lower.includes("finish or cancel") && lower.includes(`before changing ${setting}`)) {
54 const detail = /running=(true|false);\s*pending_prompt=(true|false);\s*background_jobs=(\d+)/i.exec(msg);
55 if (detail?.[2] === "true") return t(keys.busyPrompt);
56 if (detail?.[1] === "true") return t(keys.busyRunning);
57 const jobs = Number(detail?.[3] ?? 0);
58 if (jobs > 0) return t(keys.busyJobs, { n: jobs });
59 return t(keys.busy);
60 }
61 if (lower.includes("already open in another reasonix window") || lower.includes("session lease held")) return t(keys.leaseHeld);
62 if (lower.includes("workspace is still starting")) return t(keys.starting);
63 if (lower.startsWith("workspace failed to start")) return t(keys.startupFailed, { err: msg });
64 if (lower.includes(`changed while switching ${setting}`) || (lower.includes("tab ") && lower.includes("not found"))) return t(keys.retry);
65 return t(keys.failed, { err: msg });
66 }
67
68 export function effortSwitchNoticeText(err: unknown): string {
69 return settingSwitchNoticeText(err, "effort", {
70 busy: "status.effortSwitchBusy",
71 busyRunning: "status.effortSwitchBusyRunning",
72 busyPrompt: "status.effortSwitchBusyPrompt",
73 busyJobs: "status.effortSwitchBusyJobs",
74 leaseHeld: "status.effortSwitchLeaseHeld",
75 starting: "status.effortSwitchStarting",
76 startupFailed: "status.effortSwitchStartupFailed",
77 retry: "status.effortSwitchRetry",
78 failed: "status.effortSwitchFailed",
79 });
80 }
81
82 export function modelSwitchNoticeText(err: unknown): string {
83 const msg = errorMessage(err).trim() || "unknown error";
84 const unknownModel = /^unknown model (.+)$/i.exec(msg);
85 if (unknownModel) return t("status.modelSwitchUnknown", { model: unknownModel[1] });
86 const unavailable = /^model (.+) is not available because provider (.+) is not added$/i.exec(msg);
87 if (unavailable) return t("status.modelSwitchProviderUnavailable", { model: unavailable[1], provider: unavailable[2] });
88 return settingSwitchNoticeText(msg, "model", {
89 busy: "status.modelSwitchBusy",
90 busyRunning: "status.modelSwitchBusyRunning",
91 busyPrompt: "status.modelSwitchBusyPrompt",
92 busyJobs: "status.modelSwitchBusyJobs",
93 leaseHeld: "status.modelSwitchLeaseHeld",
94 starting: "status.modelSwitchStarting",
95 startupFailed: "status.modelSwitchStartupFailed",
96 retry: "status.modelSwitchRetry",
97 failed: "status.modelSwitchFailed",
98 });
99 }
100
100 lines TYPESCRIPT