feat: per-model max output tokens and a conversation-time thinking level backed by agent settings (#28)

Co-authored-by: Alice <alice@prismshadow.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-07-22 22:22:41 +08:00
1 parent 99f391f379
commit cabbab1c16
36 files changed
+797 -42

No files matched your search

+28
View File
@@ -531,6 +531,7 @@ describe("project-config round trip", () => {
provider: "custom",
model_id: "gpt-test",
context_window: 128000,
max_tokens: 8192,
api_key: "sk-abc",
base_url: "https://example.com/v1",
},
@@ -549,6 +550,7 @@ describe("project-config round trip", () => {
provider: "custom",
model_id: "gpt-test",
context_window: 128000,
max_tokens: 8192,
api_key: "sk-abc",
base_url: "https://example.com/v1",
});
@@ -644,6 +646,32 @@ describe("project-config round trip", () => {
expect(m?.vision).toBe(true);
});
it("addModel persists max_tokens and upsert preserves it when not re-specified", async () => {
await addModel(tmpRoot, DEFAULT_PROJECT_ID, {
provider: "custom",
model_id: "small-window",
max_tokens: 4096,
});
// Only supplements context_window, without max_tokens: the original annotation is kept.
await addModel(tmpRoot, DEFAULT_PROJECT_ID, {
provider: "custom",
model_id: "small-window",
context_window: 32768,
});
const ref = { provider: "custom", model_id: "small-window" };
let m = getModel(await loadProjectConfig(tmpRoot, DEFAULT_PROJECT_ID), ref);
expect(m?.max_tokens).toBe(4096);
expect(m?.context_window).toBe(32768);
// Explicitly re-pins the cap.
await addModel(tmpRoot, DEFAULT_PROJECT_ID, {
provider: "custom",
model_id: "small-window",
max_tokens: 2048,
});
m = getModel(await loadProjectConfig(tmpRoot, DEFAULT_PROJECT_ID), ref);
expect(m?.max_tokens).toBe(2048);
});
it("setVisionModel persists and validates the target", async () => {
await addModel(tmpRoot, DEFAULT_PROJECT_ID, {
provider: "custom",