From c4deb6bc5d3e4c5b05a7072fdc1d912ca1eaf096 Mon Sep 17 00:00:00 2001 From: ismeth Date: Fri, 20 Feb 2026 14:26:23 +0100 Subject: [PATCH] refactor(athena): extract applyModelThinkingConfig shared utility --- src/agents/athena/agent.ts | 8 +-- src/agents/athena/council-member-agent.ts | 8 +-- .../athena/model-thinking-config.test.ts | 55 +++++++++++++++++++ src/agents/athena/model-thinking-config.ts | 17 ++++++ 4 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 src/agents/athena/model-thinking-config.test.ts create mode 100644 src/agents/athena/model-thinking-config.ts diff --git a/src/agents/athena/agent.ts b/src/agents/athena/agent.ts index 83bf7a5b..d850e003 100644 --- a/src/agents/athena/agent.ts +++ b/src/agents/athena/agent.ts @@ -1,7 +1,7 @@ import type { AgentConfig } from "@opencode-ai/sdk" import type { AgentMode, AgentPromptMetadata } from "../types" -import { isGptModel } from "../types" import { createAgentToolRestrictions, type PermissionValue } from "../../shared/permission-compat" +import { applyModelThinkingConfig } from "./model-thinking-config" const MODE: AgentMode = "primary" @@ -227,10 +227,6 @@ export function createAthenaAgent(model: string): AgentConfig { color: "#1F8EFA", } - if (isGptModel(model)) { - return { ...base, reasoningEffort: "medium" } - } - - return { ...base, thinking: { type: "enabled", budgetTokens: 32000 } } + return applyModelThinkingConfig(base, model) } createAthenaAgent.mode = MODE diff --git a/src/agents/athena/council-member-agent.ts b/src/agents/athena/council-member-agent.ts index 10fa96fe..49ab84b2 100644 --- a/src/agents/athena/council-member-agent.ts +++ b/src/agents/athena/council-member-agent.ts @@ -1,7 +1,7 @@ import type { AgentConfig } from "@opencode-ai/sdk" import type { AgentMode } from "../types" -import { isGptModel } from "../types" import { createAgentToolRestrictions } from "../../shared/permission-compat" +import { applyModelThinkingConfig } from "./model-thinking-config" const MODE: AgentMode = "subagent" @@ -43,10 +43,6 @@ export function createCouncilMemberAgent(model: string): AgentConfig { ...restrictions, } - if (isGptModel(model)) { - return { ...base, reasoningEffort: "medium" } - } - - return { ...base, thinking: { type: "enabled", budgetTokens: 32000 } } + return applyModelThinkingConfig(base, model) } createCouncilMemberAgent.mode = MODE diff --git a/src/agents/athena/model-thinking-config.test.ts b/src/agents/athena/model-thinking-config.test.ts new file mode 100644 index 00000000..f930f837 --- /dev/null +++ b/src/agents/athena/model-thinking-config.test.ts @@ -0,0 +1,55 @@ +import { describe, expect, it } from "bun:test" +import type { AgentConfig } from "@opencode-ai/sdk" +import { applyModelThinkingConfig } from "./model-thinking-config" + +const BASE_CONFIG: AgentConfig = { + name: "test-agent", + description: "test", + model: "anthropic/claude-opus-4-6", + temperature: 0.1, +} + +describe("applyModelThinkingConfig", () => { + describe("given a GPT model", () => { + it("returns reasoningEffort medium", () => { + const result = applyModelThinkingConfig(BASE_CONFIG, "gpt-5.2") + expect(result).toEqual({ ...BASE_CONFIG, reasoningEffort: "medium" }) + }) + + it("returns reasoningEffort medium for openai-prefixed model", () => { + const result = applyModelThinkingConfig(BASE_CONFIG, "openai/gpt-5.2") + expect(result).toEqual({ ...BASE_CONFIG, reasoningEffort: "medium" }) + }) + }) + + describe("given an Anthropic model", () => { + it("returns thinking config with budgetTokens 32000", () => { + const result = applyModelThinkingConfig(BASE_CONFIG, "anthropic/claude-opus-4-6") + expect(result).toEqual({ + ...BASE_CONFIG, + thinking: { type: "enabled", budgetTokens: 32000 }, + }) + }) + }) + + describe("given a Google model", () => { + it("returns base config unchanged", () => { + const result = applyModelThinkingConfig(BASE_CONFIG, "google/gemini-3-pro") + expect(result).toBe(BASE_CONFIG) + }) + }) + + describe("given a Kimi model", () => { + it("returns base config unchanged", () => { + const result = applyModelThinkingConfig(BASE_CONFIG, "kimi/kimi-k2.5") + expect(result).toBe(BASE_CONFIG) + }) + }) + + describe("given a model with no provider prefix", () => { + it("returns base config unchanged for non-GPT model", () => { + const result = applyModelThinkingConfig(BASE_CONFIG, "gemini-3-pro") + expect(result).toBe(BASE_CONFIG) + }) + }) +}) diff --git a/src/agents/athena/model-thinking-config.ts b/src/agents/athena/model-thinking-config.ts new file mode 100644 index 00000000..a86c084f --- /dev/null +++ b/src/agents/athena/model-thinking-config.ts @@ -0,0 +1,17 @@ +import type { AgentConfig } from "@opencode-ai/sdk" +import { isGptModel } from "../types" + +export function applyModelThinkingConfig(base: AgentConfig, model: string): AgentConfig { + if (isGptModel(model)) { + return { ...base, reasoningEffort: "medium" } + } + + const slashIndex = model.indexOf("/") + const provider = slashIndex > 0 ? model.substring(0, slashIndex).toLowerCase() : "" + + if (provider === "anthropic") { + return { ...base, thinking: { type: "enabled", budgetTokens: 32000 } } + } + + return base +}