yaams 0.3.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.
- yaams-0.3.0/LICENSE +21 -0
- yaams-0.3.0/PKG-INFO +308 -0
- yaams-0.3.0/README.md +286 -0
- yaams-0.3.0/pyproject.toml +76 -0
- yaams-0.3.0/setup.cfg +4 -0
- yaams-0.3.0/tests/test_associate.py +183 -0
- yaams-0.3.0/tests/test_calendar.py +40 -0
- yaams-0.3.0/tests/test_cli.py +65 -0
- yaams-0.3.0/tests/test_cli_assoc.py +80 -0
- yaams-0.3.0/tests/test_cli_doctor.py +120 -0
- yaams-0.3.0/tests/test_cli_entity_metadata.py +76 -0
- yaams-0.3.0/tests/test_cli_envelopes.py +144 -0
- yaams-0.3.0/tests/test_cli_ingest_envelope.py +251 -0
- yaams-0.3.0/tests/test_cli_init.py +79 -0
- yaams-0.3.0/tests/test_cli_interactive_rejection.py +46 -0
- yaams-0.3.0/tests/test_cli_merge.py +167 -0
- yaams-0.3.0/tests/test_cli_query_tier.py +168 -0
- yaams-0.3.0/tests/test_cli_remaining_envelopes.py +245 -0
- yaams-0.3.0/tests/test_cli_sources.py +505 -0
- yaams-0.3.0/tests/test_config_aliases.py +71 -0
- yaams-0.3.0/tests/test_config_discovery.py +131 -0
- yaams-0.3.0/tests/test_config_validation.py +67 -0
- yaams-0.3.0/tests/test_consolidate.py +159 -0
- yaams-0.3.0/tests/test_conventions.py +202 -0
- yaams-0.3.0/tests/test_email_mbox.py +371 -0
- yaams-0.3.0/tests/test_embed_prompt.py +50 -0
- yaams-0.3.0/tests/test_entities.py +33 -0
- yaams-0.3.0/tests/test_github.py +156 -0
- yaams-0.3.0/tests/test_imessage.py +244 -0
- yaams-0.3.0/tests/test_ingest_folder.py +231 -0
- yaams-0.3.0/tests/test_ingest_runs.py +101 -0
- yaams-0.3.0/tests/test_junk_detector.py +115 -0
- yaams-0.3.0/tests/test_m365_mail.py +137 -0
- yaams-0.3.0/tests/test_merge.py +185 -0
- yaams-0.3.0/tests/test_metadata.py +89 -0
- yaams-0.3.0/tests/test_normalize_entities.py +128 -0
- yaams-0.3.0/tests/test_parse.py +301 -0
- yaams-0.3.0/tests/test_people_import.py +304 -0
- yaams-0.3.0/tests/test_query_json_envelope.py +122 -0
- yaams-0.3.0/tests/test_query_prompt.py +196 -0
- yaams-0.3.0/tests/test_render.py +99 -0
- yaams-0.3.0/tests/test_retrieve.py +536 -0
- yaams-0.3.0/tests/test_review.py +457 -0
- yaams-0.3.0/tests/test_route.py +192 -0
- yaams-0.3.0/tests/test_signal.py +282 -0
- yaams-0.3.0/tests/test_signals.py +174 -0
- yaams-0.3.0/tests/test_stats_json_envelope.py +85 -0
- yaams-0.3.0/tests/test_store.py +188 -0
- yaams-0.3.0/tests/test_synonyms.py +85 -0
- yaams-0.3.0/tests/test_synthesize.py +253 -0
- yaams-0.3.0/tests/test_teams.py +322 -0
- yaams-0.3.0/tests/test_version.py +41 -0
- yaams-0.3.0/tests/test_watermark.py +21 -0
- yaams-0.3.0/yaams/__init__.py +6 -0
- yaams-0.3.0/yaams/_default_config.yaml +129 -0
- yaams-0.3.0/yaams/cli/__init__.py +22 -0
- yaams-0.3.0/yaams/cli/_envelope.py +167 -0
- yaams-0.3.0/yaams/cli/_root.py +57 -0
- yaams-0.3.0/yaams/cli/_shared.py +107 -0
- yaams-0.3.0/yaams/cli/assoc.py +224 -0
- yaams-0.3.0/yaams/cli/consolidate.py +190 -0
- yaams-0.3.0/yaams/cli/doctor.py +182 -0
- yaams-0.3.0/yaams/cli/enrich.py +85 -0
- yaams-0.3.0/yaams/cli/entities.py +1402 -0
- yaams-0.3.0/yaams/cli/ingest.py +923 -0
- yaams-0.3.0/yaams/cli/main.py +354 -0
- yaams-0.3.0/yaams/cli/promote.py +232 -0
- yaams-0.3.0/yaams/cli/query.py +594 -0
- yaams-0.3.0/yaams/cli/review.py +180 -0
- yaams-0.3.0/yaams/cli/signals.py +143 -0
- yaams-0.3.0/yaams/cli/sources.py +1173 -0
- yaams-0.3.0/yaams/config.py +158 -0
- yaams-0.3.0/yaams/consolidate/__init__.py +19 -0
- yaams-0.3.0/yaams/consolidate/session.py +201 -0
- yaams-0.3.0/yaams/conventions.py +241 -0
- yaams-0.3.0/yaams/db.py +61 -0
- yaams-0.3.0/yaams/enrich/__init__.py +5 -0
- yaams-0.3.0/yaams/enrich/embed.py +78 -0
- yaams-0.3.0/yaams/enrich/entities.py +156 -0
- yaams-0.3.0/yaams/ingest/__init__.py +4 -0
- yaams-0.3.0/yaams/ingest/base.py +34 -0
- yaams-0.3.0/yaams/ingest/calendar.py +85 -0
- yaams-0.3.0/yaams/ingest/email_mbox.py +491 -0
- yaams-0.3.0/yaams/ingest/folder.py +300 -0
- yaams-0.3.0/yaams/ingest/github.py +360 -0
- yaams-0.3.0/yaams/ingest/imessage.py +280 -0
- yaams-0.3.0/yaams/ingest/ledger_notes.py +66 -0
- yaams-0.3.0/yaams/ingest/m365_mail.py +257 -0
- yaams-0.3.0/yaams/ingest/obsidian.py +143 -0
- yaams-0.3.0/yaams/ingest/signal.py +552 -0
- yaams-0.3.0/yaams/ingest/teams.py +353 -0
- yaams-0.3.0/yaams/ingest/teams_chatsvc.py +399 -0
- yaams-0.3.0/yaams/logsetup.py +77 -0
- yaams-0.3.0/yaams/people_import.py +256 -0
- yaams-0.3.0/yaams/promote/__init__.py +4 -0
- yaams-0.3.0/yaams/promote/candidates.py +355 -0
- yaams-0.3.0/yaams/promote/review.py +98 -0
- yaams-0.3.0/yaams/render.py +130 -0
- yaams-0.3.0/yaams/retrieve/__init__.py +19 -0
- yaams-0.3.0/yaams/retrieve/associate.py +232 -0
- yaams-0.3.0/yaams/retrieve/hybrid.py +559 -0
- yaams-0.3.0/yaams/retrieve/metadata.py +64 -0
- yaams-0.3.0/yaams/retrieve/parse.py +377 -0
- yaams-0.3.0/yaams/retrieve/route.py +137 -0
- yaams-0.3.0/yaams/retrieve/synonyms.py +93 -0
- yaams-0.3.0/yaams/schema.py +377 -0
- yaams-0.3.0/yaams/signals/__init__.py +37 -0
- yaams-0.3.0/yaams/signals/logger.py +160 -0
- yaams-0.3.0/yaams/signals/review.py +749 -0
- yaams-0.3.0/yaams/store.py +803 -0
- yaams-0.3.0/yaams/synthesize/__init__.py +29 -0
- yaams-0.3.0/yaams/synthesize/answer.py +232 -0
- yaams-0.3.0/yaams/synthesize/llm.py +266 -0
- yaams-0.3.0/yaams/time.py +31 -0
- yaams-0.3.0/yaams/watermark.py +36 -0
- yaams-0.3.0/yaams.egg-info/PKG-INFO +308 -0
- yaams-0.3.0/yaams.egg-info/SOURCES.txt +119 -0
- yaams-0.3.0/yaams.egg-info/dependency_links.txt +1 -0
- yaams-0.3.0/yaams.egg-info/entry_points.txt +2 -0
- yaams-0.3.0/yaams.egg-info/requires.txt +16 -0
- yaams-0.3.0/yaams.egg-info/top_level.txt +1 -0
yaams-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Carl Joakim Damsleth
|
|
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.
|
yaams-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yaams
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Yet Another Agent Memory System
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: click>=8.1
|
|
9
|
+
Requires-Dist: cryptography>=42.0
|
|
10
|
+
Requires-Dist: pyyaml>=6.0
|
|
11
|
+
Requires-Dist: numpy<2
|
|
12
|
+
Requires-Dist: pyobjc-framework-Cocoa>=12.1; sys_platform == "darwin"
|
|
13
|
+
Requires-Dist: sentence-transformers>=3.0
|
|
14
|
+
Requires-Dist: spacy>=3.7
|
|
15
|
+
Requires-Dist: sqlite-vec>=0.1.6
|
|
16
|
+
Requires-Dist: tqdm>=4.66
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
19
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
20
|
+
Requires-Dist: pyright>=1.1.380; extra == "dev"
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# YAAMS
|
|
24
|
+
|
|
25
|
+
[](LICENSE)
|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
**Yet Another Agent Memory System.** A local-first, high-recall memory store
|
|
29
|
+
for your personal digital exhaust - messages, email, calendar, GitHub
|
|
30
|
+
activity, notes - searchable in seconds and synthesizable into grounded,
|
|
31
|
+
cited answers by the LLM of your choice.
|
|
32
|
+
|
|
33
|
+
YAAMS is Tier 1 of a two-tier memory architecture: the firehose. Tier 2 is
|
|
34
|
+
the [cognitive-ledger](https://github.com/damsleth/cognitive-ledger): curated
|
|
35
|
+
atomic notes you keep forever. YAAMS ingests everything, lets you query
|
|
36
|
+
across the lot, and promotes the gems upstream when you're ready.
|
|
37
|
+
|
|
38
|
+
Each tier is split between a public **engine** and a private **store**:
|
|
39
|
+
|
|
40
|
+
| Tier | Engine (public) | Store (private, your data) |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| Tier 1 | **YAAMS** - this repo | a single SQLite file at `db_path` |
|
|
43
|
+
| Tier 2 | **cognitive-ledger** - sibling repo | a markdown tree of curated atomic notes |
|
|
44
|
+
|
|
45
|
+
Engines ship code, no data. Stores live outside the repo, are gitignored
|
|
46
|
+
by default, and never get pushed.
|
|
47
|
+
|
|
48
|
+
## Suite
|
|
49
|
+
|
|
50
|
+
YAAMS is one of four tools in the **[hugr](https://github.com/damsleth/hugr)**
|
|
51
|
+
memory suite. The suite gives you one install (`brew install
|
|
52
|
+
damsleth/tap/hugr`), one verb surface (`hugr query`, `hugr ingest`,
|
|
53
|
+
`hugr promote`, ...), and one CLI contract (output classes, exit
|
|
54
|
+
codes, action envelopes - see
|
|
55
|
+
[hugr/CONVENTIONS.md](https://github.com/damsleth/hugr/blob/main/CONVENTIONS.md)).
|
|
56
|
+
Power users can still call `yaams` directly and get byte-identical
|
|
57
|
+
JSON.
|
|
58
|
+
|
|
59
|
+
## What
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
query
|
|
63
|
+
|
|
|
64
|
+
v
|
|
65
|
+
ingest -> normalize -> embed -> retrieve -> fuse -> answer (cited)
|
|
66
|
+
| | | |
|
|
67
|
+
iMessage SQLite BGE-M3 Tier 2 boost
|
|
68
|
+
Signal + FTS5 + spaCy (cognitive-ledger)
|
|
69
|
+
Email + vec
|
|
70
|
+
Teams
|
|
71
|
+
Calendar
|
|
72
|
+
GitHub
|
|
73
|
+
Obsidian
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
- **Local-only by default.** Embeddings, NER, and LLM synthesis run on your
|
|
77
|
+
machine. Nothing leaves the host unless you point an adapter at a hosted
|
|
78
|
+
backend.
|
|
79
|
+
- **Append-only.** Raw items are immutable. Re-ingest is idempotent.
|
|
80
|
+
- **Cited answers.** Every synthesized claim points back to the source items.
|
|
81
|
+
- **Pluggable LLM.** `claude`, `codex`, `ollama`, any subprocess, or `dummy`.
|
|
82
|
+
- **Single SQLite file.** No daemons, no servers, no cloud bill.
|
|
83
|
+
|
|
84
|
+
## Why
|
|
85
|
+
|
|
86
|
+
Language models forget everything between sessions, and the answer is not
|
|
87
|
+
"shove more raw chat logs into the context window." The answer is a memory
|
|
88
|
+
system you can grep, query, and audit, that lives on your machine and that
|
|
89
|
+
you fully control.
|
|
90
|
+
|
|
91
|
+
YAAMS gives you that for the high-volume side of your life: every iMessage,
|
|
92
|
+
every email, every calendar event, every GitHub issue you have touched. It
|
|
93
|
+
normalizes them into a common schema, embeds them, and lets you ask
|
|
94
|
+
questions like *"what did we decide about the deploy in May?"* and get back
|
|
95
|
+
a grounded answer with citations - in seconds, offline.
|
|
96
|
+
|
|
97
|
+
## Quickstart
|
|
98
|
+
|
|
99
|
+
Requires Python 3.11+ and macOS (Linux works for everything except the
|
|
100
|
+
iMessage adapter).
|
|
101
|
+
|
|
102
|
+
Homebrew (recommended):
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
brew install damsleth/tap/yaams
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
PyPI via pipx:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pipx install yaams
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Bleeding-edge from main:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
brew install --HEAD damsleth/tap/yaams
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Then bootstrap a config and run the dry-run ingest:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
mkdir -p ~/.config/yaams
|
|
124
|
+
cp "$(brew --prefix)/share/yaams/config.yaml.example" ~/.config/yaams/config.yaml
|
|
125
|
+
$EDITOR ~/.config/yaams/config.yaml
|
|
126
|
+
yaams init-db
|
|
127
|
+
yaams ingest --dry-run
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
If you cloned the repo instead of installing the package, run the
|
|
131
|
+
all-in-one bootstrap script (`scripts/install_phase_a.sh`) - it creates
|
|
132
|
+
`.venv`, runs the config wizard, downloads the spaCy NER model, and runs
|
|
133
|
+
`init-db` + `ingest --dry-run` in sequence.
|
|
134
|
+
|
|
135
|
+
Verify the setup:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
yaams --version # 0.1.1
|
|
139
|
+
yaams stats # zero items - that is expected before first ingest
|
|
140
|
+
yaams ingest --dry-run # see what each adapter would pick up
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Then do a real ingest:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
yaams ingest
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The first run downloads the embedding model (`BAAI/bge-m3`, ~2GB). YAAMS
|
|
150
|
+
will prompt before downloading; after the cache is populated, subsequent
|
|
151
|
+
runs are fully offline.
|
|
152
|
+
|
|
153
|
+
Ask a question:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
yaams query "what did we decide about the deploy in May"
|
|
157
|
+
yaams query --answer "open items from the kickoff meeting"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## CLI
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
yaams <command> [options]
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Bare `yaams` lists commands. Global flags: `--version`, `--help`.
|
|
167
|
+
Per-command help: `yaams <command> --help`.
|
|
168
|
+
|
|
169
|
+
For the full feature walkthrough — every command, the entity-curation
|
|
170
|
+
workflow, query flags, and best practices — see the
|
|
171
|
+
**[User Guide](docs/user-guide.md)**.
|
|
172
|
+
|
|
173
|
+
| command | what it does |
|
|
174
|
+
| --- | --- |
|
|
175
|
+
| `init-db` | create the SQLite schema (idempotent) |
|
|
176
|
+
| `ingest` | run ingest for all enabled sources (or `--source <name>`) |
|
|
177
|
+
| `stats` | print item counts per source, plus last ingest run timing |
|
|
178
|
+
| `query` | full-text + vector search; `--answer` for synthesized response |
|
|
179
|
+
| `feedback` | log relevance signals against a prior query result |
|
|
180
|
+
| `signals` | inspect recent query history |
|
|
181
|
+
| `consolidate` | group conversational items into sessions |
|
|
182
|
+
| `promote` | review and accept atomic-note candidates into the Tier 2 ledger |
|
|
183
|
+
| `reset-db` | drop and recreate the database (asks first) |
|
|
184
|
+
| `version` | print version (`--json` for machine-readable) |
|
|
185
|
+
|
|
186
|
+
### Ingest sources
|
|
187
|
+
|
|
188
|
+
| source | config key | what it ingests |
|
|
189
|
+
| --- | --- | --- |
|
|
190
|
+
| `imessage` | `ingest.imessage` | iMessage conversations from local `chat.db` |
|
|
191
|
+
| `signal` | `ingest.signal` | Signal Desktop messages (1:1 + groups, attachment metadata) |
|
|
192
|
+
| `email` | `ingest.email` | `.emlx` (Apple Mail) or `.mbox` |
|
|
193
|
+
| `notes` | `ingest.notes` | Obsidian vault markdown |
|
|
194
|
+
| `tier2_ledger` | `ingest.tier2_ledger` | curated atomic notes from cognitive-ledger |
|
|
195
|
+
| `github` | `ingest.github` | GitHub issues and PRs across your repos |
|
|
196
|
+
| `calendar` / `calendar_<profile>` | `ingest.calendar` | Outlook calendar via `owa-cal` |
|
|
197
|
+
| `teams` / `teams_<profile>` | `ingest.teams` | Microsoft Teams via Graph API |
|
|
198
|
+
|
|
199
|
+
Run one source: `yaams ingest --source imessage`.
|
|
200
|
+
|
|
201
|
+
### Query
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
yaams query "budget discussion"
|
|
205
|
+
yaams query --top-k 20 "deploy"
|
|
206
|
+
yaams query --no-vector "fast FTS-only path" # skips embedder load
|
|
207
|
+
yaams query --source imessage "holiday plans"
|
|
208
|
+
yaams query --since 2025-06-01 --until 2025-09-01 "summer"
|
|
209
|
+
yaams query --no-consolidations "raw items only"
|
|
210
|
+
yaams query --format json "search term"
|
|
211
|
+
yaams query --answer "what are the open items from the kickoff"
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Promote
|
|
215
|
+
|
|
216
|
+
Surface candidate atomic notes from recent items, review them interactively,
|
|
217
|
+
and write accepted ones into your ledger inbox:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
yaams promote generate # scan last 30 days
|
|
221
|
+
yaams promote generate --days 60
|
|
222
|
+
yaams promote review # interactive: a/e/r/s/q
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Nothing is promoted without your explicit acceptance. Accepted notes land in
|
|
226
|
+
`promote.inbox_path` (default `~/yaams/ledger-inbox/`).
|
|
227
|
+
|
|
228
|
+
## Configure
|
|
229
|
+
|
|
230
|
+
`config.yaml` lives in the repo root (or `~/.config/yaams/config.yaml`, or
|
|
231
|
+
wherever `$YAAMS_CONFIG` points). It is gitignored: it carries your
|
|
232
|
+
personal entity dictionary, source paths, and addresses. Edit
|
|
233
|
+
`config.yaml.example` instead when contributing structural changes.
|
|
234
|
+
|
|
235
|
+
Rerun the wizard at any time:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
python scripts/configure_phase_a.py --config config.yaml
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Key blocks:
|
|
242
|
+
|
|
243
|
+
```yaml
|
|
244
|
+
db_path: ~/yaams/data.db
|
|
245
|
+
|
|
246
|
+
ingest:
|
|
247
|
+
since: '2025-01-01T00:00:00Z'
|
|
248
|
+
imessage:
|
|
249
|
+
chat_db_path: ~/Library/Messages/chat.db
|
|
250
|
+
email:
|
|
251
|
+
sources:
|
|
252
|
+
- type: emlx
|
|
253
|
+
path: ~/Library/Mail/V10
|
|
254
|
+
|
|
255
|
+
embed:
|
|
256
|
+
model: BAAI/bge-m3
|
|
257
|
+
device: mps # or cpu
|
|
258
|
+
|
|
259
|
+
synth:
|
|
260
|
+
backend: claude # claude | codex | ollama | subprocess | dummy
|
|
261
|
+
model: claude-sonnet-4-6
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
On Apple Silicon, use the Homebrew arm64 Python explicitly - PyTorch 2.4+
|
|
265
|
+
has no x86_64 macOS wheels:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
/opt/homebrew/bin/python3.12 -m venv .venv
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Scheduling
|
|
272
|
+
|
|
273
|
+
YAAMS is meant to run unattended. See [docs/scheduling.md](docs/scheduling.md)
|
|
274
|
+
for a `launchd` agent that runs a single nightly `yaams ingest` across all
|
|
275
|
+
enabled sources, plus the macOS Full Disk Access setup required for the
|
|
276
|
+
`imessage` adapter to work under `launchd`.
|
|
277
|
+
|
|
278
|
+
## Privacy and security
|
|
279
|
+
|
|
280
|
+
YAAMS reads and stores sensitive personal data. The defaults keep
|
|
281
|
+
everything local, but **you are responsible for protecting the database
|
|
282
|
+
file at rest** - enable full-disk encryption (FileVault / LUKS / BitLocker)
|
|
283
|
+
on the host machine.
|
|
284
|
+
|
|
285
|
+
See [SECURITY.md](SECURITY.md) for the full threat model, data
|
|
286
|
+
classification, and vulnerability disclosure flow. See
|
|
287
|
+
[docs/privacy-security.md](docs/privacy-security.md) for the operational
|
|
288
|
+
detail on what is written, what is not, and how to scrub.
|
|
289
|
+
|
|
290
|
+
## Documentation
|
|
291
|
+
|
|
292
|
+
- **[User Guide](docs/user-guide.md)** - the end-to-end manual: every
|
|
293
|
+
feature, the entity-curation workflow, query power-flags, best practices,
|
|
294
|
+
and troubleshooting.
|
|
295
|
+
- [Implementation status](docs/implementation-status.md) - architecture and
|
|
296
|
+
what's shipped.
|
|
297
|
+
- [Scheduling](docs/scheduling.md) - unattended nightly ingest via `launchd`.
|
|
298
|
+
- [Privacy and security](docs/privacy-security.md) - what's written, what
|
|
299
|
+
isn't, and how to scrub.
|
|
300
|
+
|
|
301
|
+
## Contributing
|
|
302
|
+
|
|
303
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, the test
|
|
304
|
+
suite, schema-migration rules, and commit conventions.
|
|
305
|
+
|
|
306
|
+
## License
|
|
307
|
+
|
|
308
|
+
[MIT](LICENSE). Copyright 2026 Carl Joakim Damsleth.
|
yaams-0.3.0/README.md
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# YAAMS
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
**Yet Another Agent Memory System.** A local-first, high-recall memory store
|
|
7
|
+
for your personal digital exhaust - messages, email, calendar, GitHub
|
|
8
|
+
activity, notes - searchable in seconds and synthesizable into grounded,
|
|
9
|
+
cited answers by the LLM of your choice.
|
|
10
|
+
|
|
11
|
+
YAAMS is Tier 1 of a two-tier memory architecture: the firehose. Tier 2 is
|
|
12
|
+
the [cognitive-ledger](https://github.com/damsleth/cognitive-ledger): curated
|
|
13
|
+
atomic notes you keep forever. YAAMS ingests everything, lets you query
|
|
14
|
+
across the lot, and promotes the gems upstream when you're ready.
|
|
15
|
+
|
|
16
|
+
Each tier is split between a public **engine** and a private **store**:
|
|
17
|
+
|
|
18
|
+
| Tier | Engine (public) | Store (private, your data) |
|
|
19
|
+
| --- | --- | --- |
|
|
20
|
+
| Tier 1 | **YAAMS** - this repo | a single SQLite file at `db_path` |
|
|
21
|
+
| Tier 2 | **cognitive-ledger** - sibling repo | a markdown tree of curated atomic notes |
|
|
22
|
+
|
|
23
|
+
Engines ship code, no data. Stores live outside the repo, are gitignored
|
|
24
|
+
by default, and never get pushed.
|
|
25
|
+
|
|
26
|
+
## Suite
|
|
27
|
+
|
|
28
|
+
YAAMS is one of four tools in the **[hugr](https://github.com/damsleth/hugr)**
|
|
29
|
+
memory suite. The suite gives you one install (`brew install
|
|
30
|
+
damsleth/tap/hugr`), one verb surface (`hugr query`, `hugr ingest`,
|
|
31
|
+
`hugr promote`, ...), and one CLI contract (output classes, exit
|
|
32
|
+
codes, action envelopes - see
|
|
33
|
+
[hugr/CONVENTIONS.md](https://github.com/damsleth/hugr/blob/main/CONVENTIONS.md)).
|
|
34
|
+
Power users can still call `yaams` directly and get byte-identical
|
|
35
|
+
JSON.
|
|
36
|
+
|
|
37
|
+
## What
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
query
|
|
41
|
+
|
|
|
42
|
+
v
|
|
43
|
+
ingest -> normalize -> embed -> retrieve -> fuse -> answer (cited)
|
|
44
|
+
| | | |
|
|
45
|
+
iMessage SQLite BGE-M3 Tier 2 boost
|
|
46
|
+
Signal + FTS5 + spaCy (cognitive-ledger)
|
|
47
|
+
Email + vec
|
|
48
|
+
Teams
|
|
49
|
+
Calendar
|
|
50
|
+
GitHub
|
|
51
|
+
Obsidian
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- **Local-only by default.** Embeddings, NER, and LLM synthesis run on your
|
|
55
|
+
machine. Nothing leaves the host unless you point an adapter at a hosted
|
|
56
|
+
backend.
|
|
57
|
+
- **Append-only.** Raw items are immutable. Re-ingest is idempotent.
|
|
58
|
+
- **Cited answers.** Every synthesized claim points back to the source items.
|
|
59
|
+
- **Pluggable LLM.** `claude`, `codex`, `ollama`, any subprocess, or `dummy`.
|
|
60
|
+
- **Single SQLite file.** No daemons, no servers, no cloud bill.
|
|
61
|
+
|
|
62
|
+
## Why
|
|
63
|
+
|
|
64
|
+
Language models forget everything between sessions, and the answer is not
|
|
65
|
+
"shove more raw chat logs into the context window." The answer is a memory
|
|
66
|
+
system you can grep, query, and audit, that lives on your machine and that
|
|
67
|
+
you fully control.
|
|
68
|
+
|
|
69
|
+
YAAMS gives you that for the high-volume side of your life: every iMessage,
|
|
70
|
+
every email, every calendar event, every GitHub issue you have touched. It
|
|
71
|
+
normalizes them into a common schema, embeds them, and lets you ask
|
|
72
|
+
questions like *"what did we decide about the deploy in May?"* and get back
|
|
73
|
+
a grounded answer with citations - in seconds, offline.
|
|
74
|
+
|
|
75
|
+
## Quickstart
|
|
76
|
+
|
|
77
|
+
Requires Python 3.11+ and macOS (Linux works for everything except the
|
|
78
|
+
iMessage adapter).
|
|
79
|
+
|
|
80
|
+
Homebrew (recommended):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
brew install damsleth/tap/yaams
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
PyPI via pipx:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pipx install yaams
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Bleeding-edge from main:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
brew install --HEAD damsleth/tap/yaams
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Then bootstrap a config and run the dry-run ingest:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
mkdir -p ~/.config/yaams
|
|
102
|
+
cp "$(brew --prefix)/share/yaams/config.yaml.example" ~/.config/yaams/config.yaml
|
|
103
|
+
$EDITOR ~/.config/yaams/config.yaml
|
|
104
|
+
yaams init-db
|
|
105
|
+
yaams ingest --dry-run
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
If you cloned the repo instead of installing the package, run the
|
|
109
|
+
all-in-one bootstrap script (`scripts/install_phase_a.sh`) - it creates
|
|
110
|
+
`.venv`, runs the config wizard, downloads the spaCy NER model, and runs
|
|
111
|
+
`init-db` + `ingest --dry-run` in sequence.
|
|
112
|
+
|
|
113
|
+
Verify the setup:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
yaams --version # 0.1.1
|
|
117
|
+
yaams stats # zero items - that is expected before first ingest
|
|
118
|
+
yaams ingest --dry-run # see what each adapter would pick up
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Then do a real ingest:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
yaams ingest
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The first run downloads the embedding model (`BAAI/bge-m3`, ~2GB). YAAMS
|
|
128
|
+
will prompt before downloading; after the cache is populated, subsequent
|
|
129
|
+
runs are fully offline.
|
|
130
|
+
|
|
131
|
+
Ask a question:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
yaams query "what did we decide about the deploy in May"
|
|
135
|
+
yaams query --answer "open items from the kickoff meeting"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## CLI
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
yaams <command> [options]
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Bare `yaams` lists commands. Global flags: `--version`, `--help`.
|
|
145
|
+
Per-command help: `yaams <command> --help`.
|
|
146
|
+
|
|
147
|
+
For the full feature walkthrough — every command, the entity-curation
|
|
148
|
+
workflow, query flags, and best practices — see the
|
|
149
|
+
**[User Guide](docs/user-guide.md)**.
|
|
150
|
+
|
|
151
|
+
| command | what it does |
|
|
152
|
+
| --- | --- |
|
|
153
|
+
| `init-db` | create the SQLite schema (idempotent) |
|
|
154
|
+
| `ingest` | run ingest for all enabled sources (or `--source <name>`) |
|
|
155
|
+
| `stats` | print item counts per source, plus last ingest run timing |
|
|
156
|
+
| `query` | full-text + vector search; `--answer` for synthesized response |
|
|
157
|
+
| `feedback` | log relevance signals against a prior query result |
|
|
158
|
+
| `signals` | inspect recent query history |
|
|
159
|
+
| `consolidate` | group conversational items into sessions |
|
|
160
|
+
| `promote` | review and accept atomic-note candidates into the Tier 2 ledger |
|
|
161
|
+
| `reset-db` | drop and recreate the database (asks first) |
|
|
162
|
+
| `version` | print version (`--json` for machine-readable) |
|
|
163
|
+
|
|
164
|
+
### Ingest sources
|
|
165
|
+
|
|
166
|
+
| source | config key | what it ingests |
|
|
167
|
+
| --- | --- | --- |
|
|
168
|
+
| `imessage` | `ingest.imessage` | iMessage conversations from local `chat.db` |
|
|
169
|
+
| `signal` | `ingest.signal` | Signal Desktop messages (1:1 + groups, attachment metadata) |
|
|
170
|
+
| `email` | `ingest.email` | `.emlx` (Apple Mail) or `.mbox` |
|
|
171
|
+
| `notes` | `ingest.notes` | Obsidian vault markdown |
|
|
172
|
+
| `tier2_ledger` | `ingest.tier2_ledger` | curated atomic notes from cognitive-ledger |
|
|
173
|
+
| `github` | `ingest.github` | GitHub issues and PRs across your repos |
|
|
174
|
+
| `calendar` / `calendar_<profile>` | `ingest.calendar` | Outlook calendar via `owa-cal` |
|
|
175
|
+
| `teams` / `teams_<profile>` | `ingest.teams` | Microsoft Teams via Graph API |
|
|
176
|
+
|
|
177
|
+
Run one source: `yaams ingest --source imessage`.
|
|
178
|
+
|
|
179
|
+
### Query
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
yaams query "budget discussion"
|
|
183
|
+
yaams query --top-k 20 "deploy"
|
|
184
|
+
yaams query --no-vector "fast FTS-only path" # skips embedder load
|
|
185
|
+
yaams query --source imessage "holiday plans"
|
|
186
|
+
yaams query --since 2025-06-01 --until 2025-09-01 "summer"
|
|
187
|
+
yaams query --no-consolidations "raw items only"
|
|
188
|
+
yaams query --format json "search term"
|
|
189
|
+
yaams query --answer "what are the open items from the kickoff"
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Promote
|
|
193
|
+
|
|
194
|
+
Surface candidate atomic notes from recent items, review them interactively,
|
|
195
|
+
and write accepted ones into your ledger inbox:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
yaams promote generate # scan last 30 days
|
|
199
|
+
yaams promote generate --days 60
|
|
200
|
+
yaams promote review # interactive: a/e/r/s/q
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Nothing is promoted without your explicit acceptance. Accepted notes land in
|
|
204
|
+
`promote.inbox_path` (default `~/yaams/ledger-inbox/`).
|
|
205
|
+
|
|
206
|
+
## Configure
|
|
207
|
+
|
|
208
|
+
`config.yaml` lives in the repo root (or `~/.config/yaams/config.yaml`, or
|
|
209
|
+
wherever `$YAAMS_CONFIG` points). It is gitignored: it carries your
|
|
210
|
+
personal entity dictionary, source paths, and addresses. Edit
|
|
211
|
+
`config.yaml.example` instead when contributing structural changes.
|
|
212
|
+
|
|
213
|
+
Rerun the wizard at any time:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
python scripts/configure_phase_a.py --config config.yaml
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Key blocks:
|
|
220
|
+
|
|
221
|
+
```yaml
|
|
222
|
+
db_path: ~/yaams/data.db
|
|
223
|
+
|
|
224
|
+
ingest:
|
|
225
|
+
since: '2025-01-01T00:00:00Z'
|
|
226
|
+
imessage:
|
|
227
|
+
chat_db_path: ~/Library/Messages/chat.db
|
|
228
|
+
email:
|
|
229
|
+
sources:
|
|
230
|
+
- type: emlx
|
|
231
|
+
path: ~/Library/Mail/V10
|
|
232
|
+
|
|
233
|
+
embed:
|
|
234
|
+
model: BAAI/bge-m3
|
|
235
|
+
device: mps # or cpu
|
|
236
|
+
|
|
237
|
+
synth:
|
|
238
|
+
backend: claude # claude | codex | ollama | subprocess | dummy
|
|
239
|
+
model: claude-sonnet-4-6
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
On Apple Silicon, use the Homebrew arm64 Python explicitly - PyTorch 2.4+
|
|
243
|
+
has no x86_64 macOS wheels:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
/opt/homebrew/bin/python3.12 -m venv .venv
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Scheduling
|
|
250
|
+
|
|
251
|
+
YAAMS is meant to run unattended. See [docs/scheduling.md](docs/scheduling.md)
|
|
252
|
+
for a `launchd` agent that runs a single nightly `yaams ingest` across all
|
|
253
|
+
enabled sources, plus the macOS Full Disk Access setup required for the
|
|
254
|
+
`imessage` adapter to work under `launchd`.
|
|
255
|
+
|
|
256
|
+
## Privacy and security
|
|
257
|
+
|
|
258
|
+
YAAMS reads and stores sensitive personal data. The defaults keep
|
|
259
|
+
everything local, but **you are responsible for protecting the database
|
|
260
|
+
file at rest** - enable full-disk encryption (FileVault / LUKS / BitLocker)
|
|
261
|
+
on the host machine.
|
|
262
|
+
|
|
263
|
+
See [SECURITY.md](SECURITY.md) for the full threat model, data
|
|
264
|
+
classification, and vulnerability disclosure flow. See
|
|
265
|
+
[docs/privacy-security.md](docs/privacy-security.md) for the operational
|
|
266
|
+
detail on what is written, what is not, and how to scrub.
|
|
267
|
+
|
|
268
|
+
## Documentation
|
|
269
|
+
|
|
270
|
+
- **[User Guide](docs/user-guide.md)** - the end-to-end manual: every
|
|
271
|
+
feature, the entity-curation workflow, query power-flags, best practices,
|
|
272
|
+
and troubleshooting.
|
|
273
|
+
- [Implementation status](docs/implementation-status.md) - architecture and
|
|
274
|
+
what's shipped.
|
|
275
|
+
- [Scheduling](docs/scheduling.md) - unattended nightly ingest via `launchd`.
|
|
276
|
+
- [Privacy and security](docs/privacy-security.md) - what's written, what
|
|
277
|
+
isn't, and how to scrub.
|
|
278
|
+
|
|
279
|
+
## Contributing
|
|
280
|
+
|
|
281
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, the test
|
|
282
|
+
suite, schema-migration rules, and commit conventions.
|
|
283
|
+
|
|
284
|
+
## License
|
|
285
|
+
|
|
286
|
+
[MIT](LICENSE). Copyright 2026 Carl Joakim Damsleth.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "yaams"
|
|
3
|
+
version = "0.3.0"
|
|
4
|
+
description = "Yet Another Agent Memory System"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"click>=8.1",
|
|
9
|
+
"cryptography>=42.0",
|
|
10
|
+
"pyyaml>=6.0",
|
|
11
|
+
"numpy<2",
|
|
12
|
+
"pyobjc-framework-Cocoa>=12.1; sys_platform == 'darwin'",
|
|
13
|
+
"sentence-transformers>=3.0",
|
|
14
|
+
"spacy>=3.7",
|
|
15
|
+
"sqlite-vec>=0.1.6",
|
|
16
|
+
"tqdm>=4.66",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.optional-dependencies]
|
|
20
|
+
dev = [
|
|
21
|
+
"pytest>=8.0",
|
|
22
|
+
"ruff>=0.6",
|
|
23
|
+
"pyright>=1.1.380",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.scripts]
|
|
27
|
+
yaams = "yaams.cli:cli"
|
|
28
|
+
|
|
29
|
+
[tool.setuptools.package-data]
|
|
30
|
+
yaams = ["_default_config.yaml"]
|
|
31
|
+
|
|
32
|
+
[tool.pytest.ini_options]
|
|
33
|
+
testpaths = ["tests"]
|
|
34
|
+
|
|
35
|
+
[tool.ruff]
|
|
36
|
+
line-length = 100
|
|
37
|
+
target-version = "py311"
|
|
38
|
+
indent-width = 2
|
|
39
|
+
extend-exclude = [
|
|
40
|
+
".venv",
|
|
41
|
+
"yaams.egg-info",
|
|
42
|
+
".plans",
|
|
43
|
+
".tmp",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[tool.ruff.lint]
|
|
47
|
+
# Initial rule set. Broaden to B/UP/SIM after a one-time auto-fix sweep.
|
|
48
|
+
select = [
|
|
49
|
+
"E", # pycodestyle errors
|
|
50
|
+
"F", # pyflakes (undefined names, unused imports)
|
|
51
|
+
"I", # isort (import ordering)
|
|
52
|
+
"W", # pycodestyle warnings
|
|
53
|
+
]
|
|
54
|
+
ignore = [
|
|
55
|
+
"E501", # long lines, project uses soft limit
|
|
56
|
+
"E741", # ambiguous variable names (existing usage)
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
[tool.ruff.format]
|
|
60
|
+
quote-style = "double"
|
|
61
|
+
indent-style = "space"
|
|
62
|
+
|
|
63
|
+
[tool.pyright]
|
|
64
|
+
include = ["yaams", "tests"]
|
|
65
|
+
exclude = [".venv", "yaams.egg-info", ".plans", ".tmp"]
|
|
66
|
+
pythonVersion = "3.11"
|
|
67
|
+
typeCheckingMode = "basic"
|
|
68
|
+
reportMissingImports = "warning"
|
|
69
|
+
reportFunctionMemberAccess = "none"
|
|
70
|
+
reportOperatorIssue = "warning"
|
|
71
|
+
reportArgumentType = "warning"
|
|
72
|
+
reportGeneralTypeIssues = "warning"
|
|
73
|
+
|
|
74
|
+
[build-system]
|
|
75
|
+
requires = ["setuptools>=69", "wheel"]
|
|
76
|
+
build-backend = "setuptools.build_meta"
|
yaams-0.3.0/setup.cfg
ADDED