GPUI Box GitHub

Components / agent

ToolCall builder

One quiet evidence row for a tool invocation.

A builder is RenderOnce. Construct and mount it in one expression.

use gpui_kit::agent::ToolCall;

Reviewed in tool-call.

Construct
new(ident: impl Into<Ident>, family: ToolFamily, tool: impl Into<SharedString>) -> Self
Options

Chain onto the value.

summary(summary: impl Into<SharedString>) -> Self
arguments(arguments: impl Into<ToolBody>) -> Self
state(state: ToolCallState) -> Self
elapsed(elapsed: impl Into<Elapsed>) -> Self
diff(diff: impl IntoElement) -> Self
expanded(expanded: bool) -> Self
presentation(presentation: AgentDisclosurePresentation) -> Self
on_toggle(handler: impl Fn(bool, &mut Window, &mut App) + 'static) -> Self
on_retry(handler: impl Fn(&mut Window, &mut App) + 'static) -> Self
Example · tool-call
fn tool_call(_window: &mut Window, cx: &mut App) -> AnyElement {
    let theme = cx.theme().clone();
    div()
        .flex()
        .gap(px(theme.spacing.lg))
        .child(
            stack(&theme).w(px(460.0)).child(
            ToolCall::new("scene.tool.pending", ToolFamily::External, "mcp.dispatch")
                .summary("designer review")
                .arguments("{ \"target\": \"designer-review\" }")
                .state(ToolCallState::PendingApproval),
        )
        .child(
            ToolCall::new("scene.tool.running", ToolFamily::Network, "web.fetch")
                .summary("ampcode.com/manual")
                .arguments("{ \"url\": \"https://ampcode.com/manual\" }")
                .state(ToolCallState::Running)
                .elapsed("4.2 s"),
        )
        .child(
            ToolCall::new("scene.tool.succeeded", ToolFamily::Read, "workspace.read")
                .summary("README.md")
                .arguments("{ \"path\": \"README.md\" }")
                .state(ToolCallState::succeeded(
                    ToolBody::new(
                        "# GPUI Box\n\nProduct-neutral components.\n\nEvery word is replaceable.",
                    )
                    .max_lines(2),
                ))
                .expanded(true)
                .on_toggle(|_, _, _| {})
                .elapsed("0.3 s"),
        )
        .child(
            ToolCall::new("scene.tool.silent", ToolFamily::Edit, "workspace.touch")
                .summary("notes.md")
                .arguments("{ \"path\": \"notes.md\" }")
                .state(ToolCallState::succeeded_silently())
                .elapsed("0.1 s"),
        ),
        )
        .child(
            stack(&theme)
                .w(px(460.0))
                .child(
                    ToolCall::new("scene.tool.failed", ToolFamily::Edit, "workspace.write")
                        .summary("notes.md")
                        .arguments("{ \"path\": \"/read-only/notes.md\" }")
                        .state(ToolCallState::failed("Read only."))
                        .elapsed("0.2 s")
                        .on_retry(|_, _| {}),
                )
                // A refusal reads as a decision: it is not the failure above
                // it, and not the silent success in the other column.
                .child(
                    ToolCall::new("scene.tool.refused", ToolFamily::Shell, "shell.run")
                        .summary("rm -rf build")
                        .arguments("{ \"command\": \"rm -rf build\" }")
                        .state(ToolCallState::refused("Shell commands are not allowed.")),
                )
                .child(
                    ToolCall::new("scene.tool.flow", ToolFamily::Read, "workspace.read")
                        .summary("README.md · flow")
                        .arguments("{ \"path\": \"README.md\" }")
                        .state(ToolCallState::succeeded("Product-neutral components."))
                        .expanded(true)
                        .presentation(AgentDisclosurePresentation::Flow)
                        .on_toggle(|_, _, _| {}),
                ),
        )
        .into_any_element()
}

Source: crates/gpui-kit/src/agent/tool_call.rs