bots-garden/sidekickspublic Fork
⑂ v0.1.0
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. 8ef4097 · on v0.1.0 · k33g · 3d ago
configuration.md · 198 lines · 11.5 KBmarkdown
Blame HistoryOpen raw

Référence : le fichier de configuration

Un fichier YAML décrit les agents avec lesquels Sidekicks peut converser, les channels créés au démarrage et les préférences. Les conversations, les messages et les sessions ACP n'y figurent pas (voir Architecture).

L'application le lit avec le package Go internal/config (milestone M1) : validation, valeurs par défaut, chemins, fichier par défaut, rechargement à chaque enregistrement.

Emplacement

Le fichier est cherché dans cet ordre ; la première source applicable l'emporte :

# Source Exemple
1 option de ligne de commande --config <chemin> sidekicks --config ~/agents/equipe.yaml
2 variable d'environnement SIDEKICKS_CONFIG SIDEKICKS_CONFIG=~/agents/equipe.yaml
3 le dernier fichier ouvert depuis l'application (Settings → Open… ou Recent…), conservé dans <dossier de config utilisateur>/sidekicks/preferences.json —
4 l'emplacement par défaut : <dossier de config utilisateur>/sidekicks/config.yaml macOS : ~/Library/Application Support/sidekicks/config.yaml, Linux : ~/.config/sidekicks/config.yaml

<dossier de config utilisateur> est celui de os.UserConfigDir() en Go. Si le fichier par défaut n'existe pas, Sidekicks le crée avec des commentaires qui expliquent chaque clé (issue #9).

Chemins

  • Un chemin relatif est résolu par rapport au dossier du fichier de configuration, jamais par rapport au dossier courant. Un dossier qui contient une configuration et ses agents peut donc être déplacé ou versionné avec git d'un seul tenant.
  • ~ en début de chemin désigne le dossier personnel de l'utilisateur.
  • command : un nom seul (mm, docker) est cherché dans le PATH ; tout ce qui contient / est un chemin, résolu comme ci-dessus.
  • args est transmis tel quel, sans réécriture : le processus de l'agent démarre dans son workspace, donc les arguments relatifs au workspace fonctionnent.

Clés

Racine

Clé Type Obligatoire Défaut Signification
version entier oui — Version du format ; seule 1 existe. Un format ultérieur l'incrémente, pour que Sidekicks puisse migrer ou refuser explicitement un ancien fichier.
ui objet non Préférences d'interface.
limits objet non Limites de ressources.
agents liste d'agents oui Les agents disponibles avec @nom. Peut être vide.
channels liste de channels non [] Channels créés au démarrage s'ils n'existent pas encore.

Les clés inconnues sont des erreurs, à tous les niveaux : une faute de frappe comme comand: doit être signalée, pas ignorée en silence.

ui

Clé Valeurs Défaut Signification
theme system, light, dark system Thème de couleurs ; system suit le système d'exploitation.
language en, fr en Langue de l'interface : ses libellés et les messages d'erreur de la configuration.

limits

Clé Type Défaut Signification
maxRunningAgents entier ≥ 1 2 Agents actifs en même temps. Chaque agent local garde un modèle en mémoire ; la valeur par défaut convient à un portable de 32 Go avec de petits modèles.
stopIdleAgentsAfter durée Go (30s, 10m, 1h30m), ou 0 (nombre ou texte) 10m Arrête un agent inutilisé depuis ce délai pour libérer sa mémoire. 0 ne l'arrête jamais.

Un agent

Clé Type Obligatoire Défaut Signification
name identifiant oui Minuscules, chiffres, -, _ ; commence par une lettre ; 32 caractères au plus. Sert dans @nom et /nom:commande. Unique.
title texte non name Nom affiché dans l'interface.
icon texte (un emoji) non Affiché à côté de l'agent.
description texte non Une phrase affichée dans la liste @.
command texte oui Programme qui sert ACP sur stdio.
args liste de textes non [] Ses arguments.
env dictionnaire texte → texte non Variables d'environnement supplémentaires.
afterStop liste de textes, au moins un non Commande lancée à chaque fin du processus de l'agent — arrêt, crash, arrêt pour faire de la place, ou fermeture de Sidekicks : le programme (un nom seul est cherché dans le PATH, un chemin est relatif à ce fichier), puis ses arguments. Elle tourne dans workspace avec env, 30 s au plus ; sa sortie va dans le journal de l'agent ; Sidekicks l'attend avant de se fermer. Un programme introuvable est un avertissement. Exemple : [../scripts/agents.sh, unload, alice] pour décharger le modèle.
workspace chemin non le dossier de la configuration Le dossier de l'agent : le processus y démarre et c'est le cwd de ses sessions ACP. mm y lit AGENTS.md et skills/.
runtime objet non {type: local} Où tourne l'agent (voir ci-dessous).

