Expose lifecycle timestamps on app-server thread items (#57172)

## What changed

- Add nullable `startedAtMs` and `completedAtMs` fields to `ThreadItem` in live notifications and turn history. Values are Unix milliseconds when recorded.
- Preserve recorded item times through history reconstruction, pagination, and resume, including command start times recorded during approval.
- Separate the Rust item payload into `ThreadItemPayload` while keeping the JSON payload flat, and update consumers, schemas, and generated TypeScript and Python types.

## Testing

Extend coverage for timestamp serialization, history reconstruction, paginated reads and resume, and persisted Python SDK items.

GitOrigin-RevId: ecbcee95af52db7c807b46a6e9deb30e5fba1f80
This commit is contained in:
Charlie Marsh
2026-10-26 18:13:00 +00:00
committed by copyberry
parent cf29971d93
commit a797dd7c6f
206 changed files with 4691 additions and 3089 deletions
@@ -1,6 +1,7 @@
use super::CodexErrorInfo;
use super::ThreadEnvironment;
use super::ThreadItem;
use super::ThreadItemPayload;
use super::ThreadStatus;
use super::TurnStatus;
use crate::JsonSchema;
@@ -409,6 +410,15 @@ pub struct Turn {
pub duration_ms: Option<i64>,
}
impl Turn {
/// Iterates over the item payloads in this turn.
pub fn item_payloads(
&self,
) -> impl DoubleEndedIterator<Item = &ThreadItemPayload> + ExactSizeIterator {
self.items.iter().map(|item| &item.payload)
}
}
#[derive(Default, Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]