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.
@@ -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,9 @@
1
+ include LICENSE
2
+ include README.md
3
+ include requirements.txt
4
+ include service/config.yaml
5
+ include cortex/schema.sql
6
+ recursive-include schemas *.yaml
7
+ recursive-exclude index *
8
+ recursive-exclude snapshots *
9
+ recursive-exclude __pycache__ *
@@ -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
+ );