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/personalitypicker 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--modeland/model. Required. Switching to the personality switches the provider and model exactly as/modelwould; an@effortsuffix pins effort, while a bareprovider/modelleaves your current effort in place.prompt-- a prompt fragment establishing the personality's identity, appended to the base prompt. Optional.skip_default_prompt-- whentrue, thepromptreplaces the base prompt rather than following it. Optional, defaultfalse.description-- text shown beside the name in the/personalitypicker. 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.PlanorExecute). 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/personalitypicker. Optional.tool_options-- per-tool options keyed by tool name, used by thespawntool 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.