prime-agent
CLI ToolPrimeIntellect-ai/prime-agent
A self-improving AI coding agent for long-running autonomous tasks.
Overview
Prime Agent is an open-source coding and research agent built around a Recursive Language Model (RLM) and a continual harness. It uses a persistent IPython environment with programmatic file operations, shell commands, and subagents. It features daemon-backed background sessions, direct agent-to-agent communication, and autonomous mode for long-running tasks.
README Preview
\n \n \n \n \n \n \n \n\n\n\nPrime Agent: A Self-Improving RLM Agent\n\n\n\n Documentation •\n Verifiers •\n PRIME-RL •\n pi-mono\n\n\n\n \n \n \n \n \n \n\n\nPrime Agent is an open-source coding and research agent for general and long-running work. It is designed around two core abstractions:\n\n- The **[Recursive Language Model (RLM)](https://www.primeintellect.ai/blog/rlm)** treats context as variables (*prompt-as-a-variable*) and tools like recursive subagents as function calls (*programmatic tool /sub-agent calling*) inside a persistent REPL.\n- The **[Continual Harness](https://arxiv.org/abs/2605.09998)** stores supplemental prompts, memories, skill descriptions, and reusable subagent specifications as durable state that Prime Agent can refine through small, evidence-backed updates, local to the session by default.\n\nPrime Agent combines a persistent Python control environment with durable harness state, so useful working context and reusable operating patterns can outlive a single chat window.\n\n- **Everything is programmatic:** persistent IPython is the built-in model tool; file operations, shell commands, tool use, subagents, and context management happen through code.\n- **Subagents are built in:** `rlm(...)` spawns real child agents for parallel or background work and returns their results programmatically.\n- **The harness can improve:** `/refine` reviews the current trajectory and can apply small, evidence-backed updates to supplemental harness state. It never rewrites the immutable base system prompt, and recorded snapshots support rollback.\n- **Skills are executable:** skills are importable Python packages, and the built-in skill creator can turn recurring workflows into project or personal skills.\n- **Sessions run in the background:** daemon-backed agents keep running when the terminal disconnects and can be reattached later.\n- **Agents communicate directly:** running agents can exchange messag
FAQ (5)
TroubleshootingHow do I fix Bedrock Claude 5 prompt caching not sending cachePoint blocks and billing every request as fresh input?
This is a bug in packages/ai/src/providers/amazon-bedrock.ts in prime-agent packages/ai 0.7.x and main at commit 9fb6cde. supportsPromptCaching() only enables caching for model IDs containing -4-, claude-3-7-sonnet, or claude-3-5-haiku, so Claude 5 IDs such as claude-fable-5-1, claude-opus-5-5, and claude-sonnet-5 silently omit cachePoint blocks. Setting AWS_BEDROCK_FORCE_CACHE=1 does not work because the function returns from the Claude-model branch before checking that environment variable. Apply the upstream fix or patch the function to recognize Claude 5+ models: add if (candidates.some((s) => /claude-(?:fable|opus|sonnet|haiku)-(?:[5-9]|\d{2,})(?:-|$)/.test(s))) return true; beside the existing -4- and legacy Claude checks. A safer long-term fix is to assume all Claude models support caching except a short deny list of pre-3.7 models. Rebuild and redeploy the packages/ai package, then make two consecutive ConverseStream calls with the same prefix. The second response should report cacheReadInputTokens > 0; testing on us.anthropic.claude-fable-5-1 returned cacheReadInputTokens: 21829. Monitor cache-read tokens versus fresh input tokens to confirm caching is active.
TroubleshootingHow to fix the pa-tui panic "byte index is not a char boundary" caused by a malformed non-ASCII CSI escape sequence?
The panic occurs because decode_csi_with_modifier passes a Unicode character count to str::split_at, which requires a UTF-8 byte offset. For a multi-byte character such as é in input like \x1b[;éA, the calculated offset can land inside the character.
In crates/pa-tui/src/input.rs, replace:
let (modifier, final_char) = last.split_at(last.chars().count() - 1);
with a byte boundary derived from char_indices:
let final_index = last
.char_indices()
.next_back()
.map_or(0, |(index, _)| index);
let (modifier, final_char) = last.split_at(final_index);
This splits at the start of the final UTF-8 character. The existing modifier.parse::<u8>() then rejects the malformed prefix normally instead of crashing the TUI. Use a build containing the fix for issue #3175; until then, avoid sending malformed non-ASCII CSI sequences to the terminal.
TroubleshootingHow do I prevent dill snapshot restore from truncating write-mode files to zero bytes after a kernel restart?
The failure occurs because dill 0.4.1 serializes file objects, including closed handles, as _create_filehandle(name, mode). When _restore_state calls dill.loads(), dill reopens the saved path. If the saved mode is "w", the reopen uses O_TRUNC, silently zeroing the file before any post-load check can close the handle.
Immediate workaround:
1. Do not leave with open(...) as f variables in the kernel namespace. Delete them after the block:
with open("/path/file.md", "w") as f:
f.write(data)
del f
2. Before restarting, remove any file objects from the namespace:
import io
for name, value in list(globals().items()):
if isinstance(value, io.IOBase):
try:
value.close()
except Exception:
pass
del globals()[name]
3. Existing snapshot records containing dill _create_filehandle must be discarded or stripped before dill.loads() runs. Checking the object after loading is too late because the file is already truncated during deserialization.
Permanent fix in prime-agent-runtime/src/rlm/repl.py, in _snapshot_state (~line 714):
import io
if isinstance(value, io.IOBase):
skipped.append({"name": name, "reason": "file handle"})
continue
Also strip legacy _create_filehandle records in _read_snapshot_records before deserialization. A post-load file-object check in _restore_state is only defense-in-depth cleanup; it cannot prevent the initial O_TRUNC. Upgrade to a release containing the v0.1.21 recovery-safety fix if available, and restore affected files from backup.
TroubleshootingWhy does ACP session/prompt return end_turn even when the model response was truncated at max_tokens?
This is a bug in prime-agent's ACP stop-reason mapping: it only considers the cancellation flag and autonomous token-budget status, so a final model call with finish_reason: "length" is incorrectly reported as stopReason: "end_turn". Upgrade to a release containing the fix acp: report max_tokens when the final model response was truncated. If building from source, update acp_stop_reason_for_status in crates/pa-daemon/src/acp/meta.rs and the TypeScript acpStopReason mapping in acp-stop-reason.ts so that the final assistant message's stopReason: "length" maps to ACP stopReason: "max_tokens". As a workaround, inspect the per-call model traces and treat finish_reason=length or output tokens equal to the token cap as truncation.
TroubleshootingWhy does auto-compaction fail with "Prompt is too long: N tokens > M maximum context length" error on oMLX / OpenAI-compatible local models?
The overflow detector is_context_overflow (crates/pa-ai/src/utils_inner/overflow.rs) doesn't recognize oMLX's 400 error message, so no compaction, trailing-assistant drop, or retry happens, and every subsequent prompt in the session fails identically. Two regex gaps cause this: (1) the prompt is too long pattern is case-sensitive but oMLX capitalizes "Prompt"; (2) the pattern maximum context length is \d+ tokens expects a different word order than oMLX's N tokens > M maximum context length. Fix: change the pattern to (?i)prompt is too long and/or add a new pattern (?i)tokens > \d+ maximum context length. Workaround until patched: when switching a session to a model with a smaller context window (e.g., from a large OpenRouter model to a 262k local model), manually run compaction or start a fresh session before the overflow occurs.