Commit Graph

3 Commits

  • Enforce user input length cap (#12823)
    Currently there is no bound on the length of a user message submitted in
    the TUI or through the app server interface. That means users can paste
    many megabytes of text, which can lead to bad performance, hangs, and
    crashes. In extreme cases, it can lead to a [kernel
    panic](https://github.com/openai/codex/issues/12323).
    
    This PR limits the length of a user input to 2**20 (about 1M)
    characters. This value was chosen because it fills the entire context
    window on the latest models, so accepting longer inputs wouldn't make
    sense anyway.
    
    Summary
    - add a shared `MAX_USER_INPUT_TEXT_CHARS` constant in codex-protocol
    and surface it in TUI and app server code
    - block oversized submissions in the TUI submit flow and emit error
    history cells when validation fails
    - reject heavy app-server requests with JSON-RPC `-32602` and structured
    `input_too_large` data, plus document the behavior
    
    Testing
    - ran the IDE extension with this change and verified that when I
    attempt to paste a user message that's several MB long, it correctly
    reports an error instead of crashing or making my computer hot.
  • tests: centralize in-flight turn cleanup helper (#12271)
    ## Why
    
    Several tests intentionally exercise behavior while a turn is still
    active. The cleanup sequence for those tests (`turn/interrupt` + waiting
    for `codex/event/turn_aborted`) was duplicated across files, which made
    the rationale easy to lose and the pattern easy to apply inconsistently.
    
    This change centralizes that cleanup in one place with a single
    explanatory doc comment.
    
    ## What Changed
    
    ### Added shared helper
    
    In `codex-rs/app-server/tests/common/mcp_process.rs`:
    
    - Added `McpProcess::interrupt_turn_and_wait_for_aborted(...)`.
    - Added a doc comment explaining why explicit interrupt + terminal wait
    is required for tests that intentionally leave a turn in-flight.
    
    ### Migrated call sites
    
    Replaced duplicated interrupt/aborted blocks with the helper in:
    
    - `codex-rs/app-server/tests/suite/v2/thread_resume.rs`
      - `thread_resume_rejects_history_when_thread_is_running`
      - `thread_resume_rejects_mismatched_path_when_thread_is_running`
    - `codex-rs/app-server/tests/suite/v2/turn_start_zsh_fork.rs`
      - `turn_start_shell_zsh_fork_executes_command_v2`
    -
    `turn_start_shell_zsh_fork_subcommand_decline_marks_parent_declined_v2`
    - `codex-rs/app-server/tests/suite/v2/turn_steer.rs`
      - `turn_steer_returns_active_turn_id`
    
    ### Existing cleanup retained
    
    In `codex-rs/app-server/tests/suite/v2/turn_start.rs`:
    
    - `turn_start_accepts_local_image_input` continues to explicitly wait
    for `turn/completed` so the turn lifecycle is fully drained before test
    exit.
    
    ## Verification
    
    - `cargo test -p codex-app-server`
  • feat(app-server): turn/steer API (#10821)
    This PR adds a dedicated `turn/steer` API for appending user input to an
    in-flight turn.
    
    ## Motivation
    Currently, steering in the app is implemented by just calling
    `turn/start` while a turn is running. This has some really weird quirks:
    - Client gets back a new `turn.id`, even though streamed
    events/approvals remained tied to the original active turn ID.
    - All the various turn-level override params on `turn/start` do not
    apply to the "steer", and would only apply to the next real turn.
    - There can also be a race condition where the client thinks the turn is
    active but the server has already completed it, so there might be bugs
    if the client has baked in some client-specific behavior thinking it's a
    steer when in fact the server kicked off a new turn. This is
    particularly possible when running a client against a remote app-server.
    
    Having a dedicated `turn/steer` API eliminates all those quirks.
    
    `turn/steer` behavior:
    - Requires an active turn on threadId. Returns a JSON-RPC error if there
    is no active turn.
    - If expectedTurnId is provided, it must match the active turn (more
    useful when connecting to a remote app-server).
    - Does not emit `turn/started`.
    - Does not accept turn overrides (`cwd`, `model`, `sandbox`, etc.) or
    `outputSchema` to accurately reflect that these are not applied when
    steering.