Files
codex/codex-rs/app-server/src/external_agent_config_api.rs
T
pakrym-oai 833212115e Move external agent config out of core (#18850)
## Summary
- Move external agent config migration logic and tests from `codex-core`
into `app-server/src/config`.
- Keep the migration service crate-private to app-server and update the
API adapter imports.
- Remove stale core re-exports and expose only the needed marketplace
source helper.

## Testing
- `cargo test -p codex-app-server config::external_agent_config`
- `just fmt`
- `just fix -p codex-app-server`
- `just fix -p codex-core`
- `git diff --check`
2026-04-21 08:33:58 -07:00

153 lines
6.3 KiB
Rust

use crate::config::external_agent_config::ExternalAgentConfigDetectOptions;
use crate::config::external_agent_config::ExternalAgentConfigMigrationItem as CoreMigrationItem;
use crate::config::external_agent_config::ExternalAgentConfigMigrationItemType as CoreMigrationItemType;
use crate::config::external_agent_config::ExternalAgentConfigService;
use crate::config::external_agent_config::PendingPluginImport;
use crate::error_code::INTERNAL_ERROR_CODE;
use codex_app_server_protocol::ExternalAgentConfigDetectParams;
use codex_app_server_protocol::ExternalAgentConfigDetectResponse;
use codex_app_server_protocol::ExternalAgentConfigImportParams;
use codex_app_server_protocol::ExternalAgentConfigMigrationItem;
use codex_app_server_protocol::ExternalAgentConfigMigrationItemType;
use codex_app_server_protocol::JSONRPCErrorError;
use codex_app_server_protocol::MigrationDetails;
use codex_app_server_protocol::PluginsMigration;
use std::io;
use std::path::PathBuf;
#[derive(Clone)]
pub(crate) struct ExternalAgentConfigApi {
migration_service: ExternalAgentConfigService,
}
impl ExternalAgentConfigApi {
pub(crate) fn new(codex_home: PathBuf) -> Self {
Self {
migration_service: ExternalAgentConfigService::new(codex_home),
}
}
pub(crate) async fn detect(
&self,
params: ExternalAgentConfigDetectParams,
) -> Result<ExternalAgentConfigDetectResponse, JSONRPCErrorError> {
let items = self
.migration_service
.detect(ExternalAgentConfigDetectOptions {
include_home: params.include_home,
cwds: params.cwds,
})
.await
.map_err(map_io_error)?;
Ok(ExternalAgentConfigDetectResponse {
items: items
.into_iter()
.map(|migration_item| ExternalAgentConfigMigrationItem {
item_type: match migration_item.item_type {
CoreMigrationItemType::Config => {
ExternalAgentConfigMigrationItemType::Config
}
CoreMigrationItemType::Skills => {
ExternalAgentConfigMigrationItemType::Skills
}
CoreMigrationItemType::AgentsMd => {
ExternalAgentConfigMigrationItemType::AgentsMd
}
CoreMigrationItemType::Plugins => {
ExternalAgentConfigMigrationItemType::Plugins
}
CoreMigrationItemType::McpServerConfig => {
ExternalAgentConfigMigrationItemType::McpServerConfig
}
},
description: migration_item.description,
cwd: migration_item.cwd,
details: migration_item.details.map(|details| MigrationDetails {
plugins: details
.plugins
.into_iter()
.map(|plugin| PluginsMigration {
marketplace_name: plugin.marketplace_name,
plugin_names: plugin.plugin_names,
})
.collect(),
}),
})
.collect(),
})
}
pub(crate) async fn import(
&self,
params: ExternalAgentConfigImportParams,
) -> Result<Vec<PendingPluginImport>, JSONRPCErrorError> {
self.migration_service
.import(
params
.migration_items
.into_iter()
.map(|migration_item| CoreMigrationItem {
item_type: match migration_item.item_type {
ExternalAgentConfigMigrationItemType::Config => {
CoreMigrationItemType::Config
}
ExternalAgentConfigMigrationItemType::Skills => {
CoreMigrationItemType::Skills
}
ExternalAgentConfigMigrationItemType::AgentsMd => {
CoreMigrationItemType::AgentsMd
}
ExternalAgentConfigMigrationItemType::Plugins => {
CoreMigrationItemType::Plugins
}
ExternalAgentConfigMigrationItemType::McpServerConfig => {
CoreMigrationItemType::McpServerConfig
}
},
description: migration_item.description,
cwd: migration_item.cwd,
details: migration_item.details.map(|details| {
crate::config::external_agent_config::MigrationDetails {
plugins: details
.plugins
.into_iter()
.map(|plugin| {
crate::config::external_agent_config::PluginsMigration {
marketplace_name: plugin.marketplace_name,
plugin_names: plugin.plugin_names,
}
})
.collect(),
}
}),
})
.collect(),
)
.await
.map_err(map_io_error)
}
pub(crate) async fn complete_pending_plugin_import(
&self,
pending_plugin_import: PendingPluginImport,
) -> Result<(), JSONRPCErrorError> {
self.migration_service
.import_plugins(
pending_plugin_import.cwd.as_deref(),
Some(pending_plugin_import.details),
)
.await
.map(|_| ())
.map_err(map_io_error)
}
}
fn map_io_error(err: io::Error) -> JSONRPCErrorError {
JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: err.to_string(),
data: None,
}
}