mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Add Windows unified exec yield floor (#27086)
## Why The Windows `unified_exec` experiment regressed at the turn level in a way that points to premature backgrounding / extra command cycles rather than individual responses getting heavier: - `codex_local_tool_calls_per_turn` was up about 20.7%. - `codex_local_blended_tokens_per_turn` was up about 4.1%, and `codex_local_output_tokens_per_turn` was up about 4.0%. - `codex_local_response_latency_per_turn` was up about 8.3%. - The primary activity metrics also moved down: `codex_turns` about -6.6%, `codex_dau` about -1.0%, and `codex_local_hourly_active_users` about -3.0%. At the same time, the per-response metrics moved in the other direction: blended tokens per response, output tokens per response, and latency per response were all lower in test. That suggests the bad turn-level shape is largely about extra tool/model cycles, not each response being slower or more expensive on its own. Local Windows benchmarking showed the likely mechanism: shell-wrapped commands pay a large PowerShell startup/teardown tax before the actual command has much time to run. In the benchmark, the PowerShell wrapper added roughly 0.7-1.0s versus direct exec: - Windows PowerShell: about 740ms p50 / 800ms p90 overhead versus direct exec. - PowerShell 7 (`pwsh`): about 930ms p50 / 980ms p90 overhead versus direct exec. The model commonly asks for a 1s initial yield. On Windows, that can spend nearly the whole window waiting on PowerShell machinery, so otherwise-short commands are more likely to return as background sessions and require follow-up polling/tool calls. This is intentionally a temporary unlock. It gives Windows closer to the same useful post-shell command window as other platforms while we work on reducing the PowerShell tax directly, for example with persistent PowerShell workers or conservative direct-exec paths for commands that do not need shell semantics. ## What changed - Adds a Windows-only 2s floor to `unified_exec`'s initial `yield_time_ms` clamp. - Keeps larger model-requested waits unchanged, including the existing 10s default. - Keeps the existing 30s max clamp. - Leaves non-Windows behavior unchanged. - Adds platform-gated tests for both the Windows floor and the non-Windows clamp behavior. ## Verification - `just test -p codex-core unified_exec`
This commit is contained in:
1 parent
c0b36d234a
commit
e7a9988d1a
2 files changed
+33
No files matched your search
@@ -62,6 +62,7 @@ pub(crate) use process::SpawnLifecycleHandle;
|
||||
pub(crate) use process::UnifiedExecProcess;
|
||||
|
||||
pub(crate) const MIN_YIELD_TIME_MS: u64 = 250;
|
||||
pub(crate) const WINDOWS_INITIAL_EXEC_YIELD_TIME_FLOOR_MS: u64 = 2_000;
|
||||
// Minimum yield time for an empty `write_stdin`.
|
||||
pub(crate) const MIN_EMPTY_YIELD_TIME_MS: u64 = 5_000;
|
||||
pub(crate) const MAX_YIELD_TIME_MS: u64 = 30_000;
|
||||
@@ -165,6 +166,11 @@ struct ProcessEntry {
|
||||
}
|
||||
|
||||
pub(crate) fn clamp_yield_time(yield_time_ms: u64) -> u64 {
|
||||
let yield_time_ms = if cfg!(windows) {
|
||||
yield_time_ms.max(WINDOWS_INITIAL_EXEC_YIELD_TIME_FLOOR_MS)
|
||||
} else {
|
||||
yield_time_ms
|
||||
};
|
||||
yield_time_ms.clamp(MIN_YIELD_TIME_MS, MAX_YIELD_TIME_MS)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user