NES: split open-tab vs related-file neighbor context - #326626
Merged
Ulugbek Abdullaev (ulugbekna) merged 6 commits intoJul 20, 2026
Merged
Conversation
For the xtab (NES) neighboring-files context, distinguish neighbor snippets that come from open tabs vs. language-service "related" files: - Omit line numbers for related-file snippets, matching the NES language-context path; open-tab snippets keep their line numbers. - Add a `neighborFiles.includeRelatedFiles` option (default `true`, so behavior is unchanged) that turns off the related-files context, since NES has its own language-context implementation. When off, the related-files LSP computation is skipped entirely. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1bb7414b-49be-41eb-b86b-bc8d7a319268
Copilot started reviewing on behalf of
Ulugbek Abdullaev (ulugbekna)
July 20, 2026 14:31
View session
Contributor
There was a problem hiding this comment.
Pull request overview
Splits NES neighbor context by open-tab versus language-service-related provenance.
Changes:
- Adds related-file provenance and suppresses its line numbers.
- Adds a configuration toggle that skips related-file discovery.
- Adds prompt-formatting coverage.
Show a summary per file
| File | Description |
|---|---|
xtabPromptOptions.ts |
Defines the related-files option. |
configurationService.ts |
Registers the experiment setting. |
recentFilesForPrompt.spec.ts |
Tests related-file formatting. |
xtabProvider.ts |
Threads the setting through NES. |
similarFilesContextService.ts |
Extends the service contract and snippet metadata. |
recentFilesForPrompt.ts |
Selects line-number formatting by provenance. |
similarFilesContext.ts |
Derives and applies related-file provenance. |
neighborFiles.ts |
Classifies related sources and skips their computation. |
Review details
- Files reviewed: 8/8 changed files
- Comments generated: 2
- Review effort level: Medium
…iles toggle Carry the source document's URI on ranked snippets (added to ScoredSnippet and populated in getSimilarSnippets) so neighbor-snippet provenance no longer relies on reconstructing a URI from relativePath. In multi-root workspaces two documents can share a relativePath, so the previous last-wins relativePath->uri map could misclassify an open-tab snippet as a related file and wrongly drop its line numbers. Add a test asserting that when includeRelatedFiles is false the open-tab neighbors are still returned, no related-file traits are produced, and the related-files provider is never invoked (guarding the promised LSP-work avoidance), with a positive control proving the provider is invoked when enabled. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1bb7414b-49be-41eb-b86b-bc8d7a319268
…i-root test Address review follow-ups: - getSimilarSnippets now returns SnippetWithSourceUri (uri guaranteed), and spreads the match first so the source file's uri/relativePath always win. - similarFilesContext drops the `s.uri ?? uri` fallback so a future propagation regression fails at the type level instead of silently misattributing a snippet to the active document. - Add a getSimilarSnippets test covering two neighbor files that share a relativePath (multi-root) and asserting each snippet keeps its true uri. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1bb7414b-49be-41eb-b86b-bc8d7a319268
Address review: replace the inline nested loop that derived the related-file URI set in SimilarFilesContextService with a named `collectRelatedFileUris` helper co-located with `isRelatedNeighboringFileType` in neighborFiles.ts. The call site is now a single readable line and the "which neighbor types are related" concept lives in one place. Pure refactor, behavior unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1bb7414b-49be-41eb-b86b-bc8d7a319268
Per review: rather than building a set of related-file URIs and re-classifying each ranked snippet by URI membership, decide the classification once where the neighbor type is known and let it ride on the snippet. - SimilarFileInfo/ScoredSnippet gain an optional `isFromRelatedFile` flag. - getNeighborFilesAndTraits stamps it via `isRelatedNeighboringFileType(type)` when it materializes each related doc. - getSimilarSnippets propagates the flag onto every snippet (like uri). - SimilarFilesContextService reads `s.isFromRelatedFile` directly; the `relatedFileUris` set, its plumbing, and `collectRelatedFileUris` are gone. Classification is now robust by construction (no dependence on URI-string equality across two maps). `neighborSource` is untouched (still used by completions telemetry/prompt). Adds a getSimilarSnippets test asserting the flag propagates from source file to snippet. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1bb7414b-49be-41eb-b86b-bc8d7a319268
Per review: make the provenance flag non-optional where consumers actually use it, without forcing matcher-stage snippets (which have no provenance yet) to fabricate a value. - ScoredSnippet.isFromRelatedFile stays optional on the base type (documented why: the matcher produces snippets before provenance is known), mirroring how `uri`/`relativePath` are handled. - getSimilarSnippets normalizes it (`?? false`) and its return type now guarantees `isFromRelatedFile: boolean` (renamed SnippetWithSourceUri -> SnippetWithSourceInfo, which now carries both `uri` and the flag). - SimilarFilesContextService reads `s.isFromRelatedFile` directly with no fallback. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1bb7414b-49be-41eb-b86b-bc8d7a319268
Ulugbek Abdullaev (ulugbekna)
marked this pull request as ready for review
July 20, 2026 22:41
Contributor
|
This PR will be automatically cherry-picked to |
Ulugbek Abdullaev (ulugbekna)
enabled auto-merge (squash)
July 20, 2026 22:42
roblourens
approved these changes
Jul 20, 2026
Ulugbek Abdullaev (ulugbekna)
deleted the
ulugbekna/nes-neighboring-files-context
branch
July 20, 2026 23:41
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related improvements to the xtab (NES / Next Edit Suggestions) neighboring-files context. Both hinge on distinguishing neighbor snippets that come from open tabs vs. from language-service "related" files (the non-open-tab files a language service suggests, e.g.
related/typescript,related/cpp).appendLanguageContextSnippets, which already usesIncludeLineNumbersOption.None). Open-tab neighbor snippets are unchanged and keep their line numbers.neighborFiles.includeRelatedFilesoption lets us disable the completions-style related-files context entirely, since NES already has its own language-context implementation (ILanguageContextProviderService). When off, the related-files LSP computation is skipped entirely (no wasted work), leaving only open-tab neighbors.Both default to behavior-preserving settings, so this PR is a no-op until the new config is flipped.
Motivation
NES's neighboring-files context (Jaccard-ranked snippets from Completions) overlaps with NES's own language context. This PR makes the two coexist cleanly: related-file snippets are formatted consistently with the language-context path (no line numbers), and the redundant related-files context can be switched off per experiment.
What changed
Point 1 — provenance tag + line-number formatting. Each neighbor snippet carries its provenance, decided once at the source (where the neighbor type is known) rather than re-derived from URIs:
neighborFiles.ts(completions-core):isRelatedNeighboringFileType(type)is aswitchover theRelated*enum members (robust to enum changes, no string-prefix matching).getNeighborFilesAndTraitsstampsisFromRelatedFileon each related doc as it is materialized.prompt.ts/selectRelevance.ts:SimilarFileInfoandScoredSnippetgain an optionalisFromRelatedFile.getSimilarSnippetspropagates it (and the sourceuri) onto every ranked snippet and guarantees it on its return type (SnippetWithSourceInfo).similarFilesContext.ts:getSnippetsForPromptreadss.isFromRelatedFiledirectly — no post-ranking URI set / cross-referencing.similarFilesContextService.ts:INeighborFileSnippetgainsreadonly isFromRelatedFile: boolean.recentFilesForPrompt.ts:appendNeighborFileSnippetsusesIncludeLineNumbersOption.Nonefor related-file snippets, else the configured option.Point 2 — toggle
xtabPromptOptions.ts: addsincludeRelatedFilestoNeighborFilesOptions(type +VALIDATOR+DEFAULT_OPTIONS, defaulttrue).configurationService.ts: new team-internal, experiment-based keychat.advanced.inlineEdits.xtabProvider.neighborFiles.includeRelatedFiles.xtabProvider.ts: wires the config into theneighborFilesoptions and threads the flag intogetSnippetsForPromptand the fire-and-forget telemetrycompute.neighborFiles.ts(completions-core):getNeighborFilesAndTraitsgains anincludeRelatedFiles: boolean = trueparam; whenfalseit returns early with open-tab neighbors only, before any related-files/LSP work.Behavior & compatibility
includeRelatedFilesdefaults totrue; related files continue to be included exactly as before. Line-numbering for open-tab snippets is unchanged.neighborFiles.enabledis on.How to review
Suggested reading order:
similarFilesContextService.ts— the newisFromRelatedFilefield + theincludeRelatedFilesparam on the two service methods. This is the contract for everything else.neighborFiles.ts(completions-core) —isRelatedNeighboringFileType, theisFromRelatedFilestamp on related docs, and the one-line early-return ingetNeighborFilesAndTraits(if (!includeRelatedFiles || featuresService.excludeRelatedFiles(...))). Confirm skipping related files still returns open-tab neighbors + empty traits.similarFiles.ts/selectRelevance.ts— the tag rides onSimilarFileInfo→ each snippet;getSimilarSnippetsguaranteesuri+isFromRelatedFileon its return type.similarFilesContext.ts—getSnippetsForPromptclassifies purely froms.isFromRelatedFile(no URI set), so multi-root relative-path collisions can't misclassify a snippet.recentFilesForPrompt.ts— related snippets getIncludeLineNumbersOption.None; open-tab snippets keep the configured option.Tests
similarFiles.test.ts(prompt):getSimilarSnippetspreserves each sourceuriunder a multi-root relativePath collision, and propagatesisFromRelatedFilefrom source file → snippet.neighborFiles.test.ts(completions-core):includeRelatedFiles=falseretains open-tab neighbors, keeps traits empty, and (via a call counter on the mocked provider) proves the related-files provider is never invoked — with a positive control for the enabled path.recentFilesForPrompt.spec.ts(xtab): related snippets omit line numbers; open-tab snippets keep them.