@pentatonic-ai/ai-agent-sdk 0.6.0 → 0.7.1

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 (92) hide show
  1. package/README.md +178 -69
  2. package/bin/__tests__/callback-server.test.js +4 -1
  3. package/bin/cli.js +41 -164
  4. package/bin/commands/config.js +251 -0
  5. package/bin/commands/login.js +10 -3
  6. package/package.json +2 -1
  7. package/packages/doctor/__tests__/detect.test.js +2 -6
  8. package/packages/doctor/src/checks/local-memory.js +164 -196
  9. package/packages/doctor/src/detect.js +11 -3
  10. package/packages/memory/src/corpus/adapters.js +104 -0
  11. package/packages/memory/src/corpus/cli.js +72 -7
  12. package/packages/memory/src/corpus/index.js +1 -1
  13. package/packages/memory-engine/.env.example +13 -0
  14. package/packages/memory-engine/README.md +131 -0
  15. package/packages/memory-engine/bench/README.md +99 -0
  16. package/packages/memory-engine/bench/scorecards-engine/agent-coding__pentatonic-baseline__20260427-142523.json +1115 -0
  17. package/packages/memory-engine/bench/scorecards-engine/chat-recall__pentatonic-baseline__20260427-142648.json +819 -0
  18. package/packages/memory-engine/bench/scorecards-engine/circular-economy__pentatonic-baseline__20260427-142757.json +1278 -0
  19. package/packages/memory-engine/bench/scorecards-engine/customer-support__pentatonic-baseline__20260427-142900.json +1018 -0
  20. package/packages/memory-engine/bench/scorecards-engine/marketplace-ops__pentatonic-baseline__20260427-142957.json +1038 -0
  21. package/packages/memory-engine/bench/scorecards-engine/product-catalogue__pentatonic-baseline__20260427-143122.json +961 -0
  22. package/packages/memory-engine/bench/scorecards-engine-via-docker/agent-coding__pentatonic-memory__20260427-161812.json +1115 -0
  23. package/packages/memory-engine/bench/scorecards-engine-via-docker/chat-recall__pentatonic-memory__20260427-161701.json +819 -0
  24. package/packages/memory-engine/bench/scorecards-engine-via-docker/circular-economy__pentatonic-memory__20260427-161713.json +1278 -0
  25. package/packages/memory-engine/bench/scorecards-engine-via-docker/customer-support__pentatonic-memory__20260427-161723.json +1018 -0
  26. package/packages/memory-engine/bench/scorecards-engine-via-docker/marketplace-ops__pentatonic-memory__20260427-161732.json +1038 -0
  27. package/packages/memory-engine/bench/scorecards-engine-via-docker/product-catalogue__pentatonic-memory__20260427-161741.json +937 -0
  28. package/packages/memory-engine/bench/scorecards-engine-via-l2-7-layer-populated/agent-coding__pentatonic-memory__20260427-184718.json +1115 -0
  29. package/packages/memory-engine/bench/scorecards-engine-via-l2-7-layer-populated/chat-recall__pentatonic-memory__20260427-184614.json +819 -0
  30. package/packages/memory-engine/bench/scorecards-engine-via-l2-7-layer-populated/circular-economy__pentatonic-memory__20260427-184809.json +1278 -0
  31. package/packages/memory-engine/bench/scorecards-engine-via-l2-7-layer-populated/customer-support__pentatonic-memory__20260427-184854.json +1018 -0
  32. package/packages/memory-engine/bench/scorecards-engine-via-l2-7-layer-populated/marketplace-ops__pentatonic-memory__20260427-184929.json +1038 -0
  33. package/packages/memory-engine/bench/scorecards-engine-via-l2-7-layer-populated/product-catalogue__pentatonic-memory__20260427-185015.json +961 -0
  34. package/packages/memory-engine/bench/scorecards-engine-via-l2-empty-layers/agent-coding__pentatonic-memory__20260427-175252.json +1115 -0
  35. package/packages/memory-engine/bench/scorecards-engine-via-l2-empty-layers/chat-recall__pentatonic-memory__20260427-175312.json +819 -0
  36. package/packages/memory-engine/bench/scorecards-engine-via-l2-empty-layers/circular-economy__pentatonic-memory__20260427-175335.json +1278 -0
  37. package/packages/memory-engine/bench/scorecards-engine-via-l2-empty-layers/customer-support__pentatonic-memory__20260427-175355.json +1018 -0
  38. package/packages/memory-engine/bench/scorecards-engine-via-l2-empty-layers/marketplace-ops__pentatonic-memory__20260427-175413.json +1038 -0
  39. package/packages/memory-engine/bench/scorecards-engine-via-l2-empty-layers/product-catalogue__pentatonic-memory__20260427-175430.json +883 -0
  40. package/packages/memory-engine/bench/scorecards-engine-via-shim/agent-coding__pentatonic-memory__20260427-155409.json +1115 -0
  41. package/packages/memory-engine/bench/scorecards-engine-via-shim/chat-recall__pentatonic-memory__20260427-155421.json +819 -0
  42. package/packages/memory-engine/bench/scorecards-engine-via-shim/circular-economy__pentatonic-memory__20260427-155433.json +1278 -0
  43. package/packages/memory-engine/bench/scorecards-engine-via-shim/customer-support__pentatonic-memory__20260427-155443.json +1018 -0
  44. package/packages/memory-engine/bench/scorecards-engine-via-shim/marketplace-ops__pentatonic-memory__20260427-155453.json +1038 -0
  45. package/packages/memory-engine/bench/scorecards-engine-via-shim/product-catalogue__pentatonic-memory__20260427-155503.json +937 -0
  46. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/agent-coding__pentatonic-memory-latest__20260427-145103.json +1115 -0
  47. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/agent-coding__pentatonic-memory__20260427-144909.json +1115 -0
  48. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/chat-recall__pentatonic-memory-latest__20260427-145153.json +819 -0
  49. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/chat-recall__pentatonic-memory__20260427-145120.json +542 -0
  50. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/circular-economy__pentatonic-memory-latest__20260427-145313.json +1278 -0
  51. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/circular-economy__pentatonic-memory__20260427-145207.json +894 -0
  52. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/customer-support__pentatonic-memory-latest__20260427-145412.json +1018 -0
  53. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/customer-support__pentatonic-memory__20260427-145327.json +680 -0
  54. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/marketplace-ops__pentatonic-memory-latest__20260427-145517.json +1038 -0
  55. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/marketplace-ops__pentatonic-memory__20260427-145422.json +693 -0
  56. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/product-catalogue__pentatonic-memory-latest__20260427-145616.json +961 -0
  57. package/packages/memory-engine/bench/scorecards-pentatonic-baseline/product-catalogue__pentatonic-memory__20260427-145528.json +727 -0
  58. package/packages/memory-engine/compat/Dockerfile +11 -0
  59. package/packages/memory-engine/compat/server.py +680 -0
  60. package/packages/memory-engine/docker-compose.yml +243 -0
  61. package/packages/memory-engine/engine/README.md +52 -0
  62. package/packages/memory-engine/engine/l2-hybridrag-proxy.py +1543 -0
  63. package/packages/memory-engine/engine/l5-comms-layer.py +663 -0
  64. package/packages/memory-engine/engine/l6-document-store.py +1018 -0
  65. package/packages/memory-engine/engine/services/l2/Dockerfile +41 -0
  66. package/packages/memory-engine/engine/services/l2/init_databases.py +81 -0
  67. package/packages/memory-engine/engine/services/l2/l2-hybridrag-proxy.py +1543 -0
  68. package/packages/memory-engine/engine/services/l4/Dockerfile +15 -0
  69. package/packages/memory-engine/engine/services/l4/server.py +265 -0
  70. package/packages/memory-engine/engine/services/l5/Dockerfile +9 -0
  71. package/packages/memory-engine/engine/services/l5/l5-comms-layer.py +696 -0
  72. package/packages/memory-engine/engine/services/l6/Dockerfile +11 -0
  73. package/packages/memory-engine/engine/services/l6/l6-document-store.py +1035 -0
  74. package/packages/memory-engine/engine/services/nv-embed/Dockerfile +28 -0
  75. package/packages/memory-engine/engine/services/nv-embed/server.py +152 -0
  76. package/packages/memory-engine/pme_memory/__init__.py +0 -0
  77. package/packages/memory-engine/pme_memory/__main__.py +129 -0
  78. package/packages/memory-engine/pme_memory/artifacts.py +95 -0
  79. package/packages/memory-engine/pme_memory/embed.py +74 -0
  80. package/packages/memory-engine/pme_memory/health.py +36 -0
  81. package/packages/memory-engine/pme_memory/hygiene.py +159 -0
  82. package/packages/memory-engine/pme_memory/indexer.py +200 -0
  83. package/packages/memory-engine/pme_memory/needs.py +55 -0
  84. package/packages/memory-engine/pme_memory/provenance.py +80 -0
  85. package/packages/memory-engine/pme_memory/scoring.py +168 -0
  86. package/packages/memory-engine/pme_memory/search.py +52 -0
  87. package/packages/memory-engine/pme_memory/store.py +86 -0
  88. package/packages/memory-engine/pme_memory/synthesis.py +114 -0
  89. package/packages/memory-engine/pyproject.toml +65 -0
  90. package/packages/memory-engine/scripts/kg-extractor.py +557 -0
  91. package/packages/memory-engine/scripts/kg-preflexor-v2.py +738 -0
  92. package/packages/memory-engine/tests/test_api_contract.sh +57 -0
