[6 of 7] Add app-server thread settings API#22509
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f47fe2b6ab
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ea06c8a6e8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
owenlin0
left a comment
There was a problem hiding this comment.
One follow-up concern on the new turn-context wait path.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 49bcf51b7f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
b2fa7ac to
9393c26
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 28f6e90082
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bb41cb44cf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fd4929c5b8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 78dc40ac5c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0f422dd875
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 654586eda6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a9fd5c35e1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| collaboration_mode: request | ||
| .collaboration_mode | ||
| .map(|mode| self.normalize_turn_start_collaboration_mode(mode)), |
There was a problem hiding this comment.
Merge model overrides into collaboration mode
When thread/settings/update sends collaborationMode together with top-level model or effort, the top-level values are accepted but then ignored: this constructs a CodexThreadSettingsOverrides with both fields, but core has no separate model/effort setting and uses the provided collaboration_mode as-is whenever it is Some. A client that atomically selects a mode and a model therefore gets a successful response with the nested collaboration-mode model instead of the requested top-level model; merge these fields into the mode settings or reject the combination.
Useful? React with 👍 / 👎.
|
This PR is superseded by #23502. |
## Why App-server clients need a way to update a thread's next-turn settings without starting a turn, adding transcript content, or waiting for turn lifecycle events. This gives settings UI a direct path for durable thread settings while clients observe the eventual effective state through a notification. This is a simplified rework of PR #22509. In particular, it changes the `thread/settings/update` api to return immediately rather than waiting and returning the effective (updated) thread settings. This makes the new api consistent with `turn/start` and greatly reduces the complexity of the implementation relative to the earlier attempt. ## What Changed - Adds experimental `thread/settings/update` with partial-update request fields and an empty acknowledgment response. - Adds experimental `thread/settings/updated`, carrying full effective `ThreadSettings` and scoped by `threadId` to subscribed clients for the affected thread. - Shares durable settings validation with `turn/start`, including `sandboxPolicy` plus `permissions` rejection and `serviceTier: null` clearing. - Emits the same settings notification when `turn/start` overrides change the stored effective thread settings. - Regenerates app-server protocol schema fixtures and updates `app-server/README.md`.
**Stack position:** [1 of 7] ## Summary The first three PRs in this stack are a cleanup pass before the actual thread settings API work. Today, core has several overlapping "user input" ops: `UserInput`, `UserInputWithTurnContext`, and `UserTurn`. They differ mostly in how much next-turn state they carry, which makes the later queued thread settings update harder to reason about and review. This PR starts that cleanup by adding the shared `ThreadSettingsOverrides` payload and allowing `Op::UserInput` to carry it. Existing variants remain in place here, so this layer is mostly a behavior-preserving API shape change plus mechanical constructor updates. ## End State After PR3 By the end of PR3, `Op::UserInput` is the only "user input" core op. It can carry optional thread settings overrides for callers that need to update stored defaults with a turn, while callers without updates use empty settings. `Op::UserInputWithTurnContext` and `Op::UserTurn` are deleted. ## End State After PR5 By the end of PR5, core will have only two ops for this area: - `Op::UserInput` for user-input-bearing submissions. - `Op::ThreadSettings` for settings-only updates. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai/codex#23080) (this PR) 2. [2 of 7] [Remove UserInputWithTurnContext](openai/codex#23081) 3. [3 of 7] [Remove UserTurn](openai/codex#23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai/codex#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai/codex#22508) 6. [6 of 7] [Add app-server thread settings API](openai/codex#22509) 7. [7 of 7] [Sync TUI thread settings](openai/codex#22510)
**Stack position:** [2 of 7] ## Summary This PR removes the overlapping `Op::UserInputWithTurnContext` variant now that `Op::UserInput` can carry thread settings overrides directly. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai/codex#23080) 2. [2 of 7] [Remove UserInputWithTurnContext](openai/codex#23081) (this PR) 3. [3 of 7] [Remove UserTurn](openai/codex#23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai/codex#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai/codex#22508) 6. [6 of 7] [Add app-server thread settings API](openai/codex#22509) 7. [7 of 7] [Sync TUI thread settings](openai/codex#22510)
**Stack position:** [3 of 7] ## Summary This PR finishes the input-op consolidation by moving the remaining `Op::UserTurn` callers onto `Op::UserInput` and deleting `Op::UserTurn`. This touches a lot of files, but it is a low-risk mechanical migration. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai/codex#23080) 2. [2 of 7] [Remove UserInputWithTurnContext](openai/codex#23081) 3. [3 of 7] [Remove UserTurn](openai/codex#23075) (this PR) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai/codex#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai/codex#22508) 6. [6 of 7] [Add app-server thread settings API](openai/codex#22509) 7. [7 of 7] [Sync TUI thread settings](openai/codex#22510)
**Stack position:** [5 of 7] ## Summary This PR adds `Op::ThreadSettings`, a queued settings-only update mechanism for changing stored thread settings without starting a new turn. It also removes the legacy `Op::OverrideTurnContext` in the same layer, so reviewers can see the replacement and deletion together. ## Changes - Add `Op::ThreadSettings` for settings-only queued updates. - Emit `ThreadSettingsApplied` with the effective thread settings snapshot after core applies an update. - Route settings-only updates through the same submission queue as user input. - Migrate remaining `OverrideTurnContext` tests and callers to the queued `Op::ThreadSettings` path. - Delete `Op::OverrideTurnContext` from the core protocol and submission loop. This stack addresses #20656 and #22090. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai/codex#23080) 2. [2 of 7] [Remove UserInputWithTurnContext](openai/codex#23081) 3. [3 of 7] [Remove UserTurn](openai/codex#23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai/codex#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai/codex#22508) (this PR) 6. [6 of 7] [Add app-server thread settings API](openai/codex#22509) 7. [7 of 7] [Sync TUI thread settings](openai/codex#22510)
## Why App-server clients need a way to update a thread's next-turn settings without starting a turn, adding transcript content, or waiting for turn lifecycle events. This gives settings UI a direct path for durable thread settings while clients observe the eventual effective state through a notification. This is a simplified rework of PR openai/codex#22509. In particular, it changes the `thread/settings/update` api to return immediately rather than waiting and returning the effective (updated) thread settings. This makes the new api consistent with `turn/start` and greatly reduces the complexity of the implementation relative to the earlier attempt. ## What Changed - Adds experimental `thread/settings/update` with partial-update request fields and an empty acknowledgment response. - Adds experimental `thread/settings/updated`, carrying full effective `ThreadSettings` and scoped by `threadId` to subscribed clients for the affected thread. - Shares durable settings validation with `turn/start`, including `sandboxPolicy` plus `permissions` rejection and `serviceTier: null` clearing. - Emits the same settings notification when `turn/start` overrides change the stored effective thread settings. - Regenerates app-server protocol schema fixtures and updates `app-server/README.md`.
**Stack position:** [1 of 7] ## Summary The first three PRs in this stack are a cleanup pass before the actual thread settings API work. Today, core has several overlapping "user input" ops: `UserInput`, `UserInputWithTurnContext`, and `UserTurn`. They differ mostly in how much next-turn state they carry, which makes the later queued thread settings update harder to reason about and review. This PR starts that cleanup by adding the shared `ThreadSettingsOverrides` payload and allowing `Op::UserInput` to carry it. Existing variants remain in place here, so this layer is mostly a behavior-preserving API shape change plus mechanical constructor updates. ## End State After PR3 By the end of PR3, `Op::UserInput` is the only "user input" core op. It can carry optional thread settings overrides for callers that need to update stored defaults with a turn, while callers without updates use empty settings. `Op::UserInputWithTurnContext` and `Op::UserTurn` are deleted. ## End State After PR5 By the end of PR5, core will have only two ops for this area: - `Op::UserInput` for user-input-bearing submissions. - `Op::ThreadSettings` for settings-only updates. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai#23080) (this PR) 2. [2 of 7] [Remove UserInputWithTurnContext](openai#23081) 3. [3 of 7] [Remove UserTurn](openai#23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai#22508) 6. [6 of 7] [Add app-server thread settings API](openai#22509) 7. [7 of 7] [Sync TUI thread settings](openai#22510)
**Stack position:** [2 of 7] ## Summary This PR removes the overlapping `Op::UserInputWithTurnContext` variant now that `Op::UserInput` can carry thread settings overrides directly. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai#23080) 2. [2 of 7] [Remove UserInputWithTurnContext](openai#23081) (this PR) 3. [3 of 7] [Remove UserTurn](openai#23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai#22508) 6. [6 of 7] [Add app-server thread settings API](openai#22509) 7. [7 of 7] [Sync TUI thread settings](openai#22510)
**Stack position:** [3 of 7] ## Summary This PR finishes the input-op consolidation by moving the remaining `Op::UserTurn` callers onto `Op::UserInput` and deleting `Op::UserTurn`. This touches a lot of files, but it is a low-risk mechanical migration. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai#23080) 2. [2 of 7] [Remove UserInputWithTurnContext](openai#23081) 3. [3 of 7] [Remove UserTurn](openai#23075) (this PR) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai#22508) 6. [6 of 7] [Add app-server thread settings API](openai#22509) 7. [7 of 7] [Sync TUI thread settings](openai#22510)
**Stack position:** [5 of 7] ## Summary This PR adds `Op::ThreadSettings`, a queued settings-only update mechanism for changing stored thread settings without starting a new turn. It also removes the legacy `Op::OverrideTurnContext` in the same layer, so reviewers can see the replacement and deletion together. ## Changes - Add `Op::ThreadSettings` for settings-only queued updates. - Emit `ThreadSettingsApplied` with the effective thread settings snapshot after core applies an update. - Route settings-only updates through the same submission queue as user input. - Migrate remaining `OverrideTurnContext` tests and callers to the queued `Op::ThreadSettings` path. - Delete `Op::OverrideTurnContext` from the core protocol and submission loop. This stack addresses openai#20656 and openai#22090. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai#23080) 2. [2 of 7] [Remove UserInputWithTurnContext](openai#23081) 3. [3 of 7] [Remove UserTurn](openai#23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai#22508) (this PR) 6. [6 of 7] [Add app-server thread settings API](openai#22509) 7. [7 of 7] [Sync TUI thread settings](openai#22510)
## Why App-server clients need a way to update a thread's next-turn settings without starting a turn, adding transcript content, or waiting for turn lifecycle events. This gives settings UI a direct path for durable thread settings while clients observe the eventual effective state through a notification. This is a simplified rework of PR openai#22509. In particular, it changes the `thread/settings/update` api to return immediately rather than waiting and returning the effective (updated) thread settings. This makes the new api consistent with `turn/start` and greatly reduces the complexity of the implementation relative to the earlier attempt. ## What Changed - Adds experimental `thread/settings/update` with partial-update request fields and an empty acknowledgment response. - Adds experimental `thread/settings/updated`, carrying full effective `ThreadSettings` and scoped by `threadId` to subscribed clients for the affected thread. - Shares durable settings validation with `turn/start`, including `sandboxPolicy` plus `permissions` rejection and `serviceTier: null` clearing. - Emits the same settings notification when `turn/start` overrides change the stored effective thread settings. - Regenerates app-server protocol schema fixtures and updates `app-server/README.md`.
**Stack position:** [1 of 7] ## Summary The first three PRs in this stack are a cleanup pass before the actual thread settings API work. Today, core has several overlapping "user input" ops: `UserInput`, `UserInputWithTurnContext`, and `UserTurn`. They differ mostly in how much next-turn state they carry, which makes the later queued thread settings update harder to reason about and review. This PR starts that cleanup by adding the shared `ThreadSettingsOverrides` payload and allowing `Op::UserInput` to carry it. Existing variants remain in place here, so this layer is mostly a behavior-preserving API shape change plus mechanical constructor updates. ## End State After PR3 By the end of PR3, `Op::UserInput` is the only "user input" core op. It can carry optional thread settings overrides for callers that need to update stored defaults with a turn, while callers without updates use empty settings. `Op::UserInputWithTurnContext` and `Op::UserTurn` are deleted. ## End State After PR5 By the end of PR5, core will have only two ops for this area: - `Op::UserInput` for user-input-bearing submissions. - `Op::ThreadSettings` for settings-only updates. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai#23080) (this PR) 2. [2 of 7] [Remove UserInputWithTurnContext](openai#23081) 3. [3 of 7] [Remove UserTurn](openai#23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai#22508) 6. [6 of 7] [Add app-server thread settings API](openai#22509) 7. [7 of 7] [Sync TUI thread settings](openai#22510)
**Stack position:** [2 of 7] ## Summary This PR removes the overlapping `Op::UserInputWithTurnContext` variant now that `Op::UserInput` can carry thread settings overrides directly. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai#23080) 2. [2 of 7] [Remove UserInputWithTurnContext](openai#23081) (this PR) 3. [3 of 7] [Remove UserTurn](openai#23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai#22508) 6. [6 of 7] [Add app-server thread settings API](openai#22509) 7. [7 of 7] [Sync TUI thread settings](openai#22510)
**Stack position:** [3 of 7] ## Summary This PR finishes the input-op consolidation by moving the remaining `Op::UserTurn` callers onto `Op::UserInput` and deleting `Op::UserTurn`. This touches a lot of files, but it is a low-risk mechanical migration. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai#23080) 2. [2 of 7] [Remove UserInputWithTurnContext](openai#23081) 3. [3 of 7] [Remove UserTurn](openai#23075) (this PR) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai#22508) 6. [6 of 7] [Add app-server thread settings API](openai#22509) 7. [7 of 7] [Sync TUI thread settings](openai#22510)
**Stack position:** [5 of 7] ## Summary This PR adds `Op::ThreadSettings`, a queued settings-only update mechanism for changing stored thread settings without starting a new turn. It also removes the legacy `Op::OverrideTurnContext` in the same layer, so reviewers can see the replacement and deletion together. ## Changes - Add `Op::ThreadSettings` for settings-only queued updates. - Emit `ThreadSettingsApplied` with the effective thread settings snapshot after core applies an update. - Route settings-only updates through the same submission queue as user input. - Migrate remaining `OverrideTurnContext` tests and callers to the queued `Op::ThreadSettings` path. - Delete `Op::OverrideTurnContext` from the core protocol and submission loop. This stack addresses openai#20656 and openai#22090. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai#23080) 2. [2 of 7] [Remove UserInputWithTurnContext](openai#23081) 3. [3 of 7] [Remove UserTurn](openai#23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai#22508) (this PR) 6. [6 of 7] [Add app-server thread settings API](openai#22509) 7. [7 of 7] [Sync TUI thread settings](openai#22510)
## Why App-server clients need a way to update a thread's next-turn settings without starting a turn, adding transcript content, or waiting for turn lifecycle events. This gives settings UI a direct path for durable thread settings while clients observe the eventual effective state through a notification. This is a simplified rework of PR openai#22509. In particular, it changes the `thread/settings/update` api to return immediately rather than waiting and returning the effective (updated) thread settings. This makes the new api consistent with `turn/start` and greatly reduces the complexity of the implementation relative to the earlier attempt. ## What Changed - Adds experimental `thread/settings/update` with partial-update request fields and an empty acknowledgment response. - Adds experimental `thread/settings/updated`, carrying full effective `ThreadSettings` and scoped by `threadId` to subscribed clients for the affected thread. - Shares durable settings validation with `turn/start`, including `sandboxPolicy` plus `permissions` rejection and `serviceTier: null` clearing. - Emits the same settings notification when `turn/start` overrides change the stored effective thread settings. - Regenerates app-server protocol schema fixtures and updates `app-server/README.md`.
**Stack position:** [1 of 7] ## Summary The first three PRs in this stack are a cleanup pass before the actual thread settings API work. Today, core has several overlapping "user input" ops: `UserInput`, `UserInputWithTurnContext`, and `UserTurn`. They differ mostly in how much next-turn state they carry, which makes the later queued thread settings update harder to reason about and review. This PR starts that cleanup by adding the shared `ThreadSettingsOverrides` payload and allowing `Op::UserInput` to carry it. Existing variants remain in place here, so this layer is mostly a behavior-preserving API shape change plus mechanical constructor updates. ## End State After PR3 By the end of PR3, `Op::UserInput` is the only "user input" core op. It can carry optional thread settings overrides for callers that need to update stored defaults with a turn, while callers without updates use empty settings. `Op::UserInputWithTurnContext` and `Op::UserTurn` are deleted. ## End State After PR5 By the end of PR5, core will have only two ops for this area: - `Op::UserInput` for user-input-bearing submissions. - `Op::ThreadSettings` for settings-only updates. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai#23080) (this PR) 2. [2 of 7] [Remove UserInputWithTurnContext](openai#23081) 3. [3 of 7] [Remove UserTurn](openai#23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai#22508) 6. [6 of 7] [Add app-server thread settings API](openai#22509) 7. [7 of 7] [Sync TUI thread settings](openai#22510)
**Stack position:** [2 of 7] ## Summary This PR removes the overlapping `Op::UserInputWithTurnContext` variant now that `Op::UserInput` can carry thread settings overrides directly. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai#23080) 2. [2 of 7] [Remove UserInputWithTurnContext](openai#23081) (this PR) 3. [3 of 7] [Remove UserTurn](openai#23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai#22508) 6. [6 of 7] [Add app-server thread settings API](openai#22509) 7. [7 of 7] [Sync TUI thread settings](openai#22510)
**Stack position:** [3 of 7] ## Summary This PR finishes the input-op consolidation by moving the remaining `Op::UserTurn` callers onto `Op::UserInput` and deleting `Op::UserTurn`. This touches a lot of files, but it is a low-risk mechanical migration. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai#23080) 2. [2 of 7] [Remove UserInputWithTurnContext](openai#23081) 3. [3 of 7] [Remove UserTurn](openai#23075) (this PR) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai#22508) 6. [6 of 7] [Add app-server thread settings API](openai#22509) 7. [7 of 7] [Sync TUI thread settings](openai#22510)
**Stack position:** [5 of 7] ## Summary This PR adds `Op::ThreadSettings`, a queued settings-only update mechanism for changing stored thread settings without starting a new turn. It also removes the legacy `Op::OverrideTurnContext` in the same layer, so reviewers can see the replacement and deletion together. ## Changes - Add `Op::ThreadSettings` for settings-only queued updates. - Emit `ThreadSettingsApplied` with the effective thread settings snapshot after core applies an update. - Route settings-only updates through the same submission queue as user input. - Migrate remaining `OverrideTurnContext` tests and callers to the queued `Op::ThreadSettings` path. - Delete `Op::OverrideTurnContext` from the core protocol and submission loop. This stack addresses openai#20656 and openai#22090. ## Stack 1. [1 of 7] [Add thread settings to UserInput](openai#23080) 2. [2 of 7] [Remove UserInputWithTurnContext](openai#23081) 3. [3 of 7] [Remove UserTurn](openai#23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](openai#23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](openai#22508) (this PR) 6. [6 of 7] [Add app-server thread settings API](openai#22509) 7. [7 of 7] [Sync TUI thread settings](openai#22510)
## Why App-server clients need a way to update a thread's next-turn settings without starting a turn, adding transcript content, or waiting for turn lifecycle events. This gives settings UI a direct path for durable thread settings while clients observe the eventual effective state through a notification. This is a simplified rework of PR openai#22509. In particular, it changes the `thread/settings/update` api to return immediately rather than waiting and returning the effective (updated) thread settings. This makes the new api consistent with `turn/start` and greatly reduces the complexity of the implementation relative to the earlier attempt. ## What Changed - Adds experimental `thread/settings/update` with partial-update request fields and an empty acknowledgment response. - Adds experimental `thread/settings/updated`, carrying full effective `ThreadSettings` and scoped by `threadId` to subscribed clients for the affected thread. - Shares durable settings validation with `turn/start`, including `sandboxPolicy` plus `permissions` rejection and `serviceTier: null` clearing. - Emits the same settings notification when `turn/start` overrides change the stored effective thread settings. - Regenerates app-server protocol schema fixtures and updates `app-server/README.md`.
Stack position: [6 of 7]
Summary
Remote app-server clients need a way to update thread settings for future turns without starting a turn, plus a notification so other clients can update their UI. This PR adds that app-server API and broadcast behavior on top of the queued core settings update.
Changes
thread/settings/updateandthread/settings/updated, including generated JSON schema and TypeScript protocol fixtures.Op::ThreadSettingspath and return the full effectiveThreadSettings.turn/startwhen thread settings overrides change stored defaults.This stack addresses #20656 and #22090.
Stack