Skip to content

Commit 66f5d33

Browse files
committed
document and test background responses compatibility
1 parent cc04f16 commit 66f5d33

7 files changed

Lines changed: 68 additions & 3 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ Selected runtime/environment overrides:
199199
| `CODEX_TUI_V2=0/1` | Disable/enable TUI v2 |
200200
| `CODEX_TUI_COLOR_PROFILE=truecolor|ansi256|ansi16` | TUI color profile |
201201
| `CODEX_TUI_GLYPHS=ascii|unicode|auto` | TUI glyph style |
202+
| `CODEX_AUTH_BACKGROUND_RESPONSES=0/1` | Opt in/out of stateful Responses `background: true` compatibility |
202203
| `CODEX_AUTH_FETCH_TIMEOUT_MS=<ms>` | Request timeout override |
203204
| `CODEX_AUTH_STREAM_STALL_TIMEOUT_MS=<ms>` | Stream stall timeout override |
204205

@@ -210,6 +211,8 @@ codex auth check
210211
codex auth forecast --live
211212
```
212213

214+
Responses background mode stays opt-in. Enable `backgroundResponses` in settings or `CODEX_AUTH_BACKGROUND_RESPONSES=1` only for callers that intentionally send `background: true`, because those requests switch from stateless `store=false` routing to stateful `store=true`. See [docs/upgrade.md](docs/upgrade.md) for rollout guidance.
215+
213216
---
214217

215218
## Experimental Settings Highlights

docs/development/CONFIG_FIELDS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ Used only for host plugin mode through the host runtime config file.
8383

8484
`backgroundResponses` is an opt-in compatibility switch for Responses API `background: true` requests. When enabled, those requests become stateful (`store=true`) instead of following the default stateless Codex routing.
8585

86+
Upgrade note:
87+
- Leave this disabled for existing stateless pipelines that do not intentionally send `background: true`.
88+
- Enable it only for callers that need stateful background responses and can accept forced `store=true`, preserved input item IDs, and the loss of stateless-only defaults such as fast-session trimming.
89+
- After enabling it, test one known `background: true` request end to end before rolling it across shared automation.
90+
8691
### Storage / Sync
8792

8893
| Key | Default |

docs/reference/public-api.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,10 @@ Positional signatures are preserved for backward compatibility.
6767

6868
The request-transform layer intentionally preserves and/or normalizes modern Responses API fields that callers may already send through the host SDK.
6969

70-
- `previous_response_id` is preserved when explicitly provided and may be auto-filled from plugin continuation state when `pluginConfig.responseContinuation` is enabled.
70+
- The plugin preserves `previous_response_id` when explicitly provided and may auto-fill it from plugin continuation state when `pluginConfig.responseContinuation` is enabled, maintains `text.format` when verbosity defaults are applied, and honors `prompt_cache_retention` from the request body before falling back to `providerOptions.openai.promptCacheRetention` or user config defaults.
7171
- `background` is typed as a first-class request field. It remains disabled by default and only passes through when `pluginConfig.backgroundResponses` or `CODEX_AUTH_BACKGROUND_RESPONSES=1` explicitly enables the stateful compatibility path.
72-
- `text.format` is preserved when verbosity defaults are applied, so structured-output contracts continue to flow through untouched.
73-
- `prompt_cache_retention` is preserved from the request body and can fall back to `providerOptions.openai.promptCacheRetention` or user config defaults.
7472
- Background-mode requests force `store=true`, keep caller-supplied input item IDs, and skip stateless-only defaults such as `reasoning.encrypted_content` injection and fast-session trimming.
73+
- Upgrade note: leave background mode disabled for existing stateless pipelines. Enable it only for callers that intentionally send `background: true` and are ready for stateful `store=true` routing. For rollout steps, see [../upgrade.md](../upgrade.md).
7574
- Hosted built-in tool definitions are typed and supported for:
7675
- `tool_search`
7776
- remote `mcp`

docs/upgrade.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ For maintainer/debug flows, see advanced/internal controls in [development/CONFI
7676

7777
---
7878

79+
## Responses Background Mode Upgrade Note
80+
81+
`backgroundResponses` and `CODEX_AUTH_BACKGROUND_RESPONSES=1` are opt-in compatibility controls for callers that intentionally send Responses API `background: true`.
82+
83+
- Leave them disabled for existing stateless pipelines. The default routing remains `store=false`.
84+
- Enabling them switches background requests onto the stateful path, forces `store=true`, preserves caller-supplied input item IDs, and skips stateless-only defaults such as fast-session trimming and `reasoning.encrypted_content` injection.
85+
- No new npm scripts or storage migrations are required, but you should validate one known `background: true` request end to end before enabling the flag across shared automation.
86+
87+
---
88+
7989
## Onboarding Restore Note
8090

8191
`codex auth login` now opens directly into the sign-in menu when the active pool is empty, instead of opening the account dashboard first.

test/fetch-helpers.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,30 @@ describe('createEntitlementErrorResponse', () => {
11791179
expect(result?.deferredFastSessionInputTrim).toBeUndefined();
11801180
});
11811181

1182+
it('rethrows store=false background guardrail errors at the fetch layer', async () => {
1183+
const { transformRequestForCodex } = await import('../lib/request/fetch-helpers.js');
1184+
1185+
await expect(
1186+
transformRequestForCodex(
1187+
{
1188+
body: JSON.stringify({
1189+
model: 'gpt-5.4',
1190+
background: true,
1191+
store: false,
1192+
input: [{ type: 'message', role: 'user', content: 'hello' }],
1193+
}),
1194+
},
1195+
'https://example.com',
1196+
{ global: {}, models: {} },
1197+
true,
1198+
undefined,
1199+
{ allowBackgroundResponses: true },
1200+
),
1201+
).rejects.toThrow(
1202+
'Responses background mode requires store=true and cannot be combined with stateless store=false routing.',
1203+
);
1204+
});
1205+
11821206
it('returns undefined when parsedBody is empty object and init body is unavailable', async () => {
11831207
const { transformRequestForCodex } = await import('../lib/request/fetch-helpers.js');
11841208
const result = await transformRequestForCodex(

test/plugin-config.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ describe('Plugin Configuration', () => {
6666
'CODEX_AUTH_FALLBACK_UNSUPPORTED_MODEL',
6767
'CODEX_AUTH_FALLBACK_GPT53_TO_GPT52',
6868
'CODEX_AUTH_RESPONSE_CONTINUATION',
69+
'CODEX_AUTH_BACKGROUND_RESPONSES',
6970
'CODEX_AUTH_PREEMPTIVE_QUOTA_ENABLED',
7071
'CODEX_AUTH_PREEMPTIVE_QUOTA_5H_REMAINING_PCT',
7172
'CODEX_AUTH_PREEMPTIVE_QUOTA_7D_REMAINING_PCT',

test/request-transformer.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2537,6 +2537,29 @@ describe('Request Transformer Module', () => {
25372537
);
25382538
});
25392539

2540+
it('rejects background mode when providerOptions still forces store=false', async () => {
2541+
await expect(
2542+
transformRequestBody(
2543+
{
2544+
model: 'gpt-5.4',
2545+
background: true,
2546+
providerOptions: { openai: { store: false } },
2547+
input: [{ type: 'message', role: 'user', content: 'hello' }],
2548+
},
2549+
codexInstructions,
2550+
{ global: {}, models: {} },
2551+
true,
2552+
false,
2553+
'hybrid',
2554+
30,
2555+
false,
2556+
true,
2557+
),
2558+
).rejects.toThrowError(
2559+
'Responses background mode requires store=true and cannot be combined with stateless store=false routing.',
2560+
);
2561+
});
2562+
25402563
it('throws clear TypeError when named-parameter body is invalid', async () => {
25412564
await expect(
25422565
transformRequestBody({

0 commit comments

Comments
 (0)