rajvivan commited on
Commit
0fe12d6
Β·
verified Β·
1 Parent(s): 19203c7

docs: add architecture flow and change safety contract

Browse files
Files changed (2) hide show
  1. PRESERVE_EXISTING_FUNCTIONALITY.md +112 -0
  2. README.md +37 -44
PRESERVE_EXISTING_FUNCTIONALITY.md ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Preserve Existing Functionality
2
+
3
+ This file is the change-safety contract for IRIS FINBOT. Read it before making any new code, deployment, workflow, or UI changes.
4
+
5
+ ## Goal
6
+
7
+ New changes must not overwrite saved Hugging Face deployment fixes, break the cache-backed backend fallback, remove page screenshot assets, or regress existing user workflows.
8
+
9
+ ## Protected Runtime Behavior
10
+
11
+ 1. Browser requests must use relative `/api/proxy/*` URLs.
12
+ 2. The browser must never call `localhost:8000` or `127.0.0.1:8000` directly.
13
+ 3. `/api/proxy/api/health` must return `200` even when the FastAPI process is warming up or unavailable.
14
+ 4. `/api/proxy/api/chat/query` must return cached IR answers for supported financial questions when FastAPI is unavailable.
15
+ 5. `/api/proxy/api/documents` must return indexed document metadata from local cache when FastAPI is unavailable.
16
+ 6. `/api/proxy/api/visuals/<doc_id>/<page>` must return exact PDF page screenshots from `backend/data/pages`.
17
+ 7. Legacy `/pages/<doc_id>/pages/<image>.png` links must continue to work through the Next.js proxy.
18
+ 8. `docker-entrypoint.sh` must keep the FastAPI backend in a restart loop and keep the public Next.js server alive.
19
+ 9. Hugging Face sync must not overwrite HF-specific `Dockerfile`, `docker-entrypoint.sh`, or `README.md` from GitHub automation.
20
+
21
+ ## Protected Files
22
+
23
+ Treat these files as high-risk. Do not edit them casually, and never replace them wholesale without checking the behavior above.
24
+
25
+ - `src/app/api/proxy/[...path]/route.ts`
26
+ - `src/lib/api.ts`
27
+ - `docker-entrypoint.sh`
28
+ - `Dockerfile`
29
+ - `next.config.ts`
30
+ - `sync-to-hf.sh`
31
+ - `.github/workflows/sync-to-hf.yml`
32
+ - `backend/lightweight_server.py`
33
+ - `backend/data/response_cache/**`
34
+ - `backend/data/pages/**`
35
+ - `README.md`
36
+
37
+ ## Required Checks Before Pushing
38
+
39
+ Run these checks after any change touching runtime, API, deployment, evidence, or navigation:
40
+
41
+ ```bash
42
+ npm run build
43
+ npx eslint 'src/app/api/proxy/[...path]/route.ts' src/lib/api.ts src/components/layout/ResponseWorkspace.tsx
44
+ bash -n docker-entrypoint.sh sync-to-hf.sh
45
+ ```
46
+
47
+ For backend-fallback changes, also run a forced fallback smoke test by starting Next.js with an unreachable backend:
48
+
49
+ ```bash
50
+ PORT=4012 HOSTNAME=127.0.0.1 BACKEND_INTERNAL_URL=http://127.0.0.1:65531 node .next/standalone/server.js
51
+ ```
52
+
53
+ Then verify:
54
+
55
+ ```bash
56
+ curl -s http://127.0.0.1:4012/api/proxy/api/health
57
+ curl -s http://127.0.0.1:4012/api/proxy/api/documents
58
+ curl -s -H 'Content-Type: application/json' \
59
+ -d '{"question":"What was the total profit in Q1 2026?","doc_ids":["emiratesnbd_investor_presentation_2026_q1"]}' \
60
+ http://127.0.0.1:4012/api/proxy/api/chat/query
61
+ curl -I http://127.0.0.1:4012/api/proxy/api/visuals/emiratesnbd_investor_presentation_2026_q1/1
62
+ curl -I http://127.0.0.1:4012/pages/emiratesnbd_investor_presentation_2026_q1/pages/page_0001_colpali.png
63
+ ```
64
+
65
+ Expected result:
66
+
67
+ - health: `200`
68
+ - documents: `200`
69
+ - chat: `200` with `response_type: "ir_response"` for supported cached questions
70
+ - visual image: `200 image/png`
71
+ - legacy page image: `200 image/png`
72
+
73
+ ## Change Rules
74
+
75
+ 1. Keep edits narrow and local to the requested behavior.
76
+ 2. Do not remove fallback logic just because FastAPI works locally.
77
+ 3. Do not remove cache files or screenshot folders from HF uploads.
78
+ 4. Do not reintroduce plain Git force-push for HF syncs that include PNG files; use `hf upload`.
79
+ 5. Do not change `NEXT_PUBLIC_BACKEND_URL` to a direct backend URL for production.
80
+ 6. Do not show user-facing "Backend not detected" or "Demo Mode" messages when the cache-backed proxy is working.
81
+ 7. Do not change response schemas without updating both FastAPI and Next.js fallback responses.
82
+ 8. Do not alter document/page URL formats without preserving legacy normalization.
83
+ 9. If a workflow syncs GitHub to HF, keep HF-specific deployment files excluded unless the sync path intentionally owns them.
84
+
85
+ ## HF Deployment Notes
86
+
87
+ Use targeted uploads for small fixes:
88
+
89
+ ```bash
90
+ hf upload rajvivan/iris-ir-platform <local_file> <repo_file> --repo-type space
91
+ ```
92
+
93
+ Use `./sync-to-hf.sh` only when syncing the full HF-ready bundle. The script uses `hf upload` to avoid binary screenshot push failures.
94
+
95
+ After pushing, verify:
96
+
97
+ ```bash
98
+ curl -s https://huggingface.co/api/spaces/rajvivan/iris-ir-platform
99
+ curl -L -s -o /tmp/hf-home.html -w '%{http_code}\n' https://rajvivan-iris-ir-platform.hf.space/
100
+ curl -L -s https://rajvivan-iris-ir-platform.hf.space/api/proxy/api/health
101
+ ```
102
+
103
+ ## Review Checklist
104
+
105
+ Before accepting any future change, confirm:
106
+
107
+ - Existing chat questions still produce `ir_response` where cache coverage exists.
108
+ - Source footnotes still open the correct page.
109
+ - Screen popup still opens as a full-screen overlay.
110
+ - Page screenshots still load in HF.
111
+ - Guardrail cards still render unsupported and insufficient states correctly.
112
+ - HF runtime status is `RUNNING` after rebuild.
README.md CHANGED
@@ -7,8 +7,6 @@ sdk: docker
7
  pinned: false
