memocode 0.1.0__tar.gz
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.
- memocode-0.1.0/PKG-INFO +82 -0
- memocode-0.1.0/README.md +71 -0
- memocode-0.1.0/control/__init__.py +0 -0
- memocode-0.1.0/control/audit.py +100 -0
- memocode-0.1.0/control/brain.py +643 -0
- memocode-0.1.0/control/chatmem/__init__.py +8 -0
- memocode-0.1.0/control/chatmem/cli.py +136 -0
- memocode-0.1.0/control/chatmem/compressor.py +288 -0
- memocode-0.1.0/control/chatmem/config.py +165 -0
- memocode-0.1.0/control/chatmem/context_manager.py +656 -0
- memocode-0.1.0/control/chatmem/mcp_server.py +156 -0
- memocode-0.1.0/control/chatmem/memory/__init__.py +11 -0
- memocode-0.1.0/control/chatmem/memory/consolidation.py +95 -0
- memocode-0.1.0/control/chatmem/memory/core_memory.py +239 -0
- memocode-0.1.0/control/chatmem/memory/forgetting.py +45 -0
- memocode-0.1.0/control/chatmem/memory/recent_memory.py +153 -0
- memocode-0.1.0/control/chatmem/server.py +176 -0
- memocode-0.1.0/control/chatmem/token_counter.py +62 -0
- memocode-0.1.0/control/fmt.py +91 -0
- memocode-0.1.0/control/llm.py +485 -0
- memocode-0.1.0/control/planner.py +142 -0
- memocode-0.1.0/control/project_manager.py +226 -0
- memocode-0.1.0/memocode.egg-info/PKG-INFO +82 -0
- memocode-0.1.0/memocode.egg-info/SOURCES.txt +37 -0
- memocode-0.1.0/memocode.egg-info/dependency_links.txt +1 -0
- memocode-0.1.0/memocode.egg-info/entry_points.txt +2 -0
- memocode-0.1.0/memocode.egg-info/requires.txt +3 -0
- memocode-0.1.0/memocode.egg-info/top_level.txt +3 -0
- memocode-0.1.0/pyproject.toml +28 -0
- memocode-0.1.0/safety/__init__.py +0 -0
- memocode-0.1.0/safety/backup.py +121 -0
- memocode-0.1.0/safety/policy.py +40 -0
- memocode-0.1.0/safety/safety.py +232 -0
- memocode-0.1.0/setup.cfg +4 -0
- memocode-0.1.0/tools/__init__.py +0 -0
- memocode-0.1.0/tools/file.py +229 -0
- memocode-0.1.0/tools/loader.py +74 -0
- memocode-0.1.0/tools/registry.py +72 -0
- memocode-0.1.0/tools/shell.py +81 -0
memocode-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: memocode
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Personal AI agent with memory, planning, and tool execution
|
|
5
|
+
Author: AssassinCHN
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: openai>=1.0
|
|
9
|
+
Requires-Dist: rich>=13.0
|
|
10
|
+
Requires-Dist: prompt_toolkit>=3.0
|
|
11
|
+
|
|
12
|
+
# Mcode
|
|
13
|
+
|
|
14
|
+
Personal AI coding agent with memory, planning, and tool execution.
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- **Interactive CLI** - Chat with the AI agent in a REPL
|
|
19
|
+
- **Memory System** - Persistent conversation memory with consolidation and forgetting
|
|
20
|
+
- **Project Management** - Manage multiple projects with separate contexts
|
|
21
|
+
- **Tool Execution** - Execute shell commands and file operations safely
|
|
22
|
+
- **Safety Controls** - Backup and rollback protection for file modifications
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install -e .
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
mcode # Start the agent
|
|
34
|
+
python3 run.py # Or run directly
|
|
35
|
+
|
|
36
|
+
# Options
|
|
37
|
+
--verbose # Enable verbose output
|
|
38
|
+
--dry-run # Dry run mode (no actual changes)
|
|
39
|
+
--project <name> # Start with a specific project
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Commands
|
|
43
|
+
|
|
44
|
+
| Command | Description |
|
|
45
|
+
|---------|-------------|
|
|
46
|
+
| `/quit` | Exit the agent |
|
|
47
|
+
| `/end` | End session and save to memory |
|
|
48
|
+
| `/project list` | List all projects |
|
|
49
|
+
| `/project new <name>` | Create a new project |
|
|
50
|
+
| `/project switch <name>` | Switch to a project |
|
|
51
|
+
| `/profile set <key> <value>` | Set a profile entry |
|
|
52
|
+
| `!<command>` | Run shell command directly |
|
|
53
|
+
| `@<path>` | Attach file contents to message |
|
|
54
|
+
|
|
55
|
+
## Project Structure
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
mcode/
|
|
59
|
+
├── run.py # Main entry point
|
|
60
|
+
├── control/ # Core agent logic
|
|
61
|
+
│ ├── brain.py # Main brain logic
|
|
62
|
+
│ ├── planner.py # Planning module
|
|
63
|
+
│ ├── llm.py # LLM interface
|
|
64
|
+
│ ├── project_manager.py
|
|
65
|
+
│ ├── audit.py # Audit logging
|
|
66
|
+
│ ├── fmt.py # Formatting
|
|
67
|
+
│ └── chatmem/ # Memory system
|
|
68
|
+
├── tools/ # Tool implementations
|
|
69
|
+
│ ├── file.py # File operations
|
|
70
|
+
│ ├── shell.py # Shell commands
|
|
71
|
+
│ └── registry.py # Tool registry
|
|
72
|
+
└── safety/ # Safety features
|
|
73
|
+
├── backup.py # Backup system
|
|
74
|
+
└── policy.py # Safety policies
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Requirements
|
|
78
|
+
|
|
79
|
+
- Python 3.11+
|
|
80
|
+
- openai
|
|
81
|
+
- rich
|
|
82
|
+
- prompt_toolkit
|
memocode-0.1.0/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Mcode
|
|
2
|
+
|
|
3
|
+
Personal AI coding agent with memory, planning, and tool execution.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Interactive CLI** - Chat with the AI agent in a REPL
|
|
8
|
+
- **Memory System** - Persistent conversation memory with consolidation and forgetting
|
|
9
|
+
- **Project Management** - Manage multiple projects with separate contexts
|
|
10
|
+
- **Tool Execution** - Execute shell commands and file operations safely
|
|
11
|
+
- **Safety Controls** - Backup and rollback protection for file modifications
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install -e .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
mcode # Start the agent
|
|
23
|
+
python3 run.py # Or run directly
|
|
24
|
+
|
|
25
|
+
# Options
|
|
26
|
+
--verbose # Enable verbose output
|
|
27
|
+
--dry-run # Dry run mode (no actual changes)
|
|
28
|
+
--project <name> # Start with a specific project
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Commands
|
|
32
|
+
|
|
33
|
+
| Command | Description |
|
|
34
|
+
|---------|-------------|
|
|
35
|
+
| `/quit` | Exit the agent |
|
|
36
|
+
| `/end` | End session and save to memory |
|
|
37
|
+
| `/project list` | List all projects |
|
|
38
|
+
| `/project new <name>` | Create a new project |
|
|
39
|
+
| `/project switch <name>` | Switch to a project |
|
|
40
|
+
| `/profile set <key> <value>` | Set a profile entry |
|
|
41
|
+
| `!<command>` | Run shell command directly |
|
|
42
|
+
| `@<path>` | Attach file contents to message |
|
|
43
|
+
|
|
44
|
+
## Project Structure
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
mcode/
|
|
48
|
+
├── run.py # Main entry point
|
|
49
|
+
├── control/ # Core agent logic
|
|
50
|
+
│ ├── brain.py # Main brain logic
|
|
51
|
+
│ ├── planner.py # Planning module
|
|
52
|
+
│ ├── llm.py # LLM interface
|
|
53
|
+
│ ├── project_manager.py
|
|
54
|
+
│ ├── audit.py # Audit logging
|
|
55
|
+
│ ├── fmt.py # Formatting
|
|
56
|
+
│ └── chatmem/ # Memory system
|
|
57
|
+
├── tools/ # Tool implementations
|
|
58
|
+
│ ├── file.py # File operations
|
|
59
|
+
│ ├── shell.py # Shell commands
|
|
60
|
+
│ └── registry.py # Tool registry
|
|
61
|
+
└── safety/ # Safety features
|
|
62
|
+
├── backup.py # Backup system
|
|
63
|
+
└── policy.py # Safety policies
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Requirements
|
|
67
|
+
|
|
68
|
+
- Python 3.11+
|
|
69
|
+
- openai
|
|
70
|
+
- rich
|
|
71
|
+
- prompt_toolkit
|
|
File without changes
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Audit log: persists every agent run to SQLite for traceability and rollback.
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import sqlite3
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AuditLog:
|
|
12
|
+
def __init__(self, db_path: str):
|
|
13
|
+
self.db_path = db_path
|
|
14
|
+
self._init_db()
|
|
15
|
+
|
|
16
|
+
def _conn(self) -> sqlite3.Connection:
|
|
17
|
+
conn = sqlite3.connect(self.db_path)
|
|
18
|
+
conn.row_factory = sqlite3.Row
|
|
19
|
+
return conn
|
|
20
|
+
|
|
21
|
+
def _init_db(self):
|
|
22
|
+
with self._conn() as conn:
|
|
23
|
+
conn.execute("""
|
|
24
|
+
CREATE TABLE IF NOT EXISTS audit_runs (
|
|
25
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
26
|
+
ts REAL NOT NULL,
|
|
27
|
+
project TEXT NOT NULL DEFAULT '',
|
|
28
|
+
user_input TEXT NOT NULL,
|
|
29
|
+
goal TEXT NOT NULL,
|
|
30
|
+
tasks TEXT NOT NULL,
|
|
31
|
+
success INTEGER NOT NULL,
|
|
32
|
+
log TEXT NOT NULL,
|
|
33
|
+
backups TEXT NOT NULL DEFAULT '{}'
|
|
34
|
+
)
|
|
35
|
+
""")
|
|
36
|
+
# Migrate: add project column if missing (existing DBs)
|
|
37
|
+
try:
|
|
38
|
+
conn.execute("ALTER TABLE audit_runs ADD COLUMN project TEXT NOT NULL DEFAULT ''")
|
|
39
|
+
except Exception:
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
def record(
|
|
43
|
+
self,
|
|
44
|
+
user_input: str,
|
|
45
|
+
goal: str,
|
|
46
|
+
tasks: list,
|
|
47
|
+
success: bool,
|
|
48
|
+
log: list[dict],
|
|
49
|
+
project: str = "",
|
|
50
|
+
):
|
|
51
|
+
"""Write one completed run to the audit log."""
|
|
52
|
+
backups: dict[str, str] = {}
|
|
53
|
+
for entry in log:
|
|
54
|
+
backups.update(entry.get("backups", {}))
|
|
55
|
+
|
|
56
|
+
tasks_data = [
|
|
57
|
+
{"id": t.id, "tool": t.tool, "args": t.args, "description": t.description}
|
|
58
|
+
for t in tasks
|
|
59
|
+
]
|
|
60
|
+
with self._conn() as conn:
|
|
61
|
+
conn.execute(
|
|
62
|
+
"INSERT INTO audit_runs (ts, project, user_input, goal, tasks, success, log, backups) "
|
|
63
|
+
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
|
64
|
+
(
|
|
65
|
+
time.time(),
|
|
66
|
+
project,
|
|
67
|
+
user_input,
|
|
68
|
+
goal,
|
|
69
|
+
json.dumps(tasks_data, ensure_ascii=False),
|
|
70
|
+
1 if success else 0,
|
|
71
|
+
json.dumps(log, ensure_ascii=False),
|
|
72
|
+
json.dumps(backups, ensure_ascii=False),
|
|
73
|
+
),
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
def recent(self, limit: int = 20, project: str | None = None) -> list[dict]:
|
|
77
|
+
"""Return most recent runs, newest first. Optionally filter by project."""
|
|
78
|
+
with self._conn() as conn:
|
|
79
|
+
if project is not None:
|
|
80
|
+
rows = conn.execute(
|
|
81
|
+
"SELECT * FROM audit_runs WHERE project = ? ORDER BY ts DESC LIMIT ?",
|
|
82
|
+
(project, limit),
|
|
83
|
+
).fetchall()
|
|
84
|
+
else:
|
|
85
|
+
rows = conn.execute(
|
|
86
|
+
"SELECT * FROM audit_runs ORDER BY ts DESC LIMIT ?", (limit,)
|
|
87
|
+
).fetchall()
|
|
88
|
+
return [dict(r) for r in rows]
|
|
89
|
+
|
|
90
|
+
def runs_with_backups(self, project: str | None = None) -> list[dict]:
|
|
91
|
+
"""Return runs that have backup files available, optionally filtered by project."""
|
|
92
|
+
runs = self.recent(50, project=project)
|
|
93
|
+
result = []
|
|
94
|
+
for run in runs:
|
|
95
|
+
backups = json.loads(run["backups"])
|
|
96
|
+
available = {orig: bp for orig, bp in backups.items() if os.path.exists(bp)}
|
|
97
|
+
if available:
|
|
98
|
+
run["available_backups"] = available
|
|
99
|
+
result.append(run)
|
|
100
|
+
return result
|