tool card UI redesign: semantic icons, inline diff persistence, tool detail page, MCP-friendly titles
Nightly Build / build (push) Successful in 6m38s
Nightly Build / build (push) Successful in 6m38s
This commit is contained in:
@@ -43,6 +43,12 @@ pub enum ServerEvent {
|
||||
message_id: i64,
|
||||
name: String,
|
||||
arguments: Value,
|
||||
/// Friendly, static card title ("Edit File", "Read File", or an MCP tool's
|
||||
/// resolved friendly name). Separate from `name` (the raw LLM function id).
|
||||
display_name: String,
|
||||
/// Semantic icon key (`edit`/`read`/`shell`/`mcp`/…) the frontend maps to a
|
||||
/// glyph + accent color. Never a glyph — the core commits to meaning, not look.
|
||||
icon: String,
|
||||
/// Concise human-readable label (≤60 chars): tool + primary argument.
|
||||
label_short: String,
|
||||
/// Verbose human-readable label (≤120 chars): tool + all meaningful arguments.
|
||||
@@ -62,6 +68,13 @@ pub enum ServerEvent {
|
||||
/// server; the frontend treats an absent/unknown value as plain text, so
|
||||
/// older clients degrade gracefully.
|
||||
result_type: String,
|
||||
/// For a file-write tool: the file content before/after the write, so the
|
||||
/// card renders the diff inline even for an auto-allowed write (one that
|
||||
/// never emitted a `PendingWrite`). Absent for non-write tools.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
preview_old: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
preview_new: Option<String>,
|
||||
},
|
||||
/// A tool call failed. DB status: error.
|
||||
ToolError {
|
||||
|
||||
@@ -72,6 +72,30 @@ pub trait Tool: Send + Sync {
|
||||
self.name().to_string()
|
||||
}
|
||||
|
||||
/// Friendly, **static** display name for this tool ("Edit File", "Read File"),
|
||||
/// shown as the card title in the chat UI — separate from [`name`](Self::name),
|
||||
/// which stays the raw LLM function id. Several tools map to the same friendly
|
||||
/// verb (e.g. `write_file`/`edit_file`/`insert_at_line` → "Edit File"). The
|
||||
/// default returns the raw name so unmapped tools still render something.
|
||||
fn display_name(&self) -> &str {
|
||||
self.name()
|
||||
}
|
||||
|
||||
/// Semantic icon key for the chat card — **not** a glyph. The frontend maps the
|
||||
/// key to a concrete icon + accent color (themeable), so the core commits to a
|
||||
/// meaning, never a look. Known keys: `edit`, `read`, `list`, `search`, `shell`,
|
||||
/// `subagent`, `image`, `config`, `introspection`. The default derives from
|
||||
/// [`category`](Self::category).
|
||||
fn icon(&self) -> &str {
|
||||
match self.category() {
|
||||
ToolCategory::Filesystem => "file",
|
||||
ToolCategory::Shell => "shell",
|
||||
ToolCategory::Subagent => "subagent",
|
||||
ToolCategory::Introspection => "introspection",
|
||||
ToolCategory::Config => "config",
|
||||
}
|
||||
}
|
||||
|
||||
/// If this invocation targets a single file the user can open in the file
|
||||
/// viewer, return its path (relative to the project root, or absolute).
|
||||
/// Tools that target a directory (list/grep) or no file at all return
|
||||
|
||||
Reference in New Issue
Block a user