Skip to content

Commit bd14f1a

Browse files
committed
Updates
1 parent 6a42167 commit bd14f1a

File tree

3 files changed

+126
-84
lines changed

3 files changed

+126
-84
lines changed

src/client/chat/getExecutableTool.ts

Lines changed: 23 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,17 @@ import {
1111
LanguageModelToolInvocationPrepareOptions,
1212
LanguageModelToolResult,
1313
PreparedToolInvocation,
14-
Uri,
1514
} from 'vscode';
16-
import { PythonExtension, ResolvedEnvironment } from '../api/types';
15+
import { PythonExtension } from '../api/types';
1716
import { IServiceContainer } from '../ioc/types';
1817
import { ICodeExecutionService } from '../terminals/types';
1918
import { TerminalCodeExecutionProvider } from '../terminals/codeExecution/terminalCodeExecution';
20-
import { getEnvDisplayName, isCondaEnv, raceCancellationError } from './utils';
19+
import { getEnvDisplayName, getEnvironmentDetails, raceCancellationError } from './utils';
2120
import { resolveFilePath } from './utils';
2221
import { traceError } from '../logging';
23-
import { ITerminalHelper, TerminalShellType } from '../common/terminal/types';
22+
import { ITerminalHelper } from '../common/terminal/types';
2423
import { IDiscoveryAPI } from '../pythonEnvironments/base/locator';
25-
import { Conda } from '../pythonEnvironments/common/environmentManagers/conda';
24+
import { ConfigurePythonEnvTool } from './configurePythonEnvTool';
2625

