cortex-vault 0.1.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.
Files changed (27) hide show
  1. cortex_vault-0.1.0/PKG-INFO +231 -0
  2. cortex_vault-0.1.0/README.md +203 -0
  3. cortex_vault-0.1.0/pyproject.toml +77 -0
  4. cortex_vault-0.1.0/setup.cfg +4 -0
  5. cortex_vault-0.1.0/setup.py +5 -0
  6. cortex_vault-0.1.0/src/cortex_memory/__init__.py +33 -0
  7. cortex_vault-0.1.0/src/cortex_memory/__main__.py +65 -0
  8. cortex_vault-0.1.0/src/cortex_memory/agent.py +225 -0
  9. cortex_vault-0.1.0/src/cortex_memory/config.py +112 -0
  10. cortex_vault-0.1.0/src/cortex_memory/graph/__init__.py +4 -0
  11. cortex_vault-0.1.0/src/cortex_memory/graph/memory_graph.py +87 -0
  12. cortex_vault-0.1.0/src/cortex_memory/ingestion/__init__.py +14 -0
  13. cortex_vault-0.1.0/src/cortex_memory/ingestion/ingestor.py +226 -0
  14. cortex_vault-0.1.0/src/cortex_memory/llm/__init__.py +4 -0
  15. cortex_vault-0.1.0/src/cortex_memory/llm/chat.py +84 -0
  16. cortex_vault-0.1.0/src/cortex_memory/prompts/__init__.py +4 -0
  17. cortex_vault-0.1.0/src/cortex_memory/prompts/templates.py +59 -0
  18. cortex_vault-0.1.0/src/cortex_memory/retrieval/__init__.py +4 -0
  19. cortex_vault-0.1.0/src/cortex_memory/retrieval/retriever.py +196 -0
  20. cortex_vault-0.1.0/src/cortex_vault.egg-info/PKG-INFO +231 -0
  21. cortex_vault-0.1.0/src/cortex_vault.egg-info/SOURCES.txt +25 -0
  22. cortex_vault-0.1.0/src/cortex_vault.egg-info/dependency_links.txt +1 -0
  23. cortex_vault-0.1.0/src/cortex_vault.egg-info/entry_points.txt +2 -0
  24. cortex_vault-0.1.0/src/cortex_vault.egg-info/requires.txt +11 -0
  25. cortex_vault-0.1.0/src/cortex_vault.egg-info/top_level.txt +1 -0
  26. cortex_vault-0.1.0/tests/test_ingestor.py +82 -0
  27. cortex_vault-0.1.0/tests/test_retriever.py +107 -0
