支持更多的权限请求格式
This commit is contained in:
@@ -9,6 +9,8 @@ import {
|
|||||||
ListTodo,
|
ListTodo,
|
||||||
Compass,
|
Compass,
|
||||||
FileText,
|
FileText,
|
||||||
|
Globe,
|
||||||
|
Search,
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { Badge } from "@/components/ui/badge"
|
import { Badge } from "@/components/ui/badge"
|
||||||
@@ -43,13 +45,15 @@ export function PermissionDialog({
|
|||||||
parsed.planEntries.length > 0 || Boolean(parsed.planExplanation)
|
parsed.planEntries.length > 0 || Boolean(parsed.planExplanation)
|
||||||
const hasPlanMarkdown = Boolean(parsed.planMarkdown)
|
const hasPlanMarkdown = Boolean(parsed.planMarkdown)
|
||||||
const hasAllowedPrompts = parsed.allowedPrompts.length > 0
|
const hasAllowedPrompts = parsed.allowedPrompts.length > 0
|
||||||
|
const hasWeb = Boolean(parsed.url) || Boolean(parsed.query)
|
||||||
const hasStructured =
|
const hasStructured =
|
||||||
Boolean(parsed.command) ||
|
Boolean(parsed.command) ||
|
||||||
hasFileChanges ||
|
hasFileChanges ||
|
||||||
hasPlan ||
|
hasPlan ||
|
||||||
hasPlanMarkdown ||
|
hasPlanMarkdown ||
|
||||||
hasAllowedPrompts ||
|
hasAllowedPrompts ||
|
||||||
Boolean(parsed.modeTarget)
|
Boolean(parsed.modeTarget) ||
|
||||||
|
hasWeb
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-4 mb-3 rounded-xl border border-border/70 bg-card/95 p-3 shadow-sm">
|
<div className="mx-4 mb-3 rounded-xl border border-border/70 bg-card/95 p-3 shadow-sm">
|
||||||
@@ -189,6 +193,32 @@ export function PermissionDialog({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{hasWeb && (
|
||||||
|
<div className="space-y-1.5 rounded-md border border-border/60 bg-muted/20 p-2">
|
||||||
|
{parsed.url && (
|
||||||
|
<div className="flex items-center gap-2 text-xs">
|
||||||
|
<Globe className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
|
||||||
|
<span className="break-all font-mono text-foreground/90">
|
||||||
|
{parsed.url}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{parsed.query && (
|
||||||
|
<div className="flex items-center gap-2 text-xs">
|
||||||
|
<Search className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
|
||||||
|
<span className="break-all text-foreground/90">
|
||||||
|
{parsed.query}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{parsed.prompt && (
|
||||||
|
<div className="mt-1 text-xs text-muted-foreground">
|
||||||
|
<MessageResponse>{parsed.prompt}</MessageResponse>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{!hasStructured && (
|
{!hasStructured && (
|
||||||
<pre className="rounded-md border border-border/60 bg-muted/20 p-2 text-xs whitespace-pre-wrap break-all text-foreground/90">
|
<pre className="rounded-md border border-border/60 bg-muted/20 p-2 text-xs whitespace-pre-wrap break-all text-foreground/90">
|
||||||
{parsed.jsonPreview}
|
{parsed.jsonPreview}
|
||||||
|
|||||||
@@ -242,7 +242,34 @@ function serializePermissionToolCall(toolCall: unknown): string | null {
|
|||||||
const record = asRecord(toolCall)
|
const record = asRecord(toolCall)
|
||||||
if (!record) return null
|
if (!record) return null
|
||||||
try {
|
try {
|
||||||
return JSON.stringify(record)
|
// Extract the actual tool input from the nested rawInput/raw_input field
|
||||||
|
// rather than serializing the entire permission wrapper (which includes
|
||||||
|
// internal fields like content, kind, title, toolCallId).
|
||||||
|
const nestedInput = record.rawInput ?? record.raw_input
|
||||||
|
if (nestedInput !== undefined && nestedInput !== null) {
|
||||||
|
if (typeof nestedInput === "string") return nestedInput
|
||||||
|
return JSON.stringify(nestedInput)
|
||||||
|
}
|
||||||
|
// Fallback: strip wrapper-only fields to avoid rendering internal
|
||||||
|
// permission structure as raw text.
|
||||||
|
const wrapperKeys = new Set([
|
||||||
|
"content",
|
||||||
|
"kind",
|
||||||
|
"title",
|
||||||
|
"toolCallId",
|
||||||
|
"tool_call_id",
|
||||||
|
"callId",
|
||||||
|
"call_id",
|
||||||
|
"rawInput",
|
||||||
|
"raw_input",
|
||||||
|
])
|
||||||
|
const rest: Record<string, unknown> = {}
|
||||||
|
for (const [k, v] of Object.entries(record)) {
|
||||||
|
if (!wrapperKeys.has(k)) rest[k] = v
|
||||||
|
}
|
||||||
|
return Object.keys(rest).length > 0
|
||||||
|
? JSON.stringify(rest)
|
||||||
|
: JSON.stringify(record)
|
||||||
} catch {
|
} catch {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ export interface ParsedPermissionToolCall {
|
|||||||
planMarkdown: string | null
|
planMarkdown: string | null
|
||||||
allowedPrompts: PermissionAllowedPrompt[]
|
allowedPrompts: PermissionAllowedPrompt[]
|
||||||
modeTarget: string | null
|
modeTarget: string | null
|
||||||
|
url: string | null
|
||||||
|
query: string | null
|
||||||
|
prompt: string | null
|
||||||
jsonPreview: string
|
jsonPreview: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,6 +678,13 @@ export function parsePermissionToolCall(
|
|||||||
"targetMode",
|
"targetMode",
|
||||||
]) ?? null
|
]) ?? null
|
||||||
|
|
||||||
|
const url =
|
||||||
|
pickString(rawInputObj, ["url"]) ?? pickString(toolCallObj, ["url"])
|
||||||
|
const query =
|
||||||
|
pickString(rawInputObj, ["query"]) ?? pickString(toolCallObj, ["query"])
|
||||||
|
const prompt =
|
||||||
|
pickString(rawInputObj, ["prompt"]) ?? pickString(toolCallObj, ["prompt"])
|
||||||
|
|
||||||
const title =
|
const title =
|
||||||
pickString(toolCallObj, ["title", "tool_name", "toolName", "name"]) ??
|
pickString(toolCallObj, ["title", "tool_name", "toolName", "name"]) ??
|
||||||
formatFallbackTitle(normalizedKind)
|
formatFallbackTitle(normalizedKind)
|
||||||
@@ -693,6 +703,9 @@ export function parsePermissionToolCall(
|
|||||||
planMarkdown,
|
planMarkdown,
|
||||||
allowedPrompts,
|
allowedPrompts,
|
||||||
modeTarget,
|
modeTarget,
|
||||||
|
url,
|
||||||
|
query,
|
||||||
|
prompt,
|
||||||
jsonPreview: stringifyJson(toolCallObj ?? toolCall),
|
jsonPreview: stringifyJson(toolCallObj ?? toolCall),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user