runtime

Le runtime indique à Sidekicks comment atteindre les fichiers et le terminal de l'agent (panel Agents, issue #28). Il ne change pas la façon de démarrer l'agent : c'est le rôle de command et args.

type Clés supplémentaires Signification
local aucune L'agent tourne sur cet ordinateur ; workspace est un dossier local.
container container (obligatoire), workspacePath L'agent tourne dans un conteneur Docker démarré ; fichiers et terminal passent par docker exec.
sbx sandbox (obligatoire), workspacePath L'agent tourne dans une sandbox Docker (sbx) ; fichiers et terminal passent par sbx exec.

workspacePath est un chemin absolu dans le conteneur ou la sandbox ; par défaut, celui de workspace (le même chemin, comme avec un dossier monté). Comportement de chaque runtime : workspaces.

Un channel

Clé Type Obligatoire Signification
name texte, 1 à 64 caractères oui Affiché #nom. Unique. Accents et espaces autorisés.
description texte non Affichée au survol du nom du channel, et dans un channel vide.
agents liste de noms d'agents non Membres du channel. Un agent de la liste qui n'est pas encore membre est ajouté au démarrage et au rechargement du fichier ; le retirer de la liste ne retire rien. Sans doublon.

Un channel déclaré ici est créé au démarrage, ou au rechargement du fichier, si aucun channel ne porte encore ce nom (sans tenir compte de la casse) ; il vit ensuite dans l'application comme n'importe quel channel, et peut y être renommé ou supprimé. Le retirer du fichier ne le supprime pas (supprimer un historique doit être une action explicite de l'utilisateur). Chaque fichier de configuration a ses propres channels et son propre historique (où il est gardé).

Ce qu'écrit l'assistant « Ajouter un agent »

L'assistant ajoute une entrée à la fin de agents ; le reste du fichier, commentaires compris, est gardé. Rien n'est écrit si le résultat ne serait pas valide.

Champ de l'assistant Écrit comme
Nom utilisé avec @, Nom affiché, Icône, Ce qu'il fait name, title, icon, description (champs vides omis)
Dossier de l'agent workspace, tel que saisi (~ et chemins relatifs résolus comme tout workspace)
Sur cet ordinateur command: <programme>, args: [<arguments>]
Dans un conteneur Docker command: docker, args: [exec, -i, <conteneur>, <programme>, <arguments>], runtime: {type: container, container: <conteneur>}
Dans une sandbox sbx command: sbx, args: [exec, -i, <sandbox>, <programme>, <arguments>], runtime: {type: sbx, sandbox: <sandbox>}

Les arguments sont découpés comme le ferait un shell dans les cas simples : les espaces séparent, les guillemets simples ou doubles regroupent.

Règles vérifiées par le chargeur, pas par le schéma

JSON Schema ne sait pas les exprimer ; le chargeur de configuration (issue #9) les vérifie et les signale comme les erreurs de schéma :

  1. les noms d'agents sont uniques ;
  2. les noms de channels sont uniques ;
  3. chaque nom de la liste agents d'un channel est le nom d'un agent ;
  4. command existe (dans le PATH, ou comme fichier) — signalé comme avertissement, car un agent peut être installé plus tard.

Messages d'erreur

Chaque erreur indique la ligne et la clé, dans la langue de l'interface, et dit comment corriger. Exemples avec l'interface en français (language: fr) :

Problème Message
name: Alice Smith ligne 12 — agents[0].name : « Alice Smith » n'est pas un nom valide : minuscules, chiffres, « - » ou « _ », sans espace, en commençant par une lettre (ex. « alice »)
comand: mm ligne 14 — agents[0].comand : clé inconnue « comand » ; vouliez-vous dire « command » ?
command absente ligne 3 — agents[0] : il manque la clé « command »

Exemple complet

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> <programme> lance l'agent dans la sandbox ; sbx monte le dossier de l'hôte au même chemin, donc workspace est aussi le dossier vu à l'intérieur. Cet exemple est aussi un cas de test (schema/testdata/valid/spec-example.yaml).

Package Go schema

git.rickub.com/bots-garden/sidekicks/schema embarque le JSON Schema et valide des documents avec lui.

Identifiant Signature Description
ConfigSchemaURL const string Le $id du schéma : https://git.rickub.com/bots-garden/sidekicks/schema/config.schema.json.
ConfigSchema func() []byte Une copie du document JSON Schema.
ValidateConfig func(document []byte) error nil si le document YAML respecte le schéma ; une erreur de syntaxe YAML s'il ne peut pas être lu ; sinon une *jsonschema.ValidationError qui liste toutes les violations.
if err := schema.ValidateConfig(content); err != nil {
    fmt.Println("configuration invalide :", err)
}

Une violation telle que la renvoie 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
# Référence : le fichier de configuration

- **Version du format** : 1
- **Issue** : [#4 — Spécifier le format du fichier de configuration YAML](../../../.tickets/issues/0004-specifier-le-format-du-fichier-de-configuration.yaml)
- **Schéma** : [schema/config.schema.json](../../../schema/config.schema.json) (JSON Schema 2020-12), vérifié par `go test ./schema`
- **Exemple** : [examples/test-agents.yaml](../../../examples/test-agents.yaml)

Un fichier YAML décrit les agents avec lesquels Sidekicks peut converser, les channels créés au démarrage et les préférences. Les conversations, les messages et les sessions ACP n'y figurent pas (voir [Architecture](../explanation/architecture.md)).

L'application le lit avec le package Go `internal/config` (milestone M1) : validation, valeurs par défaut, chemins, fichier par défaut, rechargement à chaque enregistrement.

## Emplacement

Le fichier est cherché dans cet ordre ; la première source applicable l'emporte :

| # | Source | Exemple |
| --- | --- | --- |
| 1 | option de ligne de commande `--config <chemin>` | `sidekicks --config ~/agents/equipe.yaml` |
| 2 | variable d'environnement `SIDEKICKS_CONFIG` | `SIDEKICKS_CONFIG=~/agents/equipe.yaml` |
| 3 | le dernier fichier ouvert depuis l'application (Settings → **Open…** ou **Recent…**), conservé dans `<dossier de config utilisateur>/sidekicks/preferences.json` | — |
| 4 | l'emplacement par défaut : `<dossier de config utilisateur>/sidekicks/config.yaml` | macOS : `~/Library/Application Support/sidekicks/config.yaml`, Linux : `~/.config/sidekicks/config.yaml` |

`<dossier de config utilisateur>` est celui de `os.UserConfigDir()` en Go. Si le fichier par défaut n'existe pas, Sidekicks le crée avec des commentaires qui expliquent chaque clé (issue #9).

## Chemins

- Un chemin relatif est résolu **par rapport au dossier du fichier de configuration**, jamais par rapport au dossier courant. Un dossier qui contient une configuration et ses agents peut donc être déplacé ou versionné avec git d'un seul tenant.
- `~` en début de chemin désigne le dossier personnel de l'utilisateur.
- `command` : un nom seul (`mm`, `docker`) est cherché dans le `PATH` ; tout ce qui contient `/` est un chemin, résolu comme ci-dessus.
- `args` est transmis tel quel, sans réécriture : le processus de l'agent démarre dans son `workspace`, donc les arguments relatifs au workspace fonctionnent.

## Clés

### Racine

| Clé | Type | Obligatoire | Défaut | Signification |
| --- | --- | --- | --- | --- |
| `version` | entier | oui | — | Version du format ; seule `1` existe. Un format ultérieur l'incrémente, pour que Sidekicks puisse migrer ou refuser explicitement un ancien fichier. |
| `ui` | objet | non | | Préférences d'interface. |
| `limits` | objet | non | | Limites de ressources. |
| `agents` | liste d'agents | oui | | Les agents disponibles avec `@nom`. Peut être vide. |
| `channels` | liste de channels | non | `[]` | Channels créés au démarrage s'ils n'existent pas encore. |

Les clés inconnues sont des **erreurs**, à tous les niveaux : une faute de frappe comme `comand:` doit être signalée, pas ignorée en silence.

### `ui`

| Clé | Valeurs | Défaut | Signification |
| --- | --- | --- | --- |
| `theme` | `system`, `light`, `dark` | `system` | Thème de couleurs ; `system` suit le système d'exploitation. |
| `language` | `en`, `fr` | `en` | Langue de l'interface : ses libellés et les messages d'erreur de la configuration. |

### `limits`

| Clé | Type | Défaut | Signification |
| --- | --- | --- | --- |
| `maxRunningAgents` | entier ≥ 1 | `2` | Agents actifs en même temps. Chaque agent local garde un modèle en mémoire ; la valeur par défaut convient à un portable de 32 Go avec de petits modèles. |
| `stopIdleAgentsAfter` | durée Go (`30s`, `10m`, `1h30m`), ou `0` (nombre ou texte) | `10m` | Arrête un agent inutilisé depuis ce délai pour libérer sa mémoire. `0` ne l'arrête jamais. |

### Un agent

| Clé | Type | Obligatoire | Défaut | Signification |
| --- | --- | --- | --- | --- |
| `name` | identifiant | oui | | Minuscules, chiffres, `-`, `_` ; commence par une lettre ; 32 caractères au plus. Sert dans `@nom` et `/nom:commande`. **Unique.** |
| `title` | texte | non | `name` | Nom affiché dans l'interface. |
| `icon` | texte (un emoji) | non | | Affiché à côté de l'agent. |
| `description` | texte | non | | Une phrase affichée dans la liste `@`. |
| `command` | texte | oui | | Programme qui sert ACP sur stdio. |
| `args` | liste de textes | non | `[]` | Ses arguments. |
| `env` | dictionnaire texte → texte | non | | Variables d'environnement supplémentaires. |
| `afterStop` | liste de textes, au moins un | non | | Commande lancée à chaque fin du processus de l'agent — arrêt, crash, arrêt pour faire de la place, ou fermeture de Sidekicks : le programme (un nom seul est cherché dans le PATH, un chemin est relatif à ce fichier), puis ses arguments. Elle tourne dans `workspace` avec `env`, 30 s au plus ; sa sortie va dans le journal de l'agent ; Sidekicks l'attend avant de se fermer. Un programme introuvable est un avertissement. Exemple : `[../scripts/agents.sh, unload, alice]` pour décharger le modèle. |
| `workspace` | chemin | non | le dossier de la configuration | Le dossier de l'agent : le processus y démarre et c'est le `cwd` de ses sessions ACP. mm y lit `AGENTS.md` et `skills/`. |
| `runtime` | objet | non | `{type: local}` | Où tourne l'agent (voir ci-dessous). |

### `runtime`

Le runtime indique à Sidekicks comment atteindre les **fichiers et le terminal** de l'agent (panel Agents, issue #28). Il ne change pas la façon de démarrer l'agent : c'est le rôle de `command` et `args`.

| `type` | Clés supplémentaires | Signification |
| --- | --- | --- |
| `local` | aucune | L'agent tourne sur cet ordinateur ; `workspace` est un dossier local. |
| `container` | `container` (obligatoire), `workspacePath` | L'agent tourne dans un conteneur Docker démarré ; fichiers et terminal passent par `docker exec`. |
| `sbx` | `sandbox` (obligatoire), `workspacePath` | L'agent tourne dans une sandbox Docker (`sbx`) ; fichiers et terminal passent par `sbx exec`. |

`workspacePath` est un chemin absolu dans le conteneur ou la sandbox ; par défaut, celui de `workspace` (le même chemin, comme avec un dossier monté). Comportement de chaque runtime : [workspaces](agents-et-evenements.md#workspaces-milestone-m4).

### Un channel

| Clé | Type | Obligatoire | Signification |
| --- | --- | --- | --- |
| `name` | texte, 1 à 64 caractères | oui | Affiché `#nom`. **Unique.** Accents et espaces autorisés. |
| `description` | texte | non | Affichée au survol du nom du channel, et dans un channel vide. |
| `agents` | liste de noms d'agents | non | Membres du channel. Un agent de la liste qui n'est pas encore membre est ajouté au démarrage et au rechargement du fichier ; le retirer de la liste ne retire rien. Sans doublon. |

Un channel déclaré ici est créé au démarrage, ou au rechargement du fichier, **si aucun channel ne porte encore ce nom** (sans tenir compte de la casse) ; il vit ensuite dans l'application comme n'importe quel channel, et peut y être renommé ou supprimé. Le retirer du fichier ne le supprime pas (supprimer un historique doit être une action explicite de l'utilisateur). Chaque fichier de configuration a ses propres channels et son propre historique ([où il est gardé](agents-et-evenements.md#historique)).

## Ce qu'écrit l'assistant « Ajouter un agent »

L'assistant ajoute une entrée à la fin de `agents` ; le reste du fichier, commentaires compris, est gardé. Rien n'est écrit si le résultat ne serait pas valide.

| Champ de l'assistant | Écrit comme |
| --- | --- |
| Nom utilisé avec @, Nom affiché, Icône, Ce qu'il fait | `name`, `title`, `icon`, `description` (champs vides omis) |
| Dossier de l'agent | `workspace`, tel que saisi (`~` et chemins relatifs résolus comme tout `workspace`) |
| Sur cet ordinateur | `command: <programme>`, `args: [<arguments>]` |
| Dans un conteneur Docker | `command: docker`, `args: [exec, -i, <conteneur>, <programme>, <arguments>]`, `runtime: {type: container, container: <conteneur>}` |
| Dans une sandbox sbx | `command: sbx`, `args: [exec, -i, <sandbox>, <programme>, <arguments>]`, `runtime: {type: sbx, sandbox: <sandbox>}` |

Les arguments sont découpés comme le ferait un shell dans les cas simples : les espaces séparent, les guillemets simples ou doubles regroupent.

## Règles vérifiées par le chargeur, pas par le schéma

JSON Schema ne sait pas les exprimer ; le chargeur de configuration (issue #9) les vérifie et les signale comme les erreurs de schéma :

1. les noms d'agents sont uniques ;
2. les noms de channels sont uniques ;
3. chaque nom de la liste `agents` d'un channel est le nom d'un agent ;
4. `command` existe (dans le `PATH`, ou comme fichier) — signalé comme avertissement, car un agent peut être installé plus tard.

## Messages d'erreur

Chaque erreur indique la ligne et la clé, dans la langue de l'interface, et dit comment corriger. Exemples avec l'interface en français (`language: fr`) :

| Problème | Message |
| --- | --- |
| `name: Alice Smith` | ligne 12 — agents[0].name : « Alice Smith » n'est pas un nom valide : minuscules, chiffres, « - » ou « _ », sans espace, en commençant par une lettre (ex. « alice ») |
| `comand: mm` | ligne 14 — agents[0].comand : clé inconnue « comand » ; vouliez-vous dire « command » ? |
| `command` absente | ligne 3 — agents[0] : il manque la clé « command » |

## Exemple complet

```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> <programme>` lance l'agent dans la sandbox ; sbx monte le dossier de l'hôte au même chemin, donc `workspace` est aussi le dossier vu à l'intérieur. Cet exemple est aussi un cas de test (`schema/testdata/valid/spec-example.yaml`).

## Package Go `schema`

`git.rickub.com/bots-garden/sidekicks/schema` embarque le JSON Schema et valide des documents avec lui.

| Identifiant | Signature | Description |
| --- | --- | --- |
| `ConfigSchemaURL` | `const string` | Le `$id` du schéma : `https://git.rickub.com/bots-garden/sidekicks/schema/config.schema.json`. |
| `ConfigSchema` | `func() []byte` | Une copie du document JSON Schema. |
| `ValidateConfig` | `func(document []byte) error` | `nil` si le document YAML respecte le schéma ; une erreur de syntaxe YAML s'il ne peut pas être lu ; sinon une `*jsonschema.ValidationError` qui liste toutes les violations. |

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

Une violation telle que la renvoie `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
```