Components / agent
AgentRunCanvas builder
A typed, read-mostly view of an AgentRunSnapshot on a node canvas.
A builder is RenderOnce. Construct and mount it in one expression.
use gpui_kit::agent::AgentRunCanvas;
Reviewed in agent-run-canvas.
Construct
new(ident: impl Into<Ident>, run: AgentRunSnapshot) -> Self
Options
Chain onto the value.
layout(layout: AgentRunLayout) -> Self
position(subject: RunSubjectId, x: f32, y: f32) -> Self
selected(selected: impl IntoIterator<Item = RunSubjectId>) -> Self
viewport(viewport: GraphViewport) -> Self
arrangeable(arrangeable: bool) -> Self
on_event(handler: impl Fn(&AgentRunCanvasEvent, &mut Window, &mut App) + 'static) -> Self
Reports
The variants of the event it emits. It never applies the change itself.
- SelectionChanged
- ViewportChanged
- PositionChanged
Example · agent-run-canvas
fn agent_run_canvas(_window: &mut Window, cx: &mut App) -> AnyElement {
let theme = cx.theme().clone();
let run = AgentRunSnapshot::new("release-topology", "orchestrator")
.execution(AgentExecutionState::Active(AgentActivity::Aggregating))
.agents([
AgentSnapshot::new(
AgentDescriptor::new("orchestrator", "Atlas").role("Run coordinator"),
)
.execution(AgentExecutionState::Active(AgentActivity::Aggregating)),
AgentSnapshot::new(
AgentDescriptor::new("researcher", "Nova").role("Repository research"),
)
.execution(AgentExecutionState::Active(AgentActivity::UsingTool(
"repository search".into(),
))),
AgentSnapshot::new(AgentDescriptor::new("reviewer", "Sage").role("Independent review"))
.execution(AgentExecutionState::Waiting(WaitReason::Approval)),
])
.tasks([
AgentTaskSnapshot::new("evidence", "Evidence bundle")
.execution(AgentExecutionState::Completed(AgentOutcome::Succeeded)),
AgentTaskSnapshot::new("synthesis", "Release synthesis").execution(
AgentExecutionState::Completed(AgentOutcome::Partial("awaiting approval".into())),
),
])
.links([
RunLink::new(
"spawn-researcher",
RunSubjectId::Agent("orchestrator".into()),
RunSubjectId::Agent("researcher".into()),
RunLinkKind::Spawn,
),
RunLink::new(
"delegate-evidence",
RunSubjectId::Agent("orchestrator".into()),
RunSubjectId::Task("evidence".into()),
RunLinkKind::Delegation,
),
RunLink::new(
"evidence-before-synthesis",
RunSubjectId::Task("evidence".into()),
RunSubjectId::Task("synthesis".into()),
RunLinkKind::Dependency,
),
RunLink::new(
"handoff-review",
RunSubjectId::Agent("researcher".into()),
RunSubjectId::Agent("reviewer".into()),
RunLinkKind::Handoff,
),
RunLink::new(
"search-report",
RunSubjectId::Invocation("search-42".into()),
RunSubjectId::Agent("researcher".into()),
RunLinkKind::Report,
),
RunLink::new(
"aggregate-review",
RunSubjectId::Agent("reviewer".into()),
RunSubjectId::Task("synthesis".into()),
RunLinkKind::Aggregation,
),
RunLink::new(
"retry-search",
RunSubjectId::Agent("reviewer".into()),
RunSubjectId::Agent("researcher".into()),
RunLinkKind::Retry,
)
.label("bounded attempt 2"),
])
.aggregation(AggregationSnapshot::new(3, 2).conflicts(1));
// Laid out down the frame rather than across it, and drawn at 1:1. Four
// node columns and the relationship wording between them are wider than
// any frame this is reviewed in, and the zoom that made them fit put the
// node bodies and the edge labels below the size at which they are text
// at all: the picture said the canvas was empty and its nodes unreadable,
// which is a claim about the component that was not true.
stack(&theme)
.w(px(920.0))
.child(
div()
.w_full()
.h(px(830.0))
.surface(&theme, Surface::Panel)
.radius(&theme, Radius::Card)
.overflow_hidden()
.child(
AgentRunCanvas::new("scene.agent-run-canvas", run)
.layout(AgentRunLayout::LayeredVertical)
.selected([RunSubjectId::Agent("researcher".into())])
// Panned far enough right for the retry loop, which
// routes around the outside of the column it returns
// to, to bring its own wording with it.
.viewport(GraphViewport::new(gpui::point(80.0, 0.0), 1.0))
.on_event(|_, _, _| {}),
),
)
.into_any_element()
}