fix(multi-edit): pass structuredPatch to update UI; harden FileEditToolUpdatedMessage against undefined patches\n\n- MultiEditTool: compute diff via getPatch and render standard update message\n- FileEditToolUpdatedMessage: treat missing structuredPatch as empty to avoid crash\n- Preserves existing feature and UI while eliminating reduce-on-undefined

This commit is contained in:
CrazyBoyM 2025-09-10 15:33:58 +08:00
parent a7af9834ef
commit b0d9f58d76
2 changed files with 34 additions and 17 deletions

View File

@ -10,7 +10,7 @@ import { useTerminalSize } from '../hooks/useTerminalSize'
type Props = {
filePath: string
structuredPatch: Hunk[]
structuredPatch?: Hunk[]
verbose: boolean
}
@ -20,11 +20,12 @@ export function FileEditToolUpdatedMessage({
verbose,
}: Props): React.ReactNode {
const { columns } = useTerminalSize()
const numAdditions = structuredPatch.reduce(
const patches = Array.isArray(structuredPatch) ? structuredPatch : []
const numAdditions = patches.reduce(
(count, hunk) => count + hunk.lines.filter(_ => _.startsWith('+')).length,
0,
)
const numRemovals = structuredPatch.reduce(
const numRemovals = patches.reduce(
(count, hunk) => count + hunk.lines.filter(_ => _.startsWith('-')).length,
0,
)
@ -49,18 +50,19 @@ export function FileEditToolUpdatedMessage({
</>
) : null}
</Text>
{intersperse(
structuredPatch.map(_ => (
<Box flexDirection="column" paddingLeft={5} key={_.newStart}>
<StructuredDiff patch={_} dim={false} width={columns - 12} />
</Box>
)),
i => (
<Box paddingLeft={5} key={`ellipsis-${i}`}>
<Text color={getTheme().secondaryText}>...</Text>
</Box>
),
)}
{patches.length > 0 &&
intersperse(
patches.map(_ => (
<Box flexDirection="column" paddingLeft={5} key={_.newStart}>
<StructuredDiff patch={_} dim={false} width={columns - 12} />
</Box>
)),
i => (
<Box paddingLeft={5} key={`ellipsis-${i}`}>
<Text color={getTheme().secondaryText}>...</Text>
</Box>
),
)}
</Box>
)
}

View File

@ -46,6 +46,7 @@ import { PROJECT_FILE } from '../../constants/product'
import { DESCRIPTION, PROMPT } from './prompt'
import { emitReminderEvent } from '../../services/systemReminder'
import { recordFileEdit } from '../../services/fileFreshness'
import { getPatch } from '../../utils/diff'
const EditSchema = z.object({
old_string: z.string().describe('The text to replace'),
@ -136,7 +137,13 @@ export const MultiEditTool = {
)
}
return <FileEditToolUpdatedMessage {...output} />
return (
<FileEditToolUpdatedMessage
filePath={output.filePath}
structuredPatch={output.structuredPatch}
verbose={false}
/>
)
},
async validateInput(
{ file_path, edits }: z.infer<typeof inputSchema>,
@ -350,12 +357,20 @@ export const MultiEditTool = {
const relativePath = relative(workingDir, filePath)
const summary = `Successfully applied ${edits.length} edits to ${relativePath}`
const structuredPatch = getPatch({
filePath: file_path,
fileContents: currentContent,
oldStr: currentContent,
newStr: modifiedContent,
})
const resultData = {
filePath: relativePath,
filePath: file_path,
wasNewFile: !fileExists,
editsApplied: appliedEdits,
totalEdits: edits.length,
summary,
structuredPatch,
}
// Log the operation