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:
parent
f39f77d155
commit
6956ce0a19
@ -22,6 +22,7 @@ import { loadAllPluginComponents } from "../features/claude-code-plugin-loader";
|
|||||||
import { createBuiltinMcps } from "../mcp";
|
import { createBuiltinMcps } from "../mcp";
|
||||||
import type { OhMyOpenCodeConfig } from "../config";
|
import type { OhMyOpenCodeConfig } from "../config";
|
||||||
import { log } from "../shared";
|
import { log } from "../shared";
|
||||||
|
import { getOpenCodeConfigPaths } from "../shared/opencode-config-dir";
|
||||||
import { migrateAgentConfig } from "../shared/permission-compat";
|
import { migrateAgentConfig } from "../shared/permission-compat";
|
||||||
import { PROMETHEUS_SYSTEM_PROMPT, PROMETHEUS_PERMISSION } from "../agents/prometheus-prompt";
|
import { PROMETHEUS_SYSTEM_PROMPT, PROMETHEUS_PERMISSION } from "../agents/prometheus-prompt";
|
||||||
import { DEFAULT_CATEGORIES } from "../tools/delegate-task/constants";
|
import { DEFAULT_CATEGORIES } from "../tools/delegate-task/constants";
|
||||||
@ -100,9 +101,10 @@ export function createConfigHandler(deps: ConfigHandlerDeps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(config.model as string | undefined)?.trim()) {
|
if (!(config.model as string | undefined)?.trim()) {
|
||||||
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null })
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'oh-my-opencode requires a default model.\n\n' +
|
'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' +
|
' "model": "anthropic/claude-sonnet-4-5"\n\n' +
|
||||||
'(Replace with your preferred provider/model)'
|
'(Replace with your preferred provider/model)'
|
||||||
)
|
)
|
||||||
|
|||||||
@ -125,7 +125,7 @@ describe("sisyphus-task", () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// #then returns descriptive error message
|
// #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 = {
|
const mockClient = {
|
||||||
app: { agents: async () => ({ data: [] }) },
|
app: { agents: async () => ({ data: [] }) },
|
||||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||||
session: {
|
session: {
|
||||||
create: async () => ({ data: { id: "test-session" } }),
|
create: async () => ({ data: { id: "test-session" } }),
|
||||||
prompt: async () => ({ data: {} }),
|
prompt: async () => ({ data: {} }),
|
||||||
@ -363,7 +363,7 @@ describe("sisyphus-task", () => {
|
|||||||
const mockManager = { launch: async () => ({}) }
|
const mockManager = { launch: async () => ({}) }
|
||||||
const mockClient = {
|
const mockClient = {
|
||||||
app: { agents: async () => ({ data: [] }) },
|
app: { agents: async () => ({ data: [] }) },
|
||||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||||
session: {
|
session: {
|
||||||
create: async () => ({ data: { id: "test-session" } }),
|
create: async () => ({ data: { id: "test-session" } }),
|
||||||
prompt: async () => ({ data: {} }),
|
prompt: async () => ({ data: {} }),
|
||||||
@ -406,7 +406,7 @@ describe("sisyphus-task", () => {
|
|||||||
const mockManager = { launch: async () => ({}) }
|
const mockManager = { launch: async () => ({}) }
|
||||||
const mockClient = {
|
const mockClient = {
|
||||||
app: { agents: async () => ({ data: [] }) },
|
app: { agents: async () => ({ data: [] }) },
|
||||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||||
session: {
|
session: {
|
||||||
create: async () => ({ data: { id: "test-session" } }),
|
create: async () => ({ data: { id: "test-session" } }),
|
||||||
prompt: async () => ({ data: {} }),
|
prompt: async () => ({ data: {} }),
|
||||||
@ -453,7 +453,7 @@ describe("sisyphus-task", () => {
|
|||||||
const mockManager = { launch: async () => ({}) }
|
const mockManager = { launch: async () => ({}) }
|
||||||
const mockClient = {
|
const mockClient = {
|
||||||
app: { agents: async () => ({ data: [] }) },
|
app: { agents: async () => ({ data: [] }) },
|
||||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||||
session: {
|
session: {
|
||||||
get: async () => ({ data: { directory: "/project" } }),
|
get: async () => ({ data: { directory: "/project" } }),
|
||||||
create: async () => ({ data: { id: "test-session" } }),
|
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: {
|
app: {
|
||||||
agents: async () => ({ data: [] }),
|
agents: async () => ({ data: [] }),
|
||||||
},
|
},
|
||||||
@ -586,7 +586,7 @@ describe("sisyphus-task", () => {
|
|||||||
data: [],
|
data: [],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createDelegateTask({
|
const tool = createDelegateTask({
|
||||||
@ -638,7 +638,7 @@ describe("sisyphus-task", () => {
|
|||||||
messages: async () => ({ data: [] }),
|
messages: async () => ({ data: [] }),
|
||||||
status: async () => ({ data: {} }),
|
status: async () => ({ data: {} }),
|
||||||
},
|
},
|
||||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||||
app: {
|
app: {
|
||||||
agents: async () => ({ data: [{ name: "ultrabrain", mode: "subagent" }] }),
|
agents: async () => ({ data: [{ name: "ultrabrain", mode: "subagent" }] }),
|
||||||
},
|
},
|
||||||
@ -698,7 +698,7 @@ describe("sisyphus-task", () => {
|
|||||||
}),
|
}),
|
||||||
status: async () => ({ data: { "ses_sync_success": { type: "idle" } } }),
|
status: async () => ({ data: { "ses_sync_success": { type: "idle" } } }),
|
||||||
},
|
},
|
||||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||||
app: {
|
app: {
|
||||||
agents: async () => ({ data: [{ name: "ultrabrain", mode: "subagent" }] }),
|
agents: async () => ({ data: [{ name: "ultrabrain", mode: "subagent" }] }),
|
||||||
},
|
},
|
||||||
@ -751,7 +751,7 @@ describe("sisyphus-task", () => {
|
|||||||
messages: async () => ({ data: [] }),
|
messages: async () => ({ data: [] }),
|
||||||
status: async () => ({ data: {} }),
|
status: async () => ({ data: {} }),
|
||||||
},
|
},
|
||||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||||
app: {
|
app: {
|
||||||
agents: async () => ({ data: [{ name: "ultrabrain", mode: "subagent" }] }),
|
agents: async () => ({ data: [{ name: "ultrabrain", mode: "subagent" }] }),
|
||||||
},
|
},
|
||||||
@ -805,7 +805,7 @@ describe("sisyphus-task", () => {
|
|||||||
}),
|
}),
|
||||||
status: async () => ({ data: {} }),
|
status: async () => ({ data: {} }),
|
||||||
},
|
},
|
||||||
config: { get: async () => ({ model: SYSTEM_DEFAULT_MODEL }) },
|
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||||
app: { agents: async () => ({ data: [] }) },
|
app: { agents: async () => ({ data: [] }) },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import { discoverSkills } from "../../features/opencode-skill-loader"
|
|||||||
import { getTaskToastManager } from "../../features/task-toast-manager"
|
import { getTaskToastManager } from "../../features/task-toast-manager"
|
||||||
import type { ModelFallbackInfo } from "../../features/task-toast-manager/types"
|
import type { ModelFallbackInfo } from "../../features/task-toast-manager/types"
|
||||||
import { subagentSessions, getSessionAgent } from "../../features/claude-code-session-state"
|
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"]
|
type OpencodeClient = PluginInput["client"]
|
||||||
|
|
||||||
@ -415,7 +415,7 @@ ${textContent || "(No text output)"}`
|
|||||||
let systemDefaultModel: string | undefined
|
let systemDefaultModel: string | undefined
|
||||||
try {
|
try {
|
||||||
const openCodeConfig = await client.config.get()
|
const openCodeConfig = await client.config.get()
|
||||||
systemDefaultModel = (openCodeConfig as { model?: string })?.model
|
systemDefaultModel = (openCodeConfig as { data?: { model?: string } })?.data?.model
|
||||||
} catch {
|
} catch {
|
||||||
// Config fetch failed, proceed without system default
|
// Config fetch failed, proceed without system default
|
||||||
systemDefaultModel = undefined
|
systemDefaultModel = undefined
|
||||||
@ -434,7 +434,13 @@ ${textContent || "(No text output)"}`
|
|||||||
if (args.category) {
|
if (args.category) {
|
||||||
// Guard: require system default model for category delegation
|
// Guard: require system default model for category delegation
|
||||||
if (!systemDefaultModel) {
|
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, {
|
const resolved = resolveCategoryConfig(args.category, {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user