fix(models): reflect context1m config in models list contextWindow display
Wire resolveContextTokensForModel() into toModelRow() so 'oc models list' reflects the context1m config param in the Ctx column. Anthropic Opus/Sonnet 4.x models with context1m: true now display '1M' instead of '195k'/'200k'. Re-submission of #46781 (was auto-closed by bot due to active PR limit).
This commit is contained in:
parent
5e417b44e1
commit
84d6506460
99
src/commands/models/list.registry.test.ts
Normal file
99
src/commands/models/list.registry.test.ts
Normal file
@ -0,0 +1,99 @@
|
||||
import type { Api, Model } from "@mariozechner/pi-ai";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
|
||||
const MOCK_1M_TOKENS = 1_048_576;
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
resolveContextTokensForModel: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../../agents/context.js", () => ({
|
||||
resolveContextTokensForModel: (...args: unknown[]) => mocks.resolveContextTokensForModel(...args),
|
||||
}));
|
||||
vi.mock("../../agents/agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir: () => "/tmp/fake-agent-dir",
|
||||
}));
|
||||
vi.mock("../../agents/auth-profiles.js", () => ({
|
||||
listProfilesForProvider: () => [],
|
||||
}));
|
||||
vi.mock("../../agents/model-auth.js", () => ({
|
||||
hasUsableCustomProviderApiKey: () => false,
|
||||
resolveAwsSdkEnvVarName: () => undefined,
|
||||
resolveEnvApiKey: () => undefined,
|
||||
}));
|
||||
vi.mock("../../agents/model-suppression.js", () => ({
|
||||
shouldSuppressBuiltInModel: () => false,
|
||||
}));
|
||||
vi.mock("../../agents/pi-model-discovery.js", () => ({
|
||||
discoverAuthStorage: () => ({}),
|
||||
discoverModels: () => ({ getAll: () => [], getAvailable: () => [] }),
|
||||
}));
|
||||
|
||||
const { toModelRow } = await import("./list.registry.js");
|
||||
|
||||
function makeModel(overrides: Partial<Model<Api>> = {}): Model<Api> {
|
||||
return {
|
||||
provider: "anthropic",
|
||||
id: "claude-opus-4-6",
|
||||
api: "anthropic-messages",
|
||||
name: "Claude Opus 4.6",
|
||||
input: ["text", "image"],
|
||||
contextWindow: 200_000,
|
||||
...overrides,
|
||||
} as Model<Api>;
|
||||
}
|
||||
|
||||
describe("toModelRow", () => {
|
||||
it("reflects context1m-resolved contextWindow from resolveContextTokensForModel", () => {
|
||||
mocks.resolveContextTokensForModel.mockReturnValue(MOCK_1M_TOKENS);
|
||||
|
||||
const row = toModelRow({
|
||||
model: makeModel(),
|
||||
key: "anthropic/claude-opus-4-6",
|
||||
tags: [],
|
||||
cfg: {} as OpenClawConfig,
|
||||
});
|
||||
|
||||
expect(row.contextWindow).toBe(MOCK_1M_TOKENS);
|
||||
expect(mocks.resolveContextTokensForModel).toHaveBeenCalledWith({
|
||||
cfg: expect.anything(),
|
||||
provider: "anthropic",
|
||||
model: "claude-opus-4-6",
|
||||
fallbackContextTokens: 200_000,
|
||||
});
|
||||
});
|
||||
|
||||
it("falls back to registry contextWindow when resolveContextTokensForModel returns undefined", () => {
|
||||
mocks.resolveContextTokensForModel.mockReturnValue(undefined);
|
||||
|
||||
const row = toModelRow({
|
||||
model: makeModel({ contextWindow: 200_000 }),
|
||||
key: "anthropic/claude-opus-4-6",
|
||||
tags: [],
|
||||
cfg: {} as OpenClawConfig,
|
||||
});
|
||||
|
||||
expect(row.contextWindow).toBeNull();
|
||||
});
|
||||
|
||||
it("passes provider and model from the Model object, not the key", () => {
|
||||
mocks.resolveContextTokensForModel.mockReturnValue(128_000);
|
||||
|
||||
const row = toModelRow({
|
||||
model: makeModel({ provider: "openai", id: "gpt-5.2", contextWindow: 128_000 }),
|
||||
key: "openai/gpt-5.2",
|
||||
tags: [],
|
||||
cfg: {} as OpenClawConfig,
|
||||
});
|
||||
|
||||
expect(row.contextWindow).toBe(128_000);
|
||||
expect(mocks.resolveContextTokensForModel).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
provider: "openai",
|
||||
model: "gpt-5.2",
|
||||
fallbackContextTokens: 128_000,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -3,6 +3,7 @@ import type { ModelRegistry } from "@mariozechner/pi-coding-agent";
|
||||
import { resolveOpenClawAgentDir } from "../../agents/agent-paths.js";
|
||||
import type { AuthProfileStore } from "../../agents/auth-profiles.js";
|
||||
import { listProfilesForProvider } from "../../agents/auth-profiles.js";
|
||||
import { resolveContextTokensForModel } from "../../agents/context.js";
|
||||
import {
|
||||
hasUsableCustomProviderApiKey,
|
||||
resolveAwsSdkEnvVarName,
|
||||
@ -188,7 +189,13 @@ export function toModelRow(params: {
|
||||
key,
|
||||
name: model.name || model.id,
|
||||
input,
|
||||
contextWindow: model.contextWindow ?? null,
|
||||
contextWindow:
|
||||
resolveContextTokensForModel({
|
||||
cfg,
|
||||
provider: model.provider,
|
||||
model: model.id,
|
||||
fallbackContextTokens: model.contextWindow,
|
||||
}) ?? null,
|
||||
local,
|
||||
available,
|
||||
tags: Array.from(mergedTags),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user