composite-memory-mcp-server 0.11.0b1__py3-none-any.whl
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.
- composite_memory_mcp_server-0.11.0b1.dist-info/METADATA +804 -0
- composite_memory_mcp_server-0.11.0b1.dist-info/RECORD +81 -0
- composite_memory_mcp_server-0.11.0b1.dist-info/WHEEL +5 -0
- composite_memory_mcp_server-0.11.0b1.dist-info/entry_points.txt +2 -0
- composite_memory_mcp_server-0.11.0b1.dist-info/licenses/AUTHORS.md +11 -0
- composite_memory_mcp_server-0.11.0b1.dist-info/licenses/LICENSE +21 -0
- composite_memory_mcp_server-0.11.0b1.dist-info/top_level.txt +2 -0
- memory_server/__init__.py +8 -0
- memory_server/admission.py +282 -0
- memory_server/api/__init__.py +1 -0
- memory_server/api/bulk_import.py +81 -0
- memory_server/api/get_context.py +58 -0
- memory_server/api/learn.py +48 -0
- memory_server/api/reflect.py +620 -0
- memory_server/api/remember.py +59 -0
- memory_server/api/search.py +42 -0
- memory_server/benchmarks/__init__.py +35 -0
- memory_server/benchmarks/longmemeval.py +500 -0
- memory_server/cli.py +374 -0
- memory_server/evaluation/__init__.py +21 -0
- memory_server/evaluation/auditor.py +520 -0
- memory_server/evaluation/confidence.py +228 -0
- memory_server/evaluation/decay.py +317 -0
- memory_server/evaluation/metrics.py +168 -0
- memory_server/evaluation/relation.py +595 -0
- memory_server/evaluation/validator.py +352 -0
- memory_server/extractors/__init__.py +1 -0
- memory_server/extractors/belief_extractor.py +100 -0
- memory_server/extractors/decision_extractor.py +89 -0
- memory_server/extractors/fact_extractor.py +82 -0
- memory_server/extractors/skill_extractor.py +117 -0
- memory_server/models/__init__.py +24 -0
- memory_server/models/belief.py +31 -0
- memory_server/models/decision.py +33 -0
- memory_server/models/entity.py +32 -0
- memory_server/models/evidence.py +22 -0
- memory_server/models/fact.py +32 -0
- memory_server/models/receipt.py +88 -0
- memory_server/models/skill.py +35 -0
- memory_server/plugins/__init__.py +1 -0
- memory_server/plugins/hermes/__init__.py +40 -0
- memory_server/plugins/hermes/config.py +105 -0
- memory_server/plugins/hermes/provider.py +1582 -0
- memory_server/plugins/hermes/writer.py +161 -0
- memory_server/providers/__init__.py +19 -0
- memory_server/providers/embedding_provider.py +229 -0
- memory_server/providers/graph_provider.py +361 -0
- memory_server/providers/lancedb_provider.py +476 -0
- memory_server/providers/qdrant_provider.py +355 -0
- memory_server/providers/sqlite_provider.py +526 -0
- memory_server/router/__init__.py +1 -0
- memory_server/router/embedding_router.py +140 -0
- memory_server/router/graph_router.py +246 -0
- memory_server/router/hybrid_router.py +267 -0
- memory_server/router/ranking.py +243 -0
- memory_server/router/rules.py +142 -0
- memory_server/server.py +1127 -0
- memory_server/services/__init__.py +1 -0
- memory_server/services/ingestion_service.py +530 -0
- storage/__init__.py +1 -0
- storage/adapters/__init__.py +9 -0
- storage/adapters/legacy_provider.py +206 -0
- storage/base.py +18 -0
- storage/models/__init__.py +27 -0
- storage/models/belief.py +114 -0
- storage/models/decision.py +69 -0
- storage/models/entity.py +66 -0
- storage/models/fact.py +62 -0
- storage/models/lifecycle.py +41 -0
- storage/models/receipt.py +62 -0
- storage/models/skill.py +75 -0
- storage/outbox.py +294 -0
- storage/outbox_worker.py +313 -0
- storage/repositories/__init__.py +19 -0
- storage/repositories/belief_repo.py +212 -0
- storage/repositories/decision_repo.py +55 -0
- storage/repositories/evidence_repo.py +133 -0
- storage/repositories/fact_repo.py +153 -0
- storage/repositories/lifecycle_repo.py +100 -0
- storage/repositories/receipt_repo.py +42 -0
- storage/repositories/skill_repo.py +43 -0
|
@@ -0,0 +1,804 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: composite-memory-mcp-server
|
|
3
|
+
Version: 0.11.0b1
|
|
4
|
+
Summary: Independent MCP memory service for AI agents
|
|
5
|
+
Author: Shtorm
|
|
6
|
+
Author-email: FedosIS <fedosis@gmail.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/fedosis/Composite-memory-MCP-server
|
|
9
|
+
Project-URL: Repository, https://github.com/fedosis/Composite-memory-MCP-server
|
|
10
|
+
Project-URL: Documentation, https://github.com/fedosis/Composite-memory-MCP-server/blob/main/README.md
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
License-File: AUTHORS.md
|
|
23
|
+
Requires-Dist: mcp>=1.0.0
|
|
24
|
+
Requires-Dist: pydantic>=2.0.0
|
|
25
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
26
|
+
Requires-Dist: sqlalchemy>=2.0.0
|
|
27
|
+
Requires-Dist: aiosqlite>=0.20.0
|
|
28
|
+
Requires-Dist: typer>=0.12.0
|
|
29
|
+
Requires-Dist: prometheus-client>=0.19.0
|
|
30
|
+
Requires-Dist: opentelemetry-api>=1.22.0
|
|
31
|
+
Provides-Extra: qdrant
|
|
32
|
+
Requires-Dist: qdrant-client>=1.0.0; extra == "qdrant"
|
|
33
|
+
Provides-Extra: lancedb
|
|
34
|
+
Requires-Dist: lancedb>=0.12.0; extra == "lancedb"
|
|
35
|
+
Requires-Dist: pyarrow>=14.0.0; extra == "lancedb"
|
|
36
|
+
Provides-Extra: graph
|
|
37
|
+
Requires-Dist: neo4j>=5.0.0; extra == "graph"
|
|
38
|
+
Provides-Extra: git
|
|
39
|
+
Requires-Dist: gitpython>=3.0.0; extra == "git"
|
|
40
|
+
Provides-Extra: hermes
|
|
41
|
+
Requires-Dist: ruamel.yaml>=0.18.0; extra == "hermes"
|
|
42
|
+
Provides-Extra: sentence
|
|
43
|
+
Requires-Dist: sentence-transformers>=3.0.0; extra == "sentence"
|
|
44
|
+
Provides-Extra: openai
|
|
45
|
+
Requires-Dist: openai>=1.0.0; extra == "openai"
|
|
46
|
+
Provides-Extra: dev
|
|
47
|
+
Requires-Dist: composite-memory-mcp-server[hermes,lancedb,qdrant,sentence]; extra == "dev"
|
|
48
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
49
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == "dev"
|
|
50
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
51
|
+
Requires-Dist: ruff>=0.6.0; extra == "dev"
|
|
52
|
+
Dynamic: license-file
|
|
53
|
+
|
|
54
|
+
# Composite Memory MCP Server (CMMS)
|
|
55
|
+
|
|
56
|
+
Composite Memory MCP Server (CMMS) is a beta local-first memory service for AI
|
|
57
|
+
agents. It exposes an MCP stdio server plus an optional Hermes native
|
|
58
|
+
MemoryProvider integration, with structured storage for facts, beliefs,
|
|
59
|
+
provenance receipts, audit data, optional vector retrieval, and graph lookup.
|
|
60
|
+
|
|
61
|
+
CMMS is meant for agents that need more than a generic vector-only memory layer:
|
|
62
|
+
explicit facts remain queryable in SQLite, receipts preserve provenance, vector
|
|
63
|
+
and graph retrieval are separate optional layers, and v0.11 adds deterministic
|
|
64
|
+
memory admission plus LongMemEval-S benchmark tooling.
|
|
65
|
+
|
|
66
|
+
[](docs/INTEGRATION.md)
|
|
67
|
+
[]()
|
|
68
|
+
[]()
|
|
69
|
+
|
|
70
|
+
## Publication status and channel order
|
|
71
|
+
|
|
72
|
+
Current public source of truth: the GitHub repository and the GitHub prerelease
|
|
73
|
+
tag `v0.11.0b1`.
|
|
74
|
+
|
|
75
|
+
Publication boundary for `v0.11.0b1`:
|
|
76
|
+
|
|
77
|
+
1. **GitHub** — published source and prerelease artifacts.
|
|
78
|
+
2. **PyPI** — not published yet; add package-manager install instructions only
|
|
79
|
+
after verifying package publication.
|
|
80
|
+
3. **Official MCP Registry** — not published; `server.json` is conservative
|
|
81
|
+
metadata for future submission, not a registry listing.
|
|
82
|
+
4. **Smithery / Glama** — not published; `docs/DIRECTORY_SUBMISSIONS.md` is
|
|
83
|
+
draft copy only.
|
|
84
|
+
5. **Hermes community** — optional integration documentation only; not a
|
|
85
|
+
distribution channel for this release.
|
|
86
|
+
|
|
87
|
+
## First-run install
|
|
88
|
+
|
|
89
|
+
### Prerequisites
|
|
90
|
+
|
|
91
|
+
- **Python 3.11+**
|
|
92
|
+
- **SQLite** (bundled with Python)
|
|
93
|
+
- Optional: LanceDB/Qdrant extras for vector search; graph lookup uses the current SimpleGraph layer
|
|
94
|
+
|
|
95
|
+
### Install
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Clone the repository
|
|
99
|
+
git clone https://github.com/fedosis/Composite-memory-MCP-server.git
|
|
100
|
+
cd Composite-memory-MCP-server
|
|
101
|
+
|
|
102
|
+
# Create and activate a virtual environment
|
|
103
|
+
python3.11 -m venv .venv
|
|
104
|
+
source .venv/bin/activate
|
|
105
|
+
|
|
106
|
+
# Install base package exactly as a clean user would
|
|
107
|
+
pip install .
|
|
108
|
+
|
|
109
|
+
# Or install with all extras (recommended for development/full functionality)
|
|
110
|
+
pip install -e ".[dev]"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Run the server
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Start the MCP server (stdio transport)
|
|
117
|
+
memory-server serve
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Use the tools
|
|
121
|
+
|
|
122
|
+
The server exposes MCP tools over stdio. For a local MCP client, point the
|
|
123
|
+
server command at the virtualenv executable:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"mcpServers": {
|
|
128
|
+
"memory-server": {
|
|
129
|
+
"command": "/absolute/path/to/memory-server/.venv/bin/memory-server",
|
|
130
|
+
"args": ["serve"]
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
For a quick local smoke check, run `memory-server --help`. To exercise the MCP
|
|
137
|
+
tools, connect through an MCP-compatible client and call the `ping` tool.
|
|
138
|
+
|
|
139
|
+
### What you can do
|
|
140
|
+
|
|
141
|
+
| Tool | Purpose |
|
|
142
|
+
|------|---------|
|
|
143
|
+
| `ping` | Health check / connectivity test |
|
|
144
|
+
| `remember` | Store a fact with provenance |
|
|
145
|
+
| `search` | Keyword search over stored facts |
|
|
146
|
+
| `semantic_search` | Vector similarity search (LanceDB default; Qdrant optional) |
|
|
147
|
+
| `get_context` | Retrieve context for a task |
|
|
148
|
+
| `learn` | Extract knowledge from natural language |
|
|
149
|
+
| `graph_search` | Entity lookup + pathfinding through the current SimpleGraph layer |
|
|
150
|
+
| `route` | 4-stage hybrid router |
|
|
151
|
+
| `audit` | Memory health report |
|
|
152
|
+
| `metrics` | Prometheus metrics |
|
|
153
|
+
| `set_belief` / `get_belief` | Belief store management |
|
|
154
|
+
| `resolve_conflict` | Resolve belief conflicts |
|
|
155
|
+
| `reflect` | 6-mode belief store analysis |
|
|
156
|
+
|
|
157
|
+
### Run tests and lint
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
pytest tests/ -q
|
|
161
|
+
ruff check src/
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Hermes Integration
|
|
167
|
+
|
|
168
|
+
CMMS can optionally run as a native Hermes MemoryProvider plugin via the
|
|
169
|
+
`[hermes]` extra. Hermes is not a base runtime dependency of the MCP stdio
|
|
170
|
+
server. The implemented integration enables Hermes lifecycle hooks such as
|
|
171
|
+
auto-recall, auto-retain, and session-boundary flushing. It is a separate
|
|
172
|
+
in-process Hermes path, not a remote MCP transport.
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
pip install -e ".[hermes]"
|
|
176
|
+
memory-server install-hermes-plugin --hermes-home ~/.hermes/profiles/coder
|
|
177
|
+
hermes gateway restart
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
See [Hermes Integration Guide](docs/INTEGRATION.md) for supported Hermes setup
|
|
181
|
+
and v0.19 compatibility notes.
|
|
182
|
+
|
|
183
|
+
## Dev Setup
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# Clone and enter
|
|
187
|
+
git clone https://github.com/fedosis/Composite-memory-MCP-server.git
|
|
188
|
+
cd Composite-memory-MCP-server
|
|
189
|
+
|
|
190
|
+
# Create venv and install
|
|
191
|
+
python -m venv .venv
|
|
192
|
+
source .venv/bin/activate
|
|
193
|
+
pip install -e ".[dev]"
|
|
194
|
+
|
|
195
|
+
# Run tests
|
|
196
|
+
pytest tests/ -x -q
|
|
197
|
+
|
|
198
|
+
# Lint
|
|
199
|
+
ruff check src/
|
|
200
|
+
|
|
201
|
+
# CLI
|
|
202
|
+
memory-server --help
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Docs
|
|
206
|
+
|
|
207
|
+
- [Agent Discovery](docs/AGENT_DISCOVERY.md) — concise MCP/client/directory metadata, capabilities, transports, and limitations
|
|
208
|
+
- [Directory Submission Text](docs/DIRECTORY_SUBMISSIONS.md) — Smithery/Glama-ready draft copy; no external publication performed
|
|
209
|
+
- [ADR](docs/ADR.md) — Architecture Decision Records (13 ADRs)
|
|
210
|
+
- [Changelog](CHANGELOG.md) — Release notes and known limitations
|
|
211
|
+
- [Integration Guide](docs/INTEGRATION.md) — Hermes MemoryProvider plugin
|
|
212
|
+
- [Agent Spec](docs/agent-spec.md) — Implementation specification
|
|
213
|
+
- [Technical Design](docs/technical-design.md) — Tech stack + roadmap
|
|
214
|
+
- [Architecture](docs/architecture.md) — Mermaid architecture diagram
|
|
215
|
+
- [Usage](docs/USAGE.md) — Full usage reference
|
|
216
|
+
- [Metrics & Benchmarking](docs/metrics.md) — Metrics and benchmark framework
|
|
217
|
+
- [LongMemEval Harness](docs/longmemeval-harness.md) — v0.11 raw/source/canonical retrieval scoring
|
|
218
|
+
- [Comparative Analysis](docs/comparative-metrics.md) — Comparative analysis with ChromaDB/SQLite
|
|
219
|
+
- [Drift Matrix](docs/drift-matrix.md) — Contract audit
|
|
220
|
+
- [Contracts](contracts/) — JSON Schema 2020-12 tool contracts
|
|
221
|
+
|
|
222
|
+
## API Reference
|
|
223
|
+
|
|
224
|
+
The server exposes fourteen MCP tools in v0.11.0b1:
|
|
225
|
+
|
|
226
|
+
| # | Tool | v0.7 | Description |
|
|
227
|
+
|---|------|------|-------------|
|
|
228
|
+
| 1 | `ping` | — | Health check |
|
|
229
|
+
| 2 | `search` | — | Keyword search over facts |
|
|
230
|
+
| 3 | `remember` | — | Store a fact with provenance |
|
|
231
|
+
| 4 | `get_context` | — | Retrieve context for a task |
|
|
232
|
+
| 5 | `semantic_search` | — | Vector similarity search |
|
|
233
|
+
| 6 | `learn` | ✓ | Extract knowledge; optionally extract beliefs |
|
|
234
|
+
| 7 | `graph_search` | — | Entity lookup + pathfinding |
|
|
235
|
+
| 8 | `route` | — | 4-stage hybrid router |
|
|
236
|
+
| 9 | `audit` | — | Memory health report |
|
|
237
|
+
| 10 | `metrics` | — | Prometheus metrics |
|
|
238
|
+
| 11 | `set_belief` | ✓ | Create, reinforce, or supersede a belief |
|
|
239
|
+
| 12 | `get_belief` | ✓ | Search beliefs with filters |
|
|
240
|
+
| 13 | `resolve_conflict` | ✓ | Resolve belief conflicts (manual + auto) |
|
|
241
|
+
| 14 | `reflect` | ✓ | 6-mode belief store analysis |
|
|
242
|
+
|
|
243
|
+
### v0.7 New Features
|
|
244
|
+
|
|
245
|
+
- **Belief Model** — Propositional knowledge with confidence, evidence provenance,
|
|
246
|
+
tags, lifecycle states (active, superseded, contradicted, discarded), and
|
|
247
|
+
version tracking.
|
|
248
|
+
- **Reflection** — The `reflect()` tool provides 6 analysis modes: overview,
|
|
249
|
+
contradictions, decay, topics, evidence_audit, and confidence histogram.
|
|
250
|
+
- **Learn-to-Belief** — `learn(extract_beliefs=True)` automatically extracts
|
|
251
|
+
beliefs from natural language text with evidence linked to extracted facts.
|
|
252
|
+
- **Conflict Resolution** — `resolve_conflict()` supports manual resolution
|
|
253
|
+
(keep_a, keep_b, merge, discard_both) and auto-resolution via confidence
|
|
254
|
+
threshold rules.
|
|
255
|
+
- **Reinforcement** — `set_belief()` automatically reinforces existing beliefs
|
|
256
|
+
with the same proposition via weighted average confidence.
|
|
257
|
+
- **Evidence Audit** — `reflect(mode="evidence_audit")` reports evidence quality
|
|
258
|
+
across all beliefs, detecting beliefs with missing or zero-weight evidence.
|
|
259
|
+
- **Decay Analysis** — `reflect(mode="decay")` forecasts lifecycle transitions
|
|
260
|
+
(stale, archived, forgotten) within the next 7 days using belief-specific TTL.
|
|
261
|
+
|
|
262
|
+
### ping
|
|
263
|
+
|
|
264
|
+
Health check — verifies the server is running and responsive.
|
|
265
|
+
|
|
266
|
+
**Arguments:** None
|
|
267
|
+
|
|
268
|
+
**Response:**
|
|
269
|
+
```json
|
|
270
|
+
{"status": "ok"}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### search
|
|
274
|
+
|
|
275
|
+
Search for stored facts by query text, subject, predicate, or object.
|
|
276
|
+
|
|
277
|
+
**Arguments:**
|
|
278
|
+
| Parameter | Type | Required | Description |
|
|
279
|
+
|-----------|--------|----------|-------------|
|
|
280
|
+
| `query` | string | yes | Text to search across all fact fields |
|
|
281
|
+
| `subject` | string | no | Filter by subject |
|
|
282
|
+
| `predicate` | string | no | Filter by predicate |
|
|
283
|
+
| `object` | string | no | Filter by object |
|
|
284
|
+
| `source` | string | no | Filter by source |
|
|
285
|
+
| `limit` | int | no | Max results (default: 10) |
|
|
286
|
+
|
|
287
|
+
**Response:**
|
|
288
|
+
```json
|
|
289
|
+
{
|
|
290
|
+
"total": 2,
|
|
291
|
+
"results": [
|
|
292
|
+
{"id": "uuid", "subject": "Docker", "predicate": "runs_on", "object": "OMV8", "confidence": 1.0, "source": "test", "created_at": "2025-01-01T00:00:00Z", "updated_at": "2025-01-01T00:00:00Z"}
|
|
293
|
+
],
|
|
294
|
+
"query": "Docker"
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### remember
|
|
299
|
+
|
|
300
|
+
Store a new fact in the memory server.
|
|
301
|
+
|
|
302
|
+
**Arguments:**
|
|
303
|
+
| Parameter | Type | Required | Description |
|
|
304
|
+
|-------------|--------|----------|-------------|
|
|
305
|
+
| `subject` | string | yes | Subject entity |
|
|
306
|
+
| `predicate` | string | yes | Relation/predicate |
|
|
307
|
+
| `object` | string | yes | Object entity |
|
|
308
|
+
| `confidence` | float | no | Confidence score 0.0–1.0 (default: 0.5) |
|
|
309
|
+
| `source` | string | no | Source identifier (default: "manual") |
|
|
310
|
+
| `tags` | list | no | Optional tags |
|
|
311
|
+
|
|
312
|
+
**Response:**
|
|
313
|
+
```json
|
|
314
|
+
{
|
|
315
|
+
"receipt": {
|
|
316
|
+
"id": "uuid",
|
|
317
|
+
"memory_type": "fact",
|
|
318
|
+
"confidence": 1.0,
|
|
319
|
+
"source": "test",
|
|
320
|
+
"verification_status": "candidate",
|
|
321
|
+
"timestamp": "2025-01-01T00:00:00Z"
|
|
322
|
+
},
|
|
323
|
+
"fact": {
|
|
324
|
+
"id": "uuid",
|
|
325
|
+
"subject": "Docker",
|
|
326
|
+
"predicate": "runs_on",
|
|
327
|
+
"object": "OMV8",
|
|
328
|
+
"confidence": 1.0,
|
|
329
|
+
"source": "test",
|
|
330
|
+
"created_at": "2025-01-01T00:00:00Z",
|
|
331
|
+
"updated_at": "2025-01-01T00:00:00Z"
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### get_context
|
|
337
|
+
|
|
338
|
+
Retrieve relevant context facts for a given task or subject.
|
|
339
|
+
|
|
340
|
+
**Arguments:**
|
|
341
|
+
| Parameter | Type | Required | Description |
|
|
342
|
+
|-------------|--------|----------|-------------|
|
|
343
|
+
| `task` | string | yes | Task description or subject to find context for |
|
|
344
|
+
| `subject` | string | no | Optional subject filter |
|
|
345
|
+
| `max_results` | int | no | Max results (default: 10) |
|
|
346
|
+
|
|
347
|
+
**Response:**
|
|
348
|
+
```json
|
|
349
|
+
{
|
|
350
|
+
"total": 2,
|
|
351
|
+
"facts": [
|
|
352
|
+
{"id": "uuid", "subject": "Caddy", "predicate": "uses", "object": "Port 443", "confidence": 1.0, "source": "test", "created_at": "2025-01-01T00:00:00Z", "updated_at": "2025-01-01T00:00:00Z"}
|
|
353
|
+
],
|
|
354
|
+
"task": "Caddy"
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### semantic_search
|
|
359
|
+
|
|
360
|
+
Semantic search — embed a query, find similar facts via vector similarity, and return ranked results with similarity scores.
|
|
361
|
+
|
|
362
|
+
Per ADR-005, routing rules (keyword-based exact matches) are evaluated **before** the embedding search. If a rule matches, the result indicates which route should handle the query (e.g., `"route": "sql"`). Otherwise, semantically ranked results are returned.
|
|
363
|
+
|
|
364
|
+
**Arguments:**
|
|
365
|
+
| Parameter | Type | Required | Default | Description |
|
|
366
|
+
|-----------------|--------|----------|---------|-------------|
|
|
367
|
+
| `query` | string | yes | — | Natural language query text |
|
|
368
|
+
| `top_k` | int | no | 10 | Maximum number of results |
|
|
369
|
+
| `score_threshold` | float | no | 0.0 | Minimum similarity score 0.0–1.0 |
|
|
370
|
+
|
|
371
|
+
**Response (rule match):**
|
|
372
|
+
```json
|
|
373
|
+
{
|
|
374
|
+
"rule_match": {
|
|
375
|
+
"route": "sql",
|
|
376
|
+
"rule_name": "ip_address_query",
|
|
377
|
+
"matched_keyword": "ip of"
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
**Response (semantic results):**
|
|
383
|
+
```json
|
|
384
|
+
{
|
|
385
|
+
"semantic_results": [
|
|
386
|
+
{
|
|
387
|
+
"id": "uuid",
|
|
388
|
+
"score": 0.92,
|
|
389
|
+
"payload": {
|
|
390
|
+
"subject": "Docker",
|
|
391
|
+
"predicate": "runs_on",
|
|
392
|
+
"object": "OMV8",
|
|
393
|
+
"content": "Docker runs on OMV8"
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
],
|
|
397
|
+
"total": 1
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### learn
|
|
402
|
+
|
|
403
|
+
Extract and store facts, decisions, and skills from natural language text. Runs all three extractors (FactExtractor, DecisionExtractor, SkillExtractor) on the input text, stores extracted items in the memory database, and returns structured results with receipts per item type.
|
|
404
|
+
|
|
405
|
+
**Arguments:**
|
|
406
|
+
| Parameter | Type | Required | Default | Description |
|
|
407
|
+
|-----------|--------|----------|---------|-------------|
|
|
408
|
+
| `text` | string | yes | — | Natural language text to extract knowledge from |
|
|
409
|
+
| `source` | string | no | "user" | Source identifier for provenance tracking |
|
|
410
|
+
|
|
411
|
+
**Response:**
|
|
412
|
+
```json
|
|
413
|
+
{
|
|
414
|
+
"facts": [
|
|
415
|
+
{
|
|
416
|
+
"receipt": {"id": "uuid", "memory_type": "fact", "source": "user", "confidence": 0.5, "verification_status": "candidate"},
|
|
417
|
+
"item": {"id": "uuid", "subject": "Docker", "predicate": "is", "object": "container", "confidence": 0.5, "source": "user"}
|
|
418
|
+
}
|
|
419
|
+
],
|
|
420
|
+
"decisions": [
|
|
421
|
+
{
|
|
422
|
+
"receipt": {"id": "uuid", "memory_type": "decision", "source": "user", "confidence": 0.5, "verification_status": "candidate"},
|
|
423
|
+
"item": {"id": "uuid", "context": "", "choice": "use Caddy", "reason": "it is simpler", "source": "user"}
|
|
424
|
+
}
|
|
425
|
+
],
|
|
426
|
+
"skills": [
|
|
427
|
+
{
|
|
428
|
+
"receipt": {"id": "uuid", "memory_type": "skill", "source": "user", "confidence": 0.5, "verification_status": "candidate"},
|
|
429
|
+
"item": {"id": "uuid", "purpose": "deploy docker", "steps": ["pull image", "run container"], "success_rate": 0.5}
|
|
430
|
+
}
|
|
431
|
+
],
|
|
432
|
+
"receipts": [
|
|
433
|
+
{"id": "uuid", "memory_type": "fact", "source": "user", "verification_status": "candidate"},
|
|
434
|
+
{"id": "uuid", "memory_type": "decision", "source": "user", "verification_status": "candidate"}
|
|
435
|
+
]
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### graph_search
|
|
440
|
+
|
|
441
|
+
Search the knowledge graph for entities, relations, and paths between entities.
|
|
442
|
+
|
|
443
|
+
Supports three search modes depending on which parameters are provided:
|
|
444
|
+
|
|
445
|
+
**Mode 1 — Query (entity lookup):** Pass a `query` string. The server extracts entity references from
|
|
446
|
+
the query and returns matching entities plus their neighbors and the relations between them.
|
|
447
|
+
|
|
448
|
+
**Mode 2 — Direct node lookup:** Pass an `entity_id` to look up a specific graph node by its ID
|
|
449
|
+
and get its neighbors and edges.
|
|
450
|
+
|
|
451
|
+
**Mode 3 — Pathfinding:** Pass `source_id` and `target_id` to find paths between two entities
|
|
452
|
+
in the graph (max depth 4).
|
|
453
|
+
|
|
454
|
+
**Arguments:**
|
|
455
|
+
| Parameter | Type | Required | Description |
|
|
456
|
+
|-------------|--------|----------|-------------|
|
|
457
|
+
| `query` | string | no | Text to extract entity references from |
|
|
458
|
+
| `entity_id` | string | no | Direct node ID lookup |
|
|
459
|
+
| `source_id` | string | no | Source entity for pathfinding |
|
|
460
|
+
| `target_id` | string | no | Target entity for pathfinding |
|
|
461
|
+
|
|
462
|
+
**Response:**
|
|
463
|
+
```json
|
|
464
|
+
{
|
|
465
|
+
"nodes": [
|
|
466
|
+
{"id": "docker", "name": "Docker", "type": "entity", "attributes": {}},
|
|
467
|
+
{"id": "omv8", "name": "OMV8", "type": "entity", "attributes": {}}
|
|
468
|
+
],
|
|
469
|
+
"edges": [
|
|
470
|
+
{"source_id": "docker", "target_id": "omv8", "relation": "runs_on", "attributes": {}}
|
|
471
|
+
],
|
|
472
|
+
"paths": []
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
**Pathfinding response:**
|
|
477
|
+
```json
|
|
478
|
+
{
|
|
479
|
+
"nodes": [],
|
|
480
|
+
"edges": [],
|
|
481
|
+
"paths": [
|
|
482
|
+
[
|
|
483
|
+
{"id": "serveralpha", "name": "ServerAlpha", "type": "entity"},
|
|
484
|
+
{"id": "webapp", "name": "WebApp", "type": "entity"},
|
|
485
|
+
{"id": "postgresql", "name": "PostgreSQL", "type": "entity"}
|
|
486
|
+
]
|
|
487
|
+
]
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### route
|
|
492
|
+
|
|
493
|
+
Route a query through the 4-stage hybrid router (rules → embeddings → graph → LLM fallback).
|
|
494
|
+
|
|
495
|
+
Per ADR-005, each stage is evaluated in priority order:
|
|
496
|
+
1. **Rules:** Keyword-based exact match rules.
|
|
497
|
+
2. **Semantic:** Embedding similarity search via the configured vector backend.
|
|
498
|
+
3. **Graph:** Entity relation lookup in the knowledge graph.
|
|
499
|
+
4. **LLM fallback:** Placeholder for future LLM-based routing.
|
|
500
|
+
|
|
501
|
+
Returns the result from the highest-priority stage that produces meaningful output.
|
|
502
|
+
|
|
503
|
+
**Arguments:**
|
|
504
|
+
| Parameter | Type | Required | Default | Description |
|
|
505
|
+
|------------------|--------|----------|---------|-------------|
|
|
506
|
+
| `query` | string | yes | — | Natural language query text |
|
|
507
|
+
| `top_k` | int | no | 10 | Maximum semantic search results |
|
|
508
|
+
| `score_threshold` | float | no | 0.0 | Minimum similarity score 0.0–1.0 |
|
|
509
|
+
|
|
510
|
+
**Response (rule match — stage 1):**
|
|
511
|
+
```json
|
|
512
|
+
{
|
|
513
|
+
"stage": 1,
|
|
514
|
+
"route": "rules",
|
|
515
|
+
"rule_match": {
|
|
516
|
+
"route": "sql",
|
|
517
|
+
"rule_name": "ip_address_query",
|
|
518
|
+
"matched_keyword": "ip of"
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**Response (semantic — stage 2):**
|
|
524
|
+
```json
|
|
525
|
+
{
|
|
526
|
+
"stage": 2,
|
|
527
|
+
"route": "semantic",
|
|
528
|
+
"semantic_results": [
|
|
529
|
+
{"id": "uuid", "score": 0.92, "payload": {"subject": "Docker", "predicate": "runs_on", "object": "OMV8"}}
|
|
530
|
+
],
|
|
531
|
+
"total": 1
|
|
532
|
+
}
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
**Response (graph — stage 3):**
|
|
536
|
+
```json
|
|
537
|
+
{
|
|
538
|
+
"stage": 3,
|
|
539
|
+
"route": "graph",
|
|
540
|
+
"graph_result": {
|
|
541
|
+
"entities": [{"id": "docker", "name": "Docker", "type": "entity"}],
|
|
542
|
+
"relations": [{"source_id": "docker", "target_id": "omv8", "relation": "runs_on"}],
|
|
543
|
+
"paths": []
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
**Response (LLM fallback — stage 4):**
|
|
549
|
+
```json
|
|
550
|
+
{
|
|
551
|
+
"stage": 4,
|
|
552
|
+
"route": "llm_fallback",
|
|
553
|
+
"message": "LLM fallback not configured"
|
|
554
|
+
}
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### audit
|
|
558
|
+
|
|
559
|
+
Run a structured memory audit covering consistency, orphan detection, confidence analysis, lifecycle validation, and index drift detection.
|
|
560
|
+
|
|
561
|
+
Supports focused sub-audits via the `audit_type` parameter, or a comprehensive `"full"` report.
|
|
562
|
+
|
|
563
|
+
**Arguments:**
|
|
564
|
+
| Parameter | Type | Required | Default | Description |
|
|
565
|
+
|-------------|--------|----------|---------|-------------|
|
|
566
|
+
| `audit_type` | string | no | "full" | One of `"full"`, `"consistency"`, `"orphans"`, `"confidence"` |
|
|
567
|
+
|
|
568
|
+
**Audit checks (full mode):**
|
|
569
|
+
|
|
570
|
+
| # | Check | Description |
|
|
571
|
+
|---|-------|-------------|
|
|
572
|
+
| 1 | **Orphan records** | Items in the validator store with no corresponding `MemoryReceipt` |
|
|
573
|
+
| 2 | **Missing receipts** | Validator entries referencing receipts that don't exist |
|
|
574
|
+
| 3 | **Lifecycle violations** | Items in an invalid lifecycle state or that skipped a required transition |
|
|
575
|
+
| 4 | **Confidence issues** | Confidence scores that conflict with current lifecycle state |
|
|
576
|
+
| 5 | **SQL/vector drift** | Consistency gaps between SQLite fact storage and the vector index |
|
|
577
|
+
| 6 | **SQL/graph drift** | Consistency gaps between SQLite fact storage and the knowledge graph |
|
|
578
|
+
|
|
579
|
+
When `audit_type` is set to a specific sub-audit (`"consistency"`, `"orphans"`, or `"confidence"`), only the corresponding analysis is returned:
|
|
580
|
+
|
|
581
|
+
- **consistency** — Checks for deprecated facts with active receipts, zero-confidence facts not marked stale/archived/forgotten, and stale facts with full confidence.
|
|
582
|
+
- **orphans** — Scans the graph for nodes with no incoming edges (unlinked facts).
|
|
583
|
+
- **confidence** — Analyzes the confidence score distribution, bucket counts, and lists low-confidence items (< 0.3).
|
|
584
|
+
|
|
585
|
+
**Response:**
|
|
586
|
+
```json
|
|
587
|
+
{
|
|
588
|
+
"audit_type": "full",
|
|
589
|
+
"warnings": [],
|
|
590
|
+
"errors": [
|
|
591
|
+
"Found 2 items without MemoryReceipt: fact_001, fact_002"
|
|
592
|
+
],
|
|
593
|
+
"stats": {
|
|
594
|
+
"confidence": {
|
|
595
|
+
"total": 150,
|
|
596
|
+
"buckets": {"0.0-0.3": 5, "0.3-0.5": 20, "0.5-0.7": 45, "0.7-0.85": 50, "0.85-1.0": 30},
|
|
597
|
+
"low_confidence": ["fact_001", "fact_002"]
|
|
598
|
+
},
|
|
599
|
+
"sql_vector_drift": {"drift_pct": 0.0, "sql_count": 150, "vector_count": 150},
|
|
600
|
+
"sql_graph_drift": {"drift_pct": 2.0, "sql_count": 150, "graph_count": 147}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
### metrics
|
|
606
|
+
|
|
607
|
+
Return a Prometheus-formatted snapshot of all observability metrics. Compatible with any Prometheus scraper or `curl | grep` workflows.
|
|
608
|
+
|
|
609
|
+
**Arguments:** None
|
|
610
|
+
|
|
611
|
+
**Response:** Plaintext Prometheus exposition format:
|
|
612
|
+
```
|
|
613
|
+
# HELP tool_calls_total Total MCP tool calls
|
|
614
|
+
# TYPE tool_calls_total counter
|
|
615
|
+
tool_calls_total{tool="search",status="success"} 42.0
|
|
616
|
+
tool_calls_total{tool="remember",status="success"} 17.0
|
|
617
|
+
# HELP search_latency_ms Search latency in ms
|
|
618
|
+
# TYPE search_latency_ms histogram
|
|
619
|
+
search_latency_ms_bucket{le="1.0"} 0.0
|
|
620
|
+
search_latency_ms_bucket{le="5.0"} 5.0
|
|
621
|
+
...
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
## Stack
|
|
625
|
+
|
|
626
|
+
Python 3.11+, MCP SDK, Pydantic, SQLAlchemy, LanceDB/Qdrant vector providers,
|
|
627
|
+
SimpleGraph, GitPython, Prometheus Client, OpenTelemetry
|
|
628
|
+
|
|
629
|
+
## Storage
|
|
630
|
+
|
|
631
|
+
The server uses a multi-tier storage architecture with SQLite/FTS5 as the primary durable and keyword-search store, backed by optional vector indexes (LanceDB by default for semantic search, Qdrant optional via `MEMORY_VECTOR_BACKEND=qdrant`) and the current in-memory SimpleGraph graph layer. Neo4j is declared only as a future/optional graph dependency and is not wired into the v0.11 runtime.
|
|
632
|
+
|
|
633
|
+
### SQLite with WAL Mode
|
|
634
|
+
|
|
635
|
+
The primary fact store uses SQLite in **WAL (Write-Ahead Logging)** mode for concurrent read performance during background indexing operations:
|
|
636
|
+
|
|
637
|
+
```sql
|
|
638
|
+
PRAGMA journal_mode=WAL;
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
WAL mode allows simultaneous reads while a single writer is active, which is critical for the outbox pattern and background indexing without blocking the MCP tool handler.
|
|
642
|
+
|
|
643
|
+
### Alembic Migrations
|
|
644
|
+
|
|
645
|
+
Database schema migrations are managed via Alembic. To apply pending migrations:
|
|
646
|
+
|
|
647
|
+
```bash
|
|
648
|
+
alembic upgrade head
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
Migrations live in `migrations/` and are automatically tested in CI (upgrade then downgrade -1).
|
|
652
|
+
|
|
653
|
+
### FTS5 Full-Text Search
|
|
654
|
+
|
|
655
|
+
The `facts_fts` virtual table provides fast keyword search across fact content:
|
|
656
|
+
|
|
657
|
+
```sql
|
|
658
|
+
CREATE VIRTUAL TABLE facts_fts USING fts5(
|
|
659
|
+
subject, predicate, object, content='facts', content_rowid='id'
|
|
660
|
+
);
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
FTS5 enables the `search` tool's full-text capabilities with ranking, prefix queries, and snippet generation.
|
|
664
|
+
|
|
665
|
+
### Outbox Pattern for Reliable Indexing
|
|
666
|
+
|
|
667
|
+
Facts are written to the SQLite store first, then queued through an **outbox pattern** for background indexing. In v0.11.0b1 the server keeps the SQLite write durable even if optional vector indexing or in-memory SimpleGraph indexing is unavailable:
|
|
668
|
+
|
|
669
|
+
1. Fact is inserted into SQLite (single write transaction)
|
|
670
|
+
2. An outbox record is created in a dedicated table or queue
|
|
671
|
+
3. A background worker picks up outbox entries and indexes available secondary paths (Qdrant only when that provider/embedder has been initialized in the worker path, plus SimpleGraph relations)
|
|
672
|
+
4. On success, the outbox record is marked as processed
|
|
673
|
+
5. On failure, the outbox record is retried — the fact is never lost
|
|
674
|
+
|
|
675
|
+
This ensures that even if vector or graph indexing fails, the fact data is durably stored and can be re-indexed on the next retry.
|
|
676
|
+
|
|
677
|
+
## Lifecycle
|
|
678
|
+
|
|
679
|
+
Every fact and extracted memory item passes through a 6-stage lifecycle.
|
|
680
|
+
The lifecycle determines how a fact moves from raw ingestion to trusted knowledge and eventual retirement.
|
|
681
|
+
|
|
682
|
+
### Lifecycle States (v0.6)
|
|
683
|
+
|
|
684
|
+
| State | Description |
|
|
685
|
+
|-------------|-------------|
|
|
686
|
+
| `candidate` | Initial state after ingestion via `remember()` or `learn()`. Low confidence (0.5 default). |
|
|
687
|
+
| `validated` | Confidence >= 0.7 — fact has passed an internal quality check. |
|
|
688
|
+
| `active` | Confidence >= 0.85 AND corroboration >= 2 sources. High-reliability knowledge. |
|
|
689
|
+
| `stale` | Confidence has decayed below threshold — fact may be outdated. |
|
|
690
|
+
| `archived` | Stale fact moved to cold storage. Retained for audit but excluded from active queries. |
|
|
691
|
+
| `forgotten` | Permanently removed from indexes. Only receipt/provenance metadata preserved. |
|
|
692
|
+
|
|
693
|
+
### Lifecycle Flow
|
|
694
|
+
|
|
695
|
+
```
|
|
696
|
+
candidate → validated → active → stale → archived → forgotten
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
Transitions are **forward-only** — once promoted, an item can only move forward through the lifecycle. Backward compatibility maps the v0.5 states `"trusted"` → `"active"` and `"deprecated"` → `"stale"`.
|
|
700
|
+
|
|
701
|
+
### Confidence Scoring
|
|
702
|
+
|
|
703
|
+
Confidence scores (0.0–1.0) are computed heuristically from:
|
|
704
|
+
|
|
705
|
+
- **Source reliability**: `verified` (0.9), `admin` (0.85), `inferred` (0.7),
|
|
706
|
+
`extracted` (0.6), `unknown` (0.3)
|
|
707
|
+
- **Age decay**: Exponential decay over TTL (default 90 days), minimum 0.3
|
|
708
|
+
- **Corroboration boost**: +0.05 for 2 sources, +0.10 for 3+
|
|
709
|
+
- **Conflict penalty**: -0.10 for 1 conflict, -0.20 for 2+
|
|
710
|
+
|
|
711
|
+
### Decay Engine
|
|
712
|
+
|
|
713
|
+
The `DecayEngine` applies time-based decay to all stored facts:
|
|
714
|
+
- TTL-based confidence reduction (default 90 days)
|
|
715
|
+
- Archive threshold: facts below 0.3 confidence are flagged for archiving
|
|
716
|
+
- Runs on-demand at audit time, not as a background process
|
|
717
|
+
|
|
718
|
+
### Auto-Indexing
|
|
719
|
+
|
|
720
|
+
When a fact is stored via `remember()` or `learn()`, the server automatically:
|
|
721
|
+
|
|
722
|
+
1. **Embeds** the fact text using SentenceTransformer (`all-MiniLM-L6-v2`) when an embedder is initialized
|
|
723
|
+
2. **Upserts** the embedding into the initialized outbox vector path (currently Qdrant when available; `semantic_search` itself uses LanceDB by default or Qdrant if configured)
|
|
724
|
+
3. **Syncs** to the in-memory SimpleGraph knowledge graph (creates entity nodes + relation edges)
|
|
725
|
+
|
|
726
|
+
This is best-effort — failures during auto-indexing never crash the caller.
|
|
727
|
+
|
|
728
|
+
## Observability
|
|
729
|
+
|
|
730
|
+
The server exposes structured observability through Prometheus metrics and OpenTelemetry instrumentation.
|
|
731
|
+
|
|
732
|
+
### Prometheus Metrics
|
|
733
|
+
|
|
734
|
+
A dedicated `/metrics` tool returns Prometheus-formatted output on demand. The `MetricsCollector` singleton tracks key performance indicators across all tool operations.
|
|
735
|
+
|
|
736
|
+
**Key metrics:**
|
|
737
|
+
|
|
738
|
+
| Metric | Type | Labels | Description |
|
|
739
|
+
|--------|------|--------|-------------|
|
|
740
|
+
| `tool_calls_total` | Counter | `tool`, `status` | Total MCP tool calls by name and success/error status |
|
|
741
|
+
| `tool_error_total` | Counter | `tool` | Total errors per tool |
|
|
742
|
+
| `search_latency_ms` | Histogram | — | Search latency buckets (1–500 ms) |
|
|
743
|
+
| `semantic_search_latency_ms` | Histogram | — | Semantic search latency buckets (10–1000 ms) |
|
|
744
|
+
| `remember_latency_ms` | Histogram | — | Remember latency buckets (5–500 ms) |
|
|
745
|
+
| `derived_index_drift` | Gauge | — | SQL/vector index drift count (updated on each audit) |
|
|
746
|
+
| `reindex_repair_total` | Counter | — | Reindex repairs triggered |
|
|
747
|
+
| `sqlite_busy_events_total` | Counter | — | SQLite WAL busy events |
|
|
748
|
+
|
|
749
|
+
### OpenTelemetry Hooks
|
|
750
|
+
|
|
751
|
+
Every tool call is wrapped with OpenTelemetry tracing:
|
|
752
|
+
|
|
753
|
+
```python
|
|
754
|
+
tracer = trace.get_tracer(__name__)
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
Spans are created per tool invocation, capturing duration and status. The `tool_call()` context manager on `MetricsCollector` automatically records:
|
|
758
|
+
- Start time and duration
|
|
759
|
+
- Success/error status
|
|
760
|
+
- Exception propagation for error counting
|
|
761
|
+
|
|
762
|
+
## Development
|
|
763
|
+
|
|
764
|
+
### Makefile Targets
|
|
765
|
+
|
|
766
|
+
| Target | Description |
|
|
767
|
+
|------------|-------------|
|
|
768
|
+
| `make install` | Install package with dev dependencies (`pip install -e ".[dev]"`) |
|
|
769
|
+
| `make test` | Run unit tests (`pytest tests/ -q`) |
|
|
770
|
+
| `make lint` | Run Ruff linter (`ruff check src/`) |
|
|
771
|
+
| `make all` | Run lint + test sequentially |
|
|
772
|
+
| `make migrate` | Apply Alembic migrations (`alembic upgrade head`) |
|
|
773
|
+
| `make build` | Build Python package (`python3 -m build`) |
|
|
774
|
+
|
|
775
|
+
### CI/CD
|
|
776
|
+
|
|
777
|
+
GitHub Actions (`.github/workflows/ci.yml`) runs on push/PR to `main`:
|
|
778
|
+
|
|
779
|
+
| Job | What it runs |
|
|
780
|
+
|-----|-------------|
|
|
781
|
+
| **lint** | `ruff check src/` |
|
|
782
|
+
| **unit-tests** | `pytest tests/ -q` |
|
|
783
|
+
| **integration-tests** | `pytest tests/ -q -k "integration or e2e or benchmark"` |
|
|
784
|
+
| **contract-tests** | JSON Schema validation + `pytest tests/ -q -k "schema or contract"` |
|
|
785
|
+
| **migration-tests** | `alembic upgrade head && alembic downgrade -1` |
|
|
786
|
+
|
|
787
|
+
## Roadmap
|
|
788
|
+
|
|
789
|
+
| Phase | Milestone |
|
|
790
|
+
|-------|-----------|
|
|
791
|
+
| v0.1a | MCP API + SQLite provider + get_context/search/remember |
|
|
792
|
+
| v0.2 | Qdrant + embeddings + semantic router |
|
|
793
|
+
| v0.3 | LLM extractors + learn() |
|
|
794
|
+
| v0.4 | Graph DB + entity relations |
|
|
795
|
+
| v0.5 | Confidence engine + validation + decay + auditor + auto-indexing |
|
|
796
|
+
| v0.6 | 6-state lifecycle, audit tool, metrics/observability, outbox indexing, storage docs, CI/CD |
|
|
797
|
+
|
|
798
|
+
## License
|
|
799
|
+
|
|
800
|
+
This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.
|
|
801
|
+
|
|
802
|
+
## Authors
|
|
803
|
+
|
|
804
|
+
See [AUTHORS.md](AUTHORS.md) for contributor and attribution information.
|