mlx-bun 0.0.4 → 0.0.6
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 +175 -93
- package/docs/dag/training-inference-map.html +575 -0
- package/docs/design/adapters-end-to-end.md +50 -46
- package/docs/design/compat-cli-surface-design.md +10 -8
- package/docs/design/docs-reorg-plan.md +14 -1
- package/docs/design/hlg-sampling.md +12 -2
- package/docs/design/memory-system.md +193 -295
- package/docs/design/optimization_plan.md +4 -2
- package/docs/design/orpo-dynamic-lambda.md +179 -0
- package/docs/design/orpo-future-enhancements.md +340 -0
- package/docs/design/orpo-training.md +1212 -0
- package/docs/design/parallel-slots.md +34 -26
- package/docs/design/parity-tier-dag.md +143 -0
- package/docs/design/runtime-isolation.md +1 -1
- package/docs/design/segmented-backward-training.md +58 -39
- package/docs/design/tauri-desktop-app.md +127 -0
- package/docs/design/w4a16-compute-precision-spike.md +232 -0
- package/docs/investigations/orpo-base-uf-experiment-and-directions.md +120 -0
- package/docs/investigations/orpo-flash-cce-pin-leak.md +167 -0
- package/docs/investigations/orpo-uf-testing-handoff.md +126 -0
- package/docs/{segmented-backward-handoff.md → investigations/segmented-backward-handoff.md} +1 -1
- package/docs/investigations/starter-model-port-handoff.md +32 -13
- package/docs/investigations/steel-flash-cce-handoff.md +489 -0
- package/docs/investigations/trainer-validation-experiment.md +173 -0
- package/docs/planning/IDEAS.md +29 -0
- package/docs/planning/PRODUCT_ROADMAP.md +147 -27
- package/docs/planning/chunk-task-roadmap.md +1 -1
- package/docs/planning/journal.md +161 -0
- package/docs/reference/distribution.md +61 -5
- package/docs/reference/library-api.md +29 -14
- package/docs/reference/memory.md +77 -0
- package/docs/reference/orpo-quickstart.md +130 -0
- package/docs/reference/server-api.md +105 -7
- package/docs/reference/server-config.md +12 -5
- package/docs/reference/training.md +296 -0
- package/package.json +1 -1
- package/src/cli.ts +651 -18
- package/src/eval/ifeval.ts +138 -0
- package/src/eval/runner.ts +76 -6
- package/src/eval/tasks/bfcl.ts +49 -15
- package/src/eval/tasks/gsm8k.ts +21 -9
- package/src/eval/tasks/hashhop.ts +33 -4
- package/src/eval/tasks/humaneval.ts +30 -8
- package/src/eval/tasks/ifeval.ts +52 -18
- package/src/eval/tasks/mmlu.ts +85 -74
- package/src/eval/ultrafeedback.ts +60 -0
- package/src/jobs/runner.ts +6 -0
- package/src/lora.ts +12 -7
- package/src/memory/chunk.ts +25 -0
- package/src/memory/cluster.ts +24 -0
- package/src/memory/db.ts +114 -0
- package/src/memory/ingest.ts +22 -0
- package/src/memory/pipeline.ts +63 -0
- package/src/memory/prompts.ts +23 -0
- package/src/memory/schedule.ts +163 -0
- package/src/memory/synthesize.ts +29 -0
- package/src/memory/tools.ts +399 -0
- package/src/memory/vault.ts +694 -0
- package/src/memory/wikify.ts +23 -0
- package/src/mlx/metal-kernel.ts +31 -4
- package/src/model/flash-attention.ts +37 -19
- package/src/model/fused-geglu-kernel.ts +111 -0
- package/src/model/gemma4-base.ts +39 -1
- package/src/model/gemma4.ts +196 -21
- package/src/model/minicpm5.ts +44 -3
- package/src/pi-provider.ts +29 -13
- package/src/pi-session.ts +81 -0
- package/src/pi-terminal.ts +13 -24
- package/src/pi-web.ts +246 -166
- package/src/quantize/job.ts +17 -2
- package/src/quantize/quantizer.ts +26 -2
- package/src/server.ts +216 -47
- package/src/tokenizer.ts +6 -2
- package/src/train/dataset.ts +29 -6
- package/src/train/flash-cce.ts +1175 -0
- package/src/train/job.ts +64 -3
- package/src/train/lora-params.ts +53 -4
- package/src/train/loss.ts +947 -0
- package/src/train/optimizer.ts +10 -3
- package/src/train/prefix-shared.ts +435 -0
- package/src/train/rank.ts +36 -0
- package/src/train/segmented.ts +1148 -3
- package/src/train/steel-qmm-header.ts +1461 -0
- package/src/train/trainer.ts +570 -54
- package/src/train/watch.ts +542 -0
- package/src/web/app.html +285 -19
- package/src/web/skills/memory/SKILL.md +97 -0
- package/src/web/skills/web-research/SKILL.md +3 -1
- package/src/web/skills.ts +46 -8
- /package/{docs → src/assets}/curve-designer.html +0 -0
|
@@ -1,339 +1,237 @@
|
|
|
1
|
-
# Memory system
|
|
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:
|
|
1
|
+
# Memory system
|
|
95
2
|
|
|
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
|
-
```
|
|
3
|
+
Status: **M0/M0.5 landed (2026-06-19)**. The vault, read tools, CLI, Obsidian open flow, and launchd scheduling are implemented. The actual synthesis stage bodies are still **M1 TODO**; `mlx-bun memory synthesize` is currently a safe no-op stub. The planned M1/M2 synthesis engine uses the same local models the user chats with, plus stage-specific LoRA adapters trained by Josh from the existing Lucien-scale memory corpus and distributed from Hugging Face.
|
|
107
4
|
|
|
108
|
-
|
|
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.
|
|
5
|
+
## Contract
|
|
118
6
|
|
|
119
|
-
|
|
7
|
+
The memory contract is ported from `../lucien`:
|
|
120
8
|
|
|
121
|
-
|
|
122
|
-
create dirs, write Meta pages (only if missing — never clobber user edits),
|
|
123
|
-
write README, `git init` + initial commit. Articles are plain markdown:
|
|
9
|
+
> **Chat-time agents read memory. The synthesis pipeline writes memory.**
|
|
124
10
|
|
|
125
|
-
|
|
126
|
-
# Archie Project
|
|
11
|
+
Memory articles are durable priors. Conversations are evidence. Synthesis is the deliberate, auditable process that turns evidence into updated articles. Normal chat must not mutate articles.
|
|
127
12
|
|
|
128
|
-
|
|
129
|
-
[[AlphaPoint]] beginning spring 2026.[^1][^2]
|
|
13
|
+
This gives both terminal and web the full pi agent experience without turning memory into an unsafe scratchpad:
|
|
130
14
|
|
|
131
|
-
|
|
132
|
-
|
|
15
|
+
- Terminal and web expose the same read-only memory tools through one shared pi surface factory.
|
|
16
|
+
- Memory tools/skill are exposed only when the user has enabled the vault.
|
|
17
|
+
- When enabled, memory is scoped to user-specific continuity: explicit recall, named personal projects/people/preferences/decisions/history, or missing personal context.
|
|
18
|
+
- Memory is **not** the default first step for weather, current public facts, generic web research, or ordinary coding/file tasks where the current files are sufficient.
|
|
19
|
+
- Mutating/coding tools remain full-power and approval-gated by pi/web as usual.
|
|
20
|
+
- Memory article writes happen only through `mlx-bun memory synthesize` once M1 lands.
|
|
21
|
+
- Users can always browse/edit their own Markdown vault directly, especially via Obsidian.
|
|
133
22
|
|
|
134
|
-
##
|
|
135
|
-
[^1]: `conv:a1b2c3d4` (2026-05-10, mlx-bun) — Archie design overview
|
|
136
|
-
```
|
|
23
|
+
## User-facing model
|
|
137
24
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
25
|
+
- User-facing capability: **memory**.
|
|
26
|
+
- Store on disk: `~/.mlx-bun/wiki/` (override: `MLX_BUN_WIKI`).
|
|
27
|
+
- User articles: `~/.mlx-bun/wiki/articles/*.md`.
|
|
28
|
+
- Read-only reference residents: `~/.mlx-bun/wiki/Reference/*.md` symlinked to mlx-bun's own docs.
|
|
29
|
+
- Operational pages: `~/.mlx-bun/wiki/Meta/*.md`.
|
|
30
|
+
- Talk pages: `~/.mlx-bun/wiki/Talk/`.
|
|
31
|
+
- Synthesis DB: `~/.cache/mlx-bun/memory.sqlite`.
|
|
142
32
|
|
|
143
|
-
|
|
33
|
+
The vault is plain Markdown and git-tracked. It is intentionally usable as an Obsidian vault. `Reference/` is a separate read-only namespace: chat tools may search/read it, but synthesis must skip it and never write through those symlinks. The SQLite DB is derived state and lives in the rebuildable cache, not in the user-owned Markdown vault.
|
|
144
34
|
|
|
145
|
-
|
|
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`.
|
|
35
|
+
Stage-specific memory LoRAs are product assets, not user-authored vault content. The creator trains them from the existing memory-pipeline data, publishes them to Hugging Face, and `memory init` can offer to download/cache them for local synthesis.
|
|
151
36
|
|
|
152
|
-
|
|
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.
|
|
37
|
+
## What is implemented now
|
|
156
38
|
|
|
157
|
-
###
|
|
39
|
+
### Vault and article helpers
|
|
158
40
|
|
|
159
|
-
|
|
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.
|
|
41
|
+
`src/memory/vault.ts` implements:
|
|
164
42
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
43
|
+
- `vaultRoot()` → `~/.mlx-bun/wiki` or `MLX_BUN_WIKI`.
|
|
44
|
+
- `setupVault()` — idempotent directory/Meta/README/git setup plus `Reference/` symlinks.
|
|
45
|
+
- `listArticles()` / `listReferenceDocs()` / `listMemoryDocuments()`.
|
|
46
|
+
- `readArticle()` / `searchArticles()` over both user articles and read-only references.
|
|
47
|
+
- `parseToc()` / `extractSection()`.
|
|
48
|
+
- `getArticleLinks()` with resolved inbound/outbound wikilinks.
|
|
49
|
+
- `importArticlesFrom()` for seeding from an existing vault such as `~/Dreaming`.
|
|
50
|
+
- `vaultStatus()` with article/reference counts and recent user article mtimes.
|
|
51
|
+
|
|
52
|
+
The read/search/link logic is ported from Lucien's pure filesystem helpers, not from MCP.
|
|
53
|
+
|
|
54
|
+
### CLI
|
|
55
|
+
|
|
56
|
+
`mlx-bun memory` supports:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
mlx-bun memory init # create vault, optionally import + schedule
|
|
60
|
+
mlx-bun memory setup # alias for init
|
|
61
|
+
mlx-bun memory status # path, article count, git, schedule, recent articles
|
|
62
|
+
mlx-bun memory open # open the vault in Obsidian, fallback Finder
|
|
63
|
+
mlx-bun memory open <article> # open one article in Obsidian/default Markdown app
|
|
64
|
+
mlx-bun memory list # list article stems + Reference/* docs
|
|
65
|
+
mlx-bun memory search <query> # search articles
|
|
66
|
+
mlx-bun memory toc <article> # headings + anchors
|
|
67
|
+
mlx-bun memory section <article> <anchor>
|
|
68
|
+
mlx-bun memory links <article> # inbound/outbound wikilinks
|
|
69
|
+
mlx-bun memory read <article> # print full article
|
|
70
|
+
mlx-bun memory synthesize [--dry-run] [--model <q>] [--since <cursor>]
|
|
71
|
+
mlx-bun memory schedule [--at HH:MM]
|
|
72
|
+
mlx-bun memory unschedule
|
|
173
73
|
```
|
|
174
74
|
|
|
175
|
-
|
|
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.
|
|
75
|
+
`memory synthesize` currently reports the M1 stub and writes nothing. Scheduling is real; the scheduled job is harmless until synthesis lands. In the full flow, `memory init` should also offer to download the memory pipeline adapter pack from Hugging Face so synthesis is ready to run locally.
|
|
179
76
|
|
|
180
|
-
###
|
|
77
|
+
### pi/web tools
|
|
181
78
|
|
|
182
|
-
`
|
|
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]]).
|
|
79
|
+
`src/memory/tools.ts` defines native pi custom tools:
|
|
191
80
|
|
|
192
|
-
|
|
81
|
+
- `memory_search`
|
|
82
|
+
- `memory_read`
|
|
83
|
+
- `memory_toc`
|
|
84
|
+
- `memory_section`
|
|
85
|
+
- `memory_links`
|
|
86
|
+
- `memory_list` (user articles plus read-only `Reference/*` docs)
|
|
87
|
+
- `memory_status` (vault path, setup state, article count, git state, last-synthesis placeholder, schedule state, recent changed articles)
|
|
193
88
|
|
|
194
|
-
|
|
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:
|
|
89
|
+
These tools are registered by the shared pi surface in `src/pi-session.ts` and consumed by both front doors:
|
|
198
90
|
|
|
199
|
-
- `
|
|
200
|
-
|
|
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
|
|
91
|
+
- `src/pi-terminal.ts`
|
|
92
|
+
- `src/pi-web.ts`
|
|
204
93
|
|
|
205
|
-
|
|
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.)
|
|
94
|
+
If the vault does not exist, memory tools and the memory skill are not exposed at all, avoiding prompt fixation on unavailable memory. If the vault exists, `memoryIndexHint()` adds a short scoped presence hint. Detailed usage lives in the memory skill rather than dumping article titles into the prompt.
|
|
215
95
|
|
|
216
|
-
|
|
96
|
+
Read-only mlx-bun docs are now a separate lookup surface (`reference_search`, `reference_read`, `reference_list`) rather than being mixed into personal-memory search. Personal memory answers “what does the user think / what did we decide”; reference tools answer “what do mlx-bun docs say.”
|
|
217
97
|
|
|
218
|
-
|
|
98
|
+
### Bundled memory skill
|
|
219
99
|
|
|
220
|
-
|
|
100
|
+
`src/web/skills/memory/SKILL.md` is bundled through `src/web/skills.ts` and materialized under `~/.mlx-bun/skills` for pi to load.
|
|
221
101
|
|
|
222
|
-
|
|
102
|
+
The skill tells the agent to:
|
|
223
103
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
104
|
+
- consult memory quietly for personal context;
|
|
105
|
+
- use `memory_search` then `memory_read`, or `memory_toc` + `memory_section` for focused reads;
|
|
106
|
+
- use `memory_links` for nearby concepts/backlinks;
|
|
107
|
+
- use `memory_status` for setup/location/schedule questions;
|
|
108
|
+
- never announce retrieval as the user's experience;
|
|
109
|
+
- never edit memory articles during chat;
|
|
110
|
+
- open the vault/article for the user if asked via `mlx-bun memory open [article]`.
|
|
111
|
+
|
|
112
|
+
### Session capture substrate
|
|
113
|
+
|
|
114
|
+
The synthesis pipeline will ingest mlx-bun's own pi sessions only:
|
|
115
|
+
|
|
116
|
+
- web sessions: `~/.mlx-bun/sessions/...` / `~/.mlx-bun/pi-sessions/...` depending on the web `SessionManager` path;
|
|
117
|
+
- terminal sessions: `~/.mlx-bun/pi/sessions/...`.
|
|
118
|
+
|
|
119
|
+
No Playwright, scraping, cloud transcript import, or Lucien runtime dependency is planned for mlx-bun memory.
|
|
120
|
+
|
|
121
|
+
### Scheduling
|
|
122
|
+
|
|
123
|
+
`src/memory/schedule.ts` installs a launchd agent:
|
|
124
|
+
|
|
125
|
+
- label: `com.mlx-bun.memory`
|
|
126
|
+
- plist: `~/Library/LaunchAgents/com.mlx-bun.memory.plist`
|
|
127
|
+
- command: `mlx-bun memory synthesize`
|
|
128
|
+
- logs: `~/.mlx-bun/logs/memory-synthesis.{out,err}.log`
|
|
129
|
+
|
|
130
|
+
`mlx-bun memory schedule --at 03:00` installs/loads it. `unschedule` unloads/removes it. `status` and `memory_status` report it.
|
|
131
|
+
|
|
132
|
+
## Synthesis pipeline design (M1/M2)
|
|
133
|
+
|
|
134
|
+
The M1/M2 pipeline mirrors Lucien's proven stages while running on the same local model stack the user chats with. The difference is execution context and authority: chat uses the model conversationally and read-only; synthesis runs the model as a constrained editor behind deterministic gates.
|
|
135
|
+
|
|
136
|
+
```text
|
|
137
|
+
ingest deterministic: pi session JSONL -> memory.sqlite conversations
|
|
138
|
+
chunk base model + memory-chunk LoRA -> topic chunks
|
|
139
|
+
cluster base model + memory-bucket LoRA -> buckets / target articles
|
|
140
|
+
synthesize base model + memory-synthesis LoRA -> candidate article updates
|
|
141
|
+
wikify base model + memory-editor LoRA + deterministic normalization
|
|
142
|
+
changelog deterministic: run summary + git commit
|
|
233
143
|
```
|
|
234
144
|
|
|
235
|
-
|
|
145
|
+
The chunking LoRA has already been trained as a WIP artifact. The remaining stage adapters are planned product assets trained by Josh from the existing Lucien/pipeline data and published to Hugging Face. mlx-bun should download/cache them during `memory init` (with user consent) or lazily on first `memory synthesize`.
|
|
236
146
|
|
|
237
|
-
|
|
238
|
-
([web/skills.ts](../../src/web/skills.ts)). This is the best vehicle because:
|
|
147
|
+
Important nouns must stay distinct:
|
|
239
148
|
|
|
240
|
-
-
|
|
241
|
-
|
|
242
|
-
-
|
|
243
|
-
|
|
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.
|
|
149
|
+
- **Conversation** — source transcript/evidence.
|
|
150
|
+
- **Chunk** — topical segment from a conversation.
|
|
151
|
+
- **Bucket** — staging group that collects related chunks.
|
|
152
|
+
- **Article** — durable Markdown memory page.
|
|
247
153
|
|
|
248
|
-
|
|
249
|
-
and the single CLI implementation stays the source of truth.
|
|
154
|
+
### Bookkeeping DB
|
|
250
155
|
|
|
251
|
-
|
|
156
|
+
`src/memory/db.ts` defines `MemoryStore` over `~/.cache/mlx-bun/memory.sqlite` with tables for:
|
|
252
157
|
|
|
253
|
-
|
|
158
|
+
- `conversations`
|
|
159
|
+
- `chunks`
|
|
160
|
+
- `buckets`
|
|
161
|
+
- `watermarks`
|
|
162
|
+
- `synthesized_bucket_chunks`
|
|
254
163
|
|
|
255
|
-
|
|
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.
|
|
164
|
+
The DB is derived and rebuildable from sessions + articles. It should not be committed to the vault.
|
|
265
165
|
|
|
266
|
-
|
|
166
|
+
### Stage-specific adapters
|
|
267
167
|
|
|
268
|
-
|
|
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`.
|
|
168
|
+
The pipeline deliberately uses **four specialized LoRA adapters** rather than one generic memory adapter:
|
|
276
169
|
|
|
277
|
-
|
|
170
|
+
| Stage | Adapter | Job | Primary quality signal |
|
|
171
|
+
| --- | --- | --- | --- |
|
|
172
|
+
| Chunk | memory-chunk | Conversation transcript → topic-coherent chunks | Boundary/label accuracy vs gold chunks |
|
|
173
|
+
| Bucket | memory-bucket | Chunk → existing bucket or new bucket proposal | Stable routing, low duplicate topics, good article target |
|
|
174
|
+
| Synthesize | memory-synthesis | New chunks + existing article → conservative candidate update | Citation preservation, faithful integration, no hallucinated claims |
|
|
175
|
+
| Edit/wikify | memory-editor | Candidate article → normalized wiki Markdown | Style, wikilinks, references, deterministic format compliance |
|
|
278
176
|
|
|
279
|
-
|
|
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]]).
|
|
177
|
+
These adapters do **not** get direct write authority. They produce candidates. The pipeline validates, normalizes, and decides whether to write/commit.
|
|
283
178
|
|
|
284
|
-
|
|
179
|
+
Implementation notes:
|
|
285
180
|
|
|
286
|
-
|
|
287
|
-
|
|
181
|
+
- Adapters should be cached with the rest of mlx-bun's HF/downloaded artifacts, not stored in the wiki vault.
|
|
182
|
+
- `memory init` should describe the adapter pack plainly and ask before downloading multi-MB/GB assets.
|
|
183
|
+
- `memory synthesize --dry-run` must work without downloading adapters when it only builds the deterministic manifest.
|
|
184
|
+
- If a required adapter is missing for a real synthesis stage, the command should offer the download or fail cleanly; it should not silently fall back to an untrained prompt path unless explicitly requested.
|
|
185
|
+
- Future routing should use the existing adapter-scoped generation path: one resident base model, stage LoRA mounted per pipeline call.
|
|
288
186
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
187
|
+
### Current stage modules
|
|
188
|
+
|
|
189
|
+
These files exist as typed stubs and currently throw if called directly:
|
|
190
|
+
|
|
191
|
+
- `src/memory/ingest.ts`
|
|
192
|
+
- `src/memory/chunk.ts`
|
|
193
|
+
- `src/memory/cluster.ts`
|
|
194
|
+
- `src/memory/synthesize.ts`
|
|
195
|
+
- `src/memory/wikify.ts`
|
|
196
|
+
- `src/memory/prompts.ts`
|
|
197
|
+
|
|
198
|
+
`src/memory/pipeline.ts` intentionally does **not** call them yet. It emits a no-op M1-stub plan so manual and scheduled synthesis cannot accidentally corrupt the vault before gates exist.
|
|
199
|
+
|
|
200
|
+
## Synthesis quality gates to port from Lucien
|
|
201
|
+
|
|
202
|
+
M1 should preserve these Lucien properties:
|
|
203
|
+
|
|
204
|
+
- deterministic manifest / dry-run before writes;
|
|
205
|
+
- per-bucket/per-article workers so failures are isolated;
|
|
206
|
+
- idempotency via `synthesized_bucket_chunks`;
|
|
207
|
+
- backfill behavior for existing imported articles;
|
|
208
|
+
- orphan detection when ledger and files disagree;
|
|
209
|
+
- conservative update prompt: integrate, do not rewrite wholesale;
|
|
210
|
+
- minimum word-count/truncation guard, e.g. Lucien's 70% floor;
|
|
211
|
+
- citation preservation: every original `conv:` reference survives;
|
|
212
|
+
- deterministic footnote repair;
|
|
213
|
+
- deterministic wikilink normalization;
|
|
214
|
+
- git commit for article changes;
|
|
215
|
+
- changelog / run summary.
|
|
216
|
+
|
|
217
|
+
A weak local-model synthesis pass should no-op, not damage the vault. This remains true even with trained adapters: LoRAs propose; deterministic gates dispose. Synthesis must operate only on `articles/` and must treat `Reference/` as immutable read-only context.
|
|
218
|
+
|
|
219
|
+
## Consent and safety
|
|
220
|
+
|
|
221
|
+
- Local session capture is local-only and part of pi/web session persistence.
|
|
222
|
+
- Creating the vault is explicit: `mlx-bun memory init`.
|
|
223
|
+
- Scheduling is explicit: `mlx-bun memory schedule` or the init wizard prompt.
|
|
224
|
+
- Chat-time memory tools are read-only and auto-allowed.
|
|
225
|
+
- Opening Obsidian/Finder is user-directed browsing/editing; it is not agent mutation.
|
|
226
|
+
- Article mutation by the agent during chat is out of bounds.
|
|
227
|
+
|
|
228
|
+
## Next implementation steps
|
|
303
229
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
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.
|
|
230
|
+
1. Implement `memory synthesize --dry-run` manifest generation without model calls.
|
|
231
|
+
2. Add memory adapter-pack metadata and `memory init` download prompt (HF-hosted LoRAs; chunk adapter exists as WIP, others follow).
|
|
232
|
+
3. Implement ingest from saved pi session JSONL into `MemoryStore`.
|
|
233
|
+
4. Wire the chunk stage to the memory-chunk LoRA and evaluate with chunk boundary/label accuracy.
|
|
234
|
+
5. Implement bucket assignment with the memory-bucket LoRA and article manifest create/update/backfill/orphan modes.
|
|
235
|
+
6. Implement per-article synthesis workers with the memory-synthesis LoRA and conservative gates.
|
|
236
|
+
7. Implement editor/wikify adapter pass plus deterministic footnote/wikilink normalization and git commits.
|
|
237
|
+
8. Move synthesis execution onto the jobs runner with SSE progress once manual synthesis is reliable.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# mlx-bun: gemma4.ts decompose & optimize — action plan
|
|
2
2
|
|
|
3
3
|
> This is the canonical **design/rationale** for the optimization work.
|
|
4
|
-
> Live **status/tracking** (checkboxes, findings) lives in
|
|
5
|
-
>
|
|
4
|
+
> Live **status/tracking** (checkboxes, findings) for Phases A–D lives in
|
|
5
|
+
> PLAN-archive.md; Phase E remains in PLAN.md.
|
|
6
|
+
|
|
7
|
+
**Status (verified 2026-06-17):** Phases A–D are **DONE** (`[x]` in PLAN-archive.md, all landed 2026-06-10/11). Phase E — per-config fused decode-SDPA kernel — is **in progress** (`[~]` in PLAN.md, started 2026-06-11; fused kernel exists and is quality-gated per PLAN.md Step 4). The body of this doc remains the durable design rationale; completed phase checkboxes and findings live in PLAN-archive.md; Phase E tracking lives in PLAN.md.
|
|
6
8
|
|
|
7
9
|
**Premise (confirmed from the source read):** the current engine sits at
|
|
8
10
|
parity-to-ahead vs mlx-lm on the 12B *while still interpreting the decode
|