Skip to content

Commit

Permalink
Support requesting kernel runtime states (#15371)
Browse files Browse the repository at this point in the history
* Support requesting kernel runtime states

* lint
  • Loading branch information
rebornix authored Mar 15, 2024
1 parent df25cd4 commit 19135a6
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
20 changes: 20 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,18 @@
"icon": "$(debug-alt-small)",
"enablement": "isWorkspaceTrusted && !jupyter.webExtension",
"category": "Jupyter"
},
{
"command": "jupyter.listPipPackages",
"title": "List Pip Packages",
"enablement": "isWorkspaceTrusted && !jupyter.webExtension",
"category": "Jupyter"
},
{
"command": "jupyter.listVariables",
"title": "List Variables",
"enablement": "isWorkspaceTrusted && !jupyter.webExtension",
"category": "Jupyter"
}
],
"submenus": [
Expand Down Expand Up @@ -1447,6 +1459,14 @@
{
"command": "jupyter.debugCellSymbols",
"when": "config.jupyter.executionAnalysis.enabled"
},
{
"command": "jupyter.listPipPackages",
"when": "false"
},
{
"command": "jupyter.listVariables",
"when": "false"
}
],
"debug/variables/context": [
Expand Down
3 changes: 3 additions & 0 deletions src/extension.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ import {
activate as activateExecutionAnalysis,
deactivate as deactivateExecutionAnalysis
} from './standalone/executionAnalysis/extension';
import { activate as activateChat, deactivate as deactivateChat } from './standalone/chat/extesnion';
import { setDisposableTracker } from './platform/common/utils/lifecycle';
import { sendTelemetryEvent } from './telemetry';
import { getVSCodeChannel } from './platform/common/application/applicationEnvironment';
Expand Down Expand Up @@ -162,6 +163,7 @@ export function deactivate(): Thenable<void> {
}

deactivateExecutionAnalysis();
deactivateChat();

return Promise.resolve();
}
Expand Down Expand Up @@ -202,6 +204,7 @@ async function activateUnsafe(
//===============================================
// dynamically load standalone plugins
activateExecutionAnalysis(context).then(noop, noop);
activateChat(context).then(noop, noop);

const api = buildApi(activationPromise, serviceManager, serviceContainer, context);
return [api, activationPromise, serviceContainer];
Expand Down
97 changes: 97 additions & 0 deletions src/standalone/chat/extesnion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import type { KernelMessage } from '@jupyterlab/services';
import * as vscode from 'vscode';
import { IKernel, IKernelProvider } from '../../kernels/types';
import { execCodeInBackgroundThread } from '../api/kernels/backgroundExecution';
import { ServiceContainer } from '../../platform/ioc/container';
import { IControllerRegistration } from '../../notebooks/controllers/types';

export async function activate(context: vscode.ExtensionContext): Promise<void> {
context.subscriptions.push(
vscode.commands.registerCommand('jupyter.listPipPackages', async (uri) => {
const documentUri = uri ?? vscode.window.activeNotebookEditor?.notebook.uri;
if (documentUri) {
const kernelProvider = ServiceContainer.instance.get<IKernelProvider>(IKernelProvider);
const kernel = await kernelProvider.get(documentUri);
if (kernel) {
const token = new vscode.CancellationTokenSource().token;
try {
const result = await sendPipListRequest(kernel, token);
if (Array.isArray(result.content)) {
return result.content;
}
} catch (_) {
// ignore
}
}
}

return [];
})
);

context.subscriptions.push(
vscode.commands.registerCommand('jupyter.listVariables', async (uri) => {
const documentUri = uri ?? vscode.window.activeNotebookEditor?.notebook.uri;

if (!documentUri) {
return [];
}

const document = vscode.workspace.notebookDocuments.find(
(item) => item.uri.toString() === documentUri.toString()
);

if (!document) {
return [];
}

const controllerRegistry = ServiceContainer.instance.get<IControllerRegistration>(IControllerRegistration);
const controller = controllerRegistry.getSelected(document);
if (!controller) {
return [];
}

const variablesProvider = controller.controller.variableProvider;

if (!variablesProvider) {
return [];
}

const token = new vscode.CancellationTokenSource().token;
const variables = variablesProvider.provideVariables(
document,
undefined,
vscode.NotebookVariablesRequestKind.Named,
0,
token
);

const resolvedVariables = [];
for await (const variable of variables) {
resolvedVariables.push(variable.variable);
}
return resolvedVariables;
})
);
}

async function sendPipListRequest(kernel: IKernel, token: vscode.CancellationToken) {
const codeToExecute = `import subprocess
proc = subprocess.Popen(["pip", "list", "--format", "json"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
stdout, stderr = proc.communicate()
return stdout
`.split('\n');

const content = await execCodeInBackgroundThread<KernelMessage.IInspectReplyMsg['content']>(
kernel,
codeToExecute,
token
);
return { content } as KernelMessage.IInspectReplyMsg;
}

// eslint-disable-next-line @typescript-eslint/no-empty-function
export function deactivate() {}

0 comments on commit 19135a6

Please sign in to comment.