Skip to content

Commit

Permalink
VSCode 0.3.34
Browse files Browse the repository at this point in the history
Implementation of features to support new `eval` log file format.

- Overhaul view display to use `inspect view` server
- Show Inspect version in the status bar
- Support readonly editor for log files (shows viewer)
  • Loading branch information
dragonstyle committed Oct 21, 2024
1 parent 6aea785 commit e924c25
Show file tree
Hide file tree
Showing 29 changed files with 1,231 additions and 669 deletions.
5 changes: 5 additions & 0 deletions tools/vscode/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 0.3.34

- Show Inspect version in status bar
- Release with internal changes to support future log viewing features.

## 0.3.33

- Fix bug that prevented run, debug buttons from appearing for tasks whose function declarations spanned more than single line.
Expand Down
10 changes: 10 additions & 0 deletions tools/vscode/assets/icon/eval.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 53 additions & 9 deletions tools/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"author": {
"name": "UK AI Safety Institute"
},
"version": "0.3.33",
"version": "0.3.34",
"license": "MIT",
"homepage": "https://inspect.ai-safety-institute.org.uk/",
"repository": {
Expand All @@ -32,12 +32,44 @@
"onWebviewPanel:inspect.logview",
"onWebviewPanel:inspect_ai.task-configuration",
"onWebviewPanel:inspect_ai.env-configuration-view",
"onLanguage:eval",
"workspaceContains:**/*.eval",
"onLanguage:python",
"workspaceContains:*.py",
"workspaceContains:*.ipynb"
"workspaceContains:**/*.py",
"workspaceContains:**/*.ipynb"
],
"main": "./dist/extension.js",
"contributes": {
"languages": [
{
"id": "eval-log",
"aliases": [
"Eval Log"
],
"extensions": [
".eval"
],
"icon": {
"light": "./assets/icon/eval.svg",
"dark": "./assets/icon/eval.svg"
}
}
],
"customEditors": [
{
"viewType": "inspect-ai.log-editor",
"displayName": "Inspect Log Viewer",
"selector": [
{
"filenamePattern": "*.eval"
},
{
"filenamePattern": "{[0-9][0-9][0-9][0-9]}-{[0-9][0-9]}-{[0-9][0-9]}T{[0-9][0-9]}[:-]{[0-9][0-9]}[:-]{[0-9][0-9]}*{[A-Za-z0-9]{21}}*.json"
}
],
"priority": "default"
}
],
"commands": [
{
"command": "inspect.showLogview",
Expand Down Expand Up @@ -163,7 +195,8 @@
"inspect_ai.openLogView": {
"type": "boolean",
"default": true,
"description": "Open the Inspect log view when evaluations in the workspace complete."
"description": "Open the Inspect Log View when evaluations in the workspace complete.",
"order": 1
},
"inspect_ai.logViewType": {
"type": "string",
Expand All @@ -175,7 +208,14 @@
"markdownEnumDescriptions": [
"Use `inspect view` to display evaluation log files.",
"Use a text editor to display evaluation log files."
]
],
"order": 2
},
"inspect_ai.jsonLogView": {
"type": "boolean",
"default": true,
"markdownDescription": "Use Inspect Log View as the default viewer for JSON log files.",
"order": 3
},
"inspect_ai.taskListView": {
"type": "string",
Expand All @@ -184,12 +224,14 @@
"tree",
"list"
],
"description": "Display task outline as a tree or list."
"description": "Display task outline as a tree or list.",
"order": 4
},
"inspect_ai.debugSingleSample": {
"type": "boolean",
"default": true,
"description": "Limit evaluation to one sample when debugging."
"description": "Limit evaluation to one sample when debugging.",
"order": 5
}
}
},
Expand Down Expand Up @@ -265,7 +307,7 @@
{
"command": "inspect.openInInspectView",
"group": "navigation@100",
"when": "inspect_ai.enableOpenInView && resourceFilename =~ /^.*\\.json$/"
"when": "inspect_ai.enableOpenInView && resourceFilename =~ /^.*\\.(json|eval)$/"
}
],
"view/item/context": [
Expand Down Expand Up @@ -340,6 +382,7 @@
"test": "vscode-test"
},
"devDependencies": {
"@types/async-lock": "^1.4.2",
"@types/lodash": "^4.17.0",
"@types/mocha": "^10.0.6",
"@types/node": "18.x",
Expand All @@ -362,7 +405,8 @@
"@microsoft/fast-components": "^2.30.6",
"@microsoft/fast-element": "^1.13.0",
"@vscode/webview-ui-toolkit": "^1.4.0",
"async-lock": "^1.4.1",
"lodash": "^4.17.21",
"semver": "^7.6.0"
}
}
}
46 changes: 29 additions & 17 deletions tools/vscode/src/components/webview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ExtensionContext,
window,
commands,
WebviewPanel,
} from "vscode";

