fix: deny todowrite/todoread per-agent when task_system is enabled
When experimental.task_system is enabled, add todowrite: deny and todoread: deny to per-agent permissions for all primary agents (sisyphus, hephaestus, atlas, prometheus, sisyphus-junior). This ensures the model never sees these tools in its tool list, complementing the existing global tools config and runtime hook.
This commit is contained in:
parent
24a013b867
commit
e7f4f6dd13
@ -943,3 +943,108 @@ describe("config-handler plugin loading error boundary (#1559)", () => {
|
|||||||
expect(commands["test-cmd"]).toBeDefined()
|
expect(commands["test-cmd"]).toBeDefined()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("per-agent todowrite/todoread deny when task_system enabled", () => {
|
||||||
|
const PRIMARY_AGENTS = ["sisyphus", "hephaestus", "atlas", "prometheus", "sisyphus-junior"]
|
||||||
|
|
||||||
|
test("denies todowrite and todoread for primary agents when task_system is enabled", async () => {
|
||||||
|
//#given
|
||||||
|
spyOn(agents, "createBuiltinAgents" as any).mockResolvedValue({
|
||||||
|
sisyphus: { name: "sisyphus", prompt: "test", mode: "primary" },
|
||||||
|
hephaestus: { name: "hephaestus", prompt: "test", mode: "primary" },
|
||||||
|
atlas: { name: "atlas", prompt: "test", mode: "primary" },
|
||||||
|
prometheus: { name: "prometheus", prompt: "test", mode: "primary" },
|
||||||
|
"sisyphus-junior": { name: "sisyphus-junior", prompt: "test", mode: "subagent" },
|
||||||
|
oracle: { name: "oracle", prompt: "test", mode: "subagent" },
|
||||||
|
})
|
||||||
|
|
||||||
|
const pluginConfig: OhMyOpenCodeConfig = {
|
||||||
|
experimental: { task_system: true },
|
||||||
|
}
|
||||||
|
const config: Record<string, unknown> = {
|
||||||
|
model: "anthropic/claude-opus-4-6",
|
||||||
|
agent: {},
|
||||||
|
}
|
||||||
|
const handler = createConfigHandler({
|
||||||
|
ctx: { directory: "/tmp" },
|
||||||
|
pluginConfig,
|
||||||
|
modelCacheState: {
|
||||||
|
anthropicContext1MEnabled: false,
|
||||||
|
modelContextLimitsCache: new Map(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
//#when
|
||||||
|
await handler(config)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
const agentResult = config.agent as Record<string, { permission?: Record<string, unknown> }>
|
||||||
|
for (const agentName of PRIMARY_AGENTS) {
|
||||||
|
expect(agentResult[agentName]?.permission?.todowrite).toBe("deny")
|
||||||
|
expect(agentResult[agentName]?.permission?.todoread).toBe("deny")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test("does not deny todowrite/todoread when task_system is disabled", async () => {
|
||||||
|
//#given
|
||||||
|
spyOn(agents, "createBuiltinAgents" as any).mockResolvedValue({
|
||||||
|
sisyphus: { name: "sisyphus", prompt: "test", mode: "primary" },
|
||||||
|
hephaestus: { name: "hephaestus", prompt: "test", mode: "primary" },
|
||||||
|
})
|
||||||
|
|
||||||
|
const pluginConfig: OhMyOpenCodeConfig = {
|
||||||
|
experimental: { task_system: false },
|
||||||
|
}
|
||||||
|
const config: Record<string, unknown> = {
|
||||||
|
model: "anthropic/claude-opus-4-6",
|
||||||
|
agent: {},
|
||||||
|
}
|
||||||
|
const handler = createConfigHandler({
|
||||||
|
ctx: { directory: "/tmp" },
|
||||||
|
pluginConfig,
|
||||||
|
modelCacheState: {
|
||||||
|
anthropicContext1MEnabled: false,
|
||||||
|
modelContextLimitsCache: new Map(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
//#when
|
||||||
|
await handler(config)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
const agentResult = config.agent as Record<string, { permission?: Record<string, unknown> }>
|
||||||
|
expect(agentResult.sisyphus?.permission?.todowrite).toBeUndefined()
|
||||||
|
expect(agentResult.sisyphus?.permission?.todoread).toBeUndefined()
|
||||||
|
expect(agentResult.hephaestus?.permission?.todowrite).toBeUndefined()
|
||||||
|
expect(agentResult.hephaestus?.permission?.todoread).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("does not deny todowrite/todoread when task_system is undefined", async () => {
|
||||||
|
//#given
|
||||||
|
spyOn(agents, "createBuiltinAgents" as any).mockResolvedValue({
|
||||||
|
sisyphus: { name: "sisyphus", prompt: "test", mode: "primary" },
|
||||||
|
})
|
||||||
|
|
||||||
|
const pluginConfig: OhMyOpenCodeConfig = {}
|
||||||
|
const config: Record<string, unknown> = {
|
||||||
|
model: "anthropic/claude-opus-4-6",
|
||||||
|
agent: {},
|
||||||
|
}
|
||||||
|
const handler = createConfigHandler({
|
||||||
|
ctx: { directory: "/tmp" },
|
||||||
|
pluginConfig,
|
||||||
|
modelCacheState: {
|
||||||
|
anthropicContext1MEnabled: false,
|
||||||
|
modelContextLimitsCache: new Map(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
//#when
|
||||||
|
await handler(config)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
const agentResult = config.agent as Record<string, { permission?: Record<string, unknown> }>
|
||||||
|
expect(agentResult.sisyphus?.permission?.todowrite).toBeUndefined()
|
||||||
|
expect(agentResult.sisyphus?.permission?.todoread).toBeUndefined()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
@ -436,6 +436,11 @@ export function createConfigHandler(deps: ConfigHandlerDeps) {
|
|||||||
// In CLI run mode, deny Question tool for all agents (no TUI to answer questions)
|
// In CLI run mode, deny Question tool for all agents (no TUI to answer questions)
|
||||||
const isCliRunMode = process.env.OPENCODE_CLI_RUN_MODE === "true";
|
const isCliRunMode = process.env.OPENCODE_CLI_RUN_MODE === "true";
|
||||||
const questionPermission = isCliRunMode ? "deny" : "allow";
|
const questionPermission = isCliRunMode ? "deny" : "allow";
|
||||||
|
|
||||||
|
// When task system is enabled, deny todowrite/todoread per-agent so models never see them
|
||||||
|
const todoPermission = pluginConfig.experimental?.task_system
|
||||||
|
? { todowrite: "deny" as const, todoread: "deny" as const }
|
||||||
|
: {};
|
||||||
|
|
||||||
if (agentResult.librarian) {
|
if (agentResult.librarian) {
|
||||||
const agent = agentResult.librarian as AgentWithPermission;
|
const agent = agentResult.librarian as AgentWithPermission;
|
||||||
@ -447,23 +452,23 @@ export function createConfigHandler(deps: ConfigHandlerDeps) {
|
|||||||
}
|
}
|
||||||
if (agentResult["atlas"]) {
|
if (agentResult["atlas"]) {
|
||||||
const agent = agentResult["atlas"] as AgentWithPermission;
|
const agent = agentResult["atlas"] as AgentWithPermission;
|
||||||
agent.permission = { ...agent.permission, task: "allow", call_omo_agent: "deny", "task_*": "allow", teammate: "allow" };
|
agent.permission = { ...agent.permission, ...todoPermission, task: "allow", call_omo_agent: "deny", "task_*": "allow", teammate: "allow" };
|
||||||
}
|
}
|
||||||
if (agentResult.sisyphus) {
|
if (agentResult.sisyphus) {
|
||||||
const agent = agentResult.sisyphus as AgentWithPermission;
|
const agent = agentResult.sisyphus as AgentWithPermission;
|
||||||
agent.permission = { ...agent.permission, call_omo_agent: "deny", task: "allow", question: questionPermission, "task_*": "allow", teammate: "allow" };
|
agent.permission = { ...agent.permission, ...todoPermission, call_omo_agent: "deny", task: "allow", question: questionPermission, "task_*": "allow", teammate: "allow" };
|
||||||
}
|
}
|
||||||
if (agentResult.hephaestus) {
|
if (agentResult.hephaestus) {
|
||||||
const agent = agentResult.hephaestus as AgentWithPermission;
|
const agent = agentResult.hephaestus as AgentWithPermission;
|
||||||
agent.permission = { ...agent.permission, call_omo_agent: "deny", task: "allow", question: questionPermission };
|
agent.permission = { ...agent.permission, ...todoPermission, call_omo_agent: "deny", task: "allow", question: questionPermission };
|
||||||
}
|
}
|
||||||
if (agentResult["prometheus"]) {
|
if (agentResult["prometheus"]) {
|
||||||
const agent = agentResult["prometheus"] as AgentWithPermission;
|
const agent = agentResult["prometheus"] as AgentWithPermission;
|
||||||
agent.permission = { ...agent.permission, call_omo_agent: "deny", task: "allow", question: questionPermission, "task_*": "allow", teammate: "allow" };
|
agent.permission = { ...agent.permission, ...todoPermission, call_omo_agent: "deny", task: "allow", question: questionPermission, "task_*": "allow", teammate: "allow" };
|
||||||
}
|
}
|
||||||
if (agentResult["sisyphus-junior"]) {
|
if (agentResult["sisyphus-junior"]) {
|
||||||
const agent = agentResult["sisyphus-junior"] as AgentWithPermission;
|
const agent = agentResult["sisyphus-junior"] as AgentWithPermission;
|
||||||
agent.permission = { ...agent.permission, task: "allow", "task_*": "allow", teammate: "allow" };
|
agent.permission = { ...agent.permission, ...todoPermission, task: "allow", "task_*": "allow", teammate: "allow" };
|
||||||
}
|
}
|
||||||
|
|
||||||
config.permission = {
|
config.permission = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user