- Replaced Python execution with a local `python -u runner.py` subprocess and NDJSON stdin/stdout framing. - Removed shared-gateway architecture, including coordinator lifecycle APIs, `useSharedGateway` wiring, and `jupyter` CLI/actions. - Simplified setup checks to a plain Python 3 availability probe and removed automatic dependency-install fallbacks. - Updated kernel cancellation and display processing to use status frames, SIGINT/SIGTERM escalation, and normalized output coercion. - Added `python-runner` integration and display tests while deleting legacy websocket and kernel lifecycle test suites.
59 lines
2.0 KiB
TypeScript
59 lines
2.0 KiB
TypeScript
import type { ToolSession } from "../../tools";
|
|
import type { ExecutorBackend, ExecutorBackendExecOptions, ExecutorBackendResult } from "../backend";
|
|
import { executePython, type PythonExecutorOptions } from "./executor";
|
|
import { checkPythonKernelAvailability } from "./kernel";
|
|
|
|
const PYTHON_SESSION_PREFIX = "python:";
|
|
|
|
function namespaceSessionId(sessionId: string): string {
|
|
return sessionId.startsWith(PYTHON_SESSION_PREFIX) ? sessionId : `${PYTHON_SESSION_PREFIX}${sessionId}`;
|
|
}
|
|
|
|
function readSetting<T>(session: ToolSession, key: string): T | undefined {
|
|
const settings = session.settings as { get?: (key: string) => T | undefined } | undefined;
|
|
return settings?.get?.(key);
|
|
}
|
|
|
|
export default {
|
|
id: "python",
|
|
label: "Python",
|
|
highlightLang: "python",
|
|
|
|
async isAvailable(session: ToolSession): Promise<boolean> {
|
|
const availability = await checkPythonKernelAvailability(session.cwd);
|
|
return availability.ok;
|
|
},
|
|
|
|
async execute(code: string, opts: ExecutorBackendExecOptions): Promise<ExecutorBackendResult> {
|
|
const kernelMode = readSetting<PythonExecutorOptions["kernelMode"]>(opts.session, "python.kernelMode");
|
|
const executorOptions: PythonExecutorOptions = {
|
|
cwd: opts.cwd,
|
|
deadlineMs: opts.deadlineMs,
|
|
signal: opts.signal,
|
|
sessionId: namespaceSessionId(opts.sessionId),
|
|
kernelMode,
|
|
sessionFile: opts.sessionFile,
|
|
artifactsDir: opts.session.getArtifactsDir?.() ?? undefined,
|
|
kernelOwnerId: opts.kernelOwnerId,
|
|
reset: opts.reset,
|
|
artifactPath: opts.artifactPath,
|
|
artifactId: opts.artifactId,
|
|
onChunk: opts.onChunk,
|
|
toolSession: opts.session,
|
|
};
|
|
const result = await executePython(code, executorOptions);
|
|
return {
|
|
output: result.output,
|
|
exitCode: result.exitCode,
|
|
cancelled: result.cancelled,
|
|
truncated: result.truncated,
|
|
artifactId: result.artifactId,
|
|
totalLines: result.totalLines,
|
|
totalBytes: result.totalBytes,
|
|
outputLines: result.outputLines,
|
|
outputBytes: result.outputBytes,
|
|
displayOutputs: result.displayOutputs,
|
|
};
|
|
},
|
|
} satisfies ExecutorBackend;
|