8
  short_description: Multimodal RAG platform for financial document intelligence
9
  thumbnail: https://huggingface.co/spaces/rajvivan/iris-ir-platform/resolve/main/screenshot.png
10
- app_port: 7860
11
- startup_duration_timeout: 1h
12
  ---
13
 
14
  # IRIS β€” Investor Relations Intelligence System
@@ -31,46 +29,36 @@ IRIS is a state-of-the-art, fully local, multimodal Retrieval-Augmented Generati
31
 
32
  ## πŸ›οΈ System Architecture
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  ```
35
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
36
- β”‚ Next.js Frontend / HF Web Server (3000/7860) β”‚
37
- β”‚ Chat UI Β· PDF Viewer Β· KPI Cards Β· Visual Evidence β”‚
38
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
39
- β”‚ /api/proxy/*
40
- β–Ό
41
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
42
- β”‚ Resilient Next.js API Proxy β”‚
43
- β”‚ β”‚
44
- β”‚ 1. Try internal FastAPI at BACKEND_INTERNAL_URL / localhost:8000 β”‚
45
- β”‚ 2. If unavailable, serve the same API from checked-in cache files β”‚
46
- β”‚ 3. Keep /api/health green so office networks do not block usage β”‚
47
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
48
- β”‚ internal container call
49
- β–Ό
50
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
51
- β”‚ FastAPI Backend (Port 8000) β”‚
52
- β”‚ β”‚
53
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Response Pipeline ─────────────────────────┐ β”‚
54
- β”‚ β”‚ β”‚ β”‚
55
- β”‚ β”‚ Layer 1 Β· Smart Engine ~1–50ms βœ… ANY trained PDF β”‚ β”‚
56
- β”‚ β”‚ β”œβ”€β”€ IntentClassifier detect financial intent β”‚ β”‚
57
- β”‚ β”‚ β”œβ”€β”€ KPIContextBuilder load verified KPIs from ground truth β”‚ β”‚
58
- β”‚ β”‚ └── SmartResponseEngine fill template / load cached response β”‚ β”‚
59
- β”‚ β”‚ β”‚ β”‚
60
- β”‚ β”‚ Layer 2 Β· Static Cache ~10ms (Emirates NBD fallbackβ”‚ β”‚
61
- β”‚ β”‚ β”‚ β”‚
62
- β”‚ β”‚ Layer 3 Β· Ollama RAG Pipeline ~30–120s (unknown questions) β”‚ β”‚
63
- β”‚ β”‚ β”œβ”€β”€ HybridRetriever (Text + Table + ColPali) β”‚ β”‚
64
- β”‚ β”‚ └── FinancialAnalystAgent (Ollama generation) β”‚ β”‚
65
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
66
- β”‚ β”‚
67
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Retrieval Legs (Hybrid RRF Fusion) ────────────────┐ β”‚
68
- β”‚ β”‚ Dense Text β”‚ Structured Tables β”‚ ColPali Visual (MaxSim) β”‚ β”‚
69
- β”‚ β”‚ ChromaDB β”‚ tables.json index β”‚ Page patch embeddings β”‚ β”‚
70
- β”‚ β”‚ BGE Embeds β”‚ Keyword + metadata β”‚ PaliGemma vision model β”‚ β”‚
71
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
72
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
73
- ```
74
 
