fix: correct config.data.model access pattern and use dynamic config paths
- Fixed delegate-task/tools.ts to access openCodeConfig.data.model instead of openCodeConfig.model
- Updated error messages to use getOpenCodeConfigPaths() for cross-platform paths
- Fixed 12 test mocks to use correct { data: { model: ... } } structure
- Fixes delegation failing with 'requires a default model' even when model is configured
This commit is contained in:
@@ -22,6 +22,7 @@ import { loadAllPluginComponents } from "../features/claude-code-plugin-loader";
|
||||
import { createBuiltinMcps } from "../mcp";
|
||||
import type { OhMyOpenCodeConfig } from "../config";
|
||||
import { log } from "../shared";
|
||||
import { getOpenCodeConfigPaths } from "../shared/opencode-config-dir";
|
||||
import { migrateAgentConfig } from "../shared/permission-compat";
|
||||
import { PROMETHEUS_SYSTEM_PROMPT, PROMETHEUS_PERMISSION } from "../agents/prometheus-prompt";
|
||||
import { DEFAULT_CATEGORIES } from "../tools/delegate-task/constants";
|
||||
@@ -100,9 +101,10 @@ export function createConfigHandler(deps: ConfigHandlerDeps) {
|
||||
}
|
||||
|
||||
if (!(config.model as string | undefined)?.trim()) {
|
||||
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null })
|
||||
throw new Error(
|
||||
'oh-my-opencode requires a default model.\n\n' +
|
||||
'Add this to ~/.config/opencode/opencode.jsonc:\n\n' +
|
||||
`Add this to ${paths.configJsonc}:\n\n` +
|
||||
' "model": "anthropic/claude-sonnet-4-5"\n\n' +
|
||||
'(Replace with your preferred provider/model)'
|
||||
)
|
||||
|
||||
@@ -125,7 +125,7 @@ describe("sisyphus-task", () => {
|
||||
)
|
||||
|
||||
// #then returns descriptive error message
|
||||
expect(result).toContain("No default model configured")
|
||||
expect(result).toContain("oh-my-opencode requires a default model")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -304,7 +304,7 @@ describe("sisyphus-task", () => {
|
||||
|
||||
const mockClient = {
|
||||
app: { agents: async () => ({ data: [] }) },
|
||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
session: {
|
||||
create: async () => ({ data: { id: "test-session" } }),
|
||||
prompt: async () => ({ data: {} }),
|
||||
@@ -363,7 +363,7 @@ describe("sisyphus-task", () => {
|
||||
const mockManager = { launch: async () => ({}) }
|
||||
const mockClient = {
|
||||
app: { agents: async () => ({ data: [] }) },
|
||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
session: {
|
||||
create: async () => ({ data: { id: "test-session" } }),
|
||||
prompt: async () => ({ data: {} }),
|
||||
@@ -406,7 +406,7 @@ describe("sisyphus-task", () => {
|
||||
const mockManager = { launch: async () => ({}) }
|
||||
const mockClient = {
|
||||
app: { agents: async () => ({ data: [] }) },
|
||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
session: {
|
||||
create: async () => ({ data: { id: "test-session" } }),
|
||||
prompt: async () => ({ data: {} }),
|
||||
@@ -453,7 +453,7 @@ describe("sisyphus-task", () => {
|
||||
const mockManager = { launch: async () => ({}) }
|
||||
const mockClient = {
|
||||
app: { agents: async () => ({ data: [] }) },
|
||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
session: {
|
||||
get: async () => ({ data: { directory: "/project" } }),
|
||||
create: async () => ({ data: { id: "test-session" } }),
|
||||
@@ -528,7 +528,7 @@ describe("sisyphus-task", () => {
|
||||
],
|
||||
}),
|
||||
},
|
||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
app: {
|
||||
agents: async () => ({ data: [] }),
|
||||
},
|
||||
@@ -586,7 +586,7 @@ describe("sisyphus-task", () => {
|
||||
data: [],
|
||||
}),
|
||||
},
|
||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
}
|
||||
|
||||
const tool = createDelegateTask({
|
||||
@@ -638,7 +638,7 @@ describe("sisyphus-task", () => {
|
||||
messages: async () => ({ data: [] }),
|
||||
status: async () => ({ data: {} }),
|
||||
},
|
||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
app: {
|
||||
agents: async () => ({ data: [{ name: "ultrabrain", mode: "subagent" }] }),
|
||||
},
|
||||
@@ -698,7 +698,7 @@ describe("sisyphus-task", () => {
|
||||
}),
|
||||
status: async () => ({ data: { "ses_sync_success": { type: "idle" } } }),
|
||||
},
|
||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
app: {
|
||||
agents: async () => ({ data: [{ name: "ultrabrain", mode: "subagent" }] }),
|
||||
},
|
||||
@@ -751,7 +751,7 @@ describe("sisyphus-task", () => {
|
||||
messages: async () => ({ data: [] }),
|
||||
status: async () => ({ data: {} }),
|
||||
},
|
||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
app: {
|
||||
agents: async () => ({ data: [{ name: "ultrabrain", mode: "subagent" }] }),
|
||||
},
|
||||
@@ -805,7 +805,7 @@ describe("sisyphus-task", () => {
|
||||
}),
|
||||
status: async () => ({ data: {} }),
|
||||
},
|
||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
app: { agents: async () => ({ data: [] }) },
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { discoverSkills } from "../../features/opencode-skill-loader"
|
||||
import { getTaskToastManager } from "../../features/task-toast-manager"
|
||||
import type { ModelFallbackInfo } from "../../features/task-toast-manager/types"
|
||||
import { subagentSessions, getSessionAgent } from "../../features/claude-code-session-state"
|
||||
import { log, getAgentToolRestrictions, resolveModel } from "../../shared"
|
||||
import { log, getAgentToolRestrictions, resolveModel, getOpenCodeConfigPaths } from "../../shared"
|
||||
|
||||
type OpencodeClient = PluginInput["client"]
|
||||
|
||||
@@ -415,7 +415,7 @@ ${textContent || "(No text output)"}`
|
||||
let systemDefaultModel: string | undefined
|
||||
try {
|
||||
const openCodeConfig = await client.config.get()
|
||||
systemDefaultModel = (openCodeConfig as { model?: string })?.model
|
||||
systemDefaultModel = (openCodeConfig as { data?: { model?: string } })?.data?.model
|
||||
} catch {
|
||||
// Config fetch failed, proceed without system default
|
||||
systemDefaultModel = undefined
|
||||
@@ -434,7 +434,13 @@ ${textContent || "(No text output)"}`
|
||||
if (args.category) {
|
||||
// Guard: require system default model for category delegation
|
||||
if (!systemDefaultModel) {
|
||||
return `No default model configured. Set a model in your OpenCode config (model field).`
|
||||
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null })
|
||||
return (
|
||||
'oh-my-opencode requires a default model.\n\n' +
|
||||
`Add this to ${paths.configJsonc}:\n\n` +
|
||||
' "model": "anthropic/claude-sonnet-4-5"\n\n' +
|
||||
'(Replace with your preferred provider/model)'
|
||||
)
|
||||
}
|
||||
|
||||
const resolved = resolveCategoryConfig(args.category, {
|
||||
|
||||
Reference in New Issue
Block a user