agentram
v0.1.65
Published
Async, model-agnostic Working RAM for coding agents.
Maintainers
Readme
AgentRAM
Async, model-agnostic Working RAM for coding agents such as Codex, Claude Code, Cursor, and custom MCP clients.
AgentRAM lets the main coding agent keep solving while a memory layer records events, decisions, file activity, task state, and long-running goals into a small project-local RAM store.
Why
Coding agents can lose direction after long sessions, compact, restart, or model switch. AgentRAM keeps durable context outside the model session:
- Source-of-truth event log.
- Structured RAM notes.
- Goal Stack to reduce goal drift.
- MCP tools any compatible coding agent can call.
- Swappable memory adapters: heuristic, Ollama, OpenAI-compatible APIs, Anthropic Claude API.
Quick Start
Install from local clone:
git clone https://github.com/trancongnghia/AGENT_RAM.git
cd RAMofagent
pip install -e .
python -m pytest -qInstall from GitHub directly:
pip install git+https://github.com/trancongnghia/AGENT_RAM.gitRun MCP server inside any project you want to give memory:
cd C:/path/to/your/project
agentram-mcpAgentRAM creates project-local storage automatically:
.agentram/
events.jsonl
memory.json
goal_state.json
project.jsonNo --ram-root required. Use --ram-root only when you want memory outside the project or shared across projects.
Model setup can be shared globally through agent_profile.jsonl, but goal_state.json, memory.json, and events.jsonl stay project-local. project.json records the project path and AgentRAM warns if the same RAM root is reused from a different folder.
If using the Claude plugin, .mcp.json sets AGENTRAM_AUTO_INIT=true, so these files are created when MCP starts. You can also call agentram_init manually.
Terminal UI CLI
AgentRAM includes a terminal UI with Claude-like slash autocomplete. It uses prompt_toolkit when installed and falls back to plain input() otherwise:
pip install -e ".[tui]"
agentramEquivalent explicit command:
agentram tuiInstall Claude Code commands and subagents into the current project:
agentram claude-install --target .Buttons inside the UI:
[1] Init RAM [2] Status [3] Retrieve
[4] Goal Show [5] Goal Set [6] Drift Check
[7] Events [8] Replay [9] Help [0] ExitUseful non-interactive commands:
agentram init
agentram status
agentram goal
agentram retrieve "adapter Groq memory writer"
agentram drift "Refactor MCP server"
agentram replayUse another RAM folder when needed:
agentram --ram-root C:/path/to/project/.agentram statusnpm / npx Usage
AgentRAM can also run through npm. Node only launches the Python package; Python 3.10+ must still be installed.
After the package is published to npm:
npm install -g agentram
agentram status
agentram tui
agentram-mcpRun without global install:
npx agentram status
npx agentram tui
npx agentram retrieve "adapter Groq memory writer"Run directly from GitHub before npm publish:
npx github:trancongnghia/AGENT_RAM status
npx github:trancongnghia/AGENT_RAM tuiRun from local clone:
npm install
npm run agentram -- status
npm run agentram -- tui
npm run agentram:mcpPublish to npm:
npm login
npm publish --access publicUse with Claude/Codex MCP through npm wrapper:
{
"mcpServers": {
"agentram": {
"type": "stdio",
"command": "agentram-mcp",
"args": []
}
}
}If python is not the right binary, set PYTHON:
PYTHON=python3 npx agentram statusCoding TUI, Slash Commands, And Subagents
AgentRAM TUI now behaves like a coding-agent CLI inspired by freecodexyz/free-code: left status panel, chat transcript, slash command registry, RAM tool calls, and Claude subagent prompt templates.
Run TUI:
agentram tuiSupported TUI slash commands. Plain text only records/retrieves RAM; use /ask to call bound models:
/help
/init
/status
/retrieve <query>
/goal
/set-goal current_goal="Ship CLI" current_task="Add slash commands"
/drift <task>
/events
/replay
/agents
/agent reviewer <task>
/claude-install .
/note <decision>
/clear
/exitClaude Code repo templates are included:
.claude/commands/ram.md
.claude/commands/ram-drift.md
.claude/commands/ram-note.md
.claude/commands/ram-status.md
.claude/agents/agentram-memory.md
.claude/agents/agentram-planner.md
.claude/agents/agentram-reviewer.md
.claude/agents/agentram-docs.mdUsage inside Claude Code:
/ram adapter memory writer
/ram-drift refactor MCP server
/ram-note Use npm wrapper only as Python launcher.
/ram-statusSubagent intent:
agentram-memory: records durable notes, no code edits.agentram-planner: checks Goal Stack and plans work.agentram-reviewer: reviews changes against RAM and goal drift.agentram-docs: updates docs from repo state and RAM notes.
Install In Coding Agents
Codex MCP
Add to Codex config:
[mcp_servers.agentram]
command = "agentram-mcp"
args = []Fallback if entrypoint is unavailable:
[mcp_servers.agentram]
command = "python"
args = ["-m", "agentram.mcp_server"]Claude Code MCP Command
After installing package:
claude mcp add --transport stdio agentram -- python -m agentram.mcp_serverOr:
claude mcp add --transport stdio agentram -- agentram-mcpCheck:
claude mcp listInside Claude Code:
/mcpClaude Code Plugin
This repo includes Claude plugin and marketplace files:
.claude-plugin/plugin.json
.claude-plugin/marketplace.json
.mcp.jsonInstall from local path inside Claude Code:
/plugin install C:/path/to/RAMofagentOr clone first:
git clone https://github.com/trancongnghia/AGENT_RAM.git
cd RAMofagentThen inside Claude Code:
/plugin install .Marketplace install from GitHub:
/plugin marketplace add agentram https://github.com/trancongnghia/AGENT_RAM
/plugin install agentram@agentramIf Claude Code uses marketplace name from .claude-plugin/marketplace.json, install with:
/plugin install agentram@agentram-marketplaceThe plugin starts AgentRAM using .mcp.json:
{
"mcpServers": {
"agentram": {
"type": "stdio",
"command": "python",
"args": ["${CLAUDE_PLUGIN_ROOT}/agentram_mcp_server.py"],
"env": {
"AGENTRAM_AUTO_INIT": "true",
"AGENTRAM_AUTO_WORKFLOW": "true",
"AGENTRAM_HOST_AGENT": "claude"
}
}
}
}Claude Desktop / JSON MCP Clients
{
"mcpServers": {
"agentram": {
"type": "stdio",
"command": "python",
"args": ["-m", "agentram.mcp_server"]
}
}
}Other Coding Agents
Any agent can use AgentRAM if it supports stdio MCP servers:
command: python
args: ["-m", "agentram.mcp_server"]Minimum usage pattern:
- Call
agentram_retrieveat task start. - Call
agentram_emit_eventafter important reads, writes, tool calls, and decisions. - Call
agentram_check_goal_driftbefore switching direction. - Call
agentram_retrieveagain near context pressure or resume.
Multi-Model Coding Orchestration
AgentRAM can bind multiple coding model endpoints and let Claude Code or MCP clients orchestrate them in parallel. This keeps the free-code style command registry, but adds project RAM, Goal Stack, and multi-agent model routing.
Bind models:
agentram bind-model claude-subagent agentram-reviewer --role reviewer
agentram bind-model claude claude-3-5-sonnet-latest --role reviewer --api-key-env ANTHROPIC_API_KEY
agentram bind-model openai-compatible qwen2.5-coder --role coder --base-url http://localhost:8000/v1 --api-key-env OPENAI_API_KEYClaude Code subagent endpoint uses your local Claude CLI entrypoint. model is the subagent name from .claude/agents, for example agentram-reviewer or agentram-planner. Default command is claude -p. Override command when needed:
set AGENTRAM_CLAUDE_COMMAND=claude
agentram bind-model claude-subagent agentram-reviewer --role reviewerBuild a dry-run orchestration plan:
agentram orchestrate "review CLI orchestration" --file agentram/cli.pyRun endpoints concurrently when keys and base URLs are configured:
agentram orchestrate "review CLI orchestration" --file agentram/cli.py --executeClaude/MCP tools:
agentram_bind_coding_model
agentram_read_coding_models
agentram_build_coding_orchestration
agentram_run_coding_orchestrationTUI slash commands. Plain text only records/retrieves RAM; use /ask to call bound models:
/bind-model claude-subagent agentram-reviewer role=reviewer
/bind-model claude claude-3-5-sonnet-latest role=reviewer api_key_env=ANTHROPIC_API_KEY
/models
/orchestrate review CLI orchestration
/ask xin chà oStorage:
.agentram/agent_profile.jsonlMCP Tools
| Tool | Purpose |
| --- | --- |
| agentram_init | Create .agentram files without overwriting existing memory. |
| agentram_retrieve | Return Goal Stack plus relevant RAM notes. |
| agentram_emit_event | Append event and optionally ingest into memory. |
| agentram_replay_events | Rebuild memory from events.jsonl. |
| agentram_read_task_state | Read RAM notes for one task_id. |
| agentram_read_goal_state | Read mission, goals, current task, histories. |
| agentram_update_goal_state | Update Goal Stack fields. |
| agentram_check_goal_drift | Warn only when task appears off-goal. |
| agentram_bind_coding_model | Bind provider/model/role/modalities endpoint. |
| agentram_read_coding_models | Read bound coding model endpoints. |
| agentram_build_coding_orchestration | Build multi-agent prompts without model calls. |
| agentram_run_coding_orchestration | Dry-run or execute endpoints concurrently. |
Init
Create .agentram files explicitly:
{}Returns created file names and paths. Existing files are not overwritten.
Retrieve
{
"query": "adapter Groq memory writer",
"task_id": "codex",
"limit": 8
}Returns:
context: prompt-ready Goal Stack plus relevant notes.items: raw memory items.
Emit Event
{
"type": "READ_FILE",
"payload": {"path": "agentram/adapter.py"},
"task_id": "codex",
"ingest": true
}Supported event types:
USER_MESSAGE user request or instruction
AGENT_MESSAGE agent output or final answer
READ_FILE file opened/read by agent
WRITE_FILE file changed by agent
TOOL_CALL shell/tool/API action
DECISION durable design or implementation choiceGoal State
{
"mission": "Build shared Working RAM for AI coding agents.",
"project_goal": "AgentRAM v1",
"current_milestone": "Goal Runtime",
"current_goal": "Reduce goal drift",
"current_task": "Add goal_state.json",
"next_tasks": ["Drift warning"],
"goal_history": ["Design schema"],
"decision_history": [
{
"content": "Event log is source of truth.",
"source_events": ["evt_123"],
"confidence": 0.9
}
]
}goal_history and decision_history append instead of replacing previous history.
Goal Drift Check
Aligned task returns no suggestions:
{
"status": "ok",
"aligned": true,
"warning": null,
"next_actions": []
}Off-goal task returns warning:
{
"status": "drift_risk",
"aligned": false,
"warning": "Potential goal drift. Confirm scope change or update goal_state before continuing.",
"next_actions": ["Confirm task belongs to current goal stack."]
}How It Works
Coding Agent
|
| emits events through MCP
v
events.jsonl ---- replayable source of truth
|
v
Memory Adapter heuristic / Ollama / OpenAI-compatible / Anthropic
|
v
memory.json normalized RAM notes
|
+--> retriever returns relevant notes
|
v
goal_state.json mission, goals, current task, history, decisionsDesign rules:
- Main agent should not block on long memory work.
events.jsonlis source of truth.memory.jsonstores normalized notes, not model-specific prose.goal_state.jsonstores durable project direction.- Every RAM note links to
source_events. - Current files beat RAM when they conflict.
Goal Stack
AgentRAM stores durable goal context separately from normal notes:
Mission (user problem/system to build)
-> Project Goal (final outcome; stop when achieved)
-> Milestones
-> Current Goal (current feature/objective)
-> Current Task (concrete plan/action)
-> Next TasksThis helps after compact, restart, model switch, or multi-day work. The agent can recover not only what it was doing, but why the task matters.
Field meaning:
mission: nhiệm vụ hệ thống cần xây dựng; bài toán user đặt ra cho coding agent để lên ý tưởng và kế hoạch.project_goal: mục đích cuối cùng cần đạt; khi hệ thống đạt đủ thứ user cần thì project goal kết thúc.current_goal: mục tiêu hiện tại của hệ thống/chức năng đang xây.current_task: kế hoạch hoặc hành động cụ thể cần thực hiện để xây dựng chức năng.
Compact Working Context
Long projects should not send the full RAM history back into the main agent. AgentRAM builds a compact prompt context instead:
Goal Stack
+ compact project summary
+ relevant retrieved notes
+ latest events only
-> main/supervisor/small agent promptWith these env values, AgentRAM auto-creates supervisor, main, and small agents from Claude Code when the MCP server starts. /setup remains optional if you want to override models, base URL, or keys.
For Codex MCP configs, use the same idea but set:
"env": {
"AGENTRAM_AUTO_INIT": "true",
"AGENTRAM_AUTO_WORKFLOW": "true",
"AGENTRAM_HOST_AGENT": "codex"
}Defaults:
AGENTRAM_CONTEXT_CHAR_BUDGET=6000limits the context block sent to agents.AGENTRAM_COMPACT_ITEM_THRESHOLD=40creates one compact summary note when memory grows.- Old
events.jsonlandmemory.jsonstay durable, but main agent only sees relevant compact context. - Small memory agent keeps updating goal/task and notes after each supervisor/main event.
Manual compact:
agentram compact
agentram compact codexInside TUI:
/compact
/compact codexThe Textual TUI shows compact progress in the activity line while it reads RAM, writes the compact summary, and rebuilds the bounded context block.
This prevents token growth during multi-hour or multi-day sessions while keeping Goal Stack and decisions recoverable.
Background Daemon
Use daemon when you want event logging fast and memory ingestion in background.
Run once:
agentram-daemon --onceRun continuously:
agentram-daemon --interval 1Replay all events:
agentram-daemon --replay-allRecommended parallel mode:
- MCP client calls
agentram_emit_eventwithingest: false. agentram-daemontailsevents.jsonl.- Daemon updates
memory.jsonindependently. - Agent calls
agentram_retrievewhen it needs RAM.
Wrapper CLI
Use wrapper when an agent does not support MCP yet:
agentram-codex "fix auth bug" --dry-runRun another command with RAM injected through stdin:
agentram-codex "fix auth bug" -- codex execUseful options:
--task-id task namespace, default codex
--ram-root storage root, default .agentram in cwd
--adapter heuristic | ollama | openai-compatible | anthropic
--prompt-as-arg pass prompt as final argv instead of stdin
--dry-run print injected prompt onlyMemory Adapters
Heuristic
Default adapter. No model, no network, deterministic.
from agentram.orchestrator import AgentRAM
ram = AgentRAM(root=".agentram")Ollama
from agentram.adapter import OllamaMemoryAdapter
from agentram.orchestrator import AgentRAM
ram = AgentRAM(
root=".agentram",
adapter=OllamaMemoryAdapter(model="qwen2.5:7b"),
)Notes:
qwen2.5:7bis recommended for local JSON reliability.- Adapter uses
format: "json",temperature: 0, andnum_predict: 512.
OpenAI-Compatible
Works with Groq, vLLM, LM Studio, llama.cpp server, LocalAI, Ollama /v1, OpenRouter-style gateways, and OpenAI-compatible APIs.
from agentram.adapter import OpenAICompatibleMemoryAdapter
from agentram.orchestrator import AgentRAM
ram = AgentRAM(
root=".agentram",
adapter=OpenAICompatibleMemoryAdapter(
model="openai/gpt-oss-20b",
base_url="https://api.groq.com/openai/v1",
api_key="YOUR_KEY",
use_response_format=False,
),
)Anthropic Claude API
Uses Anthropic API directly. This is separate from Claude Code's active model and requires ANTHROPIC_API_KEY.
from agentram.adapter import AnthropicMemoryAdapter
from agentram.orchestrator import AgentRAM
ram = AgentRAM(
root=".agentram",
adapter=AnthropicMemoryAdapter(
model="claude-3-5-haiku-latest",
api_key="YOUR_ANTHROPIC_KEY",
),
)Wrapper usage:
agentram-codex "test Claude memory writer" --adapter anthropic --dry-runEnvironment Config
Copy template:
cp .env.example .envFill values for OpenAI-compatible/Groq:
BASE_URL=https://api.groq.com/openai/v1
Model=openai/gpt-oss-20b
API_KEY=replace_meFill values for Anthropic:
ANTHROPIC_API_KEY=replace_me
ANTHROPIC_MODEL=claude-3-5-haiku-latest
ANTHROPIC_BASE_URL=https://api.anthropic.com/v1Supported keys:
base_url: BASE_URL or OPENAI_BASE_URL
model: AGENTRAM_MODEL, Model, MODEL, CODEX_MODEL, CODEX_DEFAULT_MODEL, CLAUDE_MODEL, CURSOR_MODEL, or AGENT_MODEL
api_key: API_KEY, OPENAI_API_KEY, GROQ_API_KEY, or ANTHROPIC_API_KEY
timeout: AGENTRAM_TIMEOUT
json: AGENTRAM_RESPONSE_FORMAT=true|false
anthropic: ANTHROPIC_MODEL, ANTHROPIC_BASE_URL, ANTHROPIC_VERSIONModel selection order:
- Dedicated memory model:
AGENTRAM_MODEL,Model, orMODEL. - Current coding-agent model env:
CODEX_MODEL,CODEX_DEFAULT_MODEL,CLAUDE_MODEL,CURSOR_MODEL, orAGENT_MODEL. - Clear config error if no model found.
Run smoke test:
python examples/openai_compatible_smoke.pyMultiple Projects
Recommended: one RAM root per project.
project-a/.agentram/
project-b/.agentram/If mission or project goal appears unchanged after switching folders, check the RAM root shown by agentram status or TUI startup. Same RAM root means same goal_state.json.
If sharing memory intentionally, use explicit roots:
agentram-mcp --ram-root C:/AgentRAM/project-a
agentram-mcp --ram-root C:/AgentRAM/project-bUse task_id to split tasks inside the same project RAM:
agentram-codex "fix auth bug" --task-id auth-bug
agentram-codex "refactor adapter" --task-id adapter-refactorPython API
import asyncio
from agentram.orchestrator import AgentRAM
from agentram.retriever import MemoryRetriever
from agentram.schema import Event, EventType
async def main():
ram = AgentRAM(root=".agentram")
await ram.start()
ram.emit(Event(type=EventType.READ_FILE, payload={"path": "main.py"}, task_id="demo"))
ram.emit(Event(type=EventType.DECISION, payload={"content": "Use event log as source of truth."}, task_id="demo"))
await ram.stop()
block = MemoryRetriever(ram.memory_store).context_block("event log", task_id="demo")
print(block)
asyncio.run(main())Model Adapter Contract
Adapters must return normalized memory patches:
{
"patches": [
{
"op": "upsert",
"type": "decision",
"content": "Use Event Log as source of truth.",
"source_events": ["evt_123"],
"related_files": ["agentram/storage.py"],
"confidence": 0.9,
"scope": "task"
}
]
}Rules:
- Output JSON only.
- Use only input event ids.
- Do not invent files or facts.
- Keep notes short and factual.
- Return empty
patchesif nothing important.
Development
Run tests:
python -m pytest -qCompile check:
python -B -m compileall agentram tests codex_ram.py agentram_mcp_server.py agentram_daemon.py examplesRun local demo:
python -m agentram.demoValidate plugin JSON:
python -c "import json; [json.load(open(f, encoding='utf-8')) for f in ['.claude-plugin/plugin.json', '.mcp.json']]; print('json ok')"Public Repo Hygiene
Do not commit:
.env.agentram/.agentram_*/__pycache__/.pytest_cache/- real API keys or provider tokens
Use .env.example as the shareable template.
Limitations
- Immediate MCP ingest uses local heuristic adapter.
- Model-based ingestion is best run through daemon/wrapper configuration.
- Wrapper CLI records command-level events, not deep internal agent tool events.
- Rich file/tool hooks need direct agent hooks or disciplined MCP calls.
Why TUI May Not Respond Like A Model
Plain text in agentram tui records a user message and retrieves RAM context. It does not call paid/local models by default. To get a model response:
- Put the real API key in an environment variable.
- Bind the model using the env var name, not the raw key.
- Use
/askoragentram orchestrate --execute.
Example:
set OPENAI_API_KEY=sk-your-key
agentram tuiInside TUI:
/bind-model openai-compatible Agentic --role coder --base-url http://localhost:8000/v1 --api-key-env OPENAI_API_KEY
/ask xin chà oDo not paste raw API keys into /bind-model. api_key_env means environment variable name, e.g. OPENAI_API_KEY.
Optional Rich TUI
For live slash-command dropdown and command metadata, install the optional TUI extra:
pip install agentram[tui]Without prompt_toolkit, AgentRAM still works with basic terminal input; / then Enter opens the full slash palette.
Fix Bad Model Endpoints
If /ask shows base_url is required, old model endpoints were bound without a URL. Remove or clear them:
/models
/remove-model model_xxx
# or
/clear-modelsIf /ask shows connection refused, the configured OpenAI-compatible server is not running at base_url:
/bind-model openai-compatible Agentic --role coder --base-url http://localhost:8000/v1 --api-key-env OPENAI_API_KEY
/ask xin chà oStart your local server first, or change --base-url to the provider URL.
Prompt Router Model
AgentRAM can use a separate small router model before normal prompts. The router classifies each prompt, then sends it to the right path.
coding -> bound coding endpoints / Claude subagents
planning -> Goal Stack and drift check
memory -> AgentRAM note ingest
chat -> RAM retrieve onlyBind a router model:
/bind-router openai-compatible qwen2.5:1.5b base_url=http://localhost:8000/v1 api_key_env=OPENAI_API_KEY
/route onThen prompt without slash:
fix adapter.py
cap nhat goal stack
ghi nho dung Claude subagentDisable auto routing:
/route offSupervisor + Small Agent Workflow
AgentRAM can run as a two-flow coding agent system, not only as a flat multi-model router.
agentram
|
v
Parse User Request
|
v
Supervisor Memory
|
v
Task Classifier / Supervisor Plan
|----------------------|
v v
Main Agent
(Codex CLI / Claude Code / OpenAI-compatible)
planning/coding/fix, may edit files when bound to CLI provider
|
v
Small Agent
(Qwen/OpenAI-compatible/Anthropic)
notes/RAM/coding facts only
|
v
Merge + Update Memory
|
v
Return ResultWhen installed through Claude plugin or Codex MCP with AGENTRAM_AUTO_WORKFLOW=true, workflow agents are created automatically:
Claude plugin:
supervisor -> claude-code:agentram-planner
main -> claude-code:claude
small -> claude-code:agentram-memory
Codex MCP:
supervisor -> codex-cli:current
main -> codex-cli:current
small -> codex-cli:currentManual setup is optional. Use /setup or explicit binds only when you want custom endpoints:
/bind-agent supervisor openai-compatible supervisor-model base_url=https://api.example.com/v1 api_key_env=SUPERVISOR_AGENT_KEY
/bind-agent main codex-cli current base_url="codex exec"
/bind-agent small openai-compatible qwen-codex base_url=http://localhost:8001/v1 api_key_env=SMALL_AGENT_KEY
/workflowThen use normal prompts without slash:
refactor orchestration workflow
fix bug in adapter.py
plan next milestoneRuntime behavior:
Supervisor creates plan -> Main CLI coding agent edits/returns result -> Small agent reads plan + main result and records RAM notes -> AgentRAM merges resultSmall agent should not own big direction. It records plans, decisions, files, risks, next tasks, and coding facts into RAM.
CLI coding providers for file edits:
/bind-agent main codex-cli current base_url="codex exec"
/bind-agent main claude-code claude base_url="claude"Use codex-cli or claude-code only for the main agent when you want a coding agent subprocess that can inspect and edit files. Keep the small agent on an LLM-only provider so it records notes but does not edit code.
Textual TUI
Install rich terminal UI with native scrollable chat pane:
pip install agentram[tui]
agentram tuiWhen textual is installed, AgentRAM uses a real full-screen TUI with mouse wheel scrolling inside the chat frame. If textual is missing, it falls back to the basic print-based terminal UI.
npm Python Dependencies
When installed through npm, AgentRAM runs a postinstall step that tries to install Python TUI dependencies for the Python interpreter used by agentram:
textual>=0.80
prompt_toolkit>=3.0Set target Python before install when needed:
$env:PYTHON="C:\Users\admin\anaconda3\python.exe"
npm install -g agentram@latestSkip automatic Python dependency install:
$env:AGENTRAM_SKIP_PY_DEPS="1"
npm install -g agentram@latestIf auto install fails, install manually:
python -m pip install textual prompt_toolkit