use crate::agents::adapter::{AgentAdapter, Backup};
use crate::config::ModelConfig;
use anyhow::{bail, Context, Result};
use std::path::PathBuf;
pub struct CodexAdapter;
impl CodexAdapter {
pub fn new() -> Self {
Self
}
fn config_dir(&self) -> Result<PathBuf> {
Ok(dirs::home_dir()
.context("Could not find home directory")?
.join(".codex"))
}
}
impl AgentAdapter for CodexAdapter {
fn name(&self) -> &str {
"codex"
}
fn detect(&self) -> Result<bool> {
Ok(false)
}
fn config_path(&self) -> Result<PathBuf> {
Ok(self.config_dir()?.join("config.toml"))
}
fn backup(&self) -> Result<Backup> {
let config_path = self.config_path()?;
let backup_dir = dirs::home_dir()
.context("Could not find home directory")?
.join(".agentswitch")
.join("backups")
.join("codex");
std::fs::create_dir_all(&backup_dir).context("Failed to create backup directory")?;
let timestamp = chrono::Utc::now();
let backup_filename = format!("backup-{}.toml", timestamp.format("%Y%m%d-%H%M%S"));
let backup_path = backup_dir.join(&backup_filename);
if config_path.exists() {
std::fs::copy(&config_path, &backup_path).context("Failed to backup configuration")?;
}
Ok(Backup {
agent_name: self.name().to_string(),
original_config_path: config_path,
backup_path,
timestamp,
})
}
fn apply(&self, _model_config: &ModelConfig) -> Result<()> {
bail!(
"Codex 使用 OpenAI Response API,与标准 /v1/chat/completions 协议不兼容,暂不支持自定义供应商。\\\n\
\\n\
推荐替代方案:\\n\
- claude-code: 支持 Anthropic /v1/messages 协议\\n\
- gemini-cli: 支持 OpenAI 兼容协议\\n\
- opencode: 支持多种协议\\n\
- qwen: 支持 OpenAI 兼容协议\\n\
- grok: 支持 OpenAI 兼容协议"
)
}
fn restore(&self, backup: &Backup) -> Result<()> {
if backup.backup_path.exists()
&& backup
.original_config_path
.parent()
.map(|p| p.exists())
.unwrap_or(false)
{
std::fs::copy(&backup.backup_path, &backup.original_config_path)
.context("Failed to restore backup")?;
}
Ok(())
}
fn current_model(&self) -> Result<Option<String>> {
Ok(None)
}
}