rlm(...) spawns real child agents for parallel or background work and returns their results programmatically from within the persistent IPython environment.[1] As of v0.2.3, subagents became first-class sessions: opening a subagent attaches to its own session and renders through the same rich chat UI as the main conversation instead of a laggy parent-rebuilt transcript; finished subagents stay viewable in the session list and sort below running ones.[2]
RlmRunRequest in packages/coding-agent/src/core/rlm-runtime.ts carries prompt, kwargs, and an optional cellSourceCode (the IPython cell that issued the rlm.run call) for display purposes.[3] RlmSpawnHandle — the value returned when a child agent is spawned — carries rlm_child_id, name, session_dir, and model, not a blocking result, reflecting fire-and-forget spawn semantics introduced in v0.6.0.[3] Subagent registry status in packages/coding-agent/src/core/rlm-runtime.ts is one of three string literals: "running", "completed", or "error".[3] RlmDeleteSubagentResult includes an optional outcome field with values "deleted" or "skipped_running", allowing callers to distinguish a successful deletion from a no-op due to the subagent still running.[3]
SubagentRuntimeHost in packages/coding-agent/src/core/rlm-runtime.ts is the interface the daemon or supervisor implements; only createRlmSubagentRuntime and deleteRlmSubagentRuntime are required — completeRlmSubagentRuntime, releaseRlmSubagentRuntime, and disposeRlmSubagentRuntimes are optional lifecycle hooks.[3] CreateRlmSubagentRuntimeOptions includes rlmDepth, rlmMaxDepth, and rlmParentNodeId, allowing the host to enforce recursion depth limits when spawning child agents.[3] CreateRlmSubagentRuntimeOptions.onSessionPublished is a callback that fires before the host makes the runtime addressable, allowing the parent session to be informed of the child session immediately after creation.[3] Live RLM child sessions (including grandchildren) are tracked under the children field of DaemonSessionSnapshot in packages/coding-agent/src/modes/daemon/daemon-protocol.ts, typed as AgentConnectionRlmChildAgentSnapshot[] — see Daemon protocol for the broader snapshot schema.[4] rlm-ledger.ts in packages/coding-agent/src/modes/daemon/ centralizes RLM spawn ledger ownership at the daemon supervisor layer (daemon-supervisor.ts), making it the single authoritative source of truth for tracking which RLM subagents belong to a given agent family. Centralizing the RLM spawn ledger to daemon-supervisor.ts via rlm-ledger.ts prevents races and split-brain state between sibling subagents that arose when ledger state was managed per-session in daemon-mode.ts. The consolidation of RLM subagent metadata onto the spawn ledger touched daemon-catalog-process.ts, daemon-mode.ts, rlm-ledger.ts, rlm-subagent-display.ts, test/rlm-ledger.test.ts, and test/daemon-mode.test.ts. When an RLM child agent is deleted, the daemon cleans up stale kernel state in agent-traces.ts and session-manager.ts and deduplicates artifact paths in session-file-actions.ts at write time. Invariants for RLM child-lifecycle teardown — kernel state cleanup and artifact path deduplication — are covered by session-artifacts-delete.test.ts and session-manager/artifact-paths.test.ts. The agents view (agents-view-mode.ts and agents-view-state.ts) surfaces the model identifier and effort setting for each RLM subagent alongside session info; agents-view-state.ts carries model and effort fields per agent entry. 502-unified-session-view.test.ts covers rendering of model and effort fields in the agents view. CreateRlmSubagentRuntimeOptions includes a thinkingLevel field that specifies the reasoning level for a spawned subagent, overriding the parent's reasoning level for that child. Reasoning level selection for RLM subagents is tested in 4649-subagent-model-selection.test.ts. Goal-continuation logic in agent-session.ts includes a quiescence check that defers goal continuations while any subagent work item remains in an unsettled state, preventing the orchestrator from racing ahead of outstanding subagent tasks. goal-continuation-quiescence.test.ts covers the hold-and-release behavior of goal continuations when subagent work items are unsettled. rlmMaxDepth defaults to 2, enforced in agent-session.ts and settings-manager.ts; deeper RLM recursion requires an explicit rlmMaxDepth override passed through CreateRlmSubagentRuntimeOptions. The prime-agent-runtime package provides a minimal CPython REPL implementation (rlm.repl) as the default execution host for RLM subagent sessions; the IPython tool layer remains available but is no longer the primary REPL host. RLM idle-detection in agent-session.ts is driven entirely by the activity-change event bus rather than a polling loop, eliminating periodic busy-waiting when no subagents are running; any new activity source must emit on that bus to be visible to the idle detector. Switching to activity-change event-based quiescence detection in agent-session.ts also fixes a post-compaction idle regression where the session could miss the quiescence signal after a compaction event. RLM child session snapshot projection logic is centralized in a single code path; agent-session.ts, daemon-mode.ts, and daemon-session-list.ts derive their views from the same source to prevent divergence bugs. daemon-session-list.test.ts and agent-session-recursion.test.ts cover the RLM child snapshot projection contract. RLM task-tree cancellation in agent-session.ts uses an iterative traversal with a visited set, guaranteeing each subagent node is cancelled exactly once and avoiding stack overflow or double-visits in deep or cyclic spawn graphs. agent-session-recursion.test.ts validates the cancellation contract for multi-level spawn graphs, asserting each subagent node is cancelled exactly once.
createRlmRunHostHandler validates that payload.prompt is a string and coerces a missing or non-object payload.kwargs to {}; it is the adapter between the kernel host bridge wire format and RlmRunHandler.[3] createRlmDeleteSubagentHostHandler requires payload.target to be a non-empty string and trims whitespace before delegating; a missing or blank value throws immediately.[3]
findRlmModelMatches in packages/coding-agent/src/core/rlm-runtime.ts scores models against a query using exact match (lowest score), prefix match, and partial match across the provider/id, id, and name fields; unmatched models are excluded entirely.[3] Passing an empty query to findRlmModelMatches returns all models (up to limit) with score 0, functioning as an unfiltered catalog listing.[3]
All prompt-building logic for RLM subagents lives in packages/coding-agent/src/core/prompts/rlm.js; packages/coding-agent/src/core/prompts/index.ts is a pure re-export barrel that surfaces buildChildAgentDoctrine, buildRlmPrompt, buildSubagentGuidance, ChildAgentDoctrineOptions, and RlmPromptOptions with no logic of its own.[5] buildSubagentGuidance receives hasAgentMessage and hasAgentObserve flags derived from whether the agent_message and agent_observe Python skills are installed, allowing the guidance to tailor inter-agent communication instructions — see Skills for how those skills are defined.[6]
In v0.5.0, subagent guidance was changed to retain reusable children and delete completed direct children once they are no longer needed.[7]
Sources
README.mdgithub.com…llect-ai/prime-agent/releases/tag/v0.2.3packages/coding-agent/src/core/rlm-runtime.tspackages/coding-agent/src/modes/daemon/daemon-protocol.tspackages/coding-agent/src/core/prompts/index.tspackages/coding-agent/src/core/system-prompt.tsgithub.com…llect-ai/prime-agent/releases/tag/v0.5.0