#7857·omnigent

[Bug] Runner session reads fetch the full page snapshot (items, liveness, and a probe of the runner itself) for a few stored-row fields

Author: dbczumarCreated Sep 20, 2026Updated Sep 20, 2026
LabelsBugcomp:servercomp:runnerP1-hightriagedvalidated:reproduced

Description

The runner reads GET /v1/sessions/{id} on the server for a handful of stored-row fields, and every one of those reads asks for the full page snapshot.

  • The native launch-config read (_fetch_native_launch_snapshot, omnigent/runner/native/orchestration.py) needs workspace, terminal_launch_args, model_override, reasoning_effort, labels, harness_override, external_session_id, and cost_control_mode_override, with a 10 s budget per attempt.
  • The runner's own session lookup (_session_snapshot in omnigent/runner/app.py) needs created_at, workspace, agent_id, agent_name, sub_agent_name, parent_session_id.
  • The model-override re-read at init (_fetch_session_model_override) needs model_override.
  • The Codex host-spawn check and the Antigravity launch path (_session_payload_for_host_spawn_check) need workspace, terminal_launch_args, model_override, external_session_id, labels.

With no query parameters the server builds the full snapshot: the last 100 transcript items, the liveness lookup, model options, usage totals, host resume state, pending prompts, and, on a status-cache miss, a live-status probe of the session's bound runner. That last step is circular for these callers: the runner asks the server about a session it owns, and the server turns around and asks that same runner for its status while the runner is waiting on the answer. Under server load, or when the runner's own event loop is busy, the 10 s launch-config budget expires and codex fails to start with Could not fetch Codex launch config (see #7825 and #7791 for the incident history). The probe is bounded now (#7826), but the read still pays for a page it does not need and still depends on the caller's own responsiveness.

The route already accepts include_items=false and include_liveness=false (the web chat uses both). There is no way to skip the live-status probe, and include_liveness=false cannot absorb it: the web passes that flag and relies on the returned status to reopen an already-running turn on first load, since the SSE stream does not replay the running edge.

Expected behavior

  • GET /v1/sessions/{id} accepts include_live_status=false, which reports status from the server's cached or persisted value without probing the runner. Default true, so no existing caller changes.
  • The runner's own reads pass include_items=false&include_liveness=false&include_live_status=false, so they are a couple of row reads that do not depend on runner health or the transcript size, and no longer compete with the 10 s launch-config budget.
  • Older servers ignore unknown query parameters, so a newer runner against an older server still works.