2726
export interface IResourceReference {
2827
resourcePath?: string;
@@ -47,30 +46,30 @@ export class GetExecutableTool implements LanguageModelTool<IResourceReference>
4746
options: LanguageModelToolInvocationOptions<IResourceReference>,
4847
token: CancellationToken,
4948
): Promise<LanguageModelToolResult> {
49+
if (!ConfigurePythonEnvTool.EnvironmentConfigured) {
50+
return new LanguageModelToolResult([
51+
new LanguageModelTextPart(
52+
[
53+
`A Python environment is not configured. Please configure a Python environment first using the ${ConfigurePythonEnvTool.toolName}.`,
54+
`The ${ConfigurePythonEnvTool.toolName} tool will guide the user through the process of configuring a Python environment.`,
55+
'Once the environment is configured, you can use this tool to get the Python executable information.',
56+
].join('\n'),
57+
),
58+
]);
59+
}
60+
5061
const resourcePath = resolveFilePath(options.input.resourcePath);
5162

5263
try {
53-
// environment
54-
const envPath = this.api.getActiveEnvironmentPath(resourcePath);
55-
const environment = await raceCancellationError(this.api.resolveEnvironment(envPath), token);
56-
if (!environment || !environment.version) {
57-
throw new Error('No environment found for the provided resource path: ' + resourcePath?.fsPath);
58-
}
59-
const runCommand = await raceCancellationError(
60-
getTerminalCommand(environment, resourcePath, this.terminalExecutionService, this.terminalHelper),
64+
const message = await getEnvironmentDetails(
65+
resourcePath,
66+
this.api,
67+
this.terminalExecutionService,
68+
this.terminalHelper,
69+
undefined,
6170
token,
6271
);
63-
64-
const message = [
65-
`Following is the information about the Python environment:`,
66-
`1. Environment Type: ${environment.environment?.type || 'unknown'}`,
67-
`2. Version: ${environment.version.sysVersion || 'unknown'}`,
68-
'',
69-
`3. Command Prefix to run Python in a terminal is: \`${runCommand}\``,
70-
`Instead of running \`Python sample.py\` in the terminal, you will now run: \`${runCommand} sample.py\``,
71-
`Similarly instead of running \`Python -c "import sys;...."\` in the terminal, you will now run: \`${runCommand} -c "import sys;...."\``,
72-
];
73-
return new LanguageModelToolResult([new LanguageModelTextPart(message.join('\n'))]);
72+
return new LanguageModelToolResult([new LanguageModelTextPart(message)]);
7473
} catch (error) {
7574
if (error instanceof CancellationError) {
7675
throw error;
@@ -94,36 +93,3 @@ export class GetExecutableTool implements LanguageModelTool<IResourceReference>
9493
};
9594
}
9695
}
97-
98-
export async function getTerminalCommand(
99-
environment: ResolvedEnvironment,
100-
resource: Uri | undefined,
101-
terminalExecutionService: TerminalCodeExecutionProvider,
102-
terminalHelper: ITerminalHelper,
103-
): Promise<string> {
104-
let cmd: { command: string; args: string[] };
105-
if (isCondaEnv(environment)) {
106-
cmd = (await getCondaRunCommand(environment)) || (await terminalExecutionService.getExecutableInfo(resource));
107-
} else {
108-
cmd = await terminalExecutionService.getExecutableInfo(resource);
109-
}
110-
return terminalHelper.buildCommandForTerminal(TerminalShellType.other, cmd.command, cmd.args);
111-
}
112-
async function getCondaRunCommand(environment: ResolvedEnvironment) {
113-
if (!environment.executable.uri) {
114-
return;
115-
}
116-
const conda = await Conda.getConda();
117-
if (!conda) {
118-
return;
119-
}
120-
const condaEnv = await conda.getCondaEnvironment(environment.executable.uri?.fsPath);
121-
if (!condaEnv) {
122-
return;
123-
}
124-
const cmd = await conda.getRunPythonArgs(condaEnv, true, false);
125-
if (!cmd) {
126-
return;
127-
}
128-
return { command: cmd[0], args: cmd.slice(1) };
129-
}

src/client/chat/getPythonEnvTool.ts

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ import { IServiceContainer } from '../ioc/types';
1717
import { ICodeExecutionService } from '../terminals/types';
1818
import { TerminalCodeExecutionProvider } from '../terminals/codeExecution/terminalCodeExecution';
1919
import { IProcessServiceFactory, IPythonExecutionFactory } from '../common/process/types';
20-
import { raceCancellationError } from './utils';
20+
import { getEnvironmentDetails, raceCancellationError } from './utils';
2121
import { resolveFilePath } from './utils';
2222
import { getPythonPackagesResponse } from './listPackagesTool';
23-
import { getTerminalCommand } from './getExecutableTool';
2423
import { ITerminalHelper } from '../common/terminal/types';
24+
import { ConfigurePythonEnvTool } from './configurePythonEnvTool';
2525

2626
export interface IResourceReference {
2727
resourcePath?: string;
@@ -55,6 +55,18 @@ export class GetEnvironmentInfoTool implements LanguageModelTool<IResourceRefere
5555
options: LanguageModelToolInvocationOptions<IResourceReference>,
5656
token: CancellationToken,
5757
): Promise<LanguageModelToolResult> {
58+
if (!ConfigurePythonEnvTool.EnvironmentConfigured) {
59+
return new LanguageModelToolResult([
60+
new LanguageModelTextPart(
61+
[
62+
`A Python environment is not configured. Please configure a Python environment first using the ${ConfigurePythonEnvTool.toolName}.`,
63+
`The ${ConfigurePythonEnvTool.toolName} tool will guide the user through the process of configuring a Python environment.`,
64+
'Once the environment is configured, you can use this tool to get the Python executable information.',
65+
].join('\n'),
66+
),
67+
]);
68+
}
69+
5870
const resourcePath = resolveFilePath(options.input.resourcePath);
5971

6072
try {
@@ -64,32 +76,24 @@ export class GetEnvironmentInfoTool implements LanguageModelTool<IResourceRefere
6476
if (!environment || !environment.version) {
6577
throw new Error('No environment found for the provided resource path: ' + resourcePath?.fsPath);
6678
}
67-
const [packages, runCommand] = await Promise.all([
68-
getPythonPackagesResponse(
69-
environment,
70-
this.pythonExecFactory,
71-
this.processServiceFactory,
72-
resourcePath,
73-
token,
74-
),
75-
raceCancellationError(
76-
getTerminalCommand(environment, resourcePath, this.terminalExecutionService, this.terminalHelper),
77-
token,
78-
),
79-
]);
79+
const packages = await getPythonPackagesResponse(
80+
environment,
81+
this.pythonExecFactory,
82+
this.processServiceFactory,
83+
resourcePath,
84+
token,
85+
);
8086

81-
const message = [
82-
`Following is the information about the Python environment:`,
83-
`1. Environment Type: ${environment.environment?.type || 'unknown'}`,
84-
`2. Version: ${environment.version.sysVersion || 'unknown'}`,
85-
'',
86-
`3. Command Prefix to run Python in a terminal is: \`${runCommand}\``,
87-
`Instead of running \`Python sample.py\` in the terminal, you will now run: \`${runCommand} sample.py\``,
88-
`Similarly, instead of running \`Python -c "import sys;...."\` in the terminal, you will now run: \`${runCommand} -c "import sys;...."\``,
89-
`4. ${packages}`,
90-
];
87+
const message = await getEnvironmentDetails(
88+
resourcePath,
89+
this.api,
90+
this.terminalExecutionService,
91+
this.terminalHelper,
92+
packages,
93+
token,
94+
);
9195

92-
return new LanguageModelToolResult([new LanguageModelTextPart(message.join('\n'))]);
96+
return new LanguageModelToolResult([new LanguageModelTextPart(message)]);
9397
} catch (error) {
9498
if (error instanceof CancellationError) {
9599
throw error;

src/client/chat/utils.ts

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import { CancellationError, CancellationToken, Uri, workspace } from 'vscode';
55
import { IDiscoveryAPI } from '../pythonEnvironments/base/locator';
66
import { PythonExtension, ResolvedEnvironment } from '../api/types';
7+
import { ITerminalHelper, TerminalShellType } from '../common/terminal/types';
8+
import { TerminalCodeExecutionProvider } from '../terminals/codeExecution/terminalCodeExecution';
9+
import { Conda } from '../pythonEnvironments/common/environmentManagers/conda';
710

811
export function resolveFilePath(filepath?: string): Uri | undefined {
912
if (!filepath) {
@@ -31,7 +34,11 @@ export function raceCancellationError<T>(promise: Promise<T>, token: Cancellatio
3134
});
3235
}
3336

34-
export async function getEnvDisplayName(discovery: IDiscoveryAPI, resource: Uri | undefined, api: PythonExtension['environments']) {
37+
export async function getEnvDisplayName(
38+
discovery: IDiscoveryAPI,
39+
resource: Uri | undefined,
40+
api: PythonExtension['environments'],
41+
) {
3542
try {
3643
const envPath = api.getActiveEnvironmentPath(resource);
3744
const env = await discovery.resolveEnv(envPath.path);
@@ -44,3 +51,68 @@ export async function getEnvDisplayName(discovery: IDiscoveryAPI, resource: Uri
4451
export function isCondaEnv(env: ResolvedEnvironment) {
4552
return (env.environment?.type || '').toLowerCase() === 'conda';
4653
}
54+
55+
export async function getEnvironmentDetails(
56+
resourcePath: Uri | undefined,
57+
api: PythonExtension['environments'],
58+
terminalExecutionService: TerminalCodeExecutionProvider,
59+
terminalHelper: ITerminalHelper,
60+
packages: string | undefined,
61+
token: CancellationToken,
62+
): Promise<string> {
63+
// environment
64+
const envPath = api.getActiveEnvironmentPath(resourcePath);
65+
const environment = await raceCancellationError(api.resolveEnvironment(envPath), token);
66+
if (!environment || !environment.version) {
67+
throw new Error('No environment found for the provided resource path: ' + resourcePath?.fsPath);
68+
}
69+
const runCommand = await raceCancellationError(
70+
getTerminalCommand(environment, resourcePath, terminalExecutionService, terminalHelper),
71+
token,
72+
);
73+
74+
const message = [
75+
`Following is the information about the Python environment:`,
76+
`1. Environment Type: ${environment.environment?.type || 'unknown'}`,
77+
`2. Version: ${environment.version.sysVersion || 'unknown'}`,
78+
'',
79+
`3. Command Prefix to run Python in a terminal is: \`${runCommand}\``,
80+
`Instead of running \`Python sample.py\` in the terminal, you will now run: \`${runCommand} sample.py\``,
81+
`Similarly instead of running \`Python -c "import sys;...."\` in the terminal, you will now run: \`${runCommand} -c "import sys;...."\``,
82+
packages ? `4. ${packages}` : '',
83+
];
84+
return message.join('\n');
85+
}
86+
87+
export async function getTerminalCommand(
88+
environment: ResolvedEnvironment,
89+
resource: Uri | undefined,
90+
terminalExecutionService: TerminalCodeExecutionProvider,
91+
terminalHelper: ITerminalHelper,
92+
): Promise<string> {
93+
let cmd: { command: string; args: string[] };
94+
if (isCondaEnv(environment)) {
95+
cmd = (await getCondaRunCommand(environment)) || (await terminalExecutionService.getExecutableInfo(resource));
96+
} else {
97+
cmd = await terminalExecutionService.getExecutableInfo(resource);
98+
}
99+
return terminalHelper.buildCommandForTerminal(TerminalShellType.other, cmd.command, cmd.args);
100+
}
101+
async function getCondaRunCommand(environment: ResolvedEnvironment) {
102+
if (!environment.executable.uri) {
103+
return;
104+
}
105+
const conda = await Conda.getConda();
106+
if (!conda) {
107+
return;
108+
}
109+
const condaEnv = await conda.getCondaEnvironment(environment.executable.uri?.fsPath);
110+
if (!condaEnv) {
111+
return;
112+
}
113+
const cmd = await conda.getRunPythonArgs(condaEnv, true, false);
114+
if (!cmd) {
115+
return;
116+
}
117+
return { command: cmd[0], args: cmd.slice(1) };
118+
}

0 commit comments

Comments
 (0)