Skip to content

About

Turn any agent run's trace into a shareable video — 1:1 run timeline, code/terminal/screen/orbit capsules, multi-modal artifacts + audio, composed into one film.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

@tangle-network/run-capsule

Turn any agent run's trace into a shareable video.

run-capsule consumes a run's Span[] trace (the @tangle-network/agent-eval storyboard IR), renders modality-typed capsule animations — code, terminal, screen, conversation, and a unified replay — and records each headless to MP4 on local disk. Publishing to a public link is opt-in (upload: true or --upload). The trace is redacted before anything is rendered, and an upload is refused unless the redacted trace passes the share-safety check.

The trace is the source of truth; the storyboard is the IR; the video is just one compiled target. Capture once, render many views.

import { runToVideo } from '@tangle-network/run-capsule'

const { results } = await runToVideo(spans, { title: 'Agent builds a DEX', outDir: 'out' })
for (const r of results) console.log(r.kind, r.videoPath) // local clips

// Opt in to publishing: each result also gets a public share link.
const shared = await runToVideo(spans, { title: 'Agent builds a DEX', outDir: 'out', upload: true })
for (const r of shared.results) console.log(r.kind, r.url)
npx run-capsule --workdir ./generated-project      # code capsule from real files
npx run-capsule --playwright agent-result.json     # browser/screen from a Playwright run
npx run-capsule --claude stream.jsonl              # any Claude Messages stream
npx run-capsule --demo                             # built-in sample
npx run-capsule --demo --upload                    # also publish each clip (temporary link)

# Reuse a driver's already-rendered run video (cursor overlay baked in) as the
# screen capsule, with the reasoning storyboard from the trace alongside:
npx run-capsule --playwright report.json --video recording.webm

# Opt-in heavier kinds: a 1:1 sandbox-ui run view, a rendered-model spin, and
# the full sequenced film (scoreboard shot from an eval verdict, VO, music):
npx run-capsule --demo --kinds studio,orbit,composed --orbit-dir ./frames --result verdict.json --narrate --music

Run npx run-capsule --help for the full flag reference (source of truth — do not duplicate it here); the table below explains what each rendered kind shows and where its input comes from.

What it renders

runToVideo auto-detects which capsules a trace supports and renders only those:

Capsule Built from Shows
code edit/write tool spans the agent typing each file (themed, file tabs + explorer)
terminal shell/sandbox spans commands typing out with their output
screen browser/computer-use spans, or an ingested --video real screenshots replayed with action + 💭 reasoning captions — or, with --video, the driver's own recording (cursor overlay baked in) passed through
conversation llm messages the back-and-forth reasoning
replay the whole trace the unified storyboard (title → moments → summary)
studio (opt-in) the whole trace the 1:1 sandbox-ui run view
orbit (opt-in) --orbit-dir frames a rendered-model spin
composed (opt-in) everything above the full sequenced film: intro/outro cards, an animated scoreboard shot when --result is given, and narration/music when --narrate/--music are set

studio, orbit and composed are heavier and not auto-detected — pass them explicitly with --kinds.

With --video <file> the screen capsule is the supplied recording itself (transcoded, and uploaded only with --upload), and the screenshot replay is suppressed — so a @tangle-network/browser-agent-driver run rendered with --show-cursor keeps its real animated cursor, while the trace still drives the storyboard. The overlay is rendered once, in the driver; run-capsule reuses it.

Adapters — one per surface

Map your agent surface into Span[] once, then everything downstream is uniform:

Adapter Surface
spansFromPlaywrightResult @tangle-network/agent-browser-driver TestResult (browser, with screenshots)
spansFromComputerUse computer-use loops (Anthropic computer-use, CUA, desktop drivers)
spansFromClaudeMessages any Anthropic Messages stream (e.g. sandbox-driver stream-shot-*.jsonl)
spansFromRuntimeEvents agent-eval RuntimeEventLike[]
spansFromWorkdir a generated project directory

The output is only as rich as the trace: a screen capsule shows real frames when the trace carries attributes.screenshot; a code capsule shows real code when edits carry their content.

Privacy

Clips stay in the output directory by default. With upload: true (CLI --upload), each clip is published to a public host: litterbox by default (temporary), or catbox (permanent). Anyone with the link can view it, and even temporary uploads may be cached.

Before anything is rendered, runToVideo redacts the trace, title and result with agent-eval's redaction core under the share profile (docs/redaction.md). Credentials are replaced whole, and email, card, phone and SSN values in place. User, account and session ids get stable pseudonyms, and data: screenshots are kept.

The core then checks the redacted copy again and returns a share-safety verdict. An upload goes ahead only when the verdict is SAFE or SAFE_WITH_WARNINGS. UNSAFE or UNKNOWN keeps the clip local and puts the reason in results[].error; the CLI exits 1. An ingested video is always UNKNOWN, because no text detector can read its frames, so it is never uploaded.

System dependencies

Recording needs a browser and (for MP4) ffmpeg:

  • Chromium — npx playwright install chromium (or use the Docker image / Nix flake below).
  • ffmpeg — on PATH. Without it, output stays .webm (still playable/uploadable).

Docker (everything bundled)

docker build -t run-capsule .
docker run --rm -v "$PWD/out:/out" run-capsule --demo --out /out

The image is based on the official Playwright image (Chromium + system libs preinstalled) plus ffmpeg.

Nix

nix develop          # devShell with node, pnpm, ffmpeg, and Chromium wired for Playwright

API

  • runToVideo(spans, { title, kinds?, outDir, upload?, host?, expiry?, toMp4?, video?, orbitFrames?, result?, narrate?, music?, voice? }) → { runDir, results }. upload defaults to false; set it to publish each clip and fill results[].url. Pass video to ingest an already-rendered recording as the screen capsule; pass result (an eval verdict) to drive the composed film's scoreboard shot.
  • supportedKinds(spans) → which auto-detected capsules the trace supports (excludes the opt-in studio/orbit/composed)
  • resolveKinds(kinds, hasVideo) → kinds to render, dropping screen when a video is ingested
  • renderCodeCapsuleHtml / renderTerminalCapsuleHtml / renderScreenCapsuleHtml / renderConversationCapsuleHtml / renderOrbitCapsuleHtml
  • directStoryboard(spans, opts) → narrative-aware shot timing for the replay capsule
  • autoCompose(spans, opts) / renderCompositionHtml / renderCardHtml → sequence per-capsule clips into the composed film
  • renderScoreboardHtml, renderIntroHtml, renderOutroHtml → the film's verdict and bookend cards
  • recordHtmlToVideo(htmlPath, outDir, opts) → { webm, mp4? }; transcodeToMp4(src, outMp4) → H.264 mp4 path
  • the adapters listed above

uploadToShareHost is not exported. It has no share-safety gate on its own; runToVideo's internal maybePublish() is the only caller, and only after a SAFE/SAFE_WITH_WARNINGS verdict. See AGENTS.md before reaching around it.

Resolve the current, complete export list from src/index.ts — this section is a guide, not the source of truth.

Related packages

  • @tangle-network/agent-eval owns the Span[]/storyboard IR this package renders and the redaction/share-safety core (redactForShare, assessShareSafety) that gates every upload. run-capsule never carries its own credential or PII patterns.
  • @tangle-network/traces is the CLI/SDK surface for analyzing the same trace (contracts, diffs, facts); run-capsule renders it. Both consume the same span contract.

License

MIT

About

Turn any agent run's trace into a shareable video — 1:1 run timeline, code/terminal/screen/orbit capsules, multi-modal artifacts + audio, composed into one film.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages