- Home
- Documentation
- providers
- Python Tool and IPython Runtime
Python Tool and IPython Runtime
Python Tool and IPython Runtime
Section titled “Python Tool and IPython Runtime”This document describes the current Python execution stack in packages/coding-agent.
It covers tool behavior, kernel/gateway lifecycle, environment handling, execution semantics, output rendering, and operational failure modes.
Scope and Key Files
Section titled “Scope and Key Files”- Tool surface:
src/tools/python.ts - Session/per-call kernel orchestration:
src/ipy/executor.ts - Kernel protocol + gateway integration:
src/ipy/kernel.ts - Shared local gateway coordinator:
src/ipy/gateway-coordinator.ts - Interactive-mode renderer for user-triggered Python runs:
src/modes/components/python-execution.ts - Runtime/env filtering and Python resolution:
src/ipy/runtime.ts
What the Python tool is
Section titled “What the Python tool is”The python tool executes one or more Python cells through a Jupyter Kernel Gateway-backed kernel (not by spawning python -c directly per cell).
Tool params:
{ cells: Array<{ code: string; title?: string }>; timeout?: number; // seconds, clamped to 1..600, default 30 cwd?: string; reset?: boolean; // reset kernel before first cell only}The tool is concurrency = "exclusive" for a session, so calls do not overlap.
Gateway lifecycle
Section titled “Gateway lifecycle”There are two gateway paths:
-
External gateway (
PI_PYTHON_GATEWAY_URLset)- Uses the configured URL directly.
- Optional auth with
PI_PYTHON_GATEWAY_TOKEN. - No local gateway process is spawned or managed.
-
Local shared gateway (default path)
- Uses a single shared process coordinated under
~/.xcsh/agent/python-gateway. - Metadata file:
gateway.json - Lock file:
gateway.lock - Spawn command:
python -m kernel_gateway- bound to
127.0.0.1:<allocated-port> - startup health check:
GET /api/kernelspecs
- Uses a single shared process coordinated under
Local shared gateway coordination
Section titled “Local shared gateway coordination”acquireSharedGateway():
- Takes a file lock (
gateway.lock) with heartbeat. - Reuses
gateway.jsonif PID is alive and health check passes. - Cleans stale info/PIDs when needed.
- Starts a new gateway when no healthy one exists.
releaseSharedGateway() is currently a no-op (kernel shutdown does not tear down shared gateway).
shutdownSharedGateway() explicitly terminates the shared process and clears gateway metadata.
Important constraint
Section titled “Important constraint”python.sharedGateway=false is rejected at kernel start:
- Error:
Shared Python gateway required; local gateways are disabled - There is no per-process non-shared local gateway mode.
Kernel lifecycle
Section titled “Kernel lifecycle”Each execution uses a kernel created via POST /api/kernels on the selected gateway.
Kernel startup sequence:
- Availability check (
checkPythonKernelAvailability) - Create kernel (
/api/kernels) - Open websocket (
/api/kernels/:id/channels) - Initialize kernel env (
cwd, env vars,sys.path) - Execute
PYTHON_PRELUDE - Load extension modules from:
- user:
~/.xcsh/agent/modules/*.py - project:
<cwd>/.xcsh/modules/*.py(overrides same-name user module)
- user:
Kernel shutdown:
- Deletes remote kernel via
DELETE /api/kernels/:id - Closes websocket
- Calls shared gateway release hook (no-op today)
Session persistence semantics
Section titled “Session persistence semantics”python.kernelMode controls kernel reuse:
-
session(default)- Reuses kernel sessions keyed by session identity + cwd.
- Execution is serialized per session via a queue.
- Idle sessions are evicted after 5 minutes.
- At most 4 sessions; oldest is evicted on overflow.
- Heartbeat checks detect dead kernels.
- Auto-restart allowed once; repeated crash => hard failure.
-
per-call- Creates a fresh kernel for each execute request.
- Shuts kernel down after the request.
- No cross-call state persistence.
Multi-cell behavior in a single tool call
Section titled “Multi-cell behavior in a single tool call”Cells run sequentially in the same kernel instance for that tool call.
If an intermediate cell fails:
- Earlier cell state remains in memory.
- Tool returns a targeted error indicating which cell failed.
- Later cells are not executed.
reset=true only applies to the first cell execution in that call.
Environment filtering and runtime resolution
Section titled “Environment filtering and runtime resolution”Environment is filtered before launching gateway/kernel runtime:
- Allowlist includes core vars like
PATH,HOME, locale vars,VIRTUAL_ENV,PYTHONPATH, etc. - Allow-prefixes:
LC_,XDG_,PI_ - Denylist strips common API keys (OpenAI/Anthropic/Gemini/etc.)
Runtime selection order:
- Active/located venv (
VIRTUAL_ENV, then<cwd>/.venv,<cwd>/venv) - Managed venv at
~/.xcsh/python-env pythonorpython3on PATH
When a venv is selected, its bin/Scripts path is prepended to PATH.
Kernel env initialization inside Python also:
os.chdir(cwd)- injects provided env map into
os.environ - ensures cwd is in
sys.path
Tool availability and mode selection
Section titled “Tool availability and mode selection”python.toolMode (default both) + optional PI_PY override controls exposure:
ipy-onlybash-onlyboth
PI_PY accepted values:
0/bash->bash-only1/py->ipy-onlymix/both->both
If Python preflight fails, tool creation degrades to bash-only for that session.
Execution flow and cancellation/timeout
Section titled “Execution flow and cancellation/timeout”Tool-level timeout
Section titled “Tool-level timeout”python tool timeout is in seconds, default 30, clamped to 1..600.
The tool combines:
- caller abort signal
- timeout abort signal
with AbortSignal.any(...).
Kernel execution cancellation
Section titled “Kernel execution cancellation”On abort/timeout:
- Execution is marked cancelled.
- Kernel interrupt is attempted via REST (
POST /interrupt) and control-channelinterrupt_request. - Result includes
cancelled=true. - Timeout path annotates output as
Command timed out after <n> seconds.
stdin behavior
Section titled “stdin behavior”Interactive stdin is not supported.
If kernel emits input_request:
- Tool records
stdinRequested=true - Emits explanatory text
- Sends empty
input_reply - Execution is treated as failure at executor layer
Output capture and rendering
Section titled “Output capture and rendering”Captured output classes
Section titled “Captured output classes”From kernel messages:
stream-> plain text chunksdisplay_data/execute_result-> rich display handlingerror-> traceback text- custom MIME
application/x-xcsh-status-> structured status events
Display MIME precedence:
text/markdowntext/plaintext/html(converted to basic markdown)
Additionally captured as structured outputs:
application/json-> JSON tree dataimage/png-> image payloadsapplication/x-xcsh-status-> status events
Storage and truncation
Section titled “Storage and truncation”Output is streamed through OutputSink and may be persisted to artifact storage.
Tool results can include truncation metadata and artifact://<id> for full output recovery.
Renderer behavior
Section titled “Renderer behavior”- Tool renderer (
python.ts):- shows code-cell blocks with per-cell status
- collapsed preview defaults to 10 lines
- supports expanded mode for full output and richer status detail
- Interactive renderer (
python-execution.ts):- used for user-triggered Python execution in TUI
- collapsed preview defaults to 20 lines
- clamps very long individual lines to 4000 chars for display safety
- shows cancellation/error/truncation notices
External gateway support
Section titled “External gateway support”Set:
export PI_PYTHON_GATEWAY_URL="http://127.0.0.1:8888"# Optional:export PI_PYTHON_GATEWAY_TOKEN="..."Behavior differences from local shared gateway:
- No local gateway lock/info files
- No local process spawn/termination
- Health checks and kernel CRUD run against external endpoint
- Auth failures are surfaced with explicit token guidance
Operational troubleshooting (current failure modes)
Section titled “Operational troubleshooting (current failure modes)”-
Python tool not available
- Check
python.toolMode/PI_PY. - If preflight fails, runtime falls back to bash-only.
- Check
-
Kernel availability errors
-
Local mode requires both
kernel_gatewayandipykernelimportable in resolved Python runtime. -
Install with:
Terminal window python -m pip install jupyter_kernel_gateway ipykernel
-
-
python.sharedGateway=falsecauses startup failure- This is expected with current implementation.
-
External gateway auth/reachability failures
- 401/403 -> set
PI_PYTHON_GATEWAY_TOKEN. - timeout/unreachable -> verify URL/network and gateway health.
- 401/403 -> set
-
Execution hangs then times out
- Increase tool
timeout(max 600s) if workload is legitimate. - For stuck code, cancellation triggers kernel interrupt but user code may still need refactor.
- Increase tool
-
stdin/input prompts in Python code
input()is not supported interactively in this runtime path; pass data programmatically.
-
Resource exhaustion (
EMFILE/ too many open files)- Session manager triggers shared-gateway recovery (session teardown + shared gateway restart).
-
Working directory errors
- Tool validates
cwdexists and is a directory before execution.
- Tool validates
Relevant environment variables
Section titled “Relevant environment variables”PI_PY— tool exposure override (bash-only/ipy-only/bothmapping above)PI_PYTHON_GATEWAY_URL— use external gatewayPI_PYTHON_GATEWAY_TOKEN— optional external gateway auth tokenPI_PYTHON_SKIP_CHECK=1— bypass Python preflight/warm checksPI_PYTHON_IPC_TRACE=1— log kernel IPC send/receive tracesPI_DEBUG_STARTUP=1— emit startup-stage debug markers