-
Notifications
You must be signed in to change notification settings - Fork 0
packages coding agent rlm runtime
Active contributors: Mario Zechner, kt, Armin Ronacher
Prime Agent is built around a recursive language model (RLM) runtime: the model works inside a persistent Python control environment and composes capabilities as code. Provider calls, session persistence, child lifecycles, scheduling, and safety policy remain in the TypeScript host; the IPython kernel is the model-facing programming surface. The programming model is documented in packages/coding-agent/docs/rlm.md and the runtime architecture in packages/coding-agent/docs/rlm-runtime.md.
The TypeScript-side runtime core lives in packages/coding-agent/src/core/rlm-runtime.ts. Supporting pieces include the recursion depth gate (rlm-max-depth.ts), agent-to-agent messaging (agent-messages.ts), system-prompt construction (system-prompt.ts), side questions (side-question.ts), and shared command execution (exec.ts). The Python rlm package shim runs in the kernel and is covered by the rlm package page.
packages/coding-agent/src/core/
├── rlm-runtime.ts # Typed rlm.run host handlers, spawn handles, model search
├── rlm-max-depth.ts # Wire-safe /rlm-max-depth state types
├── agent-messages.ts # Agent-to-agent messaging types, prompts, host handlers
├── system-prompt.ts # buildSystemPrompt: RLM guidance + subagent doctrine
├── side-question.ts # startSideQuestion: /btw side turns
└── exec.ts # execCommand: shared shell execution for extensions/tools
| Type | Path | Description |
|---|---|---|
RlmRunRequest |
packages/coding-agent/src/core/rlm-runtime.ts |
Request for an rlm.run host call: prompt, kwargs, and optional cell source. |
RlmSpawnHandle |
packages/coding-agent/src/core/rlm-runtime.ts |
Admission handle returned immediately: rlm_child_id, name, session_dir, model. |
RlmSubagentRegistryEntry |
packages/coding-agent/src/core/rlm-runtime.ts |
A tracked direct child with status and session identity. |
RlmModelMatch |
packages/coding-agent/src/core/rlm-runtime.ts |
A bounded model match from find_models. |
RlmSubagentRuntime |
packages/coding-agent/src/core/rlm-runtime.ts |
Host-owned child runtime wrapping an AgentSession. |
CreateRlmSubagentRuntimeOptions |
packages/coding-agent/src/core/rlm-runtime.ts |
Everything needed to spawn a child: model, thinking level, tools, depth. |
SubagentRuntimeHost |
packages/coding-agent/src/core/rlm-runtime.ts |
Host interface to create, complete, release, delete, and dispose child runtimes. |
RlmMaxDepthStatus |
packages/coding-agent/src/core/rlm-max-depth.ts |
Current max depth and its source (default, env, global, inherited, chat). |
AgentSessionMessage |
packages/coding-agent/src/core/agent-messages.ts |
A custom session message carrying an agent-to-agent payload. |
SideQuestionRun |
packages/coding-agent/src/core/side-question.ts |
A running side question with done and abort. |
ExecResult |
packages/coding-agent/src/core/exec.ts |
stdout, stderr, code, and killed flag from execCommand. |
flowchart TD
model["Parent model"]
ipython["IPython tool call"]
kernel["Persistent IPython kernel"]
shim["rlm Python shim"]
comm["comm target host.request"]
host["AgentSession host handlers"]
child["Child AgentSession"]
provider["Model provider"]
model --> ipython --> kernel --> shim
shim -->|"await rlm('task')"| comm
comm -->|"rlm.run"| host
host -->|"admit, return RLMSpawnHandle"| comm
comm -->|"control channel reply"| shim
shim -->|"handle.rlm_child_id ..."| model
host --> child --> provider
child -->|"agent_message.send(receiver_role='parent')"| host
The callable rlm is preloaded in the kernel. await rlm("task", name="x") travels over a Jupyter comm target named host.request; KernelManager dispatches request type rlm.run to the parent AgentSession, which checks depth, resolves or inherits the model, admits the child into the parent registry, and returns an admission handle. The call never waits for or returns the child's answer. Results arrive only through explicit agent_message replies or files. createRlmRunHostHandler, createRlmFindModelsHostHandler, createRlmListSubagentsHostHandler, and createRlmDeleteSubagentHostHandler in packages/coding-agent/src/core/rlm-runtime.ts adapt each handler into the typed kernel host bridge.
The rlm callable mirrors the RLM loop in packages/coding-agent/docs/rlm.md: the parent keeps its own context focused while Python holds working state and child agents receive only the context needed for their subtasks.
Child creation runs through CreateRlmSubagentRuntimeOptions and SubagentRuntimeHost in packages/coding-agent/src/core/rlm-runtime.ts. The session runtime (see the session runtime page) checks RLM_DEPTH < RLM_MAX_DEPTH, creates a sub-xxxxxxxx child directory under the parent artifact directory, admits the task and returns its handle, then runs the child prompt independently. Children inherit the parent model, provider, skills, tools, retry policy, and resource loader unless another configured model is requested. Default maximum depth is 1, so roots may create children but not grandchildren; the depth is raised via /rlm-max-depth (wire-safe state in packages/coding-agent/src/core/rlm-max-depth.ts) or RLM_MAX_DEPTH. findRlmModelMatches scores the authenticated model catalog by exact, prefix, and partial matches without adding it to the system prompt.
packages/coding-agent/src/core/agent-messages.ts implements messaging within an agent's nuclear family (parent, siblings, direct children). Key pieces:
-
buildAgentFamilyRosterderives the relationship graph;assertAgentFamilyReachandagentFamilyRelationshipenforce the parent/sibling/child boundary. Broadcast is rejected. -
createAgentSessionMessageandcreateAgentSessionMessagePromptformat the received-message prompt with[from <relationship>:<name>]andMessage idlines;parseAgentSessionMessagePromptIdandisAgentSessionMessagerecognize these messages. -
createAgentMessageHostHandlersexposesagent_message.list_agentsandagent_message.sendhost handlers, enforcingreceiver_role(parent,sibling,child) andreceiver_nameselection rules. -
AgentSessionMessageRateLimiterapplies token-bucket rate limiting per target withcapacity/refillMs. - Defaults cap message length (
DEFAULT_AGENT_MESSAGE_MAX_CHARS), pending per session, and rate limit.
Children reply with await agent_message.send(message, receiver_role="parent"); the parent can follow up with a retained child via receiver_role="child", receiver_name=<name>. The parent-scoped registry (await rlm.list_subagents()) survives compaction and kernel restart, and await rlm.delete_subagent(...) cancels or closes a child runtime.
buildSystemPrompt in packages/coding-agent/src/core/system-prompt.ts composes the RLM prompt through buildRlmPrompt from packages/coding-agent/src/core/prompts/, then appends subagent delegation guidance (buildSubagentGuidance) when recursion is enabled and IPython is available, the continual harness overview (see the refinement page), project context files, and the skills section. buildChildAgentDoctrine injects a child-agent doctrine for nested agents with the installed Python skill imports, active tools, depth, and parent identity.
startSideQuestion in packages/coding-agent/src/core/side-question.ts runs a /btw (side) question in a separate Agent whose tools are disabled. It re-clones the live main conversation each turn so follow-ups see the newest context, replays earlier side turns, and emits running, complete, cancelled, or error events. The side conversation is never added to the main session.
The default RLM runtime exposes one built-in model tool, ipython. Reading and editing files, running project commands, invoking skills, and delegating work all begin from that persistent kernel. Python state survives across tool calls and compaction. %%bash cells are temporary subshells, while Python state and %cd changes persist. packages/coding-agent/src/core/exec.ts provides execCommand, a shared spawn-based executor used by extensions and custom tools that supports abort signals, timeouts, and per-call env merging.
-
packages/coding-agent/src/core/kernel/owns the Jupyter transport andhost.requestcomm dispatch (see the session runtime page). - The session runtime (
packages/coding-agent/src/core/agent-session.ts) implements child creation, the registry, usage attribution, cancellation, and goal handlers. -
system-prompt.tsfeeds the RLM doctrine, subagent specs, skills, and harness overview to the model. - The
agent-message,agent-observe,rlm-heartbeat,goal, andcompactskills are kernel-side host-bridge clients. - The Python
rlmpackage is the model-facing shim; see therlmpackage page forRLMSpawnHandle,RLMModel,RLMSubagent, andTokenUsage.
- To change
rlm.runvalidation or host-handler adaptation, editpackages/coding-agent/src/core/rlm-runtime.ts. - To change depth reporting, edit
packages/coding-agent/src/core/rlm-max-depth.ts. - To change agent messaging policy or prompts, edit
packages/coding-agent/src/core/agent-messages.ts. - To change the RLM system prompt, edit
buildSystemPromptinpackages/coding-agent/src/core/system-prompt.tsand the prompt builders inpackages/coding-agent/src/core/prompts/. - To change side-question behavior, edit
packages/coding-agent/src/core/side-question.ts.
| File | Role |
|---|---|
packages/coding-agent/src/core/rlm-runtime.ts |
rlm.run host handlers, spawn handles, model search. |
packages/coding-agent/src/core/rlm-max-depth.ts |
Max-depth state for /rlm-max-depth. |
packages/coding-agent/src/core/agent-messages.ts |
Agent-to-agent messaging. |
packages/coding-agent/src/core/system-prompt.ts |
RLM prompt, subagent doctrine, harness overview. |
packages/coding-agent/src/core/side-question.ts |
/btw side turns. |
packages/coding-agent/src/core/exec.ts |
Shared shell command execution. |
- Package overview, SDK surface for the coding-agent package
-
Session runtime,
AgentSessionchild creation and kernel management -
Skills, the
agent-message,agent-observe,rlm-heartbeatskills -
Refinement,
rlm.harnessstate and subagent specs -
rlmpackage, the Python IPython kernel shim - Patterns and conventions, repo rules