Skip to main content
Version: latest

agent profiles

An agent profile (config.AgentProfile in config/profile.go) defines how kasmos launches an AI agent for a specific role. Profiles are configured in config.toml under [agents.<role>] and mapped to lifecycle phases via [phases].

fields

fieldtypedefaultdescription
enabledboolfalsethe role is active and can be dispatched; disabled profiles fall back to default_program
programstringexecutable name or path (e.g. claude, opencode, /usr/local/bin/codex)
flags[]string[]extra CLI flags appended after the prompt argument
modelstringmodel identifier passed to the agent (e.g. gpt-5.5, claude-sonnet-4-6)
temperaturefloat?sampling temperature, if the agent supports it
effortstringeffort level (e.g. low, medium, high), if the agent supports it
tierstring""Codex SDK only: session speed tier (accepts "fast", "flex", or "default"). Claude SDK and tmux sessions ignore this field.
execution_modestring"tmux"how the agent process is launched: "tmux" or "sdk"
permission_defaultstring""tri-state permission default: "prompt" forces an interactive permission overlay, "bypass" launches with the harness bypass flag, "" / "inherit" preserves the spawn-source default (daemon: bypass; local TUI: prompt).

execution_mode

  • tmux (default): kasmos creates a new tmux window, runs the agent inside it, and monitors the window for completion. This mode lets you watch the agent in real time.
  • sdk: kasmos drives the agent via its app-server JSON-RPC protocol (claude and codex only). For any other program, kasmos silently falls back to tmux at runtime. Use this for unattended wave execution with claude or codex.
  • headless: legacy alias for "sdk" — accepted but "sdk" is preferred in new configs.

The mode is normalized by config.NormalizeExecutionMode(): any unrecognized value (including empty string) falls back to "tmux".

tier

Sets the Codex SDK speed tier for any session spawned into this role by orchestration.

Accepted values

valueresult after normalization
"" (unset)"" — no tier forwarded
"fast""fast"
"flex""flex"
"default""flex" (normalized to "flex")
anything else (e.g. "priority")"" — unrecognized, ignored

Normalization is handled by config.NormalizeTier in config/profile.go. The match is case-insensitive, leading/trailing whitespace is trimmed, "default" is mapped to "flex", and any other unrecognized string collapses to "".

Gating — the normalized tier value is only forwarded when both conditions hold at session-start time:

  1. The resolved execution_mode is "sdk" (after session.ResolveExecutionMode has applied the program-compatibility downgrade check).
  2. The program is codex. The Claude SDK transport (session/sdk/claude_transport.go) silently ignores the field even when execution_mode = "sdk".

Per-spawn override — the S execution-mode picker offers an sdk-fast choice that overrides the profile default for that one spawn only. The override is stored as SDKSpeedTier = "fast" on the instance record; it is not written back to config.toml. See speed tier: profile default + per-spawn override for full details.

Observed behavior — when a tier is in effect:

  • The info pane shows a speed tier: fast row (ui/info_pane.go).
  • The spawn audit log records a speed_tier entry in Event.Detail (config/auditlog/logger.go).

permission_default

Sets the profile-level default for whether kasmos should prompt for permission approval or launch the harness with its bypass behavior.

Accepted values

valueresult after normalization
"" (unset)"" — inherit the spawn-source default
"inherit""" — same as omitted
"prompt""prompt"
"bypass""bypass"
anything else (e.g. "auto")"prompt" — unrecognized values ask the operator

Normalization is handled by config.NormalizePermissionDefault in config/profile.go. The match is case-insensitive, leading/trailing whitespace is trimmed, "inherit" is mapped to "", and any unrecognized value collapses to "prompt".

Spawn-source defaults — when the normalized value is "", the launcher keeps the source's existing behavior:

  • Daemon and unattended orchestration spawns default to bypass.
  • Local interactive TUI spawns default to prompt.

Per-session override — raw flags still reach the harness. For example, flags = ["--permission-mode", "bypassPermissions"] still makes Claude launch in bypass mode even when permission_default = "prompt". permission_default controls the resolved kasmos SkipPermissions value; explicit harness flags remain lower-level command arguments.

Unattended coder

