overmind-mcp 2.8.27 → 2.8.30

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.
@@ -1,284 +1,306 @@
1
- LA SUBTILISATION — comment Overmind devine ton provider LLM à partir de ton token
2
- ==============================================================================
3
-
4
- Version: Overmind 2.8.27 (2026-06-07)
5
- Hermes requis: v0.16.0+
6
-
7
-
8
- Concept (1 phrase)
9
- ------------------
10
- Le runner Overmind ne te demande PAS quel provider tu utilises.
11
- Il LIT ton token, en déduit le préfixe, et MAPPE automatiquement
12
- vers le bon env var que le plugin provider de Hermes attend.
13
-
14
-
15
- Pourquoi ça existe
16
- -----------------
17
- Les tokens de providers LLM ont des préfixes distincts que tu ne
18
- connais peut-être pas :
19
-
20
- sk-cp-... -> MiniMax (env: MINIMAX_API_KEY, MINIMAX_CN_API_KEY)
21
- sk-mm-... -> MiniMax (variante)
22
- sk-ant-... -> Anthropic (env: ANTHROPIC_AUTH_TOKEN)
23
- sk-or-... -> OpenRouter (BLOQUÉ pour LLM, embeddings only)
24
- sk-... -> OpenAI (env: OPENAI_API_KEY)
25
- 32hex.32hex -> Z.AI / GLM (env: ZAI_ANTHROPIC_FALLBACK_KEY, GLM_API_KEY)
26
- 32hex -> Z.AI (variante single-block)
27
- 16hex+ -> Z.AI (catch-all hex)
28
-
29
-
30
- CAS SPÉCIAL : sk-cp- est ambigu entre MiniMax GLOBAL et MiniMax CN
31
- ------------------------------------------------------------------
32
- Meme prefix. Pour desambiguïser, le runner regarde l'ANTHROPIC_BASE_URL :
33
- - api.minimaxi.com (avec le i) -> minimax-cn
34
- - api.minimax.com (sans le i) -> minimax (GLOBAL)
35
- L'URL gagne dans ce cas parce qu'elle est la seule a desambiguïser.
36
-
37
- Ce que tu mets dans settings_<agent>.json :
38
-
39
- {
40
- "env": {
41
- "ANTHROPIC_AUTH_TOKEN": "$ANTHROPIC_AUTH_TOKEN_2",
42
- "ANTHROPIC_BASE_URL": "https://api.minimaxi.com/anthropic",
43
- "ANTHROPIC_MODEL": "MiniMax-M3",
44
- "ANTHROPIC_PROVIDER": "minimax-cn"
45
- }
46
- }
47
-
48
- Le runner voit ANTHROPIC_BASE_URL contient "minimaxi" -> effectiveProvider = minimax-cn.
49
- Il seed auth.json avec MINIMAX_CN_API_KEY et the bon endpoint.
50
- Hermes route vers le plugin minimax-cn.
51
-
52
-
53
- CONVENTION : MiniMax = CN par defaut
54
- -------------------------------------
55
- Le prefixe sk-cp- est partage entre MiniMax GLOBAL (api.minimax.com) et
56
- MiniMax CN (api.minimaxi.com). L'URL est le seul signal qui desambigüise.
57
-
58
- Pour les setups ou TOUS les tokens MiniMax sont CN (le cas le plus commun),
59
- le runner a un fallback par defaut : quand un token sk-cp-* est detecte
60
- sans URL explicite, on bascule sur minimax-cn au lieu de minimax (GLOBAL).
61
-
62
- Controlable via la variable d'environnement OVERMIND_MINIMAX_DEFAULT :
63
-
64
- OVERMIND_MINIMAX_DEFAULT=cn (defaut) sk-cp-* sans URL -> minimax-cn
65
- OVERMIND_MINIMAX_DEFAULT=global sk-cp-* sans URL -> minimax
66
- OVERMIND_MINIMAX_DEFAULT=auto sk-cp-* sans URL -> minimax (no override)
67
-
68
- Si ANTHROPIC_BASE_URL est explicite dans les settings, l'URL gagne TOUJOURS
69
- sur OVERMIND_MINIMAX_DEFAULT (le vote 3-signal reste prioritaire).
70
-
71
- Pour ton setup actuel (tous les tokens sk-cp-* sont CN), le defaut "cn"
72
- est ce que tu veux. Pas besoin de le set explicitement, mais c'est plus
73
- safe de le mettre dans le .env pour clarifier l'intention.
74
-
75
-
76
- Comment ça marche en pratique
77
- ----------------------------
78
- 1. Tu écris un settings_<agent>.json minimal :
79
-
80
- {
81
- "env": {
82
- "ANTHROPIC_MODEL": "MiniMax-M3",
83
- "ANTHROPIC_AUTH_TOKEN": "$ANTHROPIC_AUTH_TOKEN_2",
84
- "ANTHROPIC_PROVIDER": "minimax-cn",
85
- "ANTHROPIC_BASE_URL": "https://api.minimaxi.com/anthropic"
86
- }
87
- }
88
-
89
- 2. Overmind (etapes detaillees) :
90
-
91
- a. Lit le settings BRUT (AVANT interpolation des $VAR)
92
- b. Voit "$ANTHROPIC_AUTH_TOKEN_2" -> le résout depuis process.env
93
- c. Obtient la valeur du token (ex: "sk-cp-...m0")
94
- d. SNIFF le préfixe -> détecte "sk-cp-" -> provider = minimax
95
- e. RECONCILIE 3 signaux (vote par priorite) :
96
- - token détecté : minimax (subtilisation par préfixe)
97
- - URL du base : minimax-cn (api.minimaxi.com)
98
- - settings hint : minimax-cn (ANTHROPIC_PROVIDER)
99
- URL gagne (plus specifique que le token)
100
- -> effectiveProvider = minimax-cn
101
- f. PRUNE auth.json (enleve les vieux credential_pool entries
102
- d'autres providers comme zai/minimax qui etaient stales)
103
- g. ECRIT le .env de l'agent avec les 4 champs canoniques :
104
- ANTHROPIC_MODEL=MiniMax-M3
105
- ANTHROPIC_AUTH_TOKEN=***
106
- ANTHROPIC_PROVIDER=minimax-cn
107
- ANTHROPIC_BASE_URL=https://api.minimaxi.com/anthropic
108
- + seed provider-specific (MINIMAX_CN_API_KEY=***
109
- h. ECRIT auth.json avec le bucket minimax-cn uniquement
110
- (les autres buckets du fichier sont preserves comme providers
111
- oauth, mais credential_pool est reset pour eviter le drift)
112
- i. INVOQUE Hermes qui lit son .env et route vers le bon endpoint
113
-
114
-
115
- RESOLUTION DES TOKENS (3-pass strategy, NOUVEAU en 2.8.16+)
116
- -----------------------------------------------------------
117
- Quand l'agent a PLUSIEURS clés dans son env (cas fréquent : le user met
118
- plusieurs providers dans Workflow/.env), le runner ne prend plus la première
119
- claire comme avant. Il fait 3 passes :
120
-
121
- Pass 1: settings_<agent>.json env block -> WINS si une clé de token est là
122
- - Litteral token ("sk-cp-...") -> utilisé tel quel
123
- - Reference $VAR ("$MINIMAX_CN_API_KEY") -> résolue depuis process.env
124
- - $VAR introuvable ? FAIL LOUD (throw MISSING_ENV_VAR)
125
- - On ne fallback PAS silencieusement sur une autre clé
126
-
127
- Pass A: prefer keys whose NAME matches the detected provider
128
- - Si MINIMAX_API_KEY=*** ET ANTHROPIC_AUTH_TOKEN=*** sont tous les
129
- deux présents, le user a explicitement mis la provider-specific,
130
- on respecte son choix -> MINIMAX_API_KEY gagne
131
- - FIX bug : avant, la 1re clé de TOKEN_KEYS (ANTHROPIC_AUTH_TOKEN)
132
- gagnait TOUJOURS par re-map, ce qui ecrase silencieusement la
133
- provider-specific que le user avait set explicitement
134
-
135
- Pass B: re-map la 1re clé vers le bon provider
136
- - Si seulement ANTHROPIC_AUTH_TOKEN=*** alors on sait que c'est un
137
- MiniMax (sk-cp-*), on le re-mappe vers MINIMAX_API_KEY
138
-
139
- Pass C: rare, fallback si rien ne match
140
-
141
-
142
- INTERPOLATION $VAR DANS settings_<agent>.json (FIX BUG)
143
- --------------------------------------------------------
144
- Le runner utilise interpolateEnvVars() (src/lib/envUtils.ts) pour résoudre
145
- les references $VAR et ${VAR} avant d'utiliser les settings.
146
-
147
- Bug fixé en 2.8.25 : la regex precedente `\$(\w+)|\${\w+}` avait DEUX bugs :
148
- (a) Un seul groupe capturant au lieu de deux — ${VAR} causait un crash
149
- sur process.env[undefined]
150
- (b) Le } fermant n'etait pas consomme — fuyait comme texte literal
151
-
152
- Nouvelle regex : `\$\{(\w+)\}|\$(\w+)` (deux groupes, un par branche,
153
- } consomme).
154
-
155
- Exemples :
156
- "${HOME}" -> C:\Users\Deamon (correct, } consomme)
157
- "$HOME" -> C:\Users\Deamon (correct, bare form)
158
- "sk-${REGION}-x" -> sk-cp-x (correct, mixed)
159
- "$$" -> "" (correct, escape not supported)
160
-
161
-
162
- Ce que tu n'as PAS besoin de faire
163
- ----------------------------------
164
- - Tu n'as pas à deviner quel env var name le plugin Hermes attend
165
- - Tu n'as pas à lire plugins/model-providers/minimax/init.py
166
- - Tu n'as pas à mapper manuellement $KEY vers le bon provider
167
- - Tu n'as pas à tester 50 combinaisons d'env var names
168
- - Tu n'as pas à te soucier du cwd du process pour HERMES_HOME
169
-
170
- Tu mets ton token, Overmind s'occupe du reste.
171
-
172
-
173
- HERMES_HOME : résolution déterministe (NOUVEAU en 2.8.27)
174
- ---------------------------------------------------------
175
- Le path où Hermes stocke son état (.env, auth.json, sessions, state.db)
176
- est résolu par getAgentHermesHome(agentName) dans src/lib/config.ts.
177
-
178
- Ordre de résolution :
179
- 1. $OVERMIND_AGENT_HOME (env var, set par l'install sudo ou systemd)
180
- 2. <workspace>/.overmind/hermes/agent_<name>/.hermes (legacy, si existe)
181
- 3. $HOME/.overmind/hermes/agent_<name>/.hermes (Linux/Mac sudo)
182
- %LOCALAPPDATA%\overmind\hermes\agent_<name>\.hermes (Windows)
183
- %USERPROFILE%\overmind\hermes\agent_<name>\.hermes (Windows fallback)
184
-
185
- Pour un agent "sniperbot_analyst" :
186
- - Dev local: Workflow\.overmind\hermes\agent_sniperbot_analyst\.hermes
187
- - Prod Linux: ~/.overmind/hermes/agent_sniperbot_analyst/.hermes
188
- - Prod Win: %LOCALAPPDATA%\overmind\hermes\agent_sniperbot_analyst\.hermes
189
-
190
- Pour forcer un path explicite (Docker, deploy custom) :
191
- export OVERMIND_AGENT_HOME=/var/lib/overmind/hermes
192
-
193
- Pour migrer un ancien install (state dans le workspace-relative path) :
194
- cd "C:/Users/Deamon/Desktop/Backup/Serveur MCP/Workflow"
195
- node scripts/migrate-hermes-home.mjs --dry-run # preview
196
- node scripts/migrate-hermes-home.mjs # apply
197
-
198
-
199
- Les 3 signaux que vote Overmind (priorité décroissante)
200
- --------------------------------------------------------
201
- 1. PRÉFIXE DU TOKEN (le plus fiable — c'est la vérité du fournisseur)
202
- 2. URL DU BASE (très fiable — l'API elle-même)
203
- 3. ANTHROPIC_PROVIDER (le moins fiable — c'est juste un hint que tu donnes)
204
-
205
- Si les 3 ne sont pas d'accord, Overmind LOG un warning explicite
206
- mais utilise le token (signal le plus fiable).
207
- Exception : sk-cp- + URL disambiguent -> l'URL gagne (cf. plus haut).
208
-
209
-
210
- Si tu donnes une clé foireuse
211
- -----------------------------
212
- - Token sk-cp- mais URL api.z.ai -> warning, mais token wins
213
- -> Hermes va appeler api.z.ai avec une clé MiniMax -> 401 du provider Z.AI
214
- - Token 32hex.32hex mais provider "minimax" -> warning, mais token wins
215
- -> Hermes va appeler le plugin zai avec un token Z.AI -> OK
216
-
217
- L'erreur 401 finale n'est PAS un bug du runner, c'est le provider
218
- LLM qui rejette la clé (expirée, mauvaise région, etc.).
219
-
220
-
221
- Comment Hermes obtient la API Key (le vrai flux)
222
- -----------------------------------------------
223
- Le `ANTHROPIC_AUTH_TOKEN` dans `settings.json` NE PASSE PAS DIRECTEMENT
224
- dans le body de la requête API. Hermes utilise son propre credential pool :
225
-
226
- settings_[agent].json
227
- "env": { "ANTHROPIC_AUTH_TOKEN": "$MINIMAX_CN_API_KEY" }
228
- ↓ (interpolateEnvVars par NousHermesRunner)
229
- agentCustomEnv envoyé a Hermes:
230
- ANTHROPIC_AUTH_TOKEN=***
231
- Hermes ne lit PAS ANTHROPIC_AUTH_TOKEN directement.
232
- Hermes lit le CREDENTIAL POOL (auth.json) + les .env vars listees
233
- dans api_key_env_vars.
234
-
235
- Credential pool est seed par:
236
- ZAI_ANTHROPIC_FALLBACK_KEY -> "zai" avec base_url coding
237
- Z_AI_API_KEY -> "zai" avec base_url non-coding (ancien)
238
- MINIMAX_CN_API_KEY -> "minimax-cn"
239
- MINIMAX_API_KEY -> "minimax" (GLOBAL)
240
-
241
- Le $VAR dans ANTHROPIC_AUTH_TOKEN is juste une convenience pour que
242
- le token traverse le runner et arrive dans process.env du subprocess Hermes.
243
- C'est process.env.MINIMAX_CN_API_KEY qui seed le credential pool.
244
-
245
-
246
- PRUNING auth.json (NOUVEAU en 2.8.27)
247
- --------------------------------------
248
- A chaque run, le runner PRUNE credential_pool dans auth.json pour ne
249
- laisser que les entries du effectiveProvider. Cela evite que Hermes
250
- picke un vieux bucket (ex: zai avec last_status="exhausted") au lieu
251
- du nouveau (ex: minimax-cn fraichement seede).
252
-
253
- Le version + les oauth providers sont préservés, seul credential_pool
254
- est re-seedé from scratch.
255
-
256
- Symptôme résolu : "Anthropic 401 invalid api key" avec token prefix
257
- correct (sk-cp-...) qui était en fait servi par un vieux credential
258
- zai dans le pool, pas par le nouveau MINIMAX_CN_API_KEY du .env.
259
-
260
-
261
- Implementation
262
- --------------
263
- La logique de subtilisation vit à deux endroits :
264
-
265
- 1. src/services/hermesTokenResolver.ts (canonique, exporté)
266
- - Utilisé par les tests unitaires
267
- - Source de vérité de la stratégie 3-pass
268
-
269
- 2. src/services/NousHermesRunner.ts (closure locale, dans runAgentInternal)
270
- - Copie miroir de la version canonique, pour ne pas avoir à thread
271
- 5 args (agentName, agentCustomEnv, TOKEN_KEYS, logger, ...) à chaque
272
- appel
273
- - DOIT rester sync avec la version canonique
274
-
275
- Si les deux divergent, c'est un bug.
276
-
277
-
278
- Pour résumer en 1 ligne
279
- -----------------------
280
- La subtilisation = Overmind sniffe le préfixe de ton token, vote entre
281
- token/URL/settings pour confirmer, et mappe automatiquement vers le bon
282
- provider et le bon env var, sans que tu aies à configurer le mapping
283
- provider <-> env var toi-même. Le path HERMES_HOME est déterministe,
284
- auth.json est pruné à chaque run, et l'interpolation ${VAR} est robuste.
1
+ LA SUBTILISATION — comment Overmind devine ton provider LLM à partir de ton token
2
+ ==============================================================================
3
+
4
+ Version: Overmind 2.8.28 (2026-06-07)
5
+ Hermes requis: v0.16.0+
6
+
7
+
8
+ Concept (1 phrase)
9
+ ------------------
10
+ Le runner Overmind ne te demande PAS quel provider tu utilises.
11
+ Il LIT ton token, en déduit le préfixe, et MAPPE automatiquement
12
+ vers le bon env var que le plugin provider de Hermes attend.
13
+
14
+
15
+ Pourquoi ça existe
16
+ -----------------
17
+ Les tokens de providers LLM ont des préfixes distincts que tu ne
18
+ connais peut-être pas :
19
+
20
+ sk-cp-... -> MiniMax (env: MINIMAX_API_KEY, MINIMAX_CN_API_KEY)
21
+ sk-mm-... -> MiniMax (variante)
22
+ sk-ant-... -> Anthropic (env: ANTHROPIC_AUTH_TOKEN)
23
+ sk-or-... -> OpenRouter (BLOQUÉ pour LLM, embeddings only)
24
+ sk-... -> OpenAI (env: OPENAI_API_KEY)
25
+ 32hex.32hex -> Z.AI / GLM (env: ZAI_ANTHROPIC_FALLBACK_KEY, GLM_API_KEY)
26
+ 32hex -> Z.AI (variante single-block)
27
+ 16hex+ -> Z.AI (catch-all hex)
28
+
29
+
30
+ CAS SPÉCIAL : sk-cp- est ambigu entre MiniMax GLOBAL et MiniMax CN
31
+ ------------------------------------------------------------------
32
+ Meme prefix. Pour desambiguïser, le runner regarde l'ANTHROPIC_BASE_URL :
33
+ - api.minimaxi.com (avec le i) -> minimax-cn
34
+ - api.minimax.com (sans le i) -> minimax (GLOBAL)
35
+ L'URL gagne dans ce cas parce qu'elle est la seule a desambiguïser.
36
+
37
+ Ce que tu mets dans settings_<agent>.json :
38
+
39
+ {
40
+ "env": {
41
+ "ANTHROPIC_AUTH_TOKEN": "$ANTHROPIC_AUTH_TOKEN_2",
42
+ "ANTHROPIC_BASE_URL": "https://api.minimaxi.com/anthropic",
43
+ "ANTHROPIC_MODEL": "MiniMax-M3",
44
+ "ANTHROPIC_PROVIDER": "minimax-cn"
45
+ }
46
+ }
47
+
48
+ Le runner voit ANTHROPIC_BASE_URL contient "minimaxi" -> effectiveProvider = minimax-cn.
49
+ Il seed auth.json avec MINIMAX_CN_API_KEY et the bon endpoint.
50
+ Hermes route vers le plugin minimax-cn.
51
+
52
+
53
+ CONVENTION : MiniMax = CN par defaut
54
+ -------------------------------------
55
+ Le prefixe sk-cp- est partage entre MiniMax GLOBAL (api.minimax.com) et
56
+ MiniMax CN (api.minimaxi.com). L'URL est le seul signal qui desambigüise.
57
+
58
+ Pour les setups ou TOUS les tokens MiniMax sont CN (le cas le plus commun),
59
+ le runner a un fallback par defaut : quand un token sk-cp-* est detecte
60
+ sans URL explicite, on bascule sur minimax-cn au lieu de minimax (GLOBAL).
61
+
62
+ Controlable via la variable d'environnement OVERMIND_MINIMAX_DEFAULT :
63
+
64
+ OVERMIND_MINIMAX_DEFAULT=cn (defaut) sk-cp-* sans URL -> minimax-cn
65
+ OVERMIND_MINIMAX_DEFAULT=global sk-cp-* sans URL -> minimax
66
+ OVERMIND_MINIMAX_DEFAULT=auto sk-cp-* sans URL -> minimax (no override)
67
+
68
+ Si ANTHROPIC_BASE_URL est explicite dans les settings, l'URL gagne TOUJOURS
69
+ sur OVERMIND_MINIMAX_DEFAULT (le vote 3-signal reste prioritaire).
70
+
71
+ Pour ton setup actuel (tous les tokens sk-cp-* sont CN), le defaut "cn"
72
+ est ce que tu veux. Pas besoin de le set explicitement, mais c'est plus
73
+ safe de le mettre dans le .env pour clarifier l'intention.
74
+
75
+
76
+ Comment ça marche en pratique
77
+ ----------------------------
78
+ 1. Tu écris un settings_<agent>.json minimal :
79
+
80
+ {
81
+ "env": {
82
+ "ANTHROPIC_MODEL": "MiniMax-M3",
83
+ "ANTHROPIC_AUTH_TOKEN": "$ANTHROPIC_AUTH_TOKEN_2",
84
+ "ANTHROPIC_PROVIDER": "minimax-cn",
85
+ "ANTHROPIC_BASE_URL": "https://api.minimaxi.com/anthropic"
86
+ }
87
+ }
88
+
89
+ 2. Overmind (etapes detaillees) :
90
+
91
+ a. Lit le settings BRUT (AVANT interpolation des $VAR)
92
+ b. Voit "$ANTHROPIC_AUTH_TOKEN_2" -> le résout depuis process.env
93
+ c. Obtient la valeur du token (ex: "sk-cp-...m0")
94
+ d. SNIFF le préfixe -> détecte "sk-cp-" -> provider = minimax
95
+ e. RECONCILIE 3 signaux (vote par priorite) :
96
+ - token détecté : minimax (subtilisation par préfixe)
97
+ - URL du base : minimax-cn (api.minimaxi.com)
98
+ - settings hint : minimax-cn (ANTHROPIC_PROVIDER)
99
+ URL gagne (plus specifique que le token)
100
+ -> effectiveProvider = minimax-cn
101
+ f. PRUNE auth.json (enleve les vieux credential_pool entries
102
+ d'autres providers comme zai/minimax qui etaient stales)
103
+ g. ECRIT le .env de l'agent avec les 4 champs canoniques :
104
+ ANTHROPIC_MODEL=MiniMax-M3
105
+ ANTHROPIC_AUTH_TOKEN=***
106
+ ANTHROPIC_PROVIDER=minimax-cn
107
+ ANTHROPIC_BASE_URL=https://api.minimaxi.com/anthropic
108
+ + seed provider-specific (MINIMAX_CN_API_KEY=***
109
+ h. ECRIT auth.json avec le bucket minimax-cn uniquement
110
+ (les autres buckets du fichier sont preserves comme providers
111
+ oauth, mais credential_pool est reset pour eviter le drift)
112
+ i. INVOQUE Hermes qui lit son .env et route vers le bon endpoint
113
+
114
+
115
+ RESOLUTION DES TOKENS (3-pass strategy, NOUVEAU en 2.8.16+)
116
+ -----------------------------------------------------------
117
+ Quand l'agent a PLUSIEURS clés dans son env (cas fréquent : le user met
118
+ plusieurs providers dans Workflow/.env), le runner ne prend plus la première
119
+ claire comme avant. Il fait 3 passes :
120
+
121
+ Pass 1: settings_<agent>.json env block -> WINS si une clé de token est là
122
+ - Litteral token ("sk-cp-...") -> utilisé tel quel
123
+ - Reference $VAR ("$MINIMAX_CN_API_KEY") -> résolue depuis process.env
124
+ - $VAR introuvable ? FAIL LOUD (throw MISSING_ENV_VAR)
125
+ - On ne fallback PAS silencieusement sur une autre clé
126
+
127
+ Pass A: prefer keys whose NAME matches the detected provider
128
+ - Si MINIMAX_API_KEY=*** ET ANTHROPIC_AUTH_TOKEN=*** sont tous les
129
+ deux présents, le user a explicitement mis la provider-specific,
130
+ on respecte son choix -> MINIMAX_API_KEY gagne
131
+ - FIX bug : avant, la 1re clé de TOKEN_KEYS (ANTHROPIC_AUTH_TOKEN)
132
+ gagnait TOUJOURS par re-map, ce qui ecrase silencieusement la
133
+ provider-specific que le user avait set explicitement
134
+
135
+ Pass B: re-map la 1re clé vers le bon provider
136
+ - Si seulement ANTHROPIC_AUTH_TOKEN=*** alors on sait que c'est un
137
+ MiniMax (sk-cp-*), on le re-mappe vers MINIMAX_API_KEY
138
+
139
+ Pass C: rare, fallback si rien ne match
140
+
141
+
142
+ INTERPOLATION $VAR DANS settings_<agent>.json (FIX BUG)
143
+ --------------------------------------------------------
144
+ Le runner utilise interpolateEnvVars() (src/lib/envUtils.ts) pour résoudre
145
+ les references $VAR et ${VAR} avant d'utiliser les settings.
146
+
147
+ Bug fixé en 2.8.25 : la regex precedente `\$(\w+)|\${\w+}` avait DEUX bugs :
148
+ (a) Un seul groupe capturant au lieu de deux — ${VAR} causait un crash
149
+ sur process.env[undefined]
150
+ (b) Le } fermant n'etait pas consomme — fuyait comme texte literal
151
+
152
+ Nouvelle regex : `\$\{(\w+)\}|\$(\w+)` (deux groupes, un par branche,
153
+ } consomme).
154
+
155
+ Exemples :
156
+ "${HOME}" -> C:\Users\Deamon (correct, } consomme)
157
+ "$HOME" -> C:\Users\Deamon (correct, bare form)
158
+ "sk-${REGION}-x" -> sk-cp-x (correct, mixed)
159
+ "$$" -> "" (correct, escape not supported)
160
+
161
+
162
+ Ce que tu n'as PAS besoin de faire
163
+ ----------------------------------
164
+ - Tu n'as pas à deviner quel env var name le plugin Hermes attend
165
+ - Tu n'as pas à lire plugins/model-providers/minimax/init.py
166
+ - Tu n'as pas à mapper manuellement $KEY vers le bon provider
167
+ - Tu n'as pas à tester 50 combinaisons d'env var names
168
+ - Tu n'as pas à te soucier du cwd du process pour HERMES_HOME
169
+
170
+ Tu mets ton token, Overmind s'occupe du reste.
171
+
172
+
173
+ HERMES_HOME : résolution déterministe (NOUVEAU en 2.8.27)
174
+ ---------------------------------------------------------
175
+ Le path où Hermes stocke son état (.env, auth.json, sessions, state.db)
176
+ est résolu par getAgentHermesHome(agentName) dans src/lib/config.ts.
177
+
178
+ Ordre de résolution :
179
+ 1. $OVERMIND_AGENT_HOME (env var, set par l'install sudo ou systemd)
180
+ 2. <workspace>/.overmind/hermes/agent_<name>/.hermes (legacy, si existe)
181
+ 3. $HOME/.overmind/hermes/agent_<name>/.hermes (Linux/Mac sudo)
182
+ %LOCALAPPDATA%\overmind\hermes\agent_<name>\.hermes (Windows)
183
+ %USERPROFILE%\overmind\hermes\agent_<name>\.hermes (Windows fallback)
184
+
185
+ Pour un agent "sniperbot_analyst" :
186
+ - Dev local: Workflow\.overmind\hermes\agent_sniperbot_analyst\.hermes
187
+ - Prod Linux: ~/.overmind/hermes/agent_sniperbot_analyst/.hermes
188
+ - Prod Win: %LOCALAPPDATA%\overmind\hermes\agent_sniperbot_analyst\.hermes
189
+
190
+ Pour forcer un path explicite (Docker, deploy custom) :
191
+ export OVERMIND_AGENT_HOME=/var/lib/overmind/hermes
192
+
193
+ Pour migrer un ancien install (state dans le workspace-relative path) :
194
+ cd "C:/Users/Deamon/Desktop/Backup/Serveur MCP/Workflow"
195
+ node scripts/migrate-hermes-home.mjs --dry-run # preview
196
+ node scripts/migrate-hermes-home.mjs # apply
197
+
198
+
199
+ Les 3 signaux que vote Overmind (priorité décroissante)
200
+ --------------------------------------------------------
201
+ 1. PRÉFIXE DU TOKEN (le plus fiable — c'est la vérité du fournisseur)
202
+ 2. URL DU BASE (très fiable — l'API elle-même)
203
+ 3. ANTHROPIC_PROVIDER (le moins fiable — c'est juste un hint que tu donnes)
204
+
205
+ Si les 3 ne sont pas d'accord, Overmind LOG un warning explicite
206
+ mais utilise le token (signal le plus fiable).
207
+ Exception : sk-cp- + URL disambiguent -> l'URL gagne (cf. plus haut).
208
+
209
+
210
+ Si tu donnes une clé foireuse
211
+ -----------------------------
212
+ - Token sk-cp- mais URL api.z.ai -> warning, mais token wins
213
+ -> Hermes va appeler api.z.ai avec une clé MiniMax -> 401 du provider Z.AI
214
+ - Token 32hex.32hex mais provider "minimax" -> warning, mais token wins
215
+ -> Hermes va appeler le plugin zai avec un token Z.AI -> OK
216
+
217
+ L'erreur 401 finale n'est PAS un bug du runner, c'est le provider
218
+ LLM qui rejette la clé (expirée, mauvaise région, etc.).
219
+
220
+
221
+ Comment Hermes obtient la API Key (le vrai flux)
222
+ -----------------------------------------------
223
+ Le `ANTHROPIC_AUTH_TOKEN` dans `settings.json` NE PASSE PAS DIRECTEMENT
224
+ dans le body de la requête API. Hermes utilise son propre credential pool :
225
+
226
+ settings_[agent].json
227
+ "env": { "ANTHROPIC_AUTH_TOKEN": "$MINIMAX_CN_API_KEY" }
228
+ ↓ (interpolateEnvVars par NousHermesRunner)
229
+ agentCustomEnv envoyé a Hermes:
230
+ ANTHROPIC_AUTH_TOKEN=***
231
+ Hermes ne lit PAS ANTHROPIC_AUTH_TOKEN directement.
232
+ Hermes lit le CREDENTIAL POOL (auth.json) + les .env vars listees
233
+ dans api_key_env_vars.
234
+
235
+ Credential pool est seed par:
236
+ ZAI_ANTHROPIC_FALLBACK_KEY -> "zai" avec base_url coding
237
+ Z_AI_API_KEY -> "zai" avec base_url non-coding (ancien)
238
+ MINIMAX_CN_API_KEY -> "minimax-cn"
239
+ MINIMAX_API_KEY -> "minimax" (GLOBAL)
240
+
241
+ Le $VAR dans ANTHROPIC_AUTH_TOKEN is juste une convenience pour que
242
+ le token traverse le runner et arrive dans process.env du subprocess Hermes.
243
+ C'est process.env.MINIMAX_CN_API_KEY qui seed le credential pool.
244
+
245
+
246
+ PRUNING auth.json (NOUVEAU en 2.8.27)
247
+ --------------------------------------
248
+ A chaque run, le runner PRUNE credential_pool dans auth.json pour ne
249
+ laisser que les entries du effectiveProvider. Cela evite que Hermes
250
+ picke un vieux bucket (ex: zai avec last_status="exhausted") au lieu
251
+ du nouveau (ex: minimax-cn fraichement seede).
252
+
253
+ Le version + les oauth providers sont préservés, seul credential_pool
254
+ est re-seedé from scratch.
255
+
256
+ Symptôme résolu : "Anthropic 401 invalid api key" avec token prefix
257
+ correct (sk-cp-...) qui était en fait servi par un vieux credential
258
+ zai dans le pool, pas par le nouveau MINIMAX_CN_API_KEY du .env.
259
+
260
+
261
+ NE PAS PASSER --provider au CLI Hermes (NOUVEAU en 2.8.28)
262
+ -----------------------------------------------------------
263
+ Découverte empirique : quand le runner Overmind passait
264
+ `hermes chat -q --provider minimax-cn` (avec un settings qui a déjà
265
+ `ANTHROPIC_PROVIDER=minimax-cn`), le plugin Hermes upstream renvoyait
266
+ 401. Mais `hermes chat --yolo` (SANS --provider, juste les env vars
267
+ MINIMAX_CN_API_KEY + ANTHROPIC_BASE_URL + ANTHROPIC_MODEL) marchait.
268
+
269
+ Cause : le flag --provider explicite active un code path buggé dans
270
+ le plugin Hermes qui envoie un format d'auth header rejeté par
271
+ api.minimaxi.com. Sans --provider, Hermes auto-détecte le provider
272
+ depuis l'env var (MINIMAX_CN_API_KEY, ZAI_ANTHROPIC_FALLBACK_KEY, etc.)
273
+ et passe par le bon code path.
274
+
275
+ Fix appliqué en 2.8.28 : le runner ne passe PLUS --provider. Le
276
+ resolvedProvider est juste loggué en INFO pour debug. Hermes choisit
277
+ le bon plugin depuis l'env.
278
+
279
+ Référence : C:\Users\Deamon\Desktop\launcher\Hermes-MiniMax-2.bat
280
+ marche parce qu'il fait juste `hermes chat --yolo` (pas --provider).
281
+
282
+
283
+ Implementation
284
+ --------------
285
+ La logique de subtilisation vit à deux endroits :
286
+
287
+ 1. src/services/hermesTokenResolver.ts (canonique, exporté)
288
+ - Utilisé par les tests unitaires
289
+ - Source de vérité de la stratégie 3-pass
290
+
291
+ 2. src/services/NousHermesRunner.ts (closure locale, dans runAgentInternal)
292
+ - Copie miroir de la version canonique, pour ne pas avoir à thread
293
+ 5 args (agentName, agentCustomEnv, TOKEN_KEYS, logger, ...) à chaque
294
+ appel
295
+ - DOIT rester sync avec la version canonique
296
+
297
+ Si les deux divergent, c'est un bug.
298
+
299
+
300
+ Pour résumer en 1 ligne
301
+ -----------------------
302
+ La subtilisation = Overmind sniffe le préfixe de ton token, vote entre
303
+ token/URL/settings pour confirmer, et mappe automatiquement vers le bon
304
+ provider et le bon env var, sans que tu aies à configurer le mapping
305
+ provider <-> env var toi-même. Le path HERMES_HOME est déterministe,
306
+ auth.json est pruné à chaque run, et l'interpolation ${VAR} est robuste.
@@ -176,6 +176,33 @@ toujours sur `OVERMIND_MINIMAX_DEFAULT`.
176
176
 
177
177
  ---
178
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
+
179
206
  ## HERMES_HOME resolution (multi-OS, multi-install)
180
207
 
181
208
  Chaque agent Hermes a son propre HERMES_HOME. Le path est resolu de maniere
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "overmind-mcp",
3
- "version": "2.8.27",
3
+ "version": "2.8.30",
4
4
  "description": "Orchestrateur universel agents IA multi-modeles via MCP. Inclut le protocole 'Custom-Nickname' pour identifier vos agents avec des surnoms originaux (The Chaos Prophet, Shadow Sniper, etc.), l'isolation mémoire (Private Memory Context) et le support pour QwenCli et Nous Hermes. Installation automatique des dépendances Docker (PostgreSQL, pgvector) inclus.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -471,6 +471,12 @@ function showSummary() {
471
471
  console.log(" • ~/.overmind/.env.postgres (Configuration PostgreSQL MCP)");
472
472
  console.log(" • ~/.overmind/.mcp.json (Configuration serveurs MCP)");
473
473
  console.log('');
474
+ log(COLORS.yellow, "🗂️ HERMES_HOME par agent (NOUVEAU en 2.8.27):");
475
+ console.log(" • Linux/Mac: ~/.overmind/hermes/agent_<name>/.hermes");
476
+ console.log(" • Windows: %LOCALAPPDATA%\\overmind\\hermes\\agent_<name>\\.hermes");
477
+ console.log(" • Override: export OVERMIND_AGENT_HOME=/path/to/agent/home");
478
+ console.log(" • Migration: node scripts/migrate-hermes-home.mjs");
479
+ console.log('');
474
480
  log(COLORS.yellow, "🔧 SERVEURS MCP ACTIFS:");
475
481
  console.log(" • overmind (Orchestration d'agents)");
476
482
  console.log(" • memory (Gestion mémoire vectorielle)");