@@ -0,0 +1,243 @@
1
+ name: pentatonic-memory-engine
2
+
3
+ # pentatonic-memory-engine v0.1
4
+ #
5
+ # Drop-in HTTP-compatible replacement for `pentatonic-memory` v0.5,
6
+ # backed by the 7-layer hybrid retrieval engine.
7
+ #
8
+ # Bring up: docker compose up -d
9
+ # API surface: http://localhost:8099 (matches pentatonic-memory v0.5)
10
+ # Health: curl http://localhost:8099/health
11
+ #
12
+ # Layers:
13
+ # l0 (in-process) — BM25 over SQLite FTS5 (inside L2 + L6)
14
+ # l1 (in-process) — Always-loaded core files (inside L2)
15
+ # l2 :8031 — HybridRAG proxy (RRF fusion)
16
+ # l3 :7474 — Knowledge Graph (Neo4j Community)
17
+ # l4 :8042 — sqlite-vec vector index
18
+ # l5 :8034 — Milvus comms layer
19
+ # l6 :8037 — Document store + cross-encoder reranker
20
+ # compat :8099 — pentatonic-memory v0.5 API translation shim
21
+ #
22
+ # nv-embed :8041 — NV-Embed-v2 4096d embedding service
23
+ #
24
+ # The nv-embed service requires a GPU. If running without GPU,
25
+ # override NV_EMBED_URL to point at an external embedding endpoint:
26
+ # - OpenAI's /v1/embeddings (text-embedding-3-large)
27
+ # - the Pentatonic AI Gateway
28
+ # - any OpenAI-compat embedding endpoint
29
+
30
+ x-engine-base: &engine-base
31
+ restart: unless-stopped
32
+ networks:
33
+ - engine-net
34
+
35
+ services:
36
+ # --------------------------------------------------------------------
37
+ # NV-Embed-v2 — 4096-dim embedding service (GPU required)
38
+ # --------------------------------------------------------------------
39
+ nv-embed:
40
+ <<: *engine-base
41
+ build:
42
+ context: ./engine/services/nv-embed
43
+ dockerfile: Dockerfile
44
+ container_name: pme-nv-embed
45
+ ports: ["127.0.0.1:${PME_NV_EMBED_PORT:-8041}:8041"]
46
+ volumes:
47
+ - pme-nv-embed-cache:/cache
48
+ deploy:
49
+ resources:
50
+ reservations:
51
+ devices:
52
+ - driver: nvidia
53
+ count: 1
54
+ capabilities: [gpu]
55
+ healthcheck:
56
+ test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8041/health',timeout=3)"]
57
+ interval: 15s
58
+ timeout: 10s
59
+ retries: 20
60
+ start_period: 120s
61
+
62
+ # --------------------------------------------------------------------
63
+ # L3 — Knowledge Graph (Neo4j Community)
64
+ # --------------------------------------------------------------------
65
+ l3:
66
+ <<: *engine-base
67
+ image: neo4j:5-community
68
+ container_name: pme-l3
69
+ ports:
70
+ - "127.0.0.1:${PME_L3_HTTP_PORT:-7475}:7474" # HTTP browser
71
+ - "127.0.0.1:${PME_L3_BOLT_PORT:-7688}:7687" # bolt protocol
72
+ environment:
73
+ NEO4J_AUTH: ${NEO4J_AUTH:-neo4j/local-dev-pw}
74
+ NEO4J_PLUGINS: '["apoc"]'
75
+ NEO4J_dbms_memory_heap_max__size: 512m
76
+ volumes:
77
+ - pme-l3-data:/data
78
+ healthcheck:
79
+ test: ["CMD-SHELL", "wget -qO- http://localhost:7474 >/dev/null 2>&1 || exit 1"]
80
+ interval: 10s
81
+ timeout: 5s
82
+ retries: 30
83
+ start_period: 30s
84
+
85
+ # --------------------------------------------------------------------
86
+ # L4 — sqlite-vec sidecar
87
+ # --------------------------------------------------------------------
88
+ l4:
89
+ <<: *engine-base
90
+ build:
91
+ context: ./engine/services/l4
92
+ dockerfile: Dockerfile
93
+ container_name: pme-l4
94
+ # Default 18042 to avoid port collisions on 8042.
95
+ # Override via PME_L4_PORT for bench setups that intentionally replace it.
96
+ ports: ["127.0.0.1:${PME_L4_PORT:-18042}:8042"]
97
+ environment:
98
+ L4_NV_EMBED_URL: ${NV_EMBED_URL:-http://host.docker.internal:8041/v1/embeddings}
99
+ L4_EMBED_MODEL: ${EMBED_MODEL_NAME:-nv-embed-v2}
100
+ L4_EMBED_API_KEY: ${EMBED_API_KEY:-}
101
+ L4_EMBED_DIM: ${EMBED_DIM:-4096}
102
+ L4_DB_PATH: /data/vec.db
103
+ extra_hosts:
104
+ - "host.docker.internal:host-gateway"
105
+ volumes:
106
+ - pme-l4-data:/data
107
+ healthcheck:
108
+ test: ["CMD", "python", "-c", "import urllib.request,sys; urllib.request.urlopen('http://localhost:8042/health',timeout=3)"]
109
+ interval: 10s
110
+ timeout: 5s
111
+ retries: 30
112
+
113
+ # --------------------------------------------------------------------
114
+ # L5 — Qdrant comms layer
115
+ # --------------------------------------------------------------------
116
+ l5:
117
+ <<: *engine-base
118
+ build:
119
+ context: ./engine/services/l5
120
+ dockerfile: Dockerfile
121
+ container_name: pme-l5
122
+ # Default 18034 to avoid port collisions on 8034.
123
+ # Override via PME_L5_PORT for bench setups that intentionally replace it.
124
+ ports: ["127.0.0.1:${PME_L5_PORT:-18034}:8034"]
125
+ environment:
126
+ L5_NV_EMBED_URL: ${NV_EMBED_URL:-http://host.docker.internal:8041/v1/embeddings}
127
+ L5_EMBED_MODEL: ${EMBED_MODEL_NAME:-nv-embed-v2}
128
+ L5_EMBED_API_KEY: ${EMBED_API_KEY:-}
129
+ L5_EMBED_DIM: ${EMBED_DIM:-4096}
130
+ L5_OLLAMA_DIM: ${OLLAMA_DIM:-768}
131
+ L5_OLLAMA_EMBED_URL: ${L5_OLLAMA_EMBED_URL:-http://host.docker.internal:11434/api/embed}
132
+ L5_OLLAMA_EMBED_MODEL: ${L5_OLLAMA_EMBED_MODEL:-nomic-embed-text}
133
+ L5_DB_PATH: /data/comms.db
134
+ PME_WORKSPACE: /data/workspace
135
+ extra_hosts:
136
+ - "host.docker.internal:host-gateway"
137
+ volumes:
138
+ - pme-l5-data:/data
139
+
140
+ # --------------------------------------------------------------------
141
+ # L6 — Document store + cross-encoder reranker
142
+ # --------------------------------------------------------------------
143
+ l6:
144
+ <<: *engine-base
145
+ build:
146
+ context: ./engine/services/l6
147
+ dockerfile: Dockerfile
148
+ container_name: pme-l6
149
+ # Default 18037 to avoid colliding with Spark Core L6 doc-store on 8037.
150
+ # Override via PME_L6_PORT for bench setups that intentionally replace it.
151
+ ports: ["127.0.0.1:${PME_L6_PORT:-18037}:8037"]
152
+ environment:
153
+ L6_NV_EMBED_URL: ${NV_EMBED_URL:-http://host.docker.internal:8041/v1/embeddings}
154
+ L6_EMBED_MODEL: ${EMBED_MODEL_NAME:-nv-embed-v2}
155
+ L6_EMBED_API_KEY: ${EMBED_API_KEY:-}
156
+ L6_EMBED_DIM: ${EMBED_DIM:-4096}
157
+ L6_DATA_DIR: /data
158
+ extra_hosts:
159
+ - "host.docker.internal:host-gateway"
160
+ volumes:
161
+ - pme-l6-data:/data
162
+
163
+ # --------------------------------------------------------------------
164
+ # L2 — HybridRAG orchestrator (RRF fusion across all layers)
165
+ # --------------------------------------------------------------------
166
+ l2:
167
+ <<: *engine-base
168
+ build:
169
+ context: ./engine/services/l2
170
+ dockerfile: Dockerfile
171
+ container_name: pme-l2
172
+ ports: ["127.0.0.1:${PME_L2_PORT:-8131}:8031"]
173
+ environment:
174
+ PME_NV_EMBED_URL: ${NV_EMBED_URL:-http://host.docker.internal:8041/v1/embeddings}
175
+ PME_NEO4J_URI: bolt://l3:7687
176
+ PME_NEO4J_PASSWORD: ${NEO4J_PASSWORD:-local-dev-pw}
177
+ NEO4J_PASSWORD: ${NEO4J_PASSWORD:-local-dev-pw}
178
+ PME_L5_URL: http://l5:8034
179
+ PME_L6_URL: http://l6:8037
180
+ # HyDE off (deliberate — hurts precision on retrieval-graded benches)
181
+ PME_HYDE_ENABLED: "false"
182
+ # Cross-encoder reranker on (boosts top-K precision)
183
+ PME_RERANK_ENABLED: "true"
184
+ PME_WORKSPACE: /data/workspace
185
+ PME_QMD_DB: /data/qmd.sqlite
186
+ PME_MEMORY_DB: /data/workspace.db
187
+ extra_hosts:
188
+ - "host.docker.internal:host-gateway"
189
+ volumes:
190
+ - pme-l2-data:/data
191
+ depends_on:
192
+ l3: { condition: service_healthy }
193
+ l5: { condition: service_started }
194
+ l6: { condition: service_started }
195
+
196
+ # --------------------------------------------------------------------
197
+ # Compat shim — exposes pentatonic-memory v0.5 API on :8099
198
+ #
199
+ # Now routes /search through the L2 7-layer proxy by default. L6-only
200
+ # bypass (BYPASS_L2_PROXY=1) is still available for isolated testing.
201
+ # --------------------------------------------------------------------
202
+ compat:
203
+ <<: *engine-base
204
+ build:
205
+ context: ./compat
206
+ dockerfile: Dockerfile
207
+ container_name: pme-compat
208
+ ports:
209
+ - "127.0.0.1:${PME_PORT:-8099}:8099"
210
+ environment:
211
+ L0_URL: http://l2:8031
212
+ L2_PROXY_URL: http://l2:8031
213
+ L3_KG_URL: http://l3:7474
214
+ L4_VEC_URL: http://l4:8042
215
+ L5_MILVUS_URL: http://l5:8034
216
+ L6_DOC_URL: http://l6:8037
217
+ NV_EMBED_URL: ${NV_EMBED_URL:-http://host.docker.internal:8041/v1/embeddings}
218
+ CLIENT_ID: ${CLIENT_ID:-default}
219
+ BYPASS_L2_PROXY: ${BYPASS_L2_PROXY:-0}
220
+ extra_hosts:
221
+ - "host.docker.internal:host-gateway"
222
+ depends_on:
223
+ l2: { condition: service_started }
224
+ l4: { condition: service_started }
225
+ l5: { condition: service_started }
226
+ l6: { condition: service_started }
227
+ healthcheck:
228
+ test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8099/health',timeout=3)"]
229
+ interval: 10s
230
+ timeout: 5s
231
+ retries: 30
232
+ start_period: 60s
233
+
234
+ networks:
235
+ engine-net:
236
+
237
+ volumes:
238
+ pme-nv-embed-cache:
239
+ pme-l2-data:
240
+ pme-l3-data:
241
+ pme-l4-data:
242
+ pme-l5-data:
243
+ pme-l6-data:
@@ -0,0 +1,52 @@
1
+ # engine/
2
+
3
+ Bundled engine layers for the Pentatonic Memory Engine.
4
+
5
+ | File | Layer | LOC | Purpose |
6
+ |---|---|---|---|
7
+ | `l2-hybridrag-proxy.py` | L2 | ~1.5k | RRF fusion across all layers, exposed on `:8031` |
8
+ | `l5-comms-layer.py` | L5 | ~0.7k | Milvus comms layer for chat/email/contact/memory collections, exposed on `:8034` |
9
+ | `l6-document-store.py` | L6 | ~1.5k | Document store + cross-encoder reranker, exposed on `:8037` |
10
+ | `services/nv-embed/server.py` | — | ~150 | NV-Embed-v2 4096-dim embedding service, exposed on `:8041` |
11
+
12
+ ## pme_memory SDK
13
+
14
+ The `pme_memory/` package at the repo root is an installable Python SDK for the L5 communications layer. It provides:
15
+
16
+ - **store.py** — Milvus client and collection management (chats, emails, contacts, memory)
17
+ - **search.py** — Semantic search across collections
18
+ - **embed.py** — Dual-stack embedding (NV-Embed-v2 primary, Ollama fallback)
19
+ - **indexer.py** — Data ingestion pipeline (JSONL chats, email archives, contacts, memory files)
20
+ - **scoring.py** — Pressure scoring for need signals (recency, novelty, centrality, priority)
21
+ - **synthesis.py** — Deterministic multi-parent artifact merge
22
+ - **artifacts.py** — Append-only artifact DAG store (JSONL)
23
+ - **hygiene.py** — DAG maintenance (dedup, conflict detection, orphan pruning)
24
+ - **health.py** — L5 health check
25
+ - **needs.py** — Need signal indexing
26
+ - **provenance.py** — Lineage visualization
27
+
28
+ Install: `pip install -e ".[full]"` — CLI: `pme-memory health|stats|index|search|serve`
29
+
30
+ ## KG Extraction Scripts
31
+
32
+ The `scripts/` directory contains Knowledge Graph population tools:
33
+
34
+ - **kg-extractor.py** — spaCy + regex entity/relationship extraction from memory files → Neo4j
35
+ - **kg-preflexor-v2.py** — 2-pass concurrent LLM-based extraction via Ollama (14 structured entity types + native graph discovery)
36
+
37
+ ## Where L0, L3 and the embedding service live
38
+
39
+ - **L0 BM25** — provided by SQLite FTS5; the L2 proxy queries it directly via `sqlite3`. No separate service binary.
40
+ - **L3 Knowledge Graph** — provided by Neo4j Community (free, OSS) running in a sibling container. The proxy queries it via the bolt protocol on `:7687`.
41
+ - **NV-Embed-v2 embedding service** — see `services/nv-embed/` for the Docker context. Exposes the OpenAI-compatible `/v1/embeddings` endpoint on `:8041`.
42
+
43
+ ## Dependencies
44
+
45
+ Each service has its own `requirements.txt` in `services/<layer>/`. Common heavy deps:
46
+
47
+ - `pymilvus>=2.6.12` (L5)
48
+ - `sentence-transformers` (L6 reranker, NV-Embed)
49
+ - `httpx`, `fastapi`, `uvicorn` (all)
50
+ - `spacy` (L6 entity extraction)
51
+
52
+ NV-Embed needs Torch + the model weights (auto-downloaded on first run from Hugging Face).