[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:
Owen Lin
2025-11-19 07:58:09 -08:00
committed by GitHub
parent cfc57e14c7
commit 1924500250
6 changed files with 496 additions and 5 deletions

View File

@@ -517,6 +517,10 @@ pub struct Thread {
pub created_at: i64,
/// [UNSTABLE] Path to the thread on disk.
pub path: PathBuf,
/// Only populated on a `thread/resume` response.
/// For all other responses and notifications returning a Thread,
/// the turns field will be an empty list.
pub turns: Vec<Turn>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
@@ -531,8 +535,9 @@ pub struct AccountUpdatedNotification {
#[ts(export_to = "v2/")]
pub struct Turn {
pub id: String,
/// This is currently only populated for resumed threads.
/// TODO: properly populate items for all turns.
/// Only populated on a `thread/resume` response.
/// For all other responses and notifications returning a Turn,
/// the items field will be an empty list.
pub items: Vec<ThreadItem>,
#[serde(flatten)]
pub status: TurnStatus,