Commit Graph
59 Commits
Author SHA1 Message Date
Tamir Duberstein 9a4b78579a Move the config schema generator into a dedicated crate (#41915)
## What changed

- Add the `codex-config-schema` workspace and Bazel crate for the
  `codex-write-config-schema` binary.
- Preserve `codex-rs/core/config.schema.json` as the default output location.
- Update `just write-config-schema` to run the new crate and remove the schema
  generator's `clap` dependency and binary target from `codex-core`.

GitOrigin-RevId: 7447f97d6e44d1077b16d2d850f8a8add9117ea6
2026-08-31 21:27:51 +00:00
Tamir Duberstein e45226e771 Use the async stack budget for approval reviews (#41840)
## What changed

- Define the shared 16 MiB thread stack budget in `codex-async-utils`.
- Use it for both the async main/runtime threads and the dedicated approval-review thread.

GitOrigin-RevId: c825669e1545bcfaeaaaa07066dc63874f46630f
2026-08-31 13:44:12 +00:00
Tamir Duberstein da23e131e6 Repair cursor-style rendering on older JediTerm terminals (#41673)
## Why

Older JediTerm versions can print the space intermediate in `DECSCUSR`,
overwriting the glyph beneath a cursor-style command.

## What changed

- Apply cursor-style commands at a repairable, terminal-owned glyph and redraw
  that glyph with its original style and hyperlink before restoring the requested
  cursor position.
- Omit the style command when the viewport has no safe repair anchor.
- Handle skipped cells, wide glyphs, and single-column viewports without
  corrupting content or causing scrolling.

## Testing

Add cursor rendering tests for styled and cursor-only frames, skipped and wide
hyperlinked glyphs, single-column viewports, and viewports without owned cells.

GitOrigin-RevId: c8bbb74c53737b5980c533859af39da26f0e06cc
2026-08-30 13:42:42 +00:00
Tamir Duberstein 6478a751fd Organize bundled Rust resources under asset directories (#41477)
## Why

The `core` and `tui` Bazel targets treated nearly their entire crate trees as
compile-time data, mixing embedded runtime resources with source files and test
fixtures.

## What changed

- Move embedded resources for `core` and `tui` into dedicated `assets/`
  directories and update their `include_str!` paths.
- Restrict Bazel compile data to explicit asset and frame directories.
- Move test-only prompts into `tests/fixtures`, resolve the core prompt through
  `find_resource!`, and reuse the integration-test file glob when assembling
  Bazel test data.

GitOrigin-RevId: eee9b0e41df77ea2604215a7f7333a6fe8317bfa
2026-08-29 06:05:28 +00:00
Tamir Duberstein 9a0d7a7cd0 Use rules_rs platforms for release binaries (#41476)
## What changed

- Map each supported release platform name to its Rust target triple.
- Build multiplatform release binaries against the corresponding `rules_rs`
  platform instead of the LLVM platform definitions.
- Document that `multiplatform_binaries` accepts a subset of the declared
  release platforms.

GitOrigin-RevId: 55e2fb0f92e5fa9e608c10380b1c5d893ca83895
2026-08-29 05:51:26 +00:00
Tamir Duberstein 8aea62b2d8 Harden core test fixture startup assertions (#41194)
## Why

Test fixture setup can take more than five seconds on loaded CI workers, and
failures returned from setup can be obscured when downstream mocks verify their
expectations during teardown.

## What changed

- Add a shared `expect_startup` helper with a 30-second timeout that panics on
  either timeout or setup failure before mock teardown runs.
- Use the helper for remote-environment and unified-exec fixture setup, and
  allow the same startup window for the initial exec-server requests.

## Testing

Add paused-time tests covering successful startup after five seconds, timeout
reporting, and propagation of setup errors in the presence of unmet mocks.

GitOrigin-RevId: 39db69bde2983acd023a1911a6fad106674e169a
2026-08-27 19:58:09 +00:00
Tamir Duberstein a95391160a Drive TUI stream animation from the foreground loop (#40644)
## Why

Stream animation ticks generated on a background thread can accumulate while the
TUI is busy, causing stale ticks to run after the animation stops or the chat
widget is replaced.

## What changed

- Replace the animation thread and `CommitTick` app event with a Tokio interval
  owned by the foreground event loop.
- Delay missed ticks instead of replaying a burst, and let pending app events run
  before animation work.
- Drop the interval when animation stops or the chat widget is replaced, while
  preserving `CommitTick` session-log entries.

## Testing

Add a paused-time test covering stable pacing, missed ticks, restart behavior,
and chat-widget replacement.

GitOrigin-RevId: d0561d3f8962b5e05a728463e76aa8ec83cd5a31
2026-08-25 17:17:01 +00:00
Tamir Duberstein 20c3f9733f Restart pending MCP connections when startup timeout changes (#40636)
## Why

Reusing an MCP connection that is still starting after its
`startup_timeout_sec` changes leaves the old startup budget in effect.

## What changed

- Track the effective startup timeout on each MCP connection.
- Reuse a pending startup only when its timeout still matches the current
  configuration.
- Continue reusing ready connections when only the startup timeout changes.

## Testing

Added integration coverage that refreshes the timeout while one server is
still initializing and another is ready, verifying that only the pending
startup is replaced.

GitOrigin-RevId: 5ed71a57d3bf0dd6e227aacd16acd3a35bc37ecf
2026-08-25 16:20:38 +00:00
Tamir Duberstein f5853cbe90 Reconnect MCP servers when authentication mode changes (#40634)
## What changed

- Include the configured authentication mode in the MCP connection identity so
  runtime reconciliation replaces connections instead of reusing them after an
  authentication-mode change.
- Add a regression test covering a switch from OAuth to ChatGPT authentication
  for an executor-owned MCP server.

GitOrigin-RevId: 18cd9df62a9a5ee44594dcde6a844ad7d5e67ee2
2026-08-25 16:14:26 +00:00
Tamir Duberstein c395364915 Keep the active goal clock current in the TUI (#40622)
## Why

The active goal's elapsed-time label could become stale while the TUI was idle because it was refreshed only as part of a redraw.

## What changed

- Refresh the goal status indicator when the terminal-title timer fires.
- Request a redraw only when the displayed elapsed-time label changes.

## Testing

- Add a regression test covering the minute transition and confirming that an unchanged label does not trigger another redraw.

GitOrigin-RevId: f10a1c2334cf7a5f1d2ee90d7138114479998c8d
2026-08-25 14:47:53 +00:00
Tamir Duberstein 6525b95dae Refresh animated terminal titles without redrawing the TUI (#40618)
## Why

Terminal title animations only need to update the title, but each animation tick
previously requested a full TUI frame.

## What changed

- Track the next terminal title refresh deadline on `ChatWidget`.
- Have the foreground event loop refresh the title when that deadline expires.
- Clear the deadline when title animations are disabled or the configured title is
  empty.

## Testing

- Verify spinner and action-required animations set the expected refresh deadlines.
- Verify refreshing an animated title does not enqueue a TUI draw request.

GitOrigin-RevId: 269347cd48de4ad9ba9a0aef9ed105c25d1a7dae
2026-08-25 14:24:18 +00:00
Tamir Duberstein 46aa019e80 Count serialized JSON bytes without allocating strings (#40604)
## Why

History estimation and executed-tool-call limits only need the size of serialized JSON, not the serialized output itself.

## What changed

- Add a shared `serialized_json_bytes` helper that streams JSON into a byte counter.
- Use it for response-item size estimates and executed-tool-call argument limits.
- Preserve serialization errors so callers can apply their existing fallback behavior.

## Testing

- Cover response-item sizing with escaped characters, newlines, and multibyte text.

GitOrigin-RevId: a4417996df96df5c51cae62830adc496912f69c7
2026-08-25 13:10:24 +00:00
Tamir Duberstein c941572917 Honor response budgets when reading skill resources (#40491)
## Why

`skills.read` paginated resources against a fixed response limit, so a page could exceed a smaller tool-call response budget.

## What changed

- Size each serialized `skills.read` page to the current call's response budget, accounting for JSON escaping and UTF-8 boundaries.
- Cache one bounded executor-resource snapshot per thread so cursor continuations return consistent contents without rereading the file. Replace the snapshot when another resource is read, and reject stale cursors after a reread.
- Tie cached executor snapshots to the selected environment and sandbox context without keeping the environment alive.

## Testing

- Cover budget-constrained reads, escaped and multibyte contents, multi-page reconstruction, changed resources, snapshot eviction, and expired turn-scoped access.

GitOrigin-RevId: e515935b82771b3f29b3fb91ea7a7a72e19a65ee
2026-08-24 23:00:57 +00:00
Tamir Duberstein a25e986323 Honor response budgets when listing skills (#40413)
## What changed

- Build `skills.list` pages against the current tool-call response-byte budget.
- Skip entries that cannot fit, preserve pagination across retained entries, and report oversized metadata without repeating the warning for the same budget.
- Keep existing cursors compatible while encoding the response budget in new cursors.

## Testing

- Cover direct and Code Mode listing, budget changes between pages, provider and omission warnings, oversized entries, legacy cursors, and budgets too small to return discovery warnings.

GitOrigin-RevId: 4b34cd2714e4849fe9155ce3f0021b218763c395
2026-08-24 14:54:31 +00:00
Tamir Duberstein e3609f2d02 Expose invocation sources to extension tools (#40382)
## What changed

- Add `ToolCallSource` to extension `ToolCall`s and propagate direct or Code Mode
  invocation metadata, including the runtime cell and nested tool-call IDs.
- Add `ToolCall::response_byte_budget` so extension tools can bound direct-call
  responses by the host truncation policy while allowing Code Mode responses up
  to the tool's own limit.
- Share the skills extension's response-size limit between its `list` and `read`
  tools.

## Testing

- Verify that Code Mode source metadata is preserved when core constructs an
  extension tool call.

GitOrigin-RevId: b10aef01be30d35b67bee3af24a1a4175c9ee112
2026-08-24 11:02:14 +00:00
Tamir Duberstein f6519a355a Preserve TUI event ordering during active-thread draining (#39991)
## Why

Draining every queued active-thread event in one foreground pass can overrun the
frame budget. Buffered thread events can also race ahead of queued replay and
startup app events, causing the TUI to switch views before the corresponding
history and operations have been applied.

## What changed

- Bound active-thread draining to one target frame interval and leave remaining
  notifications queued for a later frame.
- Prioritize queued app events over active-thread events so replay state is
  applied before buffered closures or other thread notifications.
- Block startup input only for pending requests, rather than ordinary queued
  notifications whose draining yielded at the frame deadline.
- Leave selected side-thread closure handling to the foreground event loop.

## Testing

Added tests covering deadline-limited notification draining and foreground
handling of a selected side thread closing.

GitOrigin-RevId: 41080d3df13ca308eec1ea0fbb0ba067a4640c4c
2026-08-21 18:43:37 +00:00
Tamir Duberstein 748d8ac834 Bound unified exec output delta frames (#39937)
## What changed

- Cap each `ExecCommandOutputDelta` frame at 8 KiB and stop building frames once the per-call delta quota is exhausted.
- Preserve complete UTF-8 scalars across producer chunks while passing malformed or incomplete trailing bytes through without losing them.
- Append all process output to the transcript independently of delta emission.

## Testing

- Cover split multibyte characters, malformed and trailing bytes, frame and event limits, transcript preservation, and interactive PTY output.

GitOrigin-RevId: ef4100e353df01569a8fbae650c70f439920a2fd
2026-08-21 14:04:33 +00:00
Tamir Duberstein 4a942885c8 Reduce unified exec output buffer allocations (#39712)
## What changed

- Accept borrowed byte slices when appending output chunks, avoiding clones before
  forwarding those chunks to streaming consumers.
- Merge drained head-tail buffers by reusing their owned storage while preserving
  the retained prefix, latest suffix, and omitted-byte count.
- Make unified exec output handles capacity-generic so bounded-output tests can
  exercise repeated drains with small buffers.

## Testing

- Update head-tail buffer and process manager tests to cover chunk retention,
  omission accounting, and repeated output drains with the new APIs.

GitOrigin-RevId: caa9813d3c9d9921cff28888263a212def381640
2026-08-20 13:17:20 +00:00
Tamir Duberstein 59f7da58d6 Log TUI app event variants without their payloads (#39709)
## Why

The TUI session logger is meant to record only the variant for unhandled app
events. Parsing `Debug` output removed tuple payloads but retained fields from
struct variants.

## What changed

Derive `IntoStaticStr` for `AppEvent` and use that conversion when recording
fallback `app_event` entries, so the `variant` field consistently contains only
the enum variant name.

GitOrigin-RevId: 5b539f414269c6b001e69cf9496db5b49aceb759
2026-08-20 12:17:44 +00:00
Tamir Duberstein 18937b2265 Use mem::take to drain unified exec output buffers (#39515)
## What changed

Replace the custom `HeadTailBuffer::drain` helper with `std::mem::take` at
the output collection call site. This moves the buffered output out while
resetting the shared buffer to its default empty state.

GitOrigin-RevId: 7a93d1312f2cea0d7913a5264eeb01726b45e0ea
2026-08-19 16:30:10 +00:00
Tamir Duberstein db675cc005 Use stored item types when materializing turn summaries (#39514)
## What changed

- Select user and agent summary items using the materialized `item_type` column.
- Fall back to the type in `item_json` when `item_type` is empty so rows written by older clients still produce the correct summary.

## Testing

- Extend the summary materialization test to cover items inserted without a stored item type.

GitOrigin-RevId: 45ca1107900e9b8d46561cea210a27ecd661cedc
2026-08-19 16:20:21 +00:00
Tamir Duberstein fcdf2b5014 Make head-tail buffer capacity const generic (#39493)
## What changed

- Parameterize `HeadTailBuffer` by a const `MAX_BYTES` value and derive its
  head and tail budgets from that value.
- Keep `UNIFIED_EXEC_OUTPUT_MAX_BYTES` as the default capacity for production
  call sites.
- Update focused buffer tests to select their smaller capacities through the
  type parameter.

GitOrigin-RevId: 106e81a2c2db935f7f77a4f301ef591017958287
2026-08-19 14:49:58 +00:00
Tamir Duberstein 3006151ad4 Simplify unified exec output snapshots (#39259)
## What changed

- Return retained unified-exec output as one contiguous byte buffer.
- Use the buffer directly for sandbox-denial checks, removing intermediate
  chunk aggregation and an unnecessary owned string conversion.
- Update the output-retention test to assert the flattened snapshot.

GitOrigin-RevId: 84eacee0166b86d3cb2d6a37e96125977fad0267
2026-08-18 18:46:44 +00:00
Tamir Duberstein 050aa077b5 Avoid redundant terminal size queries during history insertion (#39100)
## What changed

- Pass the screen size already available to TUI draw and history-tail paths into history insertion.
- Use the terminal's cached screen size for direct history insertion calls instead of querying the backend again.
- Extend the terminal size-query regression test to cover history insertion.

GitOrigin-RevId: 44c7a0f0bc5bc365d8d0c72d7e26587ed17a4821
2026-08-17 22:58:25 +00:00
Tamir Duberstein 9c099e94a2 Bound TUI thread replay buffers by delta size (#39081)
## Why

The per-thread replay buffer limited its event count, but streamed agent-message
deltas could still retain an unbounded amount of text while a thread was
inactive.

## What changed

- Coalesce adjacent deltas for the same thread, turn, and item into chunks of up
  to 4 KiB.
- Limit buffered agent-message deltas to 256 KiB, discard a single delta larger
  than that limit, and evict the oldest events when either buffer limit is
  exceeded.
- Keep pending input and approval state in sync when eviction removes the
  corresponding request, including clearing side-thread status indicators.

## Testing

Added coverage for delta coalescing, byte-based eviction, oversized deltas,
replaying only retained text, and side-thread status updates after eviction.

GitOrigin-RevId: 88d85353a124467d467822d2fd9854312b68d547
2026-08-17 21:03:06 +00:00
Tamir Duberstein 37efa18be2 Avoid redundant terminal row clears (#39075)
## Why

The custom TUI buffer diff emitted `ClearToEnd` for unchanged trailing blank
regions, producing unnecessary terminal output.

## What changed

- Clear a row tail only when its cached contents changed or a wide glyph overlaps
  the clear boundary.
- Keep blank cells marked `AlwaysUpdate` in the drawable region so viewport
  invalidation still forces them to repaint.
- Preserve Ratatui's native cell diff behavior for the remaining updates.

## Testing

Add coverage for unchanged row tails, forced blank-cell updates, and shrinking
wide graphemes, including half-width katakana with combining marks.

GitOrigin-RevId: a9cac06f5624032a2b8c80a66c651cf3e85ec7fb
2026-08-17 20:43:12 +00:00
Tamir Duberstein 796325f1e5 Rate-limit TUI frames from their actual emission time (#39057)
## Why

Recording a late frame's requested deadline as its emission time can leave the
rate limiter with a stale timestamp, allowing the next frame to be emitted
immediately in a redraw burst.

## What changed

Record the current time when the frame scheduler sends a draw notification so
the 120 FPS limit is measured from the actual emission.

## Testing

Add a paused-time regression test that submits an overdue draw and verifies the
next frame waits for `MIN_FRAME_INTERVAL`.

GitOrigin-RevId: 8c9a5ac0bf858b2ad87838f6d7c67c9470fdfc61
2026-08-17 19:34:05 +00:00
Tamir Duberstein 5c6f498b0e Stop generating accepted-line fingerprints (#38473)
## What changed

- Replace accepted-line fingerprint generation with diff-based added and deleted line counts.
- Keep `line_fingerprints` in the analytics payload as a statically empty field for schema compatibility.
- Remove the fingerprint types and public parsing API that are no longer used.

## Testing

- Update diff parsing tests to cover accepted-line counts without generating fingerprints.

GitOrigin-RevId: 4247c76c7b56b1a323f70f960823937352b84f7b
2026-08-14 01:44:33 +00:00
Tamir Duberstein 6851fae57c Refresh tracing interest in the token estimate test (#38400)
## What changed

Rebuild the tracing callsite interest cache after installing the test-local
subscriber so the `event_enabled!` assertion uses that subscriber's filters.

GitOrigin-RevId: d221dca4d7e7cb2ddd492a46f7a9d5c977088593
2026-08-13 16:08:34 +00:00
Tamir Duberstein 2bd8727a0c Preserve floating-point values when decoding rollout lines (#38399)
## Why

Serde's generic buffering for flattened and internally tagged fields is incompatible with `serde_json`'s `arbitrary_precision` representation. As a result, persisted rollout items containing nested floating-point values can fail to decode.

## What changed

- Decode the rollout envelope at the JSON persistence boundary before deserializing the item payload.
- Use the shared decoder for both session resume and thread-history projection.
- Cover token-count floats, response-item metadata, field ordering, and ignored metadata in the decoder compatibility test.

GitOrigin-RevId: 59c7f6fbcf83162b5ed6980a69381fe45fc20a0a
2026-08-13 16:03:20 +00:00
Tamir Duberstein 6fc6b9d6d2 Prevent unread events from blocking in-process requests (#38381)
## Why

Awaiting a bounded consumer event queue can stall the in-process app-server
worker when notifications are not being drained, preventing it from delivering
a request response queued behind them.

## What changed

- Use an unbounded queue for caller-facing in-process events while keeping
  command and embedded-runtime queues bounded.
- Preserve all events in order instead of dropping best-effort events and
  emitting lag markers when the consumer queue fills.
- Document that callers can await requests without concurrently draining
  notifications.

## Testing

Add a regression test that fills a capacity-one client with unread settings
notifications, verifies subsequent requests complete, and then confirms the
notifications remain readable in order.

GitOrigin-RevId: 6ca6cfb9349dfa04a613236836f813c1f799783e
2026-08-13 13:57:25 +00:00
Tamir Duberstein 4b07886d59 Represent persisted world state as JSON objects (#38274)
## Why

World-state snapshots and merge patches are keyed collections of sections. Allowing
their persisted `state` field to contain any JSON value required replay code to
handle shapes that cannot represent world state.

## What changed

- Type `WorldStateItem.state` and snapshot patches as JSON object maps.
- Reconstruct full snapshots directly from those maps and apply patches without
  fallible arbitrary-value conversions.
- Regenerate the app-server protocol schema for the object-only representation.

GitOrigin-RevId: 3d7662b74f3dd1f3ccc5fdd0200074c13a73cbe5
2026-08-12 23:56:45 +00:00
Tamir Duberstein 91d6f48992 Avoid allocations when sanitizing TUI user text (#38214)
## Why

Sanitizing user messages and pasted text always allocated a new string, even
when the input contained no terminal control characters.

## What changed

- Return a `Cow<str>` from `sanitize_user_text` so clean borrowed input remains
  borrowed.
- Reuse owned input buffers when sanitization leaves the text intact or only
  removes content at the edges.
- Update transcript rendering, history cells, and paste handling to consume the
  borrowed-or-owned result without unnecessary cloning.

## Testing

Add sanitizer coverage for clean text, control sequences, Unicode control
characters, incomplete escape sequences, buffer reuse, and multi-fragment
output.

GitOrigin-RevId: 9e39cbc0d83c5791941b37a7eb4bb918c1a05f68
2026-08-12 16:33:32 +00:00
Tamir Duberstein 16fbfe5574 Notify running turn watchers only on count changes (#38170)
## What changed

- Publish the running-turn count while holding the thread state lock so updates
  remain ordered with their corresponding state mutations.
- Use `watch::Sender::send_if_modified` to avoid waking subscribers when a
  thread status update leaves the count unchanged.

## Testing

- Add a test that verifies turn start and shutdown notify the count watcher,
  while a permission request during the turn does not.

GitOrigin-RevId: 50fe6bcfb2cac7392715263cfdde0f382fe21502
2026-08-12 11:07:46 +00:00
Tamir Duberstein 3fe19fcd81 Resolve subagent analytics connections lazily (#38165)
## Why

Subagent-start facts can arrive before their parent's connection context is
recorded, leaving later analytics events without client metadata.

## What changed

- Resolve a thread's connection by walking its parent-thread chain when the
  connection was not captured directly.
- Use the resolved connection for subagent setup, tool-call analytics, and
  completed turn events.

## Testing

Extend the subagent analytics test to start the child before the parent context
arrives and verify both command-execution and dynamic-tool-call events.

GitOrigin-RevId: c4d74a22de34abd6c6c5df1717a49ae0e1a9445d
2026-08-12 10:24:34 +00:00
Tamir Duberstein f317dc8a17 Reduce cloning in world-state patch handling (#38078)
## What changed

- Deserialize typed section snapshots directly from borrowed JSON values.
- Build and apply world-state merge patches in place instead of cloning and converting entire snapshots.
- Preserve the existing snapshot when a top-level patch has an invalid shape.

## Testing

- Extend the world-state merge-patch test to cover invalid top-level patches and verify that they leave the snapshot unchanged.

GitOrigin-RevId: 6c2212587b025a8dc3878008a0466d4526eee204
2026-08-11 21:28:35 +00:00
Tamir Duberstein 33aaf91366 Respect rendered width when adding TUI history (#38075)
## What changed

- Initialize new chat widgets with the current terminal width.
- Determine whether an added history cell is visible using the active history
  render mode and the width available after ambient-pet reservations.
- Saturate diff-summary width calculations so extremely narrow terminals remain
  renderable.

## Testing

- Cover width-sensitive history insertion with an ambient pet, raw-output mode,
  and a diff summary narrower than its indentation.

GitOrigin-RevId: 82d20900e0637431be7646b4f4aba61810ff74c1
2026-08-11 21:12:23 +00:00
Tamir Duberstein dad1db87bb Limit TUI streaming traces in SQLite logs (#38036)
## Why

Per-chunk streaming traces can flood the bounded SQLite log queue.

## What changed

- Persist `codex_tui::streaming::controller` and
  `codex_tui::streaming::table_holdback` events at `DEBUG` and above.
- Keep `TRACE` events enabled for other TUI streaming targets.

## Testing

Extended the SQLite log filter test to cover dropped streaming traces, retained
debug diagnostics, and unaffected streaming targets.

GitOrigin-RevId: e7eb999a0770eba6cce5f389005896e64928f02b
2026-08-11 17:07:24 +00:00
Tamir Duberstein e20616d265 Propagate MCP elicitation event delivery failures (#38035)
## Why

When the event receiver is closed, an MCP elicitation request cannot reach its
consumer. Ignoring that delivery failure leaves the request and its lifecycle
registration pending while waiting for a response that cannot arrive.

## What changed

Return a contextual error when an MCP elicitation event cannot be delivered.
This drops the pending-request guard immediately, removing the responder from
the router and releasing its lifecycle registration.

## Testing

Add a regression test that closes the event channel and verifies the request
fails immediately, the router is empty, and the lifecycle registration is
released.

GitOrigin-RevId: 1067f35a5775d61c5bcd07b4b190d3907d8f219a
2026-08-11 16:31:30 +00:00
Tamir Duberstein ed390a5dc4 Filter live rollout items in place (#38034)
## What changed

Retain persistable items directly in the owned append buffer instead of cloning
them into a second vector. Preserve the existing history-mode filtering and
empty-append behavior.

GitOrigin-RevId: 5300312545492bef28f63521427048a27d46a9d1
2026-08-11 16:27:58 +00:00
Tamir Duberstein 4496ba3fd5 Use session metadata to validate thread history paths (#38033)
## What changed

Validate a SQLite thread's rollout path by reading its `SessionMetaLine` and
comparing the recorded thread ID directly. This avoids constructing a
`StoredThread` solely to decide whether the path can supply the requested
history.

GitOrigin-RevId: 8eb1e329514cefc056e44ab4a76d58ff50314a97
2026-08-11 16:20:12 +00:00
Tamir Duberstein 9a6668f674 Report direct input capability for listed subagents (#35944)
## What changed

- Enrich `thread/list` and `thread/search` results for loaded spawned threads with live status and `canAcceptDirectInput`.
- Report `true` for V1 agents that accept direct input and `false` for parent-owned V2 agents, while leaving the capability `null` when it is unavailable or inapplicable.
- Distinguish untracked threads from threads known to have shut down when resolving loaded status.

## Testing

- Cover list, search, ancestor-filtered list, and rejected V2 direct-input behavior.

GitOrigin-RevId: d5faf2fc379a236661ff9167391541473ce5c1eb
2026-07-29 12:13:14 +00:00
Tamir Duberstein e597169e9a Keep agent registry identities consistent (#35744)
## Why

An agent can be registered again with restored path metadata after a root thread
resumes. Leaving its previous registry entry behind can make later lookup and
release operations act on stale metadata.

## What changed

- Add a thread-to-path index alongside the agent tree.
- Keep both indexes synchronized when root and spawned agents are registered,
  replaced, moved between paths, or released.
- Preserve other restored siblings when one agent is closed, while still
  allowing a surviving sibling to be reloaded for follow-up work.

## Testing

Add registry coverage for replacement, release, and path migration, plus resume
tests with multiple sibling agents.

GitOrigin-RevId: 1c1acf422884a6842d9bbdf89ba993d98187770d
2026-07-28 09:41:52 +00:00
Tamir Duberstein 63682c4e1a Include empty-preview threads in relationship listings (#35691)
## What changed

- Include threads without preview text when listing direct children or descendants from the persisted spawn graph.
- Continue filtering those threads out of the global thread list.

## Testing

- Extend the relationship pagination test to cover an empty-preview child in direct-child and descendant results.

GitOrigin-RevId: c2e7bb04c5f64558a48b1d7877bd24edaa364bb4
2026-07-28 00:24:52 +00:00
Tamir Duberstein 0896bf6fc0 Skip inactive TUI threads without pending user interaction (#35525)
## What changed

Only collect buffered requests from inactive threads whose event store reports
pending user input or approval. This keeps unrelated requests from being
considered when pending interactions are surfaced after leaving a side
conversation.

## Testing

Extend the side-conversation routing test with an unrelated dynamic tool request
and verify that only the pending subagent approval is selected.

GitOrigin-RevId: 388968277bde34bedc43187c1d1746d76166131e
2026-07-26 22:19:45 +00:00
Tamir Duberstein 17586d80ee [codex] package Windows ARM64 on x64 (#28001)
The first release after parallelizing Windows packaging moved the
critical path to the ARM64 packaging job:

https://github.com/openai/codex/actions/runs/27451157324

The x64 job started immediately and finished in 5m29s. The ARM64
job waited 76s for its runner and then took 5m56s, holding the
release for 1m43s after x64 had finished.

Packaging only downloads, signs, archives, and compresses already
built binaries. It does not execute target code. Run both packaging
jobs on x64 runners, keeping ARM64 hardware for compilation.
2026-06-13 12:55:53 -07:00
Tamir Duberstein 1460b509f4 [codex] stage npm packages concurrently (#27853)
In the release job from

https://github.com/openai/codex/actions/runs/27391514823

staging the nine npm release tarballs serially took 104 seconds.

Each package build writes to a separate staging directory, output path,
and npm cache. Run them through the script's existing thread pool,
bounded by the available CPU count. Delete each staging tree as its
build finishes so concurrency does not retain all copies until the end.

On ubuntu-24.04 in

https://github.com/openai/codex/actions/runs/27397232050

two serial trials took 103 and 101 seconds, while concurrent trials
both took 41 seconds. Comparing every extracted file from the first
serial and concurrent sets found no differences. This removes about one
minute from every release.
2026-06-13 00:01:14 +00:00
Tamir Duberstein 51483bb583 [codex] parallelize Windows package archives (#27854)
In the Windows x64 packaging job from

https://github.com/openai/codex/actions/runs/27391514823

building the primary and app-server package archives serially took 116
seconds.

Both archives read the same signed-binary directory but write separate
package trees and output files. Run them concurrently with xargs -P2.

The package helper rewrites DotSlash executables under the process temp
directory. A naive concurrent run failed when one process tried to
replace an executable used by the other. Give each bundle separate TMP
and TEMP roots to keep those caches independent.

On Windows x64 in

https://github.com/openai/codex/actions/runs/27397197944

three serial trials took 127, 128, and 126 seconds. Concurrent trials
took 76, 74, and 74 seconds, saving 52 to 54 seconds. This removes about
50 seconds from the release critical path without changing the packaging
commands or output set.
2026-06-13 00:00:15 +00:00
Tamir Duberstein eb46984aaa [codex] package Windows symbols in parallel (#27856)
In the x64 packaging job from

https://github.com/openai/codex/actions/runs/27391514823

archiving and uploading PDBs took 65 seconds after signing. Release
packaging could not start until that work completed.

Windows code signing changes executables but not their PDBs. Package
the PDBs in a sibling Ubuntu job as soon as all binary artifacts are
available. Signing and release packaging can then proceed without
waiting for the symbols archive, reducing the critical path by about
one minute.
2026-06-12 16:52:23 -07:00
Tamir Duberstein 5c48e31954 [codex] parallelize Windows compression (#27855)
Each Windows packaging job creates three compressed forms of five
binaries in sequence. This takes roughly two minutes and is on the
release critical path.

Use two xargs workers to compress independent binaries concurrently.
The workers only read the raw executables and write per-binary archive
names. The Codex zip can safely read the helper executables while their
own archives are generated.

On a 16-vCPU AMD EPYC 9V74 Windows x64 release runner, alternating
trials against artifacts from release run 27391514823 measured:

  serial:   121 s, 123 s, 121 s
  parallel:  73 s,  73 s,  74 s

This saves 47 to 50 seconds in the x64 packaging lane, reducing the
observed release critical path by about 48 seconds when x64 remains the
limiting lane.

https://github.com/openai/codex/actions/runs/27401905938
2026-06-12 16:26:39 -07:00
Tamir Duberstein e23d4df4ff [codex] parallelize release code generation (#27702)
The release profile still uses one codegen unit, which serializes LLVM
code generation within each crate. That setting was selected alongside
fat LTO for optimization quality and binary size, but releases now use
ThinLTO and code generation dominates the critical-path build.

Use four codegen units. On an Apple M4 Max with 16 cores and 128 GiB
RAM, using rustc 1.96.0, four and eight units took 507.486 and 505.325
seconds respectively. Four therefore keeps the build-time gain while
limiting the stripped `codex` increase to 14.7%, compared with 21.5% at
eight units. The gzip-compressed binary grows 7.8% at four units.

The one-unit build from an empty target directory took 981.150 seconds.
That comparison also populated dependency and native build caches, so it
is directional rather than controlled. It agrees with the earlier clean
matrix where eight units reduced 671 seconds to 303 seconds:
https://gist.github.com/anp/4b88393a0acd35783d9f42156f3243d5

At the local 48% reduction, the current release's 55m22s critical-path
macOS Cargo step would save about 26 minutes from the 71m28s workflow:
https://github.com/openai/codex/actions/runs/27367405663

The prompt-image medians ranged from 3.9% faster to 0.9% slower. CLI
startup shifted by 1-2 ms while user and system CPU time were unchanged.

This is a draft because the release-latency improvement may not justify
the binary-size increase.
2026-06-11 19:44:36 -07:00
Tamir Duberstein b42bff21bb [codex] revert concurrent npm publishing (#27639)
In https://github.com/openai/codex/actions/runs/27354608310, the
concurrency introduced by

https://github.com/openai/codex/commit/5e50e7e639c9284ceac24a5498b73a5602fb6615
caused the npm publish job to fail.

The six platform tarballs contain different versions of the same
`@openai/codex` package. Every publish updates the same packument, so
only two concurrent updates succeeded while four failed with HTTP 409.

Serializing that group would leave only the responses API proxy running
in parallel. Saving one publish does not justify the nested `xargs`
machinery needed to express those groups.

Restore the serial publish loop and document why the platform variants
must not publish concurrently. Platform packages remain ahead of the
root CLI wrapper, and the SDK remains after its exact root dependency.
2026-06-11 18:04:24 +00:00
Tamir Duberstein f42780109c [codex] download only release artifacts (#27529)
In https://github.com/openai/codex/actions/runs/27308011621, the
release job downloaded 10.0 GiB of workflow artifacts in 87 seconds,
then discarded 42 artifacts accounting for 3.3 GiB.

Select target and supplemental release artifact patterns at download
time. This also excludes duplicate Cargo timing files without a cleanup
pass and should reduce total release time by about 30 seconds.
2026-06-11 10:34:41 -04:00
Tamir Duberstein 9163c0a335 [codex] publish DotSlash alongside npm (#27528)
In https://github.com/openai/codex/actions/runs/27308011621,
preparing and publishing the three DotSlash configurations took 72
seconds after creating the GitHub release. npm publication could not
start until those independent steps finished.

Move DotSlash publication to a sibling job that starts after the GitHub
release. npm and DotSlash can then proceed concurrently, reducing total
release time by about one minute.
2026-06-11 10:23:46 -04:00
Tamir Duberstein 5e50e7e639 [codex] publish npm packages concurrently (#27527)
In https://github.com/openai/codex/actions/runs/27308011621,
publishing the npm tarballs serially took 147 seconds. Six platform
packages and the responses API proxy are independent.

Publish those packages concurrently, then publish the root CLI wrapper
and SDK in dependency order. Individual platform publishes took 19 to
23 seconds, so this should reduce total release time by nearly two
minutes.
2026-06-11 07:19:27 -07:00
Tamir Duberstein 387adc6c4b [codex] reuse release artifacts for npm staging (#27312)
The release job already downloads every workflow artifact into `dist`,
but npm staging creates a new cache and downloads the six target
artifacts again.

Reuse `dist` as the staging script's artifact cache while preserving the
existing download fallback for missing artifacts and standalone callers.
The script retains ownership of temporary caches but does not delete a
caller-provided directory.

In https://github.com/openai/codex/actions/runs/27242495616, the
duplicate
download transferred 3.3 GiB and took 4 minutes 13 seconds. This should
reduce total release time by about 4 minutes.
2026-06-10 13:15:43 -07:00
Tamir Duberstein 24aee3eb5e [codex] link Windows releases with LLD (#27315)
Windows x64 release builds spend about 36.5 of 48 minutes in final
LLVM code generation and MSVC linking. Use the existing target-aware
MSVC
setup action to select LLD for release builds; the Windows ARM64 archive
path already exercises the action and its LLD wrapper.

In https://github.com/openai/codex/actions/runs/27242495616, macOS
becomes
the critical path after roughly four minutes of Windows improvement, so
this is expected to reduce total workflow time by about four minutes.
2026-06-10 09:18:19 -07:00
Tamir DubersteinandChris Bookholt dffc4bf75d [codex] preserve fsmonitor for worktree Git reads (#26880)
Codex forces `core.fsmonitor=false` on internal Git commands so a
repository cannot select an executable fsmonitor helper. This also
disables Git's built-in daemon for `status`, `diff`, and `ls-files`,
turning those worktree reads into full scans in large repositories.

Read the raw effective `core.fsmonitor` value and preserve it only when
Git interprets it as true and advertises built-in daemon support through
`git version --build-options`. Query uncommon boolean spellings back
through Git using the exact effective value. Unset, false, helper paths,
malformed values, probe failures, and unsupported Git builds continue to
force `core.fsmonitor=false`.

Centralize this policy in `git-utils` while keeping process execution in
the existing local and workspace-command adapters. Probe once per
worktree workflow and reuse the result for its Git commands, including
the TUI `/diff` path. Metadata-only commands and repository discovery
remain disabled without probing. Each probe and requested Git process
keeps its own existing timeout, and the decision is not cached because
layered and conditional Git configuration can change while Codex runs.

---------

Co-authored-by: Chris Bookholt <bookholt@openai.com>
2026-06-08 21:32:46 -07:00
Tamir Duberstein 27f169bb91 cloud-tasks: use workspace deps
This seems to be the way. It made life easier when I was locally forking
clap.
2025-10-07 08:19:10 -07:00