Wire bounded output collection into the code mode runtime (#57850)

## Why

Bounding collected output also requires limiting the raw event backlog between
V8 and the cell actor. Previously, runtime events and cell output accumulated
in an unbounded channel and vector.

## What changed

- Select the event transport and `OutputCollector` from the cell's
  `output_truncation` mode. Server mode uses an ordered, bounded channel with
  backpressure; client mode retains untruncated output.
- Transfer the collector with each observation and restore it on failed
  delivery, preserving retained media and omission metadata.
- Include server-mode script errors in the observation's output budget. Build
  completion output only after completion wins against termination, so a
  rejected error cannot evict output returned by termination.
- Keep the public service on client-side truncation.

## Testing

Add regression coverage for channel backpressure, event ordering, receiver
closure, failed observation delivery, termination during completion commit,
and oversized errors across UTF-8 and omission boundaries.

GitOrigin-RevId: 7604b60416e33c636ca41138be65dc0fd452774a
This commit is contained in:
Sean Huang
2026-10-28 22:33:13 +00:00
committed by copyberry
parent 6d97d6ecb4
commit 92e802fb61
21 changed files with 686 additions and 355 deletions
@@ -16,7 +16,7 @@ use super::super::RuntimeEvent;
use super::super::RuntimeState;
use super::super::ToolCallbackMetadata;
use super::super::globals;
use crate::FunctionCallOutputContentItem;
use crate::session_runtime::OutputItem;
use crate::v8_init::ensure_v8_initialized;
// Deliberately leave JS running: the test must verify host-side admission even
@@ -109,7 +109,7 @@ clearTimeout(earlyTimer); setTimeout(() => {}, 60000);
)
.expect("install globals");
scope.set_slot(RuntimeState {
event_tx,
event_tx: event_tx.into(),
pending_tool_calls: HashMap::new(),
pending_timeouts: HashMap::new(),
stored_values: HashMap::new(),
@@ -152,7 +152,7 @@ const earlyTimer = setTimeout(() => text("early timer"), 60000);
assert!(
matches!(event_rx.try_recv(), Ok(RuntimeEvent::ContentItem(
FunctionCallOutputContentItem::InputText { text }
OutputItem::InputText { text }
)) if text == "before"),
"{label}: pre-exit output"
);