@oh-my-pi/pi-coding-agent 14.9.3 → 14.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +96 -0
- package/package.json +7 -7
- package/src/async/job-manager.ts +66 -9
- package/src/capability/rule.ts +20 -0
- package/src/cli/setup-cli.ts +14 -161
- package/src/cli/stats-cli.ts +56 -2
- package/src/cli.ts +0 -1
- package/src/config/model-registry.ts +13 -0
- package/src/config/model-resolver.ts +8 -2
- package/src/config/settings-schema.ts +1 -11
- package/src/edit/index.ts +8 -0
- package/src/edit/renderer.ts +6 -1
- package/src/edit/streaming.ts +53 -2
- package/src/eval/eval.lark +30 -10
- package/src/eval/js/context-manager.ts +334 -601
- package/src/eval/js/shared/helpers.ts +237 -0
- package/src/eval/js/shared/indirect-eval.ts +30 -0
- package/src/eval/js/{prelude.txt → shared/prelude.txt} +0 -2
- package/src/eval/js/shared/rewrite-imports.ts +211 -0
- package/src/eval/js/shared/runtime.ts +168 -0
- package/src/eval/js/shared/types.ts +18 -0
- package/src/eval/js/tool-bridge.ts +2 -4
- package/src/eval/js/worker-core.ts +146 -0
- package/src/eval/js/worker-entry.ts +24 -0
- package/src/eval/js/worker-protocol.ts +41 -0
- package/src/eval/parse.ts +218 -49
- package/src/eval/py/display.ts +71 -0
- package/src/eval/py/executor.ts +97 -96
- package/src/eval/py/index.ts +2 -2
- package/src/eval/py/kernel.ts +472 -900
- package/src/eval/py/prelude.py +106 -87
- package/src/eval/py/runner.py +879 -0
- package/src/eval/py/runtime.ts +3 -16
- package/src/eval/py/tool-bridge.ts +137 -0
- package/src/export/html/template.css +12 -0
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +113 -7
- package/src/extensibility/plugins/loader.ts +31 -6
- package/src/extensibility/skills.ts +20 -0
- package/src/internal-urls/agent-protocol.ts +63 -52
- package/src/internal-urls/artifact-protocol.ts +51 -51
- package/src/internal-urls/docs-index.generated.ts +35 -3
- package/src/internal-urls/index.ts +6 -19
- package/src/internal-urls/local-protocol.ts +49 -7
- package/src/internal-urls/mcp-protocol.ts +2 -8
- package/src/internal-urls/memory-protocol.ts +89 -59
- package/src/internal-urls/router.ts +38 -22
- package/src/internal-urls/rule-protocol.ts +2 -20
- package/src/internal-urls/skill-protocol.ts +4 -27
- package/src/main.ts +1 -1
- package/src/mcp/manager.ts +17 -0
- package/src/modes/components/session-observer-overlay.ts +2 -2
- package/src/modes/components/tool-execution.ts +6 -0
- package/src/modes/components/tree-selector.ts +4 -0
- package/src/modes/controllers/command-controller.ts +0 -23
- package/src/modes/controllers/event-controller.ts +23 -2
- package/src/modes/controllers/mcp-command-controller.ts +7 -10
- package/src/modes/interactive-mode.ts +2 -2
- package/src/modes/theme/theme.ts +27 -27
- package/src/modes/types.ts +1 -1
- package/src/modes/utils/ui-helpers.ts +14 -9
- package/src/prompts/commands/orchestrate.md +1 -0
- package/src/prompts/system/project-prompt.md +10 -2
- package/src/prompts/system/subagent-system-prompt.md +8 -8
- package/src/prompts/system/system-prompt.md +13 -7
- package/src/prompts/tools/ask.md +0 -1
- package/src/prompts/tools/bash.md +0 -10
- package/src/prompts/tools/eval.md +15 -30
- package/src/prompts/tools/github.md +6 -5
- package/src/prompts/tools/hashline.md +1 -0
- package/src/prompts/tools/job.md +14 -6
- package/src/prompts/tools/task.md +20 -3
- package/src/registry/agent-registry.ts +2 -1
- package/src/sdk.ts +87 -89
- package/src/session/agent-session.ts +58 -21
- package/src/session/artifacts.ts +7 -4
- package/src/session/history-storage.ts +77 -19
- package/src/session/session-manager.ts +30 -1
- package/src/ssh/connection-manager.ts +32 -16
- package/src/ssh/sshfs-mount.ts +10 -7
- package/src/system-prompt.ts +0 -5
- package/src/task/executor.ts +14 -2
- package/src/task/index.ts +19 -5
- package/src/tool-discovery/tool-index.ts +21 -8
- package/src/tools/ast-edit.ts +3 -2
- package/src/tools/ast-grep.ts +3 -2
- package/src/tools/bash.ts +15 -9
- package/src/tools/browser/tab-protocol.ts +4 -0
- package/src/tools/browser/tab-supervisor.ts +98 -7
- package/src/tools/browser/tab-worker.ts +104 -58
- package/src/tools/eval.ts +49 -11
- package/src/tools/fetch.ts +1 -1
- package/src/tools/gh.ts +140 -4
- package/src/tools/index.ts +12 -11
- package/src/tools/job.ts +48 -12
- package/src/tools/read.ts +5 -4
- package/src/tools/search.ts +3 -2
- package/src/tools/todo-write.ts +1 -1
- package/src/web/scrapers/mastodon.ts +1 -1
- package/src/web/scrapers/repology.ts +7 -7
- package/src/web/search/index.ts +6 -4
- package/src/cli/jupyter-cli.ts +0 -106
- package/src/commands/jupyter.ts +0 -32
- package/src/eval/py/cancellation.ts +0 -28
- package/src/eval/py/gateway-coordinator.ts +0 -424
- package/src/internal-urls/jobs-protocol.ts +0 -120
- package/src/prompts/system/now-prompt.md +0 -7
- /package/src/eval/js/{prelude.ts → shared/prelude.ts} +0 -0
package/src/eval/py/executor.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { getProjectDir, logger } from "@oh-my-pi/pi-utils";
|
|
2
2
|
import { OutputSink } from "../../session/streaming-output";
|
|
3
|
-
import {
|
|
3
|
+
import type { ToolSession } from "../../tools";
|
|
4
|
+
import type { JsStatusEvent } from "../js/shared/types";
|
|
5
|
+
import type { KernelDisplayOutput } from "./display";
|
|
4
6
|
import {
|
|
5
7
|
checkPythonKernelAvailability,
|
|
6
|
-
type KernelDisplayOutput,
|
|
7
8
|
type KernelExecuteOptions,
|
|
8
9
|
type KernelExecuteResult,
|
|
9
10
|
PythonKernel,
|
|
10
11
|
} from "./kernel";
|
|
12
|
+
import { ensurePyToolBridge, registerPyToolBridge } from "./tool-bridge";
|
|
11
13
|
|
|
12
14
|
const IDLE_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
13
15
|
const MAX_KERNEL_SESSIONS = 4;
|
|
@@ -35,13 +37,30 @@ export interface PythonExecutorOptions {
|
|
|
35
37
|
kernelMode?: PythonKernelMode;
|
|
36
38
|
/** Restart the kernel before executing */
|
|
37
39
|
reset?: boolean;
|
|
38
|
-
/** Use shared gateway across pi instances (default: true) */
|
|
39
|
-
useSharedGateway?: boolean;
|
|
40
40
|
/** Session file path for accessing task outputs */
|
|
41
41
|
sessionFile?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Effective artifacts directory for the current session. Subagents share
|
|
44
|
+
* the parent's directory, so this can differ from `sessionFile`'s sibling
|
|
45
|
+
* dir. When present, exported to the kernel as `PI_ARTIFACTS_DIR` and
|
|
46
|
+
* preferred over `PI_SESSION_FILE`-derived paths.
|
|
47
|
+
*/
|
|
48
|
+
artifactsDir?: string;
|
|
42
49
|
/** Artifact path/id for full output storage */
|
|
43
50
|
artifactPath?: string;
|
|
44
51
|
artifactId?: string;
|
|
52
|
+
/**
|
|
53
|
+
* ToolSession used to resolve host-side `tool.<name>(args)` calls made from
|
|
54
|
+
* the Python prelude's bridge proxy. When omitted, the bridge env vars are
|
|
55
|
+
* not injected and any `tool.foo(...)` raises in Python.
|
|
56
|
+
*/
|
|
57
|
+
toolSession?: ToolSession;
|
|
58
|
+
/** Callback for status events emitted by tool bridge invocations. */
|
|
59
|
+
emitStatus?: (event: JsStatusEvent) => void;
|
|
60
|
+
/** @internal Bridge session id, set by `executePython` before delegating. */
|
|
61
|
+
bridgeSessionId?: string;
|
|
62
|
+
/** @internal Bridge endpoint info, set by `executePython` before delegating. */
|
|
63
|
+
bridge?: { url: string; token: string };
|
|
45
64
|
}
|
|
46
65
|
|
|
47
66
|
export interface PythonKernelExecutor {
|
|
@@ -80,7 +99,6 @@ interface KernelSession {
|
|
|
80
99
|
restartCount: number;
|
|
81
100
|
dead: boolean;
|
|
82
101
|
needsRestart: boolean;
|
|
83
|
-
kernelInvalidatedByRecovery: boolean;
|
|
84
102
|
disposing: boolean;
|
|
85
103
|
disposeCapacityPromise?: Promise<void>;
|
|
86
104
|
resolveDisposeCapacity?: () => void;
|
|
@@ -100,11 +118,15 @@ const disposingKernelSessions = new Set<KernelSession>();
|
|
|
100
118
|
let cleanupTimer: NodeJS.Timeout | null = null;
|
|
101
119
|
|
|
102
120
|
interface KernelSessionExecutionOptions {
|
|
103
|
-
useSharedGateway?: boolean;
|
|
104
121
|
sessionFile?: string;
|
|
122
|
+
artifactsDir?: string;
|
|
105
123
|
signal?: AbortSignal;
|
|
106
124
|
deadlineMs?: number;
|
|
107
125
|
kernelOwnerId?: string;
|
|
126
|
+
/** Bridge session identifier exported into the kernel env as PI_TOOL_BRIDGE_SESSION. */
|
|
127
|
+
bridgeSessionId?: string;
|
|
128
|
+
/** Cached bridge connection info. When present, env vars for tool.<name>() get injected. */
|
|
129
|
+
bridge?: { url: string; token: string };
|
|
108
130
|
}
|
|
109
131
|
|
|
110
132
|
class PythonExecutionCancelledError extends Error {
|
|
@@ -123,6 +145,29 @@ function getExecutionDeadlineMs(options?: Pick<PythonExecutorOptions, "deadlineM
|
|
|
123
145
|
return Date.now() + options.timeoutMs;
|
|
124
146
|
}
|
|
125
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Build the env block exposed to the Python kernel. Includes the session file
|
|
150
|
+
* (for things that need the raw session path) and the effective artifacts
|
|
151
|
+
* directory (preferred by the prelude when resolving output IDs, so subagents
|
|
152
|
+
* see the parent's flat dir instead of a non-existent sibling).
|
|
153
|
+
*/
|
|
154
|
+
function buildKernelEnv(options: {
|
|
155
|
+
sessionFile?: string;
|
|
156
|
+
artifactsDir?: string;
|
|
157
|
+
bridgeSessionId?: string;
|
|
158
|
+
bridge?: { url: string; token: string };
|
|
159
|
+
}): Record<string, string> | undefined {
|
|
160
|
+
const env: Record<string, string> = {};
|
|
161
|
+
if (options.sessionFile) env.PI_SESSION_FILE = options.sessionFile;
|
|
162
|
+
if (options.artifactsDir) env.PI_ARTIFACTS_DIR = options.artifactsDir;
|
|
163
|
+
if (options.bridge && options.bridgeSessionId) {
|
|
164
|
+
env.PI_TOOL_BRIDGE_URL = options.bridge.url;
|
|
165
|
+
env.PI_TOOL_BRIDGE_TOKEN = options.bridge.token;
|
|
166
|
+
env.PI_TOOL_BRIDGE_SESSION = options.bridgeSessionId;
|
|
167
|
+
}
|
|
168
|
+
return Object.keys(env).length > 0 ? env : undefined;
|
|
169
|
+
}
|
|
170
|
+
|
|
126
171
|
function getRemainingTimeoutMs(deadlineMs?: number): number | undefined {
|
|
127
172
|
if (deadlineMs === undefined) return undefined;
|
|
128
173
|
return deadlineMs - Date.now();
|
|
@@ -245,7 +290,6 @@ function buildKernelStartOptions(
|
|
|
245
290
|
return {
|
|
246
291
|
cwd,
|
|
247
292
|
env,
|
|
248
|
-
useSharedGateway: options.useSharedGateway,
|
|
249
293
|
signal: options.signal,
|
|
250
294
|
deadlineMs: options.deadlineMs,
|
|
251
295
|
};
|
|
@@ -329,7 +373,6 @@ function finishDisposingKernelSession(session: KernelSession): void {
|
|
|
329
373
|
session.disposeResultPromise = undefined;
|
|
330
374
|
session.disposeResultTimeoutMs = undefined;
|
|
331
375
|
session.nextDisposalRetryAt = undefined;
|
|
332
|
-
session.kernelInvalidatedByRecovery = false;
|
|
333
376
|
syncCleanupTimer();
|
|
334
377
|
}
|
|
335
378
|
|
|
@@ -453,58 +496,6 @@ async function ensureKernelAvailable(
|
|
|
453
496
|
}
|
|
454
497
|
}
|
|
455
498
|
|
|
456
|
-
function isResourceExhaustionError(error: unknown): boolean {
|
|
457
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
458
|
-
return (
|
|
459
|
-
message.includes("Too many open files") ||
|
|
460
|
-
message.includes("EMFILE") ||
|
|
461
|
-
message.includes("ENFILE") ||
|
|
462
|
-
message.includes("resource temporarily unavailable")
|
|
463
|
-
);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
function clearSharedGatewayDisposingKernelSessionTracking(): void {
|
|
467
|
-
for (const session of Array.from(disposingKernelSessions.values())) {
|
|
468
|
-
if (!session.kernel.isSharedGateway) continue;
|
|
469
|
-
if (session.heartbeatTimer) {
|
|
470
|
-
clearInterval(session.heartbeatTimer);
|
|
471
|
-
session.heartbeatTimer = undefined;
|
|
472
|
-
}
|
|
473
|
-
disposingKernelSessions.delete(session);
|
|
474
|
-
session.resolveDisposeCapacity?.();
|
|
475
|
-
session.resolveDisposeCapacity = undefined;
|
|
476
|
-
session.disposeCapacityPromise = undefined;
|
|
477
|
-
session.resolveDisposeAttempt?.();
|
|
478
|
-
session.resolveDisposeAttempt = undefined;
|
|
479
|
-
session.disposeAttemptPromise = undefined;
|
|
480
|
-
session.disposeResultPromise = undefined;
|
|
481
|
-
session.disposeResultTimeoutMs = undefined;
|
|
482
|
-
session.nextDisposalRetryAt = undefined;
|
|
483
|
-
session.kernelInvalidatedByRecovery = false;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
function markLiveKernelSessionsForRecovery(): void {
|
|
488
|
-
for (const session of kernelSessions.values()) {
|
|
489
|
-
if (session.heartbeatTimer) {
|
|
490
|
-
clearInterval(session.heartbeatTimer);
|
|
491
|
-
session.heartbeatTimer = undefined;
|
|
492
|
-
}
|
|
493
|
-
session.needsRestart = true;
|
|
494
|
-
session.kernelInvalidatedByRecovery = session.kernel.isSharedGateway;
|
|
495
|
-
session.restartCount = 0;
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
async function recoverFromResourceExhaustion(): Promise<void> {
|
|
500
|
-
logger.warn("Resource exhaustion detected, recovering by restarting shared gateway");
|
|
501
|
-
stopCleanupTimer();
|
|
502
|
-
markLiveKernelSessionsForRecovery();
|
|
503
|
-
clearSharedGatewayDisposingKernelSessionTracking();
|
|
504
|
-
await shutdownSharedGateway();
|
|
505
|
-
syncCleanupTimer();
|
|
506
|
-
}
|
|
507
|
-
|
|
508
499
|
function ensureKernelHeartbeat(session: KernelSession): void {
|
|
509
500
|
if (session.heartbeatTimer) return;
|
|
510
501
|
session.heartbeatTimer = setInterval(() => {
|
|
@@ -520,24 +511,12 @@ async function createKernelSession(
|
|
|
520
511
|
sessionId: string,
|
|
521
512
|
cwd: string,
|
|
522
513
|
options: KernelSessionExecutionOptions = {},
|
|
523
|
-
isRetry?: boolean,
|
|
524
514
|
): Promise<KernelSession> {
|
|
525
515
|
requireRemainingTimeoutMs(options.deadlineMs);
|
|
526
|
-
const env
|
|
527
|
-
? { PI_SESSION_FILE: options.sessionFile }
|
|
528
|
-
: undefined;
|
|
516
|
+
const env = buildKernelEnv(options);
|
|
529
517
|
const startOptions = buildKernelStartOptions(cwd, env, options);
|
|
530
518
|
|
|
531
|
-
|
|
532
|
-
try {
|
|
533
|
-
kernel = await logger.time("createKernelSession:PythonKernel.start", PythonKernel.start, startOptions);
|
|
534
|
-
} catch (err) {
|
|
535
|
-
if (!isRetry && isResourceExhaustionError(err)) {
|
|
536
|
-
await recoverFromResourceExhaustion();
|
|
537
|
-
return createKernelSession(sessionId, cwd, options, true);
|
|
538
|
-
}
|
|
539
|
-
throw err;
|
|
540
|
-
}
|
|
519
|
+
const kernel = await logger.time("createKernelSession:PythonKernel.start", PythonKernel.start, startOptions);
|
|
541
520
|
|
|
542
521
|
const hasFallbackOwner = options.kernelOwnerId === undefined;
|
|
543
522
|
const initialOwnerId = options.kernelOwnerId ?? sessionId;
|
|
@@ -548,7 +527,6 @@ async function createKernelSession(
|
|
|
548
527
|
restartCount: 0,
|
|
549
528
|
dead: false,
|
|
550
529
|
needsRestart: false,
|
|
551
|
-
kernelInvalidatedByRecovery: false,
|
|
552
530
|
disposing: false,
|
|
553
531
|
disposeResultPromise: undefined,
|
|
554
532
|
nextDisposalRetryAt: undefined,
|
|
@@ -573,28 +551,23 @@ async function restartKernelSession(
|
|
|
573
551
|
}
|
|
574
552
|
requireRemainingTimeoutMs(options.deadlineMs);
|
|
575
553
|
try {
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
});
|
|
587
|
-
}
|
|
554
|
+
const deadKernel = session.dead || !session.kernel.isAlive();
|
|
555
|
+
const shutdownTimeoutMs = requireRemainingTimeoutMs(options.deadlineMs);
|
|
556
|
+
const shutdownResult = await session.kernel.shutdown({ signal: options.signal, timeoutMs: shutdownTimeoutMs });
|
|
557
|
+
if (!shutdownResult.confirmed && !deadKernel) {
|
|
558
|
+
throw new Error("Failed to confirm crashed kernel shutdown before restart");
|
|
559
|
+
}
|
|
560
|
+
if (!shutdownResult.confirmed) {
|
|
561
|
+
logger.warn("Proceeding with retained kernel restart after unconfirmed dead-kernel shutdown", {
|
|
562
|
+
sessionId: session.id,
|
|
563
|
+
});
|
|
588
564
|
}
|
|
589
|
-
const env
|
|
590
|
-
? { PI_SESSION_FILE: options.sessionFile }
|
|
591
|
-
: undefined;
|
|
565
|
+
const env = buildKernelEnv(options);
|
|
592
566
|
const startOptions = buildKernelStartOptions(cwd, env, options);
|
|
593
567
|
const kernel = await PythonKernel.start(startOptions);
|
|
594
568
|
session.kernel = kernel;
|
|
595
569
|
session.dead = false;
|
|
596
570
|
session.needsRestart = false;
|
|
597
|
-
session.kernelInvalidatedByRecovery = false;
|
|
598
571
|
session.lastUsedAt = Date.now();
|
|
599
572
|
ensureKernelHeartbeat(session);
|
|
600
573
|
} catch (err) {
|
|
@@ -608,9 +581,6 @@ type KernelDisposalResult = { status: "confirmed" } | { status: "unconfirmed" }
|
|
|
608
581
|
type KernelDisposalWaitResult = KernelDisposalResult | { status: "timedOut" };
|
|
609
582
|
|
|
610
583
|
function createKernelDisposalResultPromise(session: KernelSession, timeoutMs?: number): Promise<KernelDisposalResult> {
|
|
611
|
-
if (session.kernelInvalidatedByRecovery) {
|
|
612
|
-
return Promise.resolve({ status: "confirmed" as const });
|
|
613
|
-
}
|
|
614
584
|
return Promise.resolve()
|
|
615
585
|
.then(() => session.kernel.shutdown(timeoutMs === undefined ? undefined : { timeoutMs }))
|
|
616
586
|
.then(
|
|
@@ -854,6 +824,20 @@ async function executeWithKernel(
|
|
|
854
824
|
const deadlineMs = getExecutionDeadlineMs(options);
|
|
855
825
|
let executionTimeoutMs: number | undefined;
|
|
856
826
|
|
|
827
|
+
const emitStatus =
|
|
828
|
+
options?.emitStatus ??
|
|
829
|
+
((event: JsStatusEvent) => {
|
|
830
|
+
displayOutputs.push({ type: "status", event });
|
|
831
|
+
});
|
|
832
|
+
const unregisterBridge =
|
|
833
|
+
options?.toolSession && options?.bridgeSessionId
|
|
834
|
+
? registerPyToolBridge(options.bridgeSessionId, {
|
|
835
|
+
toolSession: options.toolSession,
|
|
836
|
+
signal: options.signal,
|
|
837
|
+
emitStatus,
|
|
838
|
+
})
|
|
839
|
+
: null;
|
|
840
|
+
|
|
857
841
|
try {
|
|
858
842
|
executionTimeoutMs = requireRemainingTimeoutMs(deadlineMs);
|
|
859
843
|
const result = await kernel.execute(code, {
|
|
@@ -906,6 +890,8 @@ async function executeWithKernel(
|
|
|
906
890
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
907
891
|
logger.error("Python execution failed", { error: error.message });
|
|
908
892
|
throw error;
|
|
893
|
+
} finally {
|
|
894
|
+
unregisterBridge?.();
|
|
909
895
|
}
|
|
910
896
|
}
|
|
911
897
|
|
|
@@ -936,10 +922,22 @@ export async function executePython(code: string, options?: PythonExecutorOption
|
|
|
936
922
|
await ensureKernelAvailable(cwd);
|
|
937
923
|
|
|
938
924
|
const kernelMode = executionOptions.kernelMode ?? "session";
|
|
939
|
-
|
|
925
|
+
|
|
926
|
+
if (executionOptions.toolSession && !executionOptions.bridge) {
|
|
927
|
+
try {
|
|
928
|
+
executionOptions.bridge = await ensurePyToolBridge();
|
|
929
|
+
} catch (err) {
|
|
930
|
+
logger.warn("Failed to start Python tool bridge", {
|
|
931
|
+
error: err instanceof Error ? err.message : String(err),
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
}
|
|
940
935
|
|
|
941
936
|
if (kernelMode === "per-call") {
|
|
942
|
-
|
|
937
|
+
if (executionOptions.bridge && !executionOptions.bridgeSessionId) {
|
|
938
|
+
executionOptions.bridgeSessionId = `py-bridge:${crypto.randomUUID()}`;
|
|
939
|
+
}
|
|
940
|
+
const env = buildKernelEnv(executionOptions);
|
|
943
941
|
requireRemainingTimeoutMs(deadlineMs);
|
|
944
942
|
const startOptions = buildKernelStartOptions(cwd, env, executionOptions);
|
|
945
943
|
const kernel = await PythonKernel.start(startOptions);
|
|
@@ -951,6 +949,9 @@ export async function executePython(code: string, options?: PythonExecutorOption
|
|
|
951
949
|
}
|
|
952
950
|
|
|
953
951
|
const sessionId = executionOptions.sessionId ?? `session:${cwd}`;
|
|
952
|
+
if (executionOptions.bridge && !executionOptions.bridgeSessionId) {
|
|
953
|
+
executionOptions.bridgeSessionId = sessionId;
|
|
954
|
+
}
|
|
954
955
|
if (executionOptions.reset) {
|
|
955
956
|
const existing = kernelSessions.get(sessionId);
|
|
956
957
|
if (existing) {
|
package/src/eval/py/index.ts
CHANGED
|
@@ -25,7 +25,6 @@ export default {
|
|
|
25
25
|
},
|
|
26
26
|
|
|
27
27
|
async execute(code: string, opts: ExecutorBackendExecOptions): Promise<ExecutorBackendResult> {
|
|
28
|
-
const useSharedGateway = readSetting<boolean>(opts.session, "python.sharedGateway");
|
|
29
28
|
const kernelMode = readSetting<PythonExecutorOptions["kernelMode"]>(opts.session, "python.kernelMode");
|
|
30
29
|
const executorOptions: PythonExecutorOptions = {
|
|
31
30
|
cwd: opts.cwd,
|
|
@@ -33,13 +32,14 @@ export default {
|
|
|
33
32
|
signal: opts.signal,
|
|
34
33
|
sessionId: namespaceSessionId(opts.sessionId),
|
|
35
34
|
kernelMode,
|
|
36
|
-
useSharedGateway,
|
|
37
35
|
sessionFile: opts.sessionFile,
|
|
36
|
+
artifactsDir: opts.session.getArtifactsDir?.() ?? undefined,
|
|
38
37
|
kernelOwnerId: opts.kernelOwnerId,
|
|
39
38
|
reset: opts.reset,
|
|
40
39
|
artifactPath: opts.artifactPath,
|
|
41
40
|
artifactId: opts.artifactId,
|
|
42
41
|
onChunk: opts.onChunk,
|
|
42
|
+
toolSession: opts.session,
|
|
43
43
|
};
|
|
44
44
|
const result = await executePython(code, executorOptions);
|
|
45
45
|
return {
|