From 3d8d8ff368203b1ba2732092b403dfa5711b0a74 Mon Sep 17 00:00:00 2001 From: Owen Lin Date: Thu, 11 Jun 2026 17:06:41 -0700 Subject: [PATCH 1/2] app-server: document thread and turn IDs are UUID7 --- .../schema/json/ServerNotification.json | 2 ++ .../json/codex_app_server_protocol.schemas.json | 2 ++ .../json/codex_app_server_protocol.v2.schemas.json | 2 ++ .../schema/json/v2/ReviewStartResponse.json | 1 + .../schema/json/v2/ThreadForkResponse.json | 2 ++ .../schema/json/v2/ThreadListResponse.json | 2 ++ .../json/v2/ThreadMetadataUpdateResponse.json | 2 ++ .../schema/json/v2/ThreadReadResponse.json | 2 ++ .../schema/json/v2/ThreadResumeResponse.json | 2 ++ .../schema/json/v2/ThreadRollbackResponse.json | 2 ++ .../schema/json/v2/ThreadStartResponse.json | 2 ++ .../schema/json/v2/ThreadStartedNotification.json | 2 ++ .../schema/json/v2/ThreadUnarchiveResponse.json | 2 ++ .../schema/json/v2/TurnCompletedNotification.json | 1 + .../schema/json/v2/TurnStartResponse.json | 1 + .../schema/json/v2/TurnStartedNotification.json | 1 + .../schema/typescript/ThreadId.ts | 5 +++++ .../schema/typescript/v2/Thread.ts | 6 +++++- .../schema/typescript/v2/Turn.ts | 6 +++++- .../src/protocol/v2/thread_data.rs | 2 ++ codex-rs/core/src/session/mod.rs | 13 +++++++++++-- codex-rs/protocol/src/thread_id.rs | 3 +++ 22 files changed, 59 insertions(+), 4 deletions(-) diff --git a/codex-rs/app-server-protocol/schema/json/ServerNotification.json b/codex-rs/app-server-protocol/schema/json/ServerNotification.json index 74fb9e739ce9..1950f602f047 100644 --- a/codex-rs/app-server-protocol/schema/json/ServerNotification.json +++ b/codex-rs/app-server-protocol/schema/json/ServerNotification.json @@ -3616,6 +3616,7 @@ "description": "Optional Git metadata captured when the thread was created." }, "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", "type": "string" }, "modelProvider": { @@ -5101,6 +5102,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index 3a2af11db38a..8e4f118cb9e2 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -16805,6 +16805,7 @@ "description": "Optional Git metadata captured when the thread was created." }, "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", "type": "string" }, "modelProvider": { @@ -19673,6 +19674,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json index 286fc0e2f65d..7fcf2515227c 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json @@ -14584,6 +14584,7 @@ "description": "Optional Git metadata captured when the thread was created." }, "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", "type": "string" }, "modelProvider": { @@ -17452,6 +17453,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ReviewStartResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ReviewStartResponse.json index 545ae64d4af5..4eb3489663d3 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ReviewStartResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ReviewStartResponse.json @@ -1438,6 +1438,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadForkResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadForkResponse.json index c19251667a38..97d07460492b 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadForkResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadForkResponse.json @@ -1059,6 +1059,7 @@ "description": "Optional Git metadata captured when the thread was created." }, "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", "type": "string" }, "modelProvider": { @@ -2017,6 +2018,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadListResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadListResponse.json index 9925c5411e1f..d06ee75c422f 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadListResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadListResponse.json @@ -865,6 +865,7 @@ "description": "Optional Git metadata captured when the thread was created." }, "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", "type": "string" }, "modelProvider": { @@ -1823,6 +1824,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadMetadataUpdateResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadMetadataUpdateResponse.json index 1e142947ed1a..ed63f149849d 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadMetadataUpdateResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadMetadataUpdateResponse.json @@ -865,6 +865,7 @@ "description": "Optional Git metadata captured when the thread was created." }, "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", "type": "string" }, "modelProvider": { @@ -1823,6 +1824,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadReadResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadReadResponse.json index 532a712807f6..51b3dbb278e2 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadReadResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadReadResponse.json @@ -865,6 +865,7 @@ "description": "Optional Git metadata captured when the thread was created." }, "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", "type": "string" }, "modelProvider": { @@ -1823,6 +1824,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadResumeResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadResumeResponse.json index 1a3b22f12cbf..de5cfb147ad6 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadResumeResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadResumeResponse.json @@ -1059,6 +1059,7 @@ "description": "Optional Git metadata captured when the thread was created." }, "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", "type": "string" }, "modelProvider": { @@ -2017,6 +2018,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadRollbackResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadRollbackResponse.json index 9f394b31cf11..fe235b41d19d 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadRollbackResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadRollbackResponse.json @@ -865,6 +865,7 @@ "description": "Optional Git metadata captured when the thread was created." }, "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", "type": "string" }, "modelProvider": { @@ -1823,6 +1824,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadStartResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadStartResponse.json index a754c6bc0f3c..5f9f0a72aec7 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadStartResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadStartResponse.json @@ -1059,6 +1059,7 @@ "description": "Optional Git metadata captured when the thread was created." }, "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", "type": "string" }, "modelProvider": { @@ -2017,6 +2018,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadStartedNotification.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadStartedNotification.json index 22801809cd72..457b081cdb39 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadStartedNotification.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadStartedNotification.json @@ -865,6 +865,7 @@ "description": "Optional Git metadata captured when the thread was created." }, "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", "type": "string" }, "modelProvider": { @@ -1823,6 +1824,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadUnarchiveResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadUnarchiveResponse.json index 3009e86e70bd..079bd0f8f67e 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadUnarchiveResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadUnarchiveResponse.json @@ -865,6 +865,7 @@ "description": "Optional Git metadata captured when the thread was created." }, "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", "type": "string" }, "modelProvider": { @@ -1823,6 +1824,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/TurnCompletedNotification.json b/codex-rs/app-server-protocol/schema/json/v2/TurnCompletedNotification.json index b9a940157ce4..fb703d511f11 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/TurnCompletedNotification.json +++ b/codex-rs/app-server-protocol/schema/json/v2/TurnCompletedNotification.json @@ -1438,6 +1438,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/TurnStartResponse.json b/codex-rs/app-server-protocol/schema/json/v2/TurnStartResponse.json index da10713dd18d..a8a9d5a62b68 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/TurnStartResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/TurnStartResponse.json @@ -1438,6 +1438,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/TurnStartedNotification.json b/codex-rs/app-server-protocol/schema/json/v2/TurnStartedNotification.json index 6b9349822137..becf0d87cdab 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/TurnStartedNotification.json +++ b/codex-rs/app-server-protocol/schema/json/v2/TurnStartedNotification.json @@ -1438,6 +1438,7 @@ "description": "Only populated when the Turn's status is failed." }, "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", "type": "string" }, "items": { diff --git a/codex-rs/app-server-protocol/schema/typescript/ThreadId.ts b/codex-rs/app-server-protocol/schema/typescript/ThreadId.ts index bfb3b4b4d769..801ffb35e4ed 100644 --- a/codex-rs/app-server-protocol/schema/typescript/ThreadId.ts +++ b/codex-rs/app-server-protocol/schema/typescript/ThreadId.ts @@ -2,4 +2,9 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +/** + * Identifier for a Codex thread. + * + * Codex-generated thread IDs are UUIDv7, and some use cases rely on that. + */ export type ThreadId = string; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/Thread.ts b/codex-rs/app-server-protocol/schema/typescript/v2/Thread.ts index 1c288ccbd4d1..06df74f0ad0e 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/Thread.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/Thread.ts @@ -8,7 +8,11 @@ import type { ThreadSource } from "./ThreadSource"; import type { ThreadStatus } from "./ThreadStatus"; import type { Turn } from "./Turn"; -export type Thread = { id: string, +export type Thread = { +/** + * Identifier for this thread. Codex-generated thread IDs are UUIDv7. + */ +id: string, /** * Session id shared by threads that belong to the same session tree. */ diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/Turn.ts b/codex-rs/app-server-protocol/schema/typescript/v2/Turn.ts index 6505ec345f97..b8680256d1c5 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/Turn.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/Turn.ts @@ -6,7 +6,11 @@ import type { TurnError } from "./TurnError"; import type { TurnItemsView } from "./TurnItemsView"; import type { TurnStatus } from "./TurnStatus"; -export type Turn = { id: string, +export type Turn = { +/** + * Identifier for this turn. Codex-generated turn IDs are UUIDv7. + */ +id: string, /** * Thread items currently included in this turn payload. */ diff --git a/codex-rs/app-server-protocol/src/protocol/v2/thread_data.rs b/codex-rs/app-server-protocol/src/protocol/v2/thread_data.rs index 52a8d7017a51..176172dd8c9f 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2/thread_data.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2/thread_data.rs @@ -133,6 +133,7 @@ pub struct GitInfo { #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct Thread { + /// Identifier for this thread. Codex-generated thread IDs are UUIDv7. pub id: String, /// Session id shared by threads that belong to the same session tree. pub session_id: String, @@ -186,6 +187,7 @@ pub struct Thread { #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct Turn { + /// Identifier for this turn. Codex-generated turn IDs are UUIDv7. pub id: String, /// Thread items currently included in this turn payload. pub items: Vec, diff --git a/codex-rs/core/src/session/mod.rs b/codex-rs/core/src/session/mod.rs index 32fcfd09e28a..697d1a5f95e9 100644 --- a/codex-rs/core/src/session/mod.rs +++ b/codex-rs/core/src/session/mod.rs @@ -719,7 +719,7 @@ impl Codex { op: Op, trace: Option, ) -> CodexResult { - let id = Uuid::now_v7().to_string(); + let id = new_submission_id(); let sub = Submission { id: id.clone(), op, @@ -737,7 +737,7 @@ impl Codex { client_user_message_id: Option, ) -> CodexResult { debug_assert!(matches!(op, Op::UserInput { .. })); - let id = Uuid::now_v7().to_string(); + let id = new_submission_id(); let sub = Submission { id: id.clone(), op, @@ -864,6 +864,15 @@ impl Codex { } } +/// Generate a public submission ID. App-server exposes turn-producing +/// submission IDs as turn IDs. +/// +/// Some use cases take advantage of the fact that these are UUID7, so +/// let's not change this. +fn new_submission_id() -> String { + Uuid::now_v7().to_string() +} + fn get_service_tier( configured_service_tier: Option, fast_mode_enabled: bool, diff --git a/codex-rs/protocol/src/thread_id.rs b/codex-rs/protocol/src/thread_id.rs index d6e9a8825ec0..dcfedc7f5217 100644 --- a/codex-rs/protocol/src/thread_id.rs +++ b/codex-rs/protocol/src/thread_id.rs @@ -10,6 +10,9 @@ use uuid::Uuid; #[derive(Debug, Clone, Copy, PartialEq, Eq, TS, Hash)] #[ts(type = "string")] +/// Identifier for a Codex thread. +/// +/// Codex-generated thread IDs are UUIDv7, and some use cases rely on that. pub struct ThreadId { pub(crate) uuid: Uuid, } From 008674f1390edbba704d50480ad31d9e3b262efc Mon Sep 17 00:00:00 2001 From: Owen Lin Date: Mon, 22 Jun 2026 11:53:45 -0700 Subject: [PATCH 2/2] update --- codex-rs/core/src/session/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/codex-rs/core/src/session/mod.rs b/codex-rs/core/src/session/mod.rs index 697d1a5f95e9..4da8eb14f3e4 100644 --- a/codex-rs/core/src/session/mod.rs +++ b/codex-rs/core/src/session/mod.rs @@ -864,11 +864,11 @@ impl Codex { } } -/// Generate a public submission ID. App-server exposes turn-producing -/// submission IDs as turn IDs. +/// Generate a core submission ID. App-server exposes submission IDs that +/// create turns as a public-facing turn ID. /// -/// Some use cases take advantage of the fact that these are UUID7, so -/// let's not change this. +/// Some use cases take advantage of the fact that these are UUID7 which +/// encodes a timestamp, so think carefully before changing this. fn new_submission_id() -> String { Uuid::now_v7().to_string() }