Reference: the configuration file
- Format version: 1
- Issue: #4 — Spécifier le format du fichier de configuration YAML
- Schema: schema/config.schema.json (JSON Schema 2020-12), checked by
go test ./schema - Example: examples/test-agents.yaml
One YAML file describes the agents Sidekicks can talk to, the channels created at startup, and preferences. Conversations, messages and ACP sessions are not in it (see Architecture).
The application reads it with the Go package internal/config (milestone M1): validation, defaults, paths, the default file, reloading on every save.
Location
The file is looked up in this order; the first one that applies wins:
| # | Source | Example |
|---|---|---|
| 1 | --config <path> command-line flag |
sidekicks --config ~/agents/team.yaml |
| 2 | SIDEKICKS_CONFIG environment variable |
SIDEKICKS_CONFIG=~/agents/team.yaml |
| 3 | the last file opened from the application (Settings → Open… or Recent…), kept in <user config dir>/sidekicks/preferences.json |
— |
| 4 | the default location: <user config dir>/sidekicks/config.yaml |
macOS: ~/Library/Application Support/sidekicks/config.yaml, Linux: ~/.config/sidekicks/config.yaml |
<user config dir> is Go's os.UserConfigDir(). When the default file does not exist, Sidekicks creates it with comments explaining each key (issue #9).
Paths
- A relative path is resolved against the folder of the configuration file, never against the current directory. A folder holding a configuration and its agents can therefore be moved or versioned with git as a whole.
~at the start of a path is the user's home folder.command: a bare name (mm,docker) is looked up inPATH; anything containing/is a path, resolved as above.argsare passed as they are, without rewriting: the agent process starts in itsworkspace, so arguments relative to the workspace work.
Keys
Top level
| Key | Type | Required | Default | Meaning |
|---|---|---|---|---|
version |
integer | yes | — | Format version; only 1 exists. A later format increments it, so Sidekicks can migrate or refuse an old file explicitly. |
ui |
object | no | Interface preferences. | |
limits |
object | no | Resource limits. | |
agents |
list of agents | yes | The agents available with @name. May be empty. |
|
channels |
list of channels | no | [] |
Channels created at startup when they do not exist yet. |
Unknown keys are errors, at every level: a misspelt comand: must be reported, not silently ignored.
ui
| Key | Values | Default | Meaning |
|---|---|---|---|
theme |
system, light, dark |
system |
Colour theme; system follows the operating system. |
language |
en, fr |
en |
Language of the interface: its labels and the configuration error messages. |
limits
| Key | Type | Default | Meaning |
|---|---|---|---|
maxRunningAgents |
integer ≥ 1 | 2 |
Agents running at the same time. Each local agent keeps a model in memory; the default fits a 32 GB laptop with small models. |
stopIdleAgentsAfter |
Go duration (30s, 10m, 1h30m), or 0 (number or text) |
10m |
Stops an agent unused for this long, to free its memory. 0 never stops it. |
An agent
| Key | Type | Required | Default | Meaning |
|---|---|---|---|---|
name |
identifier | yes | Lowercase letters, digits, -, _; starts with a letter; 32 characters at most. Used as @name and /name:command. Unique. |
|
title |
text | no | name |
Name shown in the interface. |
icon |
text (an emoji) | no | Shown next to the agent. | |
description |
text | no | One sentence shown in the @ list. |
|
command |
text | yes | Program serving ACP on stdio. | |
args |
list of text | no | [] |
Its arguments. |
env |
map text → text | no | Extra environment variables. | |
afterStop |
list of text, at least one | no | Command run each time the agent's process ends — stopped, crashed, stopped to make room, or Sidekicks quitting: the program (a bare name is looked up in PATH, a path is relative to this file), then its arguments. It runs in workspace with env, for 30 s at most; its output goes to the agent's log; Sidekicks waits for it before quitting. A program that cannot be found is a warning. Example: [../scripts/agents.sh, unload, alice] to unload the model. |
|
workspace |
path | no | the configuration folder | The agent's folder: the process starts there and it is the cwd of its ACP sessions. mm reads AGENTS.md and skills/ from it. |
runtime |
object | no | {type: local} |
Where the agent runs (see below). |
runtime
The runtime tells Sidekicks how to reach the agent's files and terminal (Agents panel, issue #28). It does not change how the agent is started: command and args do that.
type |
Extra keys | Meaning |
|---|---|---|
local |
none | The agent runs on this computer; workspace is a local folder. |
container |
container (required), workspacePath |
The agent runs in a running Docker container; files and terminal go through docker exec. |
sbx |
sandbox (required), workspacePath |
The agent runs in a Docker sandbox (sbx); files and terminal go through sbx exec. |
workspacePath is an absolute path inside the container or the sandbox; it defaults to workspace (the same path, as with a bind mount). Behaviour of each runtime: workspaces.
A channel
| Key | Type | Required | Meaning |
|---|---|---|---|
name |
text, 1–64 characters | yes | Shown as #name. Unique. May contain accents and spaces. |
description |
text | no | Shown when hovering the channel's name, and in an empty channel. |
agents |
list of agent names | no | Members of the channel. A listed agent that is not a member yet is added at startup and when the file is reloaded; removing it from the list removes nothing. No duplicates. |
A channel declared here is created at startup, or when the file is reloaded, if no channel has this name yet (whatever the case); after that it lives in the application like any other channel, and can be renamed or deleted there. Removing it from the file does not delete it (deleting history must be an explicit user action). Each configuration file has its own channels and history (where it is kept).
What the "Add an agent" assistant writes
The assistant appends one entry at the end of agents; the rest of the file, comments included, is kept. Nothing is written when the result would not be valid.
| Field of the assistant | Written as |
|---|---|
| Name used with @, Name shown, Icon, What it does | name, title, icon, description (empty fields left out) |
| Agent's folder | workspace, as typed (~ and relative paths are resolved like any workspace) |
| On this computer | command: <program>, args: [<arguments>] |
| In a Docker container | command: docker, args: [exec, -i, <container>, <program>, <arguments>], runtime: {type: container, container: <container>} |
| In an sbx sandbox | command: sbx, args: [exec, -i, <sandbox>, <program>, <arguments>], runtime: {type: sbx, sandbox: <sandbox>} |
The arguments are split like a shell does for simple cases: spaces separate, single or double quotes group.
Rules checked by the loader, not by the schema
JSON Schema cannot express them; the configuration loader (issue #9) checks them and reports them like schema errors:
- agent names are unique;
- channel names are unique;
- every name in a channel's
agentsis the name of an agent; commandexists (inPATH, or as a file) — reported as a warning, since an agent may be installed later.
Error messages
Every error names the line and the key, in the language of the interface, and says how to fix it. Examples with the interface in English (the default):
| Problem | Message |
|---|---|
name: Alice Smith |
line 12 — agents[0].name: "Alice Smith" is not a valid name: lowercase letters, digits, "-" or "_", no space, starting with a letter (e.g. "alice") |
comand: mm |
line 14 — agents[0].comand: unknown key "comand"; did you mean "command"? |
command missing |
line 3 — agents[0]: the key "command" is missing |
Full example
version: 1
ui:
theme: system
language: fr
limits:
maxRunningAgents: 2
stopIdleAgentsAfter: 10m
agents:
- name: alice
title: Alice (assistante)
icon: "👩"
description: Questions simples, sans outils
command: mm
args: ["-acp", "-config", "agent.yaml"]
workspace: ./agents/alice
- name: garfield
title: Garfield (traducteur)
icon: "🐮"
command: mm
args: ["-acp", "-config", "agent.yaml"]
workspace: ./agents/garfield
- name: translator-sbx
title: Traducteur (sandbox)
command: sbx
args: ["exec", "-i", "mm-translator", "mm", "-acp"]
workspace: ./agents/translator/workspace
runtime:
type: sbx
sandbox: mm-translator
channels:
- name: général
agents: [alice]
- name: traductions
agents: [garfield]
sbx exec -i <sandbox> <program> runs the agent inside the sandbox; sbx mounts the host folder at the same path, so workspace is also the folder seen inside it. This example is also a test fixture (schema/testdata/valid/spec-example.yaml).
Go package schema
git.rickub.com/bots-garden/sidekicks/schema embeds the JSON Schema and validates documents against it.
| Identifier | Signature | Description |
|---|---|---|
ConfigSchemaURL |
const string |
The schema's $id: https://git.rickub.com/bots-garden/sidekicks/schema/config.schema.json. |
ConfigSchema |
func() []byte |
A copy of the JSON Schema document. |
ValidateConfig |
func(document []byte) error |
nil if the YAML document matches the schema; a YAML syntax error if it cannot be parsed; a *jsonschema.ValidationError listing every violation otherwise. |
if err := schema.ValidateConfig(content); err != nil {
fmt.Println("invalid configuration:", err)
}
A violation as returned by ValidateConfig:
jsonschema validation failed with 'https://git.rickub.com/bots-garden/sidekicks/schema/config.schema.json#'
- at '/agents/0': additional properties 'comand' not allowed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
|