@@ -56,8 +56,8 @@ export class GetErrorsTool extends Disposable implements ICopilotTool<IGetErrors
5656 * Get diagnostics for the given paths and optional ranges.
5757 * Note - This is made public for testing purposes only.
5858 */
59- public getDiagnostics ( paths : { uri : URI ; range : Range | undefined } [ ] ) : Array < { uri : URI ; diagnostics : vscode . Diagnostic [ ] } > {
60- const results : Array < { uri : URI ; diagnostics : vscode . Diagnostic [ ] } > = [ ] ;
59+ public getDiagnostics ( paths : { uri : URI ; range : Range | undefined } [ ] ) : Array < { uri : URI ; diagnostics : vscode . Diagnostic [ ] ; inputUri ?: URI } > {
60+ const results : Array < { uri : URI ; diagnostics : vscode . Diagnostic [ ] ; inputUri ?: URI } > = [ ] ;
6161
6262 // for notebooks, we need to find the cell matching the range and get diagnostics for that cell
6363 const nonNotebookPaths = paths . filter ( p => {
@@ -89,11 +89,25 @@ export class GetErrorsTool extends Disposable implements ICopilotTool<IGetErrors
8989 const ranges : Range [ ] = [ ] ;
9090 let shouldTakeAll = false ;
9191 let foundMatch = false ;
92+ let inputUri : URI | undefined ;
93+ let matchedExactPath = false ;
94+
9295 for ( const path of nonNotebookPaths ) {
9396 // we support file or folder paths
9497 if ( isEqualOrParent ( resource , path . uri ) ) {
9598 foundMatch = true ;
9699
100+ // Track the input URI that matched - prefer exact matches, otherwise use the folder
101+ const isExactMatch = resource . toString ( ) === path . uri . toString ( ) ;
102+ if ( isExactMatch ) {
103+ // Exact match - this is the file itself, no input folder
104+ inputUri = undefined ;
105+ matchedExactPath = true ;
106+ } else if ( ! matchedExactPath ) {
107+ // Folder match - only set if we haven't found an exact match
108+ inputUri = path . uri ;
109+ }
110+
97111 if ( pendingMatchPaths . has ( path . uri ) ) {
98112 pendingMatchPaths . delete ( path . uri ) ;
99113 }
@@ -103,19 +117,22 @@ export class GetErrorsTool extends Disposable implements ICopilotTool<IGetErrors
103117 } else {
104118 // no range, so all diagnostics for this file
105119 shouldTakeAll = true ;
106- break ;
120+ // only break for exact matches
121+ if ( isExactMatch ) {
122+ break ;
123+ }
107124 }
108125 }
109126 }
110127
111128 if ( shouldTakeAll ) {
112- results . push ( { uri : resource , diagnostics : pendingDiagnostics } ) ;
129+ results . push ( { uri : resource , diagnostics : pendingDiagnostics , inputUri } ) ;
113130 continue ;
114131 }
115132
116133 if ( foundMatch && ranges . length > 0 ) {
117134 const diagnostics = pendingDiagnostics . filter ( d => ranges . some ( range => d . range . intersection ( range ) ) ) ;
118- results . push ( { uri : resource , diagnostics } ) ;
135+ results . push ( { uri : resource , diagnostics, inputUri } ) ;
119136 }
120137 }
121138
@@ -129,7 +146,7 @@ export class GetErrorsTool extends Disposable implements ICopilotTool<IGetErrors
129146
130147 async invoke ( options : vscode . LanguageModelToolInvocationOptions < IGetErrorsParams > , token : CancellationToken ) {
131148 const getAll = ( ) => this . languageDiagnosticsService . getAllDiagnostics ( )
132- . map ( d => ( { uri : d [ 0 ] , diagnostics : d [ 1 ] . filter ( e => e . severity <= DiagnosticSeverity . Warning ) } ) )
149+ . map ( d => ( { uri : d [ 0 ] , diagnostics : d [ 1 ] . filter ( e => e . severity <= DiagnosticSeverity . Warning ) , inputUri : undefined as URI | undefined } ) )
133150 // filter any documents w/o warnings or errors
134151 . filter ( d => d . diagnostics . length > 0 ) ;
135152
@@ -146,14 +163,15 @@ export class GetErrorsTool extends Disposable implements ICopilotTool<IGetErrors
146163
147164 const ds = options . input . filePaths ?. length ? getSome ( options . input . filePaths ) : getAll ( ) ;
148165
149- const diagnostics = coalesce ( await Promise . all ( ds . map ( ( async ( { uri, diagnostics } ) => {
166+ const diagnostics = coalesce ( await Promise . all ( ds . map ( ( async ( { uri, diagnostics, inputUri } ) => {
150167 try {
151168 const document = await this . workspaceService . openTextDocumentAndSnapshot ( uri ) ;
152169 checkCancellation ( token ) ;
153170 return {
154171 uri,
155172 diagnostics,
156- context : { document, language : getLanguage ( document ) }
173+ context : { document, language : getLanguage ( document ) } ,
174+ inputUri
157175 } ;
158176 } catch ( e ) {
159177 this . logService . error ( e , 'get_errors failed to open doc with diagnostics' ) ;
@@ -169,7 +187,17 @@ export class GetErrorsTool extends Disposable implements ICopilotTool<IGetErrors
169187 ] ) ;
170188
171189 const numDiagnostics = diagnostics . reduce ( ( acc , { diagnostics } ) => acc + diagnostics . length , 0 ) ;
172- const formattedURIs = this . formatURIs ( diagnostics . map ( d => d . uri ) ) ;
190+
191+ // For display message, use inputUri if available (indicating file was found via folder input), otherwise use the file uri
192+ // Deduplicate URIs since multiple files may have the same inputUri
193+ const displayUriSet = new Set < string > ( ) ;
194+ for ( const d of diagnostics ) {
195+ const displayUri = d . inputUri ?? d . uri ;
196+ displayUriSet . add ( displayUri . toString ( ) ) ;
197+ }
198+ const displayUris = Array . from ( displayUriSet ) . map ( uriStr => URI . parse ( uriStr ) ) ;
199+ const formattedURIs = this . formatURIs ( displayUris ) ;
200+
173201 if ( options . input . filePaths ?. length ) {
174202 result . toolResultMessage = numDiagnostics === 0 ?
175203 new MarkdownString ( l10n . t `Checked ${ formattedURIs } , no problems found` ) :
@@ -276,11 +304,9 @@ export class GetErrorsTool extends Disposable implements ICopilotTool<IGetErrors
276304ToolRegistry . registerTool ( GetErrorsTool ) ;
277305
278306interface IDiagnosticToolOutputProps extends BasePromptElementProps {
279- diagnosticsGroups : { context : DiagnosticContext ; uri : URI ; diagnostics : vscode . Diagnostic [ ] } [ ] ;
307+ diagnosticsGroups : { context : DiagnosticContext ; uri : URI ; diagnostics : vscode . Diagnostic [ ] ; inputUri ?: URI } [ ] ;
280308 maxDiagnostics ?: number ;
281- }
282-
283- export class DiagnosticToolOutput extends PromptElement < IDiagnosticToolOutputProps > {
309+ } export class DiagnosticToolOutput extends PromptElement < IDiagnosticToolOutputProps > {
284310 constructor (
285311 props : PromptElementProps < IDiagnosticToolOutputProps > ,
286312 @IPromptPathRepresentationService private readonly promptPathRepresentationService : IPromptPathRepresentationService ,
@@ -326,4 +352,4 @@ export class DiagnosticToolOutput extends PromptElement<IDiagnosticToolOutputPro
326352 ) }
327353 </ > ;
328354 }
329- }
355+ }
0 commit comments