mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-07 01:47:47 +08:00
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:
co-authored by
Claude Opus 5.5
parent
54fbcc25a1
commit
2257c3959f
@@ -199,7 +199,8 @@ pub use windsurf::{
|
||||
pub use xai::{
|
||||
extract_xai_user_id_from_auth_config, extract_xai_user_id_from_value,
|
||||
insert_cli_identity_headers, insert_cli_identity_headers_if_needed, is_xai_provider_transport,
|
||||
resolved_xai_request_base_url, resolved_xai_upstream_base_url,
|
||||
should_attach_cli_identity_headers, xai_auth_uses_api, xai_uses_official_api, XAI_API_BASE_URL,
|
||||
XAI_CHAT_PROXY_BASE_URL, XAI_PROVIDER_TYPE,
|
||||
resolved_xai_request_base_url, resolved_xai_upstream_base_url, set_xai_client_version,
|
||||
should_attach_cli_identity_headers, xai_auth_uses_api, xai_client_version,
|
||||
xai_uses_official_api, XAI_API_BASE_URL, XAI_CHAT_PROXY_BASE_URL, XAI_DEFAULT_CLIENT_VERSION,
|
||||
XAI_PROVIDER_TYPE,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod video;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::{OnceLock, RwLock};
|
||||
|
||||
use aether_ai_formats::normalize_api_format_alias;
|
||||
use serde_json::Value;
|
||||
@@ -10,7 +11,10 @@ use crate::snapshot::GatewayProviderTransportSnapshot;
|
||||
pub const XAI_PROVIDER_TYPE: &str = "xai";
|
||||
pub const XAI_CHAT_PROXY_BASE_URL: &str = "https://cli-chat-proxy.grok.com/v1";
|
||||
pub const XAI_API_BASE_URL: &str = "https://api.x.ai/v1";
|
||||
pub const XAI_CLIENT_VERSION: &str = "0.2.120";
|
||||
/// 内置的 Grok CLI 版本;网关后台任务会用官方发布版本覆盖它。
|
||||
///
|
||||
/// cli-chat-proxy 会对过旧的版本直接返回 426,因此这里只作为发布检查不可用时的兜底。
|
||||
pub const XAI_DEFAULT_CLIENT_VERSION: &str = "1.0.46";
|
||||
pub const XAI_TOKEN_AUTH_HEADER: &str = "x-xai-token-auth";
|
||||
pub const XAI_TOKEN_AUTH_VALUE: &str = "xai-grok-cli";
|
||||
pub const XAI_CLIENT_VERSION_HEADER: &str = "x-grok-client-version";
|
||||
@@ -19,8 +23,37 @@ pub const XAI_CLIENT_IDENTIFIER_VALUE: &str = "grok-shell";
|
||||
pub const XAI_AUTHENTICATE_RESPONSE_HEADER: &str = "x-authenticateresponse";
|
||||
pub const XAI_AUTHENTICATE_RESPONSE_VALUE: &str = "authenticate-response";
|
||||
|
||||
static ACTIVE_CLIENT_VERSION: OnceLock<RwLock<String>> = OnceLock::new();
|
||||
|
||||
fn active_client_version() -> &'static RwLock<String> {
|
||||
ACTIVE_CLIENT_VERSION.get_or_init(|| RwLock::new(XAI_DEFAULT_CLIENT_VERSION.to_owned()))
|
||||
}
|
||||
|
||||
/// 返回当前发布的 Grok CLI 版本快照。
|
||||
pub fn xai_client_version() -> String {
|
||||
active_client_version()
|
||||
.read()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
||||
.clone()
|
||||
}
|
||||
|
||||
/// 原子替换当前 Grok CLI 版本,返回替换前的版本;版本校验由发布检查器负责,这里只拒绝明显非法值。
|
||||
pub fn set_xai_client_version(version: &str) -> Result<String, &'static str> {
|
||||
let version = version.trim();
|
||||
if version.is_empty()
|
||||
|| version.len() > 64
|
||||
|| !version.bytes().all(|byte| (33..=126).contains(&byte))
|
||||
{
|
||||
return Err("invalid Grok CLI version");
|
||||
}
|
||||
let mut current = active_client_version()
|
||||
.write()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
||||
Ok(std::mem::replace(&mut *current, version.to_owned()))
|
||||
}
|
||||
|
||||
pub fn xai_cli_user_agent() -> String {
|
||||
format!("xai-grok-workspace/{XAI_CLIENT_VERSION}")
|
||||
format!("xai-grok-workspace/{}", xai_client_version())
|
||||
}
|
||||
|
||||
pub fn is_xai_provider_transport(transport: &GatewayProviderTransportSnapshot) -> bool {
|
||||
@@ -91,10 +124,11 @@ pub fn should_attach_cli_identity_headers(
|
||||
}
|
||||
|
||||
pub fn insert_cli_identity_headers(headers: &mut BTreeMap<String, String>) {
|
||||
let client_version = xai_client_version();
|
||||
let user_agent = xai_cli_user_agent();
|
||||
for (name, value) in [
|
||||
(XAI_TOKEN_AUTH_HEADER, XAI_TOKEN_AUTH_VALUE),
|
||||
(XAI_CLIENT_VERSION_HEADER, XAI_CLIENT_VERSION),
|
||||
(XAI_CLIENT_VERSION_HEADER, client_version.as_str()),
|
||||
("user-agent", user_agent.as_str()),
|
||||
(XAI_CLIENT_IDENTIFIER_HEADER, XAI_CLIENT_IDENTIFIER_VALUE),
|
||||
(
|
||||
@@ -441,4 +475,31 @@ mod tests {
|
||||
Some(r#"{"api_key":"xai-key","using_api":true}"#)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cli_identity_headers_follow_published_client_version() {
|
||||
use super::{
|
||||
insert_cli_identity_headers, set_xai_client_version, xai_client_version,
|
||||
XAI_CLIENT_VERSION_HEADER,
|
||||
};
|
||||
|
||||
let previous = xai_client_version();
|
||||
assert!(set_xai_client_version("").is_err());
|
||||
assert!(set_xai_client_version("1.0 .1").is_err());
|
||||
assert_eq!(xai_client_version(), previous);
|
||||
|
||||
set_xai_client_version(" 9.8.7 ").expect("valid version");
|
||||
let mut headers = BTreeMap::new();
|
||||
insert_cli_identity_headers(&mut headers);
|
||||
set_xai_client_version(&previous).expect("restore version");
|
||||
|
||||
assert_eq!(
|
||||
headers.get(XAI_CLIENT_VERSION_HEADER).map(String::as_str),
|
||||
Some("9.8.7")
|
||||
);
|
||||
assert_eq!(
|
||||
headers.get("user-agent").map(String::as_str),
|
||||
Some("xai-grok-workspace/9.8.7")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user