overmind-mcp 2.8.50 → 2.8.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +30 -4
- package/dist/bin/cli.js.map +1 -1
- package/dist/lib/orchestration/swarm.js +2 -2
- package/dist/lib/orchestration/swarm.js.map +1 -1
- package/dist/lib/processRegistry.js +2 -2
- package/dist/lib/processRegistry.js.map +1 -1
- package/dist/lib/sessions.js +2 -2
- package/dist/lib/sessions.js.map +1 -1
- package/dist/memory/MemoryFactory.js +2 -2
- package/dist/memory/MemoryFactory.js.map +1 -1
- package/dist/memory/PostgresMemoryProvider.d.ts.map +1 -1
- package/dist/memory/PostgresMemoryProvider.js +2 -2
- package/dist/memory/PostgresMemoryProvider.js.map +1 -1
- package/dist/services/ClineRunner.js +2 -2
- package/dist/services/ClineRunner.js.map +1 -1
- package/dist/services/GeminiRunner.js +2 -2
- package/dist/services/GeminiRunner.js.map +1 -1
- package/dist/services/NousHermesRunner.js +2 -2
- package/dist/services/NousHermesRunner.js.map +1 -1
- package/dist/services/OpenClawRunner.js +2 -2
- package/dist/services/OpenClawRunner.js.map +1 -1
- package/dist/services/OpenCodeRunner.js +2 -2
- package/dist/services/OpenCodeRunner.js.map +1 -1
- package/dist/services/QwenCliRunner.js +2 -2
- package/dist/services/QwenCliRunner.js.map +1 -1
- package/dist/services/hermes/binaryFinder.js +2 -2
- package/dist/services/hermes/binaryFinder.js.map +1 -1
- package/dist/services/hermes/configYamlFilter.js +2 -2
- package/dist/services/hermes/configYamlFilter.js.map +1 -1
- package/dist/services/hermes/processUtils.js +2 -2
- package/dist/services/hermes/processUtils.js.map +1 -1
- package/docs/OVERMIND_HERMES_SNIPERBOT_FLOW.md +1 -1
- package/docs/SETUP_HERMES_AGENT_FROM_SCRATCH.md +18 -18
- package/docs/SUBTILISATION_EXPLAINED.md +2 -2
- package/docs/agent-http-tutorial.md +524 -524
- package/docs/doc_guide_agent_hermes_permanent.md +1 -1
- package/docs/doc_hermes_gateway.md +2 -2
- package/docs/guide_agent_hermes_overmind.md +1 -1
- package/docs/provider-config-map.md +556 -556
- package/package.json +1 -1
- package/docs/PLAN_REFACTORING_OVERMIND_V2.md +0 -414
- package/docs/PLAN_REFACTOR_OVERMIND_AGI.md +0 -606
|
@@ -1,557 +1,557 @@
|
|
|
1
|
-
# Hermes x Overmind — Config Provider Map
|
|
2
|
-
|
|
3
|
-
## Ordre de resolution (qui gagne, qui perd)
|
|
4
|
-
|
|
5
|
-
Chaque variable suit cette priorite (la premiere gagne):
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
process.env (env du parent, herite par le spawn)
|
|
9
|
-
↓
|
|
10
|
-
Workflow/.env (
|
|
11
|
-
↓
|
|
12
|
-
settings_[agent].json → env (apres interpolation $VAR par process.env)
|
|
13
|
-
↓
|
|
14
|
-
HERMES_HOME/.env (
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
**Detail du code** (`NousHermesRunner.ts` l.268-456):
|
|
18
|
-
1. `agentCustomEnv = { ...process.env, ...settings.env }` (line 268 puis 384)
|
|
19
|
-
2. Puis lit `overmindHermesSubPath/.env` (le `.hermes/.env` de l'agent) et fait `agentCustomEnv[key] = value` (line 437-456) — ce qui OVERRIDE tout ce qui precede.
|
|
20
|
-
3. Finalement ecrit ce `agentCustomEnv` dans le `.env` final de l'agent (line 722-732) avec dedup sur les cles `*api_key` / `*auth_token`.
|
|
21
|
-
|
|
22
|
-
Donc le `.hermes/.env` de l'agent a **toujours le dernier mot**. Si tu mets `MINIMAX_API_KEY=*** dans le .hermes/.env, il ecrase `MINIMAX_API_KEY` du process.env et du settings.
|
|
23
|
-
|
|
24
|
-
**MAIS** pour `OPENROUTER_API_KEY` uniquement:
|
|
25
|
-
- Hermes lit d'abord `HERMES_HOME/.env` puis `os.environ`
|
|
26
|
-
- Si present dans `auth.json` avec status `exhausted` → skip
|
|
27
|
-
- Si present dans `HERMES_HOME/.env` (meme vide `""`) → **PREND LA PRIORITE sur process.env**
|
|
28
|
-
|
|
29
|
-
**MAIS** pour tous les autres providers (zai, minimax-cn, etc.):
|
|
30
|
-
- Hermes lit `HERMES_HOME/.env` → si vide/null → lit `os.environ`
|
|
31
|
-
- `os.environ` contient tout ce que le parent a passe (donc le `.env` du Workflow)
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## Les 5 fichiers cles
|
|
36
|
-
|
|
37
|
-
| Fichier | Role |
|
|
38
|
-
|---|---|
|
|
39
|
-
| `HERMES_HOME/.env` | API keys globales Hermes (fallback) |
|
|
40
|
-
| `Workflow/.env` | Variables du workflow (DB, tokens, etc.) |
|
|
41
|
-
| `settings_[agent].json` | Config par agent (model, provider, tokens, MCP) |
|
|
42
|
-
| `HERMES_HOME/.hermes/config.yaml` | Config systeme Hermes (model.default, provider, etc.) |
|
|
43
|
-
| `HERMES_HOME/auth.json` | Credential pool — status des tokens (ok/exhausted), URLs par provider |
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Les 2 endpoints Z.AI (DECOUVERTE CRITIQUE)
|
|
48
|
-
|
|
49
|
-
Z.AI a **deux endpoints distincts** — confusion entre les deux causait des erreurs 402:
|
|
50
|
-
|
|
51
|
-
| Endpoint | URL | Usage |
|
|
52
|
-
|---|---|---|
|
|
53
|
-
| **Coding** (celui qu'il faut) | `https://api.z.ai/api/coding/paas/v4` | Inference LLM (Hermes, Overmind) |
|
|
54
|
-
| **Non-coding** (ancien, different billing) | `https://api.z.ai/api/paas/v4` | Autre chose (pas le meme systeme de facturation) |
|
|
55
|
-
|
|
56
|
-
**Comment le credential pool est seed:**
|
|
57
|
-
|
|
58
|
-
| Source dans .env | Cle dans auth.json | base_url assignee |
|
|
59
|
-
|---|---|---|
|
|
60
|
-
| `ZAI_ANTHROPIC_FALLBACK_KEY` | `zai[0].access_token` | `https://api.z.ai/api/coding/paas/v4` ✅ |
|
|
61
|
-
| `Z_AI_API_KEY` | `zai[1].access_token` | `https://api.z.ai/api/paas/v4` ❌ (ancien) |
|
|
62
|
-
|
|
63
|
-
Le premier entry (priority 0) est utilise en premier. C'est celui qui est seed par `writeAuthJson()` dans `NousHermesRunner.ts` → `ZAI_ANTHROPIC_FALLBACK_KEY`.
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
## Provider → Ce qu'Hermes attend
|
|
68
|
-
|
|
69
|
-
### Z.AI (id: `zai`)
|
|
70
|
-
|
|
71
|
-
| Param | Valeur attendue | Source dans Hermes |
|
|
72
|
-
|---|---|---|
|
|
73
|
-
| Provider ID | `zai` | config.yaml ou settings |
|
|
74
|
-
| API Key | `ZAI_ANTHROPIC_FALLBACK_KEY` (cle primaire) ou `Z_AI_API_KEY` (fallback ancien) | `HERMES_HOME/.env` → `os.environ` |
|
|
75
|
-
| Base URL | `https://api.z.ai/api/coding/paas/v4` | credential pool (seed par writeAuthJson) |
|
|
76
|
-
| Model | `glm-5.
|
|
77
|
-
|
|
78
|
-
```json
|
|
79
|
-
// settings_[agent].json — Z.AI correct
|
|
80
|
-
{
|
|
81
|
-
"env": {
|
|
82
|
-
"ANTHROPIC_AUTH_TOKEN": "$ZAI_ANTHROPIC_FALLBACK_KEY",
|
|
83
|
-
"ANTHROPIC_BASE_URL": "https://api.z.ai/api/coding/paas/v4",
|
|
84
|
-
"ANTHROPIC_MODEL": "glm-5.
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
# .env minimal pour Z.AI
|
|
91
|
-
ZAI_ANTHROPIC_FALLBACK_KEY
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Le credential pool `auth.json` est ecrit par `writeAuthJson()` dans `NousHermesRunner.ts`. La cle `ZAI_ANTHROPIC_FALLBACK_KEY` est envoyee par `agentCustomEnv` → Hermes seed le credential pool avec le bon endpoint.
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
### Z.AI Multi-Token (E/Y)
|
|
99
|
-
|
|
100
|
-
Deamon a 2 tokens Z.AI (E=primary, Y=secondary). Le credential pool peut contenir les deux:
|
|
101
|
-
|
|
102
|
-
| Token | Label dans auth.json | Cle dans .env |
|
|
103
|
-
|---|---|---|
|
|
104
|
-
| Primary | `ANTHROPIC_AUTH_TOKEN_E` | `ANTHROPIC_AUTH_TOKEN_E` =
|
|
105
|
-
| Secondary | `ANTHROPIC_AUTH_TOKEN_Y` | `ANTHROPIC_AUTH_TOKEN_Y` =
|
|
106
|
-
|
|
107
|
-
Pour qu'un agent utilise le token Y (secondary) au lieu de E (primary), le settings doit utiliser `$ANTHROPIC_AUTH_TOKEN_Y` au lieu de `$ANTHROPIC_AUTH_TOKEN_E`.
|
|
108
|
-
|
|
109
|
-
---
|
|
110
|
-
|
|
111
|
-
### MiniMax CN (id: `minimax-cn`)
|
|
112
|
-
|
|
113
|
-
| Param | Valeur attendue | Source dans Hermes |
|
|
114
|
-
|---|---|---|
|
|
115
|
-
| Provider ID | `minimax-cn` | config.yaml ou settings |
|
|
116
|
-
| API Key | `MINIMAX_CN_API_KEY` **uniquement** | `HERMES_HOME/.env` → `os.environ` |
|
|
117
|
-
| Base URL | `https://api.minimaxi.com/anthropic` | hardcoded dans ProviderConfig |
|
|
118
|
-
| Model | `MiniMax-M3` | settings `env.ANTHROPIC_MODEL` |
|
|
119
|
-
|
|
120
|
-
```json
|
|
121
|
-
// settings_[agent].json — MiniMax correct
|
|
122
|
-
{
|
|
123
|
-
"env": {
|
|
124
|
-
"ANTHROPIC_AUTH_TOKEN": "$MINIMAX_CN_API_KEY",
|
|
125
|
-
"ANTHROPIC_BASE_URL": "https://api.minimaxi.com/anthropic",
|
|
126
|
-
"ANTHROPIC_MODEL": "MiniMax-M3"
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
# .env minimal pour MiniMax CN
|
|
133
|
-
MINIMAX_CN_API_KEY=ton_token_minimax_ici
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
**auth.json** stocke sous `MINIMAX_CN_API_KEY`.
|
|
137
|
-
|
|
138
|
-
#### MiniMax CN par défaut (convention)
|
|
139
|
-
|
|
140
|
-
Le préfixe `sk-cp-` est partagé entre MiniMax GLOBAL (`api.minimax.com`) et
|
|
141
|
-
MiniMax CN (`api.minimaxi.com`). L'URL est le seul signal qui disambiguïse.
|
|
142
|
-
Pour les setups où TOUS les tokens MiniMax sont CN (cas le plus commun),
|
|
143
|
-
le runner a un fallback par défaut : quand un token `sk-cp-*` est détecté
|
|
144
|
-
sans URL explicite, on bascule sur CN.
|
|
145
|
-
|
|
146
|
-
Controlable via env var :
|
|
147
|
-
|
|
148
|
-
```bash
|
|
149
|
-
# Défaut (recommandé pour les setups CN-only)
|
|
150
|
-
OVERMIND_MINIMAX_DEFAULT=cn # sk-cp-* sans URL → minimax-cn
|
|
151
|
-
|
|
152
|
-
# Pour les setups GLOBAL-only
|
|
153
|
-
OVERMIND_MINIMAX_DEFAULT=global # sk-cp-* sans URL → minimax
|
|
154
|
-
|
|
155
|
-
# Strict mode (jamais d'inference, URL obligatoire)
|
|
156
|
-
OVERMIND_MINIMAX_DEFAULT=auto # sk-cp-* sans URL → minimax (no override)
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
Si une URL explicite est présente dans `ANTHROPIC_BASE_URL`, elle gagne
|
|
160
|
-
toujours sur `OVERMIND_MINIMAX_DEFAULT`.
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
### OpenRouter — BANNIR pour LLM
|
|
165
|
-
|
|
166
|
-
| Param | Valeur attendue | Source |
|
|
167
|
-
|---|---|---|
|
|
168
|
-
| Provider ID | — | **Ne PAS utiliser** |
|
|
169
|
-
| API Key | `OPENROUTER_API_KEY` | `HERMES_HOME/.env` → `os.environ` |
|
|
170
|
-
| Base URL | `https://openrouter.ai/api/v1` | hardcoded |
|
|
171
|
-
| Guardrail | — | Force 404 si active |
|
|
172
|
-
|
|
173
|
-
**PROBLEME:** Si `OPENROUTER_API_KEY` est present (meme dans `OVERMIND_EMBEDDING_KEY` route via NousHermesRunner), Hermes le detecte et tente OpenRouter pour l'inference.
|
|
174
|
-
|
|
175
|
-
**auth.json** a une entree OpenRouter — si le status est `exhausted`, Hermes ne retry plus mais peut quand meme picker le provider "openrouter" dans le credential pool.
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
|
-
## Ne PAS passer --provider au CLI Hermes (NOUVEAU en 2.8.28)
|
|
180
|
-
|
|
181
|
-
Le runner Overmind **ne passe plus** le flag `--provider` au CLI Hermes.
|
|
182
|
-
Découverte empirique (le `Hermes-MiniMax-2.bat` du bureau marche mais
|
|
183
|
-
le sniperbot échoue) :
|
|
184
|
-
|
|
185
|
-
| Commande | Résultat |
|
|
186
|
-
|---|---|
|
|
187
|
-
| `hermes chat -q --provider minimax-cn ...` | **401** (bug plugin upstream) |
|
|
188
|
-
| `hermes chat --yolo` (sans --provider) | **200 OK** |
|
|
189
|
-
|
|
190
|
-
**Cause** : le flag `--provider` explicite active un code path buggé
|
|
191
|
-
dans le plugin Hermes upstream (`hermes-agent/plugins/model-providers/minimax/`)
|
|
192
|
-
qui envoie un format d'auth header rejeté par `api.minimaxi.com`.
|
|
193
|
-
|
|
194
|
-
**Fix appliqué** : le runner retire `--provider` de `cleanArgs` mais
|
|
195
|
-
loggue le `resolvedProvider` à INFO pour debug. Hermes auto-détecte
|
|
196
|
-
le bon provider depuis l'env var :
|
|
197
|
-
- `MINIMAX_CN_API_KEY` → plugin `minimax-cn`
|
|
198
|
-
- `MINIMAX_API_KEY` → plugin `minimax` (GLOBAL)
|
|
199
|
-
- `ZAI_ANTHROPIC_FALLBACK_KEY` ou `GLM_API_KEY` → plugin `zai`
|
|
200
|
-
- `ANTHROPIC_AUTH_TOKEN` avec préfixe `sk-ant-` → plugin `anthropic`
|
|
201
|
-
|
|
202
|
-
`ANTHROPIC_BASE_URL` et `ANTHROPIC_MODEL` sont toujours passés, donc
|
|
203
|
-
Hermes a assez d'info pour ne pas se tromper.
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
## HERMES_HOME resolution (multi-OS, multi-install)
|
|
207
|
-
|
|
208
|
-
Chaque agent Hermes a son propre HERMES_HOME. Le path est resolu de maniere
|
|
209
|
-
deterministe par `getAgentHermesHome(agentName)` dans `src/lib/config.ts`.
|
|
210
|
-
|
|
211
|
-
Ordre de resolution (la premiere gagne):
|
|
212
|
-
|
|
213
|
-
```
|
|
214
|
-
OVERMIND_AGENT_HOME (env var, set par l'install ou systemd)
|
|
215
|
-
↓
|
|
216
|
-
<workspace>/.overmind/hermes/agent_<name>/.hermes (legacy, si deja existant)
|
|
217
|
-
↓
|
|
218
|
-
$HOME/.overmind/hermes/agent_<name>/.hermes (Linux/Mac sudo npm -g)
|
|
219
|
-
%LOCALAPPDATA%\overmind\hermes\agent_<name>\.hermes (Windows npm -g)
|
|
220
|
-
%USERPROFILE%\overmind\hermes\agent_<name>\.hermes (Windows fallback)
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
Pour un agent nomme `sniperbot_analyst`:
|
|
224
|
-
- Dev local (workspace = `
|
|
225
|
-
`Workflow\.overmind\hermes\agent_sniperbot_analyst\.hermes` (si deja cree)
|
|
226
|
-
- Prod Linux: `~/.overmind/hermes/agent_sniperbot_analyst/.hermes`
|
|
227
|
-
- Prod Windows: `%LOCALAPPDATA%\overmind\hermes\agent_sniperbot_analyst\.hermes`
|
|
228
|
-
|
|
229
|
-
**Pourquoi c'est important**: avant, le runner Overmind calculait HERMES_HOME
|
|
230
|
-
depuis `process.cwd()`. Si le sniper etait lance depuis
|
|
231
|
-
et le runner depuis `Workflow\`, ils lisaient des `.hermes/.env` differents
|
|
232
|
-
et ecrivaient dans des `auth.json` differents. Maintenant, c'est cwd-independent.
|
|
233
|
-
|
|
234
|
-
Pour forcer un chemin explicite (ex: deploy Docker), set:
|
|
235
|
-
```bash
|
|
236
|
-
export OVERMIND_AGENT_HOME=/var/lib/overmind/hermes
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
## Comment Hermes decide quel provider utiliser
|
|
241
|
-
|
|
242
|
-
Il y a DEUX niveaux de decision:
|
|
243
|
-
|
|
244
|
-
### Niveau 1: Overmind runner (avant spawn)
|
|
245
|
-
|
|
246
|
-
`NousHermesRunner.writeAuthJson()` (l.782-918) vote entre 3 signaux pour determiner le `effectiveProvider` qui sera seed dans `auth.json` et le `.env` de l'agent:
|
|
247
|
-
|
|
248
|
-
1. **Token prefix** (le plus fiable) — `detectTokenProvider()` reconnait:
|
|
249
|
-
- `sk-cp-...` ou `sk-mm-...` → `minimax`
|
|
250
|
-
- `32hex.32hex` ou 32-char hex → `zai`
|
|
251
|
-
- `sk-ant-...` → `anthropic`
|
|
252
|
-
- `sk-or-...` → `openrouter` (mais BLOQUE pour LLM par la suite)
|
|
253
|
-
- `sk-...` (autre) → `openai`
|
|
254
|
-
2. **BASE_URL** (tres fiable, plus specifique que le token pour CN vs GLOBAL) — `api.minimaxi.com` → `minimax-cn`, `api.minimax.com` → `minimax`, `api.z.ai/api/coding/paas/v4` → `zai`, `anthropic.com` → `anthropic`, `openai.com` → `openai`.
|
|
255
|
-
3. **ANTHROPIC_PROVIDER** hint du settings (le moins fiable).
|
|
256
|
-
|
|
257
|
-
**Cas special CN vs GLOBAL**: `sk-cp-` est ambigu entre `minimax` et `minimax-cn` (meme prefix). Si l'URL dit `minimaxi` (avec le `i`), c'est CN. Si `minimax` (sans le `i`), c'est GLOBAL. **L'URL gagne dans ce cas precis** parce qu'elle est la seule a desambiguïser.
|
|
258
|
-
|
|
259
|
-
### Niveau 2: Hermes upstream (apres spawn)
|
|
260
|
-
|
|
261
|
-
Hermes relit son `auth.json` + `HERMES_HOME/.env` + `os.environ` avec sa propre logique (dans `hermes_cli/auth.py`):
|
|
262
|
-
|
|
263
|
-
```
|
|
264
|
-
1. Si `provider` explicite dans config.yaml → utilise ce provider
|
|
265
|
-
2. Sinon si `ANTHROPIC_BASE_URL` contient openrouter → "openrouter"
|
|
266
|
-
3. Sinon lit model name → compare avec model_defaults par provider
|
|
267
|
-
- "glm-*" → "zai"
|
|
268
|
-
- "MiniMax-*" → "minimax-cn"
|
|
269
|
-
4. Sinon fallback: model.default dans config.yaml
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
**Le runner a deja vote au Niveau 1** — donc ce que tu mets dans `auth.json` (via `writeAuthJson()`) determine ce qu'Hermes verra au Niveau 2. Si le runner a seed `minimax-cn` mais que `config.yaml` dit `provider: minimax`, Hermes va probablement se plaindre. **Garde les deux alignes** ou laisse le runner ecrire le `config.yaml` (ce qu'il fait deja a chaque run).
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## Comment NousHermesRunner passe les vars a Hermes
|
|
277
|
-
|
|
278
|
-
Le runner lit `settings_[agent].json` → applique `interpolateEnvVars()` qui remplace `$VAR` par `process.env[VAR]` → envoie le tout dans `agentCustomEnv` au processus Hermes.
|
|
279
|
-
|
|
280
|
-
```typescript
|
|
281
|
-
// Ce que NousHermesRunner.ts passe a Hermes (agentCustomEnv)
|
|
282
|
-
const agentCustomEnv = {
|
|
283
|
-
...process.env, // HERMES_HOME/.env + Workflow/.env fusionnes
|
|
284
|
-
PYTHONIOENCODING: 'utf-8',
|
|
285
|
-
OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY || '', // VIDE (fixe)
|
|
286
|
-
NVIDIA_API_KEY: process.env.NVIDIA_API_KEY || process.env.NVAPI_KEY,
|
|
287
|
-
ANTHROPIC_AUTH_TOKEN: s.env.ANTHROPIC_AUTH_TOKEN, // interpolate
|
|
288
|
-
ANTHROPIC_BASE_URL: s.env.ANTHROPIC_BASE_URL, // interpolate
|
|
289
|
-
ANTHROPIC_MODEL: s.env.ANTHROPIC_MODEL, // interpolate
|
|
290
|
-
};
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
Puis lance Hermes avec `--env-file` pour discord_llm + Workflow `.env` (via startpipeline.js).
|
|
294
|
-
|
|
295
|
-
---
|
|
296
|
-
|
|
297
|
-
## Le probleme de OPENROUTER_API_KEY
|
|
298
|
-
|
|
299
|
-
**AVANT le fix:**
|
|
300
|
-
```typescript
|
|
301
|
-
OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY || process.env.OVERMIND_EMBEDDING_KEY,
|
|
302
|
-
```
|
|
303
|
-
→ Si `OPENROUTER_API_KEY` vide mais `OVERMIND_EMBEDDING_KEY` present → passe quand meme une cle OpenRouter a Hermes → Hermes detecte `OPENROUTER_API_KEY` → tente OpenRouter → 404 guardrail.
|
|
304
|
-
|
|
305
|
-
**APRES le fix:**
|
|
306
|
-
```typescript
|
|
307
|
-
OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY || '',
|
|
308
|
-
```
|
|
309
|
-
→ `OVERMIND_EMBEDDING_KEY` n'est plus redirige. Si `OPENROUTER_API_KEY` absent du `.env`, Hermes recoit string vide et ne pick pas OpenRouter.
|
|
310
|
-
|
|
311
|
-
---
|
|
312
|
-
|
|
313
|
-
## Comment Hermes obtient la API Key (le vrai flux)
|
|
314
|
-
|
|
315
|
-
Le `ANTHROPIC_AUTH_TOKEN` dans `settings.json` **ne passe pas directement** dans le body de la requete API. Hermes utilise son propre credential pool:
|
|
316
|
-
|
|
317
|
-
```
|
|
318
|
-
settings_[agent].json
|
|
319
|
-
"env": {
|
|
320
|
-
"ANTHROPIC_AUTH_TOKEN": "$ZAI_ANTHROPIC_FALLBACK_KEY", ← Runner remplace $VAR → "token_reel"
|
|
321
|
-
"ANTHROPIC_BASE_URL": "https://api.z.ai/api/coding/paas/v4",
|
|
322
|
-
"ANTHROPIC_MODEL": "glm-5.
|
|
323
|
-
}
|
|
324
|
-
↓ (interpolateEnvVars par NousHermesRunner)
|
|
325
|
-
agentCustomEnv envoye a Hermes:
|
|
326
|
-
ANTHROPIC_AUTH_TOKEN=token_reel
|
|
327
|
-
ANTHROPIC_BASE_URL=https://api.z.ai/api/coding/paas/v4
|
|
328
|
-
ANTHROPIC_MODEL=glm-5.
|
|
329
|
-
|
|
330
|
-
MAIS Hermes ne lit PAS ANTHROPIC_AUTH_TOKEN directement.
|
|
331
|
-
Hermes lit le CREDENTIAL POOL (auth.json) + les .env vars listees dans api_key_env_vars.
|
|
332
|
-
|
|
333
|
-
Credential pool est seed par:
|
|
334
|
-
ZAI_ANTHROPIC_FALLBACK_KEY → "zai" avec base_url coding ✅
|
|
335
|
-
Z_AI_API_KEY → "zai" avec base_url non-coding (ancien)
|
|
336
|
-
MINIMAX_CN_API_KEY → "minimax-cn"
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
Le `$VAR` dans `ANTHROPIC_AUTH_TOKEN` est juste une convenience pour que le token traverse le runner et arrive dans `process.env` du subprocess Hermes. C'est `process.env.ZAI_ANTHROPIC_FALLBACK_KEY` qui seed le credential pool.
|
|
340
|
-
|
|
341
|
-
---
|
|
342
|
-
|
|
343
|
-
## Le flow complet (Z.AI par exemple)
|
|
344
|
-
|
|
345
|
-
1. `Workflow/.env` contient `ZAI_ANTHROPIC_FALLBACK_KEY=<TOKEN>`
|
|
346
|
-
2. `startpipeline.js` charge `.env` → `process.env.ZAI_ANTHROPIC_FALLBACK_KEY`
|
|
347
|
-
3. ` NousHermesRunner` lit `settings_zai.json` → `interpolateEnvVars()`
|
|
348
|
-
- `$ZAI_ANTHROPIC_FALLBACK_KEY` → `process.env["ZAI_ANTHROPIC_FALLBACK_KEY"]` → `"<TOKEN>"`
|
|
349
|
-
- `ANTHROPIC_AUTH_TOKEN="<TOKEN>"` (valeur concrete maintenant)
|
|
350
|
-
4. `agentCustomEnv` envoye a Hermes:
|
|
351
|
-
- `ANTHROPIC_AUTH_TOKEN=<TOKEN>`
|
|
352
|
-
- `ANTHROPIC_BASE_URL=https://api.z.ai/api/coding/paas/v4`
|
|
353
|
-
- `ANTHROPIC_MODEL=glm-5.
|
|
354
|
-
5. Hermes fait son propre lookup:
|
|
355
|
-
- `load_pool("zai")` → `_resolve_api_key_provider_secret("zai")`
|
|
356
|
-
- Cherche `ZAI_ANTHROPIC_FALLBACK_KEY` via `_get_env_prefer_dotenv()` dans `HERMES_HOME/.env` puis `os.environ`
|
|
357
|
-
- Trouve dans `os.environ` (herite du parent)
|
|
358
|
-
- `writeAuthJson()` ecrit dans `auth.json` avec base_url `https://api.z.ai/api/coding/paas/v4`
|
|
359
|
-
6. API call → utilise le credential pool entry pour `zai` avec le bon endpoint
|
|
360
|
-
|
|
361
|
-
---
|
|
362
|
-
|
|
363
|
-
## OPENROUTER et Les Embeddings
|
|
364
|
-
|
|
365
|
-
**`OVERMIND_EMBEDDING_KEY`** = clef OpenRouter pour les **embeddings uniquement** (PostgresMemoryProvider du Workflow). Elle est dans le `.env` Overmind. Hermes n'a pas besoin de la voir pour l'LLM inference.
|
|
366
|
-
|
|
367
|
-
**NousHermesRunner ne doit jamais forwarder de clef OpenRouter a Hermes.** OpenRouter n'est pas un provider LLM dans ce setup. Si `OPENROUTER_API_KEY` arrive jusqu'a Hermes, il detecte la clef et tente OpenRouter pour l'inference → 404 guardrail.
|
|
368
|
-
|
|
369
|
-
**Fix applique:**
|
|
370
|
-
```typescript
|
|
371
|
-
OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY || '',
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
---
|
|
375
|
-
|
|
376
|
-
## Le config.yaml ecrit par NousHermesRunner (exemple sniperbot_analyst)
|
|
377
|
-
|
|
378
|
-
```yaml
|
|
379
|
-
mcp_servers:
|
|
380
|
-
memory-server:
|
|
381
|
-
url: "http://localhost:3099/mcp"
|
|
382
|
-
discord-server:
|
|
383
|
-
url: "http://localhost:3141/mcp"
|
|
384
|
-
x-mcp-server:
|
|
385
|
-
url: "http://localhost:3142/mcp"
|
|
386
|
-
postgresql-server:
|
|
387
|
-
url: "http://localhost:5433/mcp"
|
|
388
|
-
|
|
389
|
-
model:
|
|
390
|
-
default: glm-5.
|
|
391
|
-
provider: z-ai
|
|
392
|
-
|
|
393
|
-
tts:
|
|
394
|
-
provider: elevenlabs
|
|
395
|
-
voice: charlie
|
|
396
|
-
voice_id: IKne3meq5aSn9XLyUdCD
|
|
397
|
-
model: eleven_multilingual_v2
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
Ce config est ecrit dans `.overmind/hermes/agent_<name>/.hermes/config.yaml` a chaque run. Les valeurs viennent de `settings_<agent>.json` + defaults.
|
|
401
|
-
|
|
402
|
-
---
|
|
403
|
-
|
|
404
|
-
## Checklist pour ajouter un nouveau provider
|
|
405
|
-
|
|
406
|
-
1. **Verifier le ProviderConfig** dans `hermes-agent/hermes_cli/auth.py`
|
|
407
|
-
- Verifier `api_key_env_vars` (les vars que Hermes cherche)
|
|
408
|
-
- Verifier `inference_base_url` (URL par defaut)
|
|
409
|
-
- Verifier `base_url_env_var` (optionnel, surcharge URL)
|
|
410
|
-
|
|
411
|
-
2. **Ajouter dans Workflow/.env**
|
|
412
|
-
```bash
|
|
413
|
-
MAISON_API_KEY=cle_api_du_fournisseur
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
3. **Ajouter dans settings_[agent].json**
|
|
417
|
-
```json
|
|
418
|
-
{
|
|
419
|
-
"env": {
|
|
420
|
-
"ANTHROPIC_AUTH_TOKEN": "$MAISON_API_KEY",
|
|
421
|
-
"ANTHROPIC_BASE_URL": "https://api.fournisseur.com/v1",
|
|
422
|
-
"ANTHROPIC_MODEL": "model-name"
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
4. **Verifier auth.json** — apres premiere utilisation, Hermes stocke le token avec status.
|
|
428
|
-
- Si `exhausted` → Hermes skip ce provider automatiquement
|
|
429
|
-
- Si `ok` → utilise le token
|
|
430
|
-
|
|
431
|
-
5. **NE JAMAIS** faire de mapping `AUTRE_CHOSE_API_KEY → OPENROUTER_API_KEY` — ca force OpenRouter.
|
|
432
|
-
|
|
433
|
-
6. **Pour eviter OpenRouter:** pas de `OPENROUTER_API_KEY` dans `HERMES_HOME/.env`
|
|
434
|
-
|
|
435
|
-
---
|
|
436
|
-
|
|
437
|
-
## Resume
|
|
438
|
-
|
|
439
|
-
| Tu veux... | Utilise ces vars |
|
|
440
|
-
|---|---|
|
|
441
|
-
| Z.AI (glm-5.
|
|
442
|
-
| Z.AI secondary (token Y) | `ANTHROPIC_AUTH_TOKEN_Y` dans `.env` + settings `$ANTHROPIC_AUTH_TOKEN_Y` |
|
|
443
|
-
| MiniMax CN | `MINIMAX_CN_API_KEY` dans `.env` + settings `$MINIMAX_CN_API_KEY` |
|
|
444
|
-
| Embeddings OpenRouter | `OVERMIND_EMBEDDING_KEY` (pour embeddings, PAS LLM) |
|
|
445
|
-
| Eviter OpenRouter LLM | Pas de `OPENROUTER_API_KEY` dans `HERMES_HOME/.env` |
|
|
446
|
-
|
|
447
|
-
---
|
|
448
|
-
|
|
449
|
-
## Gemini / @google/gemini-cli (id: `gemini`)
|
|
450
|
-
|
|
451
|
-
Le runner `gemini` utilise **`@google/gemini-cli`** (npm, v0.43.0) en headless mode.
|
|
452
|
-
Le CLI est installé via `npm install -g @google/gemini-cli` et disponible dans le PATH.
|
|
453
|
-
|
|
454
|
-
### Installation
|
|
455
|
-
|
|
456
|
-
```bash
|
|
457
|
-
npm install -g @google/gemini-cli
|
|
458
|
-
gemini --version # → 0.43.0
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
### Flags CLI utilisés
|
|
462
|
-
|
|
463
|
-
| Flag | Valeur | Rôle |
|
|
464
|
-
|---|---|---|
|
|
465
|
-
| `-p` / `--prompt` | prompt text | Mode headless (non-interactif) |
|
|
466
|
-
| `--approval-mode` | `yolo` | Auto-approve tous les outils |
|
|
467
|
-
| `--session-id` | UUID | Session persistante entre appels |
|
|
468
|
-
| `--acp` | (flag) | Active le protocol agent (ACP) |
|
|
469
|
-
| `--model` | `antigravity/<MODE>` | Passe le mode Antigravity comme contexte |
|
|
470
|
-
| `--output-format` | `json` | Output structuré pour parser session_id |
|
|
471
|
-
|
|
472
|
-
### Commandes equivalents (CLI direct)
|
|
473
|
-
|
|
474
|
-
```bash
|
|
475
|
-
# Test quick
|
|
476
|
-
gemini -p "Dis-moi bonjour" --approval-mode yolo
|
|
477
|
-
|
|
478
|
-
# Avec session
|
|
479
|
-
gemini -p "Analyse ce code" --approval-mode yolo --session-id <uuid> --acp
|
|
480
|
-
|
|
481
|
-
# Mode PLAN
|
|
482
|
-
gemini -p "Planifie cette tache" --model antigravity/PLAN --approval-mode yolo --acp
|
|
483
|
-
|
|
484
|
-
# List sessions
|
|
485
|
-
gemini --list-sessions
|
|
486
|
-
```
|
|
487
|
-
|
|
488
|
-
### Modes Antigravity (parametre `mode`)
|
|
489
|
-
|
|
490
|
-
Le mode est passe via `--model antigravity/<MODE>` pour donner du contexte au modele.
|
|
491
|
-
|
|
492
|
-
|| Mode | Usage |
|
|
493
|
-
|---|---|
|
|
494
|
-
| `GENERAL` | Mode par defaut, taches polyvalentes |
|
|
495
|
-
| `CONTEXT_CHECK` | Verification de contexte code |
|
|
496
|
-
| `PLAN` | Planification de taches complexes |
|
|
497
|
-
| `COMMAND` | Execution de commandes shell |
|
|
498
|
-
| `CASCADE` | Execution en cascade multi-agents |
|
|
499
|
-
| `EVAL` | Evaluation et revue de code |
|
|
500
|
-
| `ANTIGRAVITY_REVIEW` | Revue automatique Antigravity |
|
|
501
|
-
| `MQUERY` | Recherche multi-source |
|
|
502
|
-
| `COMMIT_MESSAGE` | Generation de messages de commit |
|
|
503
|
-
| `CHECKPOINT` | Sauvegarde de checkpoint |
|
|
504
|
-
| `FAST_APPLY` | Application rapide de patches |
|
|
505
|
-
|
|
506
|
-
### Utilisation Overmind (run_agent)
|
|
507
|
-
|
|
508
|
-
```typescript
|
|
509
|
-
// run_agent avec runner: 'gemini'
|
|
510
|
-
const result = await runAgent({
|
|
511
|
-
runner: 'gemini', // GeminiRunner → gemini CLI npm
|
|
512
|
-
prompt: 'Analyse ce code',
|
|
513
|
-
agentName: 'expert_python',
|
|
514
|
-
mode: 'GENERAL', // GENERAL, PLAN, COMMAND, CASCADE, EVAL, etc.
|
|
515
|
-
autoResume: false,
|
|
516
|
-
configPath: './Workflow',
|
|
517
|
-
});
|
|
518
|
-
|
|
519
|
-
// ou directement via run_gemini.ts
|
|
520
|
-
const result = await runGeminiAgent({
|
|
521
|
-
prompt: '...',
|
|
522
|
-
mode: 'PLAN',
|
|
523
|
-
});
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
### Configuration agent
|
|
527
|
-
|
|
528
|
-
Chaque agent stocke sa config dans `.antigravity/agent_<nom>/`:
|
|
529
|
-
- `mcp.json` — serveurs MCP actifs (copies depuis settings_<agent>.json)
|
|
530
|
-
- Session store — sessions persistees
|
|
531
|
-
|
|
532
|
-
### Verification installation
|
|
533
|
-
|
|
534
|
-
```bash
|
|
535
|
-
gemini --version
|
|
536
|
-
# → 0.43.0
|
|
537
|
-
|
|
538
|
-
gemini mcp list
|
|
539
|
-
# → liste les MCP servers configures
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
### Erreurs connues
|
|
543
|
-
|
|
544
|
-
| Erreur | Cause | Fix |
|
|
545
|
-
|---|---|---|
|
|
546
|
-
| `GEMINI_CLI_NOT_INSTALLED` | `@google/gemini-cli` pas dans le PATH | `npm install -g @google/gemini-cli` |
|
|
547
|
-
| `EXIT_CODE_1` | Session invalide ou prompt rejete | Retry sans sessionId |
|
|
548
|
-
| `TIMEOUT` | Reponse > 15min | Augmente `CONFIG.TIMEOUT_MS` |
|
|
549
|
-
|
|
550
|
-
### Ce qui a change (historique)
|
|
551
|
-
|
|
552
|
-
|| Avant (session 2025) | Maintenant |
|
|
553
|
-
|---|---|---|
|
|
554
|
-
| Spawn `language_server_windows_x64.exe` avec flags inexistants | Spawn `gemini` (npm bin) avec flags reels |
|
|
555
|
-
| `--mode --prompt-file --session --output-format` (flags Go inexistants) | `-p --approval-mode yolo --session-id --acp --model --output-format json` |
|
|
556
|
-
| Auth via OAuth interne Antigravity IDE | Auth via Google account du CLI npm |
|
|
1
|
+
# Hermes x Overmind — Config Provider Map
|
|
2
|
+
|
|
3
|
+
## Ordre de resolution (qui gagne, qui perd)
|
|
4
|
+
|
|
5
|
+
Chaque variable suit cette priorite (la premiere gagne):
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
process.env (env du parent, herite par le spawn)
|
|
9
|
+
↓
|
|
10
|
+
Workflow/.env (~/.env)
|
|
11
|
+
↓
|
|
12
|
+
settings_[agent].json → env (apres interpolation $VAR par process.env)
|
|
13
|
+
↓
|
|
14
|
+
HERMES_HOME/.env (~/.hermes/.env) ← DERNIER MOT
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Detail du code** (`NousHermesRunner.ts` l.268-456):
|
|
18
|
+
1. `agentCustomEnv = { ...process.env, ...settings.env }` (line 268 puis 384)
|
|
19
|
+
2. Puis lit `overmindHermesSubPath/.env` (le `.hermes/.env` de l'agent) et fait `agentCustomEnv[key] = value` (line 437-456) — ce qui OVERRIDE tout ce qui precede.
|
|
20
|
+
3. Finalement ecrit ce `agentCustomEnv` dans le `.env` final de l'agent (line 722-732) avec dedup sur les cles `*api_key` / `*auth_token`.
|
|
21
|
+
|
|
22
|
+
Donc le `.hermes/.env` de l'agent a **toujours le dernier mot**. Si tu mets `MINIMAX_API_KEY=*** dans le .hermes/.env, il ecrase `MINIMAX_API_KEY` du process.env et du settings.
|
|
23
|
+
|
|
24
|
+
**MAIS** pour `OPENROUTER_API_KEY` uniquement:
|
|
25
|
+
- Hermes lit d'abord `HERMES_HOME/.env` puis `os.environ`
|
|
26
|
+
- Si present dans `auth.json` avec status `exhausted` → skip
|
|
27
|
+
- Si present dans `HERMES_HOME/.env` (meme vide `""`) → **PREND LA PRIORITE sur process.env**
|
|
28
|
+
|
|
29
|
+
**MAIS** pour tous les autres providers (zai, minimax-cn, etc.):
|
|
30
|
+
- Hermes lit `HERMES_HOME/.env` → si vide/null → lit `os.environ`
|
|
31
|
+
- `os.environ` contient tout ce que le parent a passe (donc le `.env` du Workflow)
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Les 5 fichiers cles
|
|
36
|
+
|
|
37
|
+
| Fichier | Role |
|
|
38
|
+
|---|---|
|
|
39
|
+
| `HERMES_HOME/.env` | API keys globales Hermes (fallback) |
|
|
40
|
+
| `Workflow/.env` | Variables du workflow (DB, tokens, etc.) |
|
|
41
|
+
| `settings_[agent].json` | Config par agent (model, provider, tokens, MCP) |
|
|
42
|
+
| `HERMES_HOME/.hermes/config.yaml` | Config systeme Hermes (model.default, provider, etc.) |
|
|
43
|
+
| `HERMES_HOME/auth.json` | Credential pool — status des tokens (ok/exhausted), URLs par provider |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Les 2 endpoints Z.AI (DECOUVERTE CRITIQUE)
|
|
48
|
+
|
|
49
|
+
Z.AI a **deux endpoints distincts** — confusion entre les deux causait des erreurs 402:
|
|
50
|
+
|
|
51
|
+
| Endpoint | URL | Usage |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| **Coding** (celui qu'il faut) | `https://api.z.ai/api/coding/paas/v4` | Inference LLM (Hermes, Overmind) |
|
|
54
|
+
| **Non-coding** (ancien, different billing) | `https://api.z.ai/api/paas/v4` | Autre chose (pas le meme systeme de facturation) |
|
|
55
|
+
|
|
56
|
+
**Comment le credential pool est seed:**
|
|
57
|
+
|
|
58
|
+
| Source dans .env | Cle dans auth.json | base_url assignee |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| `ZAI_ANTHROPIC_FALLBACK_KEY` | `zai[0].access_token` | `https://api.z.ai/api/coding/paas/v4` ✅ |
|
|
61
|
+
| `Z_AI_API_KEY` | `zai[1].access_token` | `https://api.z.ai/api/paas/v4` ❌ (ancien) |
|
|
62
|
+
|
|
63
|
+
Le premier entry (priority 0) est utilise en premier. C'est celui qui est seed par `writeAuthJson()` dans `NousHermesRunner.ts` → `ZAI_ANTHROPIC_FALLBACK_KEY`.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Provider → Ce qu'Hermes attend
|
|
68
|
+
|
|
69
|
+
### Z.AI (id: `zai`)
|
|
70
|
+
|
|
71
|
+
| Param | Valeur attendue | Source dans Hermes |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| Provider ID | `zai` | config.yaml ou settings |
|
|
74
|
+
| API Key | `ZAI_ANTHROPIC_FALLBACK_KEY` (cle primaire) ou `Z_AI_API_KEY` (fallback ancien) | `HERMES_HOME/.env` → `os.environ` |
|
|
75
|
+
| Base URL | `https://api.z.ai/api/coding/paas/v4` | credential pool (seed par writeAuthJson) |
|
|
76
|
+
| Model | `glm-5.2` | settings `env.ANTHROPIC_MODEL` |
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
// settings_[agent].json — Z.AI correct
|
|
80
|
+
{
|
|
81
|
+
"env": {
|
|
82
|
+
"ANTHROPIC_AUTH_TOKEN": "$ZAI_ANTHROPIC_FALLBACK_KEY",
|
|
83
|
+
"ANTHROPIC_BASE_URL": "https://api.z.ai/api/coding/paas/v4",
|
|
84
|
+
"ANTHROPIC_MODEL": "glm-5.2"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# .env minimal pour Z.AI
|
|
91
|
+
ZAI_ANTHROPIC_FALLBACK_KEY=<your-zai-key-here>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Le credential pool `auth.json` est ecrit par `writeAuthJson()` dans `NousHermesRunner.ts`. La cle `ZAI_ANTHROPIC_FALLBACK_KEY` est envoyee par `agentCustomEnv` → Hermes seed le credential pool avec le bon endpoint.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
### Z.AI Multi-Token (E/Y)
|
|
99
|
+
|
|
100
|
+
Deamon a 2 tokens Z.AI (E=primary, Y=secondary). Le credential pool peut contenir les deux:
|
|
101
|
+
|
|
102
|
+
| Token | Label dans auth.json | Cle dans .env |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| Primary | `ANTHROPIC_AUTH_TOKEN_E` | `ANTHROPIC_AUTH_TOKEN_E` = `<your-zai-token-E>` |
|
|
105
|
+
| Secondary | `ANTHROPIC_AUTH_TOKEN_Y` | `ANTHROPIC_AUTH_TOKEN_Y` = `<your-zai-token-Y>` |
|
|
106
|
+
|
|
107
|
+
Pour qu'un agent utilise le token Y (secondary) au lieu de E (primary), le settings doit utiliser `$ANTHROPIC_AUTH_TOKEN_Y` au lieu de `$ANTHROPIC_AUTH_TOKEN_E`.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### MiniMax CN (id: `minimax-cn`)
|
|
112
|
+
|
|
113
|
+
| Param | Valeur attendue | Source dans Hermes |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| Provider ID | `minimax-cn` | config.yaml ou settings |
|
|
116
|
+
| API Key | `MINIMAX_CN_API_KEY` **uniquement** | `HERMES_HOME/.env` → `os.environ` |
|
|
117
|
+
| Base URL | `https://api.minimaxi.com/anthropic` | hardcoded dans ProviderConfig |
|
|
118
|
+
| Model | `MiniMax-M3` | settings `env.ANTHROPIC_MODEL` |
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
// settings_[agent].json — MiniMax correct
|
|
122
|
+
{
|
|
123
|
+
"env": {
|
|
124
|
+
"ANTHROPIC_AUTH_TOKEN": "$MINIMAX_CN_API_KEY",
|
|
125
|
+
"ANTHROPIC_BASE_URL": "https://api.minimaxi.com/anthropic",
|
|
126
|
+
"ANTHROPIC_MODEL": "MiniMax-M3"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# .env minimal pour MiniMax CN
|
|
133
|
+
MINIMAX_CN_API_KEY=ton_token_minimax_ici
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**auth.json** stocke sous `MINIMAX_CN_API_KEY`.
|
|
137
|
+
|
|
138
|
+
#### MiniMax CN par défaut (convention)
|
|
139
|
+
|
|
140
|
+
Le préfixe `sk-cp-` est partagé entre MiniMax GLOBAL (`api.minimax.com`) et
|
|
141
|
+
MiniMax CN (`api.minimaxi.com`). L'URL est le seul signal qui disambiguïse.
|
|
142
|
+
Pour les setups où TOUS les tokens MiniMax sont CN (cas le plus commun),
|
|
143
|
+
le runner a un fallback par défaut : quand un token `sk-cp-*` est détecté
|
|
144
|
+
sans URL explicite, on bascule sur CN.
|
|
145
|
+
|
|
146
|
+
Controlable via env var :
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# Défaut (recommandé pour les setups CN-only)
|
|
150
|
+
OVERMIND_MINIMAX_DEFAULT=cn # sk-cp-* sans URL → minimax-cn
|
|
151
|
+
|
|
152
|
+
# Pour les setups GLOBAL-only
|
|
153
|
+
OVERMIND_MINIMAX_DEFAULT=global # sk-cp-* sans URL → minimax
|
|
154
|
+
|
|
155
|
+
# Strict mode (jamais d'inference, URL obligatoire)
|
|
156
|
+
OVERMIND_MINIMAX_DEFAULT=auto # sk-cp-* sans URL → minimax (no override)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Si une URL explicite est présente dans `ANTHROPIC_BASE_URL`, elle gagne
|
|
160
|
+
toujours sur `OVERMIND_MINIMAX_DEFAULT`.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
### OpenRouter — BANNIR pour LLM
|
|
165
|
+
|
|
166
|
+
| Param | Valeur attendue | Source |
|
|
167
|
+
|---|---|---|
|
|
168
|
+
| Provider ID | — | **Ne PAS utiliser** |
|
|
169
|
+
| API Key | `OPENROUTER_API_KEY` | `HERMES_HOME/.env` → `os.environ` |
|
|
170
|
+
| Base URL | `https://openrouter.ai/api/v1` | hardcoded |
|
|
171
|
+
| Guardrail | — | Force 404 si active |
|
|
172
|
+
|
|
173
|
+
**PROBLEME:** Si `OPENROUTER_API_KEY` est present (meme dans `OVERMIND_EMBEDDING_KEY` route via NousHermesRunner), Hermes le detecte et tente OpenRouter pour l'inference.
|
|
174
|
+
|
|
175
|
+
**auth.json** a une entree OpenRouter — si le status est `exhausted`, Hermes ne retry plus mais peut quand meme picker le provider "openrouter" dans le credential pool.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Ne PAS passer --provider au CLI Hermes (NOUVEAU en 2.8.28)
|
|
180
|
+
|
|
181
|
+
Le runner Overmind **ne passe plus** le flag `--provider` au CLI Hermes.
|
|
182
|
+
Découverte empirique (le `Hermes-MiniMax-2.bat` du bureau marche mais
|
|
183
|
+
le sniperbot échoue) :
|
|
184
|
+
|
|
185
|
+
| Commande | Résultat |
|
|
186
|
+
|---|---|
|
|
187
|
+
| `hermes chat -q --provider minimax-cn ...` | **401** (bug plugin upstream) |
|
|
188
|
+
| `hermes chat --yolo` (sans --provider) | **200 OK** |
|
|
189
|
+
|
|
190
|
+
**Cause** : le flag `--provider` explicite active un code path buggé
|
|
191
|
+
dans le plugin Hermes upstream (`hermes-agent/plugins/model-providers/minimax/`)
|
|
192
|
+
qui envoie un format d'auth header rejeté par `api.minimaxi.com`.
|
|
193
|
+
|
|
194
|
+
**Fix appliqué** : le runner retire `--provider` de `cleanArgs` mais
|
|
195
|
+
loggue le `resolvedProvider` à INFO pour debug. Hermes auto-détecte
|
|
196
|
+
le bon provider depuis l'env var :
|
|
197
|
+
- `MINIMAX_CN_API_KEY` → plugin `minimax-cn`
|
|
198
|
+
- `MINIMAX_API_KEY` → plugin `minimax` (GLOBAL)
|
|
199
|
+
- `ZAI_ANTHROPIC_FALLBACK_KEY` ou `GLM_API_KEY` → plugin `zai`
|
|
200
|
+
- `ANTHROPIC_AUTH_TOKEN` avec préfixe `sk-ant-` → plugin `anthropic`
|
|
201
|
+
|
|
202
|
+
`ANTHROPIC_BASE_URL` et `ANTHROPIC_MODEL` sont toujours passés, donc
|
|
203
|
+
Hermes a assez d'info pour ne pas se tromper.
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
## HERMES_HOME resolution (multi-OS, multi-install)
|
|
207
|
+
|
|
208
|
+
Chaque agent Hermes a son propre HERMES_HOME. Le path est resolu de maniere
|
|
209
|
+
deterministe par `getAgentHermesHome(agentName)` dans `src/lib/config.ts`.
|
|
210
|
+
|
|
211
|
+
Ordre de resolution (la premiere gagne):
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
OVERMIND_AGENT_HOME (env var, set par l'install ou systemd)
|
|
215
|
+
↓
|
|
216
|
+
<workspace>/.overmind/hermes/agent_<name>/.hermes (legacy, si deja existant)
|
|
217
|
+
↓
|
|
218
|
+
$HOME/.overmind/hermes/agent_<name>/.hermes (Linux/Mac sudo npm -g)
|
|
219
|
+
%LOCALAPPDATA%\overmind\hermes\agent_<name>\.hermes (Windows npm -g)
|
|
220
|
+
%USERPROFILE%\overmind\hermes\agent_<name>\.hermes (Windows fallback)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Pour un agent nomme `sniperbot_analyst`:
|
|
224
|
+
- Dev local (workspace = `~/overmind-mcp`):
|
|
225
|
+
`Workflow\.overmind\hermes\agent_sniperbot_analyst\.hermes` (si deja cree)
|
|
226
|
+
- Prod Linux: `~/.overmind/hermes/agent_sniperbot_analyst/.hermes`
|
|
227
|
+
- Prod Windows: `%LOCALAPPDATA%\overmind\hermes\agent_sniperbot_analyst\.hermes`
|
|
228
|
+
|
|
229
|
+
**Pourquoi c'est important**: avant, le runner Overmind calculait HERMES_HOME
|
|
230
|
+
depuis `process.cwd()`. Si le sniper etait lance depuis `~/overmind-mcp/`
|
|
231
|
+
et le runner depuis `Workflow\`, ils lisaient des `.hermes/.env` differents
|
|
232
|
+
et ecrivaient dans des `auth.json` differents. Maintenant, c'est cwd-independent.
|
|
233
|
+
|
|
234
|
+
Pour forcer un chemin explicite (ex: deploy Docker), set:
|
|
235
|
+
```bash
|
|
236
|
+
export OVERMIND_AGENT_HOME=/var/lib/overmind/hermes
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
## Comment Hermes decide quel provider utiliser
|
|
241
|
+
|
|
242
|
+
Il y a DEUX niveaux de decision:
|
|
243
|
+
|
|
244
|
+
### Niveau 1: Overmind runner (avant spawn)
|
|
245
|
+
|
|
246
|
+
`NousHermesRunner.writeAuthJson()` (l.782-918) vote entre 3 signaux pour determiner le `effectiveProvider` qui sera seed dans `auth.json` et le `.env` de l'agent:
|
|
247
|
+
|
|
248
|
+
1. **Token prefix** (le plus fiable) — `detectTokenProvider()` reconnait:
|
|
249
|
+
- `sk-cp-...` ou `sk-mm-...` → `minimax`
|
|
250
|
+
- `32hex.32hex` ou 32-char hex → `zai`
|
|
251
|
+
- `sk-ant-...` → `anthropic`
|
|
252
|
+
- `sk-or-...` → `openrouter` (mais BLOQUE pour LLM par la suite)
|
|
253
|
+
- `sk-...` (autre) → `openai`
|
|
254
|
+
2. **BASE_URL** (tres fiable, plus specifique que le token pour CN vs GLOBAL) — `api.minimaxi.com` → `minimax-cn`, `api.minimax.com` → `minimax`, `api.z.ai/api/coding/paas/v4` → `zai`, `anthropic.com` → `anthropic`, `openai.com` → `openai`.
|
|
255
|
+
3. **ANTHROPIC_PROVIDER** hint du settings (le moins fiable).
|
|
256
|
+
|
|
257
|
+
**Cas special CN vs GLOBAL**: `sk-cp-` est ambigu entre `minimax` et `minimax-cn` (meme prefix). Si l'URL dit `minimaxi` (avec le `i`), c'est CN. Si `minimax` (sans le `i`), c'est GLOBAL. **L'URL gagne dans ce cas precis** parce qu'elle est la seule a desambiguïser.
|
|
258
|
+
|
|
259
|
+
### Niveau 2: Hermes upstream (apres spawn)
|
|
260
|
+
|
|
261
|
+
Hermes relit son `auth.json` + `HERMES_HOME/.env` + `os.environ` avec sa propre logique (dans `hermes_cli/auth.py`):
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
1. Si `provider` explicite dans config.yaml → utilise ce provider
|
|
265
|
+
2. Sinon si `ANTHROPIC_BASE_URL` contient openrouter → "openrouter"
|
|
266
|
+
3. Sinon lit model name → compare avec model_defaults par provider
|
|
267
|
+
- "glm-*" → "zai"
|
|
268
|
+
- "MiniMax-*" → "minimax-cn"
|
|
269
|
+
4. Sinon fallback: model.default dans config.yaml
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Le runner a deja vote au Niveau 1** — donc ce que tu mets dans `auth.json` (via `writeAuthJson()`) determine ce qu'Hermes verra au Niveau 2. Si le runner a seed `minimax-cn` mais que `config.yaml` dit `provider: minimax`, Hermes va probablement se plaindre. **Garde les deux alignes** ou laisse le runner ecrire le `config.yaml` (ce qu'il fait deja a chaque run).
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Comment NousHermesRunner passe les vars a Hermes
|
|
277
|
+
|
|
278
|
+
Le runner lit `settings_[agent].json` → applique `interpolateEnvVars()` qui remplace `$VAR` par `process.env[VAR]` → envoie le tout dans `agentCustomEnv` au processus Hermes.
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
// Ce que NousHermesRunner.ts passe a Hermes (agentCustomEnv)
|
|
282
|
+
const agentCustomEnv = {
|
|
283
|
+
...process.env, // HERMES_HOME/.env + Workflow/.env fusionnes
|
|
284
|
+
PYTHONIOENCODING: 'utf-8',
|
|
285
|
+
OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY || '', // VIDE (fixe)
|
|
286
|
+
NVIDIA_API_KEY: process.env.NVIDIA_API_KEY || process.env.NVAPI_KEY,
|
|
287
|
+
ANTHROPIC_AUTH_TOKEN: s.env.ANTHROPIC_AUTH_TOKEN, // interpolate
|
|
288
|
+
ANTHROPIC_BASE_URL: s.env.ANTHROPIC_BASE_URL, // interpolate
|
|
289
|
+
ANTHROPIC_MODEL: s.env.ANTHROPIC_MODEL, // interpolate
|
|
290
|
+
};
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Puis lance Hermes avec `--env-file` pour discord_llm + Workflow `.env` (via startpipeline.js).
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Le probleme de OPENROUTER_API_KEY
|
|
298
|
+
|
|
299
|
+
**AVANT le fix:**
|
|
300
|
+
```typescript
|
|
301
|
+
OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY || process.env.OVERMIND_EMBEDDING_KEY,
|
|
302
|
+
```
|
|
303
|
+
→ Si `OPENROUTER_API_KEY` vide mais `OVERMIND_EMBEDDING_KEY` present → passe quand meme une cle OpenRouter a Hermes → Hermes detecte `OPENROUTER_API_KEY` → tente OpenRouter → 404 guardrail.
|
|
304
|
+
|
|
305
|
+
**APRES le fix:**
|
|
306
|
+
```typescript
|
|
307
|
+
OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY || '',
|
|
308
|
+
```
|
|
309
|
+
→ `OVERMIND_EMBEDDING_KEY` n'est plus redirige. Si `OPENROUTER_API_KEY` absent du `.env`, Hermes recoit string vide et ne pick pas OpenRouter.
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Comment Hermes obtient la API Key (le vrai flux)
|
|
314
|
+
|
|
315
|
+
Le `ANTHROPIC_AUTH_TOKEN` dans `settings.json` **ne passe pas directement** dans le body de la requete API. Hermes utilise son propre credential pool:
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
settings_[agent].json
|
|
319
|
+
"env": {
|
|
320
|
+
"ANTHROPIC_AUTH_TOKEN": "$ZAI_ANTHROPIC_FALLBACK_KEY", ← Runner remplace $VAR → "token_reel"
|
|
321
|
+
"ANTHROPIC_BASE_URL": "https://api.z.ai/api/coding/paas/v4",
|
|
322
|
+
"ANTHROPIC_MODEL": "glm-5.2"
|
|
323
|
+
}
|
|
324
|
+
↓ (interpolateEnvVars par NousHermesRunner)
|
|
325
|
+
agentCustomEnv envoye a Hermes:
|
|
326
|
+
ANTHROPIC_AUTH_TOKEN=token_reel
|
|
327
|
+
ANTHROPIC_BASE_URL=https://api.z.ai/api/coding/paas/v4
|
|
328
|
+
ANTHROPIC_MODEL=glm-5.2
|
|
329
|
+
|
|
330
|
+
MAIS Hermes ne lit PAS ANTHROPIC_AUTH_TOKEN directement.
|
|
331
|
+
Hermes lit le CREDENTIAL POOL (auth.json) + les .env vars listees dans api_key_env_vars.
|
|
332
|
+
|
|
333
|
+
Credential pool est seed par:
|
|
334
|
+
ZAI_ANTHROPIC_FALLBACK_KEY → "zai" avec base_url coding ✅
|
|
335
|
+
Z_AI_API_KEY → "zai" avec base_url non-coding (ancien)
|
|
336
|
+
MINIMAX_CN_API_KEY → "minimax-cn"
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
Le `$VAR` dans `ANTHROPIC_AUTH_TOKEN` est juste une convenience pour que le token traverse le runner et arrive dans `process.env` du subprocess Hermes. C'est `process.env.ZAI_ANTHROPIC_FALLBACK_KEY` qui seed le credential pool.
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## Le flow complet (Z.AI par exemple)
|
|
344
|
+
|
|
345
|
+
1. `Workflow/.env` contient `ZAI_ANTHROPIC_FALLBACK_KEY=<TOKEN>`
|
|
346
|
+
2. `startpipeline.js` charge `.env` → `process.env.ZAI_ANTHROPIC_FALLBACK_KEY`
|
|
347
|
+
3. ` NousHermesRunner` lit `settings_zai.json` → `interpolateEnvVars()`
|
|
348
|
+
- `$ZAI_ANTHROPIC_FALLBACK_KEY` → `process.env["ZAI_ANTHROPIC_FALLBACK_KEY"]` → `"<TOKEN>"`
|
|
349
|
+
- `ANTHROPIC_AUTH_TOKEN="<TOKEN>"` (valeur concrete maintenant)
|
|
350
|
+
4. `agentCustomEnv` envoye a Hermes:
|
|
351
|
+
- `ANTHROPIC_AUTH_TOKEN=<TOKEN>`
|
|
352
|
+
- `ANTHROPIC_BASE_URL=https://api.z.ai/api/coding/paas/v4`
|
|
353
|
+
- `ANTHROPIC_MODEL=glm-5.2`
|
|
354
|
+
5. Hermes fait son propre lookup:
|
|
355
|
+
- `load_pool("zai")` → `_resolve_api_key_provider_secret("zai")`
|
|
356
|
+
- Cherche `ZAI_ANTHROPIC_FALLBACK_KEY` via `_get_env_prefer_dotenv()` dans `HERMES_HOME/.env` puis `os.environ`
|
|
357
|
+
- Trouve dans `os.environ` (herite du parent)
|
|
358
|
+
- `writeAuthJson()` ecrit dans `auth.json` avec base_url `https://api.z.ai/api/coding/paas/v4`
|
|
359
|
+
6. API call → utilise le credential pool entry pour `zai` avec le bon endpoint
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## OPENROUTER et Les Embeddings
|
|
364
|
+
|
|
365
|
+
**`OVERMIND_EMBEDDING_KEY`** = clef OpenRouter pour les **embeddings uniquement** (PostgresMemoryProvider du Workflow). Elle est dans le `.env` Overmind. Hermes n'a pas besoin de la voir pour l'LLM inference.
|
|
366
|
+
|
|
367
|
+
**NousHermesRunner ne doit jamais forwarder de clef OpenRouter a Hermes.** OpenRouter n'est pas un provider LLM dans ce setup. Si `OPENROUTER_API_KEY` arrive jusqu'a Hermes, il detecte la clef et tente OpenRouter pour l'inference → 404 guardrail.
|
|
368
|
+
|
|
369
|
+
**Fix applique:**
|
|
370
|
+
```typescript
|
|
371
|
+
OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY || '',
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## Le config.yaml ecrit par NousHermesRunner (exemple sniperbot_analyst)
|
|
377
|
+
|
|
378
|
+
```yaml
|
|
379
|
+
mcp_servers:
|
|
380
|
+
memory-server:
|
|
381
|
+
url: "http://localhost:3099/mcp"
|
|
382
|
+
discord-server:
|
|
383
|
+
url: "http://localhost:3141/mcp"
|
|
384
|
+
x-mcp-server:
|
|
385
|
+
url: "http://localhost:3142/mcp"
|
|
386
|
+
postgresql-server:
|
|
387
|
+
url: "http://localhost:5433/mcp"
|
|
388
|
+
|
|
389
|
+
model:
|
|
390
|
+
default: glm-5.2
|
|
391
|
+
provider: z-ai
|
|
392
|
+
|
|
393
|
+
tts:
|
|
394
|
+
provider: elevenlabs
|
|
395
|
+
voice: charlie
|
|
396
|
+
voice_id: IKne3meq5aSn9XLyUdCD
|
|
397
|
+
model: eleven_multilingual_v2
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Ce config est ecrit dans `.overmind/hermes/agent_<name>/.hermes/config.yaml` a chaque run. Les valeurs viennent de `settings_<agent>.json` + defaults.
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## Checklist pour ajouter un nouveau provider
|
|
405
|
+
|
|
406
|
+
1. **Verifier le ProviderConfig** dans `hermes-agent/hermes_cli/auth.py`
|
|
407
|
+
- Verifier `api_key_env_vars` (les vars que Hermes cherche)
|
|
408
|
+
- Verifier `inference_base_url` (URL par defaut)
|
|
409
|
+
- Verifier `base_url_env_var` (optionnel, surcharge URL)
|
|
410
|
+
|
|
411
|
+
2. **Ajouter dans Workflow/.env**
|
|
412
|
+
```bash
|
|
413
|
+
MAISON_API_KEY=cle_api_du_fournisseur
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
3. **Ajouter dans settings_[agent].json**
|
|
417
|
+
```json
|
|
418
|
+
{
|
|
419
|
+
"env": {
|
|
420
|
+
"ANTHROPIC_AUTH_TOKEN": "$MAISON_API_KEY",
|
|
421
|
+
"ANTHROPIC_BASE_URL": "https://api.fournisseur.com/v1",
|
|
422
|
+
"ANTHROPIC_MODEL": "model-name"
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
4. **Verifier auth.json** — apres premiere utilisation, Hermes stocke le token avec status.
|
|
428
|
+
- Si `exhausted` → Hermes skip ce provider automatiquement
|
|
429
|
+
- Si `ok` → utilise le token
|
|
430
|
+
|
|
431
|
+
5. **NE JAMAIS** faire de mapping `AUTRE_CHOSE_API_KEY → OPENROUTER_API_KEY` — ca force OpenRouter.
|
|
432
|
+
|
|
433
|
+
6. **Pour eviter OpenRouter:** pas de `OPENROUTER_API_KEY` dans `HERMES_HOME/.env`
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
## Resume
|
|
438
|
+
|
|
439
|
+
| Tu veux... | Utilise ces vars |
|
|
440
|
+
|---|---|
|
|
441
|
+
| Z.AI (glm-5.2) | `ZAI_ANTHROPIC_FALLBACK_KEY` dans `.env` + settings `$ZAI_ANTHROPIC_FALLBACK_KEY` |
|
|
442
|
+
| Z.AI secondary (token Y) | `ANTHROPIC_AUTH_TOKEN_Y` dans `.env` + settings `$ANTHROPIC_AUTH_TOKEN_Y` |
|
|
443
|
+
| MiniMax CN | `MINIMAX_CN_API_KEY` dans `.env` + settings `$MINIMAX_CN_API_KEY` |
|
|
444
|
+
| Embeddings OpenRouter | `OVERMIND_EMBEDDING_KEY` (pour embeddings, PAS LLM) |
|
|
445
|
+
| Eviter OpenRouter LLM | Pas de `OPENROUTER_API_KEY` dans `HERMES_HOME/.env` |
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## Gemini / @google/gemini-cli (id: `gemini`)
|
|
450
|
+
|
|
451
|
+
Le runner `gemini` utilise **`@google/gemini-cli`** (npm, v0.43.0) en headless mode.
|
|
452
|
+
Le CLI est installé via `npm install -g @google/gemini-cli` et disponible dans le PATH.
|
|
453
|
+
|
|
454
|
+
### Installation
|
|
455
|
+
|
|
456
|
+
```bash
|
|
457
|
+
npm install -g @google/gemini-cli
|
|
458
|
+
gemini --version # → 0.43.0
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Flags CLI utilisés
|
|
462
|
+
|
|
463
|
+
| Flag | Valeur | Rôle |
|
|
464
|
+
|---|---|---|
|
|
465
|
+
| `-p` / `--prompt` | prompt text | Mode headless (non-interactif) |
|
|
466
|
+
| `--approval-mode` | `yolo` | Auto-approve tous les outils |
|
|
467
|
+
| `--session-id` | UUID | Session persistante entre appels |
|
|
468
|
+
| `--acp` | (flag) | Active le protocol agent (ACP) |
|
|
469
|
+
| `--model` | `antigravity/<MODE>` | Passe le mode Antigravity comme contexte |
|
|
470
|
+
| `--output-format` | `json` | Output structuré pour parser session_id |
|
|
471
|
+
|
|
472
|
+
### Commandes equivalents (CLI direct)
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
# Test quick
|
|
476
|
+
gemini -p "Dis-moi bonjour" --approval-mode yolo
|
|
477
|
+
|
|
478
|
+
# Avec session
|
|
479
|
+
gemini -p "Analyse ce code" --approval-mode yolo --session-id <uuid> --acp
|
|
480
|
+
|
|
481
|
+
# Mode PLAN
|
|
482
|
+
gemini -p "Planifie cette tache" --model antigravity/PLAN --approval-mode yolo --acp
|
|
483
|
+
|
|
484
|
+
# List sessions
|
|
485
|
+
gemini --list-sessions
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### Modes Antigravity (parametre `mode`)
|
|
489
|
+
|
|
490
|
+
Le mode est passe via `--model antigravity/<MODE>` pour donner du contexte au modele.
|
|
491
|
+
|
|
492
|
+
|| Mode | Usage |
|
|
493
|
+
|---|---|
|
|
494
|
+
| `GENERAL` | Mode par defaut, taches polyvalentes |
|
|
495
|
+
| `CONTEXT_CHECK` | Verification de contexte code |
|
|
496
|
+
| `PLAN` | Planification de taches complexes |
|
|
497
|
+
| `COMMAND` | Execution de commandes shell |
|
|
498
|
+
| `CASCADE` | Execution en cascade multi-agents |
|
|
499
|
+
| `EVAL` | Evaluation et revue de code |
|
|
500
|
+
| `ANTIGRAVITY_REVIEW` | Revue automatique Antigravity |
|
|
501
|
+
| `MQUERY` | Recherche multi-source |
|
|
502
|
+
| `COMMIT_MESSAGE` | Generation de messages de commit |
|
|
503
|
+
| `CHECKPOINT` | Sauvegarde de checkpoint |
|
|
504
|
+
| `FAST_APPLY` | Application rapide de patches |
|
|
505
|
+
|
|
506
|
+
### Utilisation Overmind (run_agent)
|
|
507
|
+
|
|
508
|
+
```typescript
|
|
509
|
+
// run_agent avec runner: 'gemini'
|
|
510
|
+
const result = await runAgent({
|
|
511
|
+
runner: 'gemini', // GeminiRunner → gemini CLI npm
|
|
512
|
+
prompt: 'Analyse ce code',
|
|
513
|
+
agentName: 'expert_python',
|
|
514
|
+
mode: 'GENERAL', // GENERAL, PLAN, COMMAND, CASCADE, EVAL, etc.
|
|
515
|
+
autoResume: false,
|
|
516
|
+
configPath: './Workflow',
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
// ou directement via run_gemini.ts
|
|
520
|
+
const result = await runGeminiAgent({
|
|
521
|
+
prompt: '...',
|
|
522
|
+
mode: 'PLAN',
|
|
523
|
+
});
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### Configuration agent
|
|
527
|
+
|
|
528
|
+
Chaque agent stocke sa config dans `.antigravity/agent_<nom>/`:
|
|
529
|
+
- `mcp.json` — serveurs MCP actifs (copies depuis settings_<agent>.json)
|
|
530
|
+
- Session store — sessions persistees
|
|
531
|
+
|
|
532
|
+
### Verification installation
|
|
533
|
+
|
|
534
|
+
```bash
|
|
535
|
+
gemini --version
|
|
536
|
+
# → 0.43.0
|
|
537
|
+
|
|
538
|
+
gemini mcp list
|
|
539
|
+
# → liste les MCP servers configures
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### Erreurs connues
|
|
543
|
+
|
|
544
|
+
| Erreur | Cause | Fix |
|
|
545
|
+
|---|---|---|
|
|
546
|
+
| `GEMINI_CLI_NOT_INSTALLED` | `@google/gemini-cli` pas dans le PATH | `npm install -g @google/gemini-cli` |
|
|
547
|
+
| `EXIT_CODE_1` | Session invalide ou prompt rejete | Retry sans sessionId |
|
|
548
|
+
| `TIMEOUT` | Reponse > 15min | Augmente `CONFIG.TIMEOUT_MS` |
|
|
549
|
+
|
|
550
|
+
### Ce qui a change (historique)
|
|
551
|
+
|
|
552
|
+
|| Avant (session 2025) | Maintenant |
|
|
553
|
+
|---|---|---|
|
|
554
|
+
| Spawn `language_server_windows_x64.exe` avec flags inexistants | Spawn `gemini` (npm bin) avec flags reels |
|
|
555
|
+
| `--mode --prompt-file --session --output-format` (flags Go inexistants) | `-p --approval-mode yolo --session-id --acp --model --output-format json` |
|
|
556
|
+
| Auth via OAuth interne Antigravity IDE | Auth via Google account du CLI npm |
|
|
557
557
|
| Config `.antigravity/<agent>/` | Config `.antigravity/<agent>/` (MCP + sessions) |
|