From b2d65ed584e5a7ed351096d250f2468b52df9fc3 Mon Sep 17 00:00:00 2001 From: harryalbert Date: Wed, 20 May 2026 15:12:39 -0400 Subject: [PATCH 1/2] Add AmbientSetupPhaseEnded variant to OrderedTerminalEventType Adds an explicit shared-session-protocol marker that the sandboxed Oz AgentDriver emits when cloud-mode setup is complete but no initial LLM turn will follow (e.g. empty-prompt local-to-cloud handoff with `--skip-initial-turn`). Viewers consume the event to tear down the Cloud Mode Setup V2 "Running setup commands..." chip and clear `BlockList::is_executing_oz_environment_startup_commands` without waiting for the first `AppendedExchange`. The variant is unit-typed (no associated data) for v1. A future struct upgrade with `task_id: Option` is fine to plan for as a struct variant later but is deliberately out of scope here. Mirrors the placement and idiom of the adjacent `AgentConversationReplayStarted` / `AgentConversationReplayEnded` variants. The session-sharing-server treats `OrderedTerminalEventType` opaquely (only `CommandExecutionFinished` is special-cased for block-id tracking), so no server code changes are required to route or persist the new variant. The server will pick it up via a protocol dep rev bump after this change merges. Includes a serde round-trip test asserting the unit-variant wire form. Stage 2c of empty-prompt local-to-cloud handoff. Co-Authored-By: Oz --- src/common/ordered_terminal_events.rs | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/common/ordered_terminal_events.rs b/src/common/ordered_terminal_events.rs index 7461391..febb2c3 100644 --- a/src/common/ordered_terminal_events.rs +++ b/src/common/ordered_terminal_events.rs @@ -60,6 +60,12 @@ pub enum OrderedTerminalEventType { AgentConversationReplayStarted, /// Marks the end of historical agent conversation replay. AgentConversationReplayEnded, + /// Emitted by the sandboxed Oz AgentDriver when the cloud-mode setup phase is complete but no + /// initial LLM turn will follow (e.g. empty-prompt local-to-cloud handoff with + /// `--skip-initial-turn`). The viewer uses this to tear down the Cloud Mode Setup V2 + /// "Running setup commands…" chip and clear `BlockList::is_executing_oz_environment_startup_commands` + /// without needing to wait for the first `AppendedExchange`. + AmbientSetupPhaseEnded, } /// Represents the size of a PTY. Mimics the winsize struct that @@ -82,6 +88,7 @@ impl std::fmt::Debug for OrderedTerminalEventType { Self::AgentResponseEvent { .. } => f.write_str("AgentResponseEvent"), Self::AgentConversationReplayStarted => f.write_str("AgentConversationReplayStarted"), Self::AgentConversationReplayEnded => f.write_str("AgentConversationReplayEnded"), + Self::AmbientSetupPhaseEnded => f.write_str("AmbientSetupPhaseEnded"), } } } @@ -97,6 +104,7 @@ impl OrderedTerminalEventType { | OrderedTerminalEventType::CommandExecutionFinished { .. } | OrderedTerminalEventType::AgentConversationReplayStarted | OrderedTerminalEventType::AgentConversationReplayEnded + | OrderedTerminalEventType::AmbientSetupPhaseEnded | OrderedTerminalEventType::Resize { .. } => Byte::from_u64(0), } } @@ -114,3 +122,31 @@ impl OrderedTerminalEvent { self.event_type.num_bytes() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn ambient_setup_phase_ended_serializes_as_unit_variant() { + let event_type = OrderedTerminalEventType::AmbientSetupPhaseEnded; + let json = serde_json::to_string(&event_type).expect("serialize"); + assert_eq!(json, "\"AmbientSetupPhaseEnded\""); + } + + #[test] + fn ambient_setup_phase_ended_round_trips() { + let event = OrderedTerminalEvent { + event_no: 42, + event_type: OrderedTerminalEventType::AmbientSetupPhaseEnded, + }; + let json = serde_json::to_string(&event).expect("serialize"); + let parsed: OrderedTerminalEvent = serde_json::from_str(&json).expect("deserialize"); + assert_eq!(parsed.event_no, 42); + assert!(matches!( + parsed.event_type, + OrderedTerminalEventType::AmbientSetupPhaseEnded + )); + assert_eq!(parsed.num_bytes(), Byte::from_u64(0)); + } +} From 0db8bbdda17fda2b7a34ec103b74e84705cd5638 Mon Sep 17 00:00:00 2001 From: harryalbert Date: Fri, 22 May 2026 13:15:52 -0400 Subject: [PATCH 2/2] REMOTE-1499: add doc comment to AmbientSetupPhaseEnded explaining the missing Started half Adjacent variants come in Started/Ended pairs; AmbientSetupPhaseEnded has no matching Started because the setup-phase start is implicit in existing SetupCommandState transitions on the viewer once scrollback arrives. Co-Authored-By: Oz --- src/common/ordered_terminal_events.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common/ordered_terminal_events.rs b/src/common/ordered_terminal_events.rs index febb2c3..6f27c88 100644 --- a/src/common/ordered_terminal_events.rs +++ b/src/common/ordered_terminal_events.rs @@ -65,6 +65,11 @@ pub enum OrderedTerminalEventType { /// `--skip-initial-turn`). The viewer uses this to tear down the Cloud Mode Setup V2 /// "Running setup commands…" chip and clear `BlockList::is_executing_oz_environment_startup_commands` /// without needing to wait for the first `AppendedExchange`. + /// + /// There is no matching `AmbientSetupPhaseStarted` variant: setup-phase start is already + /// implicit in the existing `SetupCommandState` transitions on the viewer (the default + /// `running_group_id` is `Some(initial)` once scrollback arrives), so an explicit start + /// marker would be redundant. AmbientSetupPhaseEnded, }