Skip to content

Commit 5ecff05

Browse files
authored
feat(app-server): move v2 sessionId onto Thread (#21336)
## Why `session_id` and `thread_id` are separate identities after #20437, but app-server only surfaced `sessionId` on the `thread/start`, `thread/resume`, and `thread/fork` response envelopes. Other thread-bearing surfaces such as `thread/list`, `thread/read`, `thread/started`, `thread/rollback`, `thread/metadata/update`, and `thread/unarchive` either lacked the grouping key or forced clients to special-case those three responses. Making `sessionId` part of the reusable `Thread` payload gives every v2 API surface one place to expose session-tree identity. ## Mental model 1. thread.sessionId lives on `Thread` 2. It is a view/runtime identity for the current live session tree, not durable stored lineage metadata 3. When app-server has a live loaded thread, it copies the real value from core’s session_configured.session_id 4. When it only has stored/unloaded data, it falls back to thread.sessionId = thread.id ## What changed - Added `sessionId` to the v2 [`Thread`](https://github.com/openai/codex/blob/8fc9e9b4cf81b6f61d432e71f1eb266f6f104b63/codex-rs/app-server-protocol/src/protocol/v2/thread_data.rs#L105-L109). - Removed the duplicate top-level `sessionId` fields from `thread/start`, `thread/resume`, and `thread/fork`; clients should now read `response.thread.sessionId`. - Populated `thread.sessionId` when building live thread responses, replaying loaded threads, and returning stored-thread summaries so the field is present across start, resume, fork, list, read, rollback, metadata-update, unarchive, and `thread/started` paths. See [`load_thread_from_resume_source_or_send_internal`](https://github.com/openai/codex/blob/8fc9e9b4cf81b6f61d432e71f1eb266f6f104b63/codex-rs/app-server/src/request_processors/thread_processor.rs#L2824-L2918) and [`thread_from_stored_thread`](https://github.com/openai/codex/blob/8fc9e9b4cf81b6f61d432e71f1eb266f6f104b63/codex-rs/app-server/src/request_processors/thread_processor.rs#L3671-L3719). - Preserved the stored-thread fallback: if a thread has not been loaded into a live session tree yet, `thread.sessionId` falls back to `thread.id`; once the thread is live again, the field reports the active session tree root. - Regenerated the JSON/TypeScript schemas and updated the app-server README examples to show [`thread.sessionId`](https://github.com/openai/codex/blob/8fc9e9b4cf81b6f61d432e71f1eb266f6f104b63/codex-rs/app-server/README.md#L306-L310) on the thread object.
1 parent ca257b6 commit 5ecff05

43 files changed

Lines changed: 186 additions & 112 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

codex-rs/analytics/src/analytics_client_tests.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ fn sample_thread_with_metadata(
128128
) -> Thread {
129129
Thread {
130130
id: thread_id.to_string(),
131+
session_id: format!("session-{thread_id}"),
131132
forked_from_id: None,
132133
preview: "first prompt".to_string(),
133134
ephemeral,
@@ -154,7 +155,6 @@ fn sample_thread_start_response(
154155
model: &str,
155156
) -> ClientResponsePayload {
156157
ClientResponsePayload::ThreadStart(ThreadStartResponse {
157-
session_id: format!("session-{thread_id}"),
158158
thread: sample_thread_with_metadata(
159159
thread_id,
160160
ephemeral,
@@ -216,7 +216,6 @@ fn sample_thread_resume_response_with_source(
216216
thread_source: Option<AppServerThreadSource>,
217217
) -> ClientResponsePayload {
218218
ClientResponsePayload::ThreadResume(ThreadResumeResponse {
219-
session_id: format!("session-{thread_id}"),
220219
thread: sample_thread_with_metadata(thread_id, ephemeral, source, thread_source),
221220
model: model.to_string(),
222221
model_provider: "openai".to_string(),

codex-rs/analytics/src/client_tests.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ fn sample_thread_archive_request() -> ClientRequest {
7676
fn sample_thread(thread_id: &str) -> Thread {
7777
Thread {
7878
id: thread_id.to_string(),
79+
session_id: format!("session-{thread_id}"),
7980
forked_from_id: None,
8081
preview: "first prompt".to_string(),
8182
ephemeral: false,
@@ -102,7 +103,6 @@ fn sample_permission_profile() -> AppServerPermissionProfile {
102103

103104
fn sample_thread_start_response() -> ClientResponsePayload {
104105
ClientResponsePayload::ThreadStart(ThreadStartResponse {
105-
session_id: "session-1".to_string(),
106106
thread: sample_thread("thread-1"),
107107
model: "gpt-5".to_string(),
108108
model_provider: "openai".to_string(),
@@ -120,7 +120,6 @@ fn sample_thread_start_response() -> ClientResponsePayload {
120120

121121
fn sample_thread_resume_response() -> ClientResponsePayload {
122122
ClientResponsePayload::ThreadResume(ThreadResumeResponse {
123-
session_id: "session-2".to_string(),
124123
thread: sample_thread("thread-2"),
125124
model: "gpt-5".to_string(),
126125
model_provider: "openai".to_string(),
@@ -138,7 +137,6 @@ fn sample_thread_resume_response() -> ClientResponsePayload {
138137

139138
fn sample_thread_fork_response() -> ClientResponsePayload {
140139
ClientResponsePayload::ThreadFork(ThreadForkResponse {
141-
session_id: "session-3".to_string(),
142140
thread: sample_thread("thread-3"),
143141
model: "gpt-5".to_string(),
144142
model_provider: "openai".to_string(),

codex-rs/app-server-protocol/schema/json/ServerNotification.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json

Lines changed: 5 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json

Lines changed: 5 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codex-rs/app-server-protocol/schema/json/v2/ThreadForkResponse.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codex-rs/app-server-protocol/schema/json/v2/ThreadListResponse.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codex-rs/app-server-protocol/schema/json/v2/ThreadMetadataUpdateResponse.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codex-rs/app-server-protocol/schema/json/v2/ThreadReadResponse.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codex-rs/app-server-protocol/schema/json/v2/ThreadResumeResponse.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)