mlx-bun 0.0.4
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/LICENSE +21 -0
- package/README.md +362 -0
- package/THIRD_PARTY_LICENSES.md +41 -0
- package/bin/mlx-bun.mjs +32 -0
- package/docs/curve-designer.html +303 -0
- package/docs/design/adapters-end-to-end.md +201 -0
- package/docs/design/compat-cli-surface-design.md +227 -0
- package/docs/design/docs-reorg-plan.md +152 -0
- package/docs/design/hlg-sampling.md +340 -0
- package/docs/design/memory-system.md +339 -0
- package/docs/design/optimization_plan.md +344 -0
- package/docs/design/parallel-slots.md +515 -0
- package/docs/design/runtime-isolation.md +247 -0
- package/docs/design/segmented-backward-training.md +508 -0
- package/docs/investigations/chunk-finetune-experiment.md +84 -0
- package/docs/investigations/curve-bisector-routing.md +123 -0
- package/docs/investigations/curve-runs/bisector-route.json +98 -0
- package/docs/investigations/curve-runs/bisector-trace.json +1393 -0
- package/docs/investigations/curve-runs/curve-terrain.json +1179 -0
- package/docs/investigations/curve-runs/curve-terrain.svg +42 -0
- package/docs/investigations/curve-terrain.html +105 -0
- package/docs/investigations/expert-offload-single-user-moe.md +292 -0
- package/docs/investigations/hlg-ab.html +34 -0
- package/docs/investigations/hlg-explorer.html +238 -0
- package/docs/investigations/hlg-figs/cliff.svg +1 -0
- package/docs/investigations/hlg-figs/cross.svg +1 -0
- package/docs/investigations/hlg-figs/edges.svg +1 -0
- package/docs/investigations/hlg-figs/k20-grids.svg +1 -0
- package/docs/investigations/hlg-figs/k20-peaks.svg +1 -0
- package/docs/investigations/hlg-figs/lw-curve.svg +1 -0
- package/docs/investigations/hlg-figs/terrain.svg +1 -0
- package/docs/investigations/hlg-report.html +262 -0
- package/docs/investigations/hlg-runs/hlg-ab.json +149 -0
- package/docs/investigations/hlg-runs/hlg-blind-prompts.md +87 -0
- package/docs/investigations/hlg-runs/hlg-blind.json +107 -0
- package/docs/investigations/hlg-runs/hlg-cliff.json +197 -0
- package/docs/investigations/hlg-runs/hlg-cross.json +505 -0
- package/docs/investigations/hlg-runs/hlg-edge.json +388 -0
- package/docs/investigations/hlg-runs/hlg-eval1.json +25 -0
- package/docs/investigations/hlg-runs/hlg-frontier.json +86 -0
- package/docs/investigations/hlg-runs/hlg-grid.json +242 -0
- package/docs/investigations/hlg-runs/hlg-grid2.json +343 -0
- package/docs/investigations/hlg-runs/hlg-lw-coarse.json +110 -0
- package/docs/investigations/hlg-runs/hlg-map.json +383 -0
- package/docs/investigations/hlg-runs/run0-original.log +159 -0
- package/docs/investigations/hlg-runs/runA-recommended.log +131 -0
- package/docs/investigations/hlg-runs/runAA-cliff-cpm5.log +26 -0
- package/docs/investigations/hlg-runs/runAB-grid2-e4b.log +18 -0
- package/docs/investigations/hlg-runs/runAC-peak-e4b-partial.log +25 -0
- package/docs/investigations/hlg-runs/runAD-ab-samples.log +8 -0
- package/docs/investigations/hlg-runs/runAE-edge-e4b.log +51 -0
- package/docs/investigations/hlg-runs/runAF-logit-calibration.log +10 -0
- package/docs/investigations/hlg-runs/runAG-eval-config2.log +16 -0
- package/docs/investigations/hlg-runs/runB-gain-variants.log +192 -0
- package/docs/investigations/hlg-runs/runC-pivots.log +162 -0
- package/docs/investigations/hlg-runs/runD-oetf.log +132 -0
- package/docs/investigations/hlg-runs/runE-eotf.log +162 -0
- package/docs/investigations/hlg-runs/runF-shaper-working.log +86 -0
- package/docs/investigations/hlg-runs/runG-shaper-sweep.log +101 -0
- package/docs/investigations/hlg-runs/runH-wsweep.log +176 -0
- package/docs/investigations/hlg-runs/runI-asweep.log +176 -0
- package/docs/investigations/hlg-runs/runJ-knobmap.log +49 -0
- package/docs/investigations/hlg-runs/runK-frontier.log +19 -0
- package/docs/investigations/hlg-runs/runL-widemap.log +65 -0
- package/docs/investigations/hlg-runs/runM-frontier-emb.log +15 -0
- package/docs/investigations/hlg-runs/runN-verify.log +116 -0
- package/docs/investigations/hlg-runs/runO-frontier-seed5000.log +15 -0
- package/docs/investigations/hlg-runs/runP-grid-AxSm.log +15 -0
- package/docs/investigations/hlg-runs/runQ-grid-tgW.log +15 -0
- package/docs/investigations/hlg-runs/runR-blind-transcript.log +79 -0
- package/docs/investigations/hlg-runs/runS-cross-coherence.log +33 -0
- package/docs/investigations/hlg-runs/runT-cross-cpm5.log +33 -0
- package/docs/investigations/hlg-runs/runU-cross-12b.log +33 -0
- package/docs/investigations/hlg-runs/runV-lw-e4b.log +22 -0
- package/docs/investigations/hlg-runs/runW-lw-12b.log +22 -0
- package/docs/investigations/hlg-runs/runX-lw-cpm5.log +22 -0
- package/docs/investigations/hlg-runs/runY-cliff-e4b.log +26 -0
- package/docs/investigations/hlg-runs/runZ-cliff-12b.log +26 -0
- package/docs/investigations/hlg-sampling-investigation.md +970 -0
- package/docs/investigations/lab-build-journal.md +157 -0
- package/docs/investigations/pi-builtin-investigation.md +308 -0
- package/docs/investigations/starter-model-port-handoff.md +323 -0
- package/docs/planning/IDEAS.md +26 -0
- package/docs/planning/PRODUCT_ROADMAP.md +426 -0
- package/docs/planning/ResearchTopics.md +119 -0
- package/docs/planning/chunk-task-roadmap.md +77 -0
- package/docs/planning/journal.md +155 -0
- package/docs/reference/distribution.md +121 -0
- package/docs/reference/embedding.md +168 -0
- package/docs/reference/library-api.md +153 -0
- package/docs/reference/server-api.md +224 -0
- package/docs/reference/server-config.md +243 -0
- package/docs/segmented-backward-handoff.md +148 -0
- package/package.json +68 -0
- package/src/anthropic.ts +491 -0
- package/src/chat-template.ts +186 -0
- package/src/cli.ts +1075 -0
- package/src/config.ts +229 -0
- package/src/curve-sampler.ts +122 -0
- package/src/dataset/generators.ts +1087 -0
- package/src/dataset/index.ts +12 -0
- package/src/dataset/job.ts +81 -0
- package/src/dataset/llm.ts +71 -0
- package/src/dataset/registry.ts +528 -0
- package/src/download.ts +283 -0
- package/src/eval/README.md +86 -0
- package/src/eval/kl-prompts.ts +29 -0
- package/src/eval/kl.ts +294 -0
- package/src/eval/quality-db.ts +92 -0
- package/src/eval/runner.ts +102 -0
- package/src/eval/score.ts +49 -0
- package/src/eval/tasks/bfcl.ts +500 -0
- package/src/eval/tasks/gsm8k.ts +85 -0
- package/src/eval/tasks/hashhop.ts +109 -0
- package/src/eval/tasks/humaneval.ts +252 -0
- package/src/eval/tasks/ifeval.ts +354 -0
- package/src/eval/tasks/mmlu.ts +145 -0
- package/src/evaldb.ts +199 -0
- package/src/expert-offload-build.ts +77 -0
- package/src/expert-offload.ts +61 -0
- package/src/expert-trace.ts +67 -0
- package/src/fit.ts +254 -0
- package/src/generate.ts +451 -0
- package/src/harness-pi.ts +177 -0
- package/src/hf-push.ts +628 -0
- package/src/index.ts +22 -0
- package/src/jobs/db.ts +139 -0
- package/src/jobs/index.ts +29 -0
- package/src/jobs/job-entry.ts +106 -0
- package/src/jobs/runner.ts +304 -0
- package/src/jobs/sse.ts +114 -0
- package/src/jobs/types.ts +58 -0
- package/src/kv-store.ts +185 -0
- package/src/lora.ts +314 -0
- package/src/md-modules.d.ts +7 -0
- package/src/mlx/array.ts +237 -0
- package/src/mlx/autograd.ts +267 -0
- package/src/mlx/checkpoint.ts +116 -0
- package/src/mlx/compile.ts +158 -0
- package/src/mlx/custom-vjp.ts +140 -0
- package/src/mlx/ffi.ts +433 -0
- package/src/mlx/metal-kernel.ts +130 -0
- package/src/mlx/ops.ts +707 -0
- package/src/mmap.ts +90 -0
- package/src/model/batched-mask.ts +204 -0
- package/src/model/batched-rotating.ts +300 -0
- package/src/model/compiled-decode.ts +681 -0
- package/src/model/factory.ts +27 -0
- package/src/model/fingerprint.ts +33 -0
- package/src/model/flash-attention.ts +674 -0
- package/src/model/fused-decode-kernel.ts +305 -0
- package/src/model/fused-geglu-kernel.ts +87 -0
- package/src/model/gemma4-base.ts +1616 -0
- package/src/model/gemma4.ts +1012 -0
- package/src/model/generated/gemma4-12b.ts +526 -0
- package/src/model/generated/gemma4-26b.ts +500 -0
- package/src/model/generated/gemma4-e4b.ts +757 -0
- package/src/model/generated/index.ts +18 -0
- package/src/model/minicpm5.ts +278 -0
- package/src/model/qwen3-delta.ts +224 -0
- package/src/model/qwen3_5.ts +429 -0
- package/src/model/support.ts +46 -0
- package/src/native-pack.ts +152 -0
- package/src/pi-provider.ts +95 -0
- package/src/pi-terminal.ts +264 -0
- package/src/pi-web.ts +924 -0
- package/src/preflight.ts +123 -0
- package/src/prompt-cache.ts +113 -0
- package/src/quantize/allocator.ts +627 -0
- package/src/quantize/calibration.ts +180 -0
- package/src/quantize/config-writer.ts +132 -0
- package/src/quantize/index.ts +57 -0
- package/src/quantize/job.ts +136 -0
- package/src/quantize/quantizer.ts +462 -0
- package/src/quantize/safetensors-writer.ts +171 -0
- package/src/quantize/sensitivity.ts +234 -0
- package/src/registry.ts +336 -0
- package/src/responses.ts +774 -0
- package/src/safetensors.ts +158 -0
- package/src/sampler.ts +517 -0
- package/src/serve/batch-scheduler.ts +362 -0
- package/src/serve/generation-gateway.ts +160 -0
- package/src/server.ts +1891 -0
- package/src/spec/drafter.ts +261 -0
- package/src/spec/generate.ts +221 -0
- package/src/status-page.html +497 -0
- package/src/tokenizer.ts +38 -0
- package/src/tool-call.ts +242 -0
- package/src/train/dataset.ts +461 -0
- package/src/train/export.ts +32 -0
- package/src/train/forward.ts +229 -0
- package/src/train/index.ts +43 -0
- package/src/train/job.ts +148 -0
- package/src/train/lora-params.ts +194 -0
- package/src/train/loss.ts +342 -0
- package/src/train/merge.ts +195 -0
- package/src/train/optimizer.ts +176 -0
- package/src/train/rank.ts +101 -0
- package/src/train/segmented.ts +520 -0
- package/src/train/trainer.ts +600 -0
- package/src/tui.ts +161 -0
- package/src/vision/embedder.ts +168 -0
- package/src/vision/preprocess.ts +247 -0
- package/src/vision/prompt.ts +158 -0
- package/src/vision/siglip.ts +599 -0
- package/src/web/app.html +2471 -0
- package/src/web/skills/web-research/SKILL.md +44 -0
- package/src/web/skills.ts +59 -0
- package/src/web-tools.ts +426 -0
- package/src/weights.ts +91 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# Memory system — design sketch
|
|
2
|
+
|
|
3
|
+
Status: **design** (nothing built yet; capture prerequisite already landed)
|
|
4
|
+
Owner: assistant layer (pi-web / pi-terminal / web-tools / jobs)
|
|
5
|
+
Default: **off** until the user opts in (vault + schedule are explicit, consented actions)
|
|
6
|
+
|
|
7
|
+
Ported from **lucien** (`~/Code/lucien`, vault at `~/Dreaming`) — a separate,
|
|
8
|
+
already-working system at real scale (thousands of conversations, hundreds of
|
|
9
|
+
articles). We are **not importing lucien**; we are reimplementing its ideas as a
|
|
10
|
+
first-class, reusable mlx-bun module that runs on the **local model** and wires
|
|
11
|
+
into mlx-bun's own substrate (sessions, jobs, web-tools, skills, CLI).
|
|
12
|
+
|
|
13
|
+
## Goal
|
|
14
|
+
|
|
15
|
+
Give the local assistant durable, user-specific memory so it can **resume
|
|
16
|
+
instead of restart**. The product thesis is "local to you" — the moat is
|
|
17
|
+
private accumulated context, not the weights ([[local-to-you-thesis]]). Memory
|
|
18
|
+
is how that context accumulates.
|
|
19
|
+
|
|
20
|
+
Three steps, the **flywheel**:
|
|
21
|
+
|
|
22
|
+
1. **Capture** — conversations during sessions are saved to disk.
|
|
23
|
+
2. **Synthesize** — nightly, a scheduled pass turns those conversations into
|
|
24
|
+
*articles* (a small personal wiki).
|
|
25
|
+
3. **Consult** — the assistant (web + CLI) has read tools + a skill that make it
|
|
26
|
+
read the relevant articles when answering.
|
|
27
|
+
|
|
28
|
+
Talk → assistant reads the wiki → you add/correct context → nightly synthesis
|
|
29
|
+
folds it into articles → richer next conversation. Articles are *priors*,
|
|
30
|
+
conversations are *evidence*, synthesis updates the priors over time; chat-time
|
|
31
|
+
access is read-only.
|
|
32
|
+
|
|
33
|
+
## Naming: "memory", not "the Dreaming"
|
|
34
|
+
|
|
35
|
+
Recommendation: user-facing name is **memory** (`mlx-bun memory …`), the store
|
|
36
|
+
is `~/.mlx-bun/memory/`. We keep lucien's *good descriptive concepts* (articles,
|
|
37
|
+
wikilinks, Meta governance pages, Talk pages, conservative integrate-don't-
|
|
38
|
+
overwrite synthesis) but drop the mythology ("the Dreaming", "librarian",
|
|
39
|
+
"dreaming"). Reasons:
|
|
40
|
+
|
|
41
|
+
- The Dreaming mythology is Josh's personal branding for a *different* project.
|
|
42
|
+
mlx-bun has its own identity (MLX-only, bun/JS, Apple Silicon, "local to
|
|
43
|
+
you" — [[mlx-bun-scope-and-framing]]). Importing the cosmology muddies the
|
|
44
|
+
product story.
|
|
45
|
+
- "Memory" is the term users already hold (ChatGPT/Claude memory). It's
|
|
46
|
+
self-explanatory in `--help` and in the assistant's "what can you do?" list —
|
|
47
|
+
no glossary required.
|
|
48
|
+
- This is a port/reimplementation, not lucien-the-dependency. A plain name
|
|
49
|
+
avoids implying we ship or require the external lucien MCP.
|
|
50
|
+
|
|
51
|
+
## Port, not import: what carries over and what changes
|
|
52
|
+
|
|
53
|
+
| Aspect | lucien | mlx-bun memory |
|
|
54
|
+
| --- | --- | --- |
|
|
55
|
+
| Read interface | MCP server (stdio) | native web-tools + a bundled skill |
|
|
56
|
+
| Synthesis engine | spawns `claude -p --model opus` (cloud) | **the local model** (in-process / local server) |
|
|
57
|
+
| Conversation sources | claude-code JSONL + claude.ai (Playwright) + codex | **mlx-bun's own sessions** only (web + pi terminal) |
|
|
58
|
+
| Pipeline orchestration | `nightly.sh` + ~36 standalone scripts | a **job runner** on `src/jobs/*` (progress → web UI via SSE) |
|
|
59
|
+
| Scheduling | user-added crontab line | `mlx-bun memory schedule` installs a **launchd** agent |
|
|
60
|
+
| Setup | `lucien_setup` MCP tool | `mlx-bun memory setup` **or** the assistant via a skill |
|
|
61
|
+
| Vault | `~/Dreaming` markdown + git | `~/.mlx-bun/memory/` markdown + git (same format) |
|
|
62
|
+
| State DB | `.lucien/lucien.db` (sqlite) | `memory.sqlite` (sqlite) — see storage decision below |
|
|
63
|
+
|
|
64
|
+
The hard, proven parts we keep wholesale: the **article format** (lead +
|
|
65
|
+
sections + `## References` with `conv:` footnotes + `[[wikilinks]]`), the
|
|
66
|
+
**Meta governance pages** (editorial conventions live *in* the vault, read by
|
|
67
|
+
the synthesis prompts), **idempotency** (watermarks + per-chunk synthesized
|
|
68
|
+
markers so re-runs are safe), and the **conservative synthesis gate** (preserve
|
|
69
|
+
prose, ≥70% word-count floor, every original citation survives).
|
|
70
|
+
|
|
71
|
+
The big departure is **synthesis runs locally**. lucien outsources the hard NLP
|
|
72
|
+
to Opus; we do it on e4b/12B. That fits the privacy thesis (nothing leaves the
|
|
73
|
+
machine) and lines up with the planned **memory LoRAs** — each pipeline stage
|
|
74
|
+
(chunk / classify / synthesize / wikify) is a future specialized adapter routed
|
|
75
|
+
via `adapterScoped` ([[lora-routing-architecture]]). Synthesis quality on a
|
|
76
|
+
local model is the main open *quality* risk; it's a nightly batch job where
|
|
77
|
+
latency doesn't matter, so we gate output the way lucien does. Graceful
|
|
78
|
+
degradation applies
|
|
79
|
+
([[three-tier-parity-and-degradation]]): a weak synthesis pass should no-op, not
|
|
80
|
+
corrupt the vault.
|
|
81
|
+
|
|
82
|
+
## Architecture
|
|
83
|
+
|
|
84
|
+
### Storage layout
|
|
85
|
+
|
|
86
|
+
mlx-bun already splits durable user state from rebuildable cache:
|
|
87
|
+
|
|
88
|
+
- `~/.mlx-bun/` — **durable, user-owned**: `sessions/` (web chat JSONL),
|
|
89
|
+
`pi/` (terminal sessions), `pi-sessions/` (web agentDir), `skills/`,
|
|
90
|
+
`hf.json`.
|
|
91
|
+
- `~/.cache/mlx-bun/` — **rebuildable / derived**: `registry.sqlite`,
|
|
92
|
+
`evals.sqlite`, `jobs.sqlite`, `jobs/`, `datasets/`, `quants/`, `adapters/`.
|
|
93
|
+
|
|
94
|
+
Proposed:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
~/.mlx-bun/memory/ # the vault — precious, user-owned, git-tracked
|
|
98
|
+
articles/ # Topic_Name.md (underscored stems)
|
|
99
|
+
Meta/ # Editorial_Guidelines.md, Article_Conventions.md,
|
|
100
|
+
# Buckets.md, Topics_to_Ignore.md, Synthesis_Pipeline.md
|
|
101
|
+
Talk/ # per-article discussion / conflict notes
|
|
102
|
+
README.md
|
|
103
|
+
.git/ # every synthesis run commits here
|
|
104
|
+
.gitignore # ignores memory.sqlite* (don't commit a binary)
|
|
105
|
+
memory.sqlite # synthesis bookkeeping (cursors, chunks, buckets)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Everything lives under `~/.mlx-bun/memory/`** — the vault *and* the bookkeeping
|
|
109
|
+
DB (decided 2026-06-14). The win is that "your memory" is one self-contained,
|
|
110
|
+
portable folder: copy it and your memory moves to another machine, intact. It
|
|
111
|
+
also keeps the privacy story literal — one place to point at and one place to
|
|
112
|
+
delete. The DB is derived state (it can be rebuilt from the transcripts +
|
|
113
|
+
articles), so the seeded `.gitignore` excludes `memory.sqlite*` — git tracks the
|
|
114
|
+
articles (the source of truth, with history), not the binary index. This is a
|
|
115
|
+
deliberate, documented exception to the codebase's cache-vs-durable split
|
|
116
|
+
(`evals`/`jobs`/`registry` dbs live in `~/.cache/mlx-bun/`), justified by
|
|
117
|
+
treating memory as a single portable unit.
|
|
118
|
+
|
|
119
|
+
### The vault
|
|
120
|
+
|
|
121
|
+
Identical in spirit to lucien's. `mlx-bun memory setup` seeds it idempotently:
|
|
122
|
+
create dirs, write Meta pages (only if missing — never clobber user edits),
|
|
123
|
+
write README, `git init` + initial commit. Articles are plain markdown:
|
|
124
|
+
|
|
125
|
+
```markdown
|
|
126
|
+
# Archie Project
|
|
127
|
+
|
|
128
|
+
The **Archie Project** is an internal AI agent platform Josh built at
|
|
129
|
+
[[AlphaPoint]] beginning spring 2026.[^1][^2]
|
|
130
|
+
|
|
131
|
+
## Origin
|
|
132
|
+
...[^1]
|
|
133
|
+
|
|
134
|
+
## References
|
|
135
|
+
[^1]: `conv:a1b2c3d4` (2026-05-10, mlx-bun) — Archie design overview
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Citations point at `conv:<hash>` — a stable id derived from the source session,
|
|
139
|
+
so an article is traceable back to the conversation that produced it. The vault
|
|
140
|
+
is a valid Obsidian vault for free (browse with Obsidian, edit by hand; the next
|
|
141
|
+
synthesis run respects your edits).
|
|
142
|
+
|
|
143
|
+
### Ingestion — mlx-bun sessions only
|
|
144
|
+
|
|
145
|
+
No Playwright, no web scraping. The capture prerequisite **already exists**:
|
|
146
|
+
web chat persists each session to `~/.mlx-bun/sessions/*.jsonl` via
|
|
147
|
+
`SessionManager.create(...)` ([pi-web.ts:398](../../src/pi-web.ts)), and the
|
|
148
|
+
comment there already names this as "the durable transcript store the nightly
|
|
149
|
+
memory pipeline reads." Terminal pi persists to `~/.mlx-bun/pi`. Both are pi's
|
|
150
|
+
own JSONL format, enumerable via `SessionManager.list/listAll`.
|
|
151
|
+
|
|
152
|
+
So ingestion = read pi sessions → normalize to `{conv uuid, messages[]}` →
|
|
153
|
+
upsert into `memory.sqlite`, tracking a per-source watermark so each nightly run
|
|
154
|
+
only processes what's new. pi's session format becomes the ingestion contract
|
|
155
|
+
for free.
|
|
156
|
+
|
|
157
|
+
### The nightly pipeline (on `src/jobs/*`)
|
|
158
|
+
|
|
159
|
+
Reuse the existing background-job substrate (`src/jobs/{db,runner,sse}.ts`):
|
|
160
|
+
register a `memory-synthesis` runner and `submitSubprocess(...)` it so model
|
|
161
|
+
state is GPU-isolated. Stages mirror lucien, each emitting `stage`/`log` events
|
|
162
|
+
that stream to the web UI through the existing SSE endpoint — synthesis shows up
|
|
163
|
+
in the same jobs panel as quantize/finetune.
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
ingest pi sessions → memory.sqlite (watermark-gated, upsert)
|
|
167
|
+
chunk segment each new conversation into topic chunks (model call)
|
|
168
|
+
cluster assign chunks to existing buckets / propose new (model call)
|
|
169
|
+
synthesize per bucket: create-or-update its article (model call)
|
|
170
|
+
wikify deterministic gate + Wikipedia-style cleanup (non-fatal)
|
|
171
|
+
normalize canonical [[wikilinks]], footnote repair
|
|
172
|
+
changelog per-run digest → Meta/Changelog.md, git commit
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Idempotency is inherited from lucien's design: watermarks (don't re-ingest),
|
|
176
|
+
`chunked_at > updated_at` (re-chunk only changed convs), and a
|
|
177
|
+
`synthesized_bucket_chunks` table (never feed the same chunk into an article
|
|
178
|
+
twice). A killed run resumes cleanly.
|
|
179
|
+
|
|
180
|
+
### Synthesis runs on the local model
|
|
181
|
+
|
|
182
|
+
`mlx-bun memory synthesize` loads a model in-process (or reuses a running
|
|
183
|
+
server) and drives every model call through it — **no cloud, local-only**
|
|
184
|
+
(decided 2026-06-14). Default synthesis model: **e4b** (decided 2026-06-14) —
|
|
185
|
+
lighter, lower memory, and mlx-bun's strongest h2h result; a weak pass is gated
|
|
186
|
+
to no-op rather than allowed to corrupt the vault. Overridable per-run
|
|
187
|
+
(`--model 12B` when you want the parity model's quality). This is the seam where
|
|
188
|
+
the future memory
|
|
189
|
+
LoRAs plug in: today base-model + prompt per stage; later `adapterScoped` per
|
|
190
|
+
stage ([[lora-routing-architecture]]).
|
|
191
|
+
|
|
192
|
+
### Read tools — how the assistant consults memory
|
|
193
|
+
|
|
194
|
+
Add native read tools in `src/web-tools.ts` (the `defineTool` pattern), name
|
|
195
|
+
them in `WEB_TOOL_NAMES`, list them in `ALL_TOOLS` in both
|
|
196
|
+
[pi-web.ts](../../src/pi-web.ts) and [pi-terminal.ts](../../src/pi-terminal.ts);
|
|
197
|
+
read-only, so they auto-allow (no approval gate). Mirror lucien's read surface:
|
|
198
|
+
|
|
199
|
+
- `memory_search` — keyword/substring search across articles → ranked hits with
|
|
200
|
+
section anchors (the discovery entry point)
|
|
201
|
+
- `memory_read` — full article body
|
|
202
|
+
- `memory_list` — list article titles (fallback / overview)
|
|
203
|
+
- (later) `memory_section`, `memory_links` for focused reads + wikilink graph
|
|
204
|
+
|
|
205
|
+
**Knowing *when* to consult** uses three reinforcing mechanisms:
|
|
206
|
+
1. Tool descriptions that strongly cue "search the user's memory when they
|
|
207
|
+
mention their own projects, people, tools, preferences, or history."
|
|
208
|
+
2. A bundled **memory skill** (below) that says "consult quietly before
|
|
209
|
+
answering personal-context questions" — same trigger surface as the
|
|
210
|
+
`anthropic-skills:lucien` skill.
|
|
211
|
+
3. Cheap **index injection**: at session start, put the *list of article titles*
|
|
212
|
+
into the system prompt (a few hundred tokens) so the model knows what exists
|
|
213
|
+
and can fetch the right page. (Not the article bodies — that's what the tools
|
|
214
|
+
are for.)
|
|
215
|
+
|
|
216
|
+
## Two front doors: CLI + assistant
|
|
217
|
+
|
|
218
|
+
One implementation (the CLI / `src/memory` module), two ways to reach it.
|
|
219
|
+
|
|
220
|
+
### CLI — `mlx-bun memory <subcommand>`
|
|
221
|
+
|
|
222
|
+
New `case "memory"` in [cli.ts](../../src/cli.ts) + a `HELP.memory` entry.
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
mlx-bun memory setup create the vault + Meta pages + git (idempotent)
|
|
226
|
+
mlx-bun memory status vault path, #articles, last synthesis, schedule state
|
|
227
|
+
mlx-bun memory synthesize run the pipeline now (--model, --since, --dry-run)
|
|
228
|
+
mlx-bun memory schedule install the nightly launchd agent (--at 03:00)
|
|
229
|
+
mlx-bun memory unschedule remove the launchd agent
|
|
230
|
+
mlx-bun memory search <q> inspect: search articles from the terminal
|
|
231
|
+
mlx-bun memory read <title> inspect: print an article
|
|
232
|
+
mlx-bun memory forget <title> delete an article (git-tracked, recoverable)
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Assistant-driven setup (a bundled skill)
|
|
236
|
+
|
|
237
|
+
Add `src/web/skills/memory/SKILL.md` to `BUNDLED_SKILLS`
|
|
238
|
+
([web/skills.ts](../../src/web/skills.ts)). This is the best vehicle because:
|
|
239
|
+
|
|
240
|
+
- The skill's **description** makes "manage memory" appear under "what can you
|
|
241
|
+
do?" for free.
|
|
242
|
+
- The skill's **body** encodes the explain → consent → setup script: explain in
|
|
243
|
+
plain terms (it's a folder of markdown articles; it saves your conversations;
|
|
244
|
+
it synthesizes them into articles nightly; it uses them to remember you), then
|
|
245
|
+
on agreement run the `mlx-bun memory setup` and `mlx-bun memory schedule`
|
|
246
|
+
commands via the bash tool.
|
|
247
|
+
|
|
248
|
+
So the assistant can both **offer/explain** memory and **set it up** for you,
|
|
249
|
+
and the single CLI implementation stays the source of truth.
|
|
250
|
+
|
|
251
|
+
### Consent model
|
|
252
|
+
|
|
253
|
+
Drawn deliberately, two tiers:
|
|
254
|
+
|
|
255
|
+
- **Capture is default-on, not a consent gate.** Saving sessions locally is what
|
|
256
|
+
pi already does (like shell history) and it never leaves the machine. But
|
|
257
|
+
default-on ≠ silent: state it once ("I keep our chats at `~/.mlx-bun/sessions`
|
|
258
|
+
so I can remember — clear them anytime"). The recent-chats sidebar doubles as
|
|
259
|
+
the "where's my data / delete it" surface.
|
|
260
|
+
- **Synthesis into a persistent wiki + a scheduled job IS the consent gate** —
|
|
261
|
+
that's what changes the privacy posture. The skill asks in prose, and the
|
|
262
|
+
per-action approval gate confirms each persistent change (writing the vault,
|
|
263
|
+
installing the launchd agent). Two natural confirmations, the right amount for
|
|
264
|
+
installing a recurring job.
|
|
265
|
+
|
|
266
|
+
## Scheduling (launchd)
|
|
267
|
+
|
|
268
|
+
mlx-bun has no scheduler today. Recommendation: **launchd**, not crontab.
|
|
269
|
+
mlx-bun is macOS/Apple-Silicon-only by identity, so launchd is the native
|
|
270
|
+
choice — it survives reboot, runs missed jobs, and gives clean
|
|
271
|
+
install/uninstall. `mlx-bun memory schedule` writes
|
|
272
|
+
`~/Library/LaunchAgents/com.mlx-bun.memory.plist` (a `StartCalendarInterval` at
|
|
273
|
+
~03:00 running `mlx-bun memory synthesize`) and `launchctl load`s it;
|
|
274
|
+
`unschedule` unloads + removes it. Schedule state surfaces in
|
|
275
|
+
`mlx-bun memory status`.
|
|
276
|
+
|
|
277
|
+
## Privacy (the throughline)
|
|
278
|
+
|
|
279
|
+
Local model + local vault + local cron + local transcripts — **nothing leaves
|
|
280
|
+
the machine**. This is consistent with the web-chat privacy framing where the
|
|
281
|
+
web tools are the only outbound path. It is also the differentiator: not the
|
|
282
|
+
best AI, the best at knowing *you* ([[local-to-you-thesis]]).
|
|
283
|
+
|
|
284
|
+
## Module layout (reusable)
|
|
285
|
+
|
|
286
|
+
A self-contained `src/memory/` module so the feature is reusable by both the CLI
|
|
287
|
+
and the server, and is testable in isolation:
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
src/memory/
|
|
291
|
+
vault.ts paths, setup (dirs + Meta + git), article read/write/list
|
|
292
|
+
db.ts memory.sqlite: conversations, chunks, buckets, watermarks
|
|
293
|
+
ingest.ts pi sessions → db (uses SessionManager.list/listAll)
|
|
294
|
+
chunk.ts conversation → topic chunks (local-model call)
|
|
295
|
+
cluster.ts chunks → buckets (local-model call)
|
|
296
|
+
synthesize.ts bucket → article create/update + gate (local-model call)
|
|
297
|
+
wikify.ts deterministic editorial gate + normalize
|
|
298
|
+
pipeline.ts registerRunner("memory-synthesis", …) — ties stages together
|
|
299
|
+
tools.ts memory_search / memory_read / memory_list (web-tools)
|
|
300
|
+
schedule.ts launchd plist install/remove
|
|
301
|
+
prompts/ per-stage prompts (the future LoRA seams)
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Phasing
|
|
305
|
+
|
|
306
|
+
- **M0 — vault + read path.** `src/memory/{vault,db}.ts`, `memory setup`, the
|
|
307
|
+
read tools + index injection, the bundled skill (offer/explain/setup). No
|
|
308
|
+
synthesis yet — the assistant can already read a hand-written or imported
|
|
309
|
+
vault. Lets us validate the *consult* half against a real vault (even one
|
|
310
|
+
copied from `~/Dreaming`) before building the pipeline.
|
|
311
|
+
- **M1 — ingest + pipeline (manual).** `ingest/chunk/cluster/synthesize/wikify`
|
|
312
|
+
as a `memory-synthesis` job, run on demand via `memory synthesize`. Validate
|
|
313
|
+
synthesis quality on the local model against every model/quant we care about
|
|
314
|
+
([[per-model-quant-specialization]]).
|
|
315
|
+
- **M2 — schedule.** launchd install/remove; status surfacing; transparency
|
|
316
|
+
line on first capture.
|
|
317
|
+
- **M3 — quality + LoRAs.** Per-stage memory LoRAs via `adapterScoped`; KL /
|
|
318
|
+
quality benchmarks for the synthesis output ([[lora-routing-architecture]]).
|
|
319
|
+
|
|
320
|
+
## Help text + docs changes (don't forget)
|
|
321
|
+
|
|
322
|
+
- `HELP.memory` in [cli.ts](../../src/cli.ts) (+ the top-of-file command list).
|
|
323
|
+
- README: a "Memory" section under the pitch (the flywheel + privacy).
|
|
324
|
+
- `docs/reference/`: a `memory.md` (vault format, CLI surface, tool list).
|
|
325
|
+
- This design doc; update PLAN.md with a Memory phase + exit criteria.
|
|
326
|
+
- The bundled skill description (so "manage memory" shows in "what can you do?").
|
|
327
|
+
|
|
328
|
+
## Decisions (settled 2026-06-14)
|
|
329
|
+
|
|
330
|
+
1. **Storage** — everything (vault + `memory.sqlite`) under `~/.mlx-bun/memory/`,
|
|
331
|
+
one portable folder; `.gitignore` excludes the DB.
|
|
332
|
+
2. **Synthesis engine** — local-only, no cloud; weak output is gated to no-op.
|
|
333
|
+
3. **Default synthesis model** — e4b, overridable per-run (`--model 12B`).
|
|
334
|
+
|
|
335
|
+
## Open decisions
|
|
336
|
+
|
|
337
|
+
1. **Retroactive capture.** On first setup, synthesize past sessions too, or
|
|
338
|
+
future-only? Recommendation: offer "synthesize what's already here" as a
|
|
339
|
+
one-time step right after setup, surfaced by the skill.
|