mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-25 10:42:45 +00:00
feat(claude): add Haiku 5.5 with its model capabilities (#6332)
This commit is contained in:
@@ -122,10 +122,15 @@ const EXPECTED_CLAUDE_MODELS = [
|
||||
model: "Opus 4.6",
|
||||
descriptionFragment: "Most capable",
|
||||
},
|
||||
{
|
||||
id: "claude-haiku-5-5",
|
||||
model: "Haiku 5.5",
|
||||
descriptionFragment: "Fastest",
|
||||
},
|
||||
{
|
||||
id: "claude-haiku-4-5",
|
||||
model: "Haiku 4.5",
|
||||
descriptionFragment: "Fastest",
|
||||
descriptionFragment: "Previous release",
|
||||
},
|
||||
] as const;
|
||||
|
||||
@@ -435,8 +440,8 @@ try {
|
||||
"--quiet should print the same ordered model IDs returned by --json",
|
||||
);
|
||||
assert(
|
||||
claudeModelsFromJson.some((m) => m.id === "claude-sonnet-5-5"),
|
||||
"captured --json output should include the current Claude everyday model id",
|
||||
claudeModelsFromJson.some((m) => m.id === "claude-haiku-5-5"),
|
||||
"captured --json output should include the current Claude quick-answer model id",
|
||||
);
|
||||
console.log("✓ provider models --quiet outputs model IDs only\n");
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
||||
const client = new ClaudeAgentClient({
|
||||
logger,
|
||||
resolveBinary: async () => "/test/claude/bin",
|
||||
resolveVersion: async () => "2.1.284",
|
||||
resolveVersion: async () => "2.1.293",
|
||||
runtimeSettings: { env: { CLAUDE_CONFIG_DIR: emptyConfigDir } },
|
||||
});
|
||||
const { models } = await client.fetchCatalog({
|
||||
@@ -515,6 +515,15 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
||||
expect(getThinkingIds("claude-opus-4-8")).toContain("ultracode");
|
||||
expect(getThinkingIds("claude-sonnet-5")).toContain("xhigh");
|
||||
expect(getThinkingIds("claude-sonnet-5")).toContain("ultracode");
|
||||
expect(getThinkingIds("claude-haiku-5-5")).toEqual([
|
||||
"off",
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max",
|
||||
"ultracode",
|
||||
]);
|
||||
expect(getThinkingIds("claude-sonnet-5-5")).toContain("xhigh");
|
||||
expect(getThinkingIds("claude-sonnet-5-5")).not.toContain("off");
|
||||
expect(getThinkingIds("claude-opus-4-7[1m]")).toContain("ultracode");
|
||||
@@ -1223,6 +1232,7 @@ describe("ClaudeAgentSession features", () => {
|
||||
|
||||
test.each([
|
||||
["supported model", "claude-opus-4-8", { type: "disabled" }, undefined],
|
||||
["Haiku 5.5", "claude-haiku-5-5", { type: "disabled" }, undefined],
|
||||
["unsupported model", "claude-fable-5", { type: "adaptive", display: "summarized" }, "high"],
|
||||
["custom model", "openrouter/anthropic/claude-opus-4-8", undefined, undefined],
|
||||
["provider default", null, undefined, undefined],
|
||||
|
||||
@@ -170,10 +170,20 @@ export const CLAUDE_MODEL_MANIFEST = [
|
||||
effortLevels: CLAUDE_EFFORT_LEVELS.standard,
|
||||
supportsThinkingDisabled: true,
|
||||
},
|
||||
{
|
||||
id: "claude-haiku-5-5",
|
||||
label: "Haiku 5.5",
|
||||
description: "Haiku 5.5 · Fastest for quick answers",
|
||||
minimumClaudeCodeVersion: "2.1.293",
|
||||
defaultThinkingOptionId: "medium",
|
||||
contextWindowMaxTokens: 1_000_000,
|
||||
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
||||
supportsThinkingDisabled: true,
|
||||
},
|
||||
{
|
||||
id: "claude-haiku-4-5",
|
||||
label: "Haiku 4.5",
|
||||
description: "Haiku 4.5 · Fastest for quick answers",
|
||||
description: "Haiku 4.5 · Previous release",
|
||||
contextWindowMaxTokens: 200_000,
|
||||
},
|
||||
] as const satisfies readonly ClaudeModelManifestEntry[];
|
||||
|
||||
@@ -39,7 +39,7 @@ async function createClaudeConfigDirWithRawSettings(settings: string): Promise<s
|
||||
return configDir;
|
||||
}
|
||||
|
||||
function createCatalogClient(claudeCodeVersion = "2.1.284"): ClaudeAgentClient {
|
||||
function createCatalogClient(claudeCodeVersion = "2.1.293"): ClaudeAgentClient {
|
||||
return new ClaudeAgentClient({
|
||||
logger: createTestLogger(),
|
||||
resolveVersion: async () => claudeCodeVersion,
|
||||
@@ -66,6 +66,7 @@ describe("getClaudeModels", () => {
|
||||
"claude-opus-4-6",
|
||||
"claude-sonnet-4-6[1m]",
|
||||
"claude-sonnet-4-6",
|
||||
"claude-haiku-5-5",
|
||||
"claude-haiku-4-5",
|
||||
]);
|
||||
});
|
||||
@@ -100,6 +101,7 @@ describe("getClaudeModels", () => {
|
||||
["claude-opus-4-6", 200_000],
|
||||
["claude-sonnet-4-6[1m]", 1_000_000],
|
||||
["claude-sonnet-4-6", 200_000],
|
||||
["claude-haiku-5-5", 1_000_000],
|
||||
["claude-haiku-4-5", 200_000],
|
||||
]),
|
||||
);
|
||||
@@ -123,6 +125,12 @@ describe("getClaudeModels", () => {
|
||||
expect(getClaudeModels("2.1.284").map((model) => model.id)).toContain("claude-sonnet-5-5");
|
||||
});
|
||||
|
||||
it("gates Haiku 5.5 on Claude Code 2.1.293 without changing the default", () => {
|
||||
expect(getClaudeModels("2.1.292").map((model) => model.id)).not.toContain("claude-haiku-5-5");
|
||||
expect(getClaudeModels("2.1.293").map((model) => model.id)).toContain("claude-haiku-5-5");
|
||||
expect(getClaudeModels("2.1.293").find((model) => model.isDefault)?.id).toBe("claude-opus-5-5");
|
||||
});
|
||||
|
||||
it("derives thinking options from model effort capabilities", () => {
|
||||
const models = new Map(getClaudeModels().map((model) => [model.id, model]));
|
||||
|
||||
@@ -192,6 +200,8 @@ describe("getClaudeModels", () => {
|
||||
["claude-sonnet-5-20260101", true, "high"],
|
||||
["claude-fable-5", false, "high"],
|
||||
["claude-fable-5-1", false, "high"],
|
||||
["claude-haiku-5-5", true, "medium"],
|
||||
["claude-haiku-5-5-20261007", true, "medium"],
|
||||
["claude-haiku-4-5", false, undefined],
|
||||
["openrouter/anthropic/claude-opus-4-8", false, undefined],
|
||||
[null, false, undefined],
|
||||
@@ -653,6 +663,51 @@ describe("Claude Sonnet 5.5 catalog", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Claude Haiku 5.5 catalog", () => {
|
||||
it("offers one Haiku 5.5 entry with a 1M context window", () => {
|
||||
const haiku55Models = getClaudeModels()
|
||||
.filter((model) => model.id.startsWith("claude-haiku-5-5"))
|
||||
.map(({ id, label, contextWindowMaxTokens }) => ({ id, label, contextWindowMaxTokens }));
|
||||
|
||||
expect(haiku55Models).toEqual([
|
||||
{ id: "claude-haiku-5-5", label: "Haiku 5.5", contextWindowMaxTokens: 1_000_000 },
|
||||
]);
|
||||
});
|
||||
|
||||
it("offers Off and every effort level with medium as the default", () => {
|
||||
const haiku55 = getClaudeModels().find((model) => model.id === "claude-haiku-5-5");
|
||||
|
||||
expect(haiku55?.thinkingOptions?.map((option) => option.id)).toEqual([
|
||||
CLAUDE_DISABLED_THINKING_OPTION_ID,
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max",
|
||||
CLAUDE_ULTRACODE_THINKING_OPTION_ID,
|
||||
]);
|
||||
expect(haiku55?.defaultThinkingOptionId).toBe("medium");
|
||||
expect(
|
||||
haiku55?.thinkingOptions?.filter((option) => option.isDefault).map((option) => option.id),
|
||||
).toEqual(["medium"]);
|
||||
});
|
||||
|
||||
it("normalizes provider-prefixed runtime IDs", () => {
|
||||
expect(normalizeClaudeRuntimeModelId("anthropic/claude-haiku-5-5")).toBe("claude-haiku-5-5");
|
||||
expect(normalizeClaudeRuntimeModelId("us.anthropic.claude-haiku-5-5-v1:0")).toBe(
|
||||
"claude-haiku-5-5",
|
||||
);
|
||||
expect(claudeManifestModelSupportsFastMode("claude-haiku-5-5")).toBe(false);
|
||||
});
|
||||
|
||||
it("resolves suffixed and dated Haiku 5.5 IDs to the single catalog entry", () => {
|
||||
expect(findClaudeModel("claude-haiku-5-5[1m]")?.id).toBe("claude-haiku-5-5");
|
||||
expect(findClaudeModel("claude-haiku-5-5-20261007")?.id).toBe("claude-haiku-5-5");
|
||||
expect(findClaudeModel("claude-haiku-5-5-20261007[1m]")?.id).toBe("claude-haiku-5-5");
|
||||
expect(findClaudeModel("claude-haiku-5-5[1m]")?.contextWindowMaxTokens).toBe(1_000_000);
|
||||
});
|
||||
});
|
||||
|
||||
describe("claudeManifestModelSupportsFastMode", () => {
|
||||
it("keeps fast mode strict to first-party manifest model IDs", () => {
|
||||
expect(normalizeClaudeManifestModelId("openrouter/anthropic/claude-opus-4-8")).toBeNull();
|
||||
|
||||
Reference in New Issue
Block a user