@crvouga/dev-fleet 0.0.0-stage → 0.1.0

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.
Files changed (333) hide show
  1. package/.mise/locks/aws-cdk/2.1146.1/aube-lock.yaml +24 -0
  2. package/.mise/locks/aws-cdk/2.1146.1/package.json +7 -0
  3. package/.mise/locks/azure-cli/2.91.0~a837e014/pyproject.toml +5 -0
  4. package/.mise/locks/azure-cli/2.91.0~a837e014/uv.lock +2794 -0
  5. package/.mise/locks/gemini/0.66.0~84aac8e6/aube-lock.yaml +123 -0
  6. package/.mise/locks/gemini/0.66.0~84aac8e6/package.json +12 -0
  7. package/.mise/locks/npm-devcontainers-cli/0.90.0/aube-lock.yaml +24 -0
  8. package/.mise/locks/npm-devcontainers-cli/0.90.0/package.json +7 -0
  9. package/.mise/locks/npm-modelcontextprotocol-inspector/2.13.0~4c109bea/aube-lock.yaml +1432 -0
  10. package/.mise/locks/npm-modelcontextprotocol-inspector/2.13.0~4c109bea/package.json +7 -0
  11. package/.mise/locks/npm-vercel/65.8.0/aube-lock.yaml +3595 -0
  12. package/.mise/locks/npm-vercel/65.8.0/package.json +7 -0
  13. package/.mise/locks/npm-wrangler/4.156.0/aube-lock.yaml +895 -0
  14. package/.mise/locks/npm-wrangler/4.156.0/package.json +7 -0
  15. package/.mise/locks/npm-yarnpkg-cli-dist/4.18.1/aube-lock.yaml +24 -0
  16. package/.mise/locks/npm-yarnpkg-cli-dist/4.18.1/package.json +7 -0
  17. package/LICENSE +21 -0
  18. package/README.md +157 -2
  19. package/agents/antigravity-proxy.ts +3 -0
  20. package/agents/audit.md +89 -0
  21. package/agents/claude-proxy +5 -0
  22. package/agents/claude-proxy.ts +3 -0
  23. package/agents/codex-proxy.ts +3 -0
  24. package/agents/grok-proxy.ts +3 -0
  25. package/agents/managed-proxy.ts +55 -0
  26. package/agents/opencode-proxy.ts +3 -0
  27. package/agents/registry.json +209 -0
  28. package/agents/registry.schema.json +149 -0
  29. package/agents/setup.md +128 -0
  30. package/agents/t3.json +40 -0
  31. package/ansible/macos/manager.yml +30 -0
  32. package/ansible/macos/policy.json +17 -0
  33. package/ansible/monitoring/README.md +154 -0
  34. package/ansible/monitoring/agent-darwin.yml +198 -0
  35. package/ansible/monitoring/agent.yml +134 -0
  36. package/ansible/monitoring/beszel-agent.service +42 -0
  37. package/ansible/monitoring/compose.yml +74 -0
  38. package/ansible/monitoring/hub-darwin.yml +102 -0
  39. package/ansible/monitoring/lock.json +11 -0
  40. package/ansible/net/remote-probe.sh +13 -0
  41. package/ansible/ubuntu/authorize-sudo.sh +51 -0
  42. package/ansible/ubuntu/baseline.yml +89 -0
  43. package/ansible/ubuntu/disk-guard.py +104 -0
  44. package/ansible/ubuntu/policy.json +43 -0
  45. package/ansible/ubuntu/recovery.yml +15 -0
  46. package/ansible/ubuntu/t3/policy.json +7 -0
  47. package/ansible/ubuntu/t3-desktop.yml +220 -0
  48. package/ansible/ubuntu/t3-health.sh +33 -0
  49. package/ansible/ubuntu/t3-policy.yml +76 -0
  50. package/ansible/ubuntu/t3-route.yml +28 -0
  51. package/ansible/ubuntu/tailscale.yml +75 -0
  52. package/ansible/ubuntu/tasks/credentials.yml +47 -0
  53. package/ansible/ubuntu/tasks/docker.yml +31 -0
  54. package/ansible/ubuntu/tasks/packages.yml +56 -0
  55. package/ansible/ubuntu/tasks/power.yml +51 -0
  56. package/ansible/ubuntu/tasks/recovery.yml +39 -0
  57. package/ansible/ubuntu/tasks/resources.yml +252 -0
  58. package/ansible/ubuntu/tasks/services.yml +31 -0
  59. package/ansible/ubuntu/tasks/ssh.yml +71 -0
  60. package/ansible/ubuntu/tasks/user.yml +120 -0
  61. package/bin/devfleet.mjs +36 -0
  62. package/bootstrap/bootstrap.ps1 +50 -0
  63. package/bootstrap/bootstrap.sh +73 -0
  64. package/bootstrap/devfleet +7 -0
  65. package/bootstrap/docker-desktop.sh +33 -0
  66. package/bootstrap/doctor.ts +189 -0
  67. package/bootstrap/fleet-manager-run.sh +76 -0
  68. package/bootstrap/fleet-remote-bootstrap.sh +185 -0
  69. package/bootstrap/global-config.ts +113 -0
  70. package/bootstrap/install-launcher.sh +7 -0
  71. package/bootstrap/native-aws.ts +86 -0
  72. package/bootstrap/native-t3.ts +154 -0
  73. package/bootstrap/npm.ts +350 -0
  74. package/bootstrap/setup-status.ts +51 -0
  75. package/bootstrap/setup.ts +88 -0
  76. package/bootstrap/shell-path.ts +105 -0
  77. package/bootstrap/verify-t3-archive.py +49 -0
  78. package/bootstrap/worker-auth.ts +65 -0
  79. package/bootstrap/worker-github.ts +47 -0
  80. package/bootstrap/worker-tools.ts +24 -0
  81. package/cliproxy/AGENTS.md +11 -0
  82. package/cliproxy/README.md +269 -0
  83. package/cliproxy/clients/bootstrap.py +143 -0
  84. package/cliproxy/clients/launcher.py +57 -0
  85. package/cliproxy/compose.yaml +90 -0
  86. package/cliproxy/config.template.yaml +70 -0
  87. package/cliproxy/docs/cloud-adoption.md +16 -0
  88. package/cliproxy/docs/deployment.png +0 -0
  89. package/cliproxy/docs/deployment.svg +109 -0
  90. package/cliproxy/docs/health-workflow.example.yml +185 -0
  91. package/cliproxy/docs/migration.md +131 -0
  92. package/cliproxy/docs/model-health-report.schema.json +364 -0
  93. package/cliproxy/docs/model-health.md +393 -0
  94. package/cliproxy/image.lock.json +5 -0
  95. package/cliproxy/launchd/dev.devfleet.cliproxy-backup-check.plist +38 -0
  96. package/cliproxy/launchd/dev.devfleet.cliproxy-backup.plist +48 -0
  97. package/cliproxy/launchd/dev.devfleet.cliproxy-fleet.plist +32 -0
  98. package/cliproxy/launchd/dev.devfleet.cliproxy-gc.plist +38 -0
  99. package/cliproxy/launchd/dev.devfleet.cliproxy-monitor.plist +29 -0
  100. package/cliproxy/launchd/dev.devfleet.cliproxy-vault-renew.plist +31 -0
  101. package/cliproxy/models.json +1618 -0
  102. package/cliproxy/requirements.lock +78 -0
  103. package/cliproxy/scripts/accounts.py +38 -0
  104. package/cliproxy/scripts/audit.py +123 -0
  105. package/cliproxy/scripts/backup +234 -0
  106. package/cliproxy/scripts/check.py +34 -0
  107. package/cliproxy/scripts/checkpoint.py +226 -0
  108. package/cliproxy/scripts/cli.py +64 -0
  109. package/cliproxy/scripts/cliproxy_host.py +257 -0
  110. package/cliproxy/scripts/cloud_state.py +150 -0
  111. package/cliproxy/scripts/container-health +6 -0
  112. package/cliproxy/scripts/docker +24 -0
  113. package/cliproxy/scripts/external-health.py +79 -0
  114. package/cliproxy/scripts/fleet_config.py +43 -0
  115. package/cliproxy/scripts/fleet_sync.py +274 -0
  116. package/cliproxy/scripts/initialize +84 -0
  117. package/cliproxy/scripts/install-dependencies +48 -0
  118. package/cliproxy/scripts/install.py +406 -0
  119. package/cliproxy/scripts/model_health.py +16 -0
  120. package/cliproxy/scripts/modelhealth/__init__.py +5 -0
  121. package/cliproxy/scripts/modelhealth/checks.py +429 -0
  122. package/cliproxy/scripts/modelhealth/cli.py +117 -0
  123. package/cliproxy/scripts/modelhealth/config.py +186 -0
  124. package/cliproxy/scripts/modelhealth/emulator.py +536 -0
  125. package/cliproxy/scripts/modelhealth/expect.py +88 -0
  126. package/cliproxy/scripts/modelhealth/findings.py +183 -0
  127. package/cliproxy/scripts/modelhealth/protocol.py +330 -0
  128. package/cliproxy/scripts/modelhealth/redact.py +28 -0
  129. package/cliproxy/scripts/modelhealth/report.py +150 -0
  130. package/cliproxy/scripts/modelhealth/runner.py +390 -0
  131. package/cliproxy/scripts/modelhealth/scenario.py +131 -0
  132. package/cliproxy/scripts/modelhealth/schema.py +63 -0
  133. package/cliproxy/scripts/modelhealth/simulate.py +111 -0
  134. package/cliproxy/scripts/modelhealth/transport.py +213 -0
  135. package/cliproxy/scripts/monitor +68 -0
  136. package/cliproxy/scripts/ops +527 -0
  137. package/cliproxy/scripts/public-endpoint +127 -0
  138. package/cliproxy/scripts/recover_node.py +177 -0
  139. package/cliproxy/scripts/restore-verify +60 -0
  140. package/cliproxy/scripts/retention.py +144 -0
  141. package/cliproxy/scripts/service-start +7 -0
  142. package/cliproxy/scripts/validate-config +56 -0
  143. package/cliproxy/scripts/vault-access.py +57 -0
  144. package/cliproxy/scripts/vault-backup-login +55 -0
  145. package/cliproxy/scripts/vault-recovery +56 -0
  146. package/cliproxy/scripts/vault-renew +30 -0
  147. package/cliproxy/systemd/cliproxy-backup-check.service +10 -0
  148. package/cliproxy/systemd/cliproxy-backup-check.timer +8 -0
  149. package/cliproxy/systemd/cliproxy-backup.service +13 -0
  150. package/cliproxy/systemd/cliproxy-backup.timer +8 -0
  151. package/cliproxy/systemd/cliproxy-fleet.service +17 -0
  152. package/cliproxy/systemd/cliproxy-gc.service +13 -0
  153. package/cliproxy/systemd/cliproxy-gc.timer +8 -0
  154. package/cliproxy/systemd/cliproxy-monitor.service +8 -0
  155. package/cliproxy/systemd/cliproxy-monitor.timer +7 -0
  156. package/cliproxy/systemd/cliproxy-vault-renew.service +8 -0
  157. package/cliproxy/systemd/cliproxy-vault-renew.timer +7 -0
  158. package/cliproxy/vendor/LICENSE +22 -0
  159. package/cliproxy/vendor/config.upstream.yaml +1349 -0
  160. package/examples/fleet.json +95 -0
  161. package/examples/roster.json +13 -0
  162. package/mise.lock +1492 -0
  163. package/mise.toml +99 -0
  164. package/package.json +65 -4
  165. package/schema/fleet.schema.json +364 -0
  166. package/schema/roster.schema.json +77 -0
  167. package/src/agents/account-relay.ts +111 -0
  168. package/src/agents/accounts.ts +85 -0
  169. package/src/agents/audit.ts +77 -0
  170. package/src/agents/cli.ts +13 -0
  171. package/src/agents/command.ts +204 -0
  172. package/src/agents/converge.ts +123 -0
  173. package/src/agents/doctor.ts +107 -0
  174. package/src/agents/errors.ts +2 -0
  175. package/src/agents/files.ts +73 -0
  176. package/src/agents/fleet-verify.ts +156 -0
  177. package/src/agents/launch.ts +290 -0
  178. package/src/agents/native-verify.ts +226 -0
  179. package/src/agents/provider-errors.ts +50 -0
  180. package/src/agents/registry.ts +55 -0
  181. package/src/agents/render.ts +110 -0
  182. package/src/agents/round-trip.ts +192 -0
  183. package/src/agents/secrets.ts +13 -0
  184. package/src/agents/toolchain.ts +34 -0
  185. package/src/agents/verify-cache.ts +103 -0
  186. package/src/agents/verify.ts +127 -0
  187. package/src/auth-checks.ts +163 -0
  188. package/src/cli/agent-guide.ts +95 -0
  189. package/src/cli/app.ts +115 -0
  190. package/src/cli/cli.ts +21 -0
  191. package/src/cli/command-index.ts +50 -0
  192. package/src/cli/contracts.ts +25 -0
  193. package/src/cli/fleet-reference.ts +17 -0
  194. package/src/cli/fleet-sync-checkout.ts +91 -0
  195. package/src/cli/fleet-sync-enrollment.ts +144 -0
  196. package/src/cli/fleet-sync-forward.ts +134 -0
  197. package/src/cli/fleet-sync-manager.ts +193 -0
  198. package/src/cli/fleet-sync-monitoring.ts +185 -0
  199. package/src/cli/fleet-sync-output.ts +314 -0
  200. package/src/cli/fleet-sync-privilege.ts +27 -0
  201. package/src/cli/fleet-sync-progress.ts +109 -0
  202. package/src/cli/fleet-sync-remote.ts +236 -0
  203. package/src/cli/fleet-sync-report.ts +26 -0
  204. package/src/cli/fleet-sync-schedule.ts +138 -0
  205. package/src/cli/fleet-sync-vault.ts +166 -0
  206. package/src/cli/fleet-sync.ts +309 -0
  207. package/src/cli/fleet.ts +163 -0
  208. package/src/cli/managed-health.ts +219 -0
  209. package/src/cli/node-deployment.ts +34 -0
  210. package/src/cli/node-sync.ts +114 -0
  211. package/src/cli/node-t3.ts +31 -0
  212. package/src/cli/options.ts +141 -0
  213. package/src/cli/probe-source.ts +7 -0
  214. package/src/cli/program.ts +169 -0
  215. package/src/cli/register-fleet.ts +246 -0
  216. package/src/cli/registry.ts +158 -0
  217. package/src/cli/repair-apply.ts +67 -0
  218. package/src/cli/repair-guard.ts +11 -0
  219. package/src/cli/repair-inspect.ts +150 -0
  220. package/src/cli/repair-script.ts +76 -0
  221. package/src/cli/repair.ts +209 -0
  222. package/src/cli/roster.ts +89 -0
  223. package/src/cli/search.ts +35 -0
  224. package/src/cli/settings.ts +64 -0
  225. package/src/cli/source-operations.ts +78 -0
  226. package/src/cli/t3/command.ts +90 -0
  227. package/src/cli/t3/register.ts +55 -0
  228. package/src/cli/tailnet.ts +127 -0
  229. package/src/cli/ui-actions.ts +133 -0
  230. package/src/cli/ui-controller.ts +113 -0
  231. package/src/cli/ui-data.ts +106 -0
  232. package/src/cli/ui-execute.ts +163 -0
  233. package/src/cli/ui-repairs.ts +34 -0
  234. package/src/cli/ui-reports.ts +211 -0
  235. package/src/cli/ui-targets.ts +100 -0
  236. package/src/cli/ui-terminal.ts +109 -0
  237. package/src/cli/ui-types.ts +49 -0
  238. package/src/cli/ui-wizard.ts +101 -0
  239. package/src/cli/ui.ts +9 -0
  240. package/src/cli/worker-health-output.ts +37 -0
  241. package/src/config.ts +186 -0
  242. package/src/configure.ts +255 -0
  243. package/src/definition.ts +260 -0
  244. package/src/diagnostics.ts +92 -0
  245. package/src/doctor-check.ts +10 -0
  246. package/src/errors.ts +1 -0
  247. package/src/fingerprint.ts +120 -0
  248. package/src/fleet-config.ts +88 -0
  249. package/src/index.ts +6 -0
  250. package/src/input-hashes.ts +73 -0
  251. package/src/machine/local-source.ts +52 -0
  252. package/src/machine/lock-error.ts +2 -0
  253. package/src/machine/platform.ts +44 -0
  254. package/src/machine/source.ts +68 -0
  255. package/src/machine/state.ts +185 -0
  256. package/src/machine-health.ts +95 -0
  257. package/src/managed-source.ts +47 -0
  258. package/src/manager-failure.ts +48 -0
  259. package/src/manager-sync.ts +400 -0
  260. package/src/manager.ts +62 -0
  261. package/src/monitoring/apply.ts +171 -0
  262. package/src/monitoring/beszel.ts +191 -0
  263. package/src/monitoring/enroll.ts +110 -0
  264. package/src/monitoring/hub-access.ts +113 -0
  265. package/src/monitoring/hub-viewer.ts +142 -0
  266. package/src/monitoring/hub.ts +93 -0
  267. package/src/monitoring/manager-agent.ts +73 -0
  268. package/src/monitoring/manager-hub.ts +232 -0
  269. package/src/monitoring/remote.ts +65 -0
  270. package/src/network-definition.ts +83 -0
  271. package/src/node-converge-linux.ts +372 -0
  272. package/src/node-converge-shared.ts +83 -0
  273. package/src/node-converge.ts +40 -0
  274. package/src/onboard.ts +35 -0
  275. package/src/platform/ansible-receipt.ts +128 -0
  276. package/src/platform/ansible.ts +62 -0
  277. package/src/platform/darwin.ts +203 -0
  278. package/src/platform/detect.ts +11 -0
  279. package/src/platform/fallback.ts +110 -0
  280. package/src/platform/index.ts +38 -0
  281. package/src/platform/launchd.ts +98 -0
  282. package/src/platform/linux.ts +139 -0
  283. package/src/platform/ps.ts +45 -0
  284. package/src/platform/resource-verify.ts +128 -0
  285. package/src/platform/systemd-user.ts +95 -0
  286. package/src/platform/t3-policy.ts +137 -0
  287. package/src/platform/t3-route.ts +68 -0
  288. package/src/platform/t3-service.ts +75 -0
  289. package/src/platform/types.ts +123 -0
  290. package/src/platform/ubuntu-audit.ts +63 -0
  291. package/src/platform/ubuntu-verify.ts +105 -0
  292. package/src/platform/windows.ts +148 -0
  293. package/src/power-recovery.ts +55 -0
  294. package/src/probe.ts +51 -0
  295. package/src/protocol.ts +119 -0
  296. package/src/proxy-converge.ts +85 -0
  297. package/src/remote-bootstrap.ts +212 -0
  298. package/src/remote-entry.ts +89 -0
  299. package/src/remote-lock.ts +12 -0
  300. package/src/repair-catalog.ts +206 -0
  301. package/src/repair-plan.ts +78 -0
  302. package/src/repair-runner.ts +84 -0
  303. package/src/report.ts +71 -0
  304. package/src/runner.ts +104 -0
  305. package/src/secrets.ts +169 -0
  306. package/src/service-auth.ts +115 -0
  307. package/src/ssh.ts +135 -0
  308. package/src/sync.ts +104 -0
  309. package/src/t3/accounts.ts +81 -0
  310. package/src/t3/desired.ts +165 -0
  311. package/src/t3/files.ts +81 -0
  312. package/src/t3/names-check.ts +53 -0
  313. package/src/t3/names.ts +155 -0
  314. package/src/t3/plan.ts +82 -0
  315. package/src/t3/providers.ts +74 -0
  316. package/src/t3/reconcile.ts +123 -0
  317. package/src/t3-endpoint.ts +48 -0
  318. package/src/t3-linked-check.ts +101 -0
  319. package/src/tailnet-health.ts +231 -0
  320. package/src/tailnet-matching.ts +37 -0
  321. package/src/tailscale.ts +141 -0
  322. package/src/test-fixtures.ts +36 -0
  323. package/src/toolchain-checks.ts +83 -0
  324. package/src/topology.ts +24 -0
  325. package/src/transport.ts +122 -0
  326. package/src/types.ts +95 -0
  327. package/src/vault-config.ts +38 -0
  328. package/src/worker-access-checks.ts +115 -0
  329. package/src/worker-capacity.ts +34 -0
  330. package/src/worker-host-checks.ts +176 -0
  331. package/src/worker-policy.ts +64 -0
  332. package/src/worker-readiness.ts +64 -0
  333. package/src/workstation-checks.ts +29 -0
