pub struct ControlState { /* private fields */ }Expand description
The control-ownership state machine. Pure: ControlState::apply is the
only way to change it, and it never touches a clock, a socket, or a lock.
Every event is safe to feed at any time — an event that doesn’t apply to
the current state (HandBack with nothing handed back, a stale
GracePeriodExpired after an on-time hand-back) is a no-op rather than
an error, because these are UI-driven events a real client can double-
fire under an ordinary race without that being a bug.
Implementations§
Source§impl ControlState
impl ControlState
pub fn new() -> Self
pub fn owner(&self) -> ControlOwner
pub fn current_action(&self) -> Option<&str>
pub fn pending_signin(&self) -> Option<&PendingSignIn>
Sourcepub fn user_engaged(&self) -> bool
pub fn user_engaged(&self) -> bool
Is a person demonstrably at this browser right now — holding control, or having driven it since the current sign-in was requested?
The one question the sign-in timeout has to answer. See
ControlState::user_engaged.
Sourcepub fn may_agent_act(&self) -> bool
pub fn may_agent_act(&self) -> bool
The tool-boundary check a browse tool call makes before it runs:
“may the agent act right now?” false whenever the user holds
control (or no agent has attached at all).
This is also what closes the approval race: a browse action
pending at an approval prompt (a separate, pre-existing concern —
see assistant::governance/agent_loop::ApprovalDecision, not
modeled here) must not execute while the user holds control even if
it gets approved mid-race, and must run only after hand-back. That
falls out for free as long as the caller re-checks
may_agent_act() at the moment it is ABOUT TO EXECUTE the approved
action, rather than caching the answer from when approval was
requested or granted — approval and execution are different moments,
and only the second one may be gated on stale information for this
to be correct. See the approval_race_* test below.
Sourcepub fn user_holds_control(&self) -> bool
pub fn user_holds_control(&self) -> bool
Whether the user explicitly holds control right now — owner == User, nothing else.
This is deliberately NOT the same predicate as may_agent_act
(owner == Agent): they only disagree in the NoAgent case, where
may_agent_act is false (correct for the tool-boundary check,
which always runs after the calling tool has already attached) but
user_holds_control is also false (correct for a call site that
needs to gate BEFORE it has attached — e.g. browser_record_start/
browser_record_stop/browser_await_signin, which check this
before ever touching a session, so their very first invocation ever
— NoAgent, nothing to wait for — is never mistaken for the user
holding control). Use may_agent_act when the caller has already
established a session; use this when it hasn’t yet.
Sourcepub fn is_blackout_active(&self) -> bool
pub fn is_blackout_active(&self) -> bool
Whether no screenshot/frame may reach the model right now. true
while the user holds control OR a sign-in is pending — sign-in
implies the same privacy boundary even though it’s the agent’s own
browser_await_signin call, not an explicit Take Control press,
that puts the page in front of the user.
Sourcepub fn apply(&mut self, event: ControlEvent) -> Vec<ControlEffect>
pub fn apply(&mut self, event: ControlEvent) -> Vec<ControlEffect>
Apply one event, mutating in place, and return what the caller (or a caller of its result) should do as a result.
Trait Implementations§
Source§impl Clone for ControlState
impl Clone for ControlState
Source§impl Debug for ControlState
impl Debug for ControlState
Source§impl Default for ControlState
impl Default for ControlState
impl Eq for ControlState
Source§impl PartialEq for ControlState
impl PartialEq for ControlState
impl StructuralPartialEq for ControlState
Auto Trait Implementations§
impl Freeze for ControlState
impl RefUnwindSafe for ControlState
impl Send for ControlState
impl Sync for ControlState
impl Unpin for ControlState
impl UnsafeUnpin for ControlState
impl UnwindSafe for ControlState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more