mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-18 15:14:45 +00:00
test: tighten anthropic provider assertions
This commit is contained in:
@@ -47,21 +47,42 @@ function createModelRegistry(models: ProviderRuntimeModel[]) {
|
||||
};
|
||||
}
|
||||
|
||||
function requireRecord(value: unknown, label: string): Record<string, unknown> {
|
||||
expect(value, label).toBeTypeOf("object");
|
||||
expect(value, label).not.toBeNull();
|
||||
return value as Record<string, unknown>;
|
||||
}
|
||||
|
||||
function expectFields(value: unknown, fields: Record<string, unknown>) {
|
||||
const record = requireRecord(value, "record");
|
||||
for (const [key, expected] of Object.entries(fields)) {
|
||||
expect(record[key]).toEqual(expected);
|
||||
}
|
||||
}
|
||||
|
||||
function expectModelParams(models: unknown, modelId: string, params: Record<string, unknown>) {
|
||||
const model = requireRecord(requireRecord(models, "models")[modelId], modelId);
|
||||
expectFields(model.params, params);
|
||||
}
|
||||
|
||||
function levelIds(profile: unknown): Array<unknown> {
|
||||
const levels = requireRecord(profile, "thinking profile").levels;
|
||||
expect(Array.isArray(levels), "thinking levels").toBe(true);
|
||||
return (levels as Array<{ id?: unknown }>).map((level) => level.id);
|
||||
}
|
||||
|
||||
describe("anthropic provider replay hooks", () => {
|
||||
it("registers the claude-cli backend", () => {
|
||||
const captured = capturePluginRegistration({ register: anthropicPlugin.register });
|
||||
|
||||
expect(captured.cliBackends).toContainEqual(
|
||||
expect.objectContaining({
|
||||
id: "claude-cli",
|
||||
bundleMcp: true,
|
||||
config: expect.objectContaining({
|
||||
command: "claude",
|
||||
modelArg: "--model",
|
||||
sessionArg: "--session-id",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
const backend = captured.cliBackends.find((entry) => entry.id === "claude-cli");
|
||||
expect(backend).toBeDefined();
|
||||
expect(backend?.bundleMcp).toBe(true);
|
||||
expectFields(backend?.config, {
|
||||
command: "claude",
|
||||
modelArg: "--model",
|
||||
sessionArg: "--session-id",
|
||||
});
|
||||
});
|
||||
|
||||
it("owns native reasoning output mode for Claude transports", async () => {
|
||||
@@ -101,30 +122,32 @@ describe("anthropic provider replay hooks", () => {
|
||||
const provider = await registerSingleProviderPlugin(anthropicPlugin);
|
||||
|
||||
expect(
|
||||
provider.normalizeConfig?.({
|
||||
provider: "anthropic",
|
||||
providerConfig: {
|
||||
models: [{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" }],
|
||||
},
|
||||
} as never),
|
||||
).toMatchObject({
|
||||
api: "anthropic-messages",
|
||||
});
|
||||
requireRecord(
|
||||
provider.normalizeConfig?.({
|
||||
provider: "anthropic",
|
||||
providerConfig: {
|
||||
models: [{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" }],
|
||||
},
|
||||
} as never),
|
||||
"normalized config",
|
||||
).api,
|
||||
).toBe("anthropic-messages");
|
||||
});
|
||||
|
||||
it("defaults Claude CLI provider api through plugin config normalization", async () => {
|
||||
const provider = await registerSingleProviderPlugin(anthropicPlugin);
|
||||
|
||||
expect(
|
||||
provider.normalizeConfig?.({
|
||||
provider: "claude-cli",
|
||||
providerConfig: {
|
||||
models: [{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" }],
|
||||
},
|
||||
} as never),
|
||||
).toMatchObject({
|
||||
api: "anthropic-messages",
|
||||
});
|
||||
requireRecord(
|
||||
provider.normalizeConfig?.({
|
||||
provider: "claude-cli",
|
||||
providerConfig: {
|
||||
models: [{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" }],
|
||||
},
|
||||
} as never),
|
||||
"normalized config",
|
||||
).api,
|
||||
).toBe("anthropic-messages");
|
||||
});
|
||||
|
||||
it("does not default non-Anthropic provider api through plugin config normalization", async () => {
|
||||
@@ -162,11 +185,11 @@ describe("anthropic provider replay hooks", () => {
|
||||
},
|
||||
} as never);
|
||||
|
||||
expect(next?.agents?.defaults?.contextPruning).toMatchObject({
|
||||
expectFields(next?.agents?.defaults?.contextPruning, {
|
||||
mode: "cache-ttl",
|
||||
ttl: "1h",
|
||||
});
|
||||
expect(next?.agents?.defaults?.heartbeat).toMatchObject({
|
||||
expectFields(next?.agents?.defaults?.heartbeat, {
|
||||
every: "30m",
|
||||
});
|
||||
expect(
|
||||
@@ -197,10 +220,9 @@ describe("anthropic provider replay hooks", () => {
|
||||
},
|
||||
} as never);
|
||||
|
||||
expect(next?.agents?.defaults?.models).toMatchObject({
|
||||
"anthropic/claude-sonnet-4-6": { params: { cacheRetention: "short" } },
|
||||
"anthropic/claude-haiku-4-5": { params: { cacheRetention: "short" } },
|
||||
});
|
||||
const models = next?.agents?.defaults?.models;
|
||||
expectModelParams(models, "anthropic/claude-sonnet-4-6", { cacheRetention: "short" });
|
||||
expectModelParams(models, "anthropic/claude-haiku-4-5", { cacheRetention: "short" });
|
||||
});
|
||||
|
||||
it("backfills Claude CLI allowlist defaults through plugin hooks for older configs", async () => {
|
||||
@@ -227,17 +249,20 @@ describe("anthropic provider replay hooks", () => {
|
||||
},
|
||||
} as never);
|
||||
|
||||
expect(next?.agents?.defaults?.heartbeat).toMatchObject({
|
||||
expectFields(next?.agents?.defaults?.heartbeat, {
|
||||
every: "1h",
|
||||
});
|
||||
expect(next?.agents?.defaults?.models).toMatchObject({
|
||||
"anthropic/claude-opus-4-7": {},
|
||||
"anthropic/claude-sonnet-4-6": {},
|
||||
"anthropic/claude-opus-4-6": {},
|
||||
"anthropic/claude-opus-4-5": {},
|
||||
"anthropic/claude-sonnet-4-5": {},
|
||||
"anthropic/claude-haiku-4-5": {},
|
||||
});
|
||||
const models = requireRecord(next?.agents?.defaults?.models, "models");
|
||||
for (const modelId of [
|
||||
"anthropic/claude-opus-4-7",
|
||||
"anthropic/claude-sonnet-4-6",
|
||||
"anthropic/claude-opus-4-6",
|
||||
"anthropic/claude-opus-4-5",
|
||||
"anthropic/claude-sonnet-4-5",
|
||||
"anthropic/claude-haiku-4-5",
|
||||
]) {
|
||||
expect(models[modelId]).toEqual({});
|
||||
}
|
||||
});
|
||||
|
||||
it("resolves explicit claude-opus-4-7 refs from the 4.6 template family", async () => {
|
||||
@@ -260,7 +285,7 @@ describe("anthropic provider replay hooks", () => {
|
||||
]),
|
||||
} as ProviderResolveDynamicModelContext);
|
||||
|
||||
expect(resolved).toMatchObject({
|
||||
expectFields(resolved, {
|
||||
provider: "anthropic",
|
||||
id: "claude-opus-4-7",
|
||||
api: "anthropic-messages",
|
||||
@@ -268,24 +293,21 @@ describe("anthropic provider replay hooks", () => {
|
||||
contextWindow: 1_048_576,
|
||||
contextTokens: 1_048_576,
|
||||
});
|
||||
expect(
|
||||
provider.resolveThinkingProfile?.({
|
||||
provider: "anthropic",
|
||||
modelId: "claude-opus-4-7",
|
||||
} as never),
|
||||
).toMatchObject({
|
||||
levels: expect.arrayContaining([{ id: "xhigh" }, { id: "adaptive" }, { id: "max" }]),
|
||||
defaultLevel: "off",
|
||||
});
|
||||
expect(
|
||||
provider.resolveThinkingProfile?.({
|
||||
provider: "anthropic",
|
||||
modelId: "claude-opus-4-6",
|
||||
} as never),
|
||||
).toMatchObject({
|
||||
levels: expect.arrayContaining([{ id: "adaptive" }]),
|
||||
defaultLevel: "adaptive",
|
||||
});
|
||||
const opus47Profile = provider.resolveThinkingProfile?.({
|
||||
provider: "anthropic",
|
||||
modelId: "claude-opus-4-7",
|
||||
} as never);
|
||||
const opus47LevelIds = levelIds(opus47Profile);
|
||||
expect(opus47LevelIds).toContain("xhigh");
|
||||
expect(opus47LevelIds).toContain("adaptive");
|
||||
expect(opus47LevelIds).toContain("max");
|
||||
expect(requireRecord(opus47Profile, "opus 4.7 thinking profile").defaultLevel).toBe("off");
|
||||
const opus46Profile = provider.resolveThinkingProfile?.({
|
||||
provider: "anthropic",
|
||||
modelId: "claude-opus-4-6",
|
||||
} as never);
|
||||
expect(levelIds(opus46Profile)).toContain("adaptive");
|
||||
expect(requireRecord(opus46Profile, "opus 4.6 thinking profile").defaultLevel).toBe("adaptive");
|
||||
expect(
|
||||
provider
|
||||
.resolveThinkingProfile?.({
|
||||
@@ -327,7 +349,7 @@ describe("anthropic provider replay hooks", () => {
|
||||
["anthropic", "claude-opus-4-7"],
|
||||
["claude-cli", "claude-opus-4.7-20260219"],
|
||||
] as const) {
|
||||
expect(
|
||||
expectFields(
|
||||
provider.normalizeResolvedModel?.({
|
||||
provider: runtimeProvider,
|
||||
modelId,
|
||||
@@ -344,10 +366,11 @@ describe("anthropic provider replay hooks", () => {
|
||||
maxTokens: 32_000,
|
||||
},
|
||||
} as never),
|
||||
).toMatchObject({
|
||||
contextWindow: 1_048_576,
|
||||
contextTokens: 1_048_576,
|
||||
});
|
||||
{
|
||||
contextWindow: 1_048_576,
|
||||
contextTokens: 1_048_576,
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user