mirror of
https://github.com/openai/codex.git
synced 2026-11-14 21:40:39 +00:00
[codex] cover app-owned HTTP requests [ci changed_files]
This commit is contained in:
@@ -910,7 +910,11 @@ impl MessageProcessor {
|
||||
}
|
||||
ClientRequest::ExperimentalFeatureEnablementSet { params, .. } => {
|
||||
self.config_processor
|
||||
.experimental_feature_enablement_set(request_id.clone(), params)
|
||||
.experimental_feature_enablement_set(
|
||||
request_id.clone(),
|
||||
params,
|
||||
app_server_client_name.as_deref(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
ClientRequest::RemoteControlEnable { .. } => self
|
||||
@@ -1143,13 +1147,17 @@ impl MessageProcessor {
|
||||
self.thread_processor.conversation_summary(params).await
|
||||
}
|
||||
ClientRequest::SkillsList { params, .. } => {
|
||||
self.catalog_processor.skills_list(params).await
|
||||
self.catalog_processor
|
||||
.skills_list(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::SkillsExtraRootsSet { params, .. } => {
|
||||
self.catalog_processor.skills_extra_roots_set(params).await
|
||||
}
|
||||
ClientRequest::HooksList { params, .. } => {
|
||||
self.catalog_processor.hooks_list(params).await
|
||||
self.catalog_processor
|
||||
.hooks_list(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::MarketplaceAdd { params, .. } => {
|
||||
self.marketplace_processor.marketplace_add(params).await
|
||||
@@ -1161,45 +1169,67 @@ impl MessageProcessor {
|
||||
self.marketplace_processor.marketplace_upgrade(params).await
|
||||
}
|
||||
ClientRequest::PluginList { params, .. } => {
|
||||
self.plugin_processor.plugin_list(params).await
|
||||
self.plugin_processor
|
||||
.plugin_list(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::PluginInstalled { params, .. } => {
|
||||
self.plugin_processor.plugin_installed(params).await
|
||||
self.plugin_processor
|
||||
.plugin_installed(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::PluginRead { params, .. } => {
|
||||
self.plugin_processor.plugin_read(params).await
|
||||
self.plugin_processor
|
||||
.plugin_read(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::PluginSkillRead { params, .. } => {
|
||||
self.plugin_processor.plugin_skill_read(params).await
|
||||
self.plugin_processor
|
||||
.plugin_skill_read(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::PluginShareSave { params, .. } => {
|
||||
self.plugin_processor.plugin_share_save(params).await
|
||||
self.plugin_processor
|
||||
.plugin_share_save(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::PluginShareUpdateTargets { params, .. } => {
|
||||
self.plugin_processor
|
||||
.plugin_share_update_targets(params)
|
||||
.plugin_share_update_targets(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::PluginShareList { params, .. } => {
|
||||
self.plugin_processor.plugin_share_list(params).await
|
||||
self.plugin_processor
|
||||
.plugin_share_list(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::PluginShareCheckout { params, .. } => {
|
||||
self.plugin_processor.plugin_share_checkout(params).await
|
||||
self.plugin_processor
|
||||
.plugin_share_checkout(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::PluginShareDelete { params, .. } => {
|
||||
self.plugin_processor.plugin_share_delete(params).await
|
||||
self.plugin_processor
|
||||
.plugin_share_delete(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::AppsList { params, .. } => {
|
||||
self.apps_processor.apps_list(&request_id, params).await
|
||||
self.apps_processor
|
||||
.apps_list(&request_id, params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::SkillsConfigWrite { params, .. } => {
|
||||
self.catalog_processor.skills_config_write(params).await
|
||||
}
|
||||
ClientRequest::PluginInstall { params, .. } => {
|
||||
self.plugin_processor.plugin_install(params).await
|
||||
self.plugin_processor
|
||||
.plugin_install(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::PluginUninstall { params, .. } => {
|
||||
self.plugin_processor.plugin_uninstall(params).await
|
||||
self.plugin_processor
|
||||
.plugin_uninstall(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::ModelList { params, .. } => {
|
||||
self.catalog_processor
|
||||
@@ -1208,7 +1238,7 @@ impl MessageProcessor {
|
||||
}
|
||||
ClientRequest::ExperimentalFeatureList { params, .. } => {
|
||||
self.catalog_processor
|
||||
.experimental_feature_list(params)
|
||||
.experimental_feature_list(params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::PermissionProfileList { params, .. } => {
|
||||
@@ -1279,12 +1309,12 @@ impl MessageProcessor {
|
||||
}
|
||||
ClientRequest::McpServerStatusList { params, .. } => {
|
||||
self.mcp_processor
|
||||
.mcp_server_status_list(&request_id, params)
|
||||
.mcp_server_status_list(&request_id, params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::McpResourceRead { params, .. } => {
|
||||
self.mcp_processor
|
||||
.mcp_resource_read(&request_id, params)
|
||||
.mcp_resource_read(&request_id, params, app_server_client_name.as_deref())
|
||||
.await
|
||||
}
|
||||
ClientRequest::McpServerToolCall { params, .. } => {
|
||||
|
||||
@@ -533,6 +533,22 @@ pub(crate) use self::thread_summary::summary_to_thread;
|
||||
pub(crate) use self::thread_summary::thread_settings_from_config_snapshot;
|
||||
pub(crate) use self::thread_summary::thread_settings_from_core_snapshot;
|
||||
|
||||
fn http_state_context(
|
||||
config: &Config,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> codex_http_state::HttpStateContext {
|
||||
codex_http_state::HttpStateContext::new(
|
||||
config.codex_home.to_path_buf(),
|
||||
http_state_surface(app_server_client_name),
|
||||
)
|
||||
}
|
||||
|
||||
fn http_state_surface(app_server_client_name: Option<&str>) -> codex_http_state::HttpStateSurface {
|
||||
codex_http_state::HttpStateSurface::from_app_server_client_name(
|
||||
app_server_client_name.unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn build_api_turns_from_rollout_items(items: &[RolloutItem]) -> Vec<Turn> {
|
||||
let mut builder = ThreadHistoryBuilder::new();
|
||||
for item in items {
|
||||
|
||||
@@ -183,6 +183,7 @@ impl AccountRequestProcessor {
|
||||
config_manager: &ConfigManager,
|
||||
thread_manager: &Arc<ThreadManager>,
|
||||
auth: Option<CodexAuth>,
|
||||
http_state_surface: Option<HttpStateSurface>,
|
||||
) {
|
||||
match config_manager
|
||||
.load_latest_config(/*fallback_cwd*/ None)
|
||||
@@ -202,6 +203,9 @@ impl AccountRequestProcessor {
|
||||
refresh_config_manager.clone(),
|
||||
);
|
||||
})),
|
||||
http_state_surface.map(|surface| {
|
||||
HttpStateContext::new(config.codex_home.to_path_buf(), surface)
|
||||
}),
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -257,6 +261,7 @@ impl AccountRequestProcessor {
|
||||
access_token,
|
||||
chatgpt_account_id,
|
||||
chatgpt_plan_type,
|
||||
http_state_surface,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
@@ -317,8 +322,10 @@ impl AccountRequestProcessor {
|
||||
self.outgoing.send_result(request_id, result).await;
|
||||
|
||||
if logged_in {
|
||||
self.send_login_success_notifications(/*login_id*/ None)
|
||||
.await;
|
||||
self.send_login_success_notifications(
|
||||
/*login_id*/ None, /*http_state_surface*/ None,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,11 +418,7 @@ impl AccountRequestProcessor {
|
||||
});
|
||||
}
|
||||
|
||||
let outgoing_clone = self.outgoing.clone();
|
||||
let config_manager = self.config_manager.clone();
|
||||
let thread_manager = Arc::clone(&self.thread_manager);
|
||||
let chatgpt_base_url = self.config.chatgpt_base_url.clone();
|
||||
let active_login = self.active_login.clone();
|
||||
let processor = self.clone();
|
||||
let auth_url = server.auth_url.clone();
|
||||
tokio::spawn(async move {
|
||||
let (success, error_msg) = match tokio::time::timeout(
|
||||
@@ -432,19 +435,17 @@ impl AccountRequestProcessor {
|
||||
}
|
||||
};
|
||||
|
||||
Self::send_chatgpt_login_completion_notifications(
|
||||
&outgoing_clone,
|
||||
config_manager,
|
||||
thread_manager,
|
||||
chatgpt_base_url,
|
||||
login_id,
|
||||
success,
|
||||
error_msg,
|
||||
)
|
||||
.await;
|
||||
processor
|
||||
.send_chatgpt_login_completion_notifications(
|
||||
login_id,
|
||||
success,
|
||||
error_msg,
|
||||
http_state_surface,
|
||||
)
|
||||
.await;
|
||||
|
||||
// Clear the active login if it matches this attempt. It may have been replaced or cancelled.
|
||||
let mut guard = active_login.lock().await;
|
||||
let mut guard = processor.active_login.lock().await;
|
||||
if guard.as_ref().map(ActiveLogin::login_id) == Some(login_id) {
|
||||
*guard = None;
|
||||
}
|
||||
@@ -494,11 +495,7 @@ impl AccountRequestProcessor {
|
||||
let verification_url = device_code.verification_url.clone();
|
||||
let user_code = device_code.user_code.clone();
|
||||
|
||||
let outgoing_clone = self.outgoing.clone();
|
||||
let config_manager = self.config_manager.clone();
|
||||
let thread_manager = Arc::clone(&self.thread_manager);
|
||||
let chatgpt_base_url = self.config.chatgpt_base_url.clone();
|
||||
let active_login = self.active_login.clone();
|
||||
let processor = self.clone();
|
||||
tokio::spawn(async move {
|
||||
let (success, error_msg) = tokio::select! {
|
||||
_ = cancel.cancelled() => {
|
||||
@@ -512,18 +509,16 @@ impl AccountRequestProcessor {
|
||||
}
|
||||
};
|
||||
|
||||
Self::send_chatgpt_login_completion_notifications(
|
||||
&outgoing_clone,
|
||||
config_manager,
|
||||
thread_manager,
|
||||
chatgpt_base_url,
|
||||
login_id,
|
||||
success,
|
||||
error_msg,
|
||||
)
|
||||
.await;
|
||||
processor
|
||||
.send_chatgpt_login_completion_notifications(
|
||||
login_id,
|
||||
success,
|
||||
error_msg,
|
||||
http_state_surface,
|
||||
)
|
||||
.await;
|
||||
|
||||
let mut guard = active_login.lock().await;
|
||||
let mut guard = processor.active_login.lock().await;
|
||||
if guard.as_ref().map(ActiveLogin::login_id) == Some(login_id) {
|
||||
*guard = None;
|
||||
}
|
||||
@@ -571,6 +566,7 @@ impl AccountRequestProcessor {
|
||||
access_token: String,
|
||||
chatgpt_account_id: String,
|
||||
chatgpt_plan_type: Option<String>,
|
||||
http_state_surface: HttpStateSurface,
|
||||
) {
|
||||
let result = self
|
||||
.login_chatgpt_auth_tokens_response(access_token, chatgpt_account_id, chatgpt_plan_type)
|
||||
@@ -579,7 +575,7 @@ impl AccountRequestProcessor {
|
||||
self.outgoing.send_result(request_id, result).await;
|
||||
|
||||
if logged_in {
|
||||
self.send_login_success_notifications(/*login_id*/ None)
|
||||
self.send_login_success_notifications(/*login_id*/ None, Some(http_state_surface))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
@@ -634,11 +630,16 @@ impl AccountRequestProcessor {
|
||||
Ok(LoginAccountResponse::ChatgptAuthTokens {})
|
||||
}
|
||||
|
||||
async fn send_login_success_notifications(&self, login_id: Option<Uuid>) {
|
||||
async fn send_login_success_notifications(
|
||||
&self,
|
||||
login_id: Option<Uuid>,
|
||||
http_state_surface: Option<HttpStateSurface>,
|
||||
) {
|
||||
Self::maybe_refresh_remote_installed_plugins_cache_for_current_config(
|
||||
&self.config_manager,
|
||||
&self.thread_manager,
|
||||
self.auth_manager.auth_cached(),
|
||||
http_state_surface,
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -661,44 +662,45 @@ impl AccountRequestProcessor {
|
||||
}
|
||||
|
||||
async fn send_chatgpt_login_completion_notifications(
|
||||
outgoing: &OutgoingMessageSender,
|
||||
config_manager: ConfigManager,
|
||||
thread_manager: Arc<ThreadManager>,
|
||||
chatgpt_base_url: String,
|
||||
&self,
|
||||
login_id: Uuid,
|
||||
success: bool,
|
||||
error_msg: Option<String>,
|
||||
http_state_surface: HttpStateSurface,
|
||||
) {
|
||||
let payload_v2 = AccountLoginCompletedNotification {
|
||||
login_id: Some(login_id.to_string()),
|
||||
success,
|
||||
error: error_msg,
|
||||
};
|
||||
outgoing
|
||||
self.outgoing
|
||||
.send_server_notification(ServerNotification::AccountLoginCompleted(payload_v2))
|
||||
.await;
|
||||
|
||||
if success {
|
||||
let auth_manager = thread_manager.auth_manager();
|
||||
let auth_manager = self.thread_manager.auth_manager();
|
||||
auth_manager.reload().await;
|
||||
config_manager
|
||||
.replace_cloud_config_bundle_loader(auth_manager.clone(), chatgpt_base_url);
|
||||
config_manager
|
||||
self.config_manager.replace_cloud_config_bundle_loader(
|
||||
auth_manager.clone(),
|
||||
self.config.chatgpt_base_url.clone(),
|
||||
);
|
||||
self.config_manager
|
||||
.sync_default_client_residency_requirement()
|
||||
.await;
|
||||
|
||||
let auth = auth_manager.auth_cached();
|
||||
Self::maybe_refresh_remote_installed_plugins_cache_for_current_config(
|
||||
&config_manager,
|
||||
&thread_manager,
|
||||
&self.config_manager,
|
||||
&self.thread_manager,
|
||||
auth.clone(),
|
||||
Some(http_state_surface),
|
||||
)
|
||||
.await;
|
||||
let payload_v2 = AccountUpdatedNotification {
|
||||
auth_mode: auth.as_ref().map(CodexAuth::api_auth_mode),
|
||||
plan_type: auth.as_ref().and_then(CodexAuth::account_plan_type),
|
||||
};
|
||||
outgoing
|
||||
self.outgoing
|
||||
.send_server_notification(ServerNotification::AccountUpdated(payload_v2))
|
||||
.await;
|
||||
}
|
||||
@@ -724,6 +726,7 @@ impl AccountRequestProcessor {
|
||||
&self.config_manager,
|
||||
&self.thread_manager,
|
||||
self.auth_manager.auth_cached(),
|
||||
/*http_state_surface*/ None,
|
||||
)
|
||||
.await;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use super::*;
|
||||
use codex_http_state::HttpStateContext;
|
||||
|
||||
pub(crate) struct AppsRequestProcessor {
|
||||
auth_manager: Arc<AuthManager>,
|
||||
@@ -35,8 +36,9 @@ impl AppsRequestProcessor {
|
||||
&self,
|
||||
request_id: &ConnectionRequestId,
|
||||
params: AppsListParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.apps_list_inner(request_id, params)
|
||||
self.apps_list_inner(request_id, params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| response.map(Into::into))
|
||||
}
|
||||
@@ -45,6 +47,7 @@ impl AppsRequestProcessor {
|
||||
&self,
|
||||
request_id: &ConnectionRequestId,
|
||||
params: AppsListParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<AppsListResponse>, JSONRPCErrorError> {
|
||||
let thread = if let Some(thread_id) = params.thread_id.as_deref() {
|
||||
let (_, loaded_thread) = self.load_thread(thread_id).await?;
|
||||
@@ -64,7 +67,11 @@ impl AppsRequestProcessor {
|
||||
.set_enabled(Feature::Apps, thread.enabled(Feature::Apps));
|
||||
}
|
||||
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let auth = self
|
||||
.auth_manager
|
||||
.auth_for_surface(http_state_surface(app_server_client_name))
|
||||
.await;
|
||||
let http_state = http_state_context(&config, app_server_client_name);
|
||||
if !config
|
||||
.features
|
||||
.apps_enabled_for_auth(auth.as_ref().is_some_and(CodexAuth::uses_codex_backend))
|
||||
@@ -76,7 +83,7 @@ impl AppsRequestProcessor {
|
||||
}
|
||||
|
||||
if !self
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref())
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref(), &http_state)
|
||||
.await
|
||||
{
|
||||
return Ok(Some(AppsListResponse {
|
||||
@@ -92,7 +99,7 @@ impl AppsRequestProcessor {
|
||||
tokio::spawn(async move {
|
||||
tokio::select! {
|
||||
_ = shutdown_token.cancelled() => {}
|
||||
_ = Self::apps_list_task(outgoing, request, params, config, environment_manager) => {}
|
||||
_ = Self::apps_list_task(outgoing, request, params, config, environment_manager, http_state) => {}
|
||||
}
|
||||
});
|
||||
Ok(None)
|
||||
@@ -108,11 +115,15 @@ impl AppsRequestProcessor {
|
||||
params: AppsListParams,
|
||||
config: Config,
|
||||
environment_manager: Arc<EnvironmentManager>,
|
||||
http_state: HttpStateContext,
|
||||
) {
|
||||
let retry_params = params.clone();
|
||||
let retry_config = config.clone();
|
||||
let retry_environment_manager = Arc::clone(&environment_manager);
|
||||
let result = Self::apps_list_response(&outgoing, params, config, environment_manager).await;
|
||||
let retry_http_state = http_state.clone();
|
||||
let result =
|
||||
Self::apps_list_response(&outgoing, params, config, environment_manager, http_state)
|
||||
.await;
|
||||
let should_retry = result
|
||||
.as_ref()
|
||||
.is_ok_and(|(_, codex_apps_ready)| !codex_apps_ready);
|
||||
@@ -128,6 +139,7 @@ impl AppsRequestProcessor {
|
||||
retry_params,
|
||||
retry_config,
|
||||
retry_environment_manager,
|
||||
retry_http_state,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -141,6 +153,7 @@ impl AppsRequestProcessor {
|
||||
params: AppsListParams,
|
||||
config: Config,
|
||||
environment_manager: Arc<EnvironmentManager>,
|
||||
http_state: HttpStateContext,
|
||||
) -> Result<(AppsListResponse, bool), JSONRPCErrorError> {
|
||||
let AppsListParams {
|
||||
cursor,
|
||||
@@ -157,8 +170,11 @@ impl AppsRequestProcessor {
|
||||
};
|
||||
|
||||
let (mut accessible_connectors, mut all_connectors) = tokio::join!(
|
||||
connectors::list_cached_accessible_connectors_from_mcp_tools(&config),
|
||||
connectors::list_cached_all_connectors(&config)
|
||||
connectors::list_cached_accessible_connectors_from_mcp_tools_with_http_state(
|
||||
&config,
|
||||
Some(&http_state),
|
||||
),
|
||||
connectors::list_cached_all_connectors_with_http_state(&config, Some(&http_state))
|
||||
);
|
||||
let cached_all_connectors = all_connectors.clone();
|
||||
|
||||
@@ -166,12 +182,14 @@ impl AppsRequestProcessor {
|
||||
|
||||
let accessible_config = config.clone();
|
||||
let accessible_tx = tx.clone();
|
||||
let accessible_http_state = http_state.clone();
|
||||
tokio::spawn(async move {
|
||||
let result =
|
||||
connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager(
|
||||
connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager_and_http_state(
|
||||
&accessible_config,
|
||||
force_refetch,
|
||||
Arc::clone(&environment_manager),
|
||||
Some(accessible_http_state),
|
||||
)
|
||||
.await
|
||||
.map_err(|err| format!("failed to load accessible apps: {err}"));
|
||||
@@ -180,9 +198,13 @@ impl AppsRequestProcessor {
|
||||
|
||||
let all_config = config.clone();
|
||||
tokio::spawn(async move {
|
||||
let result = connectors::list_all_connectors_with_options(&all_config, force_refetch)
|
||||
.await
|
||||
.map_err(|err| format!("failed to list apps: {err}"));
|
||||
let result = connectors::list_all_connectors_with_options_and_http_state(
|
||||
&all_config,
|
||||
force_refetch,
|
||||
Some(http_state),
|
||||
)
|
||||
.await
|
||||
.map_err(|err| format!("failed to list apps: {err}"));
|
||||
let _ = tx.send(AppListLoadResult::Directory(result));
|
||||
});
|
||||
|
||||
@@ -303,11 +325,13 @@ impl AppsRequestProcessor {
|
||||
&self,
|
||||
config: &Config,
|
||||
auth: Option<&CodexAuth>,
|
||||
http_state: &HttpStateContext,
|
||||
) -> bool {
|
||||
match workspace_settings::codex_plugins_enabled_for_workspace(
|
||||
match workspace_settings::codex_plugins_enabled_for_workspace_with_http_state(
|
||||
config,
|
||||
auth,
|
||||
Some(&self.workspace_settings_cache),
|
||||
Some(http_state.clone()),
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use super::*;
|
||||
use codex_config::config_toml::ConfigToml;
|
||||
use codex_http_state::HttpStateContext;
|
||||
use codex_http_state::HttpStateSurface;
|
||||
use futures::StreamExt;
|
||||
|
||||
@@ -121,8 +122,9 @@ impl CatalogRequestProcessor {
|
||||
pub(crate) async fn skills_list(
|
||||
&self,
|
||||
params: SkillsListParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.skills_list_response(params)
|
||||
self.skills_list_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -130,8 +132,9 @@ impl CatalogRequestProcessor {
|
||||
pub(crate) async fn hooks_list(
|
||||
&self,
|
||||
params: HooksListParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.hooks_list_response(params)
|
||||
self.hooks_list_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -167,8 +170,9 @@ impl CatalogRequestProcessor {
|
||||
pub(crate) async fn experimental_feature_list(
|
||||
&self,
|
||||
params: ExperimentalFeatureListParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.experimental_feature_list_response(params)
|
||||
self.experimental_feature_list_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -229,11 +233,13 @@ impl CatalogRequestProcessor {
|
||||
&self,
|
||||
config: &Config,
|
||||
auth: Option<&CodexAuth>,
|
||||
http_state: &HttpStateContext,
|
||||
) -> bool {
|
||||
match workspace_settings::codex_plugins_enabled_for_workspace(
|
||||
match workspace_settings::codex_plugins_enabled_for_workspace_with_http_state(
|
||||
config,
|
||||
auth,
|
||||
Some(&self.workspace_settings_cache),
|
||||
Some(http_state.clone()),
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -320,6 +326,7 @@ impl CatalogRequestProcessor {
|
||||
async fn experimental_feature_list_response(
|
||||
&self,
|
||||
params: ExperimentalFeatureListParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<ExperimentalFeatureListResponse, JSONRPCErrorError> {
|
||||
let ExperimentalFeatureListParams {
|
||||
cursor,
|
||||
@@ -343,9 +350,13 @@ impl CatalogRequestProcessor {
|
||||
}
|
||||
None => self.load_latest_config(/*fallback_cwd*/ None).await?,
|
||||
};
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let http_state = http_state_context(&config, app_server_client_name);
|
||||
let auth = self
|
||||
.auth_manager
|
||||
.auth_for_surface(http_state_surface(app_server_client_name))
|
||||
.await;
|
||||
let workspace_codex_plugins_enabled = self
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref())
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref(), &http_state)
|
||||
.await;
|
||||
|
||||
let data = FEATURES
|
||||
@@ -509,6 +520,7 @@ impl CatalogRequestProcessor {
|
||||
async fn skills_list_response(
|
||||
&self,
|
||||
params: SkillsListParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<SkillsListResponse, JSONRPCErrorError> {
|
||||
let SkillsListParams { cwds, force_reload } = params;
|
||||
let cwds = if cwds.is_empty() {
|
||||
@@ -518,9 +530,13 @@ impl CatalogRequestProcessor {
|
||||
};
|
||||
|
||||
let config = self.load_latest_config(/*fallback_cwd*/ None).await?;
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let http_state = http_state_context(&config, app_server_client_name);
|
||||
let auth = self
|
||||
.auth_manager
|
||||
.auth_for_surface(http_state_surface(app_server_client_name))
|
||||
.await;
|
||||
let workspace_codex_plugins_enabled = self
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref())
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref(), &http_state)
|
||||
.await;
|
||||
let skills_manager = self.thread_manager.skills_manager();
|
||||
let plugins_manager = self.thread_manager.plugins_manager();
|
||||
@@ -615,6 +631,7 @@ impl CatalogRequestProcessor {
|
||||
async fn hooks_list_response(
|
||||
&self,
|
||||
params: HooksListParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<HooksListResponse, JSONRPCErrorError> {
|
||||
let HooksListParams { cwds } = params;
|
||||
let cwds = if cwds.is_empty() {
|
||||
@@ -623,7 +640,10 @@ impl CatalogRequestProcessor {
|
||||
cwds
|
||||
};
|
||||
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let auth = self
|
||||
.auth_manager
|
||||
.auth_for_surface(http_state_surface(app_server_client_name))
|
||||
.await;
|
||||
let plugins_manager = self.thread_manager.plugins_manager();
|
||||
let mut data = Vec::new();
|
||||
for cwd in cwds {
|
||||
@@ -651,8 +671,9 @@ impl CatalogRequestProcessor {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let http_state = http_state_context(&config, app_server_client_name);
|
||||
let workspace_codex_plugins_enabled = self
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref())
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref(), &http_state)
|
||||
.await;
|
||||
let plugins_enabled =
|
||||
config.features.enabled(Feature::Plugins) && workspace_codex_plugins_enabled;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::http_state_context;
|
||||
use super::http_state_surface;
|
||||
use crate::config_manager::ConfigManager;
|
||||
use crate::config_manager_service::ConfigManagerError;
|
||||
use crate::error_code::internal_error;
|
||||
@@ -150,6 +152,7 @@ impl ConfigRequestProcessor {
|
||||
&self,
|
||||
request_id: ConnectionRequestId,
|
||||
params: ExperimentalFeatureEnablementSetParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
let should_refresh_apps_list = params.enablement.get("apps").copied() == Some(true);
|
||||
let response = self
|
||||
@@ -162,8 +165,10 @@ impl ConfigRequestProcessor {
|
||||
)
|
||||
.await;
|
||||
if should_refresh_apps_list {
|
||||
self.refresh_apps_list_after_experimental_feature_enablement_set()
|
||||
.await;
|
||||
self.refresh_apps_list_after_experimental_feature_enablement_set(
|
||||
app_server_client_name,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
@@ -195,7 +200,10 @@ impl ConfigRequestProcessor {
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
async fn refresh_apps_list_after_experimental_feature_enablement_set(&self) {
|
||||
async fn refresh_apps_list_after_experimental_feature_enablement_set(
|
||||
&self,
|
||||
app_server_client_name: Option<&str>,
|
||||
) {
|
||||
let config = match self.load_latest_config(/*fallback_cwd*/ None).await {
|
||||
Ok(config) => config,
|
||||
Err(error) => {
|
||||
@@ -206,7 +214,11 @@ impl ConfigRequestProcessor {
|
||||
return;
|
||||
}
|
||||
};
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let http_state = http_state_context(&config, app_server_client_name);
|
||||
let auth = self
|
||||
.auth_manager
|
||||
.auth_for_surface(http_state_surface(app_server_client_name))
|
||||
.await;
|
||||
if !config.features.apps_enabled_for_auth(
|
||||
auth.as_ref()
|
||||
.is_some_and(codex_login::CodexAuth::uses_codex_backend),
|
||||
@@ -218,11 +230,16 @@ impl ConfigRequestProcessor {
|
||||
let environment_manager = self.thread_manager.environment_manager();
|
||||
tokio::spawn(async move {
|
||||
let (all_connectors_result, accessible_connectors_result) = tokio::join!(
|
||||
connectors::list_all_connectors_with_options(&config, /*force_refetch*/ true),
|
||||
connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager(
|
||||
connectors::list_all_connectors_with_options_and_http_state(
|
||||
&config,
|
||||
/*force_refetch*/ true,
|
||||
Some(http_state.clone()),
|
||||
),
|
||||
connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager_and_http_state(
|
||||
&config,
|
||||
/*force_refetch*/ true,
|
||||
Arc::clone(&environment_manager),
|
||||
Some(http_state),
|
||||
),
|
||||
);
|
||||
let all_connectors = match all_connectors_result {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use super::*;
|
||||
use codex_http_state::HttpStateContext;
|
||||
|
||||
const MCP_TOOL_THREAD_ID_META_KEY: &str = "threadId";
|
||||
|
||||
@@ -47,8 +48,9 @@ impl McpRequestProcessor {
|
||||
&self,
|
||||
request_id: &ConnectionRequestId,
|
||||
params: ListMcpServerStatusParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.list_mcp_server_status(request_id, params)
|
||||
self.list_mcp_server_status(request_id, params, app_server_client_name)
|
||||
.await
|
||||
.map(|()| None)
|
||||
}
|
||||
@@ -57,8 +59,9 @@ impl McpRequestProcessor {
|
||||
&self,
|
||||
request_id: &ConnectionRequestId,
|
||||
params: McpResourceReadParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.read_mcp_resource(request_id, params)
|
||||
self.read_mcp_resource(request_id, params, app_server_client_name)
|
||||
.await
|
||||
.map(|()| None)
|
||||
}
|
||||
@@ -195,6 +198,7 @@ impl McpRequestProcessor {
|
||||
&self,
|
||||
request_id: &ConnectionRequestId,
|
||||
params: ListMcpServerStatusParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<(), JSONRPCErrorError> {
|
||||
let request = request_id.clone();
|
||||
|
||||
@@ -213,7 +217,11 @@ impl McpRequestProcessor {
|
||||
let mcp_config = config
|
||||
.to_mcp_config(self.thread_manager.plugins_manager().as_ref())
|
||||
.await;
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let http_state = http_state_context(&config, app_server_client_name);
|
||||
let auth = self
|
||||
.auth_manager
|
||||
.auth_for_surface(http_state_surface(app_server_client_name))
|
||||
.await;
|
||||
let environment_manager = self.thread_manager.environment_manager();
|
||||
// This status path has no turn-selected environment. Use config cwd
|
||||
// as the local stdio fallback; named environment stdio MCPs must
|
||||
@@ -229,6 +237,7 @@ impl McpRequestProcessor {
|
||||
mcp_config,
|
||||
auth,
|
||||
runtime_context,
|
||||
http_state,
|
||||
)
|
||||
.await;
|
||||
});
|
||||
@@ -242,6 +251,7 @@ impl McpRequestProcessor {
|
||||
mcp_config: codex_mcp::McpConfig,
|
||||
auth: Option<CodexAuth>,
|
||||
runtime_context: McpRuntimeContext,
|
||||
http_state: HttpStateContext,
|
||||
) {
|
||||
let result = Self::list_mcp_server_status_response(
|
||||
request_id.request_id.to_string(),
|
||||
@@ -249,6 +259,7 @@ impl McpRequestProcessor {
|
||||
mcp_config,
|
||||
auth,
|
||||
runtime_context,
|
||||
http_state,
|
||||
)
|
||||
.await;
|
||||
outgoing.send_result(request_id, result).await;
|
||||
@@ -260,6 +271,7 @@ impl McpRequestProcessor {
|
||||
mcp_config: codex_mcp::McpConfig,
|
||||
auth: Option<CodexAuth>,
|
||||
runtime_context: McpRuntimeContext,
|
||||
http_state: HttpStateContext,
|
||||
) -> Result<ListMcpServerStatusResponse, JSONRPCErrorError> {
|
||||
let detail = match params.detail.unwrap_or(McpServerStatusDetail::Full) {
|
||||
McpServerStatusDetail::Full => McpSnapshotDetail::Full,
|
||||
@@ -271,6 +283,7 @@ impl McpRequestProcessor {
|
||||
auth.as_ref(),
|
||||
request_id,
|
||||
runtime_context,
|
||||
Some(http_state),
|
||||
detail,
|
||||
)
|
||||
.await;
|
||||
@@ -341,6 +354,7 @@ impl McpRequestProcessor {
|
||||
&self,
|
||||
request_id: &ConnectionRequestId,
|
||||
params: McpResourceReadParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<(), JSONRPCErrorError> {
|
||||
let outgoing = Arc::clone(&self.outgoing);
|
||||
let McpResourceReadParams {
|
||||
@@ -364,7 +378,11 @@ impl McpRequestProcessor {
|
||||
let mcp_config = config
|
||||
.to_mcp_config(self.thread_manager.plugins_manager().as_ref())
|
||||
.await;
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let http_state = http_state_context(&config, app_server_client_name);
|
||||
let auth = self
|
||||
.auth_manager
|
||||
.auth_for_surface(http_state_surface(app_server_client_name))
|
||||
.await;
|
||||
let environment_manager = self.thread_manager.environment_manager();
|
||||
// This threadless resource-read path has no turn cwd or turn-selected
|
||||
// environment. Use config cwd only as the local stdio fallback; named
|
||||
@@ -378,6 +396,7 @@ impl McpRequestProcessor {
|
||||
&mcp_config,
|
||||
auth.as_ref(),
|
||||
runtime_context,
|
||||
Some(http_state),
|
||||
&server,
|
||||
&uri,
|
||||
)
|
||||
|
||||
@@ -26,6 +26,14 @@ pub(crate) struct PluginRequestProcessor {
|
||||
workspace_settings_cache: Arc<workspace_settings::WorkspaceSettingsCache>,
|
||||
}
|
||||
|
||||
fn remote_plugin_service_config(
|
||||
config: &Config,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> RemotePluginServiceConfig {
|
||||
RemotePluginServiceConfig::new(config.chatgpt_base_url.clone())
|
||||
.with_http_state(http_state_context(config, app_server_client_name))
|
||||
}
|
||||
|
||||
fn plugin_skills_to_info(
|
||||
skills: &[codex_core::skills::SkillMetadata],
|
||||
disabled_skill_paths: &HashSet<AbsolutePathBuf>,
|
||||
@@ -341,11 +349,21 @@ impl PluginRequestProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
async fn auth_for_app_server_client(
|
||||
&self,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Option<CodexAuth> {
|
||||
self.auth_manager
|
||||
.auth_for_surface(http_state_surface(app_server_client_name))
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn plugin_list(
|
||||
&self,
|
||||
params: PluginListParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.plugin_list_response(params)
|
||||
self.plugin_list_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -353,8 +371,9 @@ impl PluginRequestProcessor {
|
||||
pub(crate) async fn plugin_installed(
|
||||
&self,
|
||||
params: PluginInstalledParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.plugin_installed_response(params)
|
||||
self.plugin_installed_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -362,8 +381,9 @@ impl PluginRequestProcessor {
|
||||
pub(crate) async fn plugin_read(
|
||||
&self,
|
||||
params: PluginReadParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.plugin_read_response(params)
|
||||
self.plugin_read_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -371,8 +391,9 @@ impl PluginRequestProcessor {
|
||||
pub(crate) async fn plugin_skill_read(
|
||||
&self,
|
||||
params: PluginSkillReadParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.plugin_skill_read_response(params)
|
||||
self.plugin_skill_read_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -380,8 +401,9 @@ impl PluginRequestProcessor {
|
||||
pub(crate) async fn plugin_share_save(
|
||||
&self,
|
||||
params: PluginShareSaveParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.plugin_share_save_response(params)
|
||||
self.plugin_share_save_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -389,8 +411,9 @@ impl PluginRequestProcessor {
|
||||
pub(crate) async fn plugin_share_update_targets(
|
||||
&self,
|
||||
params: PluginShareUpdateTargetsParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.plugin_share_update_targets_response(params)
|
||||
self.plugin_share_update_targets_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -398,8 +421,9 @@ impl PluginRequestProcessor {
|
||||
pub(crate) async fn plugin_share_list(
|
||||
&self,
|
||||
params: PluginShareListParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.plugin_share_list_response(params)
|
||||
self.plugin_share_list_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -407,8 +431,9 @@ impl PluginRequestProcessor {
|
||||
pub(crate) async fn plugin_share_checkout(
|
||||
&self,
|
||||
params: PluginShareCheckoutParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.plugin_share_checkout_response(params)
|
||||
self.plugin_share_checkout_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -416,8 +441,9 @@ impl PluginRequestProcessor {
|
||||
pub(crate) async fn plugin_share_delete(
|
||||
&self,
|
||||
params: PluginShareDeleteParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.plugin_share_delete_response(params)
|
||||
self.plugin_share_delete_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -425,8 +451,9 @@ impl PluginRequestProcessor {
|
||||
pub(crate) async fn plugin_install(
|
||||
&self,
|
||||
params: PluginInstallParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.plugin_install_response(params)
|
||||
self.plugin_install_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -434,8 +461,9 @@ impl PluginRequestProcessor {
|
||||
pub(crate) async fn plugin_uninstall(
|
||||
&self,
|
||||
params: PluginUninstallParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.plugin_uninstall_response(params)
|
||||
self.plugin_uninstall_response(params, app_server_client_name)
|
||||
.await
|
||||
.map(|response| Some(response.into()))
|
||||
}
|
||||
@@ -491,11 +519,13 @@ impl PluginRequestProcessor {
|
||||
&self,
|
||||
config: &Config,
|
||||
auth: Option<&CodexAuth>,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> bool {
|
||||
match workspace_settings::codex_plugins_enabled_for_workspace(
|
||||
match workspace_settings::codex_plugins_enabled_for_workspace_with_http_state(
|
||||
config,
|
||||
auth,
|
||||
Some(&self.workspace_settings_cache),
|
||||
Some(http_state_context(config, app_server_client_name)),
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -512,6 +542,7 @@ impl PluginRequestProcessor {
|
||||
async fn plugin_list_response(
|
||||
&self,
|
||||
params: PluginListParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginListResponse, JSONRPCErrorError> {
|
||||
let plugins_manager = self.thread_manager.plugins_manager();
|
||||
let PluginListParams {
|
||||
@@ -534,9 +565,11 @@ impl PluginRequestProcessor {
|
||||
if !config.features.enabled(Feature::Plugins) {
|
||||
return Ok(empty_response());
|
||||
}
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let auth = self
|
||||
.auth_for_app_server_client(app_server_client_name)
|
||||
.await;
|
||||
if !self
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref())
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref(), app_server_client_name)
|
||||
.await
|
||||
{
|
||||
return Ok(empty_response());
|
||||
@@ -548,6 +581,7 @@ impl PluginRequestProcessor {
|
||||
auth.clone(),
|
||||
&roots,
|
||||
Some(self.effective_plugins_changed_callback()),
|
||||
Some(http_state_context(&config, app_server_client_name)),
|
||||
);
|
||||
}
|
||||
let (mut data, marketplace_load_errors) = if include_local {
|
||||
@@ -616,9 +650,8 @@ impl PluginRequestProcessor {
|
||||
// TODO(remote plugins): Remove this once remote plugins are ready and vertical plugins are
|
||||
// served directly from the normal remote catalog.
|
||||
if include_vertical && !config.features.enabled(Feature::RemotePlugin) {
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let remote_plugin_service_config =
|
||||
remote_plugin_service_config(&config, app_server_client_name);
|
||||
match codex_core_plugins::remote::fetch_openai_curated_remote_collection_marketplace(
|
||||
&remote_plugin_service_config,
|
||||
auth.as_ref(),
|
||||
@@ -655,9 +688,8 @@ impl PluginRequestProcessor {
|
||||
remote_sources.push(RemoteMarketplaceSource::SharedWithMe);
|
||||
}
|
||||
if !remote_sources.is_empty() {
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let remote_plugin_service_config =
|
||||
remote_plugin_service_config(&config, app_server_client_name);
|
||||
match codex_core_plugins::remote::fetch_remote_marketplaces(
|
||||
&remote_plugin_service_config,
|
||||
auth.as_ref(),
|
||||
@@ -707,7 +739,11 @@ impl PluginRequestProcessor {
|
||||
.any(|marketplace| marketplace.name == OPENAI_CURATED_MARKETPLACE_NAME)
|
||||
{
|
||||
match plugins_manager
|
||||
.featured_plugin_ids_for_config(&plugins_input, auth.as_ref())
|
||||
.featured_plugin_ids_for_config_with_http_state(
|
||||
&plugins_input,
|
||||
auth.as_ref(),
|
||||
http_state_context(&config, app_server_client_name),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(featured_plugin_ids) => featured_plugin_ids,
|
||||
@@ -733,6 +769,7 @@ impl PluginRequestProcessor {
|
||||
async fn plugin_installed_response(
|
||||
&self,
|
||||
params: PluginInstalledParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginInstalledResponse, JSONRPCErrorError> {
|
||||
let plugins_manager = self.thread_manager.plugins_manager();
|
||||
let PluginInstalledParams {
|
||||
@@ -753,9 +790,11 @@ impl PluginRequestProcessor {
|
||||
if !config.features.enabled(Feature::Plugins) {
|
||||
return Ok(empty_response());
|
||||
}
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let auth = self
|
||||
.auth_for_app_server_client(app_server_client_name)
|
||||
.await;
|
||||
if !self
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref())
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref(), app_server_client_name)
|
||||
.await
|
||||
{
|
||||
return Ok(empty_response());
|
||||
@@ -768,6 +807,7 @@ impl PluginRequestProcessor {
|
||||
&plugins_input,
|
||||
auth.clone(),
|
||||
Some(self.effective_plugins_changed_callback()),
|
||||
Some(http_state_context(&config, app_server_client_name)),
|
||||
);
|
||||
|
||||
let (mut data, marketplace_load_errors) = self
|
||||
@@ -783,9 +823,11 @@ impl PluginRequestProcessor {
|
||||
data.extend(
|
||||
self.load_remote_installed_plugins(
|
||||
plugins_manager,
|
||||
&config,
|
||||
&plugins_input,
|
||||
&remote_installed_plugin_visible_scopes,
|
||||
auth.as_ref(),
|
||||
app_server_client_name,
|
||||
)
|
||||
.await,
|
||||
);
|
||||
@@ -883,9 +925,11 @@ impl PluginRequestProcessor {
|
||||
async fn load_remote_installed_plugins(
|
||||
&self,
|
||||
plugins_manager: Arc<codex_core_plugins::PluginsManager>,
|
||||
config: &Config,
|
||||
plugins_input: &codex_core_plugins::PluginsConfigInput,
|
||||
visible_scopes: &[RemotePluginScope],
|
||||
auth: Option<&CodexAuth>,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Vec<PluginMarketplaceEntry> {
|
||||
let remote_marketplaces = if let Some(remote_marketplaces) =
|
||||
plugins_manager.build_remote_installed_plugin_marketplaces_from_cache(visible_scopes)
|
||||
@@ -893,11 +937,12 @@ impl PluginRequestProcessor {
|
||||
Ok(remote_marketplaces)
|
||||
} else {
|
||||
plugins_manager
|
||||
.build_and_cache_remote_installed_plugin_marketplaces(
|
||||
.build_and_cache_remote_installed_plugin_marketplaces_with_http_state(
|
||||
plugins_input,
|
||||
auth,
|
||||
visible_scopes,
|
||||
Some(self.effective_plugins_changed_callback()),
|
||||
http_state_context(config, app_server_client_name),
|
||||
)
|
||||
.await
|
||||
};
|
||||
@@ -924,6 +969,7 @@ impl PluginRequestProcessor {
|
||||
async fn plugin_read_response(
|
||||
&self,
|
||||
params: PluginReadParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginReadResponse, JSONRPCErrorError> {
|
||||
let plugins_manager = self.thread_manager.plugins_manager();
|
||||
let PluginReadParams {
|
||||
@@ -965,10 +1011,11 @@ impl PluginRequestProcessor {
|
||||
);
|
||||
let share_context = match share_context {
|
||||
Some(context) => {
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let auth = self
|
||||
.auth_for_app_server_client(app_server_client_name)
|
||||
.await;
|
||||
let remote_plugin_service_config =
|
||||
remote_plugin_service_config(&config, app_server_client_name);
|
||||
match codex_core_plugins::remote::fetch_remote_plugin_share_context(
|
||||
&remote_plugin_service_config,
|
||||
auth.as_ref(),
|
||||
@@ -1016,6 +1063,7 @@ impl PluginRequestProcessor {
|
||||
&config,
|
||||
&outcome.plugin.apps,
|
||||
Arc::clone(&environment_manager),
|
||||
app_server_client_name,
|
||||
)
|
||||
.await;
|
||||
let visible_skills = outcome
|
||||
@@ -1071,10 +1119,11 @@ impl PluginRequestProcessor {
|
||||
"remote plugin read is not enabled for marketplace {remote_marketplace_name}"
|
||||
)));
|
||||
}
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let auth = self
|
||||
.auth_for_app_server_client(app_server_client_name)
|
||||
.await;
|
||||
let remote_plugin_service_config =
|
||||
remote_plugin_service_config(&config, app_server_client_name);
|
||||
validate_remote_plugin_id(&plugin_name)?;
|
||||
let remote_detail = codex_core_plugins::remote::fetch_remote_plugin_detail(
|
||||
&remote_plugin_service_config,
|
||||
@@ -1097,6 +1146,7 @@ impl PluginRequestProcessor {
|
||||
&config,
|
||||
&plugin_apps,
|
||||
Arc::clone(&environment_manager),
|
||||
app_server_client_name,
|
||||
)
|
||||
.await;
|
||||
remote_plugin_detail_to_info(remote_detail, app_summaries)
|
||||
@@ -1109,6 +1159,7 @@ impl PluginRequestProcessor {
|
||||
async fn plugin_skill_read_response(
|
||||
&self,
|
||||
params: PluginSkillReadParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginSkillReadResponse, JSONRPCErrorError> {
|
||||
let PluginSkillReadParams {
|
||||
remote_marketplace_name,
|
||||
@@ -1129,10 +1180,11 @@ impl PluginRequestProcessor {
|
||||
));
|
||||
}
|
||||
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let auth = self
|
||||
.auth_for_app_server_client(app_server_client_name)
|
||||
.await;
|
||||
let remote_plugin_service_config =
|
||||
remote_plugin_service_config(&config, app_server_client_name);
|
||||
let remote_skill_detail = codex_core_plugins::remote::fetch_remote_plugin_skill_detail(
|
||||
&remote_plugin_service_config,
|
||||
auth.as_ref(),
|
||||
@@ -1153,8 +1205,11 @@ impl PluginRequestProcessor {
|
||||
async fn plugin_share_save_response(
|
||||
&self,
|
||||
params: PluginShareSaveParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginShareSaveResponse, JSONRPCErrorError> {
|
||||
let (config, auth) = self.load_plugin_share_config_and_auth().await?;
|
||||
let (config, auth) = self
|
||||
.load_plugin_share_config_and_auth(app_server_client_name)
|
||||
.await?;
|
||||
if !config.features.enabled(Feature::PluginSharing) {
|
||||
return Err(invalid_request("plugin sharing is disabled"));
|
||||
}
|
||||
@@ -1183,9 +1238,8 @@ impl PluginRequestProcessor {
|
||||
validate_client_plugin_share_targets(share_targets)?;
|
||||
}
|
||||
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let remote_plugin_service_config =
|
||||
remote_plugin_service_config(&config, app_server_client_name);
|
||||
let access_policy = codex_core_plugins::remote::RemotePluginShareAccessPolicy {
|
||||
discoverability: discoverability.map(remote_plugin_share_discoverability),
|
||||
share_targets: share_targets.map(remote_plugin_share_targets),
|
||||
@@ -1211,8 +1265,11 @@ impl PluginRequestProcessor {
|
||||
async fn plugin_share_update_targets_response(
|
||||
&self,
|
||||
params: PluginShareUpdateTargetsParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginShareUpdateTargetsResponse, JSONRPCErrorError> {
|
||||
let (config, auth) = self.load_plugin_share_config_and_auth().await?;
|
||||
let (config, auth) = self
|
||||
.load_plugin_share_config_and_auth(app_server_client_name)
|
||||
.await?;
|
||||
if !config.features.enabled(Feature::PluginSharing) {
|
||||
return Err(invalid_request("plugin sharing is disabled"));
|
||||
}
|
||||
@@ -1226,9 +1283,8 @@ impl PluginRequestProcessor {
|
||||
}
|
||||
validate_client_plugin_share_targets(&share_targets)?;
|
||||
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let remote_plugin_service_config =
|
||||
remote_plugin_service_config(&config, app_server_client_name);
|
||||
let result = codex_core_plugins::remote::update_remote_plugin_share_targets(
|
||||
&remote_plugin_service_config,
|
||||
auth.as_ref(),
|
||||
@@ -1254,11 +1310,13 @@ impl PluginRequestProcessor {
|
||||
async fn plugin_share_list_response(
|
||||
&self,
|
||||
_params: PluginShareListParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginShareListResponse, JSONRPCErrorError> {
|
||||
let (config, auth) = self.load_plugin_share_config_and_auth().await?;
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let (config, auth) = self
|
||||
.load_plugin_share_config_and_auth(app_server_client_name)
|
||||
.await?;
|
||||
let remote_plugin_service_config =
|
||||
remote_plugin_service_config(&config, app_server_client_name);
|
||||
let data = codex_core_plugins::remote::list_remote_plugin_shares(
|
||||
&remote_plugin_service_config,
|
||||
auth.as_ref(),
|
||||
@@ -1285,8 +1343,11 @@ impl PluginRequestProcessor {
|
||||
async fn plugin_share_checkout_response(
|
||||
&self,
|
||||
params: PluginShareCheckoutParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginShareCheckoutResponse, JSONRPCErrorError> {
|
||||
let (config, auth) = self.load_plugin_share_config_and_auth().await?;
|
||||
let (config, auth) = self
|
||||
.load_plugin_share_config_and_auth(app_server_client_name)
|
||||
.await?;
|
||||
if !config.features.enabled(Feature::PluginSharing) {
|
||||
return Err(invalid_request("plugin sharing is disabled"));
|
||||
}
|
||||
@@ -1295,9 +1356,8 @@ impl PluginRequestProcessor {
|
||||
return Err(invalid_request("invalid remote plugin id"));
|
||||
}
|
||||
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let remote_plugin_service_config =
|
||||
remote_plugin_service_config(&config, app_server_client_name);
|
||||
let result = codex_core_plugins::remote::checkout_remote_plugin_share(
|
||||
&remote_plugin_service_config,
|
||||
auth.as_ref(),
|
||||
@@ -1321,16 +1381,18 @@ impl PluginRequestProcessor {
|
||||
async fn plugin_share_delete_response(
|
||||
&self,
|
||||
params: PluginShareDeleteParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginShareDeleteResponse, JSONRPCErrorError> {
|
||||
let (config, auth) = self.load_plugin_share_config_and_auth().await?;
|
||||
let (config, auth) = self
|
||||
.load_plugin_share_config_and_auth(app_server_client_name)
|
||||
.await?;
|
||||
let PluginShareDeleteParams { remote_plugin_id } = params;
|
||||
if remote_plugin_id.is_empty() || !is_valid_remote_plugin_id(&remote_plugin_id) {
|
||||
return Err(invalid_request("invalid remote plugin id"));
|
||||
}
|
||||
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let remote_plugin_service_config =
|
||||
remote_plugin_service_config(&config, app_server_client_name);
|
||||
codex_core_plugins::remote::delete_remote_plugin_share(
|
||||
&remote_plugin_service_config,
|
||||
auth.as_ref(),
|
||||
@@ -1345,18 +1407,22 @@ impl PluginRequestProcessor {
|
||||
|
||||
async fn load_plugin_share_config_and_auth(
|
||||
&self,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<(Config, Option<CodexAuth>), JSONRPCErrorError> {
|
||||
let config = self.load_latest_config(/*fallback_cwd*/ None).await?;
|
||||
if !config.features.enabled(Feature::Plugins) {
|
||||
return Err(invalid_request("plugin sharing is not enabled"));
|
||||
}
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let auth = self
|
||||
.auth_for_app_server_client(app_server_client_name)
|
||||
.await;
|
||||
Ok((config, auth))
|
||||
}
|
||||
|
||||
async fn plugin_install_response(
|
||||
&self,
|
||||
params: PluginInstallParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginInstallResponse, JSONRPCErrorError> {
|
||||
let PluginInstallParams {
|
||||
marketplace_path,
|
||||
@@ -1367,7 +1433,11 @@ impl PluginRequestProcessor {
|
||||
(Some(marketplace_path), None) => marketplace_path,
|
||||
(None, Some(remote_marketplace_name)) => {
|
||||
return self
|
||||
.remote_plugin_install_response(remote_marketplace_name, plugin_name)
|
||||
.remote_plugin_install_response(
|
||||
remote_marketplace_name,
|
||||
plugin_name,
|
||||
app_server_client_name,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
(Some(_), Some(_)) | (None, None) => {
|
||||
@@ -1378,10 +1448,12 @@ impl PluginRequestProcessor {
|
||||
};
|
||||
let config_cwd = marketplace_path.as_path().parent().map(Path::to_path_buf);
|
||||
let config = self.load_latest_config(config_cwd.clone()).await?;
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let auth = self
|
||||
.auth_for_app_server_client(app_server_client_name)
|
||||
.await;
|
||||
|
||||
if !self
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref())
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref(), app_server_client_name)
|
||||
.await
|
||||
{
|
||||
return Err(invalid_request(
|
||||
@@ -1418,13 +1490,13 @@ impl PluginRequestProcessor {
|
||||
}
|
||||
|
||||
let plugin_apps = load_plugin_apps(result.installed_path.as_path()).await;
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let apps_needing_auth = self
|
||||
.plugin_apps_needing_auth_for_install(
|
||||
&config,
|
||||
auth.as_ref().is_some_and(CodexAuth::is_chatgpt_auth),
|
||||
&result.plugin_id.as_key(),
|
||||
&plugin_apps,
|
||||
app_server_client_name,
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -1438,6 +1510,7 @@ impl PluginRequestProcessor {
|
||||
&self,
|
||||
remote_marketplace_name: String,
|
||||
remote_plugin_id: String,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginInstallResponse, JSONRPCErrorError> {
|
||||
let config = self.load_latest_config(/*fallback_cwd*/ None).await?;
|
||||
if !config.features.enabled(Feature::Plugins) {
|
||||
@@ -1447,10 +1520,11 @@ impl PluginRequestProcessor {
|
||||
}
|
||||
validate_remote_plugin_id(&remote_plugin_id)?;
|
||||
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let auth = self
|
||||
.auth_for_app_server_client(app_server_client_name)
|
||||
.await;
|
||||
let remote_plugin_service_config =
|
||||
remote_plugin_service_config(&config, app_server_client_name);
|
||||
let remote_detail =
|
||||
codex_core_plugins::remote::fetch_remote_plugin_detail_with_download_urls(
|
||||
&remote_plugin_service_config,
|
||||
@@ -1519,6 +1593,7 @@ impl PluginRequestProcessor {
|
||||
&config.plugins_config_input(),
|
||||
auth.clone(),
|
||||
Some(self.effective_plugins_changed_callback()),
|
||||
Some(http_state_context(&config, app_server_client_name)),
|
||||
);
|
||||
|
||||
let mut plugin_metadata =
|
||||
@@ -1540,6 +1615,7 @@ impl PluginRequestProcessor {
|
||||
auth.as_ref().is_some_and(CodexAuth::is_chatgpt_auth),
|
||||
&result.plugin_id.as_key(),
|
||||
&plugin_apps,
|
||||
app_server_client_name,
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -1555,18 +1631,25 @@ impl PluginRequestProcessor {
|
||||
is_chatgpt_auth: bool,
|
||||
plugin_id: &str,
|
||||
plugin_apps: &[codex_plugin::AppConnectorId],
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Vec<AppSummary> {
|
||||
if plugin_apps.is_empty() || !config.features.apps_enabled_for_auth(is_chatgpt_auth) {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
let environment_manager = self.thread_manager.environment_manager();
|
||||
let http_state = http_state_context(config, app_server_client_name);
|
||||
let (all_connectors_result, accessible_connectors_result) = tokio::join!(
|
||||
connectors::list_all_connectors_with_options(config, /*force_refetch*/ false),
|
||||
connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager(
|
||||
connectors::list_all_connectors_with_options_and_http_state(
|
||||
config,
|
||||
/*force_refetch*/ false,
|
||||
Some(http_state.clone()),
|
||||
),
|
||||
connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager_and_http_state(
|
||||
config,
|
||||
/*force_refetch*/ true,
|
||||
Arc::clone(&environment_manager)
|
||||
Arc::clone(&environment_manager),
|
||||
Some(http_state.clone()),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1577,7 +1660,7 @@ impl PluginRequestProcessor {
|
||||
plugin = plugin_id,
|
||||
"failed to load app metadata after plugin install: {err:#}"
|
||||
);
|
||||
connectors::list_cached_all_connectors(config)
|
||||
connectors::list_cached_all_connectors_with_http_state(config, Some(&http_state))
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
}
|
||||
@@ -1591,9 +1674,12 @@ impl PluginRequestProcessor {
|
||||
"failed to load accessible apps after plugin install: {err:#}"
|
||||
);
|
||||
(
|
||||
connectors::list_cached_accessible_connectors_from_mcp_tools(config)
|
||||
.await
|
||||
.unwrap_or_default(),
|
||||
connectors::list_cached_accessible_connectors_from_mcp_tools_with_http_state(
|
||||
config,
|
||||
Some(&http_state),
|
||||
)
|
||||
.await
|
||||
.unwrap_or_default(),
|
||||
false,
|
||||
)
|
||||
}
|
||||
@@ -1697,6 +1783,7 @@ impl PluginRequestProcessor {
|
||||
async fn plugin_uninstall_response(
|
||||
&self,
|
||||
params: PluginUninstallParams,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginUninstallResponse, JSONRPCErrorError> {
|
||||
let PluginUninstallParams { plugin_id } = params;
|
||||
if codex_plugin::PluginId::parse(&plugin_id).is_err()
|
||||
@@ -1705,7 +1792,9 @@ impl PluginRequestProcessor {
|
||||
return Err(invalid_request("invalid remote plugin id"));
|
||||
}
|
||||
if is_valid_remote_plugin_id(&plugin_id) {
|
||||
return self.remote_plugin_uninstall_response(plugin_id).await;
|
||||
return self
|
||||
.remote_plugin_uninstall_response(plugin_id, app_server_client_name)
|
||||
.await;
|
||||
}
|
||||
let plugins_manager = self.thread_manager.plugins_manager();
|
||||
|
||||
@@ -1788,6 +1877,7 @@ impl PluginRequestProcessor {
|
||||
async fn remote_plugin_uninstall_response(
|
||||
&self,
|
||||
plugin_id: String,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Result<PluginUninstallResponse, JSONRPCErrorError> {
|
||||
let config = self.load_latest_config(/*fallback_cwd*/ None).await?;
|
||||
if !config.features.enabled(Feature::Plugins) {
|
||||
@@ -1795,10 +1885,11 @@ impl PluginRequestProcessor {
|
||||
}
|
||||
validate_remote_plugin_id(&plugin_id)?;
|
||||
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let auth = self
|
||||
.auth_for_app_server_client(app_server_client_name)
|
||||
.await;
|
||||
let remote_plugin_service_config =
|
||||
remote_plugin_service_config(&config, app_server_client_name);
|
||||
let uninstall_result = codex_core_plugins::remote::uninstall_remote_plugin(
|
||||
&remote_plugin_service_config,
|
||||
auth.as_ref(),
|
||||
@@ -1819,6 +1910,7 @@ impl PluginRequestProcessor {
|
||||
&config.plugins_config_input(),
|
||||
auth.clone(),
|
||||
Some(self.effective_plugins_changed_callback()),
|
||||
Some(http_state_context(&config, app_server_client_name)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1833,29 +1925,37 @@ async fn load_plugin_app_summaries(
|
||||
config: &Config,
|
||||
plugin_apps: &[codex_plugin::AppConnectorId],
|
||||
environment_manager: Arc<EnvironmentManager>,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Vec<AppSummary> {
|
||||
if plugin_apps.is_empty() {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
let connectors =
|
||||
match connectors::list_all_connectors_with_options(config, /*force_refetch*/ false).await {
|
||||
Ok(connectors) => connectors,
|
||||
Err(err) => {
|
||||
warn!("failed to load app metadata for plugin/read: {err:#}");
|
||||
connectors::list_cached_all_connectors(config)
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
}
|
||||
};
|
||||
let http_state = http_state_context(config, app_server_client_name);
|
||||
let connectors = match connectors::list_all_connectors_with_options_and_http_state(
|
||||
config,
|
||||
/*force_refetch*/ false,
|
||||
Some(http_state.clone()),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(connectors) => connectors,
|
||||
Err(err) => {
|
||||
warn!("failed to load app metadata for plugin/read: {err:#}");
|
||||
connectors::list_cached_all_connectors_with_http_state(config, Some(&http_state))
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
}
|
||||
};
|
||||
|
||||
let plugin_connectors = connectors::connectors_for_plugin_apps(connectors, plugin_apps);
|
||||
|
||||
let accessible_connectors =
|
||||
match connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager(
|
||||
match connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager_and_http_state(
|
||||
config,
|
||||
/*force_refetch*/ false,
|
||||
environment_manager,
|
||||
Some(http_state),
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user