Skip to content

Personalities, modes, and sub-agents

A personality is an agent prototype you name in your config: a model, a prompt that establishes who it is, and one or more modes that each expose a chosen set of tools. You switch the active personality mid-session, and a personality can delegate work to another by spawning it as a sub-agent.

Wallah always has a built-in default personality with the full tool set, so a config that defines none still runs. Anything you register through a discover_agents handler appears beside it. The handler runs when your config loads and again on every /reload, with an AgentRegistry to add personalities to:

agent.on('discover_agents', function(registry)
  registry:add {
    name = 'architect',
    description = 'Plans before coding.',
    model = 'anthropic/claude-opus-4-8',
    prompt = 'You are a software architect.',
    modes = {
      {
        name = 'Plan',
        description = 'Plans before coding.',
        prompt = 'You are in planning mode; read-only.',
        tools = { 'read', 'grep', 'find', 'list_dir' },
      },
      {
        name = 'Execute',
        tools = { 'read', 'write', 'edit', 'bash', 'grep', 'find', 'list_dir' },
      },
    },
  }
end)

That registers an architect personality with two modes. It shows up in the /personality picker, and switching to it activates its model and prompt and starts it in its first mode.

The fields on a personality:

  • name -- the name shown in the /personality picker and used to spawn it. Required and unique across the set.
  • model -- the model it activates on, in the same [provider/]model[@effort] syntax as --model and /model. Required. Switching to the personality switches the provider and model exactly as /model would; an @effort suffix pins effort, while a bare provider/model leaves your current effort in place.
  • prompt -- a prompt fragment establishing the personality's identity, appended to the base prompt. Optional.
  • skip_default_prompt -- when true, the prompt replaces the base prompt rather than following it. Optional, default false.
  • description -- text shown beside the name in the /personality picker. Optional.
  • spawn_description -- text advertised to a parent model deciding whether to delegate to this personality (see Spawning sub-agents). Optional.
  • modes -- the personality's modes, in declaration order. Required and non-empty; the first is the default on activation.

Modes

A mode is a tool-and-prompt profile within a personality. The same personality in Plan mode and Execute mode is the same model and identity with a different set of tools available; a read-only Plan mode is simply one whose tools list omits the mutating tools. Each mode has:

  • name -- the mode's name (e.g. Plan or Execute). Required.
  • tools -- the tool names this mode advertises and allows. Required. A tool not listed here is neither offered to the model nor runnable in this mode.
  • prompt -- a prompt fragment reinforcing the mode's behavior, appended after the personality's own. Optional.
  • description -- text shown beside the mode's name in the /personality picker. Optional.
  • tool_options -- per-tool options keyed by tool name, used by the spawn tool below. Optional.

Switching at runtime

/personality opens the picker; /personality <name> switches directly, and /personality <name>/<mode> starts in a named mode rather than the default first one. Once a personality is active, Shift+Tab cycles through its modes.

Spawning sub-agents

A mode can delegate work to another personality through the built-in spawn tool. It is offered to the model only when the mode lists spawn in its tools, and only for the personalities named in that mode's tool_options.spawn.personalities:

{
  name = 'Execute',
  tools = { 'read', 'write', 'edit', 'bash', 'spawn' },
  tool_options = { spawn = { personalities = { 'reviewer' } } },
},

With this, a model running the architect personality in Execute mode may spawn a reviewer sub-agent, and only a reviewer. The model picks the personality and writes the task; the sub-agent runs to completion and returns its result as the tool's output. The spawn_description you gave each spawnable personality is what the parent model reads when deciding which to delegate to.

Spawning is off by default: the built-in default personality does not list spawn, so a session that defines no personalities cannot spawn until a config opts in.

Launching a sub-agent from a slash command

The spawn tool lets the model delegate. To kick off a sub-agent yourself, without going through the model, a slash command can launch a detached one with ctx:spawn_subagent{ ... }. That runs headless alongside your interactive session and is tracked by /jobs; see defining your own slash commands.

Keeping personalities tidy

As with custom tools and custom commands, a personality is best kept in a self-contained module alongside your config (e.g. ~/.config/wallah/architect.lua) that you pull in with require('architect'), so it reads and reuses independently of the rest of your config.