Files
oh-my-opencode/src/shared/agent-tool-restrictions.ts
T
ismeth c75ae6bffd fix(athena): write council prompt to .sisyphus/tmp/, switch to allow-list permissions
Council members now use an allow-list (read, grep, glob, lsp_*, ast_grep_search)
instead of a deny-list. Prompt file moved from /tmp/ to .sisyphus/tmp/ so no
external_directory permission is needed. COUNCIL_MEMBER_PROMPT is included in
the temp file for self-contained council member instructions.
2026-04-15 16:39:28 +09:00

93 lines
2.5 KiB
TypeScript

import { stripInvisibleAgentCharacters } from "./agent-display-names"
/**
* Agent tool restrictions for session.prompt calls.
* OpenCode SDK's session.prompt `tools` parameter expects boolean values.
* true = tool allowed, false = tool denied.
*/
import { COUNCIL_MEMBER_KEY_PREFIX } from "../agents/builtin-agents/council-member-agents"
const EXPLORATION_AGENT_DENYLIST: Record<string, boolean> = {
write: false,
edit: false,
task: false,
call_omo_agent: false,
}
const AGENT_RESTRICTIONS: Record<string, Record<string, boolean>> = {
explore: EXPLORATION_AGENT_DENYLIST,
librarian: EXPLORATION_AGENT_DENYLIST,
oracle: {
write: false,
edit: false,
task: false,
call_omo_agent: false,
},
metis: {
write: false,
edit: false,
task: false,
},
momus: {
write: false,
edit: false,
task: false,
},
"multimodal-looker": {
read: true,
},
"sisyphus-junior": {
task: false,
},
athena: {
write: false,
edit: false,
call_omo_agent: false,
},
// NOTE: Athena/council tool restrictions are also defined in:
// - src/agents/athena/agent.ts (AgentConfig permission format)
// - src/agents/athena/council-member-agent.ts (AgentConfig permission format — allow-list)
// - src/plugin-handlers/tool-config-handler.ts (allow/deny string format)
// Keep all three in sync when modifying.
// Council members use an allow-list: only read-only analysis tools are permitted.
// Prompt file lives in .sisyphus/tmp/ (inside project) so no external_directory needed.
"council-member": {
"*": false,
read: true,
grep: true,
glob: true,
lsp_goto_definition: true,
lsp_find_references: true,
lsp_symbols: true,
lsp_diagnostics: true,
ast_grep_search: true,
},
}
export function getAgentToolRestrictions(agentName: string): Record<string, boolean> {
// Custom/unknown agents get no restrictions (empty object), matching Claude Code's
// trust model where project-registered agents retain full tool access including bash.
const stripped = stripInvisibleAgentCharacters(agentName)
if (stripped.startsWith(COUNCIL_MEMBER_KEY_PREFIX)) {
return AGENT_RESTRICTIONS["council-member"] ?? {}
}
return AGENT_RESTRICTIONS[stripped]
?? Object.entries(AGENT_RESTRICTIONS).find(([key]) => key.toLowerCase() === stripped.toLowerCase())?.[1]
?? {}
}
export function hasAgentToolRestrictions(agentName: string): boolean {
const restrictions = getAgentToolRestrictions(agentName)
return Object.keys(restrictions).length > 0
}