Embed Replay

Show your agents working, step by step, live on any website or app

Next

python
from praisonaiagents import Agent
from praisonai.replay import watch

agent = Agent(name="Writer", instructions="Write one short paragraph.")
watch(agent, input="Solar sails")  # opens a page: press Run, watch each step

Replay draws a run as it happens. Each step and agent on the map turns from not reached to running to done. You can open it on its own page, put it in your app, or put it in any website with one <iframe>.

Diagram

Embed Replay

▶ Run or your app

🧠 Agents work

record live

📺 Replay view

🌐 Your website

Quick Start

  1. Watch a run with a Run button
    python
    from praisonaiagents import Agent, AgentTeam, Task
    from praisonai.replay import watch
    
    researcher = Agent(name="Researcher", instructions="Give 3 short facts.")
    writer = Agent(name="Writer", instructions="Write one paragraph from the facts.")
    team = AgentTeam(
        agents=[researcher, writer],
        tasks=[
            Task(name="research", description="3 facts about solar sails", agent=researcher, expected_output="3 facts"),
            Task(name="write", description="One paragraph using the facts", agent=writer, expected_output="a paragraph"),
        ],
    )
    
    watch(team)  # http://127.0.0.1:8090/

    Press ▶ Run. The map shows who is working right now. When the run ends, ▶ Play goes through it again one step at a time.

  2. Show progress inside your own app
    python
    import threading, uuid
    from fastapi import FastAPI
    from praisonaiagents import Agent
    from praisonai.replay import record, replay_app
    
    agent = Agent(name="Writer", instructions="Write one short paragraph.")
    app = FastAPI()
    app.mount("/replay", replay_app())  # the progress view, served by your app
    
    
    @app.post("/generate")
    def generate():
        run_id = f"run-{uuid.uuid4().hex[:12]}"
    
        def job():
            with record(run_id, live=True):  # live: the view follows it as it runs
                agent.start("Write about solar sails")
    
        threading.Thread(target=job, daemon=True).start()
        return {"run_id": run_id}

    Then show that run on any page:

    html
    <iframe src="/replay/?run=RUN_ID" style="width:100%;height:640px;border:0"></iframe>

How It Works

Diagram
Replay viewAgentYour appYour websiteUserReplay viewAgentYour appYour websiteUserloop[while the run is going]Click “Generate”POST /generatestart() inside record(run_id, live=True)run_idiframe /replay/?run=run_ideach step, as it happensstep turns running → done
PieceWhat it does
record(run_id, live=True)Writes every step of the run to ~/.praison/traces/<run_id>.jsonl as it happens
replay_app()The Replay view and its data, ready to mount in FastAPI or Starlette
/replay/?run=<id>Shows only that run and waits for it if it has not started yet
watch()Serves replay_app() on localhost and opens your browser

What the map shows:

LookMeaning
Dashed outlineNot reached yet
Blue, pulsingRunning now
GreenDone (×2 when it ran twice)
RedFailed
Bold outlineThe step the cursor is on

Three Ways to Run It

Python

python
from praisonaiagents import Agent
from praisonai.replay import watch

watch(Agent(name="Helper", instructions="Be brief."), input="Say hello")

CLI

bash
praisonai replay watch agents.yaml

The YAML runs as written, so the page has just a Run button and no input box.

YAML

python
from praisonai.replay import watch

watch("agents.yaml")

Embed on Any Website

The view is a normal web page, so any site can show it in an <iframe>, even when it is not built with Python.

HTML

html
<button id="go">Generate</button>
<iframe id="progress" style="width:100%;height:640px;border:0"></iframe>
<script>
  const APP = "";  // "" when this page is served by your app; else its origin, e.g. "https://agents.example.com"
  go.onclick = async () => {
    const { run_id } = await (await fetch(APP + "/generate", { method: "POST" })).json();
    progress.src = APP + "/replay/?run=" + run_id;
  };
</script>

On a different domain, the fetch to /generate is cross-origin, so allow your site in your app’s CORS settings (for FastAPI, CORSMiddleware with allow_origins=["https://your-site.example"]). The iframe itself needs no CORS.

React

jsx
export function RunProgress({ runId }) {
  if (!runId) return null;
  return (
    <iframe
      title="Agent progress"
      src={`/replay/?run=${runId}`}
      style={{ width: "100%", height: 640, border: 0 }}
    />
  );
}

Streamlit

python
import streamlit.components.v1 as components

# 127.0.0.1:8000 is local development; use your deployed app's origin when hosting
components.iframe("http://127.0.0.1:8000/replay/?run=RUN_ID", height=640)

Gradio

python
import gradio as gr

with gr.Blocks() as demo:
    # 127.0.0.1:8000 is local development; use your deployed app's origin when hosting
    gr.HTML('<iframe src="http://127.0.0.1:8000/replay/?run=RUN_ID" style="width:100%;height:640px;border:0"></iframe>')
demo.launch()
URLShows
/replay/The list of recorded runs and the selected one
/replay/?run=<id>Only that run, no list. Best for an iframe.

Common Patterns

Put the Run button in your app

Pass your agent, team or flow to replay_app() and the mounted page gets an input box and a Run button:

python
from fastapi import FastAPI
from praisonaiagents import Agent
from praisonai.replay import replay_app

agent = Agent(name="Writer", instructions="Write one short paragraph.")
app = FastAPI()
app.mount("/replay", replay_app(agent, input="Solar sails", placeholder="Topic"))

One run goes at a time. A team’s tasks start afresh on each run; an Agent keeps its chat history between runs.

Draw the view inside your own page

On a page served by the same app, load the view into any element instead of an iframe:

html
<div id="progress"></div>
<script type="module">
  import { render } from "/replay/replay.js";
  render(document.getElementById("progress"), { base: "/replay", run: "RUN_ID", approve: false });
</script>
OptionWhat it does
baseWhere replay_app() is mounted, e.g. "/replay"
runShow only this run
runner{input, placeholder} shows a Run box
approvefalse hides the Approve/Deny buttons

Teach how agents work together

watch() is a quick way to show a class or a team how a multi-agent run flows. Press Run, then ▶ Play to go through it again. Use ← → to step, Timeline to see who worked when, and Why to see what each agent was given.


Best Practices

Keep it private by default

Anyone who can open the page can read the runs (prompts and outputs). With a Run button, they can also start new runs. watch() listens on 127.0.0.1 only. In your app, mount replay_app() behind your own login. Protect /generate the same way, with login and a rate limit: anyone who can call it can start agent runs over and over.

Use one run id per request

Create the run_id yourself, pass it to record(), and return it to the page. The iframe can open /replay/?run=<id> straight away: it waits until the run starts.

Record with live=True

record(run_id, live=True) writes each step as soon as it happens. Without it, the view only fills in at the end of the run.

Prefer the iframe for other sites

The iframe works from any framework or domain. Use render() only on pages served by the same app.


Related