返回 DeepSeek-Reasonix
providerImageInput.ts
根目录 / desktop / frontend / src / lib / providerImageInput.ts
1 import type { ProviderModelCapabilityView, ProviderModelOverrideView } from "./types";
2
3 export type ImageInputMode = "auto" | "on" | "off";
4
5 // A negative-only guard for manually typed models before a backend preview
6 // exists. Mirrors openai.IsDeepSeek / IsOfficialDeepSeekTextModel — V4 Pro is
7 // the only official DeepSeek model still pinned text-only; it never infers
8 // positive capabilities from a model name.
9 export function imageInputHardBlocked(baseURL: string | undefined, model: string, capability?: ProviderModelCapabilityView): boolean {
10 if (capability?.imageInputEnableAllowed !== undefined) return !capability.imageInputEnableAllowed;
11 try {
12 return new URL(baseURL ?? "").hostname.toLowerCase().endsWith(".deepseek.com")
13 && ["deepseek-v4-pro"].includes(model.trim().toLowerCase());
14 } catch { return false; }
15 }
16
17 export function imageInputModes(overrides?: ProviderModelOverrideView[] | null): Record<string, ImageInputMode> {
18 return Object.fromEntries((overrides ?? []).map((item) => [item.model, item.vision == null ? "auto" : item.vision ? "on" : "off"]));
19 }
20
21 export function imageInputModeForModel(modes: Record<string, ImageInputMode>, model: string): ImageInputMode {
22 const key = matchingModelKey(Object.keys(modes), model);
23 return key ? modes[key] : "auto";
24 }
25
26 export function matchingModelKey(keys: string[], model: string): string | undefined {
27 const exact = model.trim();
28 return keys.includes(exact) ? exact : undefined;
29 }
30
31 export function modelCapabilityForModel(capabilities: ProviderModelCapabilityView[] | null | undefined, model: string): ProviderModelCapabilityView | undefined {
32 const key = matchingModelKey((capabilities ?? []).map((item) => item.model), model);
33 return capabilities?.find((item) => item.model === key);
34 }
35
36 // Image editing only owns vision. Context/output/reasoning fields survive.
37 export function mergeImageInputModes(
38 overrides: ProviderModelOverrideView[] | null | undefined,
39 models: string[],
40 modes: Record<string, ImageInputMode>,
41 ): ProviderModelOverrideView[] {
42 return models.flatMap((model) => {
43 const key = matchingModelKey((overrides ?? []).map((item) => item.model), model);
44 const previous = overrides?.find((item) => item.model === key);
45 const mode = imageInputModeForModel(modes, model);
46 if (!previous && mode === "auto") return [];
47 const item: ProviderModelOverrideView = {
48 reasoningProtocol: "", supportedEfforts: [], defaultEffort: "",
49 ...previous, model, vision: mode === "auto" ? null : mode === "on",
50 };
51 return [item];
52 });
53 }
54
55 export function imageInputState(mode: ImageInputMode, capability?: ProviderModelCapabilityView, fallback = "unknown"): string {
56 if (capability?.imageInputEnableAllowed === false) return "unsupported";
57 if (mode !== "auto") return mode === "on" ? "supported" : "unsupported";
58 return capability?.automaticState ?? (capability?.source === "override" ? "unknown" : capability?.state) ?? fallback;
59 }
60
60 lines TYPESCRIPT