mekosotto Claude Opus 4.7 (1M context) commited on
Commit
35ff61e
·
1 Parent(s): 0db04e6

docs: §15 orchestrator agent + §16 RAG surface (AGENTS.md + README pointers)

Browse files
Files changed (2) hide show
  1. AGENTS.md +47 -0
  2. README.md +5 -0
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