Skip to main content
Browser agents fail in ways that don’t show up in logs. Kernel gives you several ways to see what’s actually happening: live, after the fact, frame by frame, line by line, and event by event.

Live view

Every browser exposes a browser_live_view_url you can open in a browser tab or embed in an iframe. Use it to watch an agent run in real time, hand a session off to a human-in-the-loop, or surface the browser as part of your own UI.
import Kernel from '@onkernel/sdk';

const kernel = new Kernel();

const kernelBrowser = await kernel.browsers.create();
console.log(kernelBrowser.browser_live_view_url);
from kernel import Kernel

kernel = Kernel()

kernel_browser = kernel.browsers.create()
print(kernel_browser.browser_live_view_url)
package main

import (
	"context"
	"fmt"

	"github.com/kernel/kernel-go-sdk"
)

func main() {
	ctx := context.Background()
	client := kernel.NewClient()

	kernelBrowser, err := client.Browsers.New(ctx, kernel.BrowserNewParams{})
	if err != nil {
		panic(err)
	}

	fmt.Println(kernelBrowser.BrowserLiveViewURL)
}
kernel browsers view <session-id>
Add ?readOnly=true for a non-interactive view, or enable kiosk mode at creation for a fullscreen, cinematic experience. Full reference: Live View.

Replays

Replays are MP4 recordings you start and stop on demand - capture as many clips per session as you need. They’re the right tool for post-hoc debugging: a failed run gives you one or more videos to scrub through, share, or attach to a bug report. Replays can also be enabled on managed auth sessions, so you can debug failed logins the same way.
const replay = await kernel.browsers.replays.start(kernelBrowser.session_id);

// ...run the agent...

await kernel.browsers.replays.stop(replay.replay_id, {
  id: kernelBrowser.session_id,
});
replay = kernel.browsers.replays.start(kernel_browser.session_id)

# ...run the agent...

kernel.browsers.replays.stop(
    replay.replay_id,
    id=kernel_browser.session_id,
)
replay, err := client.Browsers.Replays.Start(ctx, kernelBrowser.SessionID, kernel.BrowserReplayStartParams{})
if err != nil {
	panic(err)
}

// ...run the agent...

if err := client.Browsers.Replays.Stop(
	ctx,
	replay.ReplayID,
	kernel.BrowserReplayStopParams{ID: kernelBrowser.SessionID},
); err != nil {
	panic(err)
}
# Start recording
kernel browsers replays start <session-id>

# ...run the agent...

# Stop and download
kernel browsers replays stop <session-id> <replay-id>
kernel browsers replays download <session-id> <replay-id> -o replay.mp4
Full reference: Replays.

Screenshots

Pull a frame at any moment with computer controls - useful for snapshotting state at decision points, attaching to traces, or feeding back into a vision model.
const screenshot = await kernel.browsers.computer.captureScreenshot(
  kernelBrowser.session_id,
);
screenshot = kernel.browsers.computer.capture_screenshot(
    id=kernel_browser.session_id,
)
screenshot, err := client.Browsers.Computer.CaptureScreenshot(
	ctx,
	kernelBrowser.SessionID,
	kernel.BrowserComputerCaptureScreenshotParams{},
)
if err != nil {
	panic(err)
}
defer screenshot.Body.Close()
kernel browsers computer screenshot <session-id> --to screenshot.png
For full-page captures, use Playwright execution instead.

Invocation logs

If you’re running an agent on Kernel’s app platform, every invocation produces a streaming log feed. Tail it live while the agent runs, or pull it after the fact for debugging.
const logs = await kernel.invocations.follow(invocationId);

for await (const event of logs) {
  console.log(event);
}
logs = kernel.invocations.follow(invocation_id)

for event in logs:
    print(event)
stream := client.Invocations.FollowStreaming(
	ctx,
	invocationID,
	kernel.InvocationFollowParams{},
)
defer stream.Close()

for stream.Next() {
	fmt.Println(stream.Current())
}
if err := stream.Err(); err != nil {
	panic(err)
}
Full reference: Logs.

Telemetry

Telemetry is a real-time, structured stream of what happens inside a session: console output, network activity, page lifecycle, interactions, and operational signals like crashes. Unlike a video or screenshot, it’s machine-readable, so it’s the right tool for feeding session activity into your own observability pipeline or reacting to events programmatically. Enable it at creation, then stream the events:
const browser = await kernel.browsers.create({ telemetry: { enabled: true } });

const stream = await kernel.browsers.telemetry.stream(browser.session_id);
for await (const { seq, event } of stream) {
  console.log(`#${seq} [${event.category}] ${event.type}`);
}
browser = kernel.browsers.create(telemetry={"enabled": True})

with kernel.browsers.telemetry.stream(browser.session_id) as stream:
    for envelope in stream:
        print(f"#{envelope.seq} [{envelope.event.category}] {envelope.event.type}")
stream := client.Browsers.Telemetry.StreamStreaming(
	ctx,
	kernelBrowser.SessionID,
	kernel.BrowserTelemetryStreamParams{},
)
defer stream.Close()

for stream.Next() {
	fmt.Println(stream.Current())
}
if err := stream.Err(); err != nil {
	panic(err)
}
kernel browsers telemetry stream <session-id>
Full reference: Telemetry.

Picking the right tool

  • Building the agent? Keep a live view tab open while you iterate.
  • Debugging a failure? Capture a replay for the run, then watch the video.
  • Instrumenting the agent itself? Drop screenshots and logs into your traces at the points that matter.
  • Feeding an observability pipeline? Stream telemetry events and route them wherever you collect signals.
  • Putting a human in the loop? Embed the live view in your own UI.