mazu 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.
- mazu-0.1.0/.gitignore +47 -0
- mazu-0.1.0/LICENSE +21 -0
- mazu-0.1.0/PKG-INFO +259 -0
- mazu-0.1.0/README.md +229 -0
- mazu-0.1.0/mazu/__init__.py +1 -0
- mazu-0.1.0/mazu/agent/__init__.py +0 -0
- mazu-0.1.0/mazu/agent/autonomous.py +226 -0
- mazu-0.1.0/mazu/agent/context.py +26 -0
- mazu-0.1.0/mazu/agent/council.py +151 -0
- mazu-0.1.0/mazu/agent/interaction.py +14 -0
- mazu-0.1.0/mazu/agent/loop.py +176 -0
- mazu-0.1.0/mazu/agent/prompts.py +50 -0
- mazu-0.1.0/mazu/agent/session.py +48 -0
- mazu-0.1.0/mazu/banner.py +33 -0
- mazu-0.1.0/mazu/checkpoint/__init__.py +0 -0
- mazu-0.1.0/mazu/checkpoint/manager.py +169 -0
- mazu-0.1.0/mazu/checkpoint/store.py +54 -0
- mazu-0.1.0/mazu/cli.py +386 -0
- mazu-0.1.0/mazu/config.py +45 -0
- mazu-0.1.0/mazu/llm/__init__.py +0 -0
- mazu-0.1.0/mazu/llm/client.py +110 -0
- mazu-0.1.0/mazu/llm/error_mapping.py +36 -0
- mazu-0.1.0/mazu/llm/errors.py +21 -0
- mazu-0.1.0/mazu/llm/pricing.py +29 -0
- mazu-0.1.0/mazu/llm/providers/__init__.py +0 -0
- mazu-0.1.0/mazu/llm/providers/anthropic_provider.py +82 -0
- mazu-0.1.0/mazu/llm/providers/base.py +31 -0
- mazu-0.1.0/mazu/llm/providers/deepseek_provider.py +10 -0
- mazu-0.1.0/mazu/llm/providers/openai_compatible.py +186 -0
- mazu-0.1.0/mazu/llm/providers/openai_provider.py +6 -0
- mazu-0.1.0/mazu/llm/retry.py +26 -0
- mazu-0.1.0/mazu/llm/types.py +8 -0
- mazu-0.1.0/mazu/memory/__init__.py +0 -0
- mazu-0.1.0/mazu/memory/bm25.py +52 -0
- mazu-0.1.0/mazu/memory/extraction.py +107 -0
- mazu-0.1.0/mazu/memory/retrieval.py +110 -0
- mazu-0.1.0/mazu/memory/schema.sql +25 -0
- mazu-0.1.0/mazu/memory/store.py +172 -0
- mazu-0.1.0/mazu/skills/__init__.py +0 -0
- mazu-0.1.0/mazu/skills/manager.py +129 -0
- mazu-0.1.0/mazu/tools/__init__.py +0 -0
- mazu-0.1.0/mazu/tools/base.py +24 -0
- mazu-0.1.0/mazu/tools/fs.py +140 -0
- mazu-0.1.0/mazu/tools/memory_tools.py +105 -0
- mazu-0.1.0/mazu/tools/registry.py +17 -0
- mazu-0.1.0/mazu/tools/shell.py +60 -0
- mazu-0.1.0/mazu/tools/skill_tools.py +91 -0
- mazu-0.1.0/pyproject.toml +57 -0
mazu-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
*.egg
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
.eggs/
|
|
10
|
+
|
|
11
|
+
# Virtual environments
|
|
12
|
+
.venv/
|
|
13
|
+
venv/
|
|
14
|
+
env/
|
|
15
|
+
ENV/
|
|
16
|
+
|
|
17
|
+
# Mazu runtime state (per-project memory, checkpoints, skills) — local to each
|
|
18
|
+
# machine/project, never meant to be committed. `mazu init` also writes this entry
|
|
19
|
+
# into a project's own .gitignore for the same reason.
|
|
20
|
+
.mazu/
|
|
21
|
+
|
|
22
|
+
# Secrets / local config — API keys must only ever live in environment variables
|
|
23
|
+
# or ~/.mazu/config.toml (outside the repo), never in a tracked file.
|
|
24
|
+
.env
|
|
25
|
+
.env.*
|
|
26
|
+
*.pem
|
|
27
|
+
*.key
|
|
28
|
+
config.toml
|
|
29
|
+
|
|
30
|
+
# Test / coverage artifacts
|
|
31
|
+
.pytest_cache/
|
|
32
|
+
.coverage
|
|
33
|
+
.coverage.*
|
|
34
|
+
htmlcov/
|
|
35
|
+
.tox/
|
|
36
|
+
.mypy_cache/
|
|
37
|
+
.ruff_cache/
|
|
38
|
+
|
|
39
|
+
# Editors / OS
|
|
40
|
+
.vscode/
|
|
41
|
+
.idea/
|
|
42
|
+
*.swp
|
|
43
|
+
.DS_Store
|
|
44
|
+
Thumbs.db
|
|
45
|
+
|
|
46
|
+
# Claude Code's own local session state — not part of the project
|
|
47
|
+
.claude/
|
mazu-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Turgut Sofuyev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
mazu-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mazu
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A memory-augmented, checkpointable coding agent CLI.
|
|
5
|
+
Project-URL: Homepage, https://github.com/turgutino/Mazu
|
|
6
|
+
Project-URL: Repository, https://github.com/turgutino/Mazu
|
|
7
|
+
Project-URL: Issues, https://github.com/turgutino/Mazu/issues
|
|
8
|
+
Author-email: Turgut Sofuyev <turgut.sofuyev@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agent,ai,anthropic,cli,coding-agent,deepseek,llm,memory,openai
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development
|
|
22
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
23
|
+
Classifier: Topic :: Utilities
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Requires-Dist: anthropic>=0.40.0
|
|
26
|
+
Requires-Dist: click>=8.1
|
|
27
|
+
Provides-Extra: openai
|
|
28
|
+
Requires-Dist: openai>=1.0; extra == 'openai'
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# Mazu
|
|
32
|
+
|
|
33
|
+
**A memory-augmented, checkpointable coding agent CLI.** Open source, runs entirely on your own machine, works with Anthropic, OpenAI, or DeepSeek.
|
|
34
|
+
|
|
35
|
+
Most coding agents forget everything the moment the session ends. Mazu doesn't. It keeps a real, queryable memory of your project — decisions, conventions, mistakes — that persists across sessions and gets surfaced automatically. And because every autonomous step is checkpointed (code + memory + conversation, together), you can let it run longer and less-supervised without losing the ability to undo it.
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
███╗ ███╗
|
|
39
|
+
████╗ ████║ A Z U
|
|
40
|
+
██╔████╔██║ ══════════════════════════════
|
|
41
|
+
██║╚██╔╝██║ memory-augmented coding agent
|
|
42
|
+
██║ ╚═╝ ██║ persistent memory · checkpoints · skills · multi-model
|
|
43
|
+
╚═╝ ╚═╝
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## What makes Mazu different
|
|
47
|
+
|
|
48
|
+
Compared to typical coding-agent CLIs, which reset context every session and rely on a static instructions file:
|
|
49
|
+
|
|
50
|
+
1. **Persistent structured memory.** Decisions, conventions, and mistakes made on a project are written to a local SQLite database, ranked by local BM25 (zero API cost — no embedding calls) against your current task, and automatically injected back into context. You never have to re-explain "we use Postgres, not SQLite" in every new session.
|
|
51
|
+
2. **A separate, global memory for *you*, not the project.** Personal facts — your name, preferred language, experience level, working style — live in `~/.mazu/global_memory.db` and follow you into every project, instead of being repeated (or lost) per-repo.
|
|
52
|
+
3. **Checkpointable autonomy.** Every step of an autonomous run snapshots code (via git), the memory database, and the live conversation together. Roll back any one of them and you roll back all three, consistently — "undo" for an agent's actions, not just its files.
|
|
53
|
+
4. **A self-growing local skill library.** When the agent solves something reusable, it can save it as a plain Python function. Next time a similar task comes up, it can run the skill directly — skipping the model call entirely.
|
|
54
|
+
5. **Provider-agnostic.** Anthropic, OpenAI, and DeepSeek are all first-class, behind one thin adapter interface. Mazu auto-detects which one to use from whichever API key is actually set in your environment — no provider is required over another.
|
|
55
|
+
6. **Council mode.** For a decision worth a second opinion, ask two or three different models the same question in parallel and have a lead model synthesize a final recommendation — opt-in, since it costs more than a single call.
|
|
56
|
+
|
|
57
|
+
Everything above (agent loop, tool execution, memory database, skill library, checkpoints) runs locally. The only network traffic is your chosen model's API call, plus one cheap end-of-session call (on the same provider) to extract memories from the transcript. Nothing else leaves your machine, and there is no server run by this project.
|
|
58
|
+
|
|
59
|
+
## Installation
|
|
60
|
+
|
|
61
|
+
Requires **Python 3.11+** and **git** (used for checkpoints).
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
git clone https://github.com/<your-username>/mazu.git
|
|
65
|
+
cd mazu
|
|
66
|
+
pip install -e .
|
|
67
|
+
|
|
68
|
+
# Only needed for openai:* or deepseek:* models (DeepSeek's API is OpenAI-compatible,
|
|
69
|
+
# so it reuses the same client library under a different base URL):
|
|
70
|
+
pip install -e ".[openai]"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Then set at least one API key — Mazu picks whichever provider is present automatically, so you only need the one you actually plan to use:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
export ANTHROPIC_API_KEY=sk-ant-... # or store it in ~/.mazu/config.toml
|
|
77
|
+
export DEEPSEEK_API_KEY=sk-...
|
|
78
|
+
export OPENAI_API_KEY=sk-...
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
On Windows (PowerShell): `$env:ANTHROPIC_API_KEY = "sk-ant-..."`
|
|
82
|
+
|
|
83
|
+
## Quick start
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
cd your-project/
|
|
87
|
+
mazu init # creates .mazu/ (local memory + checkpoints) and a git repo if needed
|
|
88
|
+
mazu chat # start talking to the agent
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
> we use PostgreSQL for this project, not SQLite. remember that.
|
|
93
|
+
[remember] saved (decision): use PostgreSQL, not SQLite
|
|
94
|
+
> /checkpoint
|
|
95
|
+
[checkpoint] cp_000001 saved (commit 4f2a91c)
|
|
96
|
+
> add a health-check endpoint to app.py and run the tests
|
|
97
|
+
...
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Exit and come back later (even days later) — the next session already knows about PostgreSQL, without you repeating it:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
mazu chat
|
|
104
|
+
> what database does this project use?
|
|
105
|
+
[memory] loaded prior context relevant to this task
|
|
106
|
+
|
|
107
|
+
PostgreSQL — this was a project decision, not SQLite.
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Usage
|
|
111
|
+
|
|
112
|
+
### Interactive chat
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
mazu chat # start a session in the current directory
|
|
116
|
+
mazu chat --model deepseek:deepseek-chat
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Inside the `>` prompt, two extra commands are always available:
|
|
120
|
+
|
|
121
|
+
| Command | Effect |
|
|
122
|
+
|---|---|
|
|
123
|
+
| `/checkpoint` | Snapshot code, memory, and the live conversation right now |
|
|
124
|
+
| `/rollback [id]` | Restore all three to that checkpoint (defaults to the most recent one) |
|
|
125
|
+
|
|
126
|
+
Any destructive tool call (writing a file, editing a file, running a shell command) asks for confirmation first.
|
|
127
|
+
|
|
128
|
+
### Autonomous runs
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
mazu run "add input validation to utils.py, run the tests, and fix any failures" --max-steps 15
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The agent keeps working, unattended, across multiple tool-use rounds until it finishes, hits `--max-steps`, or trips a safety limit. It checkpoints automatically along the way (`--checkpoint-every N`, default every round), so anything it does can be rolled back.
|
|
135
|
+
|
|
136
|
+
Key flags:
|
|
137
|
+
|
|
138
|
+
| Flag | Purpose |
|
|
139
|
+
|---|---|
|
|
140
|
+
| `--max-steps N` | Stop after N tool-use rounds (default 15) |
|
|
141
|
+
| `--checkpoint-every N` | Snapshot every N rounds (default 1) |
|
|
142
|
+
| `--allow-shell` | Skip the confirmation prompt for shell commands (the hardcoded safety denylist below still applies) |
|
|
143
|
+
| `--max-cost USD` | Stop once estimated spend (from a built-in pricing table) reaches this amount |
|
|
144
|
+
| `--keep-checkpoints N` | Prune on-disk checkpoint data beyond the N most recent (default 50) |
|
|
145
|
+
| `--model provider:model` | Override the model for this run |
|
|
146
|
+
|
|
147
|
+
By default, file writes/edits proceed unattended in `run` mode (checkpoints make them recoverable), but shell commands still ask for confirmation unless `--allow-shell` is passed. Regardless of that flag, a hardcoded denylist always blocks a short list of genuinely dangerous commands: force-pushing, `sudo`, touching `~/.ssh`, disk-format commands, and `rm -rf /`-style wipes. Checkpoints undo file damage — they can't undo an irreversible external action like a force-push or a sent network request, so that backstop stays even with `--allow-shell`.
|
|
148
|
+
|
|
149
|
+
`mazu run` refuses to start on a dirty working tree, so the first checkpoint is always a clean baseline. If it's interrupted with **Ctrl-C**, you're offered `[c]ontinue`, `[r]ollback <id>`, or `[q]uit` before anything is lost.
|
|
150
|
+
|
|
151
|
+
### Memory
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
mazu memory list # everything remembered about this project
|
|
155
|
+
mazu memory list --category mistake # filter by category
|
|
156
|
+
mazu memory list --global # the cross-project store (facts about you, not the code)
|
|
157
|
+
mazu memory forget <id> # delete a memory by id
|
|
158
|
+
mazu memory forget <id> --global
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Memory categories: `decision`, `convention`, `mistake`, `task_outcome`, `fact` (all project-scoped) and `user_preference` (global — your name, language, experience level, working style; injected into every project's context automatically).
|
|
162
|
+
|
|
163
|
+
Memories are written two ways: explicitly, when the agent calls `remember` (you can just tell it "remember that..."), and automatically, via a cheap end-of-session pass that extracts anything notable you didn't ask it to remember. Both paths de-duplicate against existing memories (exact and fuzzy title matching) so the same fact doesn't pile up across sessions, and an explicit `remember` call can mark an older memory as superseded when something changes.
|
|
164
|
+
|
|
165
|
+
### Skills
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
mazu skills list # saved reusable solutions for this project
|
|
169
|
+
mazu skills forget <name> # delete one
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
When the agent solves a reusable problem, it can save the solution as a plain Python function under `.mazu/skills/<name>/`. The next time a similar task comes up, it can call the skill directly instead of solving it again from scratch through the model — a real cost and latency win for repeated, mechanical work.
|
|
173
|
+
|
|
174
|
+
### Checkpoints & rollback
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
mazu checkpoint # manually snapshot code + memory (outside a chat session)
|
|
178
|
+
mazu checkpoint prune --keep 20 # drop old on-disk snapshot copies (git history is untouched)
|
|
179
|
+
mazu rollback # restore to the most recent checkpoint
|
|
180
|
+
mazu rollback cp_000003 # restore to a specific one
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
A checkpoint bundles a git commit, a consistent copy of the memory database (taken via SQLite's online backup API, safe even mid-write), the skill library, and the conversation transcript. Restoring one restores all of them together, so code, what the agent remembers, and what it was talking about never drift out of sync with each other.
|
|
184
|
+
|
|
185
|
+
### Council mode
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
mazu council "should we migrate this service to async I/O, and how risky is it?"
|
|
189
|
+
mazu council "..." --models anthropic:claude-sonnet-5,openai:gpt-5,deepseek:deepseek-chat --lead anthropic:claude-opus-4-8
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Asks each model independently and in parallel (they don't see each other's answers), then has the lead model compare and synthesize a single recommendation. Council members get **read-only** tools only (`read_file`, `list_dir`, `glob_files`, `recall`, `list_skills`) — they can inspect your project to give an informed answer, but can't write, edit, or run anything, so asking several models at once never risks them clobbering each other's changes. This is opt-in and costs one API call per model plus one for the lead — not something you'd want as the default flow for routine tasks.
|
|
193
|
+
|
|
194
|
+
## Model naming
|
|
195
|
+
|
|
196
|
+
Models are named `provider:model` — e.g. `anthropic:claude-sonnet-5`, `openai:gpt-5`, `deepseek:deepseek-chat`, `deepseek:deepseek-reasoner`. A bare name with no prefix (`MAZU_MODEL=claude-opus-4-8`) is assumed to be Anthropic.
|
|
197
|
+
|
|
198
|
+
Resolution order when you don't pass `--model`:
|
|
199
|
+
1. `MAZU_MODEL` environment variable, if set.
|
|
200
|
+
2. Auto-detected from whichever provider's API key is actually present in your environment.
|
|
201
|
+
3. A hardcoded Anthropic fallback (which just surfaces a clear "set ANTHROPIC_API_KEY" message if you truly have no key configured).
|
|
202
|
+
|
|
203
|
+
A DeepSeek-only or OpenAI-only setup works with zero extra flags — Anthropic is only a tie-breaker if more than one key happens to be set, never a hard requirement.
|
|
204
|
+
|
|
205
|
+
## How it fits together
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
mazu/
|
|
209
|
+
├── cli.py Click entry point — chat / run / council / memory / skills / checkpoint / rollback
|
|
210
|
+
├── agent/
|
|
211
|
+
│ ├── loop.py interactive chat REPL
|
|
212
|
+
│ ├── autonomous.py unattended multi-step runner with circuit breaker + cost limit
|
|
213
|
+
│ ├── council.py parallel multi-model advisory round + lead synthesis
|
|
214
|
+
│ ├── context.py builds the system prompt from project + global memory + skills
|
|
215
|
+
│ └── prompts.py the system prompt itself
|
|
216
|
+
├── llm/
|
|
217
|
+
│ ├── client.py single run_turn()/run_forced_tool() seam every provider call goes through
|
|
218
|
+
│ ├── providers/ Anthropic, OpenAI, DeepSeek adapters behind a common interface
|
|
219
|
+
│ ├── errors.py normalized error hierarchy (rate limit, auth, transient, context-length)
|
|
220
|
+
│ └── pricing.py rough per-model cost estimates for --max-cost
|
|
221
|
+
├── memory/
|
|
222
|
+
│ ├── store.py SQLite-backed memory store (shared by project + global instances)
|
|
223
|
+
│ ├── retrieval.py BM25 ranking + context-block rendering
|
|
224
|
+
│ └── extraction.py end-of-session auto-extraction prompt
|
|
225
|
+
├── checkpoint/
|
|
226
|
+
│ └── manager.py git commit + memory/skills/conversation snapshot, retention/pruning
|
|
227
|
+
├── skills/
|
|
228
|
+
│ └── manager.py save/list/run local skill functions
|
|
229
|
+
└── tools/ read_file, write_file, edit_file, list_dir, glob_files, run_shell,
|
|
230
|
+
remember, recall, save_skill, run_skill, list_skills
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
The project-scoped memory database lives at `.mazu/memory.db` (created by `mazu init`, gitignored by default). The global, cross-project store lives at `~/.mazu/global_memory.db`, outside any project entirely.
|
|
234
|
+
|
|
235
|
+
## Security notes
|
|
236
|
+
|
|
237
|
+
- All file tools are sandboxed to the project root — paths (including through symlinks) that resolve outside it are rejected.
|
|
238
|
+
- Shell commands go through a shared denylist (destructive/irreversible patterns) in **both** `mazu chat` and `mazu run`, regardless of confirmation settings.
|
|
239
|
+
- API keys are only ever read from environment variables or `~/.mazu/config.toml` (outside any repo) — Mazu never writes a key to disk itself, and `.mazu/`, `.env`, and `config.toml` are all gitignored by default.
|
|
240
|
+
- `mazu run` refuses to start with uncommitted changes already present, so autonomous edits are always diffable against a clean baseline.
|
|
241
|
+
|
|
242
|
+
## Status & roadmap
|
|
243
|
+
|
|
244
|
+
Milestones M1–M4 (bare tool loop, persistent memory, checkpoint/rollback, supervised autonomy) all have a working implementation, plus multi-provider support and council mode on top. This has been exercised through live testing against real Anthropic, OpenAI, and DeepSeek API keys — chat/run tool use, memory recall (project and global), skill save/run, checkpoint/rollback (including pruning and skill restoration), memory supersede, and parallel council queries have all been verified working end-to-end.
|
|
245
|
+
|
|
246
|
+
**Known gaps, honestly listed:**
|
|
247
|
+
- No automated test suite yet (`pytest`) — verification so far has been live testing plus ad-hoc smoke scripts, not a checked-in regression suite.
|
|
248
|
+
- No semantic/embedding-based memory retrieval yet — BM25 is a solid, zero-cost baseline, but pure keyword ranking can miss a relevant memory that's phrased very differently from the current task.
|
|
249
|
+
- Checkpoint/rollback is linear (like `git reset --hard`), not a branching tree.
|
|
250
|
+
- No context compaction for very long autonomous runs — a run that grows the conversation past a model's context window will surface a clear error rather than crash, but won't automatically summarize and continue.
|
|
251
|
+
- Windows-only testing so far; Mac/Linux should work (nothing OS-specific in the design) but hasn't been verified live.
|
|
252
|
+
- No `mazu memory consolidate` command yet for manually merging/cleaning up accumulated memories.
|
|
253
|
+
- No Google Gemini provider yet — the adapter interface is designed to make this a small addition, not a redesign.
|
|
254
|
+
|
|
255
|
+
Contributions and issue reports are welcome.
|
|
256
|
+
|
|
257
|
+
## License
|
|
258
|
+
|
|
259
|
+
MIT — see [LICENSE](LICENSE). Free to use, modify, and distribute, commercially or otherwise, as long as the copyright notice (Turgut Sofuyev) is kept in copies of the software.
|
mazu-0.1.0/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Mazu
|
|
2
|
+
|
|
3
|
+
**A memory-augmented, checkpointable coding agent CLI.** Open source, runs entirely on your own machine, works with Anthropic, OpenAI, or DeepSeek.
|
|
4
|
+
|
|
5
|
+
Most coding agents forget everything the moment the session ends. Mazu doesn't. It keeps a real, queryable memory of your project — decisions, conventions, mistakes — that persists across sessions and gets surfaced automatically. And because every autonomous step is checkpointed (code + memory + conversation, together), you can let it run longer and less-supervised without losing the ability to undo it.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
███╗ ███╗
|
|
9
|
+
████╗ ████║ A Z U
|
|
10
|
+
██╔████╔██║ ══════════════════════════════
|
|
11
|
+
██║╚██╔╝██║ memory-augmented coding agent
|
|
12
|
+
██║ ╚═╝ ██║ persistent memory · checkpoints · skills · multi-model
|
|
13
|
+
╚═╝ ╚═╝
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## What makes Mazu different
|
|
17
|
+
|
|
18
|
+
Compared to typical coding-agent CLIs, which reset context every session and rely on a static instructions file:
|
|
19
|
+
|
|
20
|
+
1. **Persistent structured memory.** Decisions, conventions, and mistakes made on a project are written to a local SQLite database, ranked by local BM25 (zero API cost — no embedding calls) against your current task, and automatically injected back into context. You never have to re-explain "we use Postgres, not SQLite" in every new session.
|
|
21
|
+
2. **A separate, global memory for *you*, not the project.** Personal facts — your name, preferred language, experience level, working style — live in `~/.mazu/global_memory.db` and follow you into every project, instead of being repeated (or lost) per-repo.
|
|
22
|
+
3. **Checkpointable autonomy.** Every step of an autonomous run snapshots code (via git), the memory database, and the live conversation together. Roll back any one of them and you roll back all three, consistently — "undo" for an agent's actions, not just its files.
|
|
23
|
+
4. **A self-growing local skill library.** When the agent solves something reusable, it can save it as a plain Python function. Next time a similar task comes up, it can run the skill directly — skipping the model call entirely.
|
|
24
|
+
5. **Provider-agnostic.** Anthropic, OpenAI, and DeepSeek are all first-class, behind one thin adapter interface. Mazu auto-detects which one to use from whichever API key is actually set in your environment — no provider is required over another.
|
|
25
|
+
6. **Council mode.** For a decision worth a second opinion, ask two or three different models the same question in parallel and have a lead model synthesize a final recommendation — opt-in, since it costs more than a single call.
|
|
26
|
+
|
|
27
|
+
Everything above (agent loop, tool execution, memory database, skill library, checkpoints) runs locally. The only network traffic is your chosen model's API call, plus one cheap end-of-session call (on the same provider) to extract memories from the transcript. Nothing else leaves your machine, and there is no server run by this project.
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
Requires **Python 3.11+** and **git** (used for checkpoints).
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
git clone https://github.com/<your-username>/mazu.git
|
|
35
|
+
cd mazu
|
|
36
|
+
pip install -e .
|
|
37
|
+
|
|
38
|
+
# Only needed for openai:* or deepseek:* models (DeepSeek's API is OpenAI-compatible,
|
|
39
|
+
# so it reuses the same client library under a different base URL):
|
|
40
|
+
pip install -e ".[openai]"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Then set at least one API key — Mazu picks whichever provider is present automatically, so you only need the one you actually plan to use:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
export ANTHROPIC_API_KEY=sk-ant-... # or store it in ~/.mazu/config.toml
|
|
47
|
+
export DEEPSEEK_API_KEY=sk-...
|
|
48
|
+
export OPENAI_API_KEY=sk-...
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
On Windows (PowerShell): `$env:ANTHROPIC_API_KEY = "sk-ant-..."`
|
|
52
|
+
|
|
53
|
+
## Quick start
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
cd your-project/
|
|
57
|
+
mazu init # creates .mazu/ (local memory + checkpoints) and a git repo if needed
|
|
58
|
+
mazu chat # start talking to the agent
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
> we use PostgreSQL for this project, not SQLite. remember that.
|
|
63
|
+
[remember] saved (decision): use PostgreSQL, not SQLite
|
|
64
|
+
> /checkpoint
|
|
65
|
+
[checkpoint] cp_000001 saved (commit 4f2a91c)
|
|
66
|
+
> add a health-check endpoint to app.py and run the tests
|
|
67
|
+
...
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Exit and come back later (even days later) — the next session already knows about PostgreSQL, without you repeating it:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
mazu chat
|
|
74
|
+
> what database does this project use?
|
|
75
|
+
[memory] loaded prior context relevant to this task
|
|
76
|
+
|
|
77
|
+
PostgreSQL — this was a project decision, not SQLite.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Usage
|
|
81
|
+
|
|
82
|
+
### Interactive chat
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
mazu chat # start a session in the current directory
|
|
86
|
+
mazu chat --model deepseek:deepseek-chat
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Inside the `>` prompt, two extra commands are always available:
|
|
90
|
+
|
|
91
|
+
| Command | Effect |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `/checkpoint` | Snapshot code, memory, and the live conversation right now |
|
|
94
|
+
| `/rollback [id]` | Restore all three to that checkpoint (defaults to the most recent one) |
|
|
95
|
+
|
|
96
|
+
Any destructive tool call (writing a file, editing a file, running a shell command) asks for confirmation first.
|
|
97
|
+
|
|
98
|
+
### Autonomous runs
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
mazu run "add input validation to utils.py, run the tests, and fix any failures" --max-steps 15
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The agent keeps working, unattended, across multiple tool-use rounds until it finishes, hits `--max-steps`, or trips a safety limit. It checkpoints automatically along the way (`--checkpoint-every N`, default every round), so anything it does can be rolled back.
|
|
105
|
+
|
|
106
|
+
Key flags:
|
|
107
|
+
|
|
108
|
+
| Flag | Purpose |
|
|
109
|
+
|---|---|
|
|
110
|
+
| `--max-steps N` | Stop after N tool-use rounds (default 15) |
|
|
111
|
+
| `--checkpoint-every N` | Snapshot every N rounds (default 1) |
|
|
112
|
+
| `--allow-shell` | Skip the confirmation prompt for shell commands (the hardcoded safety denylist below still applies) |
|
|
113
|
+
| `--max-cost USD` | Stop once estimated spend (from a built-in pricing table) reaches this amount |
|
|
114
|
+
| `--keep-checkpoints N` | Prune on-disk checkpoint data beyond the N most recent (default 50) |
|
|
115
|
+
| `--model provider:model` | Override the model for this run |
|
|
116
|
+
|
|
117
|
+
By default, file writes/edits proceed unattended in `run` mode (checkpoints make them recoverable), but shell commands still ask for confirmation unless `--allow-shell` is passed. Regardless of that flag, a hardcoded denylist always blocks a short list of genuinely dangerous commands: force-pushing, `sudo`, touching `~/.ssh`, disk-format commands, and `rm -rf /`-style wipes. Checkpoints undo file damage — they can't undo an irreversible external action like a force-push or a sent network request, so that backstop stays even with `--allow-shell`.
|
|
118
|
+
|
|
119
|
+
`mazu run` refuses to start on a dirty working tree, so the first checkpoint is always a clean baseline. If it's interrupted with **Ctrl-C**, you're offered `[c]ontinue`, `[r]ollback <id>`, or `[q]uit` before anything is lost.
|
|
120
|
+
|
|
121
|
+
### Memory
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
mazu memory list # everything remembered about this project
|
|
125
|
+
mazu memory list --category mistake # filter by category
|
|
126
|
+
mazu memory list --global # the cross-project store (facts about you, not the code)
|
|
127
|
+
mazu memory forget <id> # delete a memory by id
|
|
128
|
+
mazu memory forget <id> --global
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Memory categories: `decision`, `convention`, `mistake`, `task_outcome`, `fact` (all project-scoped) and `user_preference` (global — your name, language, experience level, working style; injected into every project's context automatically).
|
|
132
|
+
|
|
133
|
+
Memories are written two ways: explicitly, when the agent calls `remember` (you can just tell it "remember that..."), and automatically, via a cheap end-of-session pass that extracts anything notable you didn't ask it to remember. Both paths de-duplicate against existing memories (exact and fuzzy title matching) so the same fact doesn't pile up across sessions, and an explicit `remember` call can mark an older memory as superseded when something changes.
|
|
134
|
+
|
|
135
|
+
### Skills
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
mazu skills list # saved reusable solutions for this project
|
|
139
|
+
mazu skills forget <name> # delete one
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
When the agent solves a reusable problem, it can save the solution as a plain Python function under `.mazu/skills/<name>/`. The next time a similar task comes up, it can call the skill directly instead of solving it again from scratch through the model — a real cost and latency win for repeated, mechanical work.
|
|
143
|
+
|
|
144
|
+
### Checkpoints & rollback
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
mazu checkpoint # manually snapshot code + memory (outside a chat session)
|
|
148
|
+
mazu checkpoint prune --keep 20 # drop old on-disk snapshot copies (git history is untouched)
|
|
149
|
+
mazu rollback # restore to the most recent checkpoint
|
|
150
|
+
mazu rollback cp_000003 # restore to a specific one
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
A checkpoint bundles a git commit, a consistent copy of the memory database (taken via SQLite's online backup API, safe even mid-write), the skill library, and the conversation transcript. Restoring one restores all of them together, so code, what the agent remembers, and what it was talking about never drift out of sync with each other.
|
|
154
|
+
|
|
155
|
+
### Council mode
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
mazu council "should we migrate this service to async I/O, and how risky is it?"
|
|
159
|
+
mazu council "..." --models anthropic:claude-sonnet-5,openai:gpt-5,deepseek:deepseek-chat --lead anthropic:claude-opus-4-8
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Asks each model independently and in parallel (they don't see each other's answers), then has the lead model compare and synthesize a single recommendation. Council members get **read-only** tools only (`read_file`, `list_dir`, `glob_files`, `recall`, `list_skills`) — they can inspect your project to give an informed answer, but can't write, edit, or run anything, so asking several models at once never risks them clobbering each other's changes. This is opt-in and costs one API call per model plus one for the lead — not something you'd want as the default flow for routine tasks.
|
|
163
|
+
|
|
164
|
+
## Model naming
|
|
165
|
+
|
|
166
|
+
Models are named `provider:model` — e.g. `anthropic:claude-sonnet-5`, `openai:gpt-5`, `deepseek:deepseek-chat`, `deepseek:deepseek-reasoner`. A bare name with no prefix (`MAZU_MODEL=claude-opus-4-8`) is assumed to be Anthropic.
|
|
167
|
+
|
|
168
|
+
Resolution order when you don't pass `--model`:
|
|
169
|
+
1. `MAZU_MODEL` environment variable, if set.
|
|
170
|
+
2. Auto-detected from whichever provider's API key is actually present in your environment.
|
|
171
|
+
3. A hardcoded Anthropic fallback (which just surfaces a clear "set ANTHROPIC_API_KEY" message if you truly have no key configured).
|
|
172
|
+
|
|
173
|
+
A DeepSeek-only or OpenAI-only setup works with zero extra flags — Anthropic is only a tie-breaker if more than one key happens to be set, never a hard requirement.
|
|
174
|
+
|
|
175
|
+
## How it fits together
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
mazu/
|
|
179
|
+
├── cli.py Click entry point — chat / run / council / memory / skills / checkpoint / rollback
|
|
180
|
+
├── agent/
|
|
181
|
+
│ ├── loop.py interactive chat REPL
|
|
182
|
+
│ ├── autonomous.py unattended multi-step runner with circuit breaker + cost limit
|
|
183
|
+
│ ├── council.py parallel multi-model advisory round + lead synthesis
|
|
184
|
+
│ ├── context.py builds the system prompt from project + global memory + skills
|
|
185
|
+
│ └── prompts.py the system prompt itself
|
|
186
|
+
├── llm/
|
|
187
|
+
│ ├── client.py single run_turn()/run_forced_tool() seam every provider call goes through
|
|
188
|
+
│ ├── providers/ Anthropic, OpenAI, DeepSeek adapters behind a common interface
|
|
189
|
+
│ ├── errors.py normalized error hierarchy (rate limit, auth, transient, context-length)
|
|
190
|
+
│ └── pricing.py rough per-model cost estimates for --max-cost
|
|
191
|
+
├── memory/
|
|
192
|
+
│ ├── store.py SQLite-backed memory store (shared by project + global instances)
|
|
193
|
+
│ ├── retrieval.py BM25 ranking + context-block rendering
|
|
194
|
+
│ └── extraction.py end-of-session auto-extraction prompt
|
|
195
|
+
├── checkpoint/
|
|
196
|
+
│ └── manager.py git commit + memory/skills/conversation snapshot, retention/pruning
|
|
197
|
+
├── skills/
|
|
198
|
+
│ └── manager.py save/list/run local skill functions
|
|
199
|
+
└── tools/ read_file, write_file, edit_file, list_dir, glob_files, run_shell,
|
|
200
|
+
remember, recall, save_skill, run_skill, list_skills
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The project-scoped memory database lives at `.mazu/memory.db` (created by `mazu init`, gitignored by default). The global, cross-project store lives at `~/.mazu/global_memory.db`, outside any project entirely.
|
|
204
|
+
|
|
205
|
+
## Security notes
|
|
206
|
+
|
|
207
|
+
- All file tools are sandboxed to the project root — paths (including through symlinks) that resolve outside it are rejected.
|
|
208
|
+
- Shell commands go through a shared denylist (destructive/irreversible patterns) in **both** `mazu chat` and `mazu run`, regardless of confirmation settings.
|
|
209
|
+
- API keys are only ever read from environment variables or `~/.mazu/config.toml` (outside any repo) — Mazu never writes a key to disk itself, and `.mazu/`, `.env`, and `config.toml` are all gitignored by default.
|
|
210
|
+
- `mazu run` refuses to start with uncommitted changes already present, so autonomous edits are always diffable against a clean baseline.
|
|
211
|
+
|
|
212
|
+
## Status & roadmap
|
|
213
|
+
|
|
214
|
+
Milestones M1–M4 (bare tool loop, persistent memory, checkpoint/rollback, supervised autonomy) all have a working implementation, plus multi-provider support and council mode on top. This has been exercised through live testing against real Anthropic, OpenAI, and DeepSeek API keys — chat/run tool use, memory recall (project and global), skill save/run, checkpoint/rollback (including pruning and skill restoration), memory supersede, and parallel council queries have all been verified working end-to-end.
|
|
215
|
+
|
|
216
|
+
**Known gaps, honestly listed:**
|
|
217
|
+
- No automated test suite yet (`pytest`) — verification so far has been live testing plus ad-hoc smoke scripts, not a checked-in regression suite.
|
|
218
|
+
- No semantic/embedding-based memory retrieval yet — BM25 is a solid, zero-cost baseline, but pure keyword ranking can miss a relevant memory that's phrased very differently from the current task.
|
|
219
|
+
- Checkpoint/rollback is linear (like `git reset --hard`), not a branching tree.
|
|
220
|
+
- No context compaction for very long autonomous runs — a run that grows the conversation past a model's context window will surface a clear error rather than crash, but won't automatically summarize and continue.
|
|
221
|
+
- Windows-only testing so far; Mac/Linux should work (nothing OS-specific in the design) but hasn't been verified live.
|
|
222
|
+
- No `mazu memory consolidate` command yet for manually merging/cleaning up accumulated memories.
|
|
223
|
+
- No Google Gemini provider yet — the adapter interface is designed to make this a small addition, not a redesign.
|
|
224
|
+
|
|
225
|
+
Contributions and issue reports are welcome.
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
MIT — see [LICENSE](LICENSE). Free to use, modify, and distribute, commercially or otherwise, as long as the copyright notice (Turgut Sofuyev) is kept in copies of the software.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
File without changes
|