22// Licensed under the MIT License.
33
44import {
5+ CancellationError ,
56 CancellationToken ,
67 l10n ,
78 LanguageModelTool ,
@@ -12,7 +13,7 @@ import {
1213 Uri ,
1314 workspace ,
1415} from 'vscode' ;
15- import { PythonExtension } from '../api/types' ;
16+ import { PythonExtension , ResolvedEnvironment } from '../api/types' ;
1617import { IServiceContainer } from '../ioc/types' ;
1718import { ICodeExecutionService } from '../terminals/types' ;
1819import { TerminalCodeExecutionProvider } from '../terminals/codeExecution/terminalCodeExecution' ;
@@ -26,7 +27,7 @@ import {
2627} from './utils' ;
2728import { resolveFilePath } from './utils' ;
2829import { ITerminalHelper } from '../common/terminal/types' ;
29- import { raceTimeout } from '../common/utils/async' ;
30+ import { raceTimeout , sleep } from '../common/utils/async' ;
3031import { IInterpreterPathService } from '../common/types' ;
3132import { DisposableStore } from '../common/utils/resourceLifecycle' ;
3233import { IRecommendedEnvironmentService } from '../interpreter/configuration/types' ;
@@ -36,7 +37,8 @@ import { convertEnvInfoToPythonEnvironment } from '../pythonEnvironments/legacyI
3637import { sortInterpreters } from '../interpreter/helpers' ;
3738import { isStableVersion } from '../pythonEnvironments/info/pythonVersion' ;
3839import { createVirtualEnvironment } from '../pythonEnvironments/creation/createEnvApi' ;
39- import { traceError , traceWarn } from '../logging' ;
40+ import { traceError , traceVerbose , traceWarn } from '../logging' ;
41+ import { StopWatch } from '../common/utils/stopWatch' ;
4042
4143export class CreateVirtualEnvTool implements LanguageModelTool < IResourceReference > {
4244 private readonly terminalExecutionService : TerminalCodeExecutionProvider ;
@@ -62,12 +64,12 @@ export class CreateVirtualEnvTool implements LanguageModelTool<IResourceReferenc
6264 async invoke (
6365 options : LanguageModelToolInvocationOptions < IResourceReference > ,
6466 token : CancellationToken ,
65- ) : Promise < LanguageModelToolResult | undefined > {
67+ ) : Promise < LanguageModelToolResult > {
6668 const resource = resolveFilePath ( options . input . resourcePath ) ;
6769 let info = await this . getPreferredEnvForCreation ( resource ) ;
6870 if ( ! info ) {
69- traceWarn ( `${ CreateVirtualEnvTool . toolName } tool not invoked, no preferred environment found.` ) ;
70- return ;
71+ traceWarn ( `Called ${ CreateVirtualEnvTool . toolName } tool not invoked, no preferred environment found.` ) ;
72+ throw new CancellationError ( ) ;
7173 }
7274 const { workspaceFolder, preferredGlobalPythonEnv } = info ;
7375 const interpreterPathService = this . serviceContainer . get < IInterpreterPathService > ( IInterpreterPathService ) ;
@@ -85,16 +87,30 @@ export class CreateVirtualEnvTool implements LanguageModelTool<IResourceReferenc
8587 token ,
8688 ) ;
8789 if ( ! created ?. path ) {
88- traceWarn ( `${ CreateVirtualEnvTool . toolName } tool not invoked, no preferred environment found .` ) ;
89- return ;
90+ traceWarn ( `${ CreateVirtualEnvTool . toolName } tool not invoked, virtual env not created .` ) ;
91+ throw new CancellationError ( ) ;
9092 }
93+
9194 // Wait a few secs to ensure the env is selected as the active environment..
9295 // If this doesn't work, then something went wrong.
9396 await raceTimeout ( 5_000 , interpreterChanged ) ;
94- const env = await this . api . resolveEnvironment ( created . path ) ;
97+
98+ const stopWatch = new StopWatch ( ) ;
99+ let env : ResolvedEnvironment | undefined ;
100+ while ( stopWatch . elapsedTime < 5_000 || ! env ) {
101+ env = await this . api . resolveEnvironment ( created . path ) ;
102+ if ( env ) {
103+ break ;
104+ } else {
105+ traceVerbose (
106+ `${ CreateVirtualEnvTool . toolName } tool invoked, env created but not yet resolved, waiting...` ,
107+ ) ;
108+ await sleep ( 200 ) ;
109+ }
110+ }
95111 if ( ! env ) {
96- traceError ( `${ CreateVirtualEnvTool . toolName } tool not invoked, no preferred environment found .` ) ;
97- return ;
112+ traceError ( `${ CreateVirtualEnvTool . toolName } tool invoked, env created but unable to resolve details .` ) ;
113+ throw new CancellationError ( ) ;
98114 }
99115 return await getEnvDetailsForResponse (
100116 env ,
0 commit comments