bots-garden/sidekickspublic Fork
⑂ feature/m4-agents-workspace
Commits
⬇ Clone ▾
git clone https://git.rickub.com/bots-garden/sidekicks.git
git clone ssh://git@rickub.com/bots-garden/sidekicks.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP
🛟 Updated. d580a32 · on feature/m4-agents-workspace · k33g · 3d ago
configuration.md · 184 lines · 9.5 KBmarkdown
Blame HistoryOpen raw

Reference: the configuration file

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 in PATH; anything containing / is a path, resolved as above.
  • args are passed as they are, without rewriting: the agent process starts in its workspace, 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).

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:

  1. agent names are unique;
  2. channel names are unique;
  3. every name in a channel's agents is the name of an agent;
  4. command exists (in PATH, 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
# Reference: the configuration file

- **Format version**: 1
- **Issue**: [#4 — Spécifier le format du fichier de configuration YAML](../../../.tickets/issues/0004-specifier-le-format-du-fichier-de-configuration.yaml)
- **Schema**: [schema/config.schema.json](../../../schema/config.schema.json) (JSON Schema 2020-12), checked by `go test ./schema`
- **Example**: [examples/test-agents.yaml](../../../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](../explanation/architecture.md)).

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 in `PATH`; anything containing `/` is a path, resolved as above.
- `args` are passed as they are, without rewriting: the agent process starts in its `workspace`, 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](agents-and-events.md#workspaces-milestone-m4).

### 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](agents-and-events.md#history)).

## 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:

1. agent names are unique;
2. channel names are unique;
3. every name in a channel's `agents` is the name of an agent;
4. `command` exists (in `PATH`, 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

```yaml
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. |

```go
if err := schema.ValidateConfig(content); err != nil {
    fmt.Println("invalid configuration:", err)
}
```

A violation as returned by `ValidateConfig`:

```text
jsonschema validation failed with 'https://git.rickub.com/bots-garden/sidekicks/schema/config.schema.json#'
- at '/agents/0': additional properties 'comand' not allowed
```