fix(foundry): clamp Mythos Preview thinking

This commit is contained in:
Vincent Koc
2026-06-10 23:38:19 +09:00
parent e7136005eb
commit 55384bc236
3 changed files with 43 additions and 12 deletions

View File

@@ -1437,9 +1437,25 @@ describe("microsoft-foundry plugin", () => {
modelId: "prod-opaque",
} as never),
).toBeUndefined();
expect(
provider.resolveThinkingProfile?.({
provider: "microsoft-foundry",
modelId: "prod-mythos-preview",
modelName: "claude-mythos-preview",
} as never),
).toMatchObject({
defaultLevel: "adaptive",
levels: [
{ id: "minimal" },
{ id: "low" },
{ id: "medium" },
{ id: "high" },
{ id: "adaptive" },
],
});
});
it("records max-only thinking maps for Foundry Mythos Preview deployments", () => {
it("does not record native max thinking maps for Foundry Mythos Preview deployments", () => {
const result = buildFoundryAuthResult({
profileId: "microsoft-foundry:entra",
apiKey: "__entra_id_dynamic__",
@@ -1451,7 +1467,7 @@ describe("microsoft-foundry plugin", () => {
});
const model = result.configPatch?.models?.providers?.["microsoft-foundry"]?.models[0];
expect(model?.thinkingLevelMap).toEqual({ max: "max" });
expect(model?.thinkingLevelMap).toBeUndefined();
});
it("keeps Foundry chat reasoning_effort enabled for GPT-5 reasoning deployments", () => {

View File

@@ -1,8 +1,9 @@
// Microsoft Foundry provider module implements model/runtime integration.
import type { ProviderNormalizeResolvedModelContext } from "openclaw/plugin-sdk/core";
import type {
ModelProviderConfig,
ProviderPlugin,
import {
resolveClaudeThinkingProfile,
type ModelProviderConfig,
type ProviderPlugin,
} from "openclaw/plugin-sdk/provider-model-shared";
import { OPENAI_RESPONSES_STREAM_HOOKS } from "openclaw/plugin-sdk/provider-stream-family";
import { apiKeyAuthMethod, entraIdAuthMethod } from "./auth.js";
@@ -13,6 +14,7 @@ import {
applyFoundryProviderConfig,
buildFoundryProviderBaseUrl,
extractFoundryEndpoint,
isFoundryClaudeMythosPreview,
isFoundryProviderApi,
normalizeFoundryEndpoint,
resolveFoundryModelCapabilities,
@@ -175,6 +177,19 @@ export function buildMicrosoftFoundryProvider(): ProviderPlugin {
}
applyFoundryProviderConfig(ctx.config, nextProviderConfig);
},
resolveThinkingProfile: ({ modelId, modelName }) => {
const capabilities = resolveFoundryModelCapabilities(modelId, modelName);
if (!capabilities.reasoning || capabilities.api !== "anthropic-messages") {
return undefined;
}
const profile = resolveClaudeThinkingProfile(capabilities.modelName);
return isFoundryClaudeMythosPreview(capabilities.modelName)
? {
...profile,
levels: profile.levels.filter((level) => level.id !== "xhigh" && level.id !== "max"),
}
: profile;
},
normalizeResolvedModel: ({ modelId, model }: ProviderNormalizeResolvedModelContext) => {
const endpoint = extractFoundryEndpoint(model.baseUrl ?? "");
if (!endpoint) {

View File

@@ -9,7 +9,6 @@ import {
import {
isClaudeMandatoryAdaptiveThinkingModelId,
supportsClaudeAdaptiveThinking,
supportsClaudeNativeMaxEffort,
supportsClaudeNativeXhighEffort,
type ModelApi,
type ModelProviderConfig,
@@ -157,6 +156,10 @@ export function isAnthropicFoundryDeployment(modelName?: string | null): boolean
return normalized ? normalized.startsWith("claude") : false;
}
export function isFoundryClaudeMythosPreview(value?: string | null): boolean {
return normalizeFoundryModelName(value) === "claude-mythos-preview";
}
export function usesFoundryResponsesByDefault(value?: string | null): boolean {
const normalized = normalizeFoundryModelName(value);
if (!normalized) {
@@ -417,7 +420,6 @@ export function resolveFoundryModelCapabilities(
const supportedReasoningEfforts = resolveFoundryReasoningEfforts(modelName);
const isAnthropic = api === ANTHROPIC_MESSAGES_API || isAnthropicFoundryDeployment(modelName);
const supportsClaudeThinking = isAnthropic && supportsClaudeAdaptiveThinking(modelName);
const supportsClaudeMaxThinking = isAnthropic && supportsClaudeNativeMaxEffort(modelName);
const supportsClaudeXhighThinking = isAnthropic && supportsClaudeNativeXhighEffort(modelName);
const tokenLimits = resolveFoundryModelTokenLimits(modelName);
return {
@@ -429,11 +431,9 @@ export function resolveFoundryModelCapabilities(
supportsFoundryReasoningContent(modelName),
...(supportsClaudeXhighThinking
? { thinkingLevelMap: { xhigh: "xhigh", max: "max" } }
: supportsClaudeMaxThinking
? { thinkingLevelMap: { max: "max" } }
: supportedReasoningEfforts
? { thinkingLevelMap: buildFoundryThinkingLevelMap(supportedReasoningEfforts) }
: {}),
: supportedReasoningEfforts
? { thinkingLevelMap: buildFoundryThinkingLevelMap(supportedReasoningEfforts) }
: {}),
input:
normalizedInput.includes("image") || supportsFoundryImageInput(modelName)
? ["text", "image"]