mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-01 04:02:02 +08:00
feat(grokbuild): add first-class Grok Build support (#5453)
* feat(grokbuild): add backend integration * feat(grokbuild): add provider and management UI * test(grokbuild): cover configuration and integrations * fix(grokbuild): address backend review feedback * fix(grokbuild): complete UI review feedback * feat(grokbuild): add CLI lifecycle management * fix(grokbuild): align provider icon fallback * test(grokbuild): cover provider icon persistence
This commit is contained in:
@@ -250,7 +250,11 @@ pub fn codex_provider_upstream_model(provider: &Provider) -> Option<String> {
|
||||
.settings_config
|
||||
.get("config")
|
||||
.and_then(|v| v.as_str())
|
||||
.and_then(extract_codex_model_from_toml)
|
||||
.and_then(|config| {
|
||||
crate::grok_config::extract_model_config(config)
|
||||
.map(|model| model.model)
|
||||
.or_else(|| extract_codex_model_from_toml(config))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -621,6 +625,9 @@ impl CodexAdapter {
|
||||
}
|
||||
|
||||
if let Some(config_str) = config.as_str() {
|
||||
if let Some((_, key)) = crate::grok_config::extract_credentials(config_str) {
|
||||
return Some(key);
|
||||
}
|
||||
if let Some(key) =
|
||||
crate::codex_config::extract_codex_experimental_bearer_token(config_str)
|
||||
{
|
||||
@@ -675,6 +682,9 @@ impl ProviderAdapter for CodexAdapter {
|
||||
|
||||
// 尝试解析 TOML 字符串格式
|
||||
if let Some(config_str) = config.as_str() {
|
||||
if let Some(url) = crate::grok_config::extract_base_url(config_str) {
|
||||
return Ok(url.trim_end_matches('/').to_string());
|
||||
}
|
||||
if let Some(start) = config_str.find("base_url = \"") {
|
||||
let rest = &config_str[start + 12..];
|
||||
if let Some(end) = rest.find('"') {
|
||||
@@ -796,6 +806,37 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grok_build_toml_exposes_upstream_credentials_and_model() {
|
||||
let adapter = CodexAdapter::new();
|
||||
let provider = create_provider(json!({
|
||||
"config": r#"
|
||||
[models]
|
||||
default = "grok-4.5"
|
||||
|
||||
[model."grok-4.5"]
|
||||
model = "upstream-grok-model"
|
||||
base_url = "https://relay.example.com/v1/"
|
||||
name = "Example Relay"
|
||||
api_key = "grok-secret"
|
||||
api_backend = "responses"
|
||||
context_window = 500000
|
||||
"#
|
||||
}));
|
||||
|
||||
assert_eq!(
|
||||
adapter.extract_base_url(&provider).unwrap(),
|
||||
"https://relay.example.com/v1"
|
||||
);
|
||||
let auth = adapter.extract_auth(&provider).unwrap();
|
||||
assert_eq!(auth.api_key, "grok-secret");
|
||||
assert_eq!(auth.strategy, AuthStrategy::Bearer);
|
||||
assert_eq!(
|
||||
codex_provider_upstream_model(&provider).as_deref(),
|
||||
Some("upstream-grok-model")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn official_provider_uses_fixed_chatgpt_backend_without_stored_key() {
|
||||
let mut provider = create_provider(json!({ "auth": {}, "config": "" }));
|
||||
|
||||
@@ -192,10 +192,8 @@ impl ProviderType {
|
||||
}
|
||||
ProviderType::Gemini
|
||||
}
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes => {
|
||||
// These apps don't support proxy, fallback to Codex-like type
|
||||
ProviderType::Codex
|
||||
}
|
||||
AppType::GrokBuild => ProviderType::Codex,
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes => ProviderType::Codex,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,10 +244,8 @@ pub fn get_adapter(app_type: &AppType) -> Box<dyn ProviderAdapter> {
|
||||
AppType::Claude | AppType::ClaudeDesktop => Box::new(ClaudeAdapter::new()),
|
||||
AppType::Codex => Box::new(CodexAdapter::new()),
|
||||
AppType::Gemini => Box::new(GeminiAdapter::new()),
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes => {
|
||||
// These apps don't support proxy, fallback to Codex adapter
|
||||
Box::new(CodexAdapter::new())
|
||||
}
|
||||
AppType::GrokBuild => Box::new(CodexAdapter::new()),
|
||||
AppType::OpenCode | AppType::OpenClaw | AppType::Hermes => Box::new(CodexAdapter::new()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user