You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 547ba09
Browse filesBrowse the repository at this point in the historyBrowse files
feat: rotate a pool of Command Code keys on credential failures
A plan can hold several API keys. With two or more (COMMANDCODE_API_KEYS,
COMMANDCODE_KEYS_FILE or ~/.config/commandcode/keys.txt) the plugin now
picks the first key that is not cooling down, records 24h cooldowns for
402/401/403, honours Retry-After up to 6h for 429, and never blames the
key for 5xx. State is labels-only and logged without secrets; single-key
mode keeps the previous behaviour and never overrides a host header.
Los cooldowns se registran por key segun la respuesta que culpa a la credencial:
90
+
`402` (creditos insuficientes) y `401`/`403` bloquean 24h, `429` respeta
91
+
`Retry-After` hasta 6h (5m por defecto), y `5xx` nunca culpa a la key. Si todas
92
+
estan en cooldown gana la que se recupera antes. El estado guarda solo etiquetas
93
+
(`<state>/commandcode-keys-state.json`, modo 0600) y cada cooldown se registra en
94
+
`<state>/commandcode-rotation.log`.
95
+
96
+
En modo rotacion el plugin es dueno de la cabecera `Authorization` para
97
+
`api.commandcode.ai`, porque la key que inyecto el host puede ser justo la que
98
+
devolvio `402`. En modo key unica se mantiene la regla anterior: inyectar solo si
99
+
el request no trae cabecera.
100
+
75
101
### Estabilidad de sesion
76
102
77
103
Cuatro hooks independientes, todos fail-open (un error del plugin nunca puede romper
@@ -218,6 +244,9 @@ Cada ajuste es una variable de entorno con default seguro. Referencia completa:
218
244
| --- | --- | --- |
219
245
|`COMMAND_CODE_API_KEY`| - | Resolucion de la key, maxima prioridad |
220
246
|`COMMANDCODE_KEY_FILE`| - | Ruta absoluta a un archivo con la key |
247
+
|`COMMANDCODE_API_KEYS`| - | Pool de keys; dos o mas activan rotacion |
248
+
|`COMMANDCODE_KEYS_FILE`| - | Archivo pool (`label=key` o key pelada por linea) |
249
+
|`CMD_ZDR`| - |`1` para zero data retention (`x-cmd-zdr: 1`) |
221
250
|`COMMANDCODE_ALLOWED_HOSTS`| - | Hosts extra separados por coma autorizados a recibir la key |
222
251
|`CC_NO_CONNECTION_CLOSE`|`0`| Poner en `1` para dejar de inyectar `Connection: close`|
223
252
|`COMMANDCODE_STATE_DIR`|`$XDG_STATE_HOME/opencode`| Donde viven los logs y la cache de modelos |
@@ -236,6 +265,8 @@ Kill switch en runtime para la higiene de conexion: crea un archivo centinela ll
236
265
|`<state>/commandcode-sanitizer.log`| Cada reparacion de payload en vuelo, con las correcciones aplicadas |
237
266
|`<state>/commandcode-watchdog.log`| Streams SSE abortados por inactividad |
238
267
|`<state>/commandcode-retries.log`| Reintentos de transporte de Command Code: sesion, agente, proveedor, modelo, tipo de error, status HTTP, numero de intento, delay del backoff y mensaje |
268
+
|`<state>/commandcode-rotation.log`| Cooldowns de keys: etiqueta, status HTTP, motivo y hora de reset |
269
+
|`<state>/commandcode-keys-state.json`| Estado de cooldown por etiqueta (solo etiquetas, 0600) |
239
270
|`<state>/commandcode-models-cache.json`| Ultimo catalogo de modelos bueno (TTL 6h) |
240
271
241
272
`<state>` por defecto es `~/.local/state/opencode`.
|`COMMANDCODE_KEY_FILE`| unset | Absolute path to a file containing only the key. Ignored when the file is missing or empty, so the cascade keeps going. |
15
+
|`COMMANDCODE_API_KEYS`| unset | Comma or whitespace separated pool. Two or more keys enable rotation. |
16
+
|`COMMANDCODE_KEYS_FILE`| unset | Pool file, one `label=key` or bare key per line. `#` starts a comment. |
17
+
|`CMD_ZDR`| unset | Set to `1` to send `x-cmd-zdr: 1` (zero data retention). |
15
18
|`XDG_CONFIG_HOME`|`~/.config`| Base for the third resolution step: `$XDG_CONFIG_HOME/commandcode/key.txt`. |
16
19
17
20
### Resolution order
@@ -43,6 +46,32 @@ Code traffic. Every host added here can read the API key.
Copy file name to clipboardExpand all lines: docs/es/configuration.md
+26Lines changed: 26 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,6 +12,9 @@ todos los hooks.
12
12
| --- | --- | --- |
13
13
|`COMMAND_CODE_API_KEY`| sin definir | Maxima prioridad. Se usa tal cual (recortada y sin comillas envolventes). |
14
14
|`COMMANDCODE_KEY_FILE`| sin definir | Ruta absoluta a un archivo que contenga solo la key. Se ignora si el archivo falta o esta vacio, para que la cascada continue. |
15
+
|`COMMANDCODE_API_KEYS`| sin definir | Pool separado por comas o espacios. Dos o mas keys activan la rotacion. |
16
+
|`COMMANDCODE_KEYS_FILE`| sin definir | Archivo pool, una `label=key` o key pelada por linea. `#` inicia comentario. |
17
+
|`CMD_ZDR`| sin definir |`1` envia `x-cmd-zdr: 1` (zero data retention). |
15
18
|`XDG_CONFIG_HOME`|`~/.config`| Base del tercer paso de resolucion: `$XDG_CONFIG_HOME/commandcode/key.txt`. |
16
19
17
20
### Orden de resolucion
@@ -39,6 +42,29 @@ tests. `resolveApiKey()` devuelve solo el string.
39
42
Usala solo para un gateway propio que realmente termine tu trafico hacia Command Code.
40
43
Cada host que agregues aqui puede leer la API key.
41
44
45
+
### Rotacion de keys
46
+
47
+
Un pool de dos o mas keys activa la rotacion. Con una sola key (o ninguna) el plugin
48
+
mantiene el comportamiento de key unica y nunca toca una cabecera `Authorization` que
49
+
el host ya haya puesto.
50
+
51
+
| Fuente | Formato |
52
+
| --- | --- |
53
+
|`COMMANDCODE_API_KEYS`|`key1,key2` o separadas por espacios |
54
+
|`COMMANDCODE_KEYS_FILE`| una `label=key` o key pelada por linea, comentarios con `#`|
55
+
|`~/.config/commandcode/keys.txt`| mismo formato, usado si no hay variables |
56
+
57
+
| Status | Cooldown |
58
+
| --- | --- |
59
+
|`402` creditos insuficientes | 24h |
60
+
|`401` / `403` key invalida o sin permiso | 24h |
61
+
|`429` rate limit |`Retry-After` si existe y es <= 6h, si no 5m |
62
+
|`5xx`| ninguno (no es culpa de la key) |
63
+
64
+
Si todas las keys estan en cooldown se usa la que se recupera primero. El estado vive en
65
+
`<state>/commandcode-keys-state.json` (modo 0600, solo etiquetas) y cada cooldown se
0 commit comments