mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-02 11:51:35 +00:00
fix(anthropic): honor opus 5 aliases
This commit is contained in:
@@ -280,6 +280,14 @@ describe("anthropic stream wrappers", () => {
|
||||
expect(captured.model?.cost.output).toBe(50);
|
||||
});
|
||||
|
||||
it.each(["opus", "opus-5"])("uses native fast mode for the %s alias", (modelId) => {
|
||||
const captured = runNativeFastModeWrapper({ modelId });
|
||||
|
||||
expect(captured.headers?.["anthropic-beta"]).toContain("fast-mode-2026-02-01");
|
||||
expect(captured.payload).toEqual({ speed: "fast" });
|
||||
expect(captured.model?.cost.output).toBe(50);
|
||||
});
|
||||
|
||||
it("keeps standard Opus 5 payload and pricing when fast mode is disabled", () => {
|
||||
const captured = runNativeFastModeWrapper({ enabled: false });
|
||||
|
||||
|
||||
@@ -99,9 +99,12 @@ export function resolveClaudeSonnet5ModelIdentity(ref: ClaudeModelRef): string |
|
||||
return normalized.slice((match.index ?? 0) + (match[0].startsWith("-") ? 1 : 0));
|
||||
}
|
||||
|
||||
/** Resolve Claude Opus 5 through direct ids, cloud ids, or deployment metadata. */
|
||||
/** Resolve Claude Opus 5 through aliases, direct ids, cloud ids, or deployment metadata. */
|
||||
export function resolveClaudeOpus5ModelIdentity(ref: ClaudeModelRef): string | undefined {
|
||||
const normalized = resolveClaudeModelIdentity(ref);
|
||||
if (normalized === "opus" || normalized === "opus-5") {
|
||||
return "claude-opus-5";
|
||||
}
|
||||
const match = /(?:^|-)claude-opus-5(?=$|[^a-z0-9])/.exec(normalized);
|
||||
if (!match) {
|
||||
return undefined;
|
||||
@@ -112,38 +115,51 @@ export function resolveClaudeOpus5ModelIdentity(ref: ClaudeModelRef): string | u
|
||||
/** Return whether a Claude model supports adaptive thinking. */
|
||||
export function supportsClaudeAdaptiveThinking(ref: ClaudeModelRef): boolean {
|
||||
const modelId = resolveClaudeModelIdentity(ref);
|
||||
return /(?:^|-)claude-(?:fable-5|mythos-(?:5|preview)|opus-(?:4-(?:6|7|8)|5)|sonnet-(?:5|4-6))(?=$|[^a-z0-9])/.test(
|
||||
modelId,
|
||||
return (
|
||||
resolveClaudeOpus5ModelIdentity(ref) !== undefined ||
|
||||
/(?:^|-)claude-(?:fable-5|mythos-(?:5|preview)|opus-4-(?:6|7|8)|sonnet-(?:5|4-6))(?=$|[^a-z0-9])/.test(
|
||||
modelId,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/** Return whether a Claude model has a native 1M-token context window. */
|
||||
export function supportsClaude1MContext(ref: ClaudeModelRef): boolean {
|
||||
const modelId = resolveClaudeModelIdentity(ref);
|
||||
return /(?:^|-)claude-(?:fable-5|mythos-(?:5|preview)|opus-(?:4-(?:6|7|8)|5)|sonnet-(?:5|4-6))(?=$|[^a-z0-9])/.test(
|
||||
modelId,
|
||||
return (
|
||||
resolveClaudeOpus5ModelIdentity(ref) !== undefined ||
|
||||
/(?:^|-)claude-(?:fable-5|mythos-(?:5|preview)|opus-4-(?:6|7|8)|sonnet-(?:5|4-6))(?=$|[^a-z0-9])/.test(
|
||||
modelId,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/** Return whether a Claude model supports Anthropic's native fast mode. */
|
||||
export function supportsClaudeFastMode(ref: ClaudeModelRef): boolean {
|
||||
const modelId = resolveClaudeModelIdentity(ref);
|
||||
return /(?:^|-)claude-opus-(?:4-8|5)(?=$|[^a-z0-9])/.test(modelId);
|
||||
return (
|
||||
resolveClaudeOpus5ModelIdentity(ref) !== undefined ||
|
||||
/(?:^|-)claude-opus-4-8(?=$|[^a-z0-9])/.test(modelId)
|
||||
);
|
||||
}
|
||||
|
||||
/** Return whether a Claude model supports native max effort. */
|
||||
export function supportsClaudeNativeMaxEffort(ref: ClaudeModelRef): boolean {
|
||||
const modelId = resolveClaudeModelIdentity(ref);
|
||||
return /(?:^|-)claude-(?:fable-5|mythos-5|opus-(?:4-(?:6|7|8)|5)|sonnet-(?:5|4-6))(?=$|[^a-z0-9])/.test(
|
||||
modelId,
|
||||
return (
|
||||
resolveClaudeOpus5ModelIdentity(ref) !== undefined ||
|
||||
/(?:^|-)claude-(?:fable-5|mythos-5|opus-4-(?:6|7|8)|sonnet-(?:5|4-6))(?=$|[^a-z0-9])/.test(
|
||||
modelId,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/** Return whether a Claude model supports native xhigh effort. */
|
||||
export function supportsClaudeNativeXhighEffort(ref: ClaudeModelRef): boolean {
|
||||
const modelId = resolveClaudeModelIdentity(ref);
|
||||
return /(?:^|-)claude-(?:fable-5|mythos-5|opus-(?:4-(?:7|8)|5)|sonnet-5)(?=$|[^a-z0-9])/.test(
|
||||
modelId,
|
||||
return (
|
||||
resolveClaudeOpus5ModelIdentity(ref) !== undefined ||
|
||||
/(?:^|-)claude-(?:fable-5|mythos-5|opus-4-(?:7|8)|sonnet-5)(?=$|[^a-z0-9])/.test(modelId)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,8 @@ describe("Claude model contracts", () => {
|
||||
|
||||
it.each([
|
||||
["Anthropic API", { id: "claude-opus-5" }, "claude-opus-5"],
|
||||
["Anthropic alias", { id: "opus" }, "claude-opus-5"],
|
||||
["Anthropic version alias", { id: "opus-5" }, "claude-opus-5"],
|
||||
["Claude CLI", { id: "claude-opus-5" }, "claude-opus-5"],
|
||||
["Vertex AI", { id: "claude-opus-5@20260701" }, "claude-opus-5@20260701"],
|
||||
["Amazon Bedrock", { id: "global.anthropic.claude-opus-5" }, "claude-opus-5"],
|
||||
@@ -108,6 +110,8 @@ describe("Claude model contracts", () => {
|
||||
|
||||
it("recognizes native fast-mode Claude models", () => {
|
||||
expect(supportsClaudeFastMode({ id: "claude-opus-5" })).toBe(true);
|
||||
expect(supportsClaudeFastMode({ id: "opus" })).toBe(true);
|
||||
expect(supportsClaudeFastMode({ id: "opus-5" })).toBe(true);
|
||||
expect(supportsClaudeFastMode({ id: "global.anthropic.claude-opus-5" })).toBe(true);
|
||||
expect(supportsClaudeFastMode({ id: "claude-opus-4.8" })).toBe(true);
|
||||
expect(supportsClaudeFastMode({ id: "claude-opus-4-7" })).toBe(false);
|
||||
|
||||
Reference in New Issue
Block a user