The IPython tool, implemented in packages/coding-agent/src/core/tools/ipython.ts, accepts a single code string field described as 'Python scratchpad code or %%bash shell cells to execute in the agent kernel', with guidance to use the target project's own environment for project imports, tests, scripts, CLIs, and dependency checks instead of direct kernel imports.[1] The Python kernel runtime is set up automatically on first invocation; the PRIME_AGENT_KERNEL_PYTHON environment variable can be set to point to an existing Python environment with ipykernel instead.[2] A code comment marks the persistent kernel with a TODO to reconsider whether it is needed once RLM-1 weights land, indicating it may not be required long-term.[1] A kernel namespace snapshot captures the names and serialized values of kernel variables at a point in time, enabling their restoration in a future session without re-running the original code. The kernel namespace snapshot/restore contract is defined in state-snapshot.ts and is covered by the test suites kernel-state-roundtrip.test.ts and kernel-state-snapshot.test.ts. After each execution, the IPython kernel captures a namespace snapshot and prunes oversized kernel state before injecting it into subsequent turns; this cycle is implemented across kernel/index.ts, kernel/state-snapshot.ts, tools/ipython.ts, and the RLM system prompt. agent-session.ts coordinates the kernel state trim/restore cycle to prevent unbounded namespace growth, which would otherwise inflate context length and risk inference slowdowns or context-window overflows in long coding sessions.
buildRlmBootstrapCode generates IPython kernel bootstrap code that sets NO_COLOR=1, disables IPython color output, applies nest_asyncio, imports rlm (or installs the missing-rlm stub), and — when Python skills are provided — imports each skill module, wrapping it in _PrimeAgentCallableSkillModule so the module itself is directly awaitable.[1] When rlm cannot be imported into the IPython kernel, a _PrimeAgentMissingRlm stub is placed in the rlm global; calling .run(), .find_models(), .list_subagents(), .delete_subagent(), or the callable form raises a RuntimeError advising the user to remove ~/.prime/agent/kernel-venv so prime-agent can rebuild it.[1] When a Python skill module fails to import during kernel bootstrap, a _PrimeAgentUnavailableSkill stub is placed in the global namespace under the skill's name; calling it raises a RuntimeError with the import error message.[1]
IpythonToolOptions.provisioner is a shared IpythonKernelProvisioner that owns the kernel lifecycle; when provided, all other kernel-configuration options are ignored.[1] IpythonToolOptions.readyGate is a Promise<unknown> that resolves before the kernel starts, preventing a /reload's old-kernel snapshot flush from racing the new kernel's restore.[1] IpythonToolOptions.snapshotDir specifies the per-session artifact directory for kernel namespace snapshots; omitting it disables snapshots entirely.[1] IpythonToolOptions.onRestore fires once per kernel start when a previous session's namespace was revived (some names restored or some failed), enabling the session to inform the model about restored state.[1] %%bash cells can have a commandPrefix prepended to every cell body and/or a shellPath substituted for the %%bash magic (converting it to %%script <shellPath>) when IpythonToolOptions.commandPrefix or shellPath are set.[1]
IpythonToolDetails captures per-execution metadata including status ("ok" | "error" | "aborted" | "starting"), durationMs, stdout/stderr, result text, diff displays, kernel attachments, sent agent messages, and a kernelRestarted boolean.[1] The raceWithAbort helper wraps any promise with an AbortSignal; if the signal is already aborted at call time, the promise is immediately rejected without subscribing, and an optional onAbort callback fires synchronously when the signal fires.[1]
The IPython cell component in packages/coding-agent/src/modes/interactive/components/ipython-cell.ts applies syntax highlighting to the full cell content as a single unit before splitting for display, so multi-line string literals and other newline-spanning tokens retain correct color across line boundaries.
Sources