Views

View as Markdown

A View is a human-facing surface for automation. It can show a live Runtime, a completed Run, trace and event data, or a place for a person to respond when automation needs help.

The Run remains the machine-readable record. The View is the interface a person uses to observe or influence that execution. This pattern is commonly called live supervision or human-in-the-loop control.

Create a View

Create a hosted View for one Run:

1const view = await bctrl.views.create({
2 scope: { runId },
3 bell: true,
4 control: true,
5 recordings: true,
6 trace: true,
7 events: false,
8});
9
10console.log(view.id);
11console.log(view.url);

scope is required. bell, control, recordings, trace, and events are the canonical capability fields. bell, control, recordings, and trace default to true; events defaults to false. presentation defaults to hosted ({ mode: "hosted" }). expiresInSeconds defaults to 28_800 (8 hours) and accepts up to 2_592_000 (30 days).

Choose a scope

The scope determines what automation the View can show:

ScopeUse it for
{ spaceId }A Space-level workspace view
{ spaceId, runtimeIds }A Space view limited to selected Runtimes
{ runtimeId }One durable Runtime and its current session
{ runId }One execution and its history

For a Space scope, runtimeIds is optional and may contain up to 50 unique Runtime IDs. A View must use exactly one of spaceId, runtimeId, or runId.

Choose capabilities

Each capability grants the View access to a surface. Omit a capability to use its default:

CapabilityDefaultWhat it enables
belltrueIn-View notification and action center
controltrueLive browser interaction and actions from the notification center
recordingstrueRuntime recordings
tracetrueRuntime traces
eventsfalseRuntime event history

Create a supervised View when a person should be able to act:

1const supervised = await bctrl.views.create({
2 scope: { runtimeId },
3 bell: true,
4 control: true,
5 recordings: false,
6 trace: true,
7 events: false,
8});

The legacy components object is accepted as a deprecated compatibility input, but new integrations should use the capability booleans above.

Hosted and embedded Views

Hosted Views open at the returned URL:

1const hosted = await bctrl.views.create({
2 scope: { runId },
3 presentation: { mode: "hosted" },
4});
5
6console.log(hosted.url);

Use an embedded View when you want to place the surface inside your own application. allowedOrigins must contain exact HTTPS origins. HTTP is allowed only for localhost development:

1const embedded = await bctrl.views.create({
2 scope: { runtimeId },
3 bell: false,
4 control: false,
5 recordings: true,
6 trace: true,
7 events: false,
8 presentation: {
9 mode: "embedded",
10 allowedOrigins: ["https://app.example.com"],
11 },
12});

The View token is returned only when the View is created. Treat it as a short-lived bearer credential: do not log it or expose it outside the intended viewer. Use expiresInSeconds to set a shorter lifetime. It defaults to 28,800 seconds (8 hours) and the maximum is 2,592,000 seconds (30 days).

Live and recording sessions

When you need a short-lived session URL for a live browser or a recording, use the token returned during creation:

1const session = await bctrl.views.createSession(
2 view.id,
3 { runId, surface: "live" },
4 view.token,
5);
6
7console.log(session.url, session.expiresAt);

surface is "live" or "recording". A recording can be unavailable when recording was disabled for the Run.

View fields

FieldTypeAlways presentDescription
idstringYesPublic View identifier.
scopeViewScopeYesSpace, Runtime, or Run the View can access.
componentsViewComponentsYesSurfaces enabled for this View.
presentationViewPresentationYesDelivery mode: hosted or embedded.
brandingResolvedBrandingYesAccount branding resolved for this View.
createdAtstringYesCreation timestamp.
expiresAtstringYesTime after which the View is no longer available.
urlstringNoReturned only in the create response.
tokenstringNoReturned only in the create response; short-lived bearer credential.

The response components field is the normalized, persisted capability map; it is not the shape used by the canonical create request. It can contain live, inputs, recordings, trace, and events entries.

Response componentShapeWhat it represents
live{ control: "none" | "input" }Live Runtime display and optional interaction
inputs{ respond: boolean }Visibility of Agent or Tool input requests and response actions
recordings{}Run recording playback
trace{}Structured Run trace
events{}Raw Run events

token and url are available on the create response. List and get return the View resource without the token.

Manage Views

1for await (const item of bctrl.views.iter()) {
2 console.log(item.id, item.expiresAt);
3}
4
5const current = await bctrl.views.get(view.id);
6await bctrl.views.delete(view.id); // revoke access immediately

Views expire automatically. Delete a View when the viewer should lose access before its expiration time.

View, Run, and Conversation

ResourceAnswers
ViewWhat can a person see or control?
RunWhat happened during one execution?
ConversationWhat has the user and Agent said?

Use Runs for durable observability and Conversations for persistent Agent interaction. Use a View when that information or control needs to be presented to a person.