mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[app-server] populate thread>turns>items on thread/resume (#6848)
This PR allows clients to render historical messages when resuming a thread via `thread/resume` by reading from the list of `EventMsg` payloads loaded from the rollout, and then transforming them into Turns and ThreadItems to be returned on the `Thread` object. This is implemented by leveraging `SessionConfiguredNotification` which returns this list of `EventMsg` objects when resuming a conversation, and then applying a stateful `ThreadHistoryBuilder` that parses from this EventMsg log and transforms it into Turns and ThreadItems. Note that we only persist a subset of `EventMsg`s in a rollout as defined in `policy.rs`, so we lose fidelity whenever we resume a thread compared to when we streamed the thread's turns originally. However, this behavior is at parity with the legacy API.
This commit is contained in:
@@ -91,6 +91,7 @@ use codex_app_server_protocol::TurnStatus;
|
||||
use codex_app_server_protocol::UserInfoResponse;
|
||||
use codex_app_server_protocol::UserInput as V2UserInput;
|
||||
use codex_app_server_protocol::UserSavedConfig;
|
||||
use codex_app_server_protocol::build_turns_from_event_msgs;
|
||||
use codex_backend_client::Client as BackendClient;
|
||||
use codex_core::AuthManager;
|
||||
use codex_core::CodexConversation;
|
||||
@@ -1652,6 +1653,11 @@ impl CodexMessageProcessor {
|
||||
session_configured,
|
||||
..
|
||||
}) => {
|
||||
let SessionConfiguredEvent {
|
||||
rollout_path,
|
||||
initial_messages,
|
||||
..
|
||||
} = session_configured;
|
||||
// Auto-attach a conversation listener when resuming a thread.
|
||||
if let Err(err) = self
|
||||
.attach_conversation_listener(conversation_id, false, ApiVersion::V2)
|
||||
@@ -1664,8 +1670,8 @@ impl CodexMessageProcessor {
|
||||
);
|
||||
}
|
||||
|
||||
let thread = match read_summary_from_rollout(
|
||||
session_configured.rollout_path.as_path(),
|
||||
let mut thread = match read_summary_from_rollout(
|
||||
rollout_path.as_path(),
|
||||
fallback_model_provider.as_str(),
|
||||
)
|
||||
.await
|
||||
@@ -1676,13 +1682,17 @@ impl CodexMessageProcessor {
|
||||
request_id,
|
||||
format!(
|
||||
"failed to load rollout `{}` for conversation {conversation_id}: {err}",
|
||||
session_configured.rollout_path.display()
|
||||
rollout_path.display()
|
||||
),
|
||||
)
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
};
|
||||
thread.turns = initial_messages
|
||||
.as_deref()
|
||||
.map_or_else(Vec::new, build_turns_from_event_msgs);
|
||||
|
||||
let response = ThreadResumeResponse {
|
||||
thread,
|
||||
model: session_configured.model,
|
||||
@@ -1692,6 +1702,7 @@ impl CodexMessageProcessor {
|
||||
sandbox: session_configured.sandbox_policy.into(),
|
||||
reasoning_effort: session_configured.reasoning_effort,
|
||||
};
|
||||
|
||||
self.outgoing.send_response(request_id, response).await;
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -2983,6 +2994,7 @@ fn summary_to_thread(summary: ConversationSummary) -> Thread {
|
||||
model_provider,
|
||||
created_at: created_at.map(|dt| dt.timestamp()).unwrap_or(0),
|
||||
path,
|
||||
turns: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user