Skip to main content

Crate gate4agent_wake

Crate gate4agent_wake 

Source
Expand description

gate4agent-wake: the deliver-turn API – put one letter into an agent session as a turn, over structured channels only. No PTY, no raw keystrokes, no screen read: this crate must never depend on the terminal crates (gate4agent-pty, -shell-*, -runtime-native, -node-core). It has no permission model of its own; the host (hatchery) decides who may deliver. Adapters never answer a permission request; the modal stays with the session’s client.

(Adapters moved here from mail4agent, 2026-10-13; the grok leader ACP client and the routine POST followed on feat/deliver-adapters, so the messenger links no session channel.)

Layer rule: mail4agent (m4a) is a pure messenger – it hands a letter over (M4A_LETTER_HOOK) and keeps it in its durable inbox. The host (the hatchery node) decides with hosted and delivers through the adapters here.

Original description (mail4agent):

The clients (push link, decrypt, sealed store, m4a-send socket) are provider-agnostic. The only provider-specific step is wake: putting one decrypted room text in front of an agent session so it takes a turn. That step is the WakeAdapter trait. A session is addressed by a SessionKind: the vendor (ProviderKind) and the Surface it runs on (vendor-hosted web/cloud, or a CLI on the user’s machine). Replies never go through the adapter: every agent answers with the shell command m4a-send --as <own-nick> --to <peer-nick> '<text>'.

Each session gets an ordered WakeChain (chain::plan_chain, order in chain::mechanisms): a turn in the client that already has the session open first, then hooks inside that session, then the durable inbox, and a new-process resume only for a headless session.

KindPrimary (in-session)FallbacksLast resort (headless only)
Grok CLIGrokLeaderAdapter ACP on leader.sockStop hook, inboxgrok --resume -p
Codex CLIcodex::CodexAppServerAdapter turn/startStop hook, inboxcodex exec resume
Kimi Code CLIkimi::KimiServerAdapter kimi web promptsStop hook, inboxkimi -S -p
Claude Code CLIClaudeChannelAdapter channel MCP; asyncRewake waiterStop hook, inboxclaude --resume -p
Cursor CLInone for an idle chatstop hook followup_message, inboxagent --resume -p
Grok Bot / Cursor webRoutineWebhookAdapter--
Claude Code webasyncRewake waiter in the cloud sessionStop hook, inboxClaudeRoutineFireAdapter (new session)
Codex cloud-Stop hook, inboxcodex cloud exec (new task)
Kimi web, Grok webnone documented (NoInboundAdapter)--

Core four: Grok, Kimi Code, Claude Code, Codex. Cursor CLI is optional. Design: the project documentation. Only spawn::ResumeSpawnAdapter starts a provider process, and only for a headless session. No adapter answers a permission modal or logs the plaintext or a credential.

Re-exports§

pub use chain::plan_chain;
pub use chain::ChainError;
pub use chain::HostEnv;
pub use chain::Mechanism;
pub use chain::Tier;
pub use chain::WakeChain;
pub use chain::WebVendor;
pub use claude_channel::ClaudeChannelAdapter;
pub use codex::CodexAppServerAdapter;
pub use codex::CodexEndpoint;
pub use hook::HookFlavor;
pub use hook::InboxHookAdapter;
pub use hook::InboxQueueAdapter;
pub use inbox::InboxEntry;
pub use inbox::InboxLetter;
pub use kimi::KimiServerAdapter;
pub use registry::SessionRecord;
pub use spawn::ResumeSpawnAdapter;

Modules§

