fix: remove CodexBuilder and Recorder (#858)
These abstractions were originally created exclusively for the REPL, which was removed in https://github.com/openai/codex/pull/754. Currently, the create some unnecessary Tokio tasks, so we are better off without them. (We can always bring this back if we have a new use case.)
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::io::Write;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -16,7 +15,6 @@ use codex_apply_patch::ApplyPatchFileChange;
|
|||||||
use codex_apply_patch::MaybeApplyPatchVerified;
|
use codex_apply_patch::MaybeApplyPatchVerified;
|
||||||
use codex_apply_patch::maybe_parse_apply_patch_verified;
|
use codex_apply_patch::maybe_parse_apply_patch_verified;
|
||||||
use codex_apply_patch::print_summary;
|
use codex_apply_patch::print_summary;
|
||||||
use fs_err as fs;
|
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
@@ -72,20 +70,17 @@ use crate::zdr_transcript::ZdrTranscript;
|
|||||||
pub struct Codex {
|
pub struct Codex {
|
||||||
tx_sub: Sender<Submission>,
|
tx_sub: Sender<Submission>,
|
||||||
rx_event: Receiver<Event>,
|
rx_event: Receiver<Event>,
|
||||||
recorder: Recorder,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Codex {
|
impl Codex {
|
||||||
pub fn spawn(ctrl_c: Arc<Notify>) -> CodexResult<Self> {
|
pub fn spawn(ctrl_c: Arc<Notify>) -> CodexResult<Self> {
|
||||||
CodexBuilder::default().spawn(ctrl_c)
|
let (tx_sub, rx_sub) = async_channel::bounded(64);
|
||||||
}
|
let (tx_event, rx_event) = async_channel::bounded(64);
|
||||||
|
tokio::spawn(submission_loop(rx_sub, tx_event, ctrl_c));
|
||||||
pub fn builder() -> CodexBuilder {
|
Ok(Self { tx_sub, rx_event })
|
||||||
CodexBuilder::default()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn submit(&self, sub: Submission) -> CodexResult<()> {
|
pub async fn submit(&self, sub: Submission) -> CodexResult<()> {
|
||||||
self.recorder.record_submission(&sub);
|
|
||||||
self.tx_sub
|
self.tx_sub
|
||||||
.send(sub)
|
.send(sub)
|
||||||
.await
|
.await
|
||||||
@@ -98,100 +93,10 @@ impl Codex {
|
|||||||
.recv()
|
.recv()
|
||||||
.await
|
.await
|
||||||
.map_err(|_| CodexErr::InternalAgentDied)?;
|
.map_err(|_| CodexErr::InternalAgentDied)?;
|
||||||
self.recorder.record_event(&event);
|
|
||||||
Ok(event)
|
Ok(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct CodexBuilder {
|
|
||||||
record_submissions: Option<PathBuf>,
|
|
||||||
record_events: Option<PathBuf>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CodexBuilder {
|
|
||||||
pub fn spawn(self, ctrl_c: Arc<Notify>) -> CodexResult<Codex> {
|
|
||||||
let (tx_sub, rx_sub) = async_channel::bounded(64);
|
|
||||||
let (tx_event, rx_event) = async_channel::bounded(64);
|
|
||||||
let recorder = Recorder::new(&self)?;
|
|
||||||
tokio::spawn(submission_loop(rx_sub, tx_event, ctrl_c));
|
|
||||||
Ok(Codex {
|
|
||||||
tx_sub,
|
|
||||||
rx_event,
|
|
||||||
recorder,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn record_submissions(mut self, path: impl AsRef<Path>) -> Self {
|
|
||||||
debug!("Recording submissions to {:?}", path.as_ref());
|
|
||||||
self.record_submissions = Some(path.as_ref().to_path_buf());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn record_events(mut self, path: impl AsRef<Path>) -> Self {
|
|
||||||
debug!("Recording events to {:?}", path.as_ref());
|
|
||||||
self.record_events = Some(path.as_ref().to_path_buf());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct Recorder {
|
|
||||||
submissions: Option<Arc<Mutex<fs::File>>>,
|
|
||||||
events: Option<Arc<Mutex<fs::File>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Recorder {
|
|
||||||
fn new(builder: &CodexBuilder) -> CodexResult<Self> {
|
|
||||||
let submissions = match &builder.record_submissions {
|
|
||||||
Some(path) => {
|
|
||||||
if let Some(parent) = path.parent() {
|
|
||||||
fs::create_dir_all(parent)?;
|
|
||||||
}
|
|
||||||
let f = fs::File::create(path)?;
|
|
||||||
Some(Arc::new(Mutex::new(f)))
|
|
||||||
}
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
let events = match &builder.record_events {
|
|
||||||
Some(path) => {
|
|
||||||
if let Some(parent) = path.parent() {
|
|
||||||
fs::create_dir_all(parent)?;
|
|
||||||
}
|
|
||||||
let f = fs::File::create(path)?;
|
|
||||||
Some(Arc::new(Mutex::new(f)))
|
|
||||||
}
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
Ok(Self {
|
|
||||||
submissions,
|
|
||||||
events,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn record_submission(&self, sub: &Submission) {
|
|
||||||
let Some(f) = &self.submissions else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
let mut f = f.lock().unwrap();
|
|
||||||
let json = serde_json::to_string(sub).expect("failed to serialize submission json");
|
|
||||||
if let Err(e) = writeln!(f, "{json}") {
|
|
||||||
warn!("failed to record submission: {e:#}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn record_event(&self, event: &Event) {
|
|
||||||
let Some(f) = &self.events else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
let mut f = f.lock().unwrap();
|
|
||||||
let json = serde_json::to_string(event).expect("failed to serialize event json");
|
|
||||||
if let Err(e) = writeln!(f, "{json}") {
|
|
||||||
warn!("failed to record event: {e:#}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Context for an initialized model agent
|
/// Context for an initialized model agent
|
||||||
///
|
///
|
||||||
/// A session has at most 1 running task at a time, and can be interrupted by user input.
|
/// A session has at most 1 running task at a time, and can be interrupted by user input.
|
||||||
|
|||||||
Reference in New Issue
Block a user