Skip to content

Commit dfb07a7

Browse files
committed
fix(files): keep replacement content literal
1 parent b2764fb commit dfb07a7

5 files changed

Lines changed: 26 additions & 9 deletions

File tree

apps/sim/lib/copilot/tools/server/files/edit-content.test.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ describe('edit_content', () => {
154154
)
155155
})
156156

157-
it('honors replaceAll for exact patch intent', async () => {
157+
it('honors replaceAll with literal replacement content for exact patch intent', async () => {
158158
waitForLatestFileIntentMock.mockResolvedValue({
159159
operation: 'patch',
160160
fileId: 'text-1',
@@ -168,13 +168,11 @@ describe('edit_content', () => {
168168
createdAt: Date.now(),
169169
})
170170

171-
await expect(editContentServerTool.execute({ content: 'new' }, context)).resolves.toMatchObject(
172-
{
173-
success: true,
174-
}
175-
)
171+
await expect(editContentServerTool.execute({ content: '$&' }, context)).resolves.toMatchObject({
172+
success: true,
173+
})
176174
expect(compileDocForWriteMock).toHaveBeenCalledWith(
177-
expect.objectContaining({ source: 'new new' })
175+
expect.objectContaining({ source: '$& $&' })
178176
)
179177
})
180178
})

apps/sim/lib/copilot/tools/server/files/file-preview.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,19 @@ describe('buildFilePreviewText', () => {
9999
})
100100
).toBe('hello sim')
101101
})
102+
103+
it('treats replaceAll preview content as literal text', () => {
104+
expect(
105+
buildFilePreviewText({
106+
operation: 'patch',
107+
existingContent: 'old old',
108+
streamedContent: '$&',
109+
edit: {
110+
strategy: 'search_replace',
111+
search: 'old',
112+
replaceAll: true,
113+
},
114+
})
115+
).toBe('$& $&')
116+
})
102117
})

apps/sim/lib/copilot/tools/server/files/file-preview.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ function extractPatchPreview(
5353
const search = typeof edit?.search === 'string' ? edit.search : ''
5454
if (!search) return undefined
5555
if (edit?.replaceAll === true) {
56-
return existingContent.replaceAll(search, streamedContent)
56+
return existingContent.replaceAll(search, () => streamedContent)
5757
}
5858
const firstIdx = existingContent.indexOf(search)
5959
if (firstIdx === -1) return undefined

apps/sim/lib/workspace-files/edit-content.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ describe('applyStringReplacement', () => {
7070
expect(applyStringReplacement('a a a', 'a', 'b', true)).toBe('b b b')
7171
})
7272

73+
it('treats replacement substitution tokens as literal content', () => {
74+
expect(applyStringReplacement('a a', 'a', '$&', true)).toBe('$& $&')
75+
})
76+
7377
it('rejects an oversized replaceAll result before constructing it', () => {
7478
expect(() =>
7579
applyStringReplacement('aaaa', 'a', '0123456789', true, { maxOutputBytes: 20 })

apps/sim/lib/workspace-files/edit-content.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ export function applyStringReplacement(
134134
options?.maxOutputBytes
135135
)
136136

137-
if (replaceAll) return text.replaceAll(search, content)
137+
if (replaceAll) return text.replaceAll(search, () => content)
138138

139139
const index = text.indexOf(search)
140140
return text.slice(0, index) + content + text.slice(index + search.length)

0 commit comments

Comments
 (0)