返回 DeepSeek-Reasonix
sessionTitleOperation.ts
根目录 / desktop / frontend / src / lib / sessionTitleOperation.ts
1 import type { ProjectNode } from "./types";
2 import type { DictKey } from "./i18n";
3 import type { SessionSelector } from "../generated/desktopContract.generated";
4
5 // Keep the RPC's string argument compatible with older topic callers while
6 // selecting the exact durable row whenever the catalog supplies its identity.
7 export function sessionTitleTarget(node: ProjectNode): string {
8 if (node.session?.sessionId) return `session-id:${node.session.sessionId}`;
9 if (node.source) return `session-source:${encodeURIComponent(JSON.stringify(node.source))}`;
10 return node.sessionPath?.trim() || node.topicId?.trim() || "";
11 }
12
13 export function sessionTitleSelector(target: string): SessionSelector {
14 const value = target.trim();
15 if (value.startsWith("session-source:")) return { source: JSON.parse(decodeURIComponent(value.slice("session-source:".length))) };
16 if (value.startsWith("session-id:")) {
17 return { ref: { hostId: "local", sessionId: value.slice("session-id:".length) } };
18 }
19 if (value.includes("/") || value.includes("\\")) return { sessionPath: value };
20 return { topicId: value };
21 }
22
23 export function sessionTitleErrorKey(error: unknown): DictKey {
24 const record = typeof error === "object" && error !== null ? error as Record<string, unknown> : undefined;
25 const data = record && typeof record.data === "object" && record.data !== null
26 ? record.data as Record<string, unknown>
27 : undefined;
28 const message = error instanceof Error ? error.message : String(error);
29 const code = typeof data?.sessionCode === "string"
30 ? data.sessionCode
31 : message.match(/session_operation:([a-z_]+):/)?.[1];
32 const keys: Record<string, DictKey> = {
33 target_not_found: "projectTree.sessionError.targetNotFound", no_messages: "projectTree.sessionError.noMessages",
34 ambiguous_target: "projectTree.sessionError.ambiguousTarget",
35 runtime_not_open: "projectTree.sessionError.runtimeNotOpen", runtime_not_ready: "projectTree.sessionError.runtimeNotReady",
36 remote_disconnected: "projectTree.sessionError.remoteDisconnected", title_conflict: "projectTree.sessionError.titleConflict",
37 target_changed: "projectTree.sessionError.targetChanged", archived: "projectTree.sessionError.archived",
38 operation_busy: "projectTree.sessionError.operationBusy", provider_unavailable: "projectTree.sessionError.providerUnavailable",
39 stale_cursor: "projectTree.sessionError.staleCursor", unsupported: "projectTree.sessionError.unsupported",
40 operation_failed: "projectTree.sessionError.failed",
41 };
42 // Providers, disk errors and older hosts can return paths or credentials.
43 // Never render unclassified backend details in the product toast.
44 return keys[code ?? ""] ?? "projectTree.sessionError.failed";
45 }
46
46 lines TYPESCRIPT