Session Handoff

Turn durable session state into a self-contained continuation prompt for a fresh context

Session handoff assembles a continuation prompt from durable state so a fresh context can resume without scrolling.

Diagram

Session Handoff

📌 Recap

🧠 build_handoff_prompt

🎯 GoalState

🧭 Checkpoint

📝 Continuation Prompt

✅ Fresh Context

Quick Start

  1. Hand off the most recent session
    bash
    praisonai session handoff
  2. Hand off a specific session
    bash
    praisonai session handoff my-project --json
    praisonai session handoff my-project --copy
  3. Build a handoff prompt from Python
    python
    from praisonaiagents import Agent
    from praisonaiagents.session import build_handoff_prompt
    
    agent = Agent(
        name="ResumingAgent",
        instructions="Continue the interrupted work."
    )
    
    prompt = build_handoff_prompt(
        recap="Recap — where we were: refactored logging in main.py",
        goal_state={
            "goal": "Ship the logging refactor",
            "criteria": {
                "outcome": "All modules use structured logging",
                "verification": "pytest passes and logs are JSON",
                "constraints": ["do not change public API"],
            },
        },
        workflow_checkpoint={
            "completed_steps": 3,
            "total_steps": 5,
            "last_step": "wire logger",
        },
    )
    
    agent.start(prompt)

How It Works

The CLI resolves a session, reads its durable stores, and calls build_handoff_prompt to render the prompt — no LLM call, no state mutation.

Diagram
Durable Storesbuild_handoff_promptSession Resolverpraisonai session handoffUserDurable Storesbuild_handoff_promptSession Resolverpraisonai session handoffUsersession handoff [id]resolve session (default: most recent)read recap + goal + checkpointdurable statecontinuation promptpanel (or –json / –copy)

Each section maps to one durable source and is omitted when that source has no data.

SourceSection renderedOmitted when
Persisted recapRECENT ACTIONS (recap-derived):recap is empty
GoalStateGOAL: / DEFINITION OF DONE: / CONSTRAINTS (never violate): / STATUS:goal_state missing
Workflow checkpointPROGRESS: {n} of {m} workflow steps done; last completed: …checkpoint missing
Explicit recent_actions=RECENT ACTIONS: bullet listnot supplied (falls back to recap)
Explicit key_files=KEY FILES: a, b, c (de-duplicated)not supplied
Always presentPreamble + NEXT: guidance tailnever

Example Output

The Quick Start inputs render this prompt verbatim:

text
You are resuming an interrupted run. Recover from durable state; do not trust memory of a previous conversation.

GOAL: Ship the logging refactor
DEFINITION OF DONE: All modules use structured logging (verify: pytest passes and logs are JSON)
CONSTRAINTS (never violate): do not change public API
PROGRESS: 3 of 5 workflow steps done; last completed: wire logger
RECENT ACTIONS (recap-derived):
Recap — where we were: refactored logging in main.py
NEXT: continue toward the remaining work. First verify the current state on disk before acting.

Add a STATUS: line by setting last_reason on the goal state, and a KEY FILES: line by passing key_files=:

python
prompt = build_handoff_prompt(
    recap="Recap — where we were: refactored logging in main.py",
    goal_state={
        "goal": "Ship the logging refactor",
        "criteria": {
            "outcome": "All modules use structured logging",
            "verification": "pytest passes and logs are JSON",
            "constraints": ["do not change public API"],
        },
        "last_reason": "tests still failing",
    },
    workflow_checkpoint={
        "completed_steps": 3,
        "total_steps": 5,
        "last_step": "wire logger",
    },
    key_files=["src/main.py", "tests/test_main.py"],
)

Python Options

build_handoff_prompt is keyword-only. Every argument maps to a durable source.

OptionTypeDefaultDescription
recapstr""Persisted compaction summary / recap string.
goal_stateOptional[Dict]NoneA persisted GoalState.to_dict() mapping.
workflow_checkpointOptional[Dict]NoneWorkflow checkpoint dict.
recent_actionsOptional[List[str]]NoneExplicit recent-action lines; falls back to recap-derived when omitted.
key_filesOptional[List[str]]NoneFile paths to surface under KEY FILES: (de-duplicated, order preserved).
max_charsint4000 (HANDOFF_MAX_CHARS)Upper bound on the rendered prompt. 0 disables the cap.

CLI Options

praisonai session handoff prints the continuation prompt for a session.

OptionDescription
[session-id]Session to hand off. Defaults to the most recent session.
--jsonStructured output: {session_id, handoff, has_goal, has_checkpoint} (global JSON flag).
--copyBest-effort clipboard copy; falls back to printing the panel.

When the id can’t be resolved the command exits with code 1:

text
Session not found: my-project
Use 'praisonai session list' to see available sessions

Key Properties

Deterministic

No LLM call — the same durable state always renders the same prompt.

Offline-safe

Assembly reads only local durable stores, so it never blocks the hot path and never raises into the loop.

Tail-biased cap

The prompt is hard-capped at max_chars (default 4000) by trimming the middle recap while preserving the actionable NEXT: line verbatim.

Additive, read-only

Handoff assembles a prompt from durable state. It does not restore conversation (use --continue / resume) and does not mutate session state.


Choosing the Right Resume Path

Different goals call for different commands — pick the one that matches your intent.

Diagram

Keep talking in the same conversation

Inspect where we were, non-destructive

Seed a fresh context / new machine / another agent

What do you want?

praisonai run –continue

praisonai session show –recap

praisonai session handoff


Related