cortex-mem 1.0.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.
- cortex_mem-1.0.0/LICENSE +21 -0
- cortex_mem-1.0.0/MANIFEST.in +9 -0
- cortex_mem-1.0.0/PKG-INFO +153 -0
- cortex_mem-1.0.0/README.md +118 -0
- cortex_mem-1.0.0/cortex/__init__.py +0 -0
- cortex_mem-1.0.0/cortex/db.py +135 -0
- cortex_mem-1.0.0/cortex/schema.sql +75 -0
- cortex_mem-1.0.0/cortex/tier_generator.py +280 -0
- cortex_mem-1.0.0/cortex/tiered_retrieval.py +335 -0
- cortex_mem-1.0.0/cortex_mem/__init__.py +5 -0
- cortex_mem-1.0.0/cortex_mem/__version__.py +1 -0
- cortex_mem-1.0.0/cortex_mem/cli.py +170 -0
- cortex_mem-1.0.0/cortex_mem/openclaw_plugin.py +73 -0
- cortex_mem-1.0.0/cortex_mem/openclaw_provider.py +68 -0
- cortex_mem-1.0.0/cortex_mem.egg-info/PKG-INFO +153 -0
- cortex_mem-1.0.0/cortex_mem.egg-info/SOURCES.txt +29 -0
- cortex_mem-1.0.0/cortex_mem.egg-info/dependency_links.txt +1 -0
- cortex_mem-1.0.0/cortex_mem.egg-info/entry_points.txt +5 -0
- cortex_mem-1.0.0/cortex_mem.egg-info/requires.txt +13 -0
- cortex_mem-1.0.0/cortex_mem.egg-info/top_level.txt +3 -0
- cortex_mem-1.0.0/pyproject.toml +56 -0
- cortex_mem-1.0.0/requirements.txt +5 -0
- cortex_mem-1.0.0/schemas/jsonl_schemas.yaml +81 -0
- cortex_mem-1.0.0/service/__init__.py +0 -0
- cortex_mem-1.0.0/service/api.py +311 -0
- cortex_mem-1.0.0/service/client.py +105 -0
- cortex_mem-1.0.0/service/config.yaml +36 -0
- cortex_mem-1.0.0/service/models.py +69 -0
- cortex_mem-1.0.0/service/storage.py +336 -0
- cortex_mem-1.0.0/setup.cfg +4 -0
- cortex_mem-1.0.0/setup.py +5 -0
cortex_mem-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dhawalc
|
|
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.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cortex-mem
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Always-On Memory Service with Progressive Disclosure (L0/L1/L2) and Weighted Retrieval
|
|
5
|
+
Author-email: dhawalc <dhawal@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dhawalc/cortex-mem
|
|
8
|
+
Project-URL: Repository, https://github.com/dhawalc/cortex-mem
|
|
9
|
+
Project-URL: Issues, https://github.com/dhawalc/cortex-mem/issues
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Framework :: FastAPI
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: fastapi>=0.104.0
|
|
23
|
+
Requires-Dist: uvicorn[standard]>=0.24.0
|
|
24
|
+
Requires-Dist: httpx>=0.25.0
|
|
25
|
+
Requires-Dist: chromadb>=0.4.0
|
|
26
|
+
Requires-Dist: aiosqlite>=0.19.0
|
|
27
|
+
Requires-Dist: pyyaml>=6.0
|
|
28
|
+
Requires-Dist: pydantic>=2.0.0
|
|
29
|
+
Requires-Dist: click>=8.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
33
|
+
Requires-Dist: ruff; extra == "dev"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# cortex-mem
|
|
37
|
+
|
|
38
|
+
Always-On Memory Service with Progressive Disclosure (L0/L1/L2) and Weighted Retrieval.
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install cortex-mem
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or from source:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
git clone https://github.com/dhawalc/cortex-mem.git
|
|
50
|
+
cd cortex-mem
|
|
51
|
+
pip install -e .
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Quick Start (30 seconds)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Start service
|
|
58
|
+
cortex-mem start --daemon
|
|
59
|
+
|
|
60
|
+
# Check status
|
|
61
|
+
cortex-mem status
|
|
62
|
+
|
|
63
|
+
# Search memory
|
|
64
|
+
cortex-mem search "deployment"
|
|
65
|
+
|
|
66
|
+
# Stop service
|
|
67
|
+
cortex-mem stop
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## OpenClaw Integration
|
|
71
|
+
|
|
72
|
+
cortex-mem auto-configures OpenClaw on install. No manual setup needed.
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
from cortex_mem.openclaw_provider import CortexMemProvider
|
|
76
|
+
|
|
77
|
+
async with CortexMemProvider() as mem:
|
|
78
|
+
await mem.log("achievement", "Task completed", "Successfully shipped v1")
|
|
79
|
+
results = await mem.search("deployment strategies")
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Features
|
|
83
|
+
|
|
84
|
+
- **Weighted Memory** — Important memories surface automatically via reinforcement learning
|
|
85
|
+
- **Progressive Disclosure** — 98% token reduction with L0/L1/L2 tiered retrieval
|
|
86
|
+
- **4-Tier Architecture** — Episodic, Semantic, Procedural, and Working memory
|
|
87
|
+
- **Cortex Engine** — Smart query with auto-escalation across disclosure levels
|
|
88
|
+
- **HTTP API** — Simple REST endpoints for any language / agent framework
|
|
89
|
+
|
|
90
|
+
## API
|
|
91
|
+
|
|
92
|
+
| Endpoint | Method | Description |
|
|
93
|
+
|----------|--------|-------------|
|
|
94
|
+
| `/memory/{tier}` | POST | Write a memory entry |
|
|
95
|
+
| `/memory/search` | POST | Keyword search with weighted scoring |
|
|
96
|
+
| `/memory/browse/{path}` | GET | Browse module tree |
|
|
97
|
+
| `/memory/weight` | POST | Adjust entry weight (reinforcement) |
|
|
98
|
+
| `/cortex/query` | POST | Smart query with L0/L1/L2 escalation |
|
|
99
|
+
| `/cortex/documents` | GET | List indexed documents |
|
|
100
|
+
| `/health` | GET | Service health check |
|
|
101
|
+
|
|
102
|
+
## CLI
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
cortex-mem start [--port 9100] [--daemon] Start service
|
|
106
|
+
cortex-mem stop Stop service
|
|
107
|
+
cortex-mem status Health check
|
|
108
|
+
cortex-mem search QUERY [--limit 5] Search memory
|
|
109
|
+
cortex-mem migrate SOURCE Import workspace data
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Architecture
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
cortex-mem/
|
|
116
|
+
├── cortex_mem/ # Python package + CLI
|
|
117
|
+
│ ├── cli.py # Click CLI entry point
|
|
118
|
+
│ ├── openclaw_plugin.py
|
|
119
|
+
│ └── openclaw_provider.py
|
|
120
|
+
├── service/ # FastAPI application
|
|
121
|
+
│ ├── api.py # Endpoints
|
|
122
|
+
│ ├── storage.py # JSONL engine + weighted scoring
|
|
123
|
+
│ ├── models.py # Pydantic schemas
|
|
124
|
+
│ └── client.py # Async HTTP client
|
|
125
|
+
├── cortex/ # Progressive disclosure engine
|
|
126
|
+
│ ├── tiered_retrieval.py # L0/L1/L2 query
|
|
127
|
+
│ ├── tier_generator.py # Document ingestion
|
|
128
|
+
│ └── db.py # SQLite metadata
|
|
129
|
+
├── modules/ # Module tree (JSONL data)
|
|
130
|
+
│ ├── memory/
|
|
131
|
+
│ │ ├── episodic/ # experiences, decisions, failures
|
|
132
|
+
│ │ ├── semantic/ # facts, relations
|
|
133
|
+
│ │ └── procedural/ # skills, patterns
|
|
134
|
+
│ ├── identity/ # Persona, values
|
|
135
|
+
│ ├── operations/ # Workflows
|
|
136
|
+
│ └── research/ # Papers, notes
|
|
137
|
+
├── schemas/ # JSONL schema definitions
|
|
138
|
+
├── setup.py
|
|
139
|
+
├── pyproject.toml
|
|
140
|
+
├── Dockerfile
|
|
141
|
+
└── run.py # Direct entry point
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Docker
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
docker build -t cortex-mem .
|
|
148
|
+
docker run -p 9100:9100 cortex-mem
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# cortex-mem
|
|
2
|
+
|
|
3
|
+
Always-On Memory Service with Progressive Disclosure (L0/L1/L2) and Weighted Retrieval.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install cortex-mem
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or from source:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
git clone https://github.com/dhawalc/cortex-mem.git
|
|
15
|
+
cd cortex-mem
|
|
16
|
+
pip install -e .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start (30 seconds)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Start service
|
|
23
|
+
cortex-mem start --daemon
|
|
24
|
+
|
|
25
|
+
# Check status
|
|
26
|
+
cortex-mem status
|
|
27
|
+
|
|
28
|
+
# Search memory
|
|
29
|
+
cortex-mem search "deployment"
|
|
30
|
+
|
|
31
|
+
# Stop service
|
|
32
|
+
cortex-mem stop
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## OpenClaw Integration
|
|
36
|
+
|
|
37
|
+
cortex-mem auto-configures OpenClaw on install. No manual setup needed.
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from cortex_mem.openclaw_provider import CortexMemProvider
|
|
41
|
+
|
|
42
|
+
async with CortexMemProvider() as mem:
|
|
43
|
+
await mem.log("achievement", "Task completed", "Successfully shipped v1")
|
|
44
|
+
results = await mem.search("deployment strategies")
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Features
|
|
48
|
+
|
|
49
|
+
- **Weighted Memory** — Important memories surface automatically via reinforcement learning
|
|
50
|
+
- **Progressive Disclosure** — 98% token reduction with L0/L1/L2 tiered retrieval
|
|
51
|
+
- **4-Tier Architecture** — Episodic, Semantic, Procedural, and Working memory
|
|
52
|
+
- **Cortex Engine** — Smart query with auto-escalation across disclosure levels
|
|
53
|
+
- **HTTP API** — Simple REST endpoints for any language / agent framework
|
|
54
|
+
|
|
55
|
+
## API
|
|
56
|
+
|
|
57
|
+
| Endpoint | Method | Description |
|
|
58
|
+
|----------|--------|-------------|
|
|
59
|
+
| `/memory/{tier}` | POST | Write a memory entry |
|
|
60
|
+
| `/memory/search` | POST | Keyword search with weighted scoring |
|
|
61
|
+
| `/memory/browse/{path}` | GET | Browse module tree |
|
|
62
|
+
| `/memory/weight` | POST | Adjust entry weight (reinforcement) |
|
|
63
|
+
| `/cortex/query` | POST | Smart query with L0/L1/L2 escalation |
|
|
64
|
+
| `/cortex/documents` | GET | List indexed documents |
|
|
65
|
+
| `/health` | GET | Service health check |
|
|
66
|
+
|
|
67
|
+
## CLI
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
cortex-mem start [--port 9100] [--daemon] Start service
|
|
71
|
+
cortex-mem stop Stop service
|
|
72
|
+
cortex-mem status Health check
|
|
73
|
+
cortex-mem search QUERY [--limit 5] Search memory
|
|
74
|
+
cortex-mem migrate SOURCE Import workspace data
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Architecture
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
cortex-mem/
|
|
81
|
+
├── cortex_mem/ # Python package + CLI
|
|
82
|
+
│ ├── cli.py # Click CLI entry point
|
|
83
|
+
│ ├── openclaw_plugin.py
|
|
84
|
+
│ └── openclaw_provider.py
|
|
85
|
+
├── service/ # FastAPI application
|
|
86
|
+
│ ├── api.py # Endpoints
|
|
87
|
+
│ ├── storage.py # JSONL engine + weighted scoring
|
|
88
|
+
│ ├── models.py # Pydantic schemas
|
|
89
|
+
│ └── client.py # Async HTTP client
|
|
90
|
+
├── cortex/ # Progressive disclosure engine
|
|
91
|
+
│ ├── tiered_retrieval.py # L0/L1/L2 query
|
|
92
|
+
│ ├── tier_generator.py # Document ingestion
|
|
93
|
+
│ └── db.py # SQLite metadata
|
|
94
|
+
├── modules/ # Module tree (JSONL data)
|
|
95
|
+
│ ├── memory/
|
|
96
|
+
│ │ ├── episodic/ # experiences, decisions, failures
|
|
97
|
+
│ │ ├── semantic/ # facts, relations
|
|
98
|
+
│ │ └── procedural/ # skills, patterns
|
|
99
|
+
│ ├── identity/ # Persona, values
|
|
100
|
+
│ ├── operations/ # Workflows
|
|
101
|
+
│ └── research/ # Papers, notes
|
|
102
|
+
├── schemas/ # JSONL schema definitions
|
|
103
|
+
├── setup.py
|
|
104
|
+
├── pyproject.toml
|
|
105
|
+
├── Dockerfile
|
|
106
|
+
└── run.py # Direct entry point
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Docker
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
docker build -t cortex-mem .
|
|
113
|
+
docker run -p 9100:9100 cortex-mem
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
|
|
118
|
+
MIT
|
|
File without changes
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SQLite metadata store for Cortex tiered documents.
|
|
3
|
+
Thread-safe, async-compatible via aiosqlite.
|
|
4
|
+
"""
|
|
5
|
+
import json
|
|
6
|
+
import sqlite3
|
|
7
|
+
import uuid
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
10
|
+
|
|
11
|
+
DB_PATH = Path(__file__).parent.parent / "index" / "cortex_tiers.db"
|
|
12
|
+
SCHEMA_PATH = Path(__file__).parent / "schema.sql"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _get_conn(db_path: Path = DB_PATH) -> sqlite3.Connection:
|
|
16
|
+
db_path.parent.mkdir(parents=True, exist_ok=True)
|
|
17
|
+
conn = sqlite3.connect(str(db_path))
|
|
18
|
+
conn.row_factory = sqlite3.Row
|
|
19
|
+
conn.execute("PRAGMA journal_mode=WAL")
|
|
20
|
+
conn.execute("PRAGMA foreign_keys=ON")
|
|
21
|
+
return conn
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def init_db(db_path: Path = DB_PATH) -> sqlite3.Connection:
|
|
25
|
+
conn = _get_conn(db_path)
|
|
26
|
+
with open(SCHEMA_PATH) as f:
|
|
27
|
+
conn.executescript(f.read())
|
|
28
|
+
conn.commit()
|
|
29
|
+
return conn
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def insert_document(conn: sqlite3.Connection, doc: Dict[str, Any]) -> str:
|
|
33
|
+
doc_id = doc.get("doc_id") or str(uuid.uuid4())
|
|
34
|
+
tags = json.dumps(doc.get("tags", []))
|
|
35
|
+
conn.execute(
|
|
36
|
+
"""
|
|
37
|
+
INSERT OR REPLACE INTO documents (
|
|
38
|
+
doc_id, hierarchy_path, title, doc_type,
|
|
39
|
+
l0_abstract, l0_token_count,
|
|
40
|
+
l1_overview, l1_token_count,
|
|
41
|
+
l2_file_path, l2_token_count, l2_checksum,
|
|
42
|
+
chromadb_l0_id, chromadb_l1_id,
|
|
43
|
+
parent_path, depth, tags,
|
|
44
|
+
l0_generated_at, l1_generated_at,
|
|
45
|
+
source_type, cortex_tier
|
|
46
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
47
|
+
""",
|
|
48
|
+
(
|
|
49
|
+
doc_id,
|
|
50
|
+
doc["hierarchy_path"],
|
|
51
|
+
doc["title"],
|
|
52
|
+
doc["doc_type"],
|
|
53
|
+
doc["l0_abstract"],
|
|
54
|
+
doc["l0_token_count"],
|
|
55
|
+
doc.get("l1_overview"),
|
|
56
|
+
doc.get("l1_token_count", 0),
|
|
57
|
+
doc["l2_file_path"],
|
|
58
|
+
doc.get("l2_token_count", 0),
|
|
59
|
+
doc["l2_checksum"],
|
|
60
|
+
doc.get("chromadb_l0_id"),
|
|
61
|
+
doc.get("chromadb_l1_id"),
|
|
62
|
+
doc.get("parent_path"),
|
|
63
|
+
doc.get("depth", 0),
|
|
64
|
+
tags,
|
|
65
|
+
doc.get("l0_generated_at"),
|
|
66
|
+
doc.get("l1_generated_at"),
|
|
67
|
+
doc.get("source_type", "manual"),
|
|
68
|
+
doc.get("cortex_tier"),
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
conn.commit()
|
|
72
|
+
return doc_id
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def get_document(conn: sqlite3.Connection, doc_id: str) -> Optional[Dict[str, Any]]:
|
|
76
|
+
row = conn.execute("SELECT * FROM documents WHERE doc_id = ?", (doc_id,)).fetchone()
|
|
77
|
+
if row is None:
|
|
78
|
+
return None
|
|
79
|
+
return _row_to_dict(row)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def get_all_documents(conn: sqlite3.Connection) -> List[Dict[str, Any]]:
|
|
83
|
+
rows = conn.execute("SELECT * FROM documents ORDER BY updated_at DESC").fetchall()
|
|
84
|
+
return [_row_to_dict(r) for r in rows]
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def search_by_hierarchy(
|
|
88
|
+
conn: sqlite3.Connection, prefix: str
|
|
89
|
+
) -> List[Dict[str, Any]]:
|
|
90
|
+
rows = conn.execute(
|
|
91
|
+
"SELECT * FROM documents WHERE hierarchy_path LIKE ? ORDER BY hierarchy_path",
|
|
92
|
+
(prefix + "%",),
|
|
93
|
+
).fetchall()
|
|
94
|
+
return [_row_to_dict(r) for r in rows]
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def mark_stale(conn: sqlite3.Connection, doc_id: str, reason: str):
|
|
98
|
+
conn.execute(
|
|
99
|
+
"UPDATE documents SET is_stale = 1, stale_reason = ? WHERE doc_id = ?",
|
|
100
|
+
(reason, doc_id),
|
|
101
|
+
)
|
|
102
|
+
conn.commit()
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def log_query(
|
|
106
|
+
conn: sqlite3.Connection,
|
|
107
|
+
query_text: str,
|
|
108
|
+
l0_results: int,
|
|
109
|
+
l1_expansions: int,
|
|
110
|
+
l2_loads: int,
|
|
111
|
+
total_tokens: int,
|
|
112
|
+
latency_ms: int,
|
|
113
|
+
agent_id: Optional[str] = None,
|
|
114
|
+
):
|
|
115
|
+
conn.execute(
|
|
116
|
+
"""
|
|
117
|
+
INSERT INTO query_log (query_id, query_text, agent_id,
|
|
118
|
+
l0_results, l1_expansions, l2_loads, total_tokens, latency_ms)
|
|
119
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
120
|
+
""",
|
|
121
|
+
(str(uuid.uuid4()), query_text, agent_id,
|
|
122
|
+
l0_results, l1_expansions, l2_loads, total_tokens, latency_ms),
|
|
123
|
+
)
|
|
124
|
+
conn.commit()
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _row_to_dict(row: sqlite3.Row) -> Dict[str, Any]:
|
|
128
|
+
d = dict(row)
|
|
129
|
+
if isinstance(d.get("tags"), str):
|
|
130
|
+
try:
|
|
131
|
+
d["tags"] = json.loads(d["tags"])
|
|
132
|
+
except (json.JSONDecodeError, TypeError):
|
|
133
|
+
d["tags"] = []
|
|
134
|
+
d["is_stale"] = bool(d.get("is_stale"))
|
|
135
|
+
return d
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
-- Cortex Tiered Retrieval — SQLite schema
|
|
2
|
+
-- Equivalent to cortex_tiers PostgreSQL schema from master plan.
|
|
3
|
+
-- Stores document metadata + L0/L1 content; L2 lives on filesystem.
|
|
4
|
+
|
|
5
|
+
CREATE TABLE IF NOT EXISTS documents (
|
|
6
|
+
doc_id TEXT PRIMARY KEY,
|
|
7
|
+
hierarchy_path TEXT NOT NULL,
|
|
8
|
+
title TEXT NOT NULL,
|
|
9
|
+
doc_type TEXT NOT NULL CHECK (doc_type IN (
|
|
10
|
+
'strategy', 'backtest', 'research', 'episode',
|
|
11
|
+
'skill', 'pattern', 'session_learning', 'reference'
|
|
12
|
+
)),
|
|
13
|
+
|
|
14
|
+
-- Tier content
|
|
15
|
+
l0_abstract TEXT NOT NULL,
|
|
16
|
+
l0_token_count INTEGER NOT NULL,
|
|
17
|
+
l1_overview TEXT,
|
|
18
|
+
l1_token_count INTEGER DEFAULT 0,
|
|
19
|
+
l2_file_path TEXT NOT NULL,
|
|
20
|
+
l2_token_count INTEGER DEFAULT 0,
|
|
21
|
+
l2_checksum TEXT NOT NULL,
|
|
22
|
+
|
|
23
|
+
-- ChromaDB references
|
|
24
|
+
chromadb_l0_id TEXT,
|
|
25
|
+
chromadb_l1_id TEXT,
|
|
26
|
+
|
|
27
|
+
-- Hierarchy
|
|
28
|
+
parent_path TEXT,
|
|
29
|
+
depth INTEGER DEFAULT 0,
|
|
30
|
+
tags TEXT DEFAULT '[]',
|
|
31
|
+
|
|
32
|
+
-- Timestamps
|
|
33
|
+
created_at TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
34
|
+
updated_at TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
35
|
+
l0_generated_at TEXT,
|
|
36
|
+
l1_generated_at TEXT,
|
|
37
|
+
|
|
38
|
+
-- Invalidation
|
|
39
|
+
is_stale INTEGER DEFAULT 0,
|
|
40
|
+
stale_reason TEXT,
|
|
41
|
+
|
|
42
|
+
-- Source tracking
|
|
43
|
+
source_type TEXT DEFAULT 'manual',
|
|
44
|
+
cortex_tier TEXT CHECK (cortex_tier IN ('episodic', 'semantic', 'procedural') OR cortex_tier IS NULL)
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
CREATE INDEX IF NOT EXISTS idx_docs_hierarchy ON documents (hierarchy_path);
|
|
48
|
+
CREATE INDEX IF NOT EXISTS idx_docs_parent ON documents (parent_path);
|
|
49
|
+
CREATE INDEX IF NOT EXISTS idx_docs_type ON documents (doc_type);
|
|
50
|
+
CREATE INDEX IF NOT EXISTS idx_docs_stale ON documents (is_stale) WHERE is_stale = 1;
|
|
51
|
+
|
|
52
|
+
CREATE TABLE IF NOT EXISTS directories (
|
|
53
|
+
dir_id TEXT PRIMARY KEY,
|
|
54
|
+
path TEXT UNIQUE NOT NULL,
|
|
55
|
+
parent_path TEXT,
|
|
56
|
+
name TEXT NOT NULL,
|
|
57
|
+
description TEXT,
|
|
58
|
+
doc_count INTEGER DEFAULT 0,
|
|
59
|
+
created_at TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
60
|
+
updated_at TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
CREATE INDEX IF NOT EXISTS idx_dirs_parent ON directories (parent_path);
|
|
64
|
+
|
|
65
|
+
CREATE TABLE IF NOT EXISTS query_log (
|
|
66
|
+
query_id TEXT PRIMARY KEY,
|
|
67
|
+
query_text TEXT NOT NULL,
|
|
68
|
+
agent_id TEXT,
|
|
69
|
+
l0_results INTEGER DEFAULT 0,
|
|
70
|
+
l1_expansions INTEGER DEFAULT 0,
|
|
71
|
+
l2_loads INTEGER DEFAULT 0,
|
|
72
|
+
total_tokens INTEGER DEFAULT 0,
|
|
73
|
+
latency_ms INTEGER DEFAULT 0,
|
|
74
|
+
created_at TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
|
75
|
+
);
|