75
  ---
76
 
@@ -93,6 +81,12 @@ This means office networks only need to reach the single Hugging Face HTTPS URL.
93
 
94
  ---
95
 
 
 
 
 
 
 
96
  ## ⚑ Smart Response Optimizer (New)
97
 
98
  The core performance innovation. All common financial questions are handled before any LLM inference:
@@ -301,9 +295,8 @@ The 9-step training pipeline runs:
301
  5. Generate training pairs & calibrate retrieval weights
302
  6. (Optional) Fine-tune embedding model
303
  7. Embed & index chunks in ChromaDB
304
- 8. Index tables with enriched metadata
305
- 9. **[8b] Auto-generate smart response cache** ← all intent templates pre-filled
306
- 10. Render pages + ColPali visual indexing
307
 
308
  After training, all supported financial intents are instantly cached for the new document. First question β†’ template generation (<10ms). Subsequent questions β†’ cache hit (<5ms).
309
 
 
7
  pinned: false
8
  short_description: Multimodal RAG platform for financial document intelligence
9
  thumbnail: https://huggingface.co/spaces/rajvivan/iris-ir-platform/resolve/main/screenshot.png
 
 
10
  ---
11
 
12
  # IRIS β€” Investor Relations Intelligence System
 
29
 
30
  ## πŸ›οΈ System Architecture
31
 
32
+ ```mermaid
33
+ flowchart TD
34
+ S1["1. User opens HF Space or local app"]
35
+ S2["2. Next.js UI renders chat, document viewer, KPI cards, and evidence panels"]
36
+ S3["3. Browser calls relative API routes under /api/proxy/*"]
37
+ S4["4. Next.js proxy checks internal FastAPI at BACKEND_INTERNAL_URL, default 127.0.0.1:8000"]
38
+ S5{"5. Is FastAPI live?"}
39
+ S6["6A. Live path: FastAPI receives /api/health, /api/documents, /api/chat/query, /api/visuals/*"]
40
+ S7["6B. Fallback path: Next.js serves the same API from backend/data cache and page screenshots"]
41
+ S8["7. Guardrail and intent detection classify unsupported, insufficient, or IR financial query"]
42
+ S9["8. Retrieval/answer layer loads verified KPI cache, response_cache JSON, tables, and exact page images"]
43
+ S10["9. UI returns grounded answer with executive summary, KPI rows, key drivers, source footnotes, and visual evidence"]
44
+
45
+ S1 --> S2 --> S3 --> S4 --> S5
46
+ S5 -- yes --> S6 --> S8
47
+ S5 -- "no / warming / restarting" --> S7 --> S8
48
+ S8 --> S9 --> S10
49
  ```
50
+
51
+ ### 9-Step Runtime Flow
52
+
53
+ 1. User opens the Hugging Face Space or local app.
54
+ 2. Next.js renders the chat workspace, document panels, source viewer, and evidence cards.
55
+ 3. The browser calls only relative `/api/proxy/*` routes, so office networks never need direct access to `localhost:8000`.
56
+ 4. The Next.js proxy tries the private in-container FastAPI backend at `BACKEND_INTERNAL_URL`, defaulting to `http://127.0.0.1:8000`.
57
+ 5. If FastAPI is live, requests are streamed through to the backend.
58
+ 6. If FastAPI is warming, blocked, or restarting, Next.js serves the same public API contract from checked-in cache files under `backend/data`.
59
+ 7. Domain guardrails and intent detection decide whether the query is unsupported, insufficient, or a valid Investor Relations financial question.
60
+ 8. The answer layer loads verified KPI data, precomputed `response_cache` JSON, source metadata, and exact PDF page screenshots.
61
+ 9. The UI returns an evidence-grounded response with executive summary, KPI rows, key drivers, source footnotes, and visual evidence.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
  ---
64
 
 
81
 
82
  ---
83
 
84
+ ## Change Safety Contract
85
+
86
+ Before changing runtime, sync, proxy, cache, or evidence-rendering behavior, read [PRESERVE_EXISTING_FUNCTIONALITY.md](./PRESERVE_EXISTING_FUNCTIONALITY.md). It lists protected files, required checks, and the expected HF-safe deployment behavior.
87
+
88
+ ---
89
+
90
  ## ⚑ Smart Response Optimizer (New)
91
 
92
  The core performance innovation. All common financial questions are handled before any LLM inference:
 
295
  5. Generate training pairs & calibrate retrieval weights
296
  6. (Optional) Fine-tune embedding model
297
  7. Embed & index chunks in ChromaDB
298
+ 8. Index tables, render page screenshots, and build ColPali visual indexing
299
+ 9. Auto-generate smart response cache ← all intent templates pre-filled
 
300
 
301
  After training, all supported financial intents are instantly cached for the new document. First question β†’ template generation (<10ms). Subsequent questions β†’ cache hit (<5ms).
302