docs: §15 orchestrator agent + §16 RAG surface (AGENTS.md + README pointers)
Browse files
AGENTS.md
CHANGED
|
@@ -305,3 +305,50 @@ deterministic template path for a fully-reproducible demo.
|
|
| 305 |
|
| 306 |
The README's YAML front-matter declares the Space metadata
|
| 307 |
(SDK=docker, port=7860, app_file=src/frontend/app.py).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
|
| 306 |
The README's YAML front-matter declares the Space metadata
|
| 307 |
(SDK=docker, port=7860, app_file=src/frontend/app.py).
|
| 308 |
+
|
| 309 |
+
## 15. Orchestrator Agent Surface
|
| 310 |
+
|
| 311 |
+
`src/agents/orchestrator.py` exposes a single-agent function-calling
|
| 312 |
+
loop over the openai SDK (no LangChain / framework dep). The agent
|
| 313 |
+
holds 4 tools, defined in `src/agents/tools.py`:
|
| 314 |
+
|
| 315 |
+
- `run_bbb_pipeline(smiles, top_k)` — wraps `POST /predict/bbb`
|
| 316 |
+
- `run_eeg_pipeline(input_path)` — wraps `POST /pipeline/eeg`
|
| 317 |
+
- `run_mri_pipeline(input_dir, sites_csv)` — wraps `POST /pipeline/mri`
|
| 318 |
+
- `retrieve_context(query, k)` — wraps `src/rag/retrieve.py`
|
| 319 |
+
|
| 320 |
+
The system prompt (`src/agents/prompts.py:ORCHESTRATOR_SYSTEM_PROMPT`)
|
| 321 |
+
locks the workflow: pick exactly one pipeline → run it → formulate a
|
| 322 |
+
focused retrieval query → call retrieve_context → synthesize a
|
| 323 |
+
3-5 sentence response that cites at least one chunk. Language of the
|
| 324 |
+
final response is mirrored from the user's question.
|
| 325 |
+
|
| 326 |
+
`POST /agent/run` is the public surface. Default model is
|
| 327 |
+
`google/gemini-2.0-flash-exp:free` on OpenRouter (function-calling
|
| 328 |
+
support verified). Override via `NEUROBRIDGE_AGENT_MODEL` env var.
|
| 329 |
+
Returns 503 when `OPENROUTER_API_KEY` is unset.
|
| 330 |
+
|
| 331 |
+
Diagnostics: `GET /diag/agent` returns key presence, configured model,
|
| 332 |
+
RAG index status (chunk count), and the registered tool names.
|
| 333 |
+
|
| 334 |
+
## 16. RAG Surface
|
| 335 |
+
|
| 336 |
+
`src/rag/` is the retrieval layer. Stack: `fastembed`
|
| 337 |
+
(`BAAI/bge-small-en-v1.5`, 384-dim, ONNX, no torch dep) for
|
| 338 |
+
embeddings + `faiss-cpu` (`IndexFlatIP` after L2-norm = cosine) for
|
| 339 |
+
vector search.
|
| 340 |
+
|
| 341 |
+
Knowledge base lives at `data/knowledge_base/` (gitignored;
|
| 342 |
+
user-supplied `.md` / `.txt` / `.pdf`). Build the FAISS index with:
|
| 343 |
+
|
| 344 |
+
python -m src.rag.ingest [<input_dir> [<output_dir>]]
|
| 345 |
+
|
| 346 |
+
Defaults: input=`data/knowledge_base/`, output=`data/processed/faiss_index/`.
|
| 347 |
+
The Dockerfile runs this at build time so deployed Spaces start with
|
| 348 |
+
a populated index. Empty KB → empty index → `retrieve_context`
|
| 349 |
+
returns 0 chunks; the agent surfaces this and answers from the
|
| 350 |
+
pipeline result alone.
|
| 351 |
+
|
| 352 |
+
`tests/fixtures/kb_sample/` ships 3 seed markdown files (Lipinski,
|
| 353 |
+
ComBat, MNE+ICA) — these double as test fixtures and as the demo
|
| 354 |
+
seed if no user-supplied PDFs are added.
|
README.md
CHANGED
|
@@ -225,6 +225,11 @@ finishes in under 4 seconds on a 2024 laptop.
|
|
| 225 |
- **New surfaces:** `POST /explain/eeg`, `POST /explain/mri`, `GET /experiments/runs`, `POST /experiments/diff`
|
| 226 |
- **New deploy artifacts:** `Dockerfile.hf`, `supervisord.conf`
|
| 227 |
- **LLM hardening (post-Day 8):** real OpenRouter LLM is now the default in deployed Spaces — `Dockerfile`/`Dockerfile.hf` no longer hard-code `NEUROBRIDGE_DISABLE_LLM=1`. Free-tier fallback chain (10 models, smartest → smallest) in [`src/llm/explainer.py`](src/llm/explainer.py), 401/400 status classification, and language-matching / intent-split prompt. Diagnostic endpoint `GET /diag/openrouter` ([`src/api/main.py`](src/api/main.py)) + Streamlit sidebar "🔧 Diagnose LLM" button. Live verification helper: [`scripts/diagnose_openrouter.py`](scripts/diagnose_openrouter.py).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
|
| 229 |
## Day 7 — Demo Recipe
|
| 230 |
|
|
|
|
| 225 |
- **New surfaces:** `POST /explain/eeg`, `POST /explain/mri`, `GET /experiments/runs`, `POST /experiments/diff`
|
| 226 |
- **New deploy artifacts:** `Dockerfile.hf`, `supervisord.conf`
|
| 227 |
- **LLM hardening (post-Day 8):** real OpenRouter LLM is now the default in deployed Spaces — `Dockerfile`/`Dockerfile.hf` no longer hard-code `NEUROBRIDGE_DISABLE_LLM=1`. Free-tier fallback chain (10 models, smartest → smallest) in [`src/llm/explainer.py`](src/llm/explainer.py), 401/400 status classification, and language-matching / intent-split prompt. Diagnostic endpoint `GET /diag/openrouter` ([`src/api/main.py`](src/api/main.py)) + Streamlit sidebar "🔧 Diagnose LLM" button. Live verification helper: [`scripts/diagnose_openrouter.py`](scripts/diagnose_openrouter.py).
|
| 228 |
+
- **Orchestrator agent (Task 13):** [`src/agents/orchestrator.py`](src/agents/orchestrator.py), [`src/agents/tools.py`](src/agents/tools.py), [`src/agents/prompts.py`](src/agents/prompts.py)
|
| 229 |
+
- **RAG layer:** [`src/rag/`](src/rag/) — chunker, embedder (fastembed), FAISS store, retriever, ingest CLI
|
| 230 |
+
- **Agent endpoint:** `POST /agent/run` (orchestrator + RAG); diagnostic at `GET /diag/agent`
|
| 231 |
+
- **Streamlit Agent tab:** "🤖 Agent" tab in [`src/frontend/app.py`](src/frontend/app.py) — input box + decision-trace expander
|
| 232 |
+
- **RAG knowledge base:** drop `.md`/`.pdf` into [`data/knowledge_base/`](data/knowledge_base/) — see its README
|
| 233 |
|
| 234 |
## Day 7 — Demo Recipe
|
| 235 |
|