Files
oh-my-opencode/src/shared/agent-tool-restrictions.ts
T
ismeth 10e28417a3 feat(athena): add dedicated council-member agent for multi-model council
Replace oracle as the agent for council background tasks with a purpose-built

council-member agent. This avoids coupling to oracle's config/prompt and provides

proper read-only tool restrictions (deny write, edit, task, athena_council).

- New council-member-agent.ts with analysis-oriented system prompt

- Registered in agentSources (hidden from Sisyphus delegation table)

- Added to type system, Zod schemas, display names, tool restrictions

- Minimal model fallback (always overridden per council member at launch)

- Council orchestrator now launches members as council-member agent

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 15:56:20 +09:00

86 lines
2.1 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 { createAgentToolRestrictions } from "./permission-compat"
const EXPLORATION_AGENT_DENYLIST: Record<string, boolean> = {
write: false,
edit: false,
task: false,
call_omo_agent: false,
}
const ATHENA_RESTRICTIONS = permissionToToolBooleans(
createAgentToolRestrictions(["write", "edit", "athena_council"]).permission
)
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: ATHENA_RESTRICTIONS,
"council-member": {
write: false,
edit: false,
task: false,
call_omo_agent: false,
athena_council: false,
},
}
function permissionToToolBooleans(
permission: Record<string, "ask" | "allow" | "deny">
): Record<string, boolean> {
return Object.fromEntries(
Object.entries(permission).map(([tool, value]) => [tool, value === "allow"])
)
}
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)
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
}