Components / content
AgentDocument builder
A read-only sequence of typed agent output blocks.
A builder is RenderOnce. Construct and mount it in one expression.
use gpui_kit::content::AgentDocument;
Reviewed in agent-document.
Construct
remeasure_block(ident: &Ident, block: &str, window: &mut Window, cx: &mut App)
work(ident: &Ident, window: &Window, cx: &mut App) -> AgentDocumentWork
new(ident: impl Into<Ident>) -> Self
Options
Chain onto the value.
configure_markdown(configure: impl Fn(&SharedString, Markdown) -> Markdown + 'static) -> Self
virtualized(rows: usize) -> Self
state(state: AgentDocumentState) -> Self
block(block: AgentDocumentBlock) -> Self
blocks(blocks: impl IntoIterator<Item = AgentDocumentBlock>) -> Self
on_event(handler: impl Fn(&AgentDocumentEvent, &mut Window, &mut App) + 'static) -> Self
Queries
Only answer; they change nothing.
duplicate_ids() -> Vec<SharedString>
Reports
The variants of the event it emits. It never applies the change itself.
- Markdown
Example · agent-document
fn agent_document(_window: &mut Window, cx: &mut App) -> AnyElement {
let theme = cx.theme().clone();
stack(&theme)
.w(px(680.0))
.child(
AgentDocument::new("scene.agent-document")
.block(
AgentDocumentBlock::markdown(
"summary",
"## Review complete\n\nThe run kept its **verified result** while the refresh failed.",
)
.revision(3),
)
.block(
AgentDocumentBlock::code("patch", |_, _| {
CodeView::from_text(
"scene.agent-document.patch",
"pub fn bounded_retry(attempt: usize) -> bool {\n attempt < 3\n}",
)
.language("rust")
.into_any_element()
})
.label("Proposed code")
.revision(2),
)
.block(
AgentDocumentBlock::tool_call("verification", |_, _| {
ToolCall::new(
"scene.agent-document.tool",
ToolFamily::Shell,
"cargo test",
)
.summary("-p gpui-box-kit")
.state(ToolCallState::Succeeded {
output: ToolOutput::Silent,
})
.elapsed("1.4 s")
.into_any_element()
})
.revision(1),
)
.block(AgentDocumentBlock::notice(
"refresh",
"The last refresh failed; the result above is the last verified value.",
Tone::Warning,
)),
)
.child(
Divider::new()
.id("scene.agent-document.long")
.label("The same document, virtualized"),
)
// A paragraph rather than a caption. At the caption step this ran the
// full width of the document immediately above the body text it
// introduces, so the sentence explaining what to look at was set
// smaller and fainter than everything it was explaining.
.child(
crate::foundation::text(
&theme,
TypeScale::Body,
"a conversation that has been running all day: only the blocks on \
screen are built and laid out, and the ones above are still there. \
A long answer is drawn as a row per block of its own, so a token \
arriving in its last paragraph relays out that paragraph",
)
.text_tone(&theme, TextTone::Muted),
)
.child(
AgentDocument::new("scene.agent-thread")
.virtualized(5)
.block(
AgentDocumentBlock::markdown(
"answer",
"**The answer.** It kept the verified result, and the run \
below says why.\n\n\
- the refresh failed\n- the last verified value stands\n\n\
Nothing after that point was rewritten.",
)
.revision(1),
)
.blocks((0..120).map(|turn| {
AgentDocumentBlock::markdown(
format!("turn-{turn:03}"),
format!(
"**Turn {turn}.** The run kept its verified result while the \
refresh failed, and the answer below says why."
),
)
.revision(turn as u64)
})),
)
.child(
Divider::new()
.id("scene.agent-document.rule")
.label("Document states"),
)
.child(
div()
.row_reading(cx.layout_direction())
.gap_token(&theme, Space::Lg)
.child(
div().flex_1().child(
AgentDocument::new("scene.agent-document.empty")
.state(AgentDocumentState::Empty("No results were returned.".into())),
),
)
.child(
div().flex_1().child(
AgentDocument::new("scene.agent-document.unavailable").state(
AgentDocumentState::Unavailable(
"The host refused to provide this document.".into(),
),
),
),
),
)
.into_any_element()
}