agentram 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,729 @@
1
+ # AgentRAM
2
+
3
+ Async, model-agnostic Working RAM for coding agents such as Codex, Claude Code, Cursor, and custom MCP clients.
4
+
5
+ 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.
6
+
7
+ ## Why
8
+
9
+ Coding agents can lose direction after long sessions, compact, restart, or model switch. AgentRAM keeps durable context outside the model session:
10
+
11
+ - Source-of-truth event log.
12
+ - Structured RAM notes.
13
+ - Goal Stack to reduce goal drift.
14
+ - MCP tools any compatible coding agent can call.
15
+ - Swappable memory adapters: heuristic, Ollama, OpenAI-compatible APIs, Anthropic Claude API.
16
+
17
+ ## Quick Start
18
+
19
+ Install from local clone:
20
+
21
+ ```bash
22
+ git clone https://github.com/trancongnghia/AGENT_RAM.git
23
+ cd RAMofagent
24
+ pip install -e .
25
+ python -m pytest -q
26
+ ```
27
+
28
+ Install from GitHub directly:
29
+
30
+ ```bash
31
+ pip install git+https://github.com/trancongnghia/AGENT_RAM.git
32
+ ```
33
+
34
+ Run MCP server inside any project you want to give memory:
35
+
36
+ ```bash
37
+ cd C:/path/to/your/project
38
+ agentram-mcp
39
+ ```
40
+
41
+ AgentRAM creates project-local storage automatically:
42
+
43
+ ```text
44
+ .agentram/
45
+ events.jsonl
46
+ memory.json
47
+ goal_state.json
48
+ ```
49
+
50
+ No `--ram-root` required. Use `--ram-root` only when you want memory outside the project or shared across projects.
51
+
52
+ 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.
53
+
54
+ ## Terminal UI CLI
55
+
56
+ AgentRAM also includes a dependency-free terminal UI with a Claude Code-like chat frame and button menu:
57
+
58
+ ```bash
59
+ agentram
60
+ ```
61
+
62
+ Equivalent explicit command:
63
+
64
+ ```bash
65
+ agentram tui
66
+ ```
67
+
68
+ Buttons inside the UI:
69
+
70
+ ```text
71
+ [1] Init RAM [2] Status [3] Retrieve
72
+ [4] Goal Show [5] Goal Set [6] Drift Check
73
+ [7] Events [8] Replay [9] Help [0] Exit
74
+ ```
75
+
76
+ Useful non-interactive commands:
77
+
78
+ ```bash
79
+ agentram init
80
+ agentram status
81
+ agentram goal
82
+ agentram retrieve "adapter Groq memory writer"
83
+ agentram drift "Refactor MCP server"
84
+ agentram replay
85
+ ```
86
+
87
+ Use another RAM folder when needed:
88
+
89
+ ```bash
90
+ agentram --ram-root C:/path/to/project/.agentram status
91
+ ```
92
+
93
+ ## npm / npx Usage
94
+
95
+ AgentRAM can also run through npm. Node only launches the Python package; Python 3.10+ must still be installed.
96
+
97
+ After the package is published to npm:
98
+
99
+ ```bash
100
+ npm install -g agentram
101
+ agentram status
102
+ agentram tui
103
+ agentram-mcp
104
+ ```
105
+
106
+ Run without global install:
107
+
108
+ ```bash
109
+ npx agentram status
110
+ npx agentram tui
111
+ npx agentram retrieve "adapter Groq memory writer"
112
+ ```
113
+
114
+ Run directly from GitHub before npm publish:
115
+
116
+ ```bash
117
+ npx github:trancongnghia/AGENT_RAM status
118
+ npx github:trancongnghia/AGENT_RAM tui
119
+ ```
120
+
121
+ Run from local clone:
122
+
123
+ ```bash
124
+ npm install
125
+ npm run agentram -- status
126
+ npm run agentram -- tui
127
+ npm run agentram:mcp
128
+ ```
129
+
130
+ Publish to npm:
131
+
132
+ ```bash
133
+ npm login
134
+ npm publish --access public
135
+ ```
136
+
137
+ Use with Claude/Codex MCP through npm wrapper:
138
+
139
+ ```json
140
+ {
141
+ "mcpServers": {
142
+ "agentram": {
143
+ "type": "stdio",
144
+ "command": "agentram-mcp",
145
+ "args": []
146
+ }
147
+ }
148
+ }
149
+ ```
150
+
151
+ If `python` is not the right binary, set `PYTHON`:
152
+
153
+ ```bash
154
+ PYTHON=python3 npx agentram status
155
+ ```
156
+ ## Install In Coding Agents
157
+
158
+ ### Codex MCP
159
+
160
+ Add to Codex config:
161
+
162
+ ```toml
163
+ [mcp_servers.agentram]
164
+ command = "agentram-mcp"
165
+ args = []
166
+ ```
167
+
168
+ Fallback if entrypoint is unavailable:
169
+
170
+ ```toml
171
+ [mcp_servers.agentram]
172
+ command = "python"
173
+ args = ["-m", "agentram.mcp_server"]
174
+ ```
175
+
176
+ ### Claude Code MCP Command
177
+
178
+ After installing package:
179
+
180
+ ```bash
181
+ claude mcp add --transport stdio agentram -- python -m agentram.mcp_server
182
+ ```
183
+
184
+ Or:
185
+
186
+ ```bash
187
+ claude mcp add --transport stdio agentram -- agentram-mcp
188
+ ```
189
+
190
+ Check:
191
+
192
+ ```bash
193
+ claude mcp list
194
+ ```
195
+
196
+ Inside Claude Code:
197
+
198
+ ```text
199
+ /mcp
200
+ ```
201
+
202
+ ### Claude Code Plugin
203
+
204
+ This repo includes Claude plugin and marketplace files:
205
+
206
+ ```text
207
+ .claude-plugin/plugin.json
208
+ .claude-plugin/marketplace.json
209
+ .mcp.json
210
+ ```
211
+
212
+ Install from local path inside Claude Code:
213
+
214
+ ```text
215
+ /plugin install C:/path/to/RAMofagent
216
+ ```
217
+
218
+ Or clone first:
219
+
220
+ ```bash
221
+ git clone https://github.com/trancongnghia/AGENT_RAM.git
222
+ cd RAMofagent
223
+ ```
224
+
225
+ Then inside Claude Code:
226
+
227
+ ```text
228
+ /plugin install .
229
+ ```
230
+
231
+ Marketplace install from GitHub:
232
+
233
+ ```text
234
+ /plugin marketplace add agentram https://github.com/trancongnghia/AGENT_RAM
235
+ /plugin install agentram@agentram
236
+ ```
237
+
238
+ If Claude Code uses marketplace name from `.claude-plugin/marketplace.json`, install with:
239
+
240
+ ```text
241
+ /plugin install agentram@agentram-marketplace
242
+ ```
243
+
244
+ The plugin starts AgentRAM using `.mcp.json`:
245
+
246
+ ```json
247
+ {
248
+ "mcpServers": {
249
+ "agentram": {
250
+ "type": "stdio",
251
+ "command": "python",
252
+ "args": ["${CLAUDE_PLUGIN_ROOT}/agentram_mcp_server.py"],
253
+ "env": {"AGENTRAM_AUTO_INIT": "true"}
254
+ }
255
+ }
256
+ }
257
+ ```
258
+
259
+ ### Claude Desktop / JSON MCP Clients
260
+
261
+ ```json
262
+ {
263
+ "mcpServers": {
264
+ "agentram": {
265
+ "type": "stdio",
266
+ "command": "python",
267
+ "args": ["-m", "agentram.mcp_server"]
268
+ }
269
+ }
270
+ }
271
+ ```
272
+
273
+ ### Other Coding Agents
274
+
275
+ Any agent can use AgentRAM if it supports stdio MCP servers:
276
+
277
+ ```text
278
+ command: python
279
+ args: ["-m", "agentram.mcp_server"]
280
+ ```
281
+
282
+ Minimum usage pattern:
283
+
284
+ 1. Call `agentram_retrieve` at task start.
285
+ 2. Call `agentram_emit_event` after important reads, writes, tool calls, and decisions.
286
+ 3. Call `agentram_check_goal_drift` before switching direction.
287
+ 4. Call `agentram_retrieve` again near context pressure or resume.
288
+
289
+ ## MCP Tools
290
+
291
+ | Tool | Purpose |
292
+ | --- | --- |
293
+ | `agentram_init` | Create `.agentram` files without overwriting existing memory. |
294
+ | `agentram_retrieve` | Return Goal Stack plus relevant RAM notes. |
295
+ | `agentram_emit_event` | Append event and optionally ingest into memory. |
296
+ | `agentram_replay_events` | Rebuild memory from `events.jsonl`. |
297
+ | `agentram_read_task_state` | Read RAM notes for one `task_id`. |
298
+ | `agentram_read_goal_state` | Read mission, goals, current task, histories. |
299
+ | `agentram_update_goal_state` | Update Goal Stack fields. |
300
+ | `agentram_check_goal_drift` | Warn only when task appears off-goal. |
301
+
302
+ ### Init
303
+
304
+ Create `.agentram` files explicitly:
305
+
306
+ ```json
307
+ {}
308
+ ```
309
+
310
+ Returns created file names and paths. Existing files are not overwritten.
311
+
312
+ ### Retrieve
313
+
314
+ ```json
315
+ {
316
+ "query": "adapter Groq memory writer",
317
+ "task_id": "codex",
318
+ "limit": 8
319
+ }
320
+ ```
321
+
322
+ Returns:
323
+
324
+ - `context`: prompt-ready Goal Stack plus relevant notes.
325
+ - `items`: raw memory items.
326
+
327
+ ### Emit Event
328
+
329
+ ```json
330
+ {
331
+ "type": "READ_FILE",
332
+ "payload": {"path": "agentram/adapter.py"},
333
+ "task_id": "codex",
334
+ "ingest": true
335
+ }
336
+ ```
337
+
338
+ Supported event types:
339
+
340
+ ```text
341
+ USER_MESSAGE user request or instruction
342
+ AGENT_MESSAGE agent output or final answer
343
+ READ_FILE file opened/read by agent
344
+ WRITE_FILE file changed by agent
345
+ TOOL_CALL shell/tool/API action
346
+ DECISION durable design or implementation choice
347
+ ```
348
+
349
+ ### Goal State
350
+
351
+ ```json
352
+ {
353
+ "mission": "Build shared Working RAM for AI coding agents.",
354
+ "project_goal": "AgentRAM v1",
355
+ "current_milestone": "Goal Runtime",
356
+ "current_goal": "Reduce goal drift",
357
+ "current_task": "Add goal_state.json",
358
+ "next_tasks": ["Drift warning"],
359
+ "goal_history": ["Design schema"],
360
+ "decision_history": [
361
+ {
362
+ "content": "Event log is source of truth.",
363
+ "source_events": ["evt_123"],
364
+ "confidence": 0.9
365
+ }
366
+ ]
367
+ }
368
+ ```
369
+
370
+ `goal_history` and `decision_history` append instead of replacing previous history.
371
+
372
+ ### Goal Drift Check
373
+
374
+ Aligned task returns no suggestions:
375
+
376
+ ```json
377
+ {
378
+ "status": "ok",
379
+ "aligned": true,
380
+ "warning": null,
381
+ "next_actions": []
382
+ }
383
+ ```
384
+
385
+ Off-goal task returns warning:
386
+
387
+ ```json
388
+ {
389
+ "status": "drift_risk",
390
+ "aligned": false,
391
+ "warning": "Potential goal drift. Confirm scope change or update goal_state before continuing.",
392
+ "next_actions": ["Confirm task belongs to current goal stack."]
393
+ }
394
+ ```
395
+
396
+ ## How It Works
397
+
398
+ ```text
399
+ Coding Agent
400
+ |
401
+ | emits events through MCP
402
+ v
403
+ events.jsonl ---- replayable source of truth
404
+ |
405
+ v
406
+ Memory Adapter heuristic / Ollama / OpenAI-compatible / Anthropic
407
+ |
408
+ v
409
+ memory.json normalized RAM notes
410
+ |
411
+ +--> retriever returns relevant notes
412
+ |
413
+ v
414
+ goal_state.json mission, goals, current task, history, decisions
415
+ ```
416
+
417
+ Design rules:
418
+
419
+ - Main agent should not block on long memory work.
420
+ - `events.jsonl` is source of truth.
421
+ - `memory.json` stores normalized notes, not model-specific prose.
422
+ - `goal_state.json` stores durable project direction.
423
+ - Every RAM note links to `source_events`.
424
+ - Current files beat RAM when they conflict.
425
+
426
+ ## Goal Stack
427
+
428
+ AgentRAM stores durable goal context separately from normal notes:
429
+
430
+ ```text
431
+ Mission
432
+ -> Project Goal
433
+ -> Milestones
434
+ -> Current Goal
435
+ -> Current Task
436
+ -> Next Tasks
437
+ ```
438
+
439
+ This 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.
440
+
441
+ ## Background Daemon
442
+
443
+ Use daemon when you want event logging fast and memory ingestion in background.
444
+
445
+ Run once:
446
+
447
+ ```bash
448
+ agentram-daemon --once
449
+ ```
450
+
451
+ Run continuously:
452
+
453
+ ```bash
454
+ agentram-daemon --interval 1
455
+ ```
456
+
457
+ Replay all events:
458
+
459
+ ```bash
460
+ agentram-daemon --replay-all
461
+ ```
462
+
463
+ Recommended parallel mode:
464
+
465
+ 1. MCP client calls `agentram_emit_event` with `ingest: false`.
466
+ 2. `agentram-daemon` tails `events.jsonl`.
467
+ 3. Daemon updates `memory.json` independently.
468
+ 4. Agent calls `agentram_retrieve` when it needs RAM.
469
+
470
+ ## Wrapper CLI
471
+
472
+ Use wrapper when an agent does not support MCP yet:
473
+
474
+ ```bash
475
+ agentram-codex "fix auth bug" --dry-run
476
+ ```
477
+
478
+ Run another command with RAM injected through stdin:
479
+
480
+ ```bash
481
+ agentram-codex "fix auth bug" -- codex exec
482
+ ```
483
+
484
+ Useful options:
485
+
486
+ ```text
487
+ --task-id task namespace, default codex
488
+ --ram-root storage root, default .agentram in cwd
489
+ --adapter heuristic | ollama | openai-compatible | anthropic
490
+ --prompt-as-arg pass prompt as final argv instead of stdin
491
+ --dry-run print injected prompt only
492
+ ```
493
+
494
+ ## Memory Adapters
495
+
496
+ ### Heuristic
497
+
498
+ Default adapter. No model, no network, deterministic.
499
+
500
+ ```python
501
+ from agentram.orchestrator import AgentRAM
502
+
503
+ ram = AgentRAM(root=".agentram")
504
+ ```
505
+
506
+ ### Ollama
507
+
508
+ ```python
509
+ from agentram.adapter import OllamaMemoryAdapter
510
+ from agentram.orchestrator import AgentRAM
511
+
512
+ ram = AgentRAM(
513
+ root=".agentram",
514
+ adapter=OllamaMemoryAdapter(model="qwen2.5:7b"),
515
+ )
516
+ ```
517
+
518
+ Notes:
519
+
520
+ - `qwen2.5:7b` is recommended for local JSON reliability.
521
+ - Adapter uses `format: "json"`, `temperature: 0`, and `num_predict: 512`.
522
+
523
+ ### OpenAI-Compatible
524
+
525
+ Works with Groq, vLLM, LM Studio, llama.cpp server, LocalAI, Ollama `/v1`, OpenRouter-style gateways, and OpenAI-compatible APIs.
526
+
527
+ ```python
528
+ from agentram.adapter import OpenAICompatibleMemoryAdapter
529
+ from agentram.orchestrator import AgentRAM
530
+
531
+ ram = AgentRAM(
532
+ root=".agentram",
533
+ adapter=OpenAICompatibleMemoryAdapter(
534
+ model="openai/gpt-oss-20b",
535
+ base_url="https://api.groq.com/openai/v1",
536
+ api_key="YOUR_KEY",
537
+ use_response_format=False,
538
+ ),
539
+ )
540
+ ```
541
+
542
+ ### Anthropic Claude API
543
+
544
+ Uses Anthropic API directly. This is separate from Claude Code's active model and requires `ANTHROPIC_API_KEY`.
545
+
546
+ ```python
547
+ from agentram.adapter import AnthropicMemoryAdapter
548
+ from agentram.orchestrator import AgentRAM
549
+
550
+ ram = AgentRAM(
551
+ root=".agentram",
552
+ adapter=AnthropicMemoryAdapter(
553
+ model="claude-3-5-haiku-latest",
554
+ api_key="YOUR_ANTHROPIC_KEY",
555
+ ),
556
+ )
557
+ ```
558
+
559
+ Wrapper usage:
560
+
561
+ ```bash
562
+ agentram-codex "test Claude memory writer" --adapter anthropic --dry-run
563
+ ```
564
+
565
+ ## Environment Config
566
+
567
+ Copy template:
568
+
569
+ ```bash
570
+ cp .env.example .env
571
+ ```
572
+
573
+ Fill values for OpenAI-compatible/Groq:
574
+
575
+ ```env
576
+ BASE_URL=https://api.groq.com/openai/v1
577
+ Model=openai/gpt-oss-20b
578
+ API_KEY=replace_me
579
+ ```
580
+
581
+ Fill values for Anthropic:
582
+
583
+ ```env
584
+ ANTHROPIC_API_KEY=replace_me
585
+ ANTHROPIC_MODEL=claude-3-5-haiku-latest
586
+ ANTHROPIC_BASE_URL=https://api.anthropic.com/v1
587
+ ```
588
+
589
+ Supported keys:
590
+
591
+ ```text
592
+ base_url: BASE_URL or OPENAI_BASE_URL
593
+ model: AGENTRAM_MODEL, Model, MODEL, CODEX_MODEL, CODEX_DEFAULT_MODEL, CLAUDE_MODEL, CURSOR_MODEL, or AGENT_MODEL
594
+ api_key: API_KEY, OPENAI_API_KEY, GROQ_API_KEY, or ANTHROPIC_API_KEY
595
+ timeout: AGENTRAM_TIMEOUT
596
+ json: AGENTRAM_RESPONSE_FORMAT=true|false
597
+ anthropic: ANTHROPIC_MODEL, ANTHROPIC_BASE_URL, ANTHROPIC_VERSION
598
+ ```
599
+
600
+ Model selection order:
601
+
602
+ 1. Dedicated memory model: `AGENTRAM_MODEL`, `Model`, or `MODEL`.
603
+ 2. Current coding-agent model env: `CODEX_MODEL`, `CODEX_DEFAULT_MODEL`, `CLAUDE_MODEL`, `CURSOR_MODEL`, or `AGENT_MODEL`.
604
+ 3. Clear config error if no model found.
605
+
606
+ Run smoke test:
607
+
608
+ ```bash
609
+ python examples/openai_compatible_smoke.py
610
+ ```
611
+
612
+ ## Multiple Projects
613
+
614
+ Recommended: one RAM root per project.
615
+
616
+ ```text
617
+ project-a/.agentram/
618
+ project-b/.agentram/
619
+ ```
620
+
621
+ If sharing memory intentionally, use explicit roots:
622
+
623
+ ```bash
624
+ agentram-mcp --ram-root C:/AgentRAM/project-a
625
+ agentram-mcp --ram-root C:/AgentRAM/project-b
626
+ ```
627
+
628
+ Use `task_id` to split tasks inside the same project RAM:
629
+
630
+ ```bash
631
+ agentram-codex "fix auth bug" --task-id auth-bug
632
+ agentram-codex "refactor adapter" --task-id adapter-refactor
633
+ ```
634
+
635
+ ## Python API
636
+
637
+ ```python
638
+ import asyncio
639
+
640
+ from agentram.orchestrator import AgentRAM
641
+ from agentram.retriever import MemoryRetriever
642
+ from agentram.schema import Event, EventType
643
+
644
+ async def main():
645
+ ram = AgentRAM(root=".agentram")
646
+ await ram.start()
647
+ ram.emit(Event(type=EventType.READ_FILE, payload={"path": "main.py"}, task_id="demo"))
648
+ ram.emit(Event(type=EventType.DECISION, payload={"content": "Use event log as source of truth."}, task_id="demo"))
649
+ await ram.stop()
650
+
651
+ block = MemoryRetriever(ram.memory_store).context_block("event log", task_id="demo")
652
+ print(block)
653
+
654
+ asyncio.run(main())
655
+ ```
656
+
657
+ ## Model Adapter Contract
658
+
659
+ Adapters must return normalized memory patches:
660
+
661
+ ```json
662
+ {
663
+ "patches": [
664
+ {
665
+ "op": "upsert",
666
+ "type": "decision",
667
+ "content": "Use Event Log as source of truth.",
668
+ "source_events": ["evt_123"],
669
+ "related_files": ["agentram/storage.py"],
670
+ "confidence": 0.9,
671
+ "scope": "task"
672
+ }
673
+ ]
674
+ }
675
+ ```
676
+
677
+ Rules:
678
+
679
+ - Output JSON only.
680
+ - Use only input event ids.
681
+ - Do not invent files or facts.
682
+ - Keep notes short and factual.
683
+ - Return empty `patches` if nothing important.
684
+
685
+ ## Development
686
+
687
+ Run tests:
688
+
689
+ ```bash
690
+ python -m pytest -q
691
+ ```
692
+
693
+ Compile check:
694
+
695
+ ```bash
696
+ python -B -m compileall agentram tests codex_ram.py agentram_mcp_server.py agentram_daemon.py examples
697
+ ```
698
+
699
+ Run local demo:
700
+
701
+ ```bash
702
+ python -m agentram.demo
703
+ ```
704
+
705
+ Validate plugin JSON:
706
+
707
+ ```bash
708
+ python -c "import json; [json.load(open(f, encoding='utf-8')) for f in ['.claude-plugin/plugin.json', '.mcp.json']]; print('json ok')"
709
+ ```
710
+
711
+ ## Public Repo Hygiene
712
+
713
+ Do not commit:
714
+
715
+ - `.env`
716
+ - `.agentram/`
717
+ - `.agentram_*/`
718
+ - `__pycache__/`
719
+ - `.pytest_cache/`
720
+ - real API keys or provider tokens
721
+
722
+ Use `.env.example` as the shareable template.
723
+
724
+ ## Limitations
725
+
726
+ - Immediate MCP ingest uses local heuristic adapter.
727
+ - Model-based ingestion is best run through daemon/wrapper configuration.
728
+ - Wrapper CLI records command-level events, not deep internal agent tool events.
729
+ - Rich file/tool hooks need direct agent hooks or disciplined MCP calls.