GPUI Box GitHub

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()
}

Source: crates/gpui-kit/src/content/agent_document.rs