@@ -0,0 +1,1349 @@
1
+ # Configuration template using the v8 layout.
2
+ # Copy this file to config.yaml and replace the client keys and any enabled examples.
3
+ # Optional upstream credentials and request rules remain commented until configured.
4
+ # Existing legacy configuration files and /v0/management requests remain supported.
5
+ # When both spellings of a field are present, the v8 value wins (including false,
6
+ # 0, and empty collections), and the corresponding legacy field is removed on load/save.
7
+ # Legacy-only fields still work. GET requests and config-version: 8 alone do not
8
+ # migrate a legacy file; a successful configuration write through /v8/management does.
9
+ # The compatibility notes at the end show old spellings for existing deployments.
10
+ config-version: 8
11
+
12
+ # Optional model catalog sources: http(s) URLs or absolute local file paths.
13
+ # Each explicit source overrides --local-model; otherwise --local-model uses
14
+ # embedded catalogs, and normal mode uses the official remote sources.
15
+ # Failed refreshes retain the last valid catalog; custom sources never fall back
16
+ # to official URLs. Files and URLs are refreshed every 3 hours and on source changes.
17
+ # Home mode never loads the general catalog, even when explicitly configured.
18
+ models:
19
+ catalog: ""
20
+ codex-catalog: ""
21
+ devin-catalog: ""
22
+
23
+ # Listener, TLS, network discovery, and server operation.
24
+ server:
25
+ # Server host/interface to bind to. Default is empty ("") to bind all interfaces (IPv4 + IPv6).
26
+ # Use "127.0.0.1" or "localhost" to restrict access to local machine only.
27
+ host: ""
28
+
29
+ # Server port
30
+ port: 8317
31
+
32
+ # Maximum allowed size (in bytes) for incoming HTTP request bodies.
33
+ # Requests exceeding this limit are rejected with HTTP 413 Payload Too Large.
34
+ # Default is 0 (disabled / no limit).
35
+ max-request-body-bytes: 0
36
+
37
+ # Negotiated compression of downstream HTTP responses (including SSE streams).
38
+ # Responses are compressed only when the client advertises zstd or gzip in
39
+ # Accept-Encoding; WebSocket upgrades are never wrapped. Encoder memory is
40
+ # retained for the lifetime of an open stream and depends on prior pool usage.
41
+ response-compression:
42
+ # Default: true.
43
+ enabled: true
44
+ # Non-streaming responses smaller than this many bytes are sent uncompressed.
45
+ min-bytes: 1024
46
+
47
+ # Global token for GitHub requests (for example, release and asset downloads).
48
+ # A non-empty config token takes precedence over the GITHUB_TOKEN environment variable.
49
+ # Leave empty to use GITHUB_TOKEN, or unauthenticated requests if neither is set.
50
+ github-token: ""
51
+
52
+ # IP addresses or CIDRs of proxies allowed to supply forwarded client IP headers.
53
+ # An empty list (the default) does not trust forwarded headers. Restart after changing this setting.
54
+ trusted-proxies: []
55
+ # Example:
56
+ # trusted-proxies:
57
+ # - 127.0.0.1
58
+ # - 192.0.2.0/24
59
+
60
+ # TLS settings for HTTPS. When enabled, the server listens with the provided certificate and key.
61
+ tls:
62
+ enable: false
63
+ cert: ""
64
+ key: ""
65
+
66
+ # When true, disable high-overhead request logging and HTTP middleware features to reduce per-request memory usage under high concurrency.
67
+ commercial-mode: false
68
+
69
+ # Enable local network mDNS / DNS-SD service discovery (RFC 6762 / RFC 6763).
70
+ # When enabled, broadcasts _ai-gateway._tcp with API protocol subtypes on the local network.
71
+ # TXT records follow draft-su-ai-gateway-discovery-00:
72
+ # txtvers, path, tls, auth, protocols, auth_type, product, id, role
73
+ # The TXT protocols list mirrors the advertised subtypes. Management endpoints are never advertised.
74
+ # NOTE for Docker users: Link-local multicast (224.0.0.251) cannot cross default NAT bridge networks.
75
+ # To broadcast across the physical LAN, run the container with host networking (--net=host / network_mode: host).
76
+ discovery:
77
+ enabled: false
78
+ # service-name: "" # Optional name prefix. Advertised as CPA-<ShortID> or <name>-<ShortID> (e.g. office-8F3B)
79
+ # service-type: "_ai-gateway._tcp" # Service type (RFC 6335 compliant)
80
+ # subtypes: # DNS-SD API protocol subtypes to advertise
81
+ # - "_chat-completions"
82
+ # - "_responses"
83
+ # - "_messages"
84
+ # - "_generate-content"
85
+ # - "_interactions"
86
+ # # Optional extended subtypes: _completions, _responses-ws, _realtime, _images,
87
+ # # _videos, _audio, _count-tokens, _search
88
+ # interfaces:
89
+ # include: [] # White-listed interfaces (empty: auto-detect physical interfaces)
90
+ # exclude: [] # Additional interface patterns to exclude
91
+ # auth-required: true # Advertise auth=1 (credentials required)
92
+
93
+ # Local persistent KV store settings (bbolt). Ignored when Home mode is enabled.
94
+ kv-store:
95
+ # Disable local bbolt KV persistence and fall back to in-memory maps (default: false).
96
+ disabled: false
97
+ # File path for the bbolt database (default: "<auth-dir>/kv.db" when empty).
98
+ path: ""
99
+
100
+ # Management API settings
101
+ management:
102
+ # Whether to allow remote (non-localhost) management access.
103
+ # When false, only localhost can access management endpoints (a key is still required).
104
+ allow-remote: false
105
+
106
+ # Management key. If a plaintext value is provided here, it will be hashed on startup.
107
+ # All management requests (even from localhost) require this key.
108
+ # Leave empty to disable the Management API entirely (404 for /v0/management and /v8/management routes).
109
+ secret-key: ""
110
+
111
+ # Disable the bundled management control panel asset download and HTTP route when true.
112
+ disable-control-panel: false
113
+
114
+ # Disable automatic periodic background updates of the management panel from GitHub (default: false).
115
+ # When enabled, the panel is only downloaded on first access if missing, and never auto-updated afterward.
116
+ # disable-auto-update-panel: false
117
+
118
+ # Base URL of remote management API when using TUI client mode (cliproxyapi --tui).
119
+ # Defaults to http://127.0.0.1:<port> if not set. Can also be set via --management-base-url.
120
+ # base-url: "https://proxy.example.com"
121
+
122
+ # GitHub repository for the management control panel. Accepts a repository URL or releases API URL.
123
+ panel-github-repository: "https://github.com/router-for-me/Cli-Proxy-API-Management-Center"
124
+
125
+ # Client authentication for the proxy API. These are not upstream provider keys.
126
+ access:
127
+ # API keys for authentication
128
+ api-keys:
129
+ - "your-api-key-1"
130
+ - "your-api-key-2"
131
+ - "your-api-key-3"
132
+
133
+ # Optional credential concurrency and observation contracts.
134
+
135
+ # credentials:
136
+ #
137
+ # # Credential concurrency is configured by Home in Home mode. The synthesized Home config is
138
+ # # authoritative and local values, including the values below, are ignored. Do not use local
139
+ # # configuration to override a Home concurrency policy.
140
+ #
141
+ # concurrency:
142
+ # # Revisions are system-owned metadata, not ordinary editable settings.
143
+ # lifecycle-config-revision: 1
144
+ # observation-barrier-revision: 0
145
+ # cpa-heartbeat-timeout: "3s"
146
+ # cpa-cancel-bound: "5s"
147
+ # reclaim-grace: "5s"
148
+ # cleanup-interval: "5s"
149
+ # release-flush-interval: 250ms
150
+ # release-max-backoff: 2s
151
+ # busy-retry-min: 250ms
152
+ # busy-retry-max: 1s
153
+ # max-limit: 1000000
154
+ #
155
+ # # Credential in-flight observation snapshot contract.
156
+ #
157
+ # in-flight:
158
+ # snapshot-interval: 2s
159
+ # stale-after: 10s
160
+ # max-part-bytes: 262144
161
+ # max-part-count: 64
162
+ # max-revision-bytes: 16777216
163
+ # max-aggregate-groups: 100000
164
+ # max-details: 10000
165
+ # max-string-bytes: 256
166
+ # staging-retention: 1m
167
+
168
+ # Routing strategy for selecting credentials when multiple match.
169
+ routing:
170
+ strategy: "round-robin" # round-robin (default), weighted-round-robin, fill-first
171
+ # weighted-round-robin uses each credential's integer weight (default 1, maximum 1,000,000).
172
+ # Non-positive weights exclude the credential while this strategy is active.
173
+ # For OAuth/file credentials, add a top-level numeric "weight" field to the auth JSON.
174
+ # Enable universal session-sticky routing for all clients.
175
+ # Explicit Claude Code, Codex, OpenCode, and pi session headers are preferred,
176
+ # followed by prompt_cache_key, Responses conversation IDs, legacy body IDs,
177
+ # execution or derived session identity, and the existing first-message hash fallback.
178
+ # Automatic failover is always enabled when bound auth becomes unavailable.
179
+ # An established binding outranks credential priority: once a session is bound, that
180
+ # credential is kept even if a higher-priority credential recovers. Credential priority
181
+ # still decides cold bindings, requests without a session, and post-failover rebinding.
182
+ session-affinity: false # default: false
183
+ # How long session-to-auth bindings are retained. Default: 1h
184
+ session-affinity-ttl: "1h"
185
+ # When true (default), subagents (child sessions with parent references) inherit and bind
186
+ # to the parent's upstream credential across all providers (Claude, Codex, Antigravity, Gemini),
187
+ # for the same model, maximizing Prompt/KV Cache reuse and minimizing TTFT.
188
+ # Guardian reviews (X-Openai-Subagent: guardian) may inherit across models from the
189
+ # parent's most recent selection on the same real provider, if that credential is eligible.
190
+ # This includes mixed-provider pools; result-driven TTL refreshes do not reorder selections.
191
+ # Existing child bindings take precedence. Parent lookups do not extend the parent's TTL.
192
+ # When false, subagents are distributed across the credential pool via the fallback selector
193
+ # for maximum parallel concurrency.
194
+ # Ignored when routing.session-affinity is false.
195
+ session-affinity-subagents: true
196
+ # Controls which credential failures rebind an established session to the failover credential:
197
+ # - "any" (default): any credential-attributed failure unbinds and rebinds on failover.
198
+ # - "quota": transient errors (408, 5xx, empty stream, buffer limit) fail over for that
199
+ # request only while keeping the session bound to its original credential; quota and auth
200
+ # errors (429, 401/402/403, 404/model support, invalid_grant) rebind as normal.
201
+ # Ignored when routing.session-affinity is false.
202
+ session-affinity-rebind-on: "any"
203
+
204
+ # When true, unprefixed model requests only use credentials without a prefix (except when prefix == model name).
205
+ force-model-prefix: false
206
+
207
+ retry:
208
+ # Number of additional credential retry rounds after the first round exhausts
209
+ # its eligible credentials. Round 0 is the initial round; round r only admits
210
+ # credentials whose effective request-retry is at least r. Explicit non-negative
211
+ # credential/provider overrides take precedence; omitted or negative overrides
212
+ # inherit this global value, and explicit 0 only admits round 0. New CPA nodes
213
+ # send retry_round=0 for the initial round and increment it for additional rounds;
214
+ # legacy dispatch methods omit the field and keep old semantics.
215
+ # Additional rounds apply to HTTP 403, 408, 429, 500, 502, 503, and 504 failures.
216
+ # Individual credential/provider overrides take precedence; 0 disables additional
217
+ # rounds, while an omitted or negative override inherits this global setting.
218
+ request-retry: 3
219
+
220
+ # Maximum number of different credentials to try in each credential retry round
221
+ # after per-credential round filtering. Set to 0 to try all available
222
+ # credentials. Credentials skipped by this cap still age with the global round,
223
+ # so the cap does not guarantee a fixed number of actual retries per credential.
224
+ max-retry-credentials: 0
225
+
226
+ # Maximum cooldown wait in seconds between retry rounds.
227
+ # Set to 0 or below to never wait for credential cooldown.
228
+ # Retry rounds that need no wait remain controlled by request-retry.
229
+ max-retry-interval: 30
230
+
231
+ cooldown:
232
+ # When true, disable auth/model cooldown scheduling globally (prevents blackout windows after failure states).
233
+ # A credential/provider disable-cooling value, when present, overrides this global value.
234
+ disable-cooling: false
235
+
236
+ # When true, persist per-auth cooldown status as .cds files next to auth files.
237
+ # Default is false; when false, cooldown status is kept in memory only.
238
+ save-cooldown-status: false
239
+
240
+ # Cooldown duration in seconds for transient upstream errors (408/500/502/503/504/520-526).
241
+ # Set to 0 to keep the legacy 60-second cooldown; set to -1 to disable transient error cooldowns.
242
+ transient-error-cooldown-seconds: 0
243
+
244
+ # Shared request/response behavior.
245
+ requests:
246
+ # Proxy URL. Supports socks5/http/https protocols. Example: socks5://user:pass@192.168.1.1:1080/
247
+ # Per-entry proxy-url also supports "direct" or "none" to bypass both the global proxy-url and environment proxies explicitly.
248
+ proxy-url: ""
249
+ # Connection pooling has no global switch: it is enabled per api-key credential with
250
+ # `connection-pool` on an api-keys entry (group level, overridable per key). See the
251
+ # api-keys section below. OAuth credentials are never pooled by this setting;
252
+ # Antigravity keeps its own antigravity.connection-pool switch.
253
+
254
+ # Maximum time, in seconds, for upstream TLS handshakes made by the shared built-in
255
+ # uTLS client. It applies to both the Claude Code Anthropic transport and the Chrome
256
+ # ChatGPT/Codex transport; the standard fallback transport is unaffected. The timer
257
+ # starts after TCP or proxy connection establishment returns; it does not bound dialing
258
+ # or proxy CONNECT. When the upstream path accepts the connection but never answers the
259
+ # TLS ClientHello, the request would otherwise wait indefinitely and request-retry could
260
+ # never engage. The bound applies only during the TLS handshake and is lifted once it
261
+ # succeeds, so inference and long-running streams are never time-limited.
262
+ # Set to 0 to disable (default).
263
+ tls-handshake-timeout-seconds: 0
264
+
265
+ # When true, forward filtered upstream response headers to downstream clients.
266
+ # Default is false (disabled).
267
+ passthrough-headers: false
268
+
269
+ # When > 0, emit blank lines every N seconds for non-streaming responses to prevent idle timeouts.
270
+ nonstream-keepalive-interval: 0
271
+
272
+ # Streaming behavior (SSE keep-alives + safe bootstrap retries).
273
+ # streaming:
274
+ # keepalive-seconds: 15 # Default: 0 (disabled). <= 0 disables keep-alives.
275
+ # bootstrap-retries: 1 # Default: 0 (disabled). Retries before first byte is sent.
276
+ # send-keepalive-before-ft: false # Default: false. When true and keepalive-seconds > 0, send SSE heartbeats before the first token.
277
+
278
+ # Optional payload configuration
279
+ # payload:
280
+ # default: # Default rules only set parameters when they are missing in the payload.
281
+ # - models:
282
+ # - name: "gemini-2.5-pro" # Supports wildcards (e.g., "gemini-*")
283
+ # protocol: "gemini" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
284
+ # from-protocol: "responses" # restricts the rule to the source protocol, options: openai, responses, gemini, claude
285
+ # headers: # all configured request headers must match; values support "*" wildcards
286
+ # X-Client-Tier: "tenant-*-region-*"
287
+ # match: # all payload JSON paths must equal the configured values
288
+ # - "metadata.client": "codex"
289
+ # not-match: # payload JSON paths must not equal the configured values
290
+ # - "metadata.mode": "dev"
291
+ # exist: # all payload JSON paths must exist and not be null
292
+ # - "tools.#(type==\"web_search\").type"
293
+ # not-exist: # all payload JSON paths must be missing or null
294
+ # - "metadata.disable_payload"
295
+ # params: # JSON path (gjson/sjson syntax) -> value
296
+ # "generationConfig.thinkingConfig.thinkingBudget": 32768
297
+ # default-raw: # Default raw rules set parameters using raw JSON when missing (must be valid JSON).
298
+ # - models:
299
+ # - name: "gemini-2.5-pro" # Supports wildcards (e.g., "gemini-*")
300
+ # protocol: "gemini" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
301
+ # params: # JSON path (gjson/sjson syntax) -> raw JSON value (strings are used as-is, must be valid JSON)
302
+ # "generationConfig.responseJsonSchema": "{\"type\":\"object\",\"properties\":{\"answer\":{\"type\":\"string\"}}}"
303
+ # override: # Override rules always set parameters, overwriting any existing values.
304
+ # - models:
305
+ # - name: "gpt-5.4-fast"
306
+ # protocol: "codex"
307
+ # - name: "gpt-5.5-fast"
308
+ # protocol: "codex"
309
+ # params:
310
+ # service_tier: priority
311
+ # - models:
312
+ # - name: "gpt-*" # Supports wildcards (e.g., "gpt-*")
313
+ # protocol: "codex" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
314
+ # params: # JSON path (gjson/sjson syntax) -> value
315
+ # "reasoning.effort": "high"
316
+ # - models:
317
+ # - name: "claude-fable-5-1"
318
+ # protocol: "claude"
319
+ # params:
320
+ # max_tokens: 128000 # override the final Claude Messages output budget after protocol translation
321
+ # override-raw: # Override raw rules always set parameters using raw JSON (must be valid JSON).
322
+ # - models:
323
+ # - name: "gpt-*" # Supports wildcards (e.g., "gpt-*")
324
+ # protocol: "codex" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
325
+ # params: # JSON path (gjson/sjson syntax) -> raw JSON value (strings are used as-is, must be valid JSON)
326
+ # "response_format": "{\"type\":\"json_schema\",\"json_schema\":{\"name\":\"answer\",\"schema\":{\"type\":\"object\"}}}"
327
+ # filter: # Filter rules remove specified parameters from the payload.
328
+ # - models:
329
+ # - name: "gemini-2.5-pro" # Supports wildcards (e.g., "gemini-*")
330
+ # protocol: "gemini" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
331
+ # params: # JSON paths (gjson/sjson syntax) to remove from the payload
332
+ # - "generationConfig.thinkingConfig.thinkingBudget"
333
+ # - "generationConfig.responseJsonSchema"
334
+ # - models:
335
+ # - name: "gpt-*" # Supports wildcards (e.g., "gpt-*")
336
+ # protocol: "codex"
337
+ # params:
338
+ # # Flat tools array (standard OpenAI format or Codex CLI < 0.154):
339
+ # - 'tools.#(name=="apply_patch")'
340
+ # # Nested additional_tools structure in input[] (Codex CLI >= 0.154 "Responses Lite"):
341
+ # - 'input.#(type=="additional_tools")#.tools.#(name=="functions")#.tools.#(name=="apply_patch")#'
342
+
343
+ # Client-facing compatibility settings apply to both OAuth and API-key routes.
344
+ client:
345
+ codex:
346
+ # When false (default), only models that natively declare freeform apply_patch advertise it.
347
+ # When true, non-template and bridged models supported by every routing executor also advertise "freeform".
348
+ enable-apply-patch: false
349
+ # When true, optimize Codex Desktop, codex-tui, and codex_cli_rs requests for multi-agent v2.
350
+ # This refreshes Codex spawn_agent model details, removes message parameter encryption,
351
+ # normalizes encrypted agent_message content for Codex, and converts agent_message input
352
+ # into standard user messages for non-Codex upstream protocols.
353
+ # Default false. Applies to both OAuth and API-key credentials across providers.
354
+ # Legacy provider paths migrate here; this path wins conflicts, including explicit false.
355
+ optimize-multi-agent-v2: false
356
+ # Cache upstream web search results per session so replayed Codex web_search_call items
357
+ # that omit results still retain search results in later turns.
358
+ web-search-result-cache:
359
+ enabled: false
360
+ ttl: "24h"
361
+ limit: 1024
362
+
363
+ claude:
364
+ # Show public Codex commentary as visible Claude text, retaining phase markers
365
+ # for replay. Genuine reasoning summaries remain thinking blocks.
366
+ # Default false preserves existing behavior for clients such as TTS consumers.
367
+ show-codex-commentary: false
368
+
369
+ # Shared upstream behavior applies to OAuth and API-key credentials.
370
+ upstream:
371
+ codex:
372
+ # Experimental full-duplex Codex Responses WebSocket steering (default: false).
373
+ # Keeps one upstream account/model per socket; accepted input is never replayed.
374
+ response-steering: false
375
+ # Compress request bodies sent to the ChatGPT Codex backend with zstd,
376
+ # mirroring the official Codex client. Applies only to OAuth credentials
377
+ # targeting https://chatgpt.com/backend-api/codex (API-key credentials,
378
+ # custom base URLs, and SIWC requests are never compressed). A 400/415
379
+ # rejection is retried once with an uncompressed body. Default: false.
380
+ upstream-request-compression: false
381
+ # Request bodies smaller than this many bytes are sent uncompressed.
382
+ upstream-request-compression-min-bytes: 1024
383
+ # Enable permessage-deflate compression on Codex WebSocket connections
384
+ # (upstream and downstream) after negotiation. Default: true.
385
+ websocket-compression: true
386
+ # Disable forcing the official Codex User-Agent and Originator headers on HTTP/SSE and WebSocket requests.
387
+ disable-codex-cloaking: false
388
+ # Hold back the frames that carry nothing the client has seen - the handshake (response.created,
389
+ # response.in_progress, the websocket metadata frames), keepalive heartbeats, and the *.added
390
+ # announcements of an item or part that is still empty - until the upstream emits its first
391
+ # generated event. Anything else, including a server-side tool item such as web_search_call and
392
+ # any frame not on that list, releases the stream immediately. On the SSE transport the lines that
393
+ # are not `data:` frames - comments, `event:` lines, blank separators - are held alongside them.
394
+ # The hold is bounded by a frame budget and a 1 MiB byte budget, not by wall-clock time: an
395
+ # upstream that trickles frames holds the response headers for as long as the client will wait.
396
+ # Why: the upstream smuggles `server_is_overloaded` rejections *inside* an HTTP 200 stream,
397
+ # right after those handshake events, instead of returning 503 on the wire. Buffering them
398
+ # keeps the downstream response headers uncommitted long enough to transparently retry on
399
+ # another credential. Only overload/rate-limit rejections trigger failover; every other terminal
400
+ # failure is still delivered in-stream exactly as before. One pre-existing behaviour is worth
401
+ # knowing, because this option makes the window it lives in much longer: if the stream ends while
402
+ # the bootstrap is still holding, the attempt ends instead of the error reaching the client, and
403
+ # whether another credential is then tried depends on how it ended. A clean end with no terminal
404
+ # event is request-scoped on SSE, so nothing else is tried; a websocket close, or a transport error
405
+ # such as a dropped connection on either transport, is not, so the request may be retried on
406
+ # another credential. None of that is new, but before this option the hold ended at the first
407
+ # keepalive, so it was rare; now it can span the whole reasoning phase.
408
+ # Trade-off: response headers are delayed until generation starts. Because heartbeats are held
409
+ # too, the delay now ends at the first generated token rather than at the first heartbeat. The
410
+ # budget bounds how much is held, not how long: 48 SSE lines, which measures out as 15 heartbeats
411
+ # of the three-line event:/data:/blank shape, 23 of a two-line ": keepalive" comment followed by
412
+ # its blank separator, or 47 of a bare ": keepalive" with no separator - one short of the obvious
413
+ # division, because the rejection frame's own event: line comes out of the same budget before its
414
+ # data: line is parsed. An upstream that sends the rejection as a bare data: line with no event:
415
+ # line gets the round number instead. At a 10s upstream heartbeat that is 150s, 230s or 470s of
416
+ # uncommitted response headers depending on the framing the upstream picks, all of it past nginx's
417
+ # 60s default proxy_read_timeout, so raise the timeouts in front of the proxy before enabling this.
418
+ # Those seconds bound what the buffer holds, not when the response headers are committed. Headers
419
+ # are committed on the first chunk the downstream translator actually produces, so for a format
420
+ # that renders the handshake as nothing - Chat Completions and Gemini do - they stay uncommitted
421
+ # past the budget, until the first generated token. That is not specific to the budget: any frame
422
+ # that releases the buffer has always behaved this way.
423
+ # The websocket transport spends the same 48 differently - one per message read, whether the loop
424
+ # holds it or skips it, with no framing to divide by - so there it is 48 heartbeats, about 480s.
425
+ # Two cases no budget covers: a websocket peer that sends only ping frames, which the library
426
+ # answers inside the read call, leaving only the 5 minute websocket read deadline; and an upstream
427
+ # that stops mid-line on SSE, where the scanner never returns and only the request context ends the
428
+ # wait. Neither is made worse by this option - with it off the same stalled line stalls the
429
+ # conductor instead, which waits on the same context - but a client-side request timeout, not
430
+ # proxy_read_timeout, is what bounds them.
431
+ # Default: false
432
+ stream-bootstrap-buffering: false
433
+ # Optional maximum duration to hold back uncommitted response headers during bootstrap buffering.
434
+ # When set (e.g. "20s"), if the time ceiling is reached before the first generated token,
435
+ # the stream is released to the client and further in-stream overloads are delivered rather
436
+ # than failed over. This bounds how long trickled heartbeats or early empty frames can delay
437
+ # response headers before streaming begins.
438
+ # Recommendation: If your CPA is deployed behind a reverse proxy with a strict read timeout
439
+ # (e.g. Nginx default proxy_read_timeout 60s or Cloudflare 100s timeout), setting this to "20s"
440
+ # is strongly recommended to guarantee headers commit well before proxy timeouts while retaining
441
+ # a comfortable 20s window to fail over early scheduling overloads.
442
+ # Note: The timeout check is evaluated as upstream frames arrive; it never aborts the upstream
443
+ # connection. Downstream headers are committed as soon as the downstream translator emits chunks
444
+ # (for formats that render handshake/heartbeats, headers commit immediately on release; for
445
+ # formats like Chat Completions and Gemini that render nothing until the first text token, headers
446
+ # commit when that first token arrives).
447
+ # When unset or set to "0", "0s", "none", "unlimited", "disabled", "off", or "never", no time ceiling
448
+ # is applied, and buffering relies purely on the 48-frame and 1MB byte budget.
449
+ # Default: "0" (unlimited)
450
+ stream-bootstrap-timeout: "0"
451
+ # When true, enable opt-in compatibility for orphan Codex delegation outputs.
452
+ # Converts orphan function_call_output items from codex_app/create_thread and
453
+ # codex_app/send_message_to_thread (which lack a valid call_id or matching function_call)
454
+ # into standard user messages across Responses and non-Codex protocols when the request
455
+ # header contains X-Openai-Subagent: collab_spawn.
456
+ orphan-delegation-compatibility: false
457
+ # When true, scope Codex usage_limit_reached quota cooldowns to the requested model rather
458
+ # than cooling down the entire credential across all sibling models.
459
+ # Default: false
460
+ model-level-cooling: false
461
+
462
+ claude:
463
+ # When true, scope quota cooldowns to the requested model rather than cooling down
464
+ # the entire credential across all sibling models. Default is false.
465
+ model-level-cooling: false
466
+
467
+ # When true, enable Codex client tool_search on Claude Responses routes. Credentials on
468
+ # api.anthropic.com (or keys with native-tool-search: true) receive it as Anthropic native
469
+ # tool search (defer_loading + tool_reference), which keeps the prompt-cache prefix stable
470
+ # across tool discoveries; other credentials fall back to the plain translation. The Codex
471
+ # model catalog advertises supports_search_tool for a Claude model only when every
472
+ # credential serving it supports native tool search.
473
+ # Default false keeps the translation and catalog behavior that predate tool_search support.
474
+ tool-search: false
475
+
476
+ # Days to retain the cloaked currentDate pin per session in in-memory mode
477
+ # (server.kv-store.disabled: true without Home), so an idle gap or a credential
478
+ # switch cannot re-anchor the date and invalidate earlier thinking signatures and the
479
+ # prompt cache. Default 7; an explicit 0 keeps the continuity-scoped pin (1h lifetime).
480
+ # When a KV store (local bbolt or Home KV) is active, session date pins are persisted
481
+ # permanently and session-date-pin-days is ignored.
482
+ session-date-pin-days: 7
483
+
484
+ # When true, disable Claude request cloaking on OAuth and API-key CLI profiles (the Claude Code CLI disguise and
485
+ # system prompt replacement), so the original system prompt is passed through to Claude as-is.
486
+ # Credential attributes and explicit per-key cloak modes override this shared default.
487
+ # Default false keeps the per-client "auto" behavior (cloak only non-Claude-Code clients).
488
+ # API-key overrides use api-keys.claude[].keys[].cloak.mode.
489
+ disable-claude-cloak-mode: false
490
+
491
+ # When true, return original model IDs in Anthropic model list responses instead of cloaked IDs.
492
+ disable-cloaking-model-list: false
493
+
494
+ # Anthropic-Beta is assembled per request rather than sent as a fixed list, matching
495
+ # Claude Code: context-1m sits right after claude-code, mid-conversation-system
496
+ # is added only for models that accept a role=system turn, advanced-tool-use only when
497
+ # the request uses tool search (deferred tools) or another advanced tool-use feature,
498
+ # afk-mode sits between fast-mode and extended-cache-ttl, and server-side-fallback / fallback-credit /
499
+ # structured-outputs trail effort. On direct api.anthropic.com a caller may only ask for
500
+ # betas real Claude Code also sends, and they are placed at their observed positions;
501
+ # anything else is dropped so the outgoing set stays one a real client could produce.
502
+ # Other Anthropic-compatible upstreams still forward caller betas verbatim.
503
+ #
504
+ # Shared Claude CLI fingerprint defaults. Update only after measuring a new Claude Code release.
505
+ # Unconfirmed clients use this CLI baseline. Verified native Claude Code CLI, sdk-cli,
506
+ # sdk-ts, and VSCode requests preserve their measured entrypoint when the Claude Code version is a
507
+ # patch release in the configured major/minor line at or above this baseline. Older versions
508
+ # and newer major/minor lines fall back to the baseline until measured. In legacy mode,
509
+ # timeout is a fallback and
510
+ # verified native OS/arch values remain client-supplied. When stabilize-device-profile is
511
+ # enabled, OS/arch are pinned to the values below and cached profiles remain constrained to
512
+ # the same exact software baseline rather than learning newer client versions (unless the
513
+ # credential resolves to cloak_mode: never, which preserves the confirmed caller's headers).
514
+ # header-defaults:
515
+ # user-agent: "claude-cli/2.1.280 (external, cli)"
516
+ # package-version: "0.112.1"
517
+ # runtime-version: "v26.3.0"
518
+ # os: "MacOS"
519
+ # arch: "arm64"
520
+ # timeout: "600"
521
+ # timezone: "Asia/Singapore" # fallback IANA timezone for cloaked currentDate; a credential JSON "timezone" takes priority
522
+ # stabilize-device-profile: false # optional, default false; set true to enable per-auth fingerprint pinning
523
+ # # Additional Claude Code entrypoint labels (beyond built-in cli, sdk-cli, sdk-ts, claude-vscode)
524
+ # # treated as native Claude Code for passthrough when strong signals match (e.g. T3 Code's "t3-code").
525
+ # native-entrypoints: ["t3-code"]
526
+ # # Advanced operator overrides for exact-parity or gateway lanes. They apply to every Claude
527
+ # # request, after the per-request derivation above, and can produce a beta set real Claude Code
528
+ # # never sends, which api.anthropic.com may reject. Names are matched exactly; strip runs first.
529
+ # # A credential's own "headers" entries are more specific and keep precedence where they already
530
+ # # did: Anthropic-Beta on custom gateways and x-client-request-id everywhere.
531
+ # anthropic-beta-strip: [] # remove these names from the derived or caller-supplied set, keeping order
532
+ # anthropic-beta-append: [] # append these names at the end unless already present
533
+ # # Cloaked requests to api.anthropic.com get a "diagnostics" body field like Claude Code, which in
534
+ # # turn adds cache-diagnosis-2026-04-07. Set false to stop injecting it (default true).
535
+ # inject-diagnostics: true
536
+ # # x-client-request-id on first-party CLI-profile requests: "on" (default) synthesizes a fresh
537
+ # # UUID per request (a confirmed Claude Code client keeps its own), "passthrough" forwards only
538
+ # # the caller's value and never synthesizes one, "off" never sends the header.
539
+ # client-request-id: "on"
540
+
541
+ xai:
542
+ # When true, inject the native x_search tool when the request does not declare it.
543
+ # The injected tool is also added to tool_choice.allowed_tools when applicable.
544
+ inject-x-search: false
545
+
546
+ # API-key upstreams are separate from access.api-keys (client authentication).
547
+ # Each provider contains named groups: one base-url, shared settings, and a keys list.
548
+ # Add another group for another endpoint; base-url belongs to the group, not a key.
549
+ # Shared settings retain their provider-specific validation and meaning.
550
+ # Missing/null per-key overrides inherit the group value, then the runtime fallback.
551
+ # Explicit false, 0, empty strings, and empty collections override inheritance when
552
+ # supported by the field. Map/list overrides replace the inherited value as a whole.
553
+ # Negative request-retry values retain the global fallback; weight belongs to each key.
554
+ # An empty proxy-url falls back to requests.proxy-url; direct bypasses proxy settings.
555
+ # Shared provider defaults belong to upstream; OAuth-only features remain under oauth.providers.
556
+ # Keep differing legacy policies in separate groups or preserve them as key overrides.
557
+ # Uncomment the api-keys root and only the provider examples you want to configure.
558
+ # Replace placeholder keys/URLs before using them.
559
+
560
+ # BEGIN API KEY EXAMPLES
561
+
562
+ # api-keys:
563
+ #
564
+ # # Gemini API keys
565
+ #
566
+ # gemini:
567
+ # - name: gemini-1
568
+ # priority: 0 # larger values take precedence when selecting credentials
569
+ # prefix: "test" # optional: require calls like "test/gemini-3-pro-preview" to target this credential
570
+ # disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global
571
+ # request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global
572
+ # request-scoped-errors: # optional: custom rules to classify upstream errors by status and body patterns
573
+ # - status: 400 # HTTP status code to match
574
+ # match: # optional: string contains matching
575
+ # - "maximum_context_length"
576
+ # - "context_length_exceeded"
577
+ # match-regexr: # optional: regular expression matching
578
+ # - "maximum_context_length$"
579
+ # - "^context_length_exceeded"
580
+ # action: "stop" # "stop" (return error, no cooling), "stop-and-cooldown" (return error and cool down),
581
+ # # "continue" (try next credential, no cooling), "continue-and-cooldown" (try next credential and cool down)
582
+ # base-url: "https://generativelanguage.googleapis.com"
583
+ # headers:
584
+ # X-Custom-Header: "custom-value"
585
+ # # Values starting with "$" dynamically copy the header value from downstream client requests.
586
+ # # If the client did not send the specified header, the header is omitted.
587
+ # # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header
588
+ # proxy-url: "socks5://proxy.example.com:1080"
589
+ # # proxy-url: "direct" # optional: explicit direct connect for this credential
590
+ # models:
591
+ # - name: "gemini-2.5-flash" # upstream model name
592
+ # alias: "gemini-flash" # client alias mapped to the upstream model
593
+ # display-name: "Gemini Flash" # optional catalog display name
594
+ # max-context-length: 1048576 # optional: override Codex client context window metadata
595
+ # is-compat: false # optional: preserve thinking blocks with empty signatures for compatible upstreams
596
+ # thinking: # optional: exact thinking capability for this configured model
597
+ # levels: ["high", "medium", "low", "none", "auto"]
598
+ # # For budget-based models, replace levels with these capabilities:
599
+ # # min: 1024
600
+ # # max: 32768
601
+ # # zero-allowed: true
602
+ # # dynamic-allowed: true
603
+ # excluded-models:
604
+ # - "gemini-2.5-pro" # exclude specific models from this provider (exact match)
605
+ # - "gemini-2.5-*" # wildcard matching prefix (e.g. gemini-2.5-flash, gemini-2.5-pro)
606
+ # - "*-preview" # wildcard matching suffix (e.g. gemini-3-pro-preview)
607
+ # - "*flash*" # wildcard matching substring (e.g. gemini-2.5-flash-lite)
608
+ # keys:
609
+ # - api-key: "AIzaSy...01"
610
+ # weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000
611
+ # # A second key shares this group's endpoint, headers, and models.
612
+ # - api-key: "replace-with-second-gemini-key"
613
+ # weight: 2
614
+ # priority: null # inherit the group priority
615
+ # prefix: null # inherit the group prefix
616
+ # proxy-url: "direct" # override the group proxy for this key
617
+ # headers: null # inherit the complete group header map
618
+ # models: null # inherit the complete group model list
619
+ # excluded-models: [] # explicitly clear the inherited exclusions
620
+ # disable-cooling: false # an explicit false overrides a true group setting
621
+ # request-retry: 0 # explicitly disable additional rounds for this key
622
+ # request-scoped-errors: null # inherit the group rules
623
+ # - name: gemini-2
624
+ # keys:
625
+ # - api-key: "AIzaSy...02"
626
+ #
627
+ # # Native Interactions API keys
628
+ # # These keys are used only for direct /v1beta/interactions execution. Regular api-keys.gemini entries still
629
+ # # send Gemini generateContent/streamGenerateContent requests when the client enters through the interactions API.
630
+ #
631
+ # interactions:
632
+ # - name: interactions-1
633
+ # prefix: "native" # optional: require calls like "native/gemini-3-pro-preview" to target this credential
634
+ # disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global
635
+ # request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global
636
+ # request-scoped-errors: # optional: custom rules to classify upstream errors by status and body patterns
637
+ # - status: 400
638
+ # match:
639
+ # - "invalid_argument"
640
+ # action: "continue"
641
+ # base-url: "https://generativelanguage.googleapis.com"
642
+ # headers:
643
+ # X-Custom-Header: "custom-value"
644
+ # # Values starting with "$" dynamically copy the header value from downstream client requests.
645
+ # # If the client did not send the specified header, the header is omitted.
646
+ # # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header
647
+ # proxy-url: "socks5://proxy.example.com:1080"
648
+ # # proxy-url: "direct" # optional: explicit direct connect for this credential
649
+ # models:
650
+ # - name: "gemini-2.5-flash" # upstream model name
651
+ # alias: "native-gemini-flash" # client alias mapped to the upstream model
652
+ # max-context-length: 1048576 # optional: override Codex client context window metadata
653
+ # is-compat: false # optional: preserve thinking blocks with empty signatures for compatible upstreams
654
+ # thinking: # optional: exact thinking capability for this configured model
655
+ # levels: ["high", "medium", "low", "none", "auto"]
656
+ # excluded-models:
657
+ # - "gemini-2.5-pro"
658
+ # keys:
659
+ # - api-key: "AIzaSy...03"
660
+ # weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000
661
+ #
662
+ # # Vertex API keys (Vertex-compatible endpoints, base-url is optional)
663
+ #
664
+ # vertex:
665
+ # - name: vertex-1
666
+ # prefix: "test" # optional: require calls like "test/vertex-pro" to target this credential
667
+ # disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global
668
+ # request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global
669
+ # base-url: "https://example.com/api" # optional, e.g. https://zenmux.ai/api; falls back to Google Vertex when omitted
670
+ # proxy-url: "socks5://proxy.example.com:1080" # optional per-key proxy override
671
+ # # proxy-url: "direct" # optional: explicit direct connect for this credential
672
+ # # interactions: true # optional: opt into native Vertex Interactions API routing (/v1beta1/interactions). For service account JSON files under auths/, add "interactions": true at the root of the file.
673
+ # headers:
674
+ # X-Custom-Header: "custom-value"
675
+ # # Values starting with "$" dynamically copy the header value from downstream client requests.
676
+ # # If the client did not send the specified header, the header is omitted.
677
+ # # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header
678
+ # models: # optional: map aliases to upstream model names
679
+ # - name: "gemini-2.5-flash" # upstream model name
680
+ # alias: "vertex-flash" # client-visible alias
681
+ # display-name: "Vertex Flash" # optional catalog display name
682
+ # thinking: # optional: exact thinking capability for this configured model
683
+ # levels: ["high", "medium", "low", "none", "auto"]
684
+ # - name: "gemini-2.5-pro"
685
+ # alias: "vertex-pro"
686
+ # excluded-models: # optional: models to exclude from listing
687
+ # - "imagen-3.0-generate-002"
688
+ # - "imagen-*"
689
+ # keys:
690
+ # - api-key: "vk-123..." # x-goog-api-key header
691
+ # weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000
692
+ #
693
+ # # Codex API keys
694
+ #
695
+ # codex:
696
+ # - name: codex-1
697
+ # prefix: "test" # optional: require calls like "test/gpt-5-codex" to target this credential
698
+ # disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global
699
+ # request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global
700
+ # request-scoped-errors: # optional: custom rules to classify upstream errors by status and body patterns
701
+ # - status: 400
702
+ # match:
703
+ # - "context_window_exceeded"
704
+ # action: "stop-and-cooldown"
705
+ # base-url: "https://www.example.com" # use the custom codex API endpoint
706
+ # headers:
707
+ # X-Custom-Header: "custom-value"
708
+ # # Values starting with "$" dynamically copy the header value from downstream client requests.
709
+ # # If the client did not send the specified header, the header is omitted.
710
+ # # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header
711
+ # proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override
712
+ # # proxy-url: "direct" # optional: explicit direct connect for this credential
713
+ # # Optional connection reuse for this credential group. Writing the block is the opt-in;
714
+ # # `connection-pool: {}` opts in with the defaults below. Pools stay per key, so pooling
715
+ # # one key never shares connections with another key. Applies to the standard transport
716
+ # # and the Claude Code TLS transport (Anthropic upstreams); the ChatGPT browser-profile
717
+ # # transport keeps its one-connection-per-request lifecycle.
718
+ # # Defaults: idle-conn-timeout 300s, max-idle-conns-per-host 2. Zero or negative values
719
+ # # disable keep-alives (every request dials). Authenticated proxy URLs are isolated per
720
+ # # proxy credential digest so rotating user:pass or sticky-session usernames never mix.
721
+ # # connection-pool:
722
+ # # enabled: true
723
+ # # idle-conn-timeout: "300s" # defaults to 300s; measured upstreams reuse idle conns >600s
724
+ # # max-idle-conns-per-host: 2 # defaults to 2
725
+ # models:
726
+ # - name: "gpt-5-codex" # upstream model name
727
+ # alias: "codex-latest" # client alias mapped to the upstream model
728
+ # display-name: "Codex Latest" # optional catalog display name
729
+ # max-context-length: 1048576 # optional: override Codex client context window metadata
730
+ # force-mapping: true # optional: rewrite response model fields back to the alias
731
+ # # Preserve thinking blocks with empty signatures for compatible upstreams.
732
+ # # client.codex.optimize-multi-agent-v2 applies to both OAuth and API-key credentials.
733
+ # is-compat: false
734
+ # # Optional: enable configuration_update for this API-key model; omitted defaults to false.
735
+ # support-configuration-update: false
736
+ # thinking: # optional: exact thinking capability for this configured model
737
+ # levels: ["xhigh", "high", "medium", "low"]
738
+ # excluded-models:
739
+ # - "gpt-5.1" # exclude specific models (exact match)
740
+ # - "gpt-5-*" # wildcard matching prefix (e.g. gpt-5-medium, gpt-5-codex)
741
+ # - "*-mini" # wildcard matching suffix (e.g. gpt-5-codex-mini)
742
+ # - "*codex*" # wildcard matching substring (e.g. gpt-5-codex-low)
743
+ # keys:
744
+ # - api-key: "sk-atSM..."
745
+ # weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000
746
+ # # connection-pool: # optional: per-key override of the group pool setting
747
+ # # enabled: false # opt this key out while the group stays pooled
748
+ # disable-codex-cloaking: false # optional: true disables cloaking; OAuth provider settings do not apply here
749
+ # alpha-search: false # optional: allow this key to serve /v1/alpha/search via base-url + /alpha/search
750
+ # websockets: false # optional: use the Codex upstream WebSocket transport
751
+ #
752
+ # # Claude API keys
753
+ #
754
+ # claude:
755
+ # - name: claude-1
756
+ # keys:
757
+ # - api-key: "sk-atSM..." # use the official claude API key, no need to set the base url
758
+ # - name: claude-2
759
+ # prefix: "test" # optional: require calls like "test/claude-sonnet-latest" to target this credential
760
+ # disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global
761
+ # request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global
762
+ # request-scoped-errors: # optional: custom rules to classify upstream errors by status and body patterns
763
+ # - status: 400
764
+ # match:
765
+ # - "prompt is too long"
766
+ # action: "stop"
767
+ # base-url: "https://www.example.com" # use the custom claude API endpoint
768
+ # headers:
769
+ # X-Custom-Header: "custom-value"
770
+ # # Values starting with "$" dynamically copy the header value from downstream client requests.
771
+ # # If the client did not send the specified header, the header is omitted.
772
+ # # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header
773
+ # proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override
774
+ # # proxy-url: "direct" # optional: explicit direct connect for this credential
775
+ # models:
776
+ # - name: "claude-3-5-sonnet-20241022" # upstream model name
777
+ # alias: "claude-sonnet-latest" # client alias mapped to the upstream model
778
+ # display-name: "Claude Sonnet" # optional catalog display name
779
+ # max-context-length: 1048576 # optional: override Codex client context window metadata
780
+ # force-mapping: true # optional: rewrite response model fields back to the alias
781
+ # is-compat: false # optional: preserve thinking blocks with empty signatures for compatible upstreams
782
+ # thinking: # optional: exact thinking capability for this configured model
783
+ # levels: ["max", "xhigh", "high", "medium", "low", "minimal", "none", "auto"]
784
+ # excluded-models:
785
+ # - "claude-opus-4-5-20251101" # exclude specific models (exact match)
786
+ # - "claude-3-*" # wildcard matching prefix (e.g. claude-3-7-sonnet-20250219)
787
+ # - "*-thinking" # wildcard matching suffix (e.g. claude-opus-4-5-thinking)
788
+ # - "*haiku*" # wildcard matching substring (e.g. claude-3-5-haiku-20241022)
789
+ # keys:
790
+ # - api-key: "sk-atSM..."
791
+ # weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000
792
+ # rebuild-mid-system-message: false # optional: default is false; when true, move messages with role "system" into the top-level Claude system field
793
+ # native-tool-search: false # optional: default is false; when true, trust this key's custom base-url with Anthropic native tool search (defer_loading + tool_reference) for Codex tool_search; requires upstream.claude.tool-search: true
794
+ # cloak: # optional: explicitly enable request cloaking for non-Claude-Code clients
795
+ # mode: "auto" # "auto" (default inside this block): cloak only when client is not Claude Code
796
+ # # "always": cloak every unconfirmed client; confirmed native Claude Code still passes through
797
+ # # "never" / "uncloak": never apply cloaking; on non-CLI API keys, also strip incoming Claude Code identity/billing attribution
798
+ # # This "cloak" block applies to this api-keys.claude key entry only. For Claude OAuth
799
+ # # credentials, set the same options in the auth/token JSON file via "cloak_mode" /
800
+ # # "cloak_strict_mode" / "cloak_sensitive_words" / "cloak_cache_user_id".
801
+ # # upstream.claude.disable-claude-cloak-mode is the shared default; this key can override it.
802
+ # strict-mode: false # false (default): legacy-model whitelist uses a user system-reminder;
803
+ # # all other and future models use messages[].role=system
804
+ # # true: strip caller prompts and keep only Claude Code billing and identity blocks
805
+ # sensitive-words: # optional: words to obfuscate with zero-width characters
806
+ # - "API"
807
+ # - "proxy"
808
+ # cache-user-id: true # optional: default is false; set true to reuse cached user_id per API key instead of generating a random one each request
809
+ # # Every custom tool on a cloaked OAuth request automatically uses a caller-stable opaque mcp__<server>__<tool> alias.
810
+ #
811
+ # # fingerprint-profile (optional, top-level on this api-keys.claude key entry; not a cloak sub-field):
812
+ # # OAuth and API-key fingerprints are different contracts.
813
+ # # - Real Claude OAuth stays on the strict Claude Code CLI wire fingerprint.
814
+ # # - API keys (official Anthropic, custom gateways, Kimi) stay loose and
815
+ # # caller-owned unless this field is set.
816
+ # #
817
+ # # Default (omit / empty): keep the caller request fingerprint and headers.
818
+ # # Official api.anthropic.com API keys do not add extra CLI betas/identity unless
819
+ # # this field is set. Custom gateways and delegated providers are the same.
820
+ # #
821
+ # # Controls request fingerprint only on /v1/messages (and related Claude executor paths).
822
+ # # Auth scheme stays API key (x-api-key on api.anthropic.com; Bearer on custom base-url).
823
+ # # Does NOT enable OAuth refresh, profile fetch, or OAuth-cancellation semantics.
824
+ # #
825
+ # # Values:
826
+ # # omit / empty = caller-owned API-key fingerprint (respects caller)
827
+ # # "claude-code-cli" = same Messages fingerprint as Claude Code OAuth CLI,
828
+ # # including official Anthropic API keys: OAuth Anthropic-Beta
829
+ # # set, CCH signing on api.anthropic.com, stable CLI
830
+ # # metadata.user_id / session_id / device identity.
831
+ # # API keys seed identity from the key;
832
+ # # delegated OAuth providers use stable auth ID instead of
833
+ # # rotating access tokens. "oauth-cli" is a legacy alias.
834
+ # #
835
+ # # count_tokens keeps the native model/messages/tools shape for every origin, including
836
+ # # Kimi opt-in. It does not send billing/CCH, currentDate, metadata, or diagnostics.
837
+ # #
838
+ # # CCH: the billing block may carry a per-request cch hash. CPA emits it exactly where
839
+ # # Claude Code does, which is api.anthropic.com (first-party) and Vertex only. An opt-in
840
+ # # on any other gateway (including Kimi) still sends the billing block, but without cch,
841
+ # # so a per-request hash cannot bust that gateway's prompt cache. api.anthropic.com
842
+ # # strips the block itself (0 tokens, no cache impact). Kimi drops the whole block by
843
+ # # default and keeps it, unsigned, after an explicit fingerprint opt-in.
844
+ # # A real Claude OAuth credential always signs, on every upstream: a downstream Claude
845
+ # # Code pointed at CPA cannot produce that value itself.
846
+ # #
847
+ # # Example group under api-keys.claude (official Anthropic or a Messages gateway):
848
+ # # - name: cli-compatible-gateway
849
+ # # # base-url: "https://gateway.example" # omit for api.anthropic.com
850
+ # # keys:
851
+ # # - api-key: "your-key"
852
+ # # fingerprint-profile: "claude-code-cli"
853
+ # # cloak:
854
+ # # mode: "always" # recommended when upstream rejects non-CLI clients
855
+ # #
856
+ # # Delegated Anthropic Messages OAuth files (Kimi, etc.) use "fingerprint_profile"
857
+ # # in the auth JSON. Refresh keeps it. Example:
858
+ # # {
859
+ # # "type": "kimi",
860
+ # # "access_token": "...",
861
+ # # "refresh_token": "...",
862
+ # # "fingerprint_profile": "claude-code-cli"
863
+ # # }
864
+ # # Legacy "fingerprint-profile" credentials remain supported and are normalized at load time.
865
+ # # fingerprint-profile: "claude-code-cli" # optional api-keys.claude key field; default is empty (caller-owned); uncomment to opt in
866
+ # experimental-cch-signing: false # deprecated compatibility field; CCH is generated automatically
867
+ # # for real Claude OAuth on any upstream, and for claude-code-cli profiles
868
+ # # only on api.anthropic.com; Vertex keeps provider-native signing
869
+ #
870
+ # # xAI API keys
871
+ # # Uses the native xAI executor, including its Responses namespace-tool handling.
872
+ #
873
+ # xai:
874
+ # - name: xai-1
875
+ # prefix: "xai" # optional: require calls like "xai/grok-4.5" to target this credential
876
+ # disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global
877
+ # request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global
878
+ # request-scoped-errors: # optional: custom rules to classify upstream errors by status and body patterns
879
+ # - status: 400
880
+ # match:
881
+ # - "rate_limit_exceeded"
882
+ # action: "continue-and-cooldown"
883
+ # base-url: "https://api.x.ai/v1" # xAI-compatible Responses API endpoint
884
+ # headers:
885
+ # X-Custom-Header: "custom-value"
886
+ # # Values starting with "$" dynamically copy the header value from downstream client requests.
887
+ # # If the client did not send the specified header, the header is omitted.
888
+ # # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header
889
+ # proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override
890
+ # # proxy-url: "direct" # optional: explicit direct connect for this credential
891
+ # models:
892
+ # - name: "grok-4.5" # upstream model name
893
+ # alias: "grok-latest" # client alias mapped to the upstream model
894
+ # display-name: "Grok Latest" # optional catalog display name
895
+ # max-context-length: 1048576 # optional: override Codex client context window metadata
896
+ # force-mapping: true # optional: rewrite response model fields back to the alias
897
+ # is-compat: false # optional: preserve thinking blocks with empty signatures for compatible upstreams
898
+ # thinking: # optional: exact thinking capability for this configured model
899
+ # levels: ["xhigh", "high", "medium", "low"]
900
+ # excluded-models:
901
+ # - "grok-4.1" # exclude specific models (exact match)
902
+ # - "grok-3-*" # wildcard matching prefix
903
+ # keys:
904
+ # - api-key: "xai-..."
905
+ # weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000
906
+ # websockets: true # optional: use the xAI upstream websocket transport for downstream websocket requests
907
+ #
908
+ # # Meta API keys (Muse Code)
909
+ # # Uses the native Meta executor targeting https://api.meta.ai/v1.
910
+ #
911
+ # meta:
912
+ # - name: meta-1
913
+ # prefix: "meta" # optional: require calls like "meta/muse-spark-1.3" to target this credential
914
+ # disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global
915
+ # request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global
916
+ # base-url: "https://api.meta.ai/v1" # optional: defaults to https://api.meta.ai/v1
917
+ # proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override
918
+ # models:
919
+ # - name: "muse-spark-1.3" # upstream model name
920
+ # alias: "muse-latest" # client alias mapped to the upstream model
921
+ # excluded-models:
922
+ # - "muse-spark-1.1"
923
+ # keys:
924
+ # - api-key: "..."
925
+ # weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000
926
+ #
927
+ # # OpenAI compatibility providers
928
+ #
929
+ # openai-compatibility:
930
+ # - name: "openrouter" # The name of the provider; it will be used in the user agent and other places.
931
+ # disabled: false # optional: set to true to disable this provider without removing it
932
+ # prefix: "test" # optional: require calls like "test/kimi-k2" to target this provider's credentials
933
+ # base-url: "https://openrouter.ai/api/v1" # The base URL of the provider.
934
+ # support-prompt-cache-key: false # optional: derive prompt_cache_key for requests from all input protocols
935
+ # disable-cooling: false # optional provider override: true disables cooling, false enables it; omit to inherit global
936
+ # request-retry: 3 # optional per-provider override; 0 disables additional rounds; omit or set < 0 to inherit global
937
+ # request-scoped-errors: # optional: custom rules to classify upstream errors by status and body patterns
938
+ # - status: 400
939
+ # match:
940
+ # - "maximum_context_length"
941
+ # - "context_length_exceeded"
942
+ # match-regexr:
943
+ # - "maximum_context_length$"
944
+ # - "^context_length_exceeded"
945
+ # action: "stop" # "stop", "stop-and-cooldown", "continue", "continue-and-cooldown"
946
+ # headers:
947
+ # X-Custom-Header: "custom-value"
948
+ # # Values starting with "$" dynamically copy the header value from downstream client requests.
949
+ # # If the client did not send the specified header, the header is omitted.
950
+ # # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header
951
+ # keys:
952
+ # - api-key: "sk-or-v1-...b780"
953
+ # weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000
954
+ # proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override
955
+ # # proxy-url: "direct" # optional: explicit direct connect for this credential
956
+ # # connection-pool: # optional: per-key override of the group pool block
957
+ # # enabled: true
958
+ # - api-key: "sk-or-v1-...b781" # without proxy-url
959
+ # models: # The models supported by the provider.
960
+ # - name: "moonshotai/kimi-k2:free" # The actual model name.
961
+ # alias: "kimi-k2" # The alias used in the API.
962
+ # display-name: "Kimi K2" # optional catalog display name
963
+ # max-context-length: 1048576 # optional: override Codex client context window metadata
964
+ # image: false # optional: set true to allow this model on /v1/images/generations and /v1/images/edits (not chat/responses image input)
965
+ # input-modalities: [text, image] # optional: declare /v1/chat/completions and /v1/responses multimodal input for Codex clients. Use [text] for upstreams that reject multimodal tool result content.
966
+ # output-modalities: [text] # optional: declare output modalities when known
967
+ # is-compat: false # optional: preserve Claude thinking blocks for compatible upstreams
968
+ # use-max-completion-tokens: false # optional: default false (uses max_tokens); set true to use max_completion_tokens
969
+ # thinking: # optional: omit to default to levels ["low","medium","high"]. Exceeding levels (e.g. "max", "xhigh") are clamped to "high"; explicitly declare levels here if the upstream supports them
970
+ # levels: ["low", "medium", "high"]
971
+ # # You may repeat the same alias to build an internal model pool.
972
+ # # The client still sees only one alias in the model list.
973
+ # # Requests to that alias will round-robin across the upstream names below,
974
+ # # and if the chosen upstream fails before producing output, the request will
975
+ # # continue with the next upstream model in the same alias pool.
976
+ # - name: "deepseek-v3.1"
977
+ # alias: "claude-opus-4.66"
978
+ # - name: "glm-5"
979
+ # alias: "claude-opus-4.66"
980
+ # - name: "kimi-k2.5"
981
+ # alias: "claude-opus-4.66"
982
+
983
+ # END API KEY EXAMPLES
984
+
985
+ # OAuth/file-backed credentials. Token material stays in the credential store.
986
+ oauth:
987
+ # Authentication directory (supports ~ for home directory)
988
+ auth-dir: "~/.cli-proxy-api"
989
+
990
+ # Core auth auto-refresh and manual refresh-all worker pool size (OAuth/file-based auth token refresh).
991
+ # When > 0, overrides the default worker count (16).
992
+ # auth-auto-refresh-workers: 16
993
+
994
+ # Global OAuth model name aliases (per channel)
995
+ # These aliases rename model IDs for both model listing and request routing.
996
+ # Supported channels: vertex, aistudio, antigravity, claude, codex, kimi, xai, meta.
997
+ # NOTE: These aliases do not apply to any of the upstream groups under api-keys.
998
+ # NOTE: Because aliases affect the merged /v1 model list and merged request routing, overlapping
999
+ # client-visible names can become ambiguous across providers. For strict backend pinning, use
1000
+ # unique aliases/prefixes or avoid overlapping names.
1001
+ # You can repeat the same name with different aliases to expose multiple client model names.
1002
+ # Optional per-entry fields:
1003
+ # fork: true # keep the upstream model and also expose the alias as a separate client-visible model
1004
+ # display-name: "Model Name" # override the human-readable name shown in model catalogs
1005
+ # force-mapping: true # rewrite upstream response model fields back to the client-visible alias (example below uses antigravity only)
1006
+ # Per-auth OAuth aliases can also be stored in an OAuth auth JSON file as "model_aliases".
1007
+ # Legacy "model-aliases" credentials remain supported and are normalized at load time.
1008
+ # They apply only to that selected auth and take precedence over global aliases for the same client-visible alias.
1009
+ # Example auth JSON:
1010
+ # {
1011
+ # "type": "codex",
1012
+ # "email": "user@example.com",
1013
+ # "model_aliases": [
1014
+ # {"name": "gpt-5.3-codex-spark", "alias": "gpt-5.5"},
1015
+ # {"name": "gpt-5.3-codex-spark", "alias": "gpt-5.4"}
1016
+ # ]
1017
+ # }
1018
+ # model-alias:
1019
+ # vertex:
1020
+ # - name: "gemini-2.5-pro"
1021
+ # alias: "g2.5p"
1022
+ # aistudio:
1023
+ # - name: "gemini-2.5-pro"
1024
+ # alias: "g2.5p"
1025
+ # antigravity:
1026
+ # - name: "gemini-pro-agent" # upstream Antigravity model id
1027
+ # alias: "gemini-3.1-pro-preview" # client-visible id (Gemini 3.1 Pro Preview)
1028
+ # display-name: "Antigravity Gemini 3.1 Pro" # optional catalog display name
1029
+ # fork: true
1030
+ # force-mapping: true
1031
+ # claude:
1032
+ # - name: "claude-sonnet-4-5-20250929"
1033
+ # alias: "cs4.5"
1034
+ # codex:
1035
+ # - name: "gpt-5"
1036
+ # alias: "g5"
1037
+ # kimi:
1038
+ # - name: "kimi-k2.5"
1039
+ # alias: "k2.5"
1040
+ # xai:
1041
+ # - name: "grok-4.3"
1042
+ # alias: "grok-latest"
1043
+ # meta:
1044
+ # - name: "muse-spark-1.3"
1045
+ # alias: "muse-latest"
1046
+ # sample-provider: # plugin provider keys are supported for OAuth plugins
1047
+ # - name: "sample-model-latest"
1048
+ # alias: "sample-latest"
1049
+
1050
+ # OAuth provider model settings (per channel)
1051
+ # Allows overriding model-level capabilities (such as context window) for OAuth credentials.
1052
+ # Supported channels: vertex, aistudio, antigravity, claude, codex, kimi, xai, meta.
1053
+ # settings:
1054
+ # codex:
1055
+ # - name: "gpt-6-sol"
1056
+ # max-context-length: 524288 # overrides context window advertised to Codex clients
1057
+ # - name: "gpt-6-astra"
1058
+ # max-context-length: 1048576
1059
+
1060
+ # OAuth provider excluded models
1061
+ # Applies to OAuth/file-backed credentials of each provider.
1062
+ # A credential's own non-empty "excluded_models" list (set in its auth JSON file) takes priority
1063
+ # over these rules for that credential and is not merged with them. Credentials without their own
1064
+ # list (missing, empty, or null) inherit the current rules here; changes to these rules
1065
+ # take effect for them on config reload.
1066
+ # excluded-models:
1067
+ # vertex:
1068
+ # - "gemini-3-pro-preview"
1069
+ # aistudio:
1070
+ # - "gemini-3-pro-preview"
1071
+ # antigravity:
1072
+ # - "gemini-3-pro-preview"
1073
+ # claude:
1074
+ # - "claude-3-5-haiku-20241022"
1075
+ # codex:
1076
+ # - "gpt-5-codex-mini"
1077
+ # kimi:
1078
+ # - "kimi-k2-thinking"
1079
+ # xai:
1080
+ # - "grok-3-mini"
1081
+ # meta:
1082
+ # - "muse-spark-1.1"
1083
+
1084
+ # OAuth provider request-scoped error rules (custom error classification for OAuth credentials)
1085
+ # request-scoped-errors:
1086
+ # vertex:
1087
+ # - status: 400
1088
+ # match:
1089
+ # - "maximum_context_length"
1090
+ # - "context_length_exceeded"
1091
+ # match-regexr:
1092
+ # - "maximum_context_length$"
1093
+ # - "^context_length_exceeded"
1094
+ # action: "stop" # options: "stop", "stop-and-cooldown", "continue", "continue-and-cooldown"
1095
+ # aistudio:
1096
+ # - status: 400
1097
+ # match:
1098
+ # - "invalid_argument"
1099
+ # action: "stop"
1100
+ # antigravity:
1101
+ # - status: 500
1102
+ # match:
1103
+ # - "internal_server_error"
1104
+ # action: "stop-and-cooldown"
1105
+ # claude:
1106
+ # - status: 400
1107
+ # match:
1108
+ # - "prompt is too long"
1109
+ # action: "stop"
1110
+ # codex:
1111
+ # - status: 400
1112
+ # match:
1113
+ # - "context_window_exceeded"
1114
+ # action: "stop"
1115
+ # kimi:
1116
+ # - status: 400
1117
+ # match:
1118
+ # - "length_limit"
1119
+ # action: "stop"
1120
+ # xai:
1121
+ # - status: 400
1122
+ # match:
1123
+ # - "max_tokens_exceeded"
1124
+ # action: "stop"
1125
+ # meta:
1126
+ # - status: 400
1127
+ # match:
1128
+ # - "context_length_exceeded"
1129
+ # action: "stop"
1130
+
1131
+ # Provider options below apply to OAuth/file-backed credentials.
1132
+ # API-key credentials use their own group/key options.
1133
+ providers:
1134
+ aistudio:
1135
+ # When true, enable authentication for the WebSocket API (/v1/ws).
1136
+ ws-auth: true
1137
+
1138
+ # Codex provider behavior.
1139
+ codex:
1140
+ # Terminate and relay Codex Live WebRTC audio and DataChannel traffic in this process.
1141
+ # This requires inbound UDP reachability. Keep disabled to preserve direct media behavior.
1142
+ live-media-relay:
1143
+ enabled: false
1144
+ # Maximum concurrent media sessions. Zero uses the default of 32.
1145
+ max-sessions: 32
1146
+ # Reject downstream SDP candidates that target private, loopback, link-local, or unspecified IPs.
1147
+ # Keep false for local or trusted-network Codex Desktop connections.
1148
+ disable-private-remote-ips: false
1149
+ # Public IPv4 or IPv6 address advertised when CPA is behind 1:1 NAT.
1150
+ public-ip: ""
1151
+ # Optional UDP allocation range. Both values must be set together and provide at least two ports per session.
1152
+ udp-port-min: 0
1153
+ udp-port-max: 0
1154
+ # Optional STUN/TURN servers. TURN credentials are never returned by the JSON config API.
1155
+ # Without a concrete global/per-auth proxy-url, WebRTC uses normal direct ICE/STUN/TURN connectivity.
1156
+ # With http, https, socks5, or socks5h proxy-url, the OpenAI-facing leg is forced through
1157
+ # authenticated ICE-TCP over that proxy and never falls back to UDP or a direct connection.
1158
+ # The Codex Desktop-facing leg remains direct, and configured ICE servers still apply to it.
1159
+ # ice-servers:
1160
+ # - urls:
1161
+ # - "stun:stun.example.com:3478"
1162
+ # - urls:
1163
+ # - "turn:turn.example.com:3478?transport=udp"
1164
+ # username: "user"
1165
+ # credential: "secret"
1166
+
1167
+ # Identifier (agent_name_hint and User-Agent prefix) for Sign in with ChatGPT (SIWC) OAuth and API requests.
1168
+ signin-with-chatgpt-identifier: "CLIProxyAPI"
1169
+
1170
+ # Default headers for Codex OAuth model requests.
1171
+ # These are used only for file-backed/OAuth Codex requests when the client
1172
+ # does not send the header. `user-agent` applies to HTTP and websocket requests;
1173
+ # `beta-features` only applies to websocket requests. They do not apply to api-keys.codex entries.
1174
+ # header-defaults:
1175
+ # user-agent: "codex_cli_rs/0.114.0 (Mac OS 14.2.0; x86_64) vscode/1.111.0"
1176
+ # beta-features: "multi_agent"
1177
+
1178
+ # Antigravity provider behavior.
1179
+ antigravity:
1180
+ # sensitive-words: # optional: words to obfuscate with zero-width characters in system instructions
1181
+ # - "API"
1182
+ # - "proxy"
1183
+ # connection-pool: # optional: upstream HTTP connection pool settings
1184
+ # enabled: false # whether to enable connection pooling (default: false)
1185
+ # idle-conn-timeout: "30s" # idle keep-alive timeout (default: 30s, capped at 210s)
1186
+ # max-idle-conns-per-host: 2 # max idle connections per host per credential (default: 2)
1187
+ # Use credits as a last resort after free-tier Claude quota is exhausted.
1188
+ antigravity-credits: true
1189
+
1190
+ # Signature cache validation for thinking blocks (Antigravity/Claude).
1191
+ # When true (default), cached signatures are preferred and validated.
1192
+ # When false, client signatures are used directly after normalization (bypass mode for testing).
1193
+ # signature-cache-enabled: true
1194
+
1195
+ # Bypass mode signature validation strictness (only applies when signature cache is disabled).
1196
+ # When true, validates full Claude protobuf tree (Field 2 -> Field 1 structure).
1197
+ # When false (default), only checks R/E prefix + base64 + first byte 0x12.
1198
+ # signature-bypass-strict: false
1199
+
1200
+ # Devin provider behavior.
1201
+ # devin:
1202
+ # sensitive-words: # optional: words to obfuscate with zero-width characters in system instructions and prompts
1203
+ # - "API"
1204
+ # - "proxy"
1205
+
1206
+ # Image and video behavior.
1207
+ multimedia:
1208
+ # disable-image-generation supports: false (default), true, "chat", or "passthrough".
1209
+ # - true: disable image_generation everywhere (also returns 404 for /v1/images/generations and /v1/images/edits).
1210
+ # - "chat": disable image_generation injection on non-images endpoints, but keep /v1/images/generations and /v1/images/edits enabled.
1211
+ # - "passthrough": never inject or strip image_generation on non-images endpoints (forward the client payload unchanged); behaves like "chat" on /v1/images/* endpoints.
1212
+ disable-image-generation: false
1213
+
1214
+ # Base model used by the legacy hosted image_generation tool path when a Codex image request is not proxied directly through the Image API.
1215
+ # Must start with "gpt-" (case-insensitive). If unset or invalid, defaults to "gpt-5.4-mini".
1216
+ # gpt-image-2-base-model: "gpt-5.4-mini"
1217
+
1218
+ # Grok video routes accept grok-imagine-video, grok-imagine-video-1.5,
1219
+ # grok-imagine-video-1.5-preview, and grok-imagine-video-1.5-lite.
1220
+ # Supported on /openai/v1/videos and the native xAI /v1/videos/* endpoints.
1221
+ # The OpenAI-compatible route accepts resolution 480p, 720p, or 1080p (default: 720p).
1222
+ # Built-in xAI video models remain available when a refreshed catalog omits them.
1223
+
1224
+ # How long video IDs returned by /openai/v1/videos and xAI video creation stay bound
1225
+ # to the credential that created them. Default: 3h.
1226
+ video-result-auth-cache-ttl: "3h"
1227
+
1228
+ # Application logs, request logs, usage aggregation, and profiling.
1229
+ observability:
1230
+ logs:
1231
+ # Enable debug logging
1232
+ debug: false
1233
+
1234
+ # When true, write application logs to rotating files instead of stdout
1235
+ logging-to-file: false
1236
+
1237
+ # Maximum total size (MB) of log files under the logs directory. When exceeded, the oldest log
1238
+ # files are deleted until within the limit. Set to 0 to disable.
1239
+ logs-max-total-size-mb: 0
1240
+
1241
+ # Maximum number of error log files retained when request logging is disabled.
1242
+ # When exceeded, the oldest error log files are deleted. Default is 10. Set to 0 to disable cleanup.
1243
+ error-logs-max-files: 10
1244
+
1245
+ # Record proxy request/response logs. Management requests are excluded.
1246
+ request-log: false
1247
+
1248
+ usage:
1249
+ # When false, disable in-memory usage statistics aggregation
1250
+ usage-statistics-enabled: false
1251
+
1252
+ # How long (in seconds) usage queue items are retained in memory for the Management API.
1253
+ # The local Redis RESP usage output is disabled.
1254
+ # Default: 60. Max: 3600.
1255
+ redis-usage-queue-retention-seconds: 60
1256
+
1257
+ # Enable pprof HTTP debug server (host:port). Keep it bound to localhost for safety.
1258
+ pprof:
1259
+ enable: false
1260
+ addr: "127.0.0.1:8316"
1261
+
1262
+ # Standard dynamic library plugins are trusted in-process code. They are disabled by default.
1263
+ # Build Go examples with go build -buildmode=c-shared for the target GOOS/GOARCH.
1264
+ # Other languages can implement the same C ABI and JSON method protocol.
1265
+ # Plugin executors require a matching auth record with the same provider key.
1266
+ # If the same provider is configured as OpenAI-compatible, the native executor wins.
1267
+ # Plugin command-line flags and Management API routes are optional capabilities.
1268
+ # Existing native flags/routes and higher-priority plugin flags/routes cannot be replaced.
1269
+ # Plugin list Management API reads Logo and ConfigFields from plugin metadata for management UI display.
1270
+ # Per-plugin enabled only controls plugins.configs.<pluginID>.enabled and does not implicitly change global plugins.enabled.
1271
+ plugins:
1272
+ enabled: false
1273
+ dir: "plugins"
1274
+ # Additional plugin store registries. The built-in official registry is always included.
1275
+ # store-sources:
1276
+ # - "https://example.com/cliproxy-plugins/registry.json"
1277
+ # Optional plugin store auth rules. Secrets are read from environment variables.
1278
+ # Tokens are not stored in plugin manifests or node status.
1279
+ # store-auth:
1280
+ # - match: "https://plugins.example.com/bearer/"
1281
+ # apply-to: ["registry", "artifact"]
1282
+ # type: "bearer"
1283
+ # token-env: "CLIPROXY_PLUGIN_STORE_TOKEN"
1284
+ # allow-insecure: false
1285
+ # - match: "https://plugins.example.com/basic/"
1286
+ # apply-to: ["registry", "artifact"]
1287
+ # type: "basic"
1288
+ # username-env: "CLIPROXY_PLUGIN_STORE_USER"
1289
+ # password-env: "CLIPROXY_PLUGIN_STORE_PASSWORD"
1290
+ # allow-insecure: false
1291
+ # - match: "https://plugins.example.com/header/"
1292
+ # apply-to: ["registry", "artifact"]
1293
+ # type: "header"
1294
+ # header-name: "X-Plugin-Token"
1295
+ # header-value-env: "CLIPROXY_PLUGIN_STORE_HEADER_TOKEN"
1296
+ # allow-insecure: false
1297
+ # - match: "https://api.github.com/repos/example/"
1298
+ # apply-to: ["registry", "artifact"]
1299
+ # type: "github-token"
1300
+ # token-env: "CLIPROXY_PLUGIN_GITHUB_TOKEN"
1301
+ # allow-insecure: false
1302
+
1303
+ # Home owns this revision; it is not an ordinary editable setting.
1304
+ # auth-revision: 0
1305
+
1306
+ configs:
1307
+ example:
1308
+ enabled: true
1309
+ priority: 1
1310
+ config1: true
1311
+ config2: "string"
1312
+ config3: 3
1313
+ mode: "safe" # enum example: safe, fast
1314
+ config-list: ["a", "b"]
1315
+ config-object:
1316
+ mode: "safe"
1317
+
1318
+ # Legacy compatibility reference (comments only; not part of this v8 template).
1319
+ # Old files and /v0/management still work without a v8 write. Existing legacy-only
1320
+ # fields remain in their old locations until a successful v8 configuration write.
1321
+ # When manually mixing layouts, a present new field wins over its legacy equivalent.
1322
+ # To deliberately use an old field again, remove its corresponding new field first.
1323
+ # Client keys moved from the old api-keys list to access.api-keys; the new root
1324
+ # api-keys is reserved for provider groups. These cannot share one YAML key.
1325
+ #
1326
+ # Old spellings shown for reference:
1327
+ # host: "" # now server.host
1328
+ # port: 8317 # now server.port
1329
+ # remote-management: # now management
1330
+ # allow-remote: false
1331
+ # secret-key: ""
1332
+ # api-keys: ["your-api-key-1"] # now access.api-keys
1333
+ # request-retry: 3 # now routing.retry.request-retry
1334
+ # debug: false # now observability.logs.debug
1335
+ # proxy-url: "" # now requests.proxy-url
1336
+ # auth-dir: "~/.cli-proxy-api" # now oauth.auth-dir
1337
+ # codex: # now oauth.providers.codex
1338
+ # disable-codex-cloaking: false
1339
+ # codex-api-key: # now api-keys.codex groups with keys
1340
+ # - api-key: "your-upstream-key"
1341
+ # base-url: "https://codex.example.com"
1342
+ #
1343
+ # Compatibility-only quota switches have no new v8 counterpart. They remain
1344
+ # readable/editable in legacy files and through /v0/management, but are omitted
1345
+ # from the active v8 template:
1346
+ # quota-exceeded:
1347
+ # switch-project: true
1348
+ # switch-preview-model: true
1349
+ # antigravity-credits moved to oauth.providers.antigravity.antigravity-credits.