@@ -164,6 +164,42 @@ export interface AssertFileOkForToolOptions {
164164 readOnly ?: boolean ;
165165}
166166
167+ async function isUriAllowedWithoutWorkspaceMembership (
168+ uri : URI ,
169+ normalizedUri : URI ,
170+ tabsAndEditorsService : ITabsAndEditorsService ,
171+ customInstructionsService : ICustomInstructionsService ,
172+ diskSessionResources : IChatDiskSessionResources ,
173+ chatDebugFileLogger : IChatDebugFileLoggerService ,
174+ sessionTranscriptService : ISessionTranscriptService ,
175+ buildPromptContext ?: IBuildPromptContext ,
176+ options ?: AssertFileOkForToolOptions ,
177+ ) : Promise < boolean > {
178+ if ( uri . scheme === Schemas . untitled ) {
179+ return true ;
180+ }
181+ if ( options ?. readOnly && uri . scheme === 'vscode-chat-response-resource' ) {
182+ return true ;
183+ }
184+ if ( await isExternalInstructionsFile ( normalizedUri , customInstructionsService , buildPromptContext ) ) {
185+ return true ;
186+ }
187+ if ( diskSessionResources . isSessionResourceUri ( normalizedUri ) ) {
188+ return true ;
189+ }
190+ if ( chatDebugFileLogger . isDebugLogUri ( normalizedUri ) ) {
191+ return true ;
192+ }
193+ if ( sessionTranscriptService . isTranscriptUri ( normalizedUri ) ) {
194+ return true ;
195+ }
196+ if ( tabsAndEditorsService . tabs . some ( tab => isEqual ( tab . uri , uri ) ) ) {
197+ return true ;
198+ }
199+
200+ return false ;
201+ }
202+
167203export async function assertFileOkForTool ( accessor : ServicesAccessor , uri : URI , buildPromptContext ?: IBuildPromptContext , options ?: AssertFileOkForToolOptions ) : Promise < void > {
168204 const workspaceService = accessor . get ( IWorkspaceService ) ;
169205 const tabsAndEditorsService = accessor . get ( ITabsAndEditorsService ) ;
@@ -183,23 +219,17 @@ export async function assertFileOkForTool(accessor: ServicesAccessor, uri: URI,
183219 if ( options ?. readOnly && isUriUnderAdditionalReadAccessPaths ( normalizedUri , configurationService ) ) {
184220 return ;
185221 }
186- if ( uri . scheme === Schemas . untitled ) {
187- return ;
188- }
189- const fileOpenInSomeTab = tabsAndEditorsService . tabs . some ( tab => isEqual ( tab . uri , uri ) ) ;
190- if ( fileOpenInSomeTab ) {
191- return ;
192- }
193- if ( diskSessionResources . isSessionResourceUri ( normalizedUri ) ) {
194- return ;
195- }
196- if ( chatDebugFileLogger . isDebugLogUri ( normalizedUri ) ) {
197- return ;
198- }
199- if ( sessionTranscriptService . isTranscriptUri ( normalizedUri ) ) {
200- return ;
201- }
202- if ( await isExternalInstructionsFile ( normalizedUri , customInstructionsService , buildPromptContext ) ) {
222+ if ( await isUriAllowedWithoutWorkspaceMembership (
223+ uri ,
224+ normalizedUri ,
225+ tabsAndEditorsService ,
226+ customInstructionsService ,
227+ diskSessionResources ,
228+ chatDebugFileLogger ,
229+ sessionTranscriptService ,
230+ buildPromptContext ,
231+ options ,
232+ ) ) {
203233 return ;
204234 }
205235 throw new Error ( `File ${ promptPathRepresentationService . getFilePath ( normalizedUri ) } is outside of the workspace, and not open in an editor, and can't be read` ) ;
@@ -281,29 +311,24 @@ export async function isFileExternalAndNeedsConfirmation(accessor: ServicesAcces
281311
282312 const normalizedUri = normalizePath ( uri ) ;
283313
284- // Not external if: in workspace, untitled, instructions file, session resource , or open in editor
314+ // Not external if: in workspace, under configured read-only paths , or otherwise allowlisted for read-only access.
285315 if ( workspaceService . getWorkspaceFolder ( normalizedUri ) ) {
286316 return false ;
287317 }
288318 if ( options ?. readOnly && isUriUnderAdditionalReadAccessPaths ( normalizedUri , configurationService ) ) {
289319 return false ;
290320 }
291- if ( uri . scheme === Schemas . untitled || uri . scheme === 'vscode-chat-response-resource' ) {
292- return false ;
293- }
294- if ( await isExternalInstructionsFile ( normalizedUri , customInstructionsService , buildPromptContext ) ) {
295- return false ;
296- }
297- if ( diskSessionResources . isSessionResourceUri ( normalizedUri ) ) {
298- return false ;
299- }
300- if ( chatDebugFileLogger . isDebugLogUri ( normalizedUri ) ) {
301- return false ;
302- }
303- if ( sessionTranscriptService . isTranscriptUri ( normalizedUri ) ) {
304- return false ;
305- }
306- if ( tabsAndEditorsService . tabs . some ( tab => isEqual ( tab . uri , uri ) ) ) {
321+ if ( await isUriAllowedWithoutWorkspaceMembership (
322+ uri ,
323+ normalizedUri ,
324+ tabsAndEditorsService ,
325+ customInstructionsService ,
326+ diskSessionResources ,
327+ chatDebugFileLogger ,
328+ sessionTranscriptService ,
329+ buildPromptContext ,
330+ options ,
331+ ) ) {
307332 return false ;
308333 }
309334
0 commit comments