trw-memory 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.
- trw_memory-0.3.0/.env.example +43 -0
- trw_memory-0.3.0/.github/workflows/ci.yml +37 -0
- trw_memory-0.3.0/.github/workflows/release.yml +39 -0
- trw_memory-0.3.0/.gitignore +36 -0
- trw_memory-0.3.0/CHANGELOG.md +124 -0
- trw_memory-0.3.0/CLAUDE.md +42 -0
- trw_memory-0.3.0/LICENSE +41 -0
- trw_memory-0.3.0/PKG-INFO +457 -0
- trw_memory-0.3.0/README.md +391 -0
- trw_memory-0.3.0/benchmarks/__init__.py +1 -0
- trw_memory-0.3.0/benchmarks/__main__.py +6 -0
- trw_memory-0.3.0/benchmarks/bench_latency.py +152 -0
- trw_memory-0.3.0/benchmarks/bench_memory.py +132 -0
- trw_memory-0.3.0/benchmarks/bench_quality.py +253 -0
- trw_memory-0.3.0/benchmarks/bench_throughput.py +134 -0
- trw_memory-0.3.0/benchmarks/corpus.py +424 -0
- trw_memory-0.3.0/benchmarks/fixtures/__init__.py +1 -0
- trw_memory-0.3.0/benchmarks/fixtures/dedup_set.json +544 -0
- trw_memory-0.3.0/benchmarks/fixtures/golden_set.json +1154 -0
- trw_memory-0.3.0/benchmarks/runner.py +467 -0
- trw_memory-0.3.0/pyproject.toml +216 -0
- trw_memory-0.3.0/requirements.lock +92 -0
- trw_memory-0.3.0/src/trw_memory/__init__.py +41 -0
- trw_memory-0.3.0/src/trw_memory/_logging.py +121 -0
- trw_memory-0.3.0/src/trw_memory/_version.py +5 -0
- trw_memory-0.3.0/src/trw_memory/adapters/__init__.py +17 -0
- trw_memory-0.3.0/src/trw_memory/adapters/openai_compat.py +186 -0
- trw_memory-0.3.0/src/trw_memory/cli.py +340 -0
- trw_memory-0.3.0/src/trw_memory/cli_formatters.py +156 -0
- trw_memory-0.3.0/src/trw_memory/cli_parser.py +92 -0
- trw_memory-0.3.0/src/trw_memory/client.py +518 -0
- trw_memory-0.3.0/src/trw_memory/decorators.py +22 -0
- trw_memory-0.3.0/src/trw_memory/embeddings/__init__.py +6 -0
- trw_memory-0.3.0/src/trw_memory/embeddings/interface.py +64 -0
- trw_memory-0.3.0/src/trw_memory/embeddings/local.py +169 -0
- trw_memory-0.3.0/src/trw_memory/exceptions.py +40 -0
- trw_memory-0.3.0/src/trw_memory/graph.py +397 -0
- trw_memory-0.3.0/src/trw_memory/integrations/__init__.py +22 -0
- trw_memory-0.3.0/src/trw_memory/integrations/_backend.py +121 -0
- trw_memory-0.3.0/src/trw_memory/integrations/_mixin.py +32 -0
- trw_memory-0.3.0/src/trw_memory/integrations/crewai.py +168 -0
- trw_memory-0.3.0/src/trw_memory/integrations/factory.py +117 -0
- trw_memory-0.3.0/src/trw_memory/integrations/langchain.py +134 -0
- trw_memory-0.3.0/src/trw_memory/integrations/llamaindex.py +210 -0
- trw_memory-0.3.0/src/trw_memory/integrations/vscode.py +202 -0
- trw_memory-0.3.0/src/trw_memory/lifecycle/__init__.py +48 -0
- trw_memory-0.3.0/src/trw_memory/lifecycle/_utils.py +49 -0
- trw_memory-0.3.0/src/trw_memory/lifecycle/consolidation.py +521 -0
- trw_memory-0.3.0/src/trw_memory/lifecycle/dedup.py +325 -0
- trw_memory-0.3.0/src/trw_memory/lifecycle/scoring.py +568 -0
- trw_memory-0.3.0/src/trw_memory/lifecycle/tiers/__init__.py +19 -0
- trw_memory-0.3.0/src/trw_memory/lifecycle/tiers/_cold.py +195 -0
- trw_memory-0.3.0/src/trw_memory/lifecycle/tiers/_manager.py +226 -0
- trw_memory-0.3.0/src/trw_memory/lifecycle/tiers/_scoring.py +112 -0
- trw_memory-0.3.0/src/trw_memory/lifecycle/tiers/_sweep.py +214 -0
- trw_memory-0.3.0/src/trw_memory/lifecycle/tiers/_warm.py +234 -0
- trw_memory-0.3.0/src/trw_memory/migration/__init__.py +5 -0
- trw_memory-0.3.0/src/trw_memory/migration/from_trw.py +290 -0
- trw_memory-0.3.0/src/trw_memory/models/__init__.py +14 -0
- trw_memory-0.3.0/src/trw_memory/models/config.py +103 -0
- trw_memory-0.3.0/src/trw_memory/models/events.py +35 -0
- trw_memory-0.3.0/src/trw_memory/models/memory.py +89 -0
- trw_memory-0.3.0/src/trw_memory/namespace.py +14 -0
- trw_memory-0.3.0/src/trw_memory/namespaces/__init__.py +18 -0
- trw_memory-0.3.0/src/trw_memory/namespaces/manager.py +71 -0
- trw_memory-0.3.0/src/trw_memory/namespaces/path_mapping.py +35 -0
- trw_memory-0.3.0/src/trw_memory/namespaces/validation.py +45 -0
- trw_memory-0.3.0/src/trw_memory/py.typed +0 -0
- trw_memory-0.3.0/src/trw_memory/retrieval/__init__.py +25 -0
- trw_memory-0.3.0/src/trw_memory/retrieval/bm25.py +128 -0
- trw_memory-0.3.0/src/trw_memory/retrieval/dense.py +134 -0
- trw_memory-0.3.0/src/trw_memory/retrieval/fusion.py +64 -0
- trw_memory-0.3.0/src/trw_memory/retrieval/pipeline.py +125 -0
- trw_memory-0.3.0/src/trw_memory/security/__init__.py +80 -0
- trw_memory-0.3.0/src/trw_memory/security/audit.py +202 -0
- trw_memory-0.3.0/src/trw_memory/security/encryption.py +141 -0
- trw_memory-0.3.0/src/trw_memory/security/keys.py +215 -0
- trw_memory-0.3.0/src/trw_memory/security/pii.py +303 -0
- trw_memory-0.3.0/src/trw_memory/security/poisoning.py +251 -0
- trw_memory-0.3.0/src/trw_memory/security/rbac.py +101 -0
- trw_memory-0.3.0/src/trw_memory/server.py +37 -0
- trw_memory-0.3.0/src/trw_memory/storage/__init__.py +23 -0
- trw_memory-0.3.0/src/trw_memory/storage/_parsing.py +92 -0
- trw_memory-0.3.0/src/trw_memory/storage/_shared.py +112 -0
- trw_memory-0.3.0/src/trw_memory/storage/interface.py +170 -0
- trw_memory-0.3.0/src/trw_memory/storage/persistence.py +219 -0
- trw_memory-0.3.0/src/trw_memory/storage/sqlite_backend.py +814 -0
- trw_memory-0.3.0/src/trw_memory/storage/yaml_backend.py +433 -0
- trw_memory-0.3.0/src/trw_memory/sync/__init__.py +24 -0
- trw_memory-0.3.0/src/trw_memory/sync/conflict.py +122 -0
- trw_memory-0.3.0/src/trw_memory/sync/remote.py +185 -0
- trw_memory-0.3.0/src/trw_memory/sync/retry_queue.py +148 -0
- trw_memory-0.3.0/src/trw_memory/sync/subscriber.py +106 -0
- trw_memory-0.3.0/src/trw_memory/tools/__init__.py +30 -0
- trw_memory-0.3.0/src/trw_memory/tools/_types.py +28 -0
- trw_memory-0.3.0/src/trw_memory/tools/consolidate.py +181 -0
- trw_memory-0.3.0/src/trw_memory/tools/forget.py +146 -0
- trw_memory-0.3.0/src/trw_memory/tools/recall.py +223 -0
- trw_memory-0.3.0/src/trw_memory/tools/search.py +146 -0
- trw_memory-0.3.0/src/trw_memory/tools/status.py +131 -0
- trw_memory-0.3.0/src/trw_memory/tools/store.py +145 -0
- trw_memory-0.3.0/tests/CLAUDE.md +114 -0
- trw_memory-0.3.0/tests/conftest.py +198 -0
- trw_memory-0.3.0/tests/test_audit.py +283 -0
- trw_memory-0.3.0/tests/test_benchmarks.py +617 -0
- trw_memory-0.3.0/tests/test_cli.py +974 -0
- trw_memory-0.3.0/tests/test_cli_formatters.py +216 -0
- trw_memory-0.3.0/tests/test_client.py +388 -0
- trw_memory-0.3.0/tests/test_concurrent.py +273 -0
- trw_memory-0.3.0/tests/test_consolidation.py +647 -0
- trw_memory-0.3.0/tests/test_decorators.py +188 -0
- trw_memory-0.3.0/tests/test_dedup.py +531 -0
- trw_memory-0.3.0/tests/test_dense_edge_cases.py +80 -0
- trw_memory-0.3.0/tests/test_embeddings.py +270 -0
- trw_memory-0.3.0/tests/test_encryption.py +430 -0
- trw_memory-0.3.0/tests/test_graph.py +726 -0
- trw_memory-0.3.0/tests/test_integrations.py +922 -0
- trw_memory-0.3.0/tests/test_keys.py +513 -0
- trw_memory-0.3.0/tests/test_lifecycle_utils.py +159 -0
- trw_memory-0.3.0/tests/test_migration.py +349 -0
- trw_memory-0.3.0/tests/test_models.py +348 -0
- trw_memory-0.3.0/tests/test_namespace.py +81 -0
- trw_memory-0.3.0/tests/test_namespace_migration.py +200 -0
- trw_memory-0.3.0/tests/test_openai_compat.py +158 -0
- trw_memory-0.3.0/tests/test_package.py +112 -0
- trw_memory-0.3.0/tests/test_persistence.py +279 -0
- trw_memory-0.3.0/tests/test_pii.py +393 -0
- trw_memory-0.3.0/tests/test_poisoning.py +331 -0
- trw_memory-0.3.0/tests/test_rbac.py +556 -0
- trw_memory-0.3.0/tests/test_retrieval.py +569 -0
- trw_memory-0.3.0/tests/test_scoring.py +496 -0
- trw_memory-0.3.0/tests/test_security.py +524 -0
- trw_memory-0.3.0/tests/test_server.py +122 -0
- trw_memory-0.3.0/tests/test_storage_sqlite.py +616 -0
- trw_memory-0.3.0/tests/test_storage_yaml.py +339 -0
- trw_memory-0.3.0/tests/test_sync.py +1053 -0
- trw_memory-0.3.0/tests/test_team_memory.py +222 -0
- trw_memory-0.3.0/tests/test_tier_thread_safety.py +144 -0
- trw_memory-0.3.0/tests/test_tiers.py +834 -0
- trw_memory-0.3.0/tests/test_tools.py +222 -0
- trw_memory-0.3.0/tests/test_tools_lifecycle.py +233 -0
- trw_memory-0.3.0/vulture_whitelist.py +22 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# TRW Memory Engine — Environment Variables
|
|
2
|
+
# All settings use MEMORY_ prefix (case-insensitive via pydantic-settings).
|
|
3
|
+
# Copy to .env and uncomment/fill values as needed.
|
|
4
|
+
|
|
5
|
+
# ── API Authentication (optional) ─────────────────────────────────────────
|
|
6
|
+
# Disabled if not set — enables X-API-Key header validation
|
|
7
|
+
# MEMORY_API_KEY=your-api-key-here
|
|
8
|
+
|
|
9
|
+
# ── Field-Level Encryption (optional) ─────────────────────────────────────
|
|
10
|
+
# Disabled if not set — hex-encoded 32-byte key
|
|
11
|
+
# Generate with: python -c "import secrets; print(secrets.token_hex(32))"
|
|
12
|
+
# MEMORY_MASTER_KEY=
|
|
13
|
+
|
|
14
|
+
# ── Storage Backend ────────────────────────────────────────────────────────
|
|
15
|
+
# MEMORY_STORAGE_BACKEND=sqlite # sqlite (default) or yaml
|
|
16
|
+
# MEMORY_STORAGE_PATH=.memory
|
|
17
|
+
# MEMORY_SQLITE_DB_NAME=memory.db
|
|
18
|
+
|
|
19
|
+
# ── Encryption Settings ───────────────────────────────────────────────────
|
|
20
|
+
# MEMORY_ENCRYPTION_ENABLED=false
|
|
21
|
+
# MEMORY_KEY_SOURCE=env # env, keyring, or file
|
|
22
|
+
# MEMORY_KEY_FILE_PATH=~/.trw-memory/master.key
|
|
23
|
+
|
|
24
|
+
# ── Retrieval Tuning ──────────────────────────────────────────────────────
|
|
25
|
+
# MEMORY_BM25_CANDIDATES=50
|
|
26
|
+
# MEMORY_VECTOR_CANDIDATES=50
|
|
27
|
+
# MEMORY_RRF_K=60
|
|
28
|
+
|
|
29
|
+
# ── Deduplication ─────────────────────────────────────────────────────────
|
|
30
|
+
# MEMORY_DEDUP_ENABLED=true
|
|
31
|
+
# MEMORY_DEDUP_SKIP_THRESHOLD=0.95
|
|
32
|
+
# MEMORY_DEDUP_MERGE_THRESHOLD=0.85
|
|
33
|
+
|
|
34
|
+
# ── Tier Lifecycle ────────────────────────────────────────────────────────
|
|
35
|
+
# MEMORY_HOT_MAX_ENTRIES=50
|
|
36
|
+
# MEMORY_HOT_TTL_DAYS=7
|
|
37
|
+
# MEMORY_COLD_THRESHOLD_DAYS=90
|
|
38
|
+
# MEMORY_RETENTION_DAYS=365
|
|
39
|
+
|
|
40
|
+
# ── Scoring Weights (must sum to 1.0) ────────────────────────────────────
|
|
41
|
+
# MEMORY_SCORE_RELEVANCE_WEIGHT=0.4
|
|
42
|
+
# MEMORY_SCORE_RECENCY_WEIGHT=0.3
|
|
43
|
+
# MEMORY_SCORE_IMPORTANCE_WEIGHT=0.3
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ matrix.python-version }}
|
|
20
|
+
- name: Cache pip packages
|
|
21
|
+
uses: actions/cache@v4
|
|
22
|
+
with:
|
|
23
|
+
path: ~/.cache/pip
|
|
24
|
+
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}
|
|
25
|
+
restore-keys: |
|
|
26
|
+
${{ runner.os }}-pip-${{ matrix.python-version }}-
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: |
|
|
29
|
+
python -m pip install --upgrade pip
|
|
30
|
+
pip install -e ".[dev,vectors,bm25,mcp]"
|
|
31
|
+
pip install cryptography keyring sentence-transformers
|
|
32
|
+
- name: Lint
|
|
33
|
+
run: ruff check src/
|
|
34
|
+
- name: Type check
|
|
35
|
+
run: mypy --strict src/trw_memory/
|
|
36
|
+
- name: Test
|
|
37
|
+
run: pytest tests/ -x --timeout=120 -q
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
id-token: write # Required for trusted publishing
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
- name: Install build tools
|
|
19
|
+
run: pip install build
|
|
20
|
+
- name: Build package
|
|
21
|
+
run: python -m build
|
|
22
|
+
- name: Upload artifacts
|
|
23
|
+
uses: actions/upload-artifact@v4
|
|
24
|
+
with:
|
|
25
|
+
name: dist
|
|
26
|
+
path: dist/
|
|
27
|
+
|
|
28
|
+
publish:
|
|
29
|
+
needs: build
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
environment: pypi
|
|
32
|
+
permissions:
|
|
33
|
+
id-token: write
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/download-artifact@v4
|
|
36
|
+
with:
|
|
37
|
+
name: dist
|
|
38
|
+
path: dist/
|
|
39
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
*.egg
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
.eggs/
|
|
9
|
+
|
|
10
|
+
# Virtual environments
|
|
11
|
+
.venv/
|
|
12
|
+
venv/
|
|
13
|
+
|
|
14
|
+
# Testing
|
|
15
|
+
.pytest_cache/
|
|
16
|
+
.hypothesis/
|
|
17
|
+
.coverage
|
|
18
|
+
htmlcov/
|
|
19
|
+
coverage.xml
|
|
20
|
+
.mypy_cache/
|
|
21
|
+
|
|
22
|
+
# IDE
|
|
23
|
+
.vscode/
|
|
24
|
+
.idea/
|
|
25
|
+
|
|
26
|
+
# TRW runtime state
|
|
27
|
+
.trw/
|
|
28
|
+
|
|
29
|
+
# Internal Claude Code settings — not for public consumption
|
|
30
|
+
.claude/
|
|
31
|
+
|
|
32
|
+
# Internal PRD/sprint docs — development artefacts, not part of the public package
|
|
33
|
+
docs/
|
|
34
|
+
|
|
35
|
+
# Scratch workspace
|
|
36
|
+
scratch/
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the TRW Memory package.
|
|
4
|
+
|
|
5
|
+
## [0.3.0] — 2026-03-19
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Structured logging** — new `trw_memory/_logging.py` module with `configure_logging()`, `-v/-q/--log-level` CLI flags, `NullHandler` in `__init__.py` (library best practice), and `exc_info=True` added to exception handlers in `embeddings/local.py` and `migration/from_trw.py`. All 28 source files normalized to `structlog.get_logger(__name__)`. 10 sentence-style log messages converted to snake_case event names.
|
|
10
|
+
- **BSL 1.1 license** — `pyproject.toml` updated from CC BY-NC-SA to `BUSL-1.1` (Change Date 2030-03-21, Change License Apache 2.0) in preparation for open-source publication.
|
|
11
|
+
- **CI hardening** — ruff format checks now blocking in the memory CI workflow; pre-existing ruff lint issues resolved. mypy `--strict` fully clean across all 77 files.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **Version aligned to monorepo v24.4_TRW release** — package version bumped from 0.2.0 to 0.3.0 at the v24.4 framework release (`98608d2a`).
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## [0.2.0] — 2026-03-19
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **Structured logging foundation** — `_logging.py` introduced as part of the monorepo-wide logging overhaul. Library stays silent by default (`NullHandler`); CLI configures logging at startup only.
|
|
24
|
+
- **CLI verbosity flags** — `-v/--verbose`, `-q/--quiet`, `--log-level` added to all CLI subcommands.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- **Logger normalization** — all 28 source files migrated from bare `structlog.get_logger()` to `structlog.get_logger(__name__)` for module-level filtering.
|
|
29
|
+
- **Log event naming** — 10 sentence-style event strings converted to snake_case.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## [0.1.3] — 2026-03-17
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- **WAL mode reliability** — enabled `PRAGMA journal_mode=WAL; PRAGMA synchronous=NORMAL;` on `SQLiteBackend` with a warning log if WAL activation fails. Allows concurrent reads without write serialization.
|
|
38
|
+
- **Decay loop `datetime.now()` per-iteration** — captured once before the loop instead of calling it on every iteration.
|
|
39
|
+
- **`graph.py` thread-safe commits** — `conn.commit()` calls now accept an optional `threading.Lock` parameter; wired in from all callers.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## [0.1.2] — 2026-03-15
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- **mypy `--strict` clean** — resolved all 13 pre-existing type errors: fixed `type: ignore` codes in `sqlite_backend.py`, `local.py`, and `client.py`; widened formatter params to `Sequence[Mapping]` for TypedDict covariance in `cli_formatters.py`; added `_backend_or_raise` property for None safety in `llamaindex.py`. Zero errors across 77 files.
|
|
48
|
+
- **Ruff expanded** — rule set expanded from 14 to 26 categories (matching monorepo standard). 244 violations fixed, 0 remaining.
|
|
49
|
+
- **`delete_by_namespace` cursor fix** — `cursor.rowcount` moved inside the write lock to prevent a race condition with concurrent deletes.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## [0.1.1] — 2026-03-10
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- **Standalone REST API removed** — the orphaned `trw-memory/api/` package (8 files, ~1,428 LOC) and its 5 matching test files were deleted. The API was superseded by the backend package and was unreachable without a running platform instance. The removal cleans up dead code and reduces confusion for consumers.
|
|
58
|
+
- **`_parsing.py` shared helpers** — `storage/_parsing.py` introduced with `parse_dt`, `parse_json_list`, `parse_json_dict_str`, `parse_json_dict_int` to replace duplicated parsing in `sqlite_backend.py` and `yaml_backend.py`. Fixes a subtle UTC normalization bug in `yaml_backend`.
|
|
59
|
+
- **Sprint 39/40 quality review** — CLI import merge check fixed (keyword recall replaced with `backend.get(eid)` for reliable ID-based dedup during `--merge` imports); `BackendOwnerMixin` extracted to eliminate identical `close/__enter__/__exit__` boilerplate across LangChain, CrewAI, and VSCode integration adapters; `corpus.py` docstrings corrected (said "YAML" but writes JSON).
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## [0.1.0] — 2026-02-27
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
|
|
67
|
+
- **Initial release** — `trw-memory` introduced as a standalone persistent memory engine extracted from `trw-mcp`. Shipped as part of the monorepo alongside trw-mcp's knowledge topology and hybrid retrieval work (commit `b28c2490`).
|
|
68
|
+
|
|
69
|
+
#### Storage backends
|
|
70
|
+
|
|
71
|
+
- **SQLite primary backend** — `storage/sqlite_backend.py` with FTS5 full-text search, WAL journal mode, and `check_same_thread=False` for concurrent HTTP client access.
|
|
72
|
+
- **YAML secondary backend** — `storage/yaml_backend.py` for backward compatibility with pre-migration entries.
|
|
73
|
+
|
|
74
|
+
#### Retrieval
|
|
75
|
+
|
|
76
|
+
- **BM25 sparse retrieval** — `retrieval/bm25.py` via `rank-bm25` with hyphenated-tag expansion and zero-IDF fallback.
|
|
77
|
+
- **Dense vector retrieval** — `retrieval/dense.py` via `sqlite-vec` (384-dim all-MiniLM-L6-v2).
|
|
78
|
+
- **Hybrid search with RRF** — `retrieval/hybrid.py` combines BM25 and dense rankings via Reciprocal Rank Fusion (k=60). Gracefully degrades to BM25-only when vectors are unavailable.
|
|
79
|
+
|
|
80
|
+
#### Lifecycle
|
|
81
|
+
|
|
82
|
+
- **Tiered storage** — `lifecycle/tiers.py`: hot tier (in-memory LRU), warm tier (sqlite-vec + JSONL sidecar), cold tier (YAML archive). Four automatic transitions: Hot→Warm (TTL/overflow), Warm→Cold (idle+low-impact), Cold→Warm (on access), Cold→Purge (365d+low-impact). Purge audit trail at `.trw/memory/purge_audit.jsonl`.
|
|
83
|
+
- **Scoring engine** — `lifecycle/scoring.py`: Q-learning with EMA updates, Ebbinghaus forgetting curve, Bayesian MACLA calibration. Stanford Generative Agents importance formula: `w1*relevance + w2*recency + w3*importance`.
|
|
84
|
+
- **LLM consolidation** — `lifecycle/consolidation.py`: embedding-based cluster detection (single-linkage agglomerative, pairwise cosine threshold), LLM-powered summarization via `anthropic` SDK (claude-haiku), original entry archival to cold tier with atomic rollback.
|
|
85
|
+
- **Semantic dedup** — `lifecycle/dedup.py`: three-tier write-time dedup (skip ≥0.95, merge ≥0.85, store <0.85) via cosine similarity. `merge_entries()` with union tags/evidence, max impact, recurrence increment, and `merged_from` audit trail.
|
|
86
|
+
|
|
87
|
+
#### Knowledge graph
|
|
88
|
+
|
|
89
|
+
- **`graph.py`** — similarity, tag co-occurrence, and consolidation edges; BFS traversal; importance boost/decay with outcome history.
|
|
90
|
+
|
|
91
|
+
#### Remote sync
|
|
92
|
+
|
|
93
|
+
- **`sync/remote.py`** — publish/fetch with anonymization and fail-open design.
|
|
94
|
+
- **`sync/conflict.py`** — vector clock comparison, merge, and conflict resolution.
|
|
95
|
+
- **`sync/retry_queue.py`** — thread-safe JSONL queue with 500-entry depth cap.
|
|
96
|
+
- **`sync/subscriber.py`** — SSE real-time stream with automatic reconnection.
|
|
97
|
+
|
|
98
|
+
#### Security
|
|
99
|
+
|
|
100
|
+
- **`security/`** — AES-256-GCM field-level encryption, PII detection and redaction, memory poisoning detection, RBAC, and full audit trail.
|
|
101
|
+
|
|
102
|
+
#### Integrations
|
|
103
|
+
|
|
104
|
+
- **LangChain** — `TRWChatMessageHistory` and `TRWVectorStore` adapters.
|
|
105
|
+
- **LlamaIndex** — reader and writer components.
|
|
106
|
+
- **CrewAI** — `TRWCrewStorage` component.
|
|
107
|
+
- **OpenAI-compatible** — `LocalMemoryAdapter` with 4 function-call operations (store, recall, search, forget).
|
|
108
|
+
|
|
109
|
+
#### CLI
|
|
110
|
+
|
|
111
|
+
- **`trw-memory` CLI** — 8 subcommands (`store`, `recall`, `search`, `forget`, `consolidate`, `export`, `import`, `status`) with JSON, table, and YAML output formats. `cli_parser.py` extracted for line-count compliance.
|
|
112
|
+
|
|
113
|
+
#### MCP tools
|
|
114
|
+
|
|
115
|
+
- **6 MCP tools** (`tools/`) — `store`, `recall`, `search`, `consolidate`, `forget`, `status` for direct integration into Claude Code sessions.
|
|
116
|
+
|
|
117
|
+
#### Client SDK
|
|
118
|
+
|
|
119
|
+
- **`MemoryClient`** (`client.py`) — high-level async Python client with `store()`, `recall()`, `forget()`, and `search()` methods.
|
|
120
|
+
- **TypeScript SDK** — `@trw/memory-sdk` with `MemoryClient` class and full TypeScript types.
|
|
121
|
+
|
|
122
|
+
#### Benchmarks
|
|
123
|
+
|
|
124
|
+
- **`benchmarks/`** — 4 benchmark modules (latency, throughput, memory, quality) with configurable thresholds and `python -m benchmarks` entry point.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# trw-memory
|
|
2
|
+
|
|
3
|
+
Standalone persistent memory engine for AI agents — hybrid retrieval (BM25 + dense vectors), tiered storage (SQLite primary, YAML secondary), semantic dedup, and knowledge-graph traversal. Used by trw-mcp as its memory backend via `memory_adapter.py`.
|
|
4
|
+
|
|
5
|
+
## Build & Test
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cd trw-memory
|
|
9
|
+
.venv/bin/python -m pytest tests/test_specific_file.py -v # Single file (preferred)
|
|
10
|
+
.venv/bin/python -m pytest tests/ -v # Full suite (delivery only)
|
|
11
|
+
.venv/bin/python -m mypy --strict src/trw_memory/ # Type check
|
|
12
|
+
pip install -e ".[dev]" # Dev install
|
|
13
|
+
pip install -e ".[dev,vectors,bm25]" # With optional deps
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Architecture
|
|
17
|
+
|
|
18
|
+
| Module | Purpose |
|
|
19
|
+
|--------|---------|
|
|
20
|
+
| `storage/` | SQLite + YAML dual backends (`sqlite_backend.py`, `yaml_backend.py`) |
|
|
21
|
+
| `retrieval/` | BM25 keyword + dense vector hybrid search |
|
|
22
|
+
| `lifecycle/` | Tier promotion/demotion, utility scoring, dedup, consolidation |
|
|
23
|
+
| `graph.py` | Knowledge graph with BFS traversal |
|
|
24
|
+
| `sync/` | Remote publish/fetch with vector clocks |
|
|
25
|
+
| `security/` | Field-level encryption, PII detection, RBAC |
|
|
26
|
+
| `tools/` | MCP tool wrappers (optional `[mcp]` dep) |
|
|
27
|
+
| `client.py` | Public `MemoryClient` — primary consumer API |
|
|
28
|
+
|
|
29
|
+
## Testing Patterns
|
|
30
|
+
|
|
31
|
+
- **In-memory SQLite**: `SQLiteBackend(":memory:")` — use for unit tests, no `tmp_path` needed
|
|
32
|
+
- **Disk SQLite**: `SQLiteBackend(tmp_path / "test.db")` — use for integration tests
|
|
33
|
+
- **Shared fixtures**: `tests/conftest.py` provides `sqlite_backend`, `sqlite_memory_backend`, `memory_client`, `make_entry()`, `make_entry_dict()`
|
|
34
|
+
- `asyncio_mode = "auto"` — write `async def test_foo():` without `@pytest.mark.asyncio`
|
|
35
|
+
|
|
36
|
+
## Key Gotchas
|
|
37
|
+
|
|
38
|
+
- `sqlite-vec` is an optional dep (`[vectors]`) — skip dense vector tests with `pytest.importorskip("sqlite_vec")`
|
|
39
|
+
- `sentence-transformers` is optional (`[embeddings]`) — embeddings fail gracefully when unavailable
|
|
40
|
+
- Pydantic v2: `use_enum_values=True` required for YAML round-trip; `populate_by_name=True` when using `Field(alias=...)`
|
|
41
|
+
- structlog: never use `event=` as a kwarg — it's reserved; use `action=` or `operation=`
|
|
42
|
+
- Coverage threshold: 85% (fail_under in pyproject.toml)
|
trw_memory-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
Licensor: Tyler Wall
|
|
4
|
+
Licensed Work: TRW Framework
|
|
5
|
+
The Licensed Work is (c) 2026 Tyler Wall.
|
|
6
|
+
|
|
7
|
+
Additional Use Grant:
|
|
8
|
+
You may use the Licensed Work for any purpose other than offering
|
|
9
|
+
a commercial product or service that competes with the Licensed Work.
|
|
10
|
+
|
|
11
|
+
"Compete" means providing a substantially similar product or service
|
|
12
|
+
that replaces or substitutes for the Licensed Work's core functionality:
|
|
13
|
+
persistent memory with scoring and decay, sprint orchestration,
|
|
14
|
+
requirements lifecycle management, phase gates, or agent team
|
|
15
|
+
coordination for AI coding agents.
|
|
16
|
+
|
|
17
|
+
For clarity, the following uses are always permitted:
|
|
18
|
+
- Using TRW in your own software development projects
|
|
19
|
+
- Integrating TRW into your development workflow
|
|
20
|
+
- Building applications, tools, or services that use TRW internally
|
|
21
|
+
- Modifying TRW for your own non-competing use
|
|
22
|
+
- Evaluating, testing, and benchmarking TRW
|
|
23
|
+
|
|
24
|
+
Change Date: 2030-03-21
|
|
25
|
+
|
|
26
|
+
Change License: Apache License, Version 2.0
|
|
27
|
+
|
|
28
|
+
Notice:
|
|
29
|
+
|
|
30
|
+
The Business Source License (this document, or the "License") is not
|
|
31
|
+
an Open Source license. However, the Licensed Work will eventually be
|
|
32
|
+
made available under the Change License, as stated in this License.
|
|
33
|
+
|
|
34
|
+
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights
|
|
35
|
+
Reserved. "Business Source License" is a trademark of MariaDB
|
|
36
|
+
Corporation Ab.
|
|
37
|
+
|
|
38
|
+
For the full BSL 1.1 license text, see:
|
|
39
|
+
https://mariadb.com/bsl11/
|
|
40
|
+
|
|
41
|
+
SPDX-License-Identifier: BUSL-1.1
|