fix(xai): track the official Grok CLI version for cli-chat-proxy

cli-chat-proxy.grok.com started rejecting every request on 2026-10-01
with HTTP 426 "Your Grok CLI version (0.2.120) is outdated. Please
update to version 1.0.13 or later", because x-grok-client-version and
the xai-grok-workspace user agent were pinned to 0.2.120.

Replace the pin with a runtime-published version (built-in fallback
1.0.46) and add a gateway worker, modelled on the Codex profile worker,
that prewarms at startup and refreshes every 3h:

- read the official stable channel https://x.ai/cli/stable, falling
  back to npm @xai-official/grok/latest (deployments that cannot reach
  x.ai directly), requiring all six platform binaries at one version;
- never roll back, persist the verified version in runtime KV and
  restore it on restart;
- AETHER_XAI_CLIENT_VERSION pins a version, and
  AETHER_XAI_CLIENT_PROFILE_REFRESH=off disables the network check.

Endpoint header rules still win over the injected identity headers.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
stabey
2026-10-01 14:53:26 +08:00
co-authored by Claude Opus 5.5
parent 54fbcc25a1
commit 2257c3959f
7 changed files with 693 additions and 6 deletions
+9
View File
@@ -75,6 +75,7 @@ use crate::maintenance::spawn_stats_hourly_aggregation_worker;
use crate::maintenance::spawn_usage_cleanup_worker;
use crate::maintenance::spawn_usage_counter_flush_worker;
use crate::maintenance::spawn_wallet_daily_usage_aggregation_worker;
use crate::xai_profile::spawn_worker as spawn_xai_client_profile_worker;
const SYSTEM_CONFIG_CACHE_TTL: Duration = Duration::from_secs(30);
// Requests may use a stale value after the fresh window until the entry reaches
@@ -153,6 +154,10 @@ impl AppState {
crate::codex_profile::prewarm(self.runtime_state()).await
}
pub async fn prewarm_xai_client_profile(&self) -> Result<String, String> {
crate::xai_profile::prewarm(self.runtime_state()).await
}
pub async fn prewarm_chat_pii_redaction_runtime_config(&self) -> Result<bool, String> {
crate::privacy::read_chat_pii_redaction_runtime_config(self)
.await
@@ -2351,6 +2356,10 @@ impl AppState {
crate::task_runtime::TASK_KEY_CODEX_CLIENT_PROFILE,
Some(spawn_codex_client_profile_worker(background_state.clone())),
);
supervise_worker(
crate::task_runtime::TASK_KEY_XAI_CLIENT_PROFILE,
Some(spawn_xai_client_profile_worker(background_state.clone())),
);
supervise_worker(
crate::task_runtime::TASK_KEY_VIDEO_TASK_POLLER,
spawn_video_task_poller(background_state.clone()),