Skip to content
Merged
1 change: 1 addition & 0 deletions crates/goose-server/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ derive_utoipa!(Icon as IconSchema);
super::routes::config_management::remove_custom_provider,
super::routes::config_management::check_provider,
super::routes::config_management::set_config_provider,
super::routes::config_management::configure_provider_oauth,
super::routes::config_management::get_pricing,
super::routes::prompts::get_prompts,
super::routes::prompts::get_prompt,
Expand Down
48 changes: 48 additions & 0 deletions crates/goose-server/src/routes/config_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,50 @@ pub async fn set_config_provider(
Ok(())
}

#[utoipa::path(
post,
path = "/config/providers/{name}/oauth",
params(
("name" = String, Path, description = "Provider name")
),
responses(
(status = 200, description = "OAuth configuration completed"),
(status = 400, description = "OAuth configuration failed")
Comment thread
michaelneale marked this conversation as resolved.
)
)]
pub async fn configure_provider_oauth(
Path(provider_name): Path<String>,
) -> Result<Json<String>, (StatusCode, String)> {
use goose::model::ModelConfig;
use goose::providers::create;

let temp_model =
ModelConfig::new("temp").map_err(|e| (StatusCode::BAD_REQUEST, e.to_string()))?;

let provider = create(&provider_name, temp_model).await.map_err(|e| {
(
StatusCode::BAD_REQUEST,
format!("Failed to create provider: {}", e),
)
})?;

provider.configure_oauth().await.map_err(|e| {
(
StatusCode::BAD_REQUEST,
format!("OAuth configuration failed: {}", e),
)
})?;

// Mark the provider as configured after successful OAuth
let configured_marker = format!("{}_configured", provider_name);
Comment thread
codefromthecrypt marked this conversation as resolved.
let config = goose::config::Config::global();
config
.set_param(&configured_marker, true)
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;

Ok(Json("OAuth configuration completed".to_string()))
}

pub fn routes(state: Arc<AppState>) -> Router {
Router::new()
.route("/config", get(read_all_config))
Expand Down Expand Up @@ -851,6 +895,10 @@ pub fn routes(state: Arc<AppState>) -> Router {
.route("/config/custom-providers/{id}", get(get_custom_provider))
.route("/config/check_provider", post(check_provider))
.route("/config/set_provider", post(set_config_provider))
.route(
"/config/providers/{name}/oauth",
post(configure_provider_oauth),
)
.with_state(state)
}

Expand Down
10 changes: 10 additions & 0 deletions crates/goose-server/src/routes/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ pub fn check_provider_configured(metadata: &ProviderMetadata, provider_type: Pro
.is_ok();
}
}

// Special case: OAuth providers - check for configured marker
let has_oauth_key = metadata.config_keys.iter().any(|key| key.oauth_flow);
if has_oauth_key {
let configured_marker = format!("{}_configured", metadata.name);
if config.get_param::<bool>(&configured_marker).is_ok() {
return true;
}
}

// Special case: Zero-config providers (no config keys)
if metadata.config_keys.is_empty() {
// Check if the provider has been explicitly configured via the UI
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3024,6 +3024,10 @@
"provider_model": "gpt-5.1-codex-mini",
"canonical_model": "openai/gpt-5.1-codex-mini"
},
{
"provider_model": "gpt-5.2-codex",
"canonical_model": "openai/gpt-5.2-codex"
},
{
"provider_model": "gpt-5.2",
"canonical_model": "openai/gpt-5.2"
Expand Down
21 changes: 21 additions & 0 deletions crates/goose/src/providers/canonical/data/canonical_models.json
Original file line number Diff line number Diff line change
Expand Up @@ -2181,6 +2181,27 @@
"image": 0.0
}
},
{
"id": "openai/gpt-5.2-codex",
"name": "OpenAI: GPT-5.2-Codex",
"context_length": 400000,
"max_completion_tokens": 128000,
"input_modalities": [
"file",
"image",
"text"
],
"output_modalities": [
"text"
],
"supports_tools": true,
"pricing": {
"prompt": 1.75e-6,
"completion": 0.000014,
"request": 0.0,
"image": 0.0
}
},
{
"id": "openai/gpt-5.2-pro",
"name": "OpenAI: GPT-5.2 Pro",
Expand Down
5 changes: 4 additions & 1 deletion crates/goose/src/providers/canonical/name_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,10 @@ fn swap_claude_word_order(model: &str) -> Option<String> {
}

fn is_hosting_provider(provider: &str) -> bool {
matches!(provider, "databricks" | "openrouter" | "azure" | "bedrock")
matches!(
provider,
"databricks" | "openrouter" | "azure" | "bedrock" | "chatgpt_codex"
)
}

/// Infer the real provider from model name patterns
Expand Down
Loading
Loading