fix(agents): project thinking catalog compat

This commit is contained in:
Vincent Koc
2026-06-11 21:03:36 +09:00
parent 9a6c71a47d
commit 68ec783e74
2 changed files with 64 additions and 11 deletions
+19 -3
View File
@@ -339,7 +339,7 @@ describe("createAgentSession thinking level defaults", () => {
provider: "ollama",
reasoning: true,
params: { canonicalModelId: "qwen3:8b" },
compat: { thinkingFormat: "ollama" },
compat: { thinkingFormat: "qwen" },
} satisfies Model;
const { session } = await createAgentSession({
model: ollamaModel,
@@ -353,7 +353,16 @@ describe("createAgentSession thinking level defaults", () => {
expect(thinkingMocks.resolveThinkingDefaultForModel).toHaveBeenCalledWith({
provider: "ollama",
model: testModel.id,
catalog: [ollamaModel],
catalog: [
{
provider: "ollama",
id: testModel.id,
api: ollamaModel.api,
reasoning: true,
params: { canonicalModelId: "qwen3:8b" },
compat: { thinkingFormat: "qwen" },
},
],
});
});
@@ -393,7 +402,14 @@ describe("createAgentSession thinking level defaults", () => {
expect(thinkingMocks.resolveThinkingDefaultForModel).toHaveBeenCalledWith({
provider: "ollama",
model: testModel.id,
catalog: [customOllamaModel],
catalog: [
{
provider: "ollama",
id: testModel.id,
api: "ollama",
reasoning: true,
},
],
});
});
+45 -8
View File
@@ -4,7 +4,10 @@
* Selects models, wires built-in/custom tools, loads resources, and creates AgentSession instances.
*/
import { join } from "node:path";
import { resolveThinkingDefaultForModel } from "../../auto-reply/thinking.js";
import {
resolveThinkingDefaultForModel,
type ThinkingCatalogEntry,
} from "../../auto-reply/thinking.js";
import { clampThinkingLevel } from "../../llm/model-utils.js";
import { streamSimple } from "../../llm/stream.js";
import type { Message, Model } from "../../llm/types.js";
@@ -42,6 +45,28 @@ import {
withFileMutationQueue,
} from "./tools/index.js";
type ThinkingCatalogCompat = NonNullable<ThinkingCatalogEntry["compat"]>;
function projectThinkingCatalogCompat(compat: Model["compat"]) {
if (!compat || typeof compat !== "object") {
return undefined;
}
const record = compat as Record<string, unknown>;
const projected: ThinkingCatalogCompat = {};
if (typeof record.thinkingFormat === "string") {
projected.thinkingFormat = record.thinkingFormat;
}
if (record.supportedReasoningEfforts === null) {
projected.supportedReasoningEfforts = null;
} else if (
Array.isArray(record.supportedReasoningEfforts) &&
record.supportedReasoningEfforts.every((effort) => typeof effort === "string")
) {
projected.supportedReasoningEfforts = record.supportedReasoningEfforts;
}
return Object.keys(projected).length > 0 ? projected : undefined;
}
export interface CreateAgentSessionOptions {
/** Working directory for project-local discovery. Default: process.cwd() */
cwd?: string;
@@ -272,13 +297,25 @@ export async function createAgentSession(
// Use "off" when a provider explicitly opts out of thinking (e.g. Ollama). Non-off
// provider defaults (high, low, adaptive) fall back to DEFAULT_THINKING_LEVEL to avoid
// silent cost changes for DeepSeek, OpenRouter, xAI, and other providers.
const resolvedProviderDefault = model
? resolveThinkingDefaultForModel({
provider: model.api === "ollama" ? "ollama" : model.provider,
model: model.id,
catalog: [model],
})
: undefined;
const modelThinkingProvider = model?.api === "ollama" ? "ollama" : model?.provider;
const modelThinkingCompat = model ? projectThinkingCatalogCompat(model.compat) : undefined;
const resolvedProviderDefault =
model && modelThinkingProvider
? resolveThinkingDefaultForModel({
provider: modelThinkingProvider,
model: model.id,
catalog: [
{
provider: modelThinkingProvider,
id: model.id,
api: model.api,
reasoning: model.reasoning,
...(model.params ? { params: model.params } : {}),
...(modelThinkingCompat ? { compat: modelThinkingCompat } : {}),
},
],
})
: undefined;
const modelThinkingDefault: ThinkingLevel =
resolvedProviderDefault === "off" ? "off" : DEFAULT_THINKING_LEVEL;