Files
oh-my-pi/packages/catalog/test/kimi-code-provider.test.ts
T
roboomp 913ec0baae fix(kimi-code): preserved k3 native effort contract
- Parsed live named efforts, mandatory-thinking state, and model protocol metadata.

- Sent native Kimi named efforts and adaptive Anthropic override efforts without generic token budgets.

Fixes #5893
2026-07-17 18:19:00 +00:00

79 lines
2.6 KiB
TypeScript

import { describe, expect, it } from "bun:test";
import { buildModel } from "@oh-my-pi/pi-catalog/build";
import { Effort } from "@oh-my-pi/pi-catalog/effort";
import { kimiCodeModelManagerOptions } from "@oh-my-pi/pi-catalog/provider-models/openai-compat";
import type { FetchImpl } from "@oh-my-pi/pi-catalog/types";
const LIVE_K3 = {
id: "k3",
display_name: "K3",
context_length: 1_048_576,
supports_reasoning: true,
supports_thinking_type: "only",
think_efforts: {
support: true,
valid_efforts: ["low", "high", "max"],
default_effort: "max",
},
protocol: null,
};
async function discover(models: readonly Record<string, unknown>[]) {
const fetchImpl: FetchImpl = async () => Response.json({ data: models });
const fetchDynamicModels = kimiCodeModelManagerOptions({ apiKey: "test-key", fetch: fetchImpl }).fetchDynamicModels;
if (!fetchDynamicModels) throw new Error("Kimi Code dynamic discovery is not configured");
return (await fetchDynamicModels())?.map(buildModel) ?? [];
}
describe("Kimi Code provider catalog", () => {
it("uses live K3 effort, mandatory-thinking, and native-protocol metadata", async () => {
const models = await discover([LIVE_K3]);
const model = models.find(candidate => candidate.id === "k3");
expect(model).toMatchObject({
id: "k3",
name: "K3",
reasoning: true,
contextWindow: 1_048_576,
thinking: {
mode: "effort",
efforts: [Effort.Low, Effort.High, Effort.Max],
defaultLevel: Effort.Max,
requiresEffort: true,
},
compat: {
thinkingFormat: "kimi",
kimiApiFormat: "openai",
},
});
});
it("uses server protocol while preserving legacy K2 discovery defaults", async () => {
const models = await discover([
{ ...LIVE_K3, id: "k3-anthropic", protocol: "anthropic" },
{
id: "kimi-for-coding",
display_name: "K2.7 Code",
context_length: 262_144,
supports_reasoning: true,
},
]);
const anthropic = models.find(candidate => candidate.id === "k3-anthropic");
const legacy = models.find(candidate => candidate.id === "kimi-for-coding");
expect(anthropic?.compat.kimiApiFormat).toBe("anthropic");
expect(legacy?.compat).toMatchObject({ thinkingFormat: "zai" });
expect(legacy?.compat.kimiApiFormat).toBeUndefined();
expect(legacy?.thinking?.efforts).toEqual([Effort.Minimal, Effort.Low, Effort.Medium, Effort.High]);
});
it("lets supports_thinking_type override the legacy reasoning flag", async () => {
const models = await discover([
{ ...LIVE_K3, id: "non-thinking", supports_thinking_type: "no", think_efforts: undefined },
]);
expect(models[0]?.reasoning).toBe(false);
expect(models[0]?.thinking).toBeUndefined();
});
});