Skip to content

Commit 714e6d8

Browse files
committed
fix(chat): include the line range in file-selection equality
Cursor Bugbot: areContextsEqual compared only fileId and text for file_selection, while the comment directly above claimed equality was the selected range. A line that occurs twice in a file — a repeated import, a closing brace — highlighted at both places produced identical text, so prepareContextForInsert called the second a duplicate and dropped its chip, even though the labels (notes.md:12 vs notes.md:50) were plainly different. Comparing startLine/endLine as well makes the code match what the comment promised. The rich-markdown editor omits the range, so both sides are undefined there and identical text still dedupes — correct, since two identical passages are genuinely indistinguishable without line numbers. Tests cover both: distinct ranges stay distinct, an exact repeat still dedupes, and the no-line-number path still dedupes. Verified the first fails against text-only equality.
1 parent 3bb5d6c commit 714e6d8

2 files changed

Lines changed: 28 additions & 1 deletion

File tree

  • apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/user-input

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/user-input/utils.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,22 @@ describe('prepareContextForInsert', () => {
6767
expect(prepareContextForInsert(other, [fileSelection()])).not.toBeNull()
6868
})
6969

70+
it('distinguishes identical text highlighted at two places in one file', () => {
71+
// A repeated line — an import, a closing brace — selected twice. Comparing
72+
// text alone would call the second a duplicate and silently drop its chip.
73+
const first = fileSelection({ label: 'notes.md:12', startLine: 12, endLine: 12 })
74+
const second = fileSelection({ label: 'notes.md:50', startLine: 50, endLine: 50 })
75+
76+
expect(prepareContextForInsert(second, [first])).not.toBeNull()
77+
expect(prepareContextForInsert(first, [first])).toBeNull()
78+
})
79+
80+
it('still dedupes identical text when the source has no line numbers', () => {
81+
// The rich-markdown editor omits the range, so two identical passages are
82+
// indistinguishable in the data model and deduping is the honest outcome.
83+
expect(prepareContextForInsert(fileSelection(), [fileSelection()])).toBeNull()
84+
})
85+
7086
it('treats the same rows picked in a different order as one selection', () => {
7187
// Row ids iterate in click order, so re-picking the same rows differently
7288
// must no-op rather than add a second chip over rows already referenced.

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/user-input/utils.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,18 @@ export function areContextsEqual(c: ChatContext, context: ChatContext): boolean
254254
// already-referenced file would be swallowed as a duplicate.
255255
case 'file_selection': {
256256
const ctx = context as FileSelectionContext
257-
return c.fileId === ctx.fileId && c.text === ctx.text
257+
// Location too, not just the text: the same line can occur twice in a file
258+
// (a repeated import, a closing brace), and comparing text alone would
259+
// treat the second highlight as a duplicate and drop its chip. Where the
260+
// source has no line numbers — the rich-markdown editor — both are
261+
// undefined and identical text is genuinely indistinguishable, so it
262+
// correctly still dedupes.
263+
return (
264+
c.fileId === ctx.fileId &&
265+
c.text === ctx.text &&
266+
c.startLine === ctx.startLine &&
267+
c.endLine === ctx.endLine
268+
)
258269
}
259270
case 'table_selection': {
260271
const ctx = context as TableSelectionContext

0 commit comments

Comments
 (0)