惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
博客园 - 司徒正美
I
InfoQ
宝玉的分享
宝玉的分享
G
Google Developers Blog
J
Java Code Geeks
Martin Fowler
Martin Fowler
The GitHub Blog
The GitHub Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
罗磊的独立博客
腾讯CDC
F
Fortinet All Blogs
A
About on SuperTechFans
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Recent Announcements
Recent Announcements
Last Week in AI
Last Week in AI
B
Blog RSS Feed
博客园 - 聂微东
D
DataBreaches.Net
Hugging Face - Blog
Hugging Face - Blog
The Cloudflare Blog
L
LangChain Blog
Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
fix(agents): normalize prefixed Anthropic model ids (#885...
TurboTheTurt · 2026-05-31 · via Recent Commits to openclaw:main

File tree

  • packages/model-catalog-core/src

Original file line numberDiff line numberDiff line change

@@ -34,4 +34,16 @@ describe("provider model id policy normalization", () => {

3434

),

3535

).toBe("openrouter/google/gemini-3.1-pro-preview");

3636

});

37+
38+

it("normalizes native Anthropic catalog refs without retaining the provider prefix", () => {

39+

expect(

40+

normalizeStaticProviderModelIdWithPolicies(

41+

"anthropic",

42+

"anthropic/claude-haiku-4-5",

43+

),

44+

).toBe("claude-haiku-4-5");

45+

expect(

46+

normalizeConfiguredProviderCatalogModelId("anthropic", "anthropic/claude-haiku-4-5"),

47+

).toBe("claude-haiku-4-5");

48+

});

3749

});

Original file line numberDiff line numberDiff line change

@@ -119,7 +119,12 @@ export function normalizeBuiltInProviderModelId(provider: string, model: string)

119119

"opus-4.6": "claude-opus-4-6",

120120

"sonnet-4.6": "claude-sonnet-4-6",

121121

};

122-

return anthropicAliases[normalizeLowercaseStringOrEmpty(model)] ?? model;

122+

const anthropicPrefix = "anthropic/";

123+

const normalizedModel = normalizeLowercaseStringOrEmpty(model);

124+

const providerModel = normalizedModel.startsWith(anthropicPrefix)

125+

? model.trim().slice(anthropicPrefix.length)

126+

: model;

127+

return anthropicAliases[normalizeLowercaseStringOrEmpty(providerModel)] ?? providerModel;

123128

}

124129

if (normalizedProvider === "vercel-ai-gateway") {

125130

const vercelAliases: Record<string, string> = {

Original file line numberDiff line numberDiff line change

@@ -556,6 +556,70 @@ describe("resolveModel", () => {

556556

expect(discoverModels).not.toHaveBeenCalled();

557557

});

558558
559+

it("looks up each static fallback candidate with its own normalized model id", async () => {

560+

resolveBundledStaticCatalogModelMock.mockImplementation(({ provider, modelId }) => ({

561+

provider,

562+

id: modelId,

563+

name: modelId,

564+

api: "openai-responses",

565+

input: ["text"],

566+

cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },

567+

}));

568+
569+

const anthropicResult = await resolveModelAsync(

570+

"anthropic",

571+

"anthropic/claude-haiku-4-5",

572+

"/tmp/agent",

573+

undefined,

574+

{

575+

allowBundledStaticCatalogFallback: true,

576+

runtimeHooks: createRuntimeHooks(),

577+

skipAgentDiscovery: true,

578+

skipProviderRuntimeHooks: true,

579+

},

580+

);

581+

const openaiResult = await resolveModelAsync("openai", "gpt-4o", "/tmp/agent", undefined, {

582+

allowBundledStaticCatalogFallback: true,

583+

runtimeHooks: createRuntimeHooks(),

584+

skipAgentDiscovery: true,

585+

skipProviderRuntimeHooks: true,

586+

});

587+
588+

expectRecordFields(expectResolvedModel(anthropicResult), {

589+

provider: "anthropic",

590+

id: "claude-haiku-4-5",

591+

});

592+

expectRecordFields(expectResolvedModel(openaiResult), {

593+

provider: "openai",

594+

id: "gpt-4o",

595+

});

596+

expect(resolveBundledStaticCatalogModelMock).toHaveBeenCalledWith({

597+

provider: "anthropic",

598+

modelId: "claude-haiku-4-5",

599+

cfg: undefined,

600+

workspaceDir: undefined,

601+

});

602+

expect(resolveBundledStaticCatalogModelMock).toHaveBeenCalledWith({

603+

provider: "openai",

604+

modelId: "gpt-4o",

605+

cfg: undefined,

606+

workspaceDir: undefined,

607+

});

608+

expect(resolveBundledStaticCatalogModelMock).not.toHaveBeenCalledWith(

609+

expect.objectContaining({

610+

provider: "openai",

611+

modelId: "claude-haiku-4-5",

612+

}),

613+

);

614+

expect(resolveBundledStaticCatalogModelMock).not.toHaveBeenCalledWith(

615+

expect.objectContaining({

616+

modelId: "anthropic/claude-haiku-4-5",

617+

}),

618+

);

619+

expect(discoverAuthStorage).not.toHaveBeenCalled();

620+

expect(discoverModels).not.toHaveBeenCalled();

621+

});

622+
559623

it("applies provider overrides to bundled static catalog rows while skipping agent discovery", async () => {

560624

resolveBundledStaticCatalogModelMock.mockReturnValueOnce({

561625

provider: "mistral",

Original file line numberDiff line numberDiff line change

@@ -1716,6 +1716,36 @@ describe("runWithModelFallback", () => {

17161716

]);

17171717

});

17181718
1719+

it("normalizes prefixed Anthropic fallback candidates independently", () => {

1720+

const cfg = makeCfg({

1721+

agents: {

1722+

defaults: {

1723+

model: {

1724+

primary: "anthropic/claude-sonnet-4-6",

1725+

fallbacks: ["anthropic/claude-haiku-4-5", "anthropic/claude-opus-4-7"],

1726+

},

1727+

models: {

1728+

"anthropic/claude-sonnet-4-6": {},

1729+

"anthropic/claude-haiku-4-5": {},

1730+

"anthropic/claude-opus-4-7": {},

1731+

},

1732+

},

1733+

},

1734+

});

1735+
1736+

const candidates = testing.resolveFallbackCandidates({

1737+

cfg,

1738+

provider: "anthropic",

1739+

model: "anthropic/claude-sonnet-4-6",

1740+

});

1741+
1742+

expect(candidates).toEqual([

1743+

{ provider: "anthropic", model: "claude-sonnet-4-6" },

1744+

{ provider: "anthropic", model: "claude-haiku-4-5" },

1745+

{ provider: "anthropic", model: "claude-opus-4-7" },

1746+

]);

1747+

});

1748+
17191749

it("tries configured fallbacks before primary for override credential validation errors", async () => {

17201750

const cfg = makeCfg();

17211751

const run = createOverrideFailureRun({

Original file line numberDiff line numberDiff line change

@@ -39,6 +39,12 @@ describe("normalizeStaticProviderModelId", () => {

3939

);

4040

});

4141
42+

it("strips native Anthropic provider prefixes from static catalog ids", () => {

43+

expect(normalizeStaticProviderModelId("anthropic", "anthropic/claude-haiku-4-5")).toBe(

44+

"claude-haiku-4-5",

45+

);

46+

});

47+
4248

it("uses supplied manifest normalization policies when provided", () => {

4349

const manifestPlugins = [

4450

{