superlocalmemory 2.5.0 → 2.6.0
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.
- package/CHANGELOG.md +16 -0
- package/README.md +125 -71
- package/api_server.py +47 -0
- package/docs/architecture-diagram.drawio +405 -0
- package/docs/plans/2026-02-13-benchmark-suite.md +1349 -0
- package/mcp_server.py +72 -17
- package/package.json +6 -3
- package/scripts/generate-thumbnails.py +220 -0
- package/src/agent_registry.py +34 -1
- package/src/auth_middleware.py +63 -0
- package/src/cache_manager.py +1 -1
- package/src/db_connection_manager.py +16 -2
- package/src/event_bus.py +15 -0
- package/src/graph_engine.py +113 -44
- package/src/hybrid_search.py +2 -2
- package/src/memory-reset.py +17 -3
- package/src/memory_store_v2.py +80 -7
- package/src/rate_limiter.py +87 -0
- package/src/trust_scorer.py +38 -6
- package/src/webhook_dispatcher.py +17 -0
- package/ui_server.py +55 -1
- package/docs/COMPETITIVE-ANALYSIS.md +0 -210
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,22 @@ SuperLocalMemory V2 - Intelligent local memory system for AI coding assistants.
|
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
+
## [2.5.1] - 2026-02-13
|
|
20
|
+
|
|
21
|
+
**Release Type:** Framework Integration Release — "Plugged Into the Ecosystem"
|
|
22
|
+
**Backward Compatible:** Yes (additive packages only, no core changes)
|
|
23
|
+
|
|
24
|
+
### The Big Picture
|
|
25
|
+
SuperLocalMemory is now a first-class memory backend for LangChain and LlamaIndex — the two largest AI/LLM frameworks. Two pip-installable packages, zero cloud dependencies.
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
- **LangChain Integration** (`langchain-superlocalmemory`): Persistent chat message history backed by local SQLite. Works with `RunnableWithMessageHistory` and LCEL chains. `pip install langchain-superlocalmemory`
|
|
29
|
+
- **LlamaIndex Integration** (`llama-index-storage-chat-store-superlocalmemory`): Full `BaseChatStore` implementation. Works with `ChatMemoryBuffer` and `SimpleChatEngine`. `pip install llama-index-storage-chat-store-superlocalmemory`
|
|
30
|
+
- **Example scripts** for both frameworks in `examples/` directory — runnable without API keys
|
|
31
|
+
- **Session isolation**: Framework memories are tagged separately and never appear in normal `slm recall`
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
19
35
|
## [2.5.0] - 2026-02-12
|
|
20
36
|
|
|
21
37
|
**Release Type:** Major Feature Release — "Your AI Memory Has a Heartbeat"
|
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://
|
|
2
|
+
<img src="https://superlocalmemory.com/assets/branding/icon-512.png" alt="SuperLocalMemory V2" width="200"/>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<h1 align="center">
|
|
5
|
+
<h1 align="center">SuperLocalMemory V2</h1>
|
|
6
|
+
<p align="center"><strong>Your AI Finally Remembers You</strong></p>
|
|
6
7
|
|
|
7
8
|
<p align="center">
|
|
8
9
|
<strong>⚡ Created & Architected by <a href="https://github.com/varun369">Varun Pratap Bhardwaj</a> ⚡</strong><br/>
|
|
@@ -13,6 +14,10 @@
|
|
|
13
14
|
<strong>Stop re-explaining your codebase every session. 100% local. Zero setup. Completely free.</strong>
|
|
14
15
|
</p>
|
|
15
16
|
|
|
17
|
+
<p align="center">
|
|
18
|
+
<a href="https://superlocalmemory.com"><img src="https://img.shields.io/badge/🌐_Website-superlocalmemory.com-ff6b35?style=for-the-badge" alt="Official Website"/></a>
|
|
19
|
+
</p>
|
|
20
|
+
|
|
16
21
|
<p align="center">
|
|
17
22
|
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.8+-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python 3.8+"/></a>
|
|
18
23
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="MIT License"/></a>
|
|
@@ -23,6 +28,7 @@
|
|
|
23
28
|
</p>
|
|
24
29
|
|
|
25
30
|
<p align="center">
|
|
31
|
+
<a href="https://superlocalmemory.com"><strong>superlocalmemory.com</strong></a> •
|
|
26
32
|
<a href="#-quick-start">Quick Start</a> •
|
|
27
33
|
<a href="#-why-superlocalemory">Why This?</a> •
|
|
28
34
|
<a href="#-features">Features</a> •
|
|
@@ -39,24 +45,62 @@
|
|
|
39
45
|
|
|
40
46
|
---
|
|
41
47
|
|
|
42
|
-
## NEW: v2.
|
|
48
|
+
## NEW: v2.6 — Security Hardening & Performance
|
|
43
49
|
|
|
44
|
-
> **SuperLocalMemory is
|
|
50
|
+
> **SuperLocalMemory is now production-hardened with trust enforcement, rate limiting, and accelerated graph building.**
|
|
45
51
|
|
|
46
|
-
| What's New | Why It Matters |
|
|
47
|
-
|
|
48
|
-
| **
|
|
49
|
-
| **
|
|
50
|
-
| **
|
|
51
|
-
| **
|
|
52
|
-
| **
|
|
53
|
-
| **
|
|
52
|
+
| What's New in v2.6 | Why It Matters |
|
|
53
|
+
|---------------------|----------------|
|
|
54
|
+
| **Trust Enforcement** | Agents with trust below 0.3 are blocked from write/delete — Bayesian scoring now actively protects your memory. |
|
|
55
|
+
| **Profile Isolation** | Memory profiles are fully sandboxed — no cross-profile data leakage. |
|
|
56
|
+
| **Rate Limiting** | Protects against memory flooding and spam from misbehaving agents. |
|
|
57
|
+
| **SSRF Protection** | Webhook dispatcher validates URLs to prevent server-side request forgery. |
|
|
58
|
+
| **HNSW-Accelerated Graphs** | Knowledge graph edge building uses HNSW index for faster construction at scale. |
|
|
59
|
+
| **Hybrid Search Engine** | Combined semantic + FTS5 + graph retrieval for maximum accuracy. |
|
|
60
|
+
|
|
61
|
+
**v2.5 highlights (included):** Real-time event stream, WAL-mode concurrent writes, agent tracking, memory provenance, 28 API endpoints.
|
|
54
62
|
|
|
55
63
|
**Upgrade:** `npm install -g superlocalmemory@latest`
|
|
56
64
|
|
|
57
65
|
**Dashboard:** `python3 ~/.claude-memory/ui_server.py` then open `http://localhost:8765`
|
|
58
66
|
|
|
59
|
-
[Architecture Doc](docs/ARCHITECTURE-V2.5.md) | [Full Changelog](CHANGELOG.md)
|
|
67
|
+
[Interactive Architecture Diagram](https://superlocalmemory.com/architecture.html) | [Architecture Doc](docs/ARCHITECTURE-V2.5.md) | [Full Changelog](CHANGELOG.md)
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## NEW: Framework Integrations (v2.5.1)
|
|
72
|
+
|
|
73
|
+
Use SuperLocalMemory as a memory backend in your LangChain and LlamaIndex applications — 100% local, zero cloud.
|
|
74
|
+
|
|
75
|
+
### LangChain
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install langchain-superlocalmemory
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from langchain_superlocalmemory import SuperLocalMemoryChatMessageHistory
|
|
83
|
+
from langchain_core.runnables.history import RunnableWithMessageHistory
|
|
84
|
+
|
|
85
|
+
history = SuperLocalMemoryChatMessageHistory(session_id="my-session")
|
|
86
|
+
# Messages persist across sessions, stored locally in ~/.claude-memory/memory.db
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### LlamaIndex
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pip install llama-index-storage-chat-store-superlocalmemory
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from llama_index.storage.chat_store.superlocalmemory import SuperLocalMemoryChatStore
|
|
97
|
+
from llama_index.core.memory import ChatMemoryBuffer
|
|
98
|
+
|
|
99
|
+
chat_store = SuperLocalMemoryChatStore()
|
|
100
|
+
memory = ChatMemoryBuffer.from_defaults(chat_store=chat_store, chat_store_key="user-1")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
[LangChain Guide](https://github.com/varun369/SuperLocalMemoryV2/wiki/LangChain-Integration) | [LlamaIndex Guide](https://github.com/varun369/SuperLocalMemoryV2/wiki/LlamaIndex-Integration)
|
|
60
104
|
|
|
61
105
|
---
|
|
62
106
|
|
|
@@ -71,7 +115,7 @@ Or clone manually:
|
|
|
71
115
|
git clone https://github.com/varun369/SuperLocalMemoryV2.git && cd SuperLocalMemoryV2 && ./install.sh
|
|
72
116
|
```
|
|
73
117
|
|
|
74
|
-
Both methods auto-detect and configure **
|
|
118
|
+
Both methods auto-detect and configure **17+ IDEs and AI tools** — Cursor, VS Code/Copilot, Codex, Claude, Windsurf, Gemini CLI, JetBrains, and more.
|
|
75
119
|
|
|
76
120
|
---
|
|
77
121
|
|
|
@@ -217,7 +261,7 @@ python ~/.claude-memory/ui_server.py
|
|
|
217
261
|
| **Hierarchical Leiden** | Recursive community detection — clusters within clusters up to 3 levels. "Python" → "FastAPI" → "Auth patterns" |
|
|
218
262
|
| **Community Summaries** | TF-IDF structured reports per cluster: key topics, projects, categories at a glance |
|
|
219
263
|
| **MACLA Confidence** | Bayesian Beta-Binomial scoring (arXiv:2512.18950) — calibrated confidence, not raw frequency |
|
|
220
|
-
| **Auto-Backup** | Configurable SQLite backups with retention policies,
|
|
264
|
+
| **Auto-Backup** | Configurable SQLite backups with retention policies, restore from any backup via CLI |
|
|
221
265
|
| **Profile UI** | Create, switch, delete profiles from the web dashboard — full isolation per context |
|
|
222
266
|
| **Profile Isolation** | All API endpoints (graph, clusters, patterns, timeline) scoped to active profile |
|
|
223
267
|
|
|
@@ -229,12 +273,12 @@ SuperLocalMemory V2.2.0 implements **hybrid search** combining multiple strategi
|
|
|
229
273
|
|
|
230
274
|
### Search Strategies
|
|
231
275
|
|
|
232
|
-
| Strategy | Method | Best For |
|
|
233
|
-
|
|
234
|
-
| **Semantic Search** | TF-IDF vectors + cosine similarity | Conceptual queries ("authentication patterns") |
|
|
235
|
-
| **Full-Text Search** | SQLite FTS5 with ranking | Exact phrases ("JWT tokens expire") |
|
|
236
|
-
| **Graph-Enhanced** | Knowledge graph traversal | Related concepts ("show auth-related") |
|
|
237
|
-
| **Hybrid Mode** | All three combined | General queries
|
|
276
|
+
| Strategy | Method | Best For |
|
|
277
|
+
|----------|--------|----------|
|
|
278
|
+
| **Semantic Search** | TF-IDF vectors + cosine similarity | Conceptual queries ("authentication patterns") |
|
|
279
|
+
| **Full-Text Search** | SQLite FTS5 with ranking | Exact phrases ("JWT tokens expire") |
|
|
280
|
+
| **Graph-Enhanced** | Knowledge graph traversal | Related concepts ("show auth-related") |
|
|
281
|
+
| **Hybrid Mode** | All three combined | General queries (default) |
|
|
238
282
|
|
|
239
283
|
### Search Examples
|
|
240
284
|
|
|
@@ -256,52 +300,65 @@ slm recall "API design patterns"
|
|
|
256
300
|
# Combines semantic + exact + graph for optimal results
|
|
257
301
|
```
|
|
258
302
|
|
|
259
|
-
### Search
|
|
303
|
+
### Measured Search Latency
|
|
260
304
|
|
|
261
|
-
|
|
|
262
|
-
|
|
263
|
-
| 100
|
|
264
|
-
| 500
|
|
265
|
-
| 1,000
|
|
266
|
-
| 5,000 | 85ms | 50ms | 110ms | 150ms |
|
|
305
|
+
| Database Size | Median | P95 | P99 |
|
|
306
|
+
|---------------|--------|-----|-----|
|
|
307
|
+
| 100 memories | **10.6ms** | 14.9ms | 15.8ms |
|
|
308
|
+
| 500 memories | **65.2ms** | 101.7ms | 112.5ms |
|
|
309
|
+
| 1,000 memories | **124.3ms** | 190.1ms | 219.5ms |
|
|
267
310
|
|
|
268
|
-
|
|
311
|
+
For typical personal databases (under 500 memories), search returns faster than you blink. [Full benchmarks →](https://github.com/varun369/SuperLocalMemoryV2/wiki/Performance-Benchmarks)
|
|
269
312
|
|
|
270
313
|
---
|
|
271
314
|
|
|
272
|
-
## ⚡ Performance
|
|
315
|
+
## ⚡ Measured Performance
|
|
316
|
+
|
|
317
|
+
All numbers measured on real hardware (Apple M4 Pro, 24GB RAM). No estimates — real benchmarks.
|
|
318
|
+
|
|
319
|
+
### Search Speed
|
|
320
|
+
|
|
321
|
+
| Database Size | Median Latency | P95 Latency |
|
|
322
|
+
|---------------|----------------|-------------|
|
|
323
|
+
| 100 memories | **10.6ms** | 14.9ms |
|
|
324
|
+
| 500 memories | **65.2ms** | 101.7ms |
|
|
325
|
+
| 1,000 memories | **124.3ms** | 190.1ms |
|
|
273
326
|
|
|
274
|
-
|
|
327
|
+
For typical personal use (under 500 memories), search results return faster than you blink.
|
|
275
328
|
|
|
276
|
-
|
|
277
|
-
|-----------|------|------------|-------|
|
|
278
|
-
| **Add Memory** | < 10ms | - | Instant indexing |
|
|
279
|
-
| **Search (Hybrid)** | 80ms | 3.3x faster than v1 | 500 memories |
|
|
280
|
-
| **Graph Build** | < 2s | - | 100 memories |
|
|
281
|
-
| **Pattern Learning** | < 2s | - | Incremental |
|
|
282
|
-
| **Dashboard Load** | < 500ms | - | 1,000 memories |
|
|
283
|
-
| **Timeline Render** | < 300ms | - | All memories |
|
|
329
|
+
### Concurrent Writes — Zero Errors
|
|
284
330
|
|
|
285
|
-
|
|
331
|
+
| Scenario | Writes/sec | Errors |
|
|
332
|
+
|----------|------------|--------|
|
|
333
|
+
| 1 AI tool writing | **204/sec** | 0 |
|
|
334
|
+
| 2 AI tools simultaneously | **220/sec** | 0 |
|
|
335
|
+
| 5 AI tools simultaneously | **130/sec** | 0 |
|
|
336
|
+
| 10 AI tools simultaneously | **25/sec** | 0 |
|
|
286
337
|
|
|
287
|
-
|
|
288
|
-
|------|-------------|-------------|---------|
|
|
289
|
-
| **Tier 1** | Active memories (0-30 days) | None | - |
|
|
290
|
-
| **Tier 2** | Warm memories (30-90 days) | 60% | Progressive summarization |
|
|
291
|
-
| **Tier 3** | Cold storage (90+ days) | 96% | JSON archival |
|
|
338
|
+
WAL mode + serialized write queue = zero "database is locked" errors, ever.
|
|
292
339
|
|
|
293
|
-
|
|
340
|
+
### Storage
|
|
294
341
|
|
|
295
|
-
|
|
342
|
+
10,000 memories = **13.6 MB** on disk (~1.9 KB per memory). Your entire AI memory history takes less space than a photo.
|
|
296
343
|
|
|
297
|
-
|
|
298
|
-
|--------------|-------------|-------------|-----------|
|
|
299
|
-
| 100 memories | 35ms | 0.5s | < 30MB |
|
|
300
|
-
| 500 memories | 45ms | 2s | < 50MB |
|
|
301
|
-
| 1,000 memories | 55ms | 5s | < 80MB |
|
|
302
|
-
| 5,000 memories | 85ms | 30s | < 150MB |
|
|
344
|
+
### Trust Defense
|
|
303
345
|
|
|
304
|
-
|
|
346
|
+
Bayesian trust scoring achieves **perfect separation** (trust gap = 1.0) between honest and malicious agents. Detects "sleeper" attacks with 74.7% trust drop. Zero false positives.
|
|
347
|
+
|
|
348
|
+
### Graph Construction
|
|
349
|
+
|
|
350
|
+
| Memories | Build Time |
|
|
351
|
+
|----------|-----------|
|
|
352
|
+
| 100 | 0.28s |
|
|
353
|
+
| 1,000 | 10.6s |
|
|
354
|
+
|
|
355
|
+
Leiden clustering discovers 6-7 natural topic communities automatically.
|
|
356
|
+
|
|
357
|
+
> **Graph Scaling:** Knowledge graph features work best with up to 10,000 memories. For larger databases, the system uses intelligent sampling (most recent + highest importance memories) for graph construction. Core search and memory storage have no upper limit.
|
|
358
|
+
|
|
359
|
+
> **LoCoMo benchmark results coming soon** — evaluation against the standardized [LoCoMo](https://snap-research.github.io/locomo/) long-conversation memory benchmark (Snap Research, ACL 2024).
|
|
360
|
+
|
|
361
|
+
[Full benchmark details →](https://github.com/varun369/SuperLocalMemoryV2/wiki/Performance-Benchmarks)
|
|
305
362
|
|
|
306
363
|
---
|
|
307
364
|
|
|
@@ -433,7 +490,7 @@ Not another simple key-value store. SuperLocalMemory implements **cutting-edge m
|
|
|
433
490
|
| **Completely Free** | Limited | Limited | Partial | ✅ | ✅ |
|
|
434
491
|
|
|
435
492
|
**SuperLocalMemory V2 is the ONLY solution that:**
|
|
436
|
-
- ✅ Works across
|
|
493
|
+
- ✅ Works across 17+ IDEs and CLI tools
|
|
437
494
|
- ✅ Remains 100% local (no cloud dependencies)
|
|
438
495
|
- ✅ Completely free with unlimited memories
|
|
439
496
|
|
|
@@ -445,6 +502,8 @@ Not another simple key-value store. SuperLocalMemory implements **cutting-edge m
|
|
|
445
502
|
|
|
446
503
|
### Multi-Layer Memory Architecture
|
|
447
504
|
|
|
505
|
+
**[View Interactive Architecture Diagram](https://superlocalmemory.com/architecture.html)** — Click any layer for details, research references, and file paths.
|
|
506
|
+
|
|
448
507
|
```
|
|
449
508
|
┌─────────────────────────────────────────────────────────────┐
|
|
450
509
|
│ Layer 9: VISUALIZATION (NEW v2.2.0) │
|
|
@@ -457,7 +516,7 @@ Not another simple key-value store. SuperLocalMemory implements **cutting-edge m
|
|
|
457
516
|
├─────────────────────────────────────────────────────────────┤
|
|
458
517
|
│ Layer 7: UNIVERSAL ACCESS │
|
|
459
518
|
│ MCP + Skills + CLI (works everywhere) │
|
|
460
|
-
│
|
|
519
|
+
│ 17+ IDEs with single database │
|
|
461
520
|
├─────────────────────────────────────────────────────────────┤
|
|
462
521
|
│ Layer 6: MCP INTEGRATION │
|
|
463
522
|
│ Model Context Protocol: 6 tools, 4 resources, 2 prompts │
|
|
@@ -595,23 +654,18 @@ superlocalmemoryv2:reset hard --confirm # Nuclear option
|
|
|
595
654
|
|
|
596
655
|
---
|
|
597
656
|
|
|
598
|
-
## 📊 Performance
|
|
599
|
-
|
|
600
|
-
**SEO:** Performance benchmarks, memory system speed, search latency, visualization dashboard performance
|
|
657
|
+
## 📊 Performance at a Glance
|
|
601
658
|
|
|
602
|
-
| Metric | Result |
|
|
603
|
-
|
|
604
|
-
| **
|
|
605
|
-
| **
|
|
606
|
-
| **
|
|
607
|
-
| **
|
|
608
|
-
| **
|
|
609
|
-
| **
|
|
610
|
-
| **Timeline render** | **< 300ms** | All memories visualized |
|
|
611
|
-
| **Storage compression** | **60-96% reduction** | Progressive tiering |
|
|
612
|
-
| **Memory overhead** | **< 50MB RAM** | Lightweight |
|
|
659
|
+
| Metric | Measured Result |
|
|
660
|
+
|--------|----------------|
|
|
661
|
+
| **Search latency** | **10.6ms** median (100 memories) |
|
|
662
|
+
| **Concurrent writes** | **220/sec** with 2 agents, zero errors |
|
|
663
|
+
| **Storage** | **1.9 KB** per memory at scale (13.6 MB for 10K) |
|
|
664
|
+
| **Trust defense** | **1.0** trust gap (perfect separation) |
|
|
665
|
+
| **Graph build** | **0.28s** for 100 memories |
|
|
666
|
+
| **Search quality** | **MRR 0.90** (first result correct 9/10 times) |
|
|
613
667
|
|
|
614
|
-
|
|
668
|
+
[Full benchmark details →](https://github.com/varun369/SuperLocalMemoryV2/wiki/Performance-Benchmarks)
|
|
615
669
|
|
|
616
670
|
---
|
|
617
671
|
|
package/api_server.py
CHANGED
|
@@ -51,6 +51,53 @@ app = FastAPI(
|
|
|
51
51
|
UI_DIR.mkdir(exist_ok=True)
|
|
52
52
|
app.mount("/static", StaticFiles(directory=str(UI_DIR)), name="static")
|
|
53
53
|
|
|
54
|
+
# Rate limiting (v2.6)
|
|
55
|
+
try:
|
|
56
|
+
from rate_limiter import write_limiter, read_limiter
|
|
57
|
+
|
|
58
|
+
@app.middleware("http")
|
|
59
|
+
async def rate_limit_middleware(request, call_next):
|
|
60
|
+
client_ip = request.client.host if request.client else "unknown"
|
|
61
|
+
|
|
62
|
+
# Determine if this is a write or read endpoint
|
|
63
|
+
is_write = request.method in ("POST", "PUT", "DELETE", "PATCH")
|
|
64
|
+
limiter = write_limiter if is_write else read_limiter
|
|
65
|
+
|
|
66
|
+
allowed, remaining = limiter.is_allowed(client_ip)
|
|
67
|
+
if not allowed:
|
|
68
|
+
from fastapi.responses import JSONResponse
|
|
69
|
+
return JSONResponse(
|
|
70
|
+
status_code=429,
|
|
71
|
+
content={"error": "Too many requests. Please slow down."},
|
|
72
|
+
headers={"Retry-After": str(limiter.window)}
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
response = await call_next(request)
|
|
76
|
+
response.headers["X-RateLimit-Remaining"] = str(remaining)
|
|
77
|
+
return response
|
|
78
|
+
|
|
79
|
+
except ImportError:
|
|
80
|
+
pass # Rate limiter not available — continue without it
|
|
81
|
+
|
|
82
|
+
# Optional API key authentication (v2.6)
|
|
83
|
+
try:
|
|
84
|
+
from auth_middleware import check_api_key
|
|
85
|
+
|
|
86
|
+
@app.middleware("http")
|
|
87
|
+
async def auth_middleware(request, call_next):
|
|
88
|
+
is_write = request.method in ("POST", "PUT", "DELETE", "PATCH")
|
|
89
|
+
headers = dict(request.headers)
|
|
90
|
+
if not check_api_key(headers, is_write=is_write):
|
|
91
|
+
from fastapi.responses import JSONResponse
|
|
92
|
+
return JSONResponse(
|
|
93
|
+
status_code=401,
|
|
94
|
+
content={"error": "Invalid or missing API key. Set X-SLM-API-Key header."}
|
|
95
|
+
)
|
|
96
|
+
response = await call_next(request)
|
|
97
|
+
return response
|
|
98
|
+
except ImportError:
|
|
99
|
+
pass # Auth middleware not available
|
|
100
|
+
|
|
54
101
|
|
|
55
102
|
# ============================================================================
|
|
56
103
|
# Request/Response Models
|