ka-agent.toml (default ~/.config/ka-agent/ka-agent.toml) is strict TOML: unknown keys are hard errors. The schema lives in crates/ka-agent-core/src/config.rs; a fully commented copy ships in examples/config/ka-agent.toml.
| Key |
Type |
Default |
Meaning |
workspace |
path |
required |
The single workspace directory every engine runs in. ~ expands against $HOME. |
model |
selector |
engine decides |
Default Ka model selector for new sessions. |
mode |
string |
guarded |
Permission mode: guarded, accept_edits, free or plan. Re-asserted by the worker after every attach. |
approval_ttl_secs |
1..=86400 |
900 |
Approval card TTL; expiry denies (fail closed). |
turn_grace_secs |
1..=600 |
10 |
Grace after /stop before abort escalates: SIGTERM, then SIGKILL. |
| Key |
Default |
Meaning |
backoff_start_ms |
1000 |
First backoff after a worker crash. |
backoff_max_ms |
60000 |
Backoff ceiling. |
crash_window_secs |
600 |
Crash-loop window. |
crash_max |
5 |
Crashes inside the window that degrade the session (resume then needs /resume or /new). |
| Key |
Meaning |
daily_usd |
Daily USD cap across sessions. Omit for none. |
daily_tokens |
Daily token cap (input+output+cache); the only cap that binds for unpriced models. Omit for none. |
| Key |
Meaning |
engine_layer |
Optional path to a Ka engine layer in ka’s own strict ka.toml format, validated with Config::parse_layer by the worker. See examples/config/engine.toml. |
The worker’s security overlay is applied after the engine layer and always wins: mode = "guarded", bash jobs never detach, the remember tool is disabled, and [guards] spend_usd comes from the daemon budgets. The layer can tune the engine, never loosen policy.
| Key |
Meaning |
enabled |
Turn the channel on. |
token_secret |
Name of the bot token in the secret store (see below). |
api_base |
Bot API base URL; tests point this at a fake server. |
allow_user_ids |
Numeric operator ids; private chats only. Usernames are never trusted. |
Secrets never live in ka-agent.toml; the config names them, and ka_agent_channels::secret resolves each name in order:
$KA_AGENT_SECRET_<NAME> (name uppercased, dots become underscores);
<data>/secrets/<name>: a 0600 file, single line.
So telegram.bot_token resolves from $KA_AGENT_SECRET_TELEGRAM_BOT_TOKEN or <data>/secrets/telegram.bot_token.