

























@@ -43,6 +43,19 @@ type LmstudioConfiguredCatalogEntry = {
4343compat?: ModelDefinitionConfig["compat"];
4444};
454546+const LMSTUDIO_OPENAI_COMPAT_ENABLED_REASONING_EFFORTS = [
47+"minimal",
48+"low",
49+"medium",
50+"high",
51+"xhigh",
52+] as const;
53+54+const LMSTUDIO_OPENAI_COMPAT_REASONING_EFFORTS = [
55+"none",
56+ ...LMSTUDIO_OPENAI_COMPAT_ENABLED_REASONING_EFFORTS,
57+] as const;
58+4659function normalizeReasoningOption(value: unknown): string | null {
4760if (typeof value !== "string") {
4861return null;
@@ -72,38 +85,94 @@ function normalizeReasoningOptions(value: unknown): string[] {
7285];
7386}
748775-function resolveLmstudioReasoningDefault(
76-reasoning: LmstudioReasoningCapabilityWire,
77-): string | null {
78-const normalizedDefault = normalizeReasoningOption(reasoning.default);
79-return normalizedDefault && isReasoningEnabledOption(normalizedDefault)
80- ? normalizedDefault
81- : null;
88+function isLmstudioBinaryReasoningOptions(allowedOptions: readonly string[]): boolean {
89+return (
90+allowedOptions.some((option) => option === "on") &&
91+allowedOptions.every((option) => option === "on" || option === "off")
92+);
8293}
839484-function resolveLmstudioEnabledReasoningOption(
85-allowedOptions: readonly string[],
86-reasoning: LmstudioReasoningCapabilityWire,
87-): string | undefined {
88-const normalizedDefault = resolveLmstudioReasoningDefault(reasoning);
89-if (normalizedDefault && allowedOptions.includes(normalizedDefault)) {
90-return normalizedDefault;
95+function resolveLmstudioTransportReasoningEfforts(allowedOptions: readonly string[]): string[] {
96+if (isLmstudioBinaryReasoningOptions(allowedOptions)) {
97+return allowedOptions.includes("off")
98+ ? [...LMSTUDIO_OPENAI_COMPAT_REASONING_EFFORTS]
99+ : [...LMSTUDIO_OPENAI_COMPAT_ENABLED_REASONING_EFFORTS];
91100}
92-return (
93-allowedOptions.find((option) => option === "on" || option === "default") ??
94-allowedOptions.find((option) => isReasoningEnabledOption(option))
95-);
101+return [
102+ ...new Set(
103+allowedOptions
104+.map((option) => (option === "off" ? "none" : option))
105+.filter((option) => option !== "on"),
106+),
107+];
96108}
9710998-function resolveLmstudioDisabledReasoningOption(
99-allowedOptions: readonly string[],
110+function resolveLmstudioEnabledTransportReasoningOption(
111+supportedReasoningEfforts: readonly string[],
100112): string | undefined {
101113return (
102-allowedOptions.find((option) => option === "off") ??
103-allowedOptions.find((option) => option === "none")
114+supportedReasoningEfforts.find((option) => option === "xhigh") ??
115+supportedReasoningEfforts.find((option) => option === "high") ??
116+supportedReasoningEfforts.find((option) => option !== "none")
104117);
105118}
106119120+function buildLmstudioReasoningEffortMap(
121+supportedReasoningEfforts: readonly string[],
122+): Record<string, string> | undefined {
123+const disabled = supportedReasoningEfforts.includes("none") ? "none" : undefined;
124+const max = resolveLmstudioEnabledTransportReasoningOption(supportedReasoningEfforts);
125+const map = {
126+ ...(disabled ? { off: disabled, none: disabled } : {}),
127+ ...(max ? { adaptive: max, max } : {}),
128+};
129+return Object.keys(map).length > 0 ? map : undefined;
130+}
131+132+function buildLmstudioReasoningCompat(
133+allowedOptions: readonly string[],
134+): ModelDefinitionConfig["compat"] | undefined {
135+const supportedReasoningEfforts = resolveLmstudioTransportReasoningEfforts(allowedOptions);
136+if (supportedReasoningEfforts.length === 0) {
137+return undefined;
138+}
139+if (!supportedReasoningEfforts.some((option) => option !== "none")) {
140+return undefined;
141+}
142+return {
143+supportsReasoningEffort: true,
144+ supportedReasoningEfforts,
145+reasoningEffortMap: buildLmstudioReasoningEffortMap(supportedReasoningEfforts),
146+};
147+}
148+149+function normalizeLmstudioTransportReasoningCompat(
150+compat: NonNullable<ModelDefinitionConfig["compat"]>,
151+): NonNullable<ModelDefinitionConfig["compat"]> {
152+const supportedReasoningEfforts = compat.supportedReasoningEfforts;
153+const map = compat.reasoningEffortMap;
154+const hasBinarySupported =
155+Array.isArray(supportedReasoningEfforts) &&
156+supportedReasoningEfforts.some((option) => option === "on");
157+const hasBinaryMapValue =
158+map !== undefined && Object.values(map).some((value) => value === "on" || value === "off");
159+if (!hasBinarySupported && !hasBinaryMapValue) {
160+return compat;
161+}
162+const hasDisabled =
163+supportedReasoningEfforts?.includes("off") === true ||
164+supportedReasoningEfforts?.includes("none") === true ||
165+Object.values(map ?? {}).some((value) => value === "off" || value === "none");
166+const normalizedSupportedReasoningEfforts = hasDisabled
167+ ? [...LMSTUDIO_OPENAI_COMPAT_REASONING_EFFORTS]
168+ : [...LMSTUDIO_OPENAI_COMPAT_ENABLED_REASONING_EFFORTS];
169+return {
170+ ...compat,
171+supportedReasoningEfforts: normalizedSupportedReasoningEfforts,
172+reasoningEffortMap: buildLmstudioReasoningEffortMap(normalizedSupportedReasoningEfforts),
173+};
174+}
175+107176export function resolveLmstudioReasoningCompat(
108177entry: Pick<LmstudioModelWire, "capabilities">,
109178): ModelDefinitionConfig["compat"] | undefined {
@@ -115,25 +184,7 @@ export function resolveLmstudioReasoningCompat(
115184if (allowedOptions.length === 0) {
116185return undefined;
117186}
118-const enabled = resolveLmstudioEnabledReasoningOption(allowedOptions, reasoning);
119-if (!enabled) {
120-return undefined;
121-}
122-const disabled = resolveLmstudioDisabledReasoningOption(allowedOptions);
123-return {
124-supportsReasoningEffort: true,
125-supportedReasoningEfforts: allowedOptions,
126-reasoningEffortMap: {
127- ...(disabled ? { off: disabled, none: disabled } : {}),
128-minimal: enabled,
129-low: enabled,
130-medium: enabled,
131-high: enabled,
132-xhigh: enabled,
133-adaptive: enabled,
134-max: enabled,
135-},
136-};
187+return buildLmstudioReasoningCompat(allowedOptions);
137188}
138189139190/**
@@ -235,7 +286,9 @@ function normalizeLmstudioConfiguredCompat(value: unknown): ModelDefinitionConfi
235286if (reasoningEffortMap) {
236287compat.reasoningEffortMap = reasoningEffortMap;
237288}
238-return Object.keys(compat).length > 0 ? compat : undefined;
289+return Object.keys(compat).length > 0
290+ ? normalizeLmstudioTransportReasoningCompat(compat)
291+ : undefined;
239292}
240293241294function toFetchableLmstudioBaseUrl(value: string): string {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。