Skip to content

Commit 40467c7

Browse files
committed
feat: Roast Review V5 Phase 1 - credibility leaks fixed
- Rebranded from 'production-grade' to 'production-shaped prototype' - Fixed .gitignore invalid glob (removed 'indexes,eval}') - ruff check src api tests passes (0 errors, E402 ignored for tests) - Fixed B017 (broad pytest.raises) in test_comprehensive.py - API startup: removed index loading from startup event (deferred to first query) - Health check: VectorStore instantiation wrapped in try/except, no longer crashes on missing indices - Docker: SECRET_KEY uses ${SECRET_KEY:?...} for fail-fast validation - Added 'Known Limits' section to README (7 honest limitations) - Fixed unused HTTPException import in api/main.py 163 tests passing (93 unit + 70 integration)
1 parent 7268d1e commit 40467c7

9 files changed

Lines changed: 1518 additions & 62 deletions

File tree

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,3 @@ roast_review*.md
6262

6363
# Stale files
6464
server.log
65-
"indexes,eval}"

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Cost-Aware Agentic RAG
22

3-
Production-grade Agentic RAG system for SEC 10-K Financial Document Analysis with cost-aware model routing. Uses a trained ML classifier to route queries by complexity, hybrid retrieval with RRF fusion, cross-encoder reranking, and a LangGraph-based agentic loop with self-reflection.
3+
Production-shaped Agentic RAG prototype for SEC 10-K Financial Document Analysis with cost-aware model routing. Uses a trained ML classifier to route queries by complexity, hybrid retrieval with RRF fusion, cross-encoder reranking, and a LangGraph-based agentic loop with self-reflection.
44

55
## Architecture
66

@@ -392,6 +392,16 @@ curl -X POST http://localhost:8001/query/stream \
392392
-d '{"query": "What are Tesla'\''s main risk factors?"}'
393393
```
394394

395+
## Known Limits
396+
397+
- **Cost model is approximate** — Token costs use per-million-token rates from public Ollama pricing. Actual costs may vary by deployment.
398+
- **Upload status is in-memory** — Server restart loses pending upload status. Production would use persistent queue.
399+
- **File-based auth** — Admin users and sessions stored in JSON files. Suitable for demo, not enterprise multi-tenant.
400+
- **Single-process retrieval** — No distributed search or horizontal scaling. ChromaDB and BM25 are local.
401+
- **Eval harness is offline** — Golden set has 20 entries. Online eval with production traffic not yet implemented.
402+
- **Agent loop is bounded** — Max 2 reflection iterations. No human-in-the-loop approval or tool budget enforcement.
403+
- **No persistent deployment** — Docker builds locally. No cloud deployment, load balancer, or auto-scaling.
404+
395405
## License
396406

397407
MIT

api/main.py

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
import logging
66
import sys
7+
import time
78
from pathlib import Path
89

9-
from fastapi import FastAPI, HTTPException, Request
10+
from fastapi import FastAPI, Request
1011
from fastapi.middleware.cors import CORSMiddleware
1112
from fastapi.responses import HTMLResponse
1213
from fastapi.staticfiles import StaticFiles
@@ -32,9 +33,11 @@
3233

3334
logger = logging.getLogger(__name__)
3435

36+
_startup_time = time.perf_counter()
37+
3538
app = FastAPI(
3639
title="Cost-Aware Agentic RAG",
37-
description="Production-grade RAG for SEC 10-K Financial Analysis",
40+
description="Production-shaped Agentic RAG prototype for SEC 10-K Financial Analysis",
3841
version="0.1.0",
3942
)
4043

@@ -59,17 +62,13 @@
5962

6063
@app.on_event("startup")
6164
async def startup_event():
62-
"""Initialize admin user, tracing, and load indices on startup."""
65+
"""Initialize admin user and tracing on startup.
66+
67+
Index loading is deferred to first query for fast startup.
68+
"""
6369
setup_tracing()
6470
init_admin()
65-
66-
try:
67-
from src.retrieval.hybrid import HybridRetriever
68-
retriever = HybridRetriever()
69-
retriever.load_indices()
70-
logger.info("Indices loaded successfully")
71-
except Exception as e:
72-
logger.warning(f"Could not load indices: {e}")
71+
logger.info("Startup complete in %.1fs", time.perf_counter() - _startup_time)
7372

7473
# FastAPI OTel middleware (if opentelemetry-instrumentation-fastapi is installed)
7574
try:
@@ -140,26 +139,26 @@ def cost_optimization_page(request: Request) -> HTMLResponse:
140139
# ── Health Check ─────────────────────────────────────────────────────
141140
@app.get("/health", response_model=HealthResponse)
142141
def health() -> HealthResponse:
142+
doc_count = 0
143+
if settings.raw_dir.exists():
144+
for company_dir in settings.raw_dir.iterdir():
145+
if company_dir.is_dir():
146+
for year_dir in company_dir.iterdir():
147+
if year_dir.is_dir():
148+
for _f in year_dir.glob("*.txt"):
149+
doc_count += 1
150+
151+
chunk_count = 0
143152
try:
144-
doc_count = 0
145-
if settings.raw_dir.exists():
146-
for company_dir in settings.raw_dir.iterdir():
147-
if company_dir.is_dir():
148-
for year_dir in company_dir.iterdir():
149-
if year_dir.is_dir():
150-
for _f in year_dir.glob("*.txt"):
151-
doc_count += 1
152-
153153
from src.retrieval.vector_store import VectorStore
154154
vs = VectorStore()
155155
chunk_count = vs.count()
156+
except Exception:
157+
pass
156158

157-
return HealthResponse(
158-
status="ok",
159-
document_count=doc_count,
160-
chunk_count=chunk_count,
161-
version="0.1.0",
162-
)
163-
except Exception as e:
164-
logger.error(f"Health check failed: {e}")
165-
raise HTTPException(status_code=503, detail=f"Service unavailable: {e}") from e
159+
return HealthResponse(
160+
status="ok",
161+
document_count=doc_count,
162+
chunk_count=chunk_count,
163+
version="0.1.0",
164+
)

0 commit comments

Comments
 (0)