import { Disposable } from "../core/dispose";
Expand All @@ -13,6 +14,7 @@ import { ExtensionHost, HostWebviewPanel } from "../hooks";
import { isNotebook } from "./notebook";
import { FocusManager } from "./focus";
import { log } from "../core/log";
import { InspectViewServer } from "../providers/inspect/inspect-view-server";

export interface ShowOptions {
readonly preserveFocus?: boolean;
Expand All @@ -21,32 +23,38 @@ export interface ShowOptions {

export class InspectWebviewManager<T extends InspectWebview<S>, S> {
constructor(
protected readonly context: ExtensionContext,
protected readonly context_: ExtensionContext,
private readonly server_: InspectViewServer,
private readonly viewType_: string,
private readonly title_: string,
private readonly localResourceRoots: Uri[],
private webviewType_: new (
context: ExtensionContext,
server: InspectViewServer,
state: S,
webviewPanel: HostWebviewPanel
) => T,
private host_: ExtensionHost
) {
this.extensionUri_ = context.extensionUri;
this.extensionUri_ = context_.extensionUri;

context.subscriptions.push(
context_.subscriptions.push(
window.registerWebviewPanelSerializer(this.viewType_, {
deserializeWebviewPanel: (panel) => {
//this.restoreWebview(panel as HostWebviewPanel, state);
setTimeout(() => {
panel.dispose();
}, 200);
deserializeWebviewPanel: (panel: WebviewPanel, state?: S) => {
state = state || this.getWorkspaceState();
if (state) {
this.restoreWebview(panel as HostWebviewPanel, state);
} else {
setTimeout(() => {
panel.dispose();
}, 200);
}
return Promise.resolve();
},
})
);

this.focusManager_ = new FocusManager(context);
this.focusManager_ = new FocusManager(context_);
}
private focusManager_: FocusManager;

Expand All @@ -62,7 +70,7 @@ export class InspectWebviewManager<T extends InspectWebview<S>, S> {
if (this.activeView_) {
this.activeView_.show(state, options);
} else {
const view = this.createWebview(this.context, state, options);
const view = this.createWebview(this.context_, state, options);
this.registerWebviewListeners(view);
this.activeView_ = view;
}
Expand Down Expand Up @@ -97,6 +105,11 @@ export class InspectWebviewManager<T extends InspectWebview<S>, S> {

protected onViewStateChanged() { }

protected getWorkspaceState(): S | undefined {
return undefined;
}


private resolveOnShow() {
if (this.onShow_) {
this.onShow_();
Expand Down Expand Up @@ -147,7 +160,7 @@ export class InspectWebviewManager<T extends InspectWebview<S>, S> {


private restoreWebview(panel: HostWebviewPanel, state: S): void {
const view = new this.webviewType_(this.context, state, panel);
const view = new this.webviewType_(this.context_, this.server_, state, panel);
this.registerWebviewListeners(view);
this.activeView_ = view;
}
Expand All @@ -172,7 +185,7 @@ export class InspectWebviewManager<T extends InspectWebview<S>, S> {
}
);

const inspectWebView = new this.webviewType_(context, state, previewPanel);
const inspectWebView = new this.webviewType_(context, this.server_, state, previewPanel);
return inspectWebView;
}

Expand Down Expand Up @@ -217,7 +230,8 @@ export abstract class InspectWebview<T> extends Disposable {
public readonly onDispose = this._onDidDispose.event;

public constructor(
private readonly context: ExtensionContext,
private readonly _context: ExtensionContext,
private readonly _server: InspectViewServer,
state: T,
webviewPanel: HostWebviewPanel
) {
Expand All @@ -229,8 +243,6 @@ export abstract class InspectWebview<T> extends Disposable {
this.dispose();
})
);

this.show(state);
}

public override dispose() {
Expand All @@ -254,7 +266,7 @@ export abstract class InspectWebview<T> extends Disposable {
protected abstract getHtml(state: T): string;

protected getExtensionVersion(): string {
return (this.context.extension.packageJSON as Record<string, unknown>)
return (this._context.extension.packageJSON as Record<string, unknown>)
.version as string;
}

Expand Down Expand Up @@ -331,7 +343,7 @@ export abstract class InspectWebview<T> extends Disposable {

protected extensionResourceUrl(parts: string[]): Uri {
return this._webviewPanel.webview.asWebviewUri(
Uri.joinPath(this.context.extensionUri, ...parts)
Uri.joinPath(this._context.extensionUri, ...parts)
);
}

Expand Down
2 changes: 2 additions & 0 deletions tools/vscode/src/core/jsonrpc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// constants for json-rpc methods
export const kMethodEvalLogs = "eval_logs";
export const kMethodEvalLog = "eval_log";
export const kMethodEvalLogSize = "eval_log_size";
export const kMethodEvalLogBytes = "eval_log_bytes";
export const kMethodEvalLogHeaders = "eval_log_headers";


Expand Down
15 changes: 7 additions & 8 deletions tools/vscode/src/core/process.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SpawnSyncOptionsWithStringEncoding, spawn, spawnSync } from "child_process";
import { SpawnOptions, SpawnSyncOptionsWithStringEncoding, spawn, spawnSync } from "child_process";
import { AbsolutePath } from "./path";


Expand Down Expand Up @@ -35,27 +35,25 @@ export function runProcess(
export function spawnProcess(
cmd: string,
args: string[],
cwd: AbsolutePath,
options: SpawnOptions,
io?: {
stdout?: (data: Buffer | string) => void;
stderr?: (data: Buffer | string) => void;
stdout?: (data: string) => void;
stderr?: (data: string) => void;
},
lifecycle?: {
onError?: (error: Error) => void;
onClose?: (code: number) => void;
}
) {
// Process options
const options = {
cwd: cwd.path,
detached: true,
};
options = { detached: true, ...options };

// Start the actual process
const process = spawn(cmd, args, options);

// Capture stdout
if (process.stdout) {
process.stdout.setEncoding("utf-8");
if (io?.stdout) {
process.stdout.on("data", io.stdout);
}
Expand All @@ -65,6 +63,7 @@ export function spawnProcess(

// Capture stderr
if (process.stderr) {
process.stderr.setEncoding("utf-8");
if (io?.stderr) {
process.stderr.on("data", io.stderr);
}
Expand Down
6 changes: 3 additions & 3 deletions tools/vscode/src/core/python/exec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ export function spawnPython(
args: string[],
cwd: AbsolutePath,
io?: {
stdout?: (data: Buffer | string) => void;
stderr?: (data: Buffer | string) => void;
stdout?: (data: string) => void;
stderr?: (data: string) => void;
},
lifecycle?: {
onError?: (error: Error) => void;
Expand All @@ -89,7 +89,7 @@ export function spawnPython(
if (execCommand) {
const cmd = execCommand[0];
args = [...execCommand.slice(1), ...args];
return spawnProcess(cmd, args, cwd, io, lifecycle);
return spawnProcess(cmd, args, { cwd: cwd.path }, io, lifecycle);
} else {
throw new Error("No active Python interpreter available.");
}
Expand Down
Loading

0 comments on commit e924c25

Please sign in to comment.