Expand description
Identity, configuration, commands, events and the envelope — the entire
client↔session contract (PLAN-phase2 §2.1–§2.4). Everything a client can
send is serde-able from day one; SessionEventWire::Stream deliberately
is not (it carries the un-serialised StreamEvent in-process).
Modules§
- reasoning_
level_ serde ReasoningLevelhas no serde impls in agent-core; go through its canonical string form.
Structs§
- Addressed
- A command with its origin.
from: None= host-originated (router, lifecycle, idle probe) and bypasses input ownership (B1). - Attach
Snapshot - Client
Capabilities - Opt-in stream signals (see
ClientMeta::capabilities). The daemon’s event enums nested underStream(WireLlmEvent, …) have no#[serde(other)]: an older client fails the whole frame on an unknown variant — and a failed frame reads as a dead socket (the TUI drops into reconnect, whoseAttachedreplay would carry the same variant). So every new nested variant is sent only to a client that declares it here. - Client
Id - Minted by the actor per Attach.
- Client
Info - One attached client as every client sees it (
AttachSnapshot.roster,ClientJoined,/clients,synaps daemon sessions). - Client
Meta - Confirm
Scope - Who raised an extension tool-call Confirm and what “Allow all” would
cover. Built host-side from the hook chain (
HookBus::emitstamps the extension ids; an extension cannot name itself or another extension), so the dialog can show the exact scope BEFORE the user answers. - Continue
Info Wire - Serializable copy of
engine::setup::ContinueInfo. - Conversation
Snapshot - Serializable mirror of
ConversationState(+ the actor’s auto-turn counter). Clients MUST replace, never merge, onConversation(_). - Conversation
Tokens - Envelope
- Per-session, gapless
seqassigned at the single emit site (SessionActor::emit);tsfrom the host clock. - Messages
Hash Memo - Memo of
wire::messages_hash(api_messages)shared by every clone of one snapshot: the daemon converts aConversationto its wire digest once per socket client, and hashing serialises the whole history — now once per event, not once per client. Keyed on the history’s length and last message identity (histories only grow), so a snapshot whose messages are replaced afterwards recomputes instead of reusing a stale hash. - Owned
Config - Daemon-set (
SessionConfig::owned): the session is owned, bound to the connection that presentstoken. - Owner
Bind - Host-side (never wire): an owner claim plus the claiming connection’s
liveness. The connection task holds a drop guard on
alivefor as long as it serves, so the actor learns its owner is gone when the task ends for ANY reason (EOF, error, panic, an attach that timed out after this was queued), even if noDetachever arrives. - Owner
Claim - A connection’s claim to be an owned session’s owner: the token, plus the
secrets it forwards (
None= forward none). - Owner
Token - The capability that binds an owned session to its owner: minted by the
daemon at create, returned only to the creating connection, presented
again to re-bind after a daemon reload.
Debugis redacted. - Prompt
Request - Reasoning
Clamp Wire - Roster
- A client-side copy of the session’s roster, kept current from the
attach snapshot,
ClientJoinedandClientLeft(each transport owns one). - Secret
Env - Secret env vars an OWNED session’s creator forwards (
forward_secrets): exactly the varscapture_client_envstrips as secrets. Held in the daemon’s memory for the session’s lifetime only, applied to its tools’ env and never toSessionConfig, the journal, the reload record or any log.Debugprints names only. - Session
Config - Everything
EngineHost::create_sessionneeds. Serializable: it is the payload of the wireAttach::Create. MirrorsEngineOptsminus the host-level fields (profile, no_extensions), plus the per-session facts a daemon cannot inherit from its own process (cwd, env overlay). - Session
Header Sessionminusapi_messagesand accounting: what a client mirrors.- Session
Id - Conversation session id — the
Session.idstring ({name}-{ts}-{pid}; see events/registry.rs sanitize rules). NOT the tools::activation::SessionId (that is the per-runtime gate identity minted at Runtime::from_parts). - Session
Meta - Session
Reload Record - What
Checkpoint{Reload}reports sodaemon reloadcan rebuild the session as it IS (not as it was created): the actor’s config, keep-warm pin, lifecycle, the non-persisted knobs (settings_replay, incl./system), the CURRENT model/thinking, and its tool activations. - Setting
Applied - ToolEnv
- What a session’s tools spawn with: the session env snapshot, plus (owned
sessions with
forward_secretsonly) the forwarded secrets, kept apart so noDebugof the runtime, the tool capabilities or a worker’s workspace can print them. Merged into a child’s env only at spawn (ToolEnv::spawn_vars).
Enums§
- Attach
Mode - Attach mode. Ownership (B1):
Mirrorowns input iff nobody does,Takeoversteals it,Observenever owns it. - Attach
State - Actor-side client accounting (§8):
Detachednever cancels a stream. - Checkpoint
Reason - Why a
Checkpointwas requested. - Client
Input - Who may drive a daemon session with several clients attached
(
client_input; specmulti-client-sessions.md§6). Every client is the daemon’s own user. - Client
Kind - Compaction
Policy Wire - Serializable mirror of
runtime::compaction::CompactionPolicy. - EndReason
- History
Mode - What a client wants in
Attached/Conversation: the fullapi_messagesmirror (Full, the 741b6b60 behaviour) or only the digest + a daemon-side display tail (Digest, phase 4). - Host
Event - Host-originated events pushed into a session (C3 router, loader).
- Owner
Change Reason - Prompt
Kind - Session
Command - The entire client→session control surface (SEAMS §5.2/§5.3).
- Session
Event Wire - What a session tells its clients.
Streamcarries the un-serialised StreamEvent in-process (LocalTransport) — that IS the byte-identical contract. The socket boundary converts towire::WireSessionEvent. - Session
Lifecycle - Where a session is in its park/unpark life (
SessionHandle::lifecycle). - Session
Query - Session
Setting - The
&mut Runtimesetters the TUI/rpc/server call (SEAMS §5.3). - Turn
Trigger
Constants§
- CLIENT_
NAME_ MAX - Longest client name (
validate_client_name). - CONFIRM_
ACTIVATION_ PROMPT_ TITLE - Fixed title
confirm_activation_with_hostuses for theactivate_toolsy/yes gate (tools/discovery.rs). Everything not in the confirm set isSecret(masked input). - CONFIRM_
PROMPT_ TITLE - Fixed title
resolve_before_tool_call_resultuses for Confirm prompts (runtime/mod.rs). - DEFAULT_
TAIL_ ITEMS - Default for
ClientMeta.tail_items: matches the TUI’s resumed-display cap. - RELOADING_
REFUSAL - What a session tells a client whose command a daemon reload refused.
Traits§
- PinSink
- Where a daemon session writes its pin (
daemon::pins::PinBook). The actor calls it exactly when the pin changes, when a pinned session moves to a new journal or is renamed, and when a pinned session is ended on purpose. Implementations do their own I/O and never fail the caller.
Functions§
- capture_
client_ env - Secret patterns (case-insensitive suffix/infix) stripped at the client.
Secrets never reach the daemon — the broker owns credentials.
Build a
SessionEnvfrom the current process environment, stripping client-only prefixes and secrets. Returns(kept_env, stripped_secret_names). The stripped names are ONLY the secrets (notSYNAPS_*prefixes, those are noise). Used by thin clients beforeHello. - capture_
client_ secrets - The secrets
capture_client_envstrips from this process’s env, with their values: what an owned create withforward_secretssends. - client_
name_ from_ env SYNAPS_CLIENT_NAME, trimmed;Nonewhen unset or empty. Not validated here: the caller reports a bad one.- client_
secret_ env - The pure part of
capture_client_secrets: the varsstrip_client_envrecords as stripped secrets. Client-onlySYNAPS_*knobs never go, even with a secret-looking name. - is_
secret_ key - Whether a key matches the secret denylist (case-insensitive).
Delegates to the canonical implementation in
agent_core::core::config. - resolve_
client_ name - The name a joining client gets in a session: its requested name, or its
kind’s name if it asked for none (or an invalid one), with the lowest
free
-Nsuffix (N ≥ 2) if another client already has it. Names compare case-insensitively. - sanitize_
prompt_ text - Make prompt text safe to print in any client (prA I-R4-3, I-R5): drop
C0/C1 control characters except
\n(a\tbecomes a space); the zero-width space and the LRM/RLM marks (U+200B, U+200E, U+200F); bidi embeddings/overrides/isolates (U+202A–U+202E, U+2066–U+2069) and the Arabic letter mark (U+061C); and the line/paragraph separators (U+2028, U+2029), which some terminals treat as line breaks. ZWNJ / ZWJ (U+200C, U+200D) are KEPT: emoji sequences and several scripts need them. Prevents an extension’s text from moving the cursor (\x1b[3A,\r) over the host-built header, or disguising text with direction overrides. - should_
strip_ env - Whether a key should be stripped from the client env snapshot.
- strip_
client_ env - The pure part of
capture_client_env: filtervars(unit-testable without touching the process environment). - tail_
items_ from_ env SYNAPS_ATTACH_TAIL_ITEMS(client side): display items requested inAttached.display_tail;DEFAULT_TAIL_ITEMSwhen unset/invalid.- validate_
client_ name - A client name is 1–32 ASCII letters, digits,
-or_, starting with a letter or digit. The client checks before connecting; the daemon checks again and refuses the handshake.
Type Aliases§
- Session
Env - Ordered key-value snapshot of a client’s environment.