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
| field | type | default | description |
|---|---|---|---|
enabled | bool | false | the role is active and can be dispatched; disabled profiles fall back to default_program |
program | string | — | executable name or path (e.g. claude, opencode, /usr/local/bin/codex) |
flags | []string | [] | extra CLI flags appended after the prompt argument |
model | string | — | model identifier passed to the agent (e.g. claude-sonnet-4-5) |
temperature | float? | — | sampling temperature, if the agent supports it |
effort | string | — | effort level (e.g. low, medium, high), if the agent supports it |
execution_mode | string | "tmux" | how the agent process is launched: "tmux" or "sdk" |
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".
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):
- Look up
phases[phase]→ role name. - Look up
agents[role]→AgentProfile. - If the profile has a non-empty
ProgramandEnabled = true, use it. - 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.
examples
claude (tmux, interactive)
[agents.coder]
enabled = true
program = "claude"
model = "claude-sonnet-4-5"
execution_mode = "tmux"
flags = ["--permission-mode bypassPermissions"]
Launches claude --permission-mode bypassPermissions in a new tmux window. The -p <prompt> and --model flags are injected by kasmos before appending flags.
opencode (tmux, high-effort planner)
[agents.planner]
enabled = true
program = "opencode"
execution_mode = "tmux"
effort = "high"
Runs opencode in a tmux window with effort = "high". opencode interprets the effort field to choose model tiers and thinking budgets. Note: execution_mode = "sdk" has no effect for opencode — there is no sdk transport for it; kasmos would fall back to tmux silently.
codex (sdk with custom model)
[agents.reviewer]
enabled = true
program = "codex"
model = "o3"
execution_mode = "sdk"
flags = ["--approval-mode", "full-auto"]
Drives codex --approval-mode full-auto via the Codex App Server protocol with model = "o3".
mixed setup (different agents per role)
[phases]
planning = "planner"
elaborating = "architect"
implementing = "coder"
quality_review = "reviewer"
[agents.planner]
enabled = true
program = "opencode"
execution_mode = "tmux"
effort = "high"
[agents.architect]
enabled = true
program = "claude"
model = "claude-sonnet-4-5"
execution_mode = "sdk"
[agents.coder]
enabled = true
program = "claude"
model = "claude-sonnet-4-5"
execution_mode = "tmux"
flags = ["--permission-mode bypassPermissions"]
[agents.reviewer]
enabled = true
program = "claude"
model = "claude-opus-4-5"
execution_mode = "sdk"
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:
opencode(preferred)claude
It sources your shell's rc file (~/.zshrc or ~/.bashrc) so shell aliases are visible. If neither is found via the shell, exec.LookPath is used as a fallback.