Support featured plugins (#15042)

This commit is contained in:
alexsong-oai
2026-03-18 17:45:30 -07:00
committed by GitHub
parent 81996fcde6
commit 825d09373d
16 changed files with 385 additions and 22 deletions
+42 -1
View File
@@ -7,6 +7,7 @@ use url::Url;
const DEFAULT_REMOTE_MARKETPLACE_NAME: &str = "openai-curated";
const REMOTE_PLUGIN_FETCH_TIMEOUT: Duration = Duration::from_secs(30);
const REMOTE_FEATURED_PLUGIN_FETCH_TIMEOUT: Duration = Duration::from_secs(10);
const REMOTE_PLUGIN_MUTATION_TIMEOUT: Duration = Duration::from_secs(30);
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
@@ -80,7 +81,7 @@ pub enum RemotePluginMutationError {
}
#[derive(Debug, thiserror::Error)]
pub(crate) enum RemotePluginFetchError {
pub enum RemotePluginFetchError {
#[error("chatgpt authentication required to sync remote plugins")]
AuthRequired,
@@ -158,6 +159,46 @@ pub(crate) async fn fetch_remote_plugin_status(
})
}
pub async fn fetch_remote_featured_plugin_ids(
config: &Config,
auth: Option<&CodexAuth>,
) -> Result<Vec<String>, RemotePluginFetchError> {
let base_url = config.chatgpt_base_url.trim_end_matches('/');
let url = format!("{base_url}/plugins/featured");
let client = build_reqwest_client();
let mut request = client
.get(&url)
.timeout(REMOTE_FEATURED_PLUGIN_FETCH_TIMEOUT);
if let Some(auth) = auth.filter(|auth| auth.is_chatgpt_auth()) {
let token = auth
.get_token()
.map_err(RemotePluginFetchError::AuthToken)?;
request = request.bearer_auth(token);
if let Some(account_id) = auth.get_account_id() {
request = request.header("chatgpt-account-id", account_id);
}
}
let response = request
.send()
.await
.map_err(|source| RemotePluginFetchError::Request {
url: url.clone(),
source,
})?;
let status = response.status();
let body = response.text().await.unwrap_or_default();
if !status.is_success() {
return Err(RemotePluginFetchError::UnexpectedStatus { url, status, body });
}
serde_json::from_str(&body).map_err(|source| RemotePluginFetchError::Decode {
url: url.clone(),
source,
})
}
pub(crate) async fn enable_remote_plugin(
config: &Config,
auth: Option<&CodexAuth>,