To date, we have a number of hardcoded OpenAI model slug checks spread throughout the codebase, which makes it hard to audit the various special cases for each model. To mitigate this issue, this PR introduces the idea of a `ModelFamily` that has fields to represent the existing special cases, such as `supports_reasoning_summaries` and `uses_local_shell_tool`. There is a `find_family_for_model()` function that maps the raw model slug to a `ModelFamily`. This function hardcodes all the knowledge about the special attributes for each model. This PR then replaces the hardcoded model name checks with checks against a `ModelFamily`. Note `ModelFamily` is now available as `Config::model_family`. We should ultimately remove `Config::model` in favor of `Config::model_family::slug`.
64 lines
1.9 KiB
Rust
64 lines
1.9 KiB
Rust
use std::path::Path;
|
|
|
|
use codex_common::summarize_sandbox_policy;
|
|
use codex_core::WireApi;
|
|
use codex_core::config::Config;
|
|
use codex_core::protocol::Event;
|
|
|
|
pub(crate) enum CodexStatus {
|
|
Running,
|
|
InitiateShutdown,
|
|
Shutdown,
|
|
}
|
|
|
|
pub(crate) trait EventProcessor {
|
|
/// Print summary of effective configuration and user prompt.
|
|
fn print_config_summary(&mut self, config: &Config, prompt: &str);
|
|
|
|
/// Handle a single event emitted by the agent.
|
|
fn process_event(&mut self, event: Event) -> CodexStatus;
|
|
}
|
|
|
|
pub(crate) fn create_config_summary_entries(config: &Config) -> Vec<(&'static str, String)> {
|
|
let mut entries = vec![
|
|
("workdir", config.cwd.display().to_string()),
|
|
("model", config.model.clone()),
|
|
("provider", config.model_provider_id.clone()),
|
|
("approval", config.approval_policy.to_string()),
|
|
("sandbox", summarize_sandbox_policy(&config.sandbox_policy)),
|
|
];
|
|
if config.model_provider.wire_api == WireApi::Responses
|
|
&& config.model_family.supports_reasoning_summaries
|
|
{
|
|
entries.push((
|
|
"reasoning effort",
|
|
config.model_reasoning_effort.to_string(),
|
|
));
|
|
entries.push((
|
|
"reasoning summaries",
|
|
config.model_reasoning_summary.to_string(),
|
|
));
|
|
}
|
|
|
|
entries
|
|
}
|
|
|
|
pub(crate) fn handle_last_message(last_agent_message: Option<&str>, output_file: &Path) {
|
|
let message = last_agent_message.unwrap_or_default();
|
|
write_last_message_file(message, Some(output_file));
|
|
if last_agent_message.is_none() {
|
|
eprintln!(
|
|
"Warning: no last agent message; wrote empty content to {}",
|
|
output_file.display()
|
|
);
|
|
}
|
|
}
|
|
|
|
fn write_last_message_file(contents: &str, last_message_path: Option<&Path>) {
|
|
if let Some(path) = last_message_path {
|
|
if let Err(e) = std::fs::write(path, contents) {
|
|
eprintln!("Failed to write last message file {path:?}: {e}");
|
|
}
|
|
}
|
|
}
|