normalize tool display; remove backticks (#1482)
This commit is contained in:
committed by
GitHub
parent
d0392e6d5e
commit
84d80659b3
1
.gitignore
vendored
1
.gitignore
vendored
@@ -69,6 +69,7 @@ crates/executors/bindings
|
||||
crates/utils/bindings
|
||||
crates/services/bindings
|
||||
crates/server/bindings
|
||||
crates/remote/bindings
|
||||
|
||||
build-npm-package-codesign.sh
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ use agent_client_protocol::{self as acp, SessionNotification};
|
||||
use futures::StreamExt;
|
||||
use regex::Regex;
|
||||
use serde::Deserialize;
|
||||
use tracing::{debug, trace};
|
||||
use workspace_utils::msg_store::MsgStore;
|
||||
|
||||
pub use super::AcpAgentHarness;
|
||||
@@ -38,7 +37,7 @@ pub fn normalize_logs(msg_store: Arc<MsgStore>, worktree_path: &Path) {
|
||||
let mut stdout_lines = msg_store.stdout_lines_stream();
|
||||
while let Some(Ok(line)) = stdout_lines.next().await {
|
||||
if let Some(parsed) = AcpEventParser::parse_line(&line) {
|
||||
trace!("Parsed ACP line: {:?}", parsed);
|
||||
tracing::trace!("Parsed ACP line: {:?}", parsed);
|
||||
match parsed {
|
||||
AcpEvent::SessionStart(id) => {
|
||||
if !stored_session_id {
|
||||
@@ -207,7 +206,7 @@ pub fn normalize_logs(msg_store: Arc<MsgStore>, worktree_path: &Path) {
|
||||
.map(|s| s.title.clone())
|
||||
.or_else(|| Some("".to_string()));
|
||||
}
|
||||
trace!("Got tool call update: {:?}", update);
|
||||
tracing::trace!("Got tool call update: {:?}", update);
|
||||
if let Ok(tc) = agent_client_protocol::ToolCall::try_from(update.clone()) {
|
||||
handle_tool_call(
|
||||
&tc,
|
||||
@@ -218,7 +217,7 @@ pub fn normalize_logs(msg_store: Arc<MsgStore>, worktree_path: &Path) {
|
||||
&msg_store,
|
||||
);
|
||||
} else {
|
||||
debug!("Failed to convert tool call update to ToolCall");
|
||||
tracing::debug!("Failed to convert tool call update to ToolCall");
|
||||
}
|
||||
}
|
||||
AcpEvent::User(_) | AcpEvent::Other(_) => (),
|
||||
@@ -303,9 +302,10 @@ pub fn normalize_logs(msg_store: Arc<MsgStore>, worktree_path: &Path) {
|
||||
// Prefer structured raw_output, else fallback to aggregated text content
|
||||
let completed =
|
||||
matches!(tc.status, agent_client_protocol::ToolCallStatus::Completed);
|
||||
trace!(
|
||||
tracing::trace!(
|
||||
"Mapping execute tool call, completed: {}, command: {}",
|
||||
completed, command
|
||||
completed,
|
||||
command
|
||||
);
|
||||
let tc_exit_status = match tc.status {
|
||||
agent_client_protocol::ToolCallStatus::Completed => {
|
||||
@@ -617,7 +617,7 @@ impl AcpEventParser {
|
||||
return Some(acp_event);
|
||||
}
|
||||
|
||||
debug!("Failed to parse ACP raw log {trimmed}");
|
||||
tracing::debug!("Failed to parse ACP raw log {trimmed}");
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
@@ -1196,11 +1196,11 @@ impl ClaudeLogProcessor {
|
||||
worktree_path: &str,
|
||||
) -> String {
|
||||
match action_type {
|
||||
ActionType::FileRead { path } => format!("`{path}`"),
|
||||
ActionType::FileEdit { path, .. } => format!("`{path}`"),
|
||||
ActionType::CommandRun { command, .. } => format!("`{command}`"),
|
||||
ActionType::Search { query } => format!("`{query}`"),
|
||||
ActionType::WebFetch { url } => format!("`{url}`"),
|
||||
ActionType::FileRead { path } => path.to_string(),
|
||||
ActionType::FileEdit { path, .. } => path.to_string(),
|
||||
ActionType::CommandRun { command, .. } => command.to_string(),
|
||||
ActionType::Search { query } => query.to_string(),
|
||||
ActionType::WebFetch { url } => url.to_string(),
|
||||
ActionType::TaskCreate { description } => {
|
||||
if description.is_empty() {
|
||||
"Task".to_string()
|
||||
@@ -1232,13 +1232,13 @@ impl ClaudeLogProcessor {
|
||||
if relative_path.is_empty() {
|
||||
"List directory".to_string()
|
||||
} else {
|
||||
format!("List directory: `{relative_path}`")
|
||||
format!("List directory: {relative_path}")
|
||||
}
|
||||
}
|
||||
ClaudeToolData::Glob { pattern, path, .. } => {
|
||||
if let Some(search_path) = path {
|
||||
format!(
|
||||
"Find files: `{}` in `{}`",
|
||||
"Find files: `{}` in {}",
|
||||
pattern,
|
||||
make_path_relative(search_path, worktree_path)
|
||||
)
|
||||
@@ -1257,7 +1257,7 @@ impl ClaudeLogProcessor {
|
||||
ClaudeToolData::CodebaseSearchAgent { query, path, .. } => {
|
||||
match (query.as_ref(), path.as_ref()) {
|
||||
(Some(q), Some(p)) if !q.is_empty() && !p.is_empty() => format!(
|
||||
"Codebase search: `{}` in `{}`",
|
||||
"Codebase search: `{}` in {}",
|
||||
q,
|
||||
make_path_relative(p, worktree_path)
|
||||
),
|
||||
@@ -1948,7 +1948,7 @@ mod tests {
|
||||
"/tmp/test-worktree",
|
||||
);
|
||||
|
||||
assert_eq!(result, "`**/*.ts`");
|
||||
assert_eq!(result, "**/*.ts");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1967,7 +1967,7 @@ mod tests {
|
||||
"/tmp/test-worktree",
|
||||
);
|
||||
|
||||
assert_eq!(result, "`*.js`");
|
||||
assert_eq!(result, "*.js");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1984,7 +1984,7 @@ mod tests {
|
||||
"/tmp/test-worktree",
|
||||
);
|
||||
|
||||
assert_eq!(result, "List directory: `components`");
|
||||
assert_eq!(result, "List directory: components");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2190,8 +2190,8 @@ mod tests {
|
||||
let parsed: ClaudeJson = serde_json::from_str(bash_json).unwrap();
|
||||
let entries = normalize(&parsed, "/tmp/work");
|
||||
assert_eq!(entries.len(), 1);
|
||||
// Content should display the command in backticks
|
||||
assert_eq!(entries[0].content, "`echo hello`");
|
||||
// Content should display the command
|
||||
assert_eq!(entries[0].content, "echo hello");
|
||||
|
||||
// Task content should include description/prompt wrapped in backticks
|
||||
let task_json = r#"{
|
||||
|
||||
@@ -82,7 +82,7 @@ struct CommandState {
|
||||
|
||||
impl ToNormalizedEntry for CommandState {
|
||||
fn to_normalized_entry(&self) -> NormalizedEntry {
|
||||
let content = format!("`{}`", self.command);
|
||||
let content = self.command.to_string();
|
||||
|
||||
NormalizedEntry {
|
||||
timestamp: None,
|
||||
@@ -894,7 +894,7 @@ pub fn normalize_logs(msg_store: Arc<MsgStore>, worktree_path: &Path) {
|
||||
},
|
||||
status: ToolStatus::Success,
|
||||
},
|
||||
content: format!("`{relative_path}`"),
|
||||
content: relative_path.to_string(),
|
||||
metadata: None,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -717,10 +717,7 @@ impl CursorToolCall {
|
||||
match self {
|
||||
CursorToolCall::Read { args, .. } => {
|
||||
let path = make_path_relative(&args.path, worktree_path);
|
||||
(
|
||||
ActionType::FileRead { path: path.clone() },
|
||||
format!("`{path}`"),
|
||||
)
|
||||
(ActionType::FileRead { path: path.clone() }, path)
|
||||
}
|
||||
CursorToolCall::Write { args, .. } => {
|
||||
let path = make_path_relative(&args.path, worktree_path);
|
||||
@@ -729,7 +726,7 @@ impl CursorToolCall {
|
||||
path: path.clone(),
|
||||
changes: vec![],
|
||||
},
|
||||
format!("`{path}`"),
|
||||
path,
|
||||
)
|
||||
}
|
||||
CursorToolCall::Edit { args, result, .. } => {
|
||||
@@ -789,7 +786,7 @@ impl CursorToolCall {
|
||||
path: path.clone(),
|
||||
changes,
|
||||
},
|
||||
format!("`{path}`"),
|
||||
path,
|
||||
)
|
||||
}
|
||||
CursorToolCall::Delete { args, .. } => {
|
||||
@@ -799,7 +796,7 @@ impl CursorToolCall {
|
||||
path: path.clone(),
|
||||
changes: vec![FileChange::Delete],
|
||||
},
|
||||
format!("`{path}`"),
|
||||
path.to_string(),
|
||||
)
|
||||
}
|
||||
CursorToolCall::Shell { args, .. } => {
|
||||
@@ -809,7 +806,7 @@ impl CursorToolCall {
|
||||
command: cmd.clone(),
|
||||
result: None,
|
||||
},
|
||||
format!("`{cmd}`"),
|
||||
cmd.to_string(),
|
||||
)
|
||||
}
|
||||
CursorToolCall::Grep { args, .. } => {
|
||||
@@ -818,7 +815,7 @@ impl CursorToolCall {
|
||||
ActionType::Search {
|
||||
query: pattern.clone(),
|
||||
},
|
||||
format!("`{pattern}`"),
|
||||
pattern.to_string(),
|
||||
)
|
||||
}
|
||||
CursorToolCall::SemSearch { args, .. } => {
|
||||
@@ -827,7 +824,7 @@ impl CursorToolCall {
|
||||
ActionType::Search {
|
||||
query: query.clone(),
|
||||
},
|
||||
format!("`{query}`"),
|
||||
query.to_string(),
|
||||
)
|
||||
}
|
||||
CursorToolCall::Glob { args, .. } => {
|
||||
@@ -838,7 +835,7 @@ impl CursorToolCall {
|
||||
ActionType::Search {
|
||||
query: pattern.clone(),
|
||||
},
|
||||
format!("Find files: `{pattern}` in `{path}`"),
|
||||
format!("Find files: `{pattern}` in {path}"),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
@@ -854,7 +851,7 @@ impl CursorToolCall {
|
||||
let content = if path.is_empty() {
|
||||
"List directory".to_string()
|
||||
} else {
|
||||
format!("List directory: `{path}`")
|
||||
format!("List directory: {path}")
|
||||
};
|
||||
(
|
||||
ActionType::Other {
|
||||
|
||||
@@ -1026,7 +1026,7 @@ impl ToNormalizedEntry for FileReadState {
|
||||
},
|
||||
status: self.status.clone(),
|
||||
},
|
||||
content: format!("`{}`", self.path),
|
||||
content: self.path.clone(),
|
||||
metadata: None,
|
||||
}
|
||||
}
|
||||
@@ -1052,7 +1052,7 @@ impl ToNormalizedEntry for FileEditState {
|
||||
},
|
||||
status: self.status.clone(),
|
||||
},
|
||||
content: format!("`{}`", self.path),
|
||||
content: self.path.clone(),
|
||||
metadata: None,
|
||||
}
|
||||
}
|
||||
@@ -1094,7 +1094,7 @@ impl ToNormalizedEntry for CommandRunState {
|
||||
},
|
||||
status: self.status.clone(),
|
||||
},
|
||||
content: format!("`{}`", self.command),
|
||||
content: self.command.clone(),
|
||||
metadata: None,
|
||||
}
|
||||
}
|
||||
@@ -1149,7 +1149,7 @@ impl ToNormalizedEntry for SearchState {
|
||||
},
|
||||
status: self.status.clone(),
|
||||
},
|
||||
content: format!("`{}`", self.query),
|
||||
content: self.query.clone(),
|
||||
metadata: None,
|
||||
}
|
||||
}
|
||||
@@ -1173,7 +1173,7 @@ impl ToNormalizedEntry for WebFetchState {
|
||||
},
|
||||
status: self.status.clone(),
|
||||
},
|
||||
content: format!("`{}`", self.url),
|
||||
content: self.url.clone(),
|
||||
metadata: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ export default function DiffCard({
|
||||
// Title row
|
||||
const title = (
|
||||
<p
|
||||
className="text-xs font-mono overflow-x-auto flex-1"
|
||||
className="text-sm font-mono overflow-x-auto flex-1"
|
||||
style={{ color: 'hsl(var(--muted-foreground) / 0.7)' }}
|
||||
>
|
||||
<Icon className="h-3 w-3 inline mr-2" aria-hidden />
|
||||
|
||||
@@ -516,9 +516,9 @@ const ToolCallCard: React.FC<{
|
||||
{entryType && getEntryIcon(entryType)}
|
||||
</span>
|
||||
{showInlineSummary ? (
|
||||
<span className="font-light">{inlineText}</span>
|
||||
<span className="text-sm font-mono">{inlineText}</span>
|
||||
) : (
|
||||
<span className="font-normal">{label}</span>
|
||||
<span className="text-sm font-mono">{label}</span>
|
||||
)}
|
||||
</span>
|
||||
</HeaderWrapper>
|
||||
|
||||
@@ -136,7 +136,7 @@ const FileChangeRenderer = ({
|
||||
{icon}
|
||||
<p
|
||||
onClick={() => expandable && setExpanded()}
|
||||
className="text-sm font-light overflow-x-auto flex-1 cursor-pointer"
|
||||
className="text-sm font-mono overflow-x-auto flex-1 cursor-pointer"
|
||||
>
|
||||
{titleNode}
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user