fixes subagent thinking override

added by Pete a couple weeks ago but the config doesn't recognize it when you try to use it.
This commit is contained in:
KraFourZee 2026-01-28 22:43:32 -05:00
parent 109ac1c549
commit ceed611745
6 changed files with 99 additions and 1 deletions

View File

@ -30,6 +30,9 @@ Cost note: each sub-agent has its **own** context and token usage. For heavy or
tasks, set a cheaper model for sub-agents and keep your main agent on a higher-quality model.
You can configure this via `agents.defaults.subagents.model` or per-agent overrides.
Thinking level: sub-agents inherit the caller's thinking level by default. Override globally
via `agents.defaults.subagents.thinking` or per-spawn via the `thinking` tool param.
## Tool
Use `sessions_spawn`:
@ -102,7 +105,9 @@ Override via config:
agents: {
defaults: {
subagents: {
maxConcurrent: 1
maxConcurrent: 1,
model: "anthropic/claude-haiku-4",
thinking: "low"
}
}
},

View File

@ -195,4 +195,79 @@ describe("moltbot-tools: subagents", () => {
model: "minimax/MiniMax-M2.1",
});
});
it("sessions_spawn applies default subagent thinking from defaults config", async () => {
resetSubagentRegistryForTests();
callGatewayMock.mockReset();
configOverride = {
session: { mainKey: "main", scope: "per-sender" },
agents: { defaults: { subagents: { thinking: "medium" } } },
};
const calls: Array<{ method?: string; params?: unknown }> = [];
callGatewayMock.mockImplementation(async (opts: unknown) => {
const request = opts as { method?: string; params?: unknown };
calls.push(request);
if (request.method === "agent") {
return { runId: "run-default-thinking", status: "accepted" };
}
return {};
});
const tool = createMoltbotTools({
agentSessionKey: "agent:main:main",
agentChannel: "discord",
}).find((candidate) => candidate.name === "sessions_spawn");
if (!tool) throw new Error("missing sessions_spawn tool");
const result = await tool.execute("call-default-thinking", {
task: "do thing",
});
expect(result.details).toMatchObject({
status: "accepted",
});
const agentCall = calls.find((call) => call.method === "agent");
expect(agentCall?.params).toMatchObject({
thinking: "medium",
});
});
it("sessions_spawn tool param thinking overrides config default", async () => {
resetSubagentRegistryForTests();
callGatewayMock.mockReset();
configOverride = {
session: { mainKey: "main", scope: "per-sender" },
agents: { defaults: { subagents: { thinking: "low" } } },
};
const calls: Array<{ method?: string; params?: unknown }> = [];
callGatewayMock.mockImplementation(async (opts: unknown) => {
const request = opts as { method?: string; params?: unknown };
calls.push(request);
if (request.method === "agent") {
return { runId: "run-override-thinking", status: "accepted" };
}
return {};
});
const tool = createMoltbotTools({
agentSessionKey: "agent:main:main",
agentChannel: "discord",
}).find((candidate) => candidate.name === "sessions_spawn");
if (!tool) throw new Error("missing sessions_spawn tool");
const result = await tool.execute("call-override-thinking", {
task: "do thing",
thinking: "high",
});
expect(result.details).toMatchObject({
status: "accepted",
});
const agentCall = calls.find((call) => call.method === "agent");
expect(agentCall?.params).toMatchObject({
thinking: "high",
});
});
});

View File

@ -176,6 +176,10 @@ export function createSessionsSpawnTool(opts?: {
});
}
thinkingOverride = normalized;
} else {
// Fall back to config defaults if no explicit override
thinkingOverride =
targetAgentConfig?.subagents?.thinking ?? cfg.agents?.defaults?.subagents?.thinking;
}
if (resolvedModel) {
try {

View File

@ -204,6 +204,8 @@ export type AgentDefaultsConfig = {
archiveAfterMinutes?: number;
/** Default model selection for spawned sub-agents (string or {primary,fallbacks}). */
model?: string | { primary?: string; fallbacks?: string[] };
/** Default thinking level for spawned sub-agents. */
thinking?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
};
/** Optional sandbox settings for non-main sessions. */
sandbox?: {

View File

@ -433,6 +433,8 @@ export type ToolsConfig = {
subagents?: {
/** Default model selection for spawned sub-agents (string or {primary,fallbacks}). */
model?: string | { primary?: string; fallbacks?: string[] };
/** Default thinking level for spawned sub-agents. */
thinking?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
tools?: {
allow?: string[];
deny?: string[];

View File

@ -150,6 +150,16 @@ export const AgentDefaultsSchema = z
.strict(),
])
.optional(),
thinking: z
.union([
z.literal("off"),
z.literal("minimal"),
z.literal("low"),
z.literal("medium"),
z.literal("high"),
z.literal("xhigh"),
])
.optional(),
})
.strict()
.optional(),