mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-23 06:28:08 +00:00
* feat(anthropic): support Claude Fable 5 * test(anthropic): tighten Fable stream fixtures * fix(anthropic): preserve Vertex input types * test(anthropic): use provider-ready Vertex effort * fix(anthropic): support Fable deployment aliases * fix(anthropic): discard incomplete Fable output * feat(anthropic): support Fable on Bedrock * fix(anthropic): preserve Fable reasoning contracts * refactor(anthropic): unify canonical Claude model policy * fix(anthropic): satisfy extension thinking types * test(anthropic): complete canonical alias fixture * fix(bedrock): scope thinking case declarations
122 lines
3.9 KiB
TypeScript
122 lines
3.9 KiB
TypeScript
// Github Copilot plugin module implements model metadata behavior.
|
|
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
|
import { supportsClaudeAdaptiveThinking } from "openclaw/plugin-sdk/provider-model-shared";
|
|
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
|
|
type CopilotRuntimeApi = "anthropic-messages" | "openai-completions" | "openai-responses";
|
|
type CopilotReasoningCompat = {
|
|
supportedReasoningEfforts?: readonly string[] | null;
|
|
};
|
|
|
|
const COPILOT_CHAT_COMPLETIONS_COMPAT: ModelDefinitionConfig["compat"] = {
|
|
supportsStore: false,
|
|
supportsDeveloperRole: false,
|
|
supportsUsageInStreaming: false,
|
|
maxTokensField: "max_tokens",
|
|
};
|
|
const COPILOT_XHIGH_MODEL_IDS = new Set(["gpt-5.4", "gpt-5.3-codex"]);
|
|
|
|
const STATIC_MODEL_OVERRIDES = new Map<string, Partial<ModelDefinitionConfig>>([
|
|
[
|
|
"claude-opus-4.6-1m",
|
|
{
|
|
name: "Claude Opus 4.6 (1M context)",
|
|
api: "anthropic-messages",
|
|
reasoning: true,
|
|
contextWindow: 1_000_000,
|
|
maxTokens: 64_000,
|
|
thinkingLevelMap: { xhigh: null, max: null },
|
|
compat: { supportedReasoningEfforts: ["low", "medium", "high"] },
|
|
},
|
|
],
|
|
[
|
|
"claude-opus-4.7-1m-internal",
|
|
{
|
|
name: "Claude Opus 4.7 (1M context)",
|
|
api: "anthropic-messages",
|
|
reasoning: true,
|
|
contextWindow: 1_000_000,
|
|
maxTokens: 64_000,
|
|
thinkingLevelMap: { xhigh: "xhigh", max: null },
|
|
compat: { supportedReasoningEfforts: ["low", "medium", "high", "xhigh"] },
|
|
},
|
|
],
|
|
[
|
|
"gpt-5.5",
|
|
{
|
|
name: "GPT-5.5",
|
|
reasoning: true,
|
|
contextWindow: 400_000,
|
|
maxTokens: 128_000,
|
|
},
|
|
],
|
|
]);
|
|
|
|
function isCopilotGeminiModelId(modelId: string): boolean {
|
|
return /(?:^|[-_.])gemini(?:$|[-_.])/.test(modelId);
|
|
}
|
|
|
|
export function resolveCopilotTransportApi(modelId: string): CopilotRuntimeApi {
|
|
const normalized = normalizeOptionalLowercaseString(modelId) ?? "";
|
|
if (normalized.includes("claude")) {
|
|
return "anthropic-messages";
|
|
}
|
|
if (isCopilotGeminiModelId(normalized)) {
|
|
return "openai-completions";
|
|
}
|
|
return "openai-responses";
|
|
}
|
|
|
|
export function resolveCopilotModelCompat(
|
|
modelId: string,
|
|
): ModelDefinitionConfig["compat"] | undefined {
|
|
const normalized = normalizeOptionalLowercaseString(modelId) ?? "";
|
|
return isCopilotGeminiModelId(normalized) ? { ...COPILOT_CHAT_COMPLETIONS_COMPAT } : undefined;
|
|
}
|
|
|
|
function compatSupportsEffort(
|
|
compat: CopilotReasoningCompat | null | undefined,
|
|
effort: "xhigh" | "max",
|
|
): boolean {
|
|
return (
|
|
Array.isArray(compat?.supportedReasoningEfforts) &&
|
|
compat.supportedReasoningEfforts.some(
|
|
(candidate) => normalizeOptionalLowercaseString(candidate) === effort,
|
|
)
|
|
);
|
|
}
|
|
|
|
export function resolveCopilotExtendedThinkingLevels(
|
|
modelId: string,
|
|
compat?: CopilotReasoningCompat | null,
|
|
): Array<"xhigh" | "max"> {
|
|
const normalizedModelId = normalizeOptionalLowercaseString(modelId) ?? "";
|
|
const staticCompat = resolveStaticCopilotModelOverride(normalizedModelId)?.compat;
|
|
const isClaudeModel = normalizedModelId.includes("claude");
|
|
const supportsAdaptiveClaudeEffort =
|
|
!isClaudeModel || supportsClaudeAdaptiveThinking({ id: normalizedModelId });
|
|
const levels: Array<"xhigh" | "max"> = [];
|
|
if (
|
|
supportsAdaptiveClaudeEffort &&
|
|
(COPILOT_XHIGH_MODEL_IDS.has(normalizedModelId) ||
|
|
compatSupportsEffort(compat, "xhigh") ||
|
|
compatSupportsEffort(staticCompat, "xhigh"))
|
|
) {
|
|
levels.push("xhigh");
|
|
}
|
|
if (
|
|
isClaudeModel &&
|
|
supportsAdaptiveClaudeEffort &&
|
|
(compatSupportsEffort(compat, "max") || compatSupportsEffort(staticCompat, "max"))
|
|
) {
|
|
levels.push("max");
|
|
}
|
|
return levels;
|
|
}
|
|
|
|
export function resolveStaticCopilotModelOverride(
|
|
modelId: string,
|
|
): Partial<ModelDefinitionConfig> | undefined {
|
|
return STATIC_MODEL_OVERRIDES.get(normalizeOptionalLowercaseString(modelId) ?? "");
|
|
}
|