Skip to main content
praisonai attach connects a second terminal to a live agent session on the warm runtime. By default it streams events read-only; with --message it steers the live turn, and with --interrupt it cancels it — both as one-shot sends that exit without streaming.
Live-turn steering (-m / --message) and interrupt (--interrupt) landed in PR #5847 (release after 2026-10-15). Earlier releases supported read-only observation only. If attach -m or attach --interrupt prints runtime does not support …, the warm daemon is older than your CLI — restart it with praisonai daemon stop && praisonai daemon start.

Quick Start

1

Start the warm runtime

2

Run an agent with a session id (terminal A)

3

Attach from another terminal (terminal B)

4

Steer the live turn from another terminal

Sends the steering message and exits. The running agent picks it up on its next tool-loop iteration.
5

Interrupt the live turn from another terminal

Requests a cooperative cancel and exits. The run stops at the next safe boundary.
What --attach <id> really tags. --attach <id> is an event-stream label, not a session identity. Two things happen independently:
  1. Persistence / continuity is driven by --session <id> or --continue (a --no-save run has no session identity, so no history is loaded or saved).
  2. Live event fan-out to praisonai attach <id> clients is driven by --attach <id> (falls back to the session id when --attach is omitted).
So praisonai run "..." --no-save --attach obs-1 streams events to observers under obs-1 but persists nothing; praisonai run "..." --session s1 (no --attach) is observable under s1 and its history is retained across turns; praisonai run "..." --session s1 --attach obs-1 runs the stateful s1 conversation but publishes its events under obs-1.

Usage

Options must come before the session id. praisonai attach <id> --json and praisonai attach <id> -m "..." do not parse due to a Typer group-callback limitation. Always write praisonai attach -m "..." <id>.

Steering a live turn

Send mid-run guidance to a session that is already executing on the warm runtime; it lands on the agent’s next tool-loop iteration without restarting the run.
The CLI always sends priority 5 (NORMAL). For URGENT (20) or INTERRUPT (30) priorities, call agent.steer(message, priority=…) from Python. See Message Steering.

Interrupting a live turn

--interrupt requests a cooperative cancel; the agent stops at the next safe boundary, so partial progress and conversation history stay intact.
--interrupt only cancels the currently running turn. The session stays warm — the next praisonai run --session my-session "..." continues from where the interrupted turn left off.

Which flag do I want?

Both flags can be combined (-m "focus" --interrupt <id>): the message is sent first, then the interrupt.

How It Works

Attaching never starts execution; plain attach only observes, while -m and --interrupt act on a turn already in flight (not gated by the run lock). Detaching (Ctrl-C) does not stop the run on terminal A.
Events arrive over Server-Sent Events at GET /sessions/{session_id}/events with Bearer auth from the runtime lockfile. Session ids are percent-encoded on the wire. A : keep-alive comment is sent every ~15s and ignored.

Event Reference


Exit Codes


Common Patterns

Watch a long-running agent from a second terminal — start with --attach, observe progress without blocking terminal A. Pipe JSON into jq — praisonai attach my-session --json | jq 'select(.type=="run.result")'. Multiple observers — several terminals can attach to the same session concurrently; all receive the same events. Observe without persisting — praisonai run "..." --no-save --attach obs-1 streams events under obs-1 for observers while keeping the run on the anonymous, non-persisted path. Steer a long multi-tool run from a second terminal — praisonai attach -m "focus on the EU market only" my-session lands on the next tool-loop iteration without restarting the run. Stop a stuck turn without losing the session — praisonai attach --interrupt my-session cancels the current turn only; the next run --session my-session continues from where it left off.

Best Practices

Run praisonai daemon start before run --attach. Without a warm runtime, attach exits with code 1.
--attach on praisonai run works for direct prompts only — not YAML files, --agent, or --command.
Ctrl-C in an attach terminal never cancels the underlying agent run.
-m and --interrupt send one request and exit. Run them again from a second terminal as needed; there is no persistent input loop inside attach.
If attach -m or attach --interrupt prints runtime does not support …, the warm daemon pre-dates PR #5847. Run praisonai daemon stop && praisonai daemon start to pick up the new routes.
If CLI and daemon major versions differ, attach refuses to connect. Run praisonai daemon stop && praisonai daemon start after upgrading.

Run

--attach flag for tagging warm-runtime sessions

Daemon

Warm runtime lifecycle and version handshake

Message Steering

Send guidance from Python with priority levels (URGENT / INTERRUPT)