feat: at-mentions for canvas nodes#3968
Conversation
31e9ab8 to
04240c0
Compare
0d10adf to
e1e348f
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e1e348f. Configure here.
| const re = new RegExp(`(^|[\\s])@${escaped}(?=\\s|$|[.,!?;:])`, "g"); | ||
| out = out.replace(re, `$1@[node:${id}]`); | ||
| } | ||
| return out; |
There was a problem hiding this comment.
Duplicate display names cause wrong node transcoding
Medium Severity
transcodeAiNodeMentions matches @Name text by display name, but applyMention only inserts the display name (not the node ID) into the composer. When two or more nodes share the same aiBuilderNodeDisplayName (common for unnamed nodes, which all resolve to "Untitled"), every @Untitled mention silently maps to whichever node appears first — regardless of which entry the user explicitly picked from the typeahead. The user's deliberate selection is lost.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit e1e348f. Configure here.
|
👋 Commands for maintainers:
|
Signed-off-by: re-pixel <relja.brdar@gmail.com>
…u disappear when the mention is selected Signed-off-by: re-pixel <relja.brdar@gmail.com>
Signed-off-by: re-pixel <relja.brdar@gmail.com>
Signed-off-by: re-pixel <relja.brdar@gmail.com>
Signed-off-by: re-pixel <relja.brdar@gmail.com>
Signed-off-by: re-pixel <relja.brdar@gmail.com>
Signed-off-by: re-pixel <relja.brdar@gmail.com>
Signed-off-by: re-pixel <relja.brdar@gmail.com>
Signed-off-by: re-pixel <relja.brdar@gmail.com>
95a4142 to
77bba14
Compare


What this does
In AI Builder, users can @-mention steps on the canvas by the same names they see in the workflow. Mentions are chosen from a typeahead list, sent to the agent as stable node IDs (not guessed from free text), and the agent gets extra context for those nodes.
User-facing behavior
@in the composer to open a filtered list of canvas nodes (by display name).@+ that name and a trailing space.@[node:<id>]in the request body.describe_canvas, and appends a short “Referenced nodes” section to the model prompt (id, name, type, block).That appendix increases the size of the text we send in the prompt, but it pays for itself in practice: the model no longer has to infer which node the user meant or discover it only by calling tools—the user’s selection is explicit, which removes one reasoning step and tends to make runs more direct.
Implementation
@Nametext in the composer; right beforefetch,transcodeAiNodeMentions()rewrites mentions to stable@[node:id]tokens (longest display name first, same boundaries as autocomplete).@opens a filtered node list; Enter picks a row when the menu is open, otherwise it sends; the menu is portaled with fixed positioning and a high z-index so it stacks above the rest of the sidebar; accepting a mention closes the menu and refreshes mention state from the cursor.formatAiBuilderWireMentionsForDisplay()turns@[node:id]back into@DisplayNameusing the currentcanvasNodesmap; the sidebar applies that to session titles and user message text so lists and bubbles stay name-first.node_mentions.pyparses wire tokens, resolves nodes viadescribe_canvas, appends the “Referenced nodes” appendix to the model prompt, and primescanvas_cache;repl_webruns that expansion on each user turn;system_prompt.txtdocuments the token convention.strip_referenced_nodes_appendix_for_display()removes the appendix only when building user-facing history from the API;PersistedRunRecordercan take a separateinitial_messageso chat titles/previews stay the short client question.test_node_mentions.pycovers parsing, expansion, and stripping helpers.Related Issues
#3966