返回 DeepSeek-Reasonix
providerModelDraft.ts
根目录 / desktop / frontend / src / lib / providerModelDraft.ts
1 import { matchingModelKey } from "./providerImageInput";
2 import type { ProviderModelOverrideView } from "./types";
3
4 export type ModelDraft = { model: string; context: string; output: string; vision: "auto" | "yes" | "no" };
5
6 /** Validate explicit overrides without turning an inherited value into a guessed limit. */
7 export function modelDraftError(draft: ModelDraft, existing: string[], original?: string): "required" | "duplicate" | "syntax" | "context" | "output" | null {
8 const model = draft.model.trim();
9 if (!model) return "required";
10 if (/[\s,,]/.test(model)) return "syntax";
11 if (existing.some((name) => name !== original && name === model)) return "duplicate";
12 const valid = (value: string, allowOmit = false) => !value.trim() || (Number.isSafeInteger(Number(value)) && (Number(value) > 0 || (allowOmit && Number(value) === -1)));
13 if (!valid(draft.context)) return "context";
14 if (!valid(draft.output, true)) return "output";
15 return null;
16 }
17
18 /** Keep unedited reasoning and future view fields when changing one model. */
19 export function applyModelDraft(overrides: ProviderModelOverrideView[], draft: ModelDraft, original?: string): ProviderModelOverrideView[] {
20 const key = matchingModelKey(overrides.map((item) => item.model), original ?? draft.model);
21 const previous = overrides.find((item) => item.model === key);
22 const next: ProviderModelOverrideView = {
23 reasoningProtocol: "", supportedEfforts: [], defaultEffort: "", ...previous,
24 model: draft.model.trim(), contextWindow: Number(draft.context) || 0, maxOutputTokens: Number(draft.output) || 0,
25 vision: draft.vision === "auto" ? null : draft.vision === "yes",
26 };
27 return [...overrides.filter((item) => item.model !== key && item.model !== next.model), next];
28 }
29
29 lines TYPESCRIPT