Count Codex background terminals
This commit is contained in:
1 parent
cbae7ee8c0
commit
827a30768c
5 files changed
+361
-35
No files matched your search
@@ -5,7 +5,7 @@
|
||||
//! ignore the rest; an added Codex item must not make a live session go deaf.
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use serde_json::{Value, json};
|
||||
|
||||
@@ -18,6 +18,7 @@ pub(super) struct Translator {
|
||||
completed: bool,
|
||||
limited: bool,
|
||||
subagents: Option<Arc<Subagents>>,
|
||||
background_processes: Option<Arc<Mutex<HashSet<String>>>>,
|
||||
children: HashMap<String, Translator>,
|
||||
prompts: HashMap<String, String>,
|
||||
async_messages: HashSet<String>,
|
||||
@@ -25,10 +26,16 @@ pub(super) struct Translator {
|
||||
}
|
||||
|
||||
impl Translator {
|
||||
pub(super) fn new(subagents: Arc<Subagents>, thread_id: Option<String>, in_turn: bool) -> Self {
|
||||
pub(super) fn new(
|
||||
subagents: Arc<Subagents>,
|
||||
background_processes: Arc<Mutex<HashSet<String>>>,
|
||||
thread_id: Option<String>,
|
||||
in_turn: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
thread_id,
|
||||
subagents: Some(subagents),
|
||||
background_processes: Some(background_processes),
|
||||
in_turn,
|
||||
..Self::default()
|
||||
}
|
||||
@@ -118,9 +125,14 @@ impl Translator {
|
||||
}
|
||||
|
||||
fn background_task_count(&self) -> Option<usize> {
|
||||
self.subagents
|
||||
.as_ref()
|
||||
.map(|subagents| subagents.open_count())
|
||||
self.subagents.as_ref().map(|subagents| {
|
||||
subagents.open_count()
|
||||
+ self
|
||||
.background_processes
|
||||
.as_ref()
|
||||
.map(|processes| processes.lock().unwrap().len())
|
||||
.unwrap_or(0)
|
||||
})
|
||||
}
|
||||
|
||||
fn translate_line(&mut self, kind: Option<&str>, body: &Value, line: &Value) -> Vec<Event> {
|
||||
@@ -242,11 +254,7 @@ impl Translator {
|
||||
events.extend(self.failure(error));
|
||||
}
|
||||
events.push(Event::Status {
|
||||
state: if self
|
||||
.subagents
|
||||
.as_ref()
|
||||
.is_some_and(|subagents| subagents.any_open(true))
|
||||
{
|
||||
state: if self.background_task_count().is_some_and(|count| count > 0) {
|
||||
SessionStatus::Waiting
|
||||
} else {
|
||||
SessionStatus::Idle
|
||||
@@ -390,13 +398,7 @@ impl Translator {
|
||||
subagents.finish(id);
|
||||
}
|
||||
self.prompts.remove(id);
|
||||
if was_open
|
||||
&& !self.in_turn
|
||||
&& self
|
||||
.subagents
|
||||
.as_ref()
|
||||
.is_some_and(|subagents| !subagents.any_open(true))
|
||||
{
|
||||
if was_open && !self.in_turn && self.background_task_count() == Some(0) {
|
||||
vec![Event::Status {
|
||||
state: SessionStatus::Idle,
|
||||
}]
|
||||
@@ -1216,8 +1218,10 @@ mod tests {
|
||||
fn codex_subagents_get_their_own_transcripts_and_hold_the_parent_waiting() {
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
let subagents = Arc::new(Subagents::new(dir.path().to_path_buf()));
|
||||
let background_processes = Arc::new(Mutex::new(HashSet::new()));
|
||||
let mut translator = Translator::new(
|
||||
Arc::clone(&subagents),
|
||||
Arc::clone(&background_processes),
|
||||
Some("parent-thread".to_string()),
|
||||
false,
|
||||
);
|
||||
@@ -1313,8 +1317,10 @@ mod tests {
|
||||
fn codex_reports_each_change_to_its_live_background_count() {
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
let subagents = Arc::new(Subagents::new(dir.path().to_path_buf()));
|
||||
let background_processes = Arc::new(Mutex::new(HashSet::new()));
|
||||
let mut translator = Translator::new(
|
||||
Arc::clone(&subagents),
|
||||
Arc::clone(&background_processes),
|
||||
Some("parent-thread".to_string()),
|
||||
false,
|
||||
);
|
||||
@@ -1335,7 +1341,11 @@ mod tests {
|
||||
}));
|
||||
assert_eq!(events.last(), Some(&Event::BackgroundTasks { count }));
|
||||
}
|
||||
for (child, count) in [("child-a", 1), ("child-b", 0)] {
|
||||
background_processes
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert("command-a".to_string());
|
||||
for (child, count) in [("child-a", 2), ("child-b", 1)] {
|
||||
let events = translator.translate(&json!({
|
||||
"method": "item/completed",
|
||||
"params": {
|
||||
@@ -1350,6 +1360,14 @@ mod tests {
|
||||
}
|
||||
}));
|
||||
assert_eq!(events.last(), Some(&Event::BackgroundTasks { count }));
|
||||
assert!(!events.iter().any(|event| {
|
||||
matches!(
|
||||
event,
|
||||
Event::Status {
|
||||
state: SessionStatus::Idle
|
||||
}
|
||||
)
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1490,6 +1508,7 @@ mod tests {
|
||||
subagents.start("child-thread", "child", Some("work"));
|
||||
let mut translator = Translator::new(
|
||||
Arc::clone(&subagents),
|
||||
Arc::new(Mutex::new(HashSet::new())),
|
||||
Some("parent-thread".to_string()),
|
||||
true,
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user