chain
Ordered wake chains and host/session detection.
claude_channel
Claude Code CLI: a channel MCP server that pushes mail4agent letters into a running interactive session.
codex
Codex CLI: start a turn in a running thread through codex app-server.
grok_leader
Grok CLI deliver channel: ACP session/load + session/prompt over an already-running grok leader (leader.sock; a named pipe on Windows). Moved here from mail4agent-grok (2026-10-13) so the messenger links no session channel of its own.
hook
Hook doorbells: the session’s own hook process picks the letter up.
hosted
Wake for sessions a host owns (the hatchery node): the host knows which sessions are live (it spawned them and assigned each its m4a account, nick = key = role); g4a decides what a letter does and frames the prompt; the host executes the decision on its own runtime (submit a prompt into the live PTY/ACP session, or spawn one). No I/O here, so the decision is the same for every host and testable without one.
inbox
Per-session inbox: one JSON file per letter, written by the local client and drained by a process the provider runs (the Claude channel MCP server, or a hook such as Kimi Stop / Claude Stop).
kimi
Kimi Code CLI: submit a prompt to a session hosted by the local Kimi server (kimi web / kimi rc, Kimi Code 2.x).
kimi_acp
Kimi ACP host: a persistent kimi acp stdio process per m4a session.
registry
Sessions that announced themselves to the local client.
routine
Routine webhook deliver channel: one JSON POST to a session’s preconfigured routine URL. Moved here from mail4agent’s post_routine_json (2026-10-13): the messenger no longer makes HTTP calls to routines; the host (hatchery node) delivers through this.
spawn
Last resort: start a NEW provider process that resumes the session for one turn. Only for a session marked headless (no client holds it open). A session that has a live client is never spawned into: two writers on one transcript is how sessions get corrupted.

Structs§

AdapterConfig
Endpoints the host hands to adapter_for. Every field is optional; an adapter whose endpoint is missing reports WakeError::Unavailable. Credentials come from the host keychain / environment, never a literal.
ClaudeRoutineFireAdapter
Claude Code on the web, LAST resort: routine /fire (POST https://api.anthropic.com/v1/claude_code/routines/{id}/fire, per-routine bearer, anthropic-beta: experimental-cc-routine-2026-04-01, body {"text": ...}). Every fire starts a NEW cloud session (rate limited), so it is used only for a session marked headless. An open cloud session is reached by its own hooks (claude-async-rewake, claude-stop-hook) first.
CodexCloudAdapter
Codex cloud (stub, vendor-side fix).
CursorAgentAdapter
Cursor CLI: the session’s own stop hook (m4a-inbox drain --format cursor-stop) returns followup_message, which Cursor auto-submits as the next user turn. No documented way into an idle interactive chat another process owns (agent acp / persist start their own agent), so this is a hook doorbell; see chain::mechanisms for the order.
GrokLeaderAdapter
Grok CLI: ACP session/prompt on an already-running leader.sock.
NoInboundAdapter
Vendor web surface with no documented inbound trigger (Kimi web, Grok web).
ProviderSession
One session a client wakes.
RoutineWebhookAdapter
Vendor-hosted web session woken by its own webhook routine (Cursor / Grok Bot boxes). Same JSON object m4a-web-client posts today (body, from, from_nick, to, event_id, room, reply).
SessionKind
Vendor + surface: what picks the adapter.
WakeLetter
One decrypted room text to put in front of the session.

Enums§

ProviderKind
Agent vendors the stack drives. Ids match the gate4agent catalog / adapter ids (grok, kimi, claude, codex, cursor).
Surface
Where a session runs.
WakeError
Why a wake did not happen. Never carries the plaintext or a secret.
WakeOutcome
What a wake did.

Constants§

CLAUDE_FIRE_TOKEN_ENV
Claude routine token env.
CLAUDE_FIRE_URL_ENV
Claude routine fire URL env.
CLAUDE_ROUTINE_BETA
anthropic-beta value for routine fire (override M4A_CLAUDE_ROUTINE_BETA).
INBOX_DIR_ENV
Environment variable for a per-session inbox directory used by queue-style adapters (Claude channel server, hook doorbells).
LEADER_SOCK_ENV
M4A_LEADER_SOCK: the grok leader socket.
PROVIDER_ENV
Environment variable naming the provider of a local session.
SEND_COMMAND
Command a woken bot runs to answer, as shown in the wake’s reply.

Traits§

WakeAdapter
Vendor/surface-specific wake. One instance per session.

Functions§

adapter_for
Builds the adapter for kind from config.
reply_hint
The reply hint for a wake from from_nick to to.
wake_prompt
The prompt text every local adapter injects. Same shape for all providers so agents learn one protocol (docs/mail4agent/agent-mail-protocol.md). Web routines get the JSON object instead, whose reply field carries the same command.