Agent profiles
June 4, 2026 · View on GitHub
An agent profile is a named, reusable persona: a bundle of system prompt,
model, and tool policy you can switch to at runtime. Where a prompt
(/prompt) only changes the system prompt + tool restrictions, an agent profile
also routes the loop to a different model — so you can keep the right
model-for-the-job one keystroke away (a cheap fast model for review, a stronger
one for hard implementation) without editing config.
The feature is fully opt-in: with no profiles defined, dirge behaves exactly
as before. Defining a profile changes nothing until you /agent <name> into it.
Agent profiles drive the main loop's active persona. They are separate from — and do not change — the built-in role routing (critic / review / escalation / summarization / subagent), which is still configured via the
*_providerkeys inconfig.json./agentsshows both side by side.
Defining profiles
Profiles come from three sources, layered so a more specific one overrides a more general one of the same name:
| Precedence | Source | Location |
|---|---|---|
| highest | project file | .dirge/agents/<name>.md |
| middle | global file | ~/.config/dirge/agents/<name>.md |
| lowest | config | config.json "agents": { "<name>": { … } } |
File form (.dirge/agents/<name>.md)
The filename stem is the profile name. The file is markdown with optional YAML-ish frontmatter (the same tiny format as prompts/skills — no nested objects); the body is the system prompt.
---
model: haiku
deny_tools: [bash, write, edit, apply_patch]
reasoning: high
temperature: 0.2
description: read-only reviewer on a cheap fast model
---
You are a meticulous code reviewer. Read the diff and the surrounding code,
then report concrete findings ordered by severity. Do not modify files.
All frontmatter keys are optional:
| Key | Meaning |
|---|---|
model | A providers alias or a model name. Resolved to a model string for the current client (see Model routing below). Omit to keep the current model. |
deny_tools | Tools to deny while this profile is active (e.g. [bash, write, edit, apply_patch]). |
allow_tools | The complement: deny every built-in not listed. deny_tools wins if both are given. |
reasoning | Reasoning-effort hint (low / medium / high). |
temperature | Sampling temperature. |
description | One-line summary shown in /agents. |
A frontmatter-less file is treated as a body-only profile (just a system prompt).
Config form (config.json)
The same shape as a JSON object, for profiles you'd rather keep in config:
{
"agents": {
"reviewer": {
"model": "haiku",
"deny_tools": ["bash", "write", "edit", "apply_patch"],
"description": "read-only reviewer on a cheap fast model"
},
"architect": {
"model": "opus",
"prompt": "You are a senior architect. Think in trade-offs; propose a plan before code."
}
}
}
Using profiles
| Command | Effect |
|---|---|
/agents (or /agent) | List defined profiles (active one marked *) and the built-in role routing. |
/agent <name> | Activate a profile: apply its system prompt, tool policy (at the permission layer), and model (rebuilds the agent). |
/agent off | Deactivate the profile and restore the underlying state: the active /prompt's prompt + denies come back, and the model is restored to whatever it was before the profile was activated. |
The /prompt and /agent selections are independent composing layers, not
one shared slot. Activating a profile no longer wipes the active prompt's
restrictions, and deactivating it no longer wipes the prompt:
- Prompt — if the profile defines a body, it overrides the active system
prompt while the profile is on; otherwise your
/promptbody is kept. The "mode" (which drives plan/review reminders) stays owned by/prompt. - Tools — the profile's
deny_tools/allow_toolsare enforced at the permission layer (the same path that backs per-prompt restrictions), not just as prose. They compose with the active prompt'sdeny_toolsas a union: a profile can only add restrictions to a prompt's, never weaken them (so/prompt review+ a permissive profile keepsreview's denies). To drop a prompt's restrictions, switch the prompt (/prompt default), not the agent.allow_toolsis best-effort over built-in tools; for a hard cap preferdeny_tools. - Revert —
/agent offpops only the profile layer: the/promptlayer's body + denies and the pre-profile model are restored in one step. - Model — see below.
Model routing
A profile's model is resolved to a model string for the current client:
if it names a providers alias that carries a model, that model is used;
otherwise the value is used verbatim as the model name. This covers the common
case (e.g. everyone on one OpenRouter/Anthropic account switching between
models).
Cross-provider switching — a profile model that points at a different backend (its own
provider_type/base_url/ API key) — is not yet wired for/agent; only the model string is taken. The built-in roles (critic/escalation) already build full per-role clients and are unaffected.
Running a subagent under a profile
The task tool — which spawns a one-shot subagent for an independent subtask —
can run that subagent under a profile. When any profiles are defined, the tool
advertises an agent parameter (an enum of your profile names); the model calls
it like:
task(prompt="Review the auth changes for security issues", agent="reviewer")
The subagent then runs on the profile's model and system prompt, so you
can fan work out to specialized personas (a cheap fast reviewer, a stronger
planner) from a single session. Omitting agent uses the default subagent,
exactly as before — the parameter only appears when profiles exist, and naming a
profile that isn't defined is a hard error (no silent fallback). The default
subagent (no agent=) runs on subagent_provider's model when that role key is
configured, otherwise the main model.
Profiles are resolved into subagent routes once at startup. Two current limits:
subagents are tool-less (a profile's deny_tools/allow_tools doesn't
apply to a subagent, which has no tools to begin with), and the profile's
reasoning/temperature aren't applied on the subagent path — only the model
and system prompt are. Routing /plan phases to named profiles, and
cross-provider client switching, remain follow-ups.
Relationship to the built-in critic and roles
Defining profiles never disables or changes the built-in critic or any role
routing. The critic is still opt-in via critic_provider; review / escalation /
summarization / subagent still resolve through their *_provider keys.
/agents surfaces both the user profiles and the configured role routing so the
whole picture is visible in one place.