[agents.coder]
enabled = true
program = "codex"
model = "gpt-5.5"
execution_mode = "tmux"
permission_default = "bypass"

This makes orchestration-spawned coder sessions use bypass permissions for unattended automation.

Operator-approved reviewer

[agents.reviewer]
enabled = true
program = "claude"
model = "claude-sonnet-4-6"
execution_mode = "tmux"
permission_default = "prompt"

This makes reviewer sessions wait for operator approval of tool calls even when the daemon starts them.

BuildCommand()

AgentProfile.BuildCommand() constructs the full command string for logging and display:

strings.Join(append([]string{p.Program}, p.Flags...), " ")

For example, a profile with program = "claude" and flags = ["--permission-mode bypassPermissions"] produces:

claude --permission-mode bypassPermissions

The model and other flags that kasmos injects into the prompt are not part of BuildCommand() — they are handled separately by the orchestration layer.

profile resolution

kasmos resolves a profile for a given lifecycle phase via config.Config.ResolveProfile(phase, defaultProgram):

  1. Look up phases[phase] → role name.
  2. Look up agents[role]AgentProfile.
  3. If the profile has a non-empty Program and Enabled = true, use it.
  4. Otherwise fall back to AgentProfile{Program: defaultProgram, ExecutionMode: "tmux"}.

This means you can disable a role without removing it from the config — just set enabled = false.

[orchestration].planners resolves profile names directly from [agents.<profile>], not through [phases].planning. For example, planners = ["planner_opus", "planner_gpt"] requires both [agents.planner_opus] and [agents.planner_gpt] to exist and be enabled. If the list is unset or empty, kasmos uses the legacy single-planner resolution through [phases].planning.

examples

claude (tmux, interactive)

[agents.coder]
enabled = true
program = "codex"
model = "gpt-5.5"
execution_mode = "tmux"
tier = "fast"

Launches claude --permission-mode bypassPermissions in a new tmux window. The -p <prompt> and --model flags are injected by kasmos before appending flags.

claude opus (tmux, parallel planner)

[agents.planner_opus]
enabled = true
program = "claude"
model = "claude-opus-4-8"
execution_mode = "tmux"
effort = "xhigh"
flags = ["--permission-mode bypassPermissions"]

Runs Claude Opus in a tmux window as one lane of the default parallel planner set.

codex (tmux with current default model)

[agents.planner_gpt]
enabled = true
program = "codex"
model = "gpt-5.5"
execution_mode = "tmux"
tier = "fast"
effort = "xhigh"

Runs Codex as the second lane of the default parallel planner set. Codex model names remain free text; the wizard offers curated suggestions.

mixed setup (different agents per role)

[phases]
planning = "planner"
elaborating = "architect"
implementing = "coder"
quality_review = "reviewer"

[agents.planner_opus]
enabled = true
program = "claude"
model = "claude-opus-4-8"
execution_mode = "tmux"
effort = "xhigh"
flags = ["--permission-mode bypassPermissions"]

[agents.planner_gpt]
enabled = true
program = "codex"
model = "gpt-5.5"
execution_mode = "tmux"
effort = "xhigh"
tier = "fast"

[agents.architect]
enabled = true
program = "claude"
model = "claude-opus-4-8"
execution_mode = "tmux"
effort = "xhigh"
flags = ["--permission-mode bypassPermissions"]

[agents.coder]
enabled = true
program = "codex"
model = "gpt-5.5"
execution_mode = "tmux"
effort = "low"
tier = "fast"

[agents.reviewer]
enabled = true
program = "claude"
model = "claude-sonnet-4-6"
execution_mode = "tmux"
effort = "medium"
flags = ["--permission-mode bypassPermissions"]

[orchestration]
planners = ["planner_opus", "planner_gpt"]

disabling a role

[agents.architect]
enabled = false
program = "claude"

When enabled = false, kasmos falls back to default_program for that phase. The program field is still required but is not used.

default program detection

When default_program is not set in config.toml, kasmos calls config.GetDefaultCommand() which tries executables in order:

  1. codex (preferred)
  2. opencode
  3. claude

It sources your shell's rc file (~/.zshrc or ~/.bashrc) so shell aliases are visible. If none is found via the shell, exec.LookPath is used as a fallback.