@@ -0,0 +1,231 @@
1
+ Metadata-Version: 2.4
2
+ Name: cortex-vault
3
+ Version: 0.1.0
4
+ Summary: LLM-powered long-term memory layer backed by a Neo4j knowledge graph.
5
+ Author: tdevansh
6
+ License: MIT
7
+ Project-URL: Repository, https://github.com/tdevansh/cortex-vault
8
+ Keywords: llm,memory,neo4j,langchain,knowledge-graph,retrieval-augmented-generation,agent
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: langchain-groq>=0.2
19
+ Requires-Dist: langchain>=0.3
20
+ Requires-Dist: sentence-transformers>=3.0
21
+ Requires-Dist: neo4j>=5.0
22
+ Requires-Dist: python-dotenv>=1.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=8.0; extra == "dev"
25
+ Requires-Dist: pytest-mock>=3.14; extra == "dev"
26
+ Requires-Dist: ruff>=0.4; extra == "dev"
27
+ Requires-Dist: mypy>=1.10; extra == "dev"
28
+
29
+ # cortex-memory
30
+
31
+ > An LLM-powered long-term memory layer backed by a **Neo4j knowledge graph** — packaged as a reusable Python library you can drop into any project.
32
+
33
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
34
+
35
+ ---
36
+
37
+ ## What it does
38
+
39
+ 1. **Chat** — queries the LLM with retrieved memory context injected automatically.
40
+ 2. **Retrieve** — embeds your query with `all-MiniLM-L6-v2`, runs a Neo4j vector-index search, then re-ranks with:
41
+ - `importance_weight` (very_high → low)
42
+ - `stability_weight` (permanent → transient)
43
+ - `tag_matches` between the query and stored memory tags
44
+ 3. **Ingest** — asks the LLM to decide if an input is worth storing. If so, it extracts `type`, `label`, `content`, `stability`, `importance`, and `related_entities`, chunks the text, embeds each chunk, and upserts it into Neo4j as a `Memory` node linked to `Entity` nodes via `RELATED_TO`.
45
+ 4. **Reinforce** — memories recalled during chat have their `last_accessed` refreshed; `transient` memories are promoted to `stable`.
46
+
47
+ ---
48
+
49
+ ## Project structure
50
+
51
+ ```
52
+ cortex-ai-memory/
53
+ ├── src/
54
+ │ └── cortex_memory/ ← installable package
55
+ │ ├── __init__.py ← public API
56
+ │ ├── __main__.py ← CLI entrypoint
57
+ │ ├── agent.py ← CortexMemory orchestrator
58
+ │ ├── config.py ← CortexConfig dataclass
59
+ │ ├── graph/
60
+ │ │ └── memory_graph.py ← Neo4j upsert (MemoryGraph)
61
+ │ ├── retrieval/
62
+ │ │ └── retriever.py ← WeightedMemoryRetriever
63
+ │ ├── ingestion/
64
+ │ │ └── ingestor.py ← ingestion pipeline
65
+ │ ├── llm/
66
+ │ │ └── chat.py ← LLM client + chat_with_assistant
67
+ │ └── prompts/
68
+ │ └── templates.py ← all prompt strings
69
+ ├── examples/
70
+ │ ├── basic_chat.py
71
+ │ └── ingest_document.py
72
+ ├── tests/
73
+ │ ├── test_retriever.py
74
+ │ └── test_ingestor.py
75
+ ├── setups/
76
+ │ └── neo4j/ ← Docker / docker-compose setup
77
+ ├── pyproject.toml
78
+ ├── requirements-dev.txt
79
+ └── .env.example
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Prerequisites
85
+
86
+ - Python 3.10+
87
+ - Docker (for Neo4j 5.13+)
88
+ - A [Groq API key](https://console.groq.com/keys)
89
+
90
+ ---
91
+
92
+ ## Installation
93
+
94
+ ### As a dependency in another project
95
+
96
+ ```bash
97
+ pip install git+https://github.com/your-org/cortex-ai-memory.git
98
+ ```
99
+
100
+ ### For local development
101
+
102
+ ```bash
103
+ git clone https://github.com/your-org/cortex-ai-memory.git
104
+ cd cortex-ai-memory
105
+ pip install -e ".[dev]"
106
+ ```
107
+
108
+ ---
109
+
110
+ ## Configuration
111
+
112
+ Copy `.env.example` to `.env` and fill in your values:
113
+
114
+ ```env
115
+ NEO4J_URI=bolt://localhost:7687
116
+ NEO4J_USERNAME=neo4j
117
+ NEO4J_PASSWORD=your_neo4j_password_here
118
+ GROQ_API_KEY=your_groq_api_key_here
119
+
120
+ # Optional overrides
121
+ # CORTEX_MODEL=openai/gpt-oss-20b
122
+ # CORTEX_EMBEDDER=all-MiniLM-L6-v2
123
+ # CORTEX_TOP_K=5
124
+ # CORTEX_SCORE_THRESHOLD=0.65
125
+ # CORTEX_CHUNK_MAX_CHARS=400
126
+ ```
127
+
128
+ ---
129
+
130
+ ## Usage
131
+
132
+ ### Python API
133
+
134
+ ```python
135
+ from cortex_memory import CortexMemory
136
+
137
+ # Context manager — closes Neo4j connections automatically
138
+ with CortexMemory.from_env() as memory:
139
+ # Retrieve + chat + ingest + reinforce — all in one call
140
+ response = memory.chat("What do I know about Japan?")
141
+ print(response)
142
+
143
+ # Ingest standalone text
144
+ memory.ingest("User booked flights to Tokyo for March.", source="upload")
145
+
146
+ # Raw retrieval without chat
147
+ results = memory.retrieve("Japan travel plans", top_k=5)
148
+ ```
149
+
150
+ ### CLI
151
+
152
+ ```bash
153
+ # Chat
154
+ cortex-memory chat "What do I know about Japan?"
155
+
156
+ # Ingest
157
+ cortex-memory ingest "User loves hiking in the Alps and dislikes crowded cities."
158
+
159
+ # Override top-k and disable auto-ingestion
160
+ cortex-memory chat "Remind me about my diet goals." --top-k 3 --no-ingest
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Running Neo4j with Docker
166
+
167
+ ```bash
168
+ docker run -d \
169
+ --name memory-graph-neo4j \
170
+ -p 7474:7474 \
171
+ -p 7687:7687 \
172
+ -e NEO4J_AUTH=neo4j/your_neo4j_password_here \
173
+ -v neo4j_data:/data \
174
+ neo4j:5.15
175
+ ```
176
+
177
+ Or using **docker-compose** (see `setups/neo4j/`):
178
+
179
+ ```bash
180
+ docker-compose -f setups/neo4j/docker-compose.yml up -d
181
+ ```
182
+
183
+ Verify at **http://localhost:7474**.
184
+
185
+ ---
186
+
187
+ ## Running tests
188
+
189
+ ```bash
190
+ pytest tests/
191
+ ```
192
+
193
+ ---
194
+
195
+ ## Memory schema
196
+
197
+ | Field | Description |
198
+ |---|---|
199
+ | `id` | UUID |
200
+ | `type` | `context`, `event`, `fact`, … |
201
+ | `label` | Short title |
202
+ | `content` | Chunked text |
203
+ | `source` | `upload`, `assistant_chat`, `cli`, … |
204
+ | `created_at` / `last_accessed` | ISO timestamps |
205
+ | `stability` | `transient` → `stable` → `permanent` |
206
+ | `status` | `active` |
207
+ | `tags` | Keyword list |
208
+ | `embedding` | 384-dim vector (`all-MiniLM-L6-v2`) |
209
+ | `importance` | `very_high`, `high`, `medium`, `low` |
210
+
211
+ Related entities are linked as `(:Memory)-[:RELATED_TO]->(:Entity)`.
212
+
213
+ ---
214
+
215
+ ## Using in another project
216
+
217
+ ```python
218
+ # my_project/memory_layer.py
219
+ from cortex_memory import CortexMemory, CortexConfig
220
+
221
+ # Explicit config — no .env needed
222
+ config = CortexConfig(
223
+ neo4j_uri="bolt://localhost:7687",
224
+ neo4j_username="neo4j",
225
+ neo4j_password="secret",
226
+ groq_api_key="gsk_...",
227
+ top_k=10,
228
+ score_threshold=0.70,
229
+ )
230
+ memory = CortexMemory(config)
231
+ ```
@@ -0,0 +1,203 @@
1
+ # cortex-memory
2
+
3
+ > An LLM-powered long-term memory layer backed by a **Neo4j knowledge graph** — packaged as a reusable Python library you can drop into any project.
4
+
5
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
6
+
7
+ ---
8
+
9
+ ## What it does
10
+
11
+ 1. **Chat** — queries the LLM with retrieved memory context injected automatically.
12
+ 2. **Retrieve** — embeds your query with `all-MiniLM-L6-v2`, runs a Neo4j vector-index search, then re-ranks with:
13
+ - `importance_weight` (very_high → low)
14
+ - `stability_weight` (permanent → transient)
15
+ - `tag_matches` between the query and stored memory tags
16
+ 3. **Ingest** — asks the LLM to decide if an input is worth storing. If so, it extracts `type`, `label`, `content`, `stability`, `importance`, and `related_entities`, chunks the text, embeds each chunk, and upserts it into Neo4j as a `Memory` node linked to `Entity` nodes via `RELATED_TO`.
17
+ 4. **Reinforce** — memories recalled during chat have their `last_accessed` refreshed; `transient` memories are promoted to `stable`.
18
+
19
+ ---
20
+
21
+ ## Project structure
22
+
23
+ ```
24
+ cortex-ai-memory/
25
+ ├── src/
26
+ │ └── cortex_memory/ ← installable package
27
+ │ ├── __init__.py ← public API
28
+ │ ├── __main__.py ← CLI entrypoint
29
+ │ ├── agent.py ← CortexMemory orchestrator
30
+ │ ├── config.py ← CortexConfig dataclass
31
+ │ ├── graph/
32
+ │ │ └── memory_graph.py ← Neo4j upsert (MemoryGraph)
33
+ │ ├── retrieval/
34
+ │ │ └── retriever.py ← WeightedMemoryRetriever
35
+ │ ├── ingestion/
36
+ │ │ └── ingestor.py ← ingestion pipeline
37
+ │ ├── llm/
38
+ │ │ └── chat.py ← LLM client + chat_with_assistant
39
+ │ └── prompts/
40
+ │ └── templates.py ← all prompt strings
41
+ ├── examples/
42
+ │ ├── basic_chat.py
43
+ │ └── ingest_document.py
44
+ ├── tests/
45
+ │ ├── test_retriever.py
46
+ │ └── test_ingestor.py
47
+ ├── setups/
48
+ │ └── neo4j/ ← Docker / docker-compose setup
49
+ ├── pyproject.toml
50
+ ├── requirements-dev.txt
51
+ └── .env.example
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Prerequisites
57
+
58
+ - Python 3.10+
59
+ - Docker (for Neo4j 5.13+)
60
+ - A [Groq API key](https://console.groq.com/keys)
61
+
62
+ ---
63
+
64
+ ## Installation
65
+
66
+ ### As a dependency in another project
67
+
68
+ ```bash
69
+ pip install git+https://github.com/your-org/cortex-ai-memory.git
70
+ ```
71
+
72
+ ### For local development
73
+
74
+ ```bash
75
+ git clone https://github.com/your-org/cortex-ai-memory.git
76
+ cd cortex-ai-memory
77
+ pip install -e ".[dev]"
78
+ ```
79
+
80
+ ---
81
+
82
+ ## Configuration
83
+
84
+ Copy `.env.example` to `.env` and fill in your values:
85
+
86
+ ```env
87
+ NEO4J_URI=bolt://localhost:7687
88
+ NEO4J_USERNAME=neo4j
89
+ NEO4J_PASSWORD=your_neo4j_password_here
90
+ GROQ_API_KEY=your_groq_api_key_here
91
+
92
+ # Optional overrides
93
+ # CORTEX_MODEL=openai/gpt-oss-20b
94
+ # CORTEX_EMBEDDER=all-MiniLM-L6-v2
95
+ # CORTEX_TOP_K=5
96
+ # CORTEX_SCORE_THRESHOLD=0.65
97
+ # CORTEX_CHUNK_MAX_CHARS=400
98
+ ```
99
+
100
+ ---
101
+
102
+ ## Usage
103
+
104
+ ### Python API
105
+
106
+ ```python
107
+ from cortex_memory import CortexMemory
108
+
109
+ # Context manager — closes Neo4j connections automatically
110
+ with CortexMemory.from_env() as memory:
111
+ # Retrieve + chat + ingest + reinforce — all in one call
112
+ response = memory.chat("What do I know about Japan?")
113
+ print(response)
114
+
115
+ # Ingest standalone text
116
+ memory.ingest("User booked flights to Tokyo for March.", source="upload")
117
+
118
+ # Raw retrieval without chat
119
+ results = memory.retrieve("Japan travel plans", top_k=5)
120
+ ```
121
+
122
+ ### CLI
123
+
124
+ ```bash
125
+ # Chat
126
+ cortex-memory chat "What do I know about Japan?"
127
+
128
+ # Ingest
129
+ cortex-memory ingest "User loves hiking in the Alps and dislikes crowded cities."
130
+
131
+ # Override top-k and disable auto-ingestion
132
+ cortex-memory chat "Remind me about my diet goals." --top-k 3 --no-ingest
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Running Neo4j with Docker
138
+
139
+ ```bash
140
+ docker run -d \
141
+ --name memory-graph-neo4j \
142
+ -p 7474:7474 \
143
+ -p 7687:7687 \
144
+ -e NEO4J_AUTH=neo4j/your_neo4j_password_here \
145
+ -v neo4j_data:/data \
146
+ neo4j:5.15
147
+ ```
148
+
149
+ Or using **docker-compose** (see `setups/neo4j/`):
150
+
151
+ ```bash
152
+ docker-compose -f setups/neo4j/docker-compose.yml up -d
153
+ ```
154
+
155
+ Verify at **http://localhost:7474**.
156
+
157
+ ---
158
+
159
+ ## Running tests
160
+
161
+ ```bash
162
+ pytest tests/
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Memory schema
168
+
169
+ | Field | Description |
170
+ |---|---|
171
+ | `id` | UUID |
172
+ | `type` | `context`, `event`, `fact`, … |
173
+ | `label` | Short title |
174
+ | `content` | Chunked text |
175
+ | `source` | `upload`, `assistant_chat`, `cli`, … |
176
+ | `created_at` / `last_accessed` | ISO timestamps |
177
+ | `stability` | `transient` → `stable` → `permanent` |
178
+ | `status` | `active` |
179
+ | `tags` | Keyword list |
180
+ | `embedding` | 384-dim vector (`all-MiniLM-L6-v2`) |
181
+ | `importance` | `very_high`, `high`, `medium`, `low` |
182
+
183
+ Related entities are linked as `(:Memory)-[:RELATED_TO]->(:Entity)`.
184
+
185
+ ---
186
+
187
+ ## Using in another project
188
+
189
+ ```python
190
+ # my_project/memory_layer.py
191
+ from cortex_memory import CortexMemory, CortexConfig
192
+
193
+ # Explicit config — no .env needed
194
+ config = CortexConfig(
195
+ neo4j_uri="bolt://localhost:7687",
196
+ neo4j_username="neo4j",
197
+ neo4j_password="secret",
198
+ groq_api_key="gsk_...",
199
+ top_k=10,
200
+ score_threshold=0.70,
201
+ )
202
+ memory = CortexMemory(config)
203
+ ```
@@ -0,0 +1,77 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "cortex-vault"
7
+ version = "0.1.0"
8
+ description = "LLM-powered long-term memory layer backed by a Neo4j knowledge graph."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "tdevansh" }]
13
+
14
+ keywords = [
15
+ "llm", "memory", "neo4j", "langchain", "knowledge-graph",
16
+ "retrieval-augmented-generation", "agent",
17
+ ]
18
+
19
+ classifiers = [
20
+ "Development Status :: 3 - Alpha",
21
+ "Intended Audience :: Developers",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
27
+ ]
28
+
29
+ dependencies = [
30
+ "langchain-groq>=0.2",
31
+ "langchain>=0.3",
32
+ "sentence-transformers>=3.0",
33
+ "neo4j>=5.0",
34
+ "python-dotenv>=1.0",
35
+ ]
36
+
37
+ [project.optional-dependencies]
38
+ dev = [
39
+ "pytest>=8.0",
40
+ "pytest-mock>=3.14",
41
+ "ruff>=0.4",
42
+ "mypy>=1.10",
43
+ ]
44
+
45
+ [project.scripts]
46
+ cortex-vault = "cortex_memory.__main__:main"
47
+
48
+ [project.urls]
49
+ Repository = "https://github.com/tdevansh/cortex-vault"
50
+
51
+ [tool.setuptools.packages.find]
52
+ where = ["src"]
53
+
54
+ # ---------------------------------------------------------------------------
55
+ # Ruff (linting + formatting)
56
+ # ---------------------------------------------------------------------------
57
+ [tool.ruff]
58
+ line-length = 100
59
+ target-version = "py310"
60
+
61
+ [tool.ruff.lint]
62
+ select = ["E", "F", "I", "UP", "B"]
63
+ ignore = ["E501"]
64
+
65
+ # ---------------------------------------------------------------------------
66
+ # Mypy (type-checking)
67
+ # ---------------------------------------------------------------------------
68
+ [tool.mypy]
69
+ python_version = "3.10"
70
+ warn_return_any = true
71
+ ignore_missing_imports = true
72
+
73
+ # ---------------------------------------------------------------------------
74
+ # Pytest
75
+ # ---------------------------------------------------------------------------
76
+ [tool.pytest.ini_options]
77
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ # setup.py — shim for editable installs on pip < 21.3
2
+ # This file is intentionally minimal. All real config lives in pyproject.toml.
3
+ from setuptools import setup
4
+
5
+ setup()
@@ -0,0 +1,33 @@
1
+ """
2
+ cortex_memory
3
+ ~~~~~~~~~~~~~
4
+ An LLM-powered memory layer backed by a Neo4j knowledge graph.
5
+
6
+ Public API::
7
+
8
+ from cortex_memory import CortexMemory, CortexConfig
9
+
10
+ # Quickstart — reads NEO4J_* and GROQ_API_KEY from .env
11
+ memory = CortexMemory.from_env()
12
+ response = memory.chat("What do I know about Japan?")
13
+ memory.ingest("User is planning a trip to Kyoto in October.")
14
+ memory.close()
15
+
16
+ Low-level access::
17
+
18
+ from cortex_memory import WeightedMemoryRetriever, ingest_text_to_memory_graph
19
+ """
20
+
21
+ from cortex_memory.agent import CortexMemory
22
+ from cortex_memory.config import CortexConfig
23
+ from cortex_memory.ingestion.ingestor import ingest_text_to_memory_graph
24
+ from cortex_memory.retrieval.retriever import WeightedMemoryRetriever
25
+
26
+ __all__ = [
27
+ "CortexMemory",
28
+ "CortexConfig",
29
+ "ingest_text_to_memory_graph",
30
+ "WeightedMemoryRetriever",
31
+ ]
32
+
33
+ __version__ = "0.1.0"
@@ -0,0 +1,65 @@
1
+ """
2
+ cortex_memory.__main__
3
+ ~~~~~~~~~~~~~~~~~~~~~~~
4
+ CLI entrypoint — invoked via ``python -m cortex_memory`` or the
5
+ ``cortex-memory`` script installed by pyproject.toml.
6
+
7
+ Usage
8
+ -----
9
+ cortex-memory chat "What do I know about Japan?"
10
+ cortex-memory ingest "User loves hiking in the Alps."
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import argparse
16
+ import sys
17
+
18
+ from cortex_memory import CortexMemory
19
+
20
+
21
+ def main() -> None:
22
+ parser = argparse.ArgumentParser(
23
+ prog="cortex-vault",
24
+ description="Cortex Vault CLI — interact with your Neo4j memory graph.",
25
+ )
26
+ sub = parser.add_subparsers(dest="command", required=True)
27
+
28
+ # --- chat ---
29
+ chat_parser = sub.add_parser("chat", help="Query the memory agent.")
30
+ chat_parser.add_argument("query", help="The query to send to the assistant.")
31
+ chat_parser.add_argument(
32
+ "--top-k", type=int, default=None, help="Number of memories to retrieve."
33
+ )
34
+ chat_parser.add_argument(
35
+ "--no-ingest", action="store_true", help="Disable auto-ingestion of the query."
36
+ )
37
+
38
+ # --- ingest ---
39
+ ingest_parser = sub.add_parser("ingest", help="Ingest text into memory.")
40
+ ingest_parser.add_argument("text", help="Text to evaluate and store.")
41
+ ingest_parser.add_argument(
42
+ "--source", default="cli", help="Source tag for the memory (default: 'cli')."
43
+ )
44
+
45
+ args = parser.parse_args()
46
+
47
+ with CortexMemory.from_env() as memory:
48
+ if args.command == "chat":
49
+ response = memory.chat(
50
+ args.query,
51
+ top_k=args.top_k,
52
+ auto_ingest=not args.no_ingest,
53
+ )
54
+ print(f"\n🤖 Assistant:\n{response}\n")
55
+
56
+ elif args.command == "ingest":
57
+ ingested = memory.ingest(args.text, source=args.source)
58
+ if ingested:
59
+ print("✅ Memory ingested successfully.")
60
+ else:
61
+ print("❌ No ingestion was performed.")
62
+
63
+
64
+ if __name__ == "__main__":
65
+ main()