mirror of
https://github.com/openai/codex.git
synced 2026-10-30 19:18:49 +00:00
Merge 1ae001f0a2 into sapling-pr-archive-bolinfest
This commit is contained in:
@@ -11,6 +11,7 @@ use crate::outgoing_message::OutgoingMessageSender;
|
||||
use crate::outgoing_message::OutgoingNotification;
|
||||
use crate::outgoing_message::ThreadScopedOutgoingMessageSender;
|
||||
use crate::thread_status::ThreadWatchManager;
|
||||
use crate::thread_status::resolve_thread_status;
|
||||
use chrono::DateTime;
|
||||
use chrono::SecondsFormat;
|
||||
use chrono::Utc;
|
||||
@@ -2051,10 +2052,12 @@ impl CodexMessageProcessor {
|
||||
.upsert_thread(thread.clone())
|
||||
.await;
|
||||
|
||||
thread.status = self
|
||||
.thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await;
|
||||
thread.status = resolve_thread_status(
|
||||
self.thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await,
|
||||
false,
|
||||
);
|
||||
|
||||
let response = ThreadStartResponse {
|
||||
thread: thread.clone(),
|
||||
@@ -2370,10 +2373,12 @@ impl CodexMessageProcessor {
|
||||
|
||||
match result {
|
||||
Ok(mut thread) => {
|
||||
thread.status = self
|
||||
.thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await;
|
||||
thread.status = resolve_thread_status(
|
||||
self.thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await,
|
||||
false,
|
||||
);
|
||||
let thread_id = thread.id.clone();
|
||||
let response = ThreadUnarchiveResponse { thread };
|
||||
self.outgoing.send_response(request_id, response).await;
|
||||
@@ -2747,10 +2752,12 @@ impl CodexMessageProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
thread.status = self
|
||||
.thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await;
|
||||
thread.status = resolve_thread_status(
|
||||
self.thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await,
|
||||
false,
|
||||
);
|
||||
let response = ThreadReadResponse { thread };
|
||||
self.outgoing.send_response(request_id, response).await;
|
||||
}
|
||||
@@ -2927,10 +2934,12 @@ impl CodexMessageProcessor {
|
||||
.upsert_thread(thread.clone())
|
||||
.await;
|
||||
|
||||
thread.status = self
|
||||
.thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await;
|
||||
thread.status = resolve_thread_status(
|
||||
self.thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await,
|
||||
false,
|
||||
);
|
||||
|
||||
let response = ThreadResumeResponse {
|
||||
thread,
|
||||
@@ -3440,10 +3449,12 @@ impl CodexMessageProcessor {
|
||||
.upsert_thread(thread.clone())
|
||||
.await;
|
||||
|
||||
thread.status = self
|
||||
.thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await;
|
||||
thread.status = resolve_thread_status(
|
||||
self.thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await,
|
||||
false,
|
||||
);
|
||||
|
||||
let response = ThreadForkResponse {
|
||||
thread: thread.clone(),
|
||||
@@ -5581,10 +5592,12 @@ impl CodexMessageProcessor {
|
||||
self.thread_watch_manager
|
||||
.upsert_thread(thread.clone())
|
||||
.await;
|
||||
thread.status = self
|
||||
.thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await;
|
||||
thread.status = resolve_thread_status(
|
||||
self.thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await,
|
||||
false,
|
||||
);
|
||||
let notif = ThreadStartedNotification { thread };
|
||||
self.outgoing
|
||||
.send_server_notification(ServerNotification::ThreadStarted(notif))
|
||||
@@ -6244,6 +6257,9 @@ async fn handle_pending_thread_resume_request(
|
||||
let state = thread_state.lock().await;
|
||||
state.active_turn_snapshot()
|
||||
};
|
||||
let mut has_in_progress_turn = active_turn
|
||||
.as_ref()
|
||||
.is_some_and(|turn| matches!(turn.status, TurnStatus::InProgress));
|
||||
|
||||
let request_id = pending.request_id;
|
||||
let connection_id = request_id.connection_id;
|
||||
@@ -6270,9 +6286,20 @@ async fn handle_pending_thread_resume_request(
|
||||
return;
|
||||
}
|
||||
};
|
||||
thread.status = thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await;
|
||||
|
||||
has_in_progress_turn = has_in_progress_turn
|
||||
|| thread
|
||||
.turns
|
||||
.iter()
|
||||
.any(|turn| matches!(turn.status, TurnStatus::InProgress));
|
||||
|
||||
let status = resolve_thread_status(
|
||||
thread_watch_manager
|
||||
.loaded_status_for_thread(&thread.id)
|
||||
.await,
|
||||
has_in_progress_turn,
|
||||
);
|
||||
thread.status = status;
|
||||
|
||||
let ThreadConfigSnapshot {
|
||||
model,
|
||||
|
||||
@@ -239,6 +239,22 @@ impl ThreadWatchManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_thread_status(
|
||||
status: ThreadStatus,
|
||||
has_in_progress_turn: bool,
|
||||
) -> ThreadStatus {
|
||||
// Running-turn events can arrive before the watch runtime state is observed by
|
||||
// the listener loop. In that window we prefer to reflect a real active turn as
|
||||
// `Active` instead of `Idle`/`NotLoaded`.
|
||||
if has_in_progress_turn && matches!(status, ThreadStatus::Idle | ThreadStatus::NotLoaded) {
|
||||
return ThreadStatus::Active {
|
||||
active_flags: Vec::new(),
|
||||
};
|
||||
}
|
||||
|
||||
status
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ThreadWatchState {
|
||||
runtime_by_thread_id: HashMap<String, RuntimeFacts>,
|
||||
@@ -459,6 +475,37 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolves_in_progress_turn_to_active_status() {
|
||||
let status = resolve_thread_status(ThreadStatus::Idle, true);
|
||||
assert_eq!(
|
||||
status,
|
||||
ThreadStatus::Active {
|
||||
active_flags: Vec::new(),
|
||||
}
|
||||
);
|
||||
|
||||
let status = resolve_thread_status(ThreadStatus::NotLoaded, true);
|
||||
assert_eq!(
|
||||
status,
|
||||
ThreadStatus::Active {
|
||||
active_flags: Vec::new(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn keeps_status_when_no_in_progress_turn() {
|
||||
assert_eq!(
|
||||
resolve_thread_status(ThreadStatus::Idle, false),
|
||||
ThreadStatus::Idle
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_thread_status(ThreadStatus::SystemError, false),
|
||||
ThreadStatus::SystemError
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn system_error_sets_idle_flag_until_next_turn() {
|
||||
let manager = ThreadWatchManager::new();
|
||||
|
||||
Reference in New Issue
Block a user