优化agent请求文件修改权限时的文件差异显示样式

This commit is contained in:
xintaofei
2026-03-28 18:10:20 +08:00
parent 622d8c90bd
commit a049db51e2
3 changed files with 45 additions and 36 deletions

View File

@@ -514,10 +514,11 @@ async fn run_connection(
let conn_id = conn_id.clone();
let handle = handle.clone();
let perms = perms.clone();
let perm_cwd = cwd_string.clone();
async move |req: RequestPermissionRequest,
responder: Responder<RequestPermissionResponse>,
_cx: ConnectionTo<Agent>| {
handle_permission_request(&conn_id, &handle, &perms, req, responder).await;
handle_permission_request(&conn_id, &handle, &perms, &perm_cwd, req, responder).await;
Ok(())
}
},
@@ -861,6 +862,7 @@ async fn handle_permission_request(
conn_id: &str,
handle: &tauri::AppHandle,
perms: &PendingPermissions,
cwd: &str,
req: RequestPermissionRequest,
responder: Responder<RequestPermissionResponse>,
) {
@@ -882,7 +884,36 @@ async fn handle_permission_request(
})
.collect();
let tool_call_value = serde_json::to_value(&req.tool_call).unwrap_or_default();
let mut tool_call_value = serde_json::to_value(&req.tool_call).unwrap_or_default();
// Resolve line numbers in rawInput for edit tool permission requests
if let Some(obj) = tool_call_value.as_object_mut() {
let raw_input_key = if obj.contains_key("rawInput") {
Some("rawInput")
} else if obj.contains_key("raw_input") {
Some("raw_input")
} else {
None
};
if let Some(key) = raw_input_key {
if let Some(input_val) = obj.get(key).cloned() {
let input_text = match &input_val {
serde_json::Value::String(s) => Some(s.clone()),
v if !v.is_null() => Some(v.to_string()),
_ => None,
};
if let Some(text) = input_text {
let resolved = resolve_live_tool_input(&text, Some(cwd));
if resolved != text {
obj.insert(
key.to_string(),
serde_json::Value::String(resolved),
);
}
}
}
}
}
perms.lock().await.insert(request_id.clone(), responder);

View File

@@ -5,7 +5,6 @@ import { useTranslations } from "next-intl"
import {
ShieldAlert,
Terminal,
FilePenLine,
ListTodo,
Compass,
FileText,
@@ -15,6 +14,7 @@ import {
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { CodeBlock } from "@/components/ai-elements/code-block"
import { UnifiedDiffPreview } from "@/components/diff/unified-diff-preview"
import { MessageResponse } from "@/components/ai-elements/message"
import type { PendingPermission } from "@/contexts/acp-connections-context"
import { parsePermissionToolCall } from "@/lib/permission-request"
@@ -86,38 +86,8 @@ export function PermissionDialog({
</div>
)}
{hasFileChanges && (
<div className="space-y-1.5 rounded-md border border-border/60 bg-muted/20 p-2">
<div className="flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
<FilePenLine className="h-3.5 w-3.5" />
<span>
{t("filesSummary", { count: parsed.fileChanges.length })}
</span>
{(parsed.additions > 0 || parsed.deletions > 0) && (
<span>
+{parsed.additions} / -{parsed.deletions}
</span>
)}
</div>
<div className="space-y-1 rounded-md bg-muted/40 p-2">
{parsed.fileChanges.slice(0, 8).map((change, index) => (
<div
key={`${change.path}-${index}`}
className="break-all font-mono text-xs text-foreground/90"
>
{change.path}
</div>
))}
{parsed.fileChanges.length > 8 && (
<div className="text-xs text-muted-foreground">
{t("moreFiles", { count: parsed.fileChanges.length - 8 })}
</div>
)}
</div>
{parsed.diffPreview && (
<CodeBlock code={parsed.diffPreview} language="diff" />
)}
</div>
{hasFileChanges && parsed.diffPreview && (
<UnifiedDiffPreview diffText={parsed.diffPreview} />
)}
{hasPlan && (

View File

@@ -145,7 +145,15 @@ function buildCompactDiffFromTexts(
Math.min(oldLines.length, oldLines.length - suffix + contextLines)
)
const parts: string[] = [`--- ${path}`, `+++ ${path}`]
const oldStart = Math.max(1, prefix - before.length + 1)
const oldCount = before.length + removed.length + after.length
const newCount = before.length + added.length + after.length
const parts: string[] = [
`--- ${path}`,
`+++ ${path}`,
`@@ -${oldStart},${oldCount} +${oldStart},${newCount} @@`,
]
for (const line of before) parts.push(` ${line}`)
for (const line of removed) parts.push(`-${line}`)
for (const line of added) parts.push(`+${line}`)