Daemon — Warm Runtime

Keep agents warm in memory so repeated runs skip cold-start

praisonai daemon keeps provider clients, MCP connections, and agents hot in memory — repeated praisonai run calls reuse the already-warm agent instead of paying cold-start costs every time.

Diagram

hit

miss

praisonai run prompt

Lockfile?

Loopback POST

Warm Agent

Reply

In-process run

Quick Start

  1. Install PraisonAI
    bash
    pip install praisonai
  2. Start the warm runtime in the background
    bash
    praisonai daemon start --background
  3. Run prompts — they attach automatically
    bash
    praisonai run "Hello"
    praisonai run "What is the capital of France?"

    No flag, no env var. When the daemon is running, praisonai run forwards to it automatically. Bare prompts (praisonai "Hello") route to run, so they reuse the same warm path.

  4. Check status and stop when done
    bash
    praisonai daemon status
    praisonai daemon stop

Project rules and local tools

As of PR #4943, the warm runtime honors AGENTS.md / CLAUDE.md subtree instructions and loads project-local .praisonai/tools/*.py on every run — so the daemon now behaves identically to the cold path for these two implicit, project-scoped sources.

Previously the warm runtime built a bare agent with no subtree instruction hook and no local tools, so a daemon-forwarded praisonai run returned fluent text and exited 0 while touching nothing — indistinguishable from success until you checked the filesystem.

bash
# Cold path (already worked)
praisonai run "list the todos"     # honored ./AGENTS.md and ./.praisonai/tools/

# Warm path (now equally honored, from PR #4943)
praisonai daemon start
praisonai run "list the todos"     # same rules, same tools, same result

How It Works

Diagram
Warm AgentDaemon ServerDescriptor Lockfilepraisonai runWarm AgentDaemon ServerDescriptor Lockfilepraisonai runalt[lockfile present and daemon alive][no lockfile / stale]read lockfilehost:port + tokenPOST /run (prompt)reuse cached agentresultstreamed replyin-process fallback
What is warmWhat is rebuilt per call
Provider client (LiteLLM)Prompt text
MCP connectionsOutput format (structured, stream, etc.)
Loaded agent configSession/memory overrides
Tool registrationsPer-invocation flags (see below)

When run Falls Back to In-Process

praisonai run does not forward to the daemon when you use these flags. They are handled in-process instead:

FlagReason
--session, --continue, --forkSession continuity requires stateful context
--memoryMemory backend must be initialized per-session
--approvalApproval backends need a live terminal or channel
--tools, --toolsetPer-invocation tool overrides change agent config
--attachLive session tagging for multi-terminal observation
--output json, --streamStructured output modes attach directly to the process
--trace, --profileTracing and profiling require direct process access

When any of these flags is set, run behaves exactly as if no daemon were running — fully backward compatible.


CLI Reference

praisonai daemon start

Start the warm runtime server.

bash
praisonai daemon start

praisonai daemon start --background

praisonai daemon start --host 127.0.0.1 --port 8899 --model gpt-4o-mini --idle-timeout 3600
OptionTypeDefaultDescription
--host, -hstr127.0.0.1Loopback address to bind. Non-loopback addresses are rejected.
--port, -pint0 (auto)Port to bind. 0 picks a free port automatically.
--model, -mstrNoneDefault model for warm agents. Inherits your configured default when unset.
--idle-timeoutfloat1800.0Seconds of inactivity before the daemon auto-shuts-down. 0 disables.
--background, -bboolFalseDetach from the terminal and run in the background.

praisonai daemon status

bash
praisonai daemon status

praisonai daemon status --json
OptionTypeDefaultDescription
--jsonboolFalseMachine-readable JSON output.

praisonai daemon stop

bash
praisonai daemon stop

Sends SIGTERM to the daemon process. If the lockfile is stale (PID reuse), cleans up the lockfile instead of killing a random process.


Version compatibility

The warm runtime records its package version in the lockfile. Thin clients (praisonai run, praisonai attach) require a matching major version before reusing the runtime — a stale daemon after upgrade is ignored and the CLI falls back to in-process execution (or attach exits with code 1).

After upgrading PraisonAI:

bash
praisonai daemon stop
praisonai daemon start --background

See Attach for streaming live session events from a second terminal.


Security

ProtectionHow
Loopback-onlyipaddress.is_loopback check at startup — non-loopback --host exits 1
Token authBearer token generated at startup, stored in lockfile with 0600 permissions
PID-reuse safetydaemon stop pings before sending SIGTERM; stale lockfile is cleaned, not used to kill a random process
Concurrent prompt safetyPer-model lock serializes /run calls — concurrent prompts cannot corrupt agent state
Error isolationAgent evicted from cache on failed start() — transient LLM errors don’t leave a half-consumed turn cached

Troubleshooting

Runtime descriptor is stale

The lockfile exists but the PID it points to is dead. This usually happens after a crash or force-kill.

Fix: Run praisonai daemon stop — it detects the stale lockfile and cleans it up automatically. Then praisonai daemon start again.

Runtime did not report ready in time (–background)

The daemon started but did not write its lockfile within the timeout.

Fix: Try starting in foreground mode first (praisonai daemon start) to see error output. Common causes: port already in use, missing credentials, MCP server refusing connection.

praisonai run still feels slow

Verify the daemon is actually running and being detected:

bash
praisonai daemon status --json

If the daemon is running but run is still in-process, you may be using a flag that forces in-process execution (see the fallback table above).

daemon start –background exits immediately

On some systems, background detach requires a clean environment. Try:

bash
nohup praisonai daemon start > ~/.praisonai/daemon.log 2>&1 &

Related