Files
oh-my-pi/docs/ipy-kernel-protocol.md
T
can1357 1d414c1383 feat: added IPython-backed Python tool with streaming output and Jupyter integration
- Added IPython-backed Python tool with streaming output and image/JSON rendering.
- Implemented Jupyter kernel gateway integration with WebSocket communication.
- Added Python prelude with 30+ shell-like utility functions for file operations.
- Migrated environment variables from PI_ to OMP_ prefix with automatic migration.
- Added streaming output system with automatic spill-to-disk for large outputs.
- Reorganized settings interface into behavior, tools, display, voice, status, lsp, and exa tabs.
2026-01-18 19:32:27 +01:00

93 lines
3.5 KiB
Markdown

# IPython Kernel REPL Tool (coding-agent)
## Implementation Status: COMPLETE
The Python REPL tool has been implemented using **Jupyter Kernel Gateway** for IPC instead of direct ZeroMQ connections. This avoids Bun's incompatibility with the zeromq NAPI module (libuv `uv_async_init` not supported).
## Architecture
```
TypeScript (coding-agent)
│
├── REST API (kernel lifecycle)
│ POST /api/kernels → create kernel
│ DELETE /api/kernels/{id} → shutdown kernel
│ POST /api/kernels/{id}/interrupt → interrupt execution
│
└── WebSocket (message passing)
ws://host:port/api/kernels/{id}/channels
└── Multiplexed Jupyter protocol (shell, iopub, stdin, control)
│
▼
Jupyter Kernel Gateway (Python process)
│
└── ZeroMQ (internal, handled by pyzmq)
│
▼
ipykernel (Python kernel)
```
## Key Files
- `packages/coding-agent/src/core/python-kernel.ts` - Kernel Gateway client
- `packages/coding-agent/src/core/python-executor.ts` - Execution wrapper
- `packages/coding-agent/src/core/tools/python.ts` - Tool definition
## Dependencies
**Python (user must install):**
```bash
pip install jupyter_kernel_gateway ipykernel
```
**TypeScript:** No native dependencies. Uses standard WebSocket API.
## WebSocket Wire Protocol
The Jupyter Kernel Gateway uses a binary WebSocket protocol:
```
┌─────────────┬──────────┬──────────┬─────┬─────────┬──────────┬─────┐
│ offset_count│ offset_0 │ offset_1 │ ... │ msg │ buffer_0 │ ... │
│ (4 bytes) │ (4 bytes)│ (4 bytes)│ │ (JSON) │ (binary) │ │
└─────────────┴──────────┴──────────┴─────┴─────────┴──────────┴─────┘
```
Message JSON structure:
```json
{
"channel": "shell|iopub|stdin|control",
"header": { "msg_id", "session", "username", "date", "msg_type", "version" },
"parent_header": {},
"metadata": {},
"content": {}
}
```
## Kernel Lifecycle
1. **Start Gateway**: Spawn `python -m jupyter_kernel_gateway --port=<port>`
2. **Wait for Ready**: Poll `GET /api/kernelspecs` until 200
3. **Create Kernel**: `POST /api/kernels` with `{ "name": "python3" }`
4. **Connect WebSocket**: `ws://host:port/api/kernels/{id}/channels`
5. **Execute Code**: Send `execute_request` on shell channel
6. **Receive Output**: Handle `stream`, `execute_result`, `display_data`, `error` on iopub
7. **Shutdown**: `DELETE /api/kernels/{id}`, then kill gateway process
## Settings
| Setting | Values | Default | Description |
|---------|--------|---------|-------------|
| `python.toolMode` | `ipy-only`, `bash-only`, `both` | `ipy-only` | How Python code is executed |
| `python.kernelMode` | `session`, `per-call` | `session` | Whether to keep kernel alive |
## Previous Approach (Deprecated)
The original plan used direct ZeroMQ connections from TypeScript to ipykernel. This was abandoned because:
1. The `zeromq` npm package uses NAPI with libuv internals
2. Bun doesn't support `uv_async_init` (see https://github.com/oven-sh/bun/issues/18546)
3. No pure-JS ZeroMQ implementation exists
Jupyter Kernel Gateway solves this by handling ZeroMQ internally (via Python's pyzmq) and exposing a standard HTTP/WebSocket interface.