shak3008 commited on
Commit
92f72d7
·
1 Parent(s): 599225c

fixed gaugepilot upload routes

Browse files
DocPilot/backend/app/main.py CHANGED
@@ -37,11 +37,11 @@ app.include_router(auth.router, prefix="/auth")
37
  app.include_router(billing.router, prefix="/billing")
38
  app.include_router(history.router, prefix="/history")
39
  app.include_router(models.router, prefix="/models", tags=["models"])
40
- app.include_router(
41
  benchmark.router,
42
  prefix="/benchmark",
43
  tags=["benchmark"],
44
- )
45
  app.add_middleware(
46
  CORSMiddleware,
47
  allow_origins=["*"],
 
37
  app.include_router(billing.router, prefix="/billing")
38
  app.include_router(history.router, prefix="/history")
39
  app.include_router(models.router, prefix="/models", tags=["models"])
40
+ """app.include_router(
41
  benchmark.router,
42
  prefix="/benchmark",
43
  tags=["benchmark"],
44
+ )"""
45
  app.add_middleware(
46
  CORSMiddleware,
47
  allow_origins=["*"],
GaugePilot/backend/app/api/benchmark.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Depends
2
+
3
+ from GaugePilot.backend.app.core.dependencies import (
4
+ get_current_user,
5
+ )
6
+
7
+ from GaugePilot.backend.app.schemas.benchmark import (
8
+ BenchmarkRequest,
9
+ )
10
+
11
+ from pilotcore.benchmarking.benchmark_runner import (
12
+ run_benchmark,
13
+ )
14
+
15
+ from pilotcore.benchmarking.leaderboard import (
16
+ generate_leaderboard,
17
+ )
18
+
19
+ from pilotcore.runtime.experiment_config import (
20
+ ExperimentConfig,
21
+ )
22
+
23
+ router = APIRouter()
24
+
25
+
26
+ @router.post("/run")
27
+ def run_benchmark_endpoint(
28
+ request: BenchmarkRequest,
29
+ current_user=Depends(get_current_user),
30
+ ):
31
+ configs = [
32
+ ExperimentConfig(
33
+ experiment_name="Hybrid+MiniLM",
34
+ retrieval_method="hybrid",
35
+ reranker=True,
36
+ reranker_model="minilm",
37
+ ),
38
+ ExperimentConfig(
39
+ experiment_name="BM25",
40
+ retrieval_method="lexical",
41
+ reranker=False,
42
+ ),
43
+ ExperimentConfig(
44
+ experiment_name="Hybrid_NoRewrite",
45
+ retrieval_method="hybrid",
46
+ reranker=True,
47
+ reranker_model="minilm",
48
+ query_rewrite=False,
49
+ ),
50
+ ExperimentConfig(
51
+ experiment_name="Hybrid_NoReranker",
52
+ retrieval_method="hybrid",
53
+ reranker=False,
54
+ ),
55
+ ExperimentConfig(
56
+ experiment_name="Vector_Only",
57
+ retrieval_method="vector",
58
+ reranker=True,
59
+ reranker_model="minilm",
60
+ ),
61
+ ]
62
+
63
+ results = run_benchmark(
64
+ questions=request.questions,
65
+ configs=configs,
66
+ user_id=current_user.id,
67
+ source=None,
68
+ )
69
+
70
+ leaderboard = generate_leaderboard(results)
71
+
72
+ return {"leaderboard": leaderboard}
GaugePilot/backend/app/api/documents.py ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import (
2
+ APIRouter,
3
+ UploadFile,
4
+ File,
5
+ Depends,
6
+ HTTPException,
7
+ )
8
+
9
+ from sqlalchemy.orm import Session
10
+
11
+ import shutil
12
+ import os
13
+
14
+ from DocPilot.backend.app.services.ingestion import (
15
+ process_document,
16
+ TextExtractionError,
17
+ )
18
+
19
+ from pilotcore.retrieval.vector_store import (
20
+ reset_vector_store,
21
+ rebuild_index_without_document,
22
+ )
23
+
24
+ from DocPilot.backend.app.core.dependencies import (
25
+ get_current_user,
26
+ )
27
+
28
+ from DocPilot.backend.app.db.session import get_db
29
+
30
+ from DocPilot.backend.app.models.document import Document
31
+
32
+ from GaugePilot.backend.app.schemas.document import (
33
+ DocumentResponse,
34
+ )
35
+
36
+ router = APIRouter()
37
+
38
+
39
+ @router.post("/upload")
40
+ async def upload_document(
41
+ file: UploadFile = File(...),
42
+ current_user=Depends(get_current_user),
43
+ db: Session = Depends(get_db),
44
+ ):
45
+
46
+ document_count = (
47
+ db.query(Document).filter(Document.owner_id == current_user.id).count()
48
+ )
49
+
50
+ if current_user.plan == "free" and document_count >= 3:
51
+
52
+ raise HTTPException(
53
+ status_code=403,
54
+ detail="Free plan upload limit reached.",
55
+ )
56
+
57
+ os.makedirs(
58
+ "temp",
59
+ exist_ok=True,
60
+ )
61
+
62
+ allowed_extensions = [
63
+ ".pdf",
64
+ ".docx",
65
+ ".pptx",
66
+ ".txt",
67
+ ".md",
68
+ ".csv",
69
+ ".xlsx",
70
+ ".png",
71
+ ".jpg",
72
+ ".jpeg",
73
+ ".webp",
74
+ # treated as plain-text/code-like content
75
+ ".py",
76
+ ".js",
77
+ ".jsx",
78
+ ".ts",
79
+ ".tsx",
80
+ ".java",
81
+ ".cpp",
82
+ ".c",
83
+ ".h",
84
+ ".go",
85
+ ".rs",
86
+ ".json",
87
+ ".yaml",
88
+ ".yml",
89
+ ".sql",
90
+ ".css",
91
+ ".html",
92
+ ]
93
+
94
+ file_ext = os.path.splitext(file.filename)[1].lower()
95
+
96
+ if file_ext not in allowed_extensions:
97
+
98
+ raise HTTPException(
99
+ status_code=400,
100
+ detail="Unsupported file type.",
101
+ )
102
+
103
+ file_path = f"temp/{file.filename}"
104
+
105
+ with open(
106
+ file_path,
107
+ "wb",
108
+ ) as buffer:
109
+
110
+ shutil.copyfileobj(
111
+ file.file,
112
+ buffer,
113
+ )
114
+
115
+ document = Document(
116
+ owner_id=current_user.id,
117
+ filename=file.filename,
118
+ filepath=file_path,
119
+ file_size=os.path.getsize(file_path),
120
+ )
121
+
122
+ db.add(document)
123
+
124
+ db.commit()
125
+
126
+ db.refresh(document)
127
+
128
+ try:
129
+
130
+ process_document(
131
+ file_path,
132
+ current_user.id,
133
+ document.id,
134
+ mime_type=file.content_type,
135
+ )
136
+
137
+ except TextExtractionError as exc:
138
+
139
+ db.delete(document)
140
+
141
+ db.commit()
142
+
143
+ raise HTTPException(
144
+ status_code=422,
145
+ detail=str(exc),
146
+ ) from exc
147
+
148
+ return {
149
+ "message": "Document uploaded",
150
+ "document_id": document.id,
151
+ }
152
+
153
+
154
+ @router.get(
155
+ "/",
156
+ response_model=list[DocumentResponse],
157
+ )
158
+ def get_documents(
159
+ db: Session = Depends(get_db),
160
+ current_user=Depends(get_current_user),
161
+ ):
162
+
163
+ documents = db.query(Document).filter(Document.owner_id == current_user.id).all()
164
+
165
+ return documents
166
+
167
+
168
+ @router.delete("/reset")
169
+ def reset_documents(
170
+ current_user=Depends(get_current_user),
171
+ db: Session = Depends(get_db),
172
+ ):
173
+ reset_vector_store(current_user.id)
174
+
175
+ db.query(Document).filter(Document.owner_id == current_user.id).delete()
176
+ db.commit()
177
+
178
+ return {"message": "Vector store and documents cleared."}
179
+
180
+
181
+ @router.delete("/{document_id}")
182
+ def delete_document(
183
+ document_id: int,
184
+ db: Session = Depends(get_db),
185
+ current_user=Depends(get_current_user),
186
+ ):
187
+
188
+ document = (
189
+ db.query(Document)
190
+ .filter(
191
+ Document.id == document_id,
192
+ Document.owner_id == current_user.id,
193
+ )
194
+ .first()
195
+ )
196
+
197
+ if not document:
198
+
199
+ raise HTTPException(
200
+ status_code=404,
201
+ detail="Document not found",
202
+ )
203
+
204
+ if os.path.exists(document.filepath):
205
+
206
+ os.remove(document.filepath)
207
+
208
+ rebuild_index_without_document(
209
+ current_user.id,
210
+ document.id,
211
+ )
212
+
213
+ db.delete(document)
214
+
215
+ db.commit()
216
+
217
+ return {
218
+ "message": "Document deleted",
219
+ }
GaugePilot/backend/app/core/dependencies.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ from fastapi import Depends
2
+
3
+ # Reuse DocPilot's auth/db wiring if available in this monorepo.
4
+ # This keeps GaugePilot thin while preserving existing behavior.
5
+ from DocPilot.backend.app.core.dependencies import get_current_user # noqa: F401
GaugePilot/backend/app/main.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+
5
+ from .api import benchmark
6
+ from .api import documents
7
+
8
+ app = FastAPI()
9
+
10
+ app.add_middleware(
11
+ CORSMiddleware,
12
+ allow_origins=["*"],
13
+ allow_credentials=True,
14
+ allow_methods=["*"],
15
+ allow_headers=["*"],
16
+ )
17
+
18
+ app.include_router(benchmark.router, prefix="/benchmark", tags=["benchmark"])
19
+
20
+ app.include_router(
21
+ documents.router,
22
+ prefix="/docs",
23
+ )
24
+
25
+
26
+ @app.get("/")
27
+ def root():
28
+ return {"status": "running", "service": "gaugepilot"}
GaugePilot/backend/app/schemas/benchmark.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class BenchmarkRequest(BaseModel):
5
+ questions: list[str]
GaugePilot/backend/app/schemas/document.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+ from datetime import datetime
3
+
4
+
5
+ class DocumentResponse(BaseModel):
6
+ id: int
7
+
8
+ filename: str
9
+
10
+ filepath: str
11
+
12
+ file_size: int | None = None
13
+
14
+ page_count: int | None = None
15
+
16
+ chunk_count: int | None = None
17
+
18
+ ocr_used: bool
19
+
20
+ status: str
21
+
22
+ created_at: datetime
23
+
24
+ class Config:
25
+ from_attributes = True
README.md CHANGED
@@ -10,202 +10,167 @@ pinned: false
10
 
11
  # PilotMaster
12
 
13
- **PilotMaster** is a retrieval engineering and AI observability platform for building, debugging, and evaluating Retrieval-Augmented Generation (RAG) systems.
14
 
15
  Most RAG applications expose only the final answer.
16
 
17
  PilotMaster exposes the entire retrieval journey.
18
 
19
- It allows developers to inspect what was retrieved, why chunks ranked the way they did, whether retrieval methods agreed, how reranking influenced the final context, how grounded the answer was, and how different language models behave when given the same evidence.
20
-
21
- The platform combines:
22
-
23
- - **DocPilot** — document intelligence and grounded question answering
24
- - **TracePilot** — observability, tracing, replay, and evaluation
25
- - **PilotCore** — the shared execution kernel that powers retrieval, generation, evaluation, and tracing
26
-
27
- ---
28
-
29
- # Why PilotMaster Exists
30
-
31
- Modern GenAI systems often behave like black boxes.
32
-
33
- A document is uploaded.
34
-
35
- A question is asked.
36
-
37
- An answer is returned.
38
-
39
- What remains invisible is:
40
-
41
- - what information was retrieved
42
- - why certain chunks outranked others
43
- - whether dense retrieval or lexical retrieval dominated
44
- - how confident the reranker was
45
- - whether the answer was sufficiently grounded
46
- - where hallucination risk emerged
47
- - how a different model would have answered using the exact same context
48
-
49
- PilotMaster was built to make those decisions observable.
50
 
51
  ---
52
 
53
- # Experimental Workspace
54
-
55
- PilotMaster includes an Experimental Workspace for retrieval engineering research and controlled pipeline experimentation.
56
 
57
- Unlike the production workspace, which uses the platform's recommended retrieval configuration, the Experimental Workspace allows developers to modify retrieval strategies and retrieval enhancements at runtime.
58
 
59
- Current experimentation capabilities include:
60
 
61
- - Dense-only retrieval
62
- - BM25-only retrieval
63
- - Hybrid retrieval
64
- - Hybrid + RRF
65
- - Hybrid + RRF + Reranker
66
 
67
- The Experimental Workspace is designed to answer questions such as:
68
 
69
- - Does reranking improve grounding?
70
- - When does BM25 outperform dense retrieval?
71
- - How much does RRF improve recall?
72
- - Which retrieval strategy performs best for a specific document collection?
 
 
73
 
74
- The long-term goal is transforming PilotMaster from a RAG application into a retrieval engineering platform.
75
 
76
- # What PilotMaster Does
77
 
78
- PilotMaster combines:
79
 
80
- - Dense semantic retrieval
81
- - BM25 retrieval
82
- - Hybrid retrieval
83
- - Reciprocal Rank Fusion (RRF)
84
- - Cross-encoder reranking
85
- - Runtime model selection
86
- - Grounded generation
87
  - Retrieval diagnostics
 
88
  - Replayable traces
89
- - Retrieval evaluation
90
- - Comparative model benchmarking
91
-
92
- The objective is not merely generating answers.
93
 
94
- The objective is understanding how answers were generated.
95
 
96
- ---
97
 
98
- # High-Level Architecture
99
 
100
- Current request flow:
 
 
 
 
 
 
 
101
 
102
- Dashboard.jsx
103
- → FastAPI
104
- → DocPilot
105
- → PilotCore
106
- → Retrieval
107
- → Reranking
108
- → Generation
109
- → Evaluation
110
- → TracePilot
111
 
112
- PilotCore acts as the execution kernel shared by both DocPilot and TracePilot.
113
 
114
- ---
115
 
116
- # System Components
117
 
118
- ## PilotCore Execution Kernel
119
 
120
- PilotCore contains:
121
 
122
- - embeddings
123
- - retrieval
124
- - reranking
125
- - prompt construction
126
- - generation
127
- - evaluation
128
- - tracing
129
- - replay
130
 
131
- Key runtime modules:
 
 
 
 
 
 
 
132
 
133
- pilotcore/retrieval/runtime.py
134
 
135
- pilotcore/retrieval/vector_store.py
136
 
137
- pilotcore/retrieval/reranker.py
138
 
139
- pilotcore/runtime/pipeline.py
140
 
141
- pilotcore/generation/generator.py
142
 
143
- Both DocPilot and TracePilot delegate execution to PilotCore.
 
 
 
 
 
 
 
144
 
145
  ---
146
 
147
- ## DocPilot — Document Intelligence Layer
148
 
149
- DocPilot is the primary user-facing application.
150
 
151
- Features include:
152
 
153
- - document upload
154
- - OCR ingestion
155
- - citation-aware QA
156
- - grounded responses
157
- - chat sessions
158
- - runtime model selection
159
 
160
- Supported formats:
161
 
162
- - PDF
163
- - DOCX
164
- - TXT
165
- - CSV
166
- - XLSX
167
- - PNG
168
- - JPG
169
- - JPEG
170
 
171
- ---
172
 
173
- ## TracePilot Observability Layer
 
 
 
 
174
 
175
- TracePilot exposes the internal behavior of retrieval and generation.
176
 
177
- Every trace can contain:
178
 
179
- - retrieved chunks
180
- - dense retrieval diagnostics
181
- - BM25 diagnostics
182
- - RRF fusion signals
183
- - reranker diagnostics
184
- - retrieval lineage
185
- - latency spans
186
- - evaluation metrics
187
- - replay metadata
 
188
 
189
- The goal is observable AI execution rather than guess-based debugging.
190
 
191
  ---
192
 
193
- # Retrieval System
194
 
195
  ## Retrieval Pipeline
196
 
197
- Current retrieval flow:
198
-
199
  Query
200
- → Dense Retrieval (FAISS)
201
  → BM25 Retrieval
202
- → Reciprocal Rank Fusion (RRF)
203
- → Candidate Pool Construction
204
  → Cross-Encoder Reranking
205
- Top Context Selection
206
  → LLM Generation
207
  → Evaluation
208
- → Trace Ingestion
209
 
210
  ---
211
 
@@ -214,93 +179,101 @@ Query
214
  Semantic retrieval uses:
215
 
216
  - SentenceTransformers
217
- - all-mpnet-base-v2
218
- - FAISS IndexFlatIP
219
- - cosine similarity
 
 
220
 
221
- Dense retrieval is responsible for semantic recall and concept-level matching.
 
 
222
 
223
  ---
224
 
225
  ## BM25 Retrieval
226
 
227
- BM25 complements dense retrieval by handling:
228
 
229
- - exact terminology
230
- - acronyms
231
- - keyword-heavy queries
232
- - lexical matching
233
- - negation-sensitive retrieval
234
 
235
- This mitigates weaknesses found in vector-only retrieval systems.
236
 
237
  ---
238
 
239
- ## Reciprocal Rank Fusion (RRF)
240
 
241
- RRF combines:
242
 
243
- - dense retrieval rankings
244
  - BM25 rankings
245
 
246
- This provides a more stable ranking signal than simple result concatenation.
 
 
 
 
247
 
248
  ---
249
 
250
  ## Cross-Encoder Reranking
251
 
252
- Final ranking uses:
253
 
254
- cross-encoder/ms-marco-MiniLM-L-6-v2
255
 
256
- The reranker:
 
 
257
 
258
- - jointly evaluates query-chunk pairs
259
- - rescoring fused candidates
260
- - promotes semantically relevant evidence
261
- - improves ranking precision
262
 
263
- Reranking occurs after retrieval and before prompt construction.
 
 
 
264
 
265
  ---
266
 
267
- # Current Retrieval Configuration
268
-
269
- | Component | Configuration |
270
- | ----------------------- | ----------------------------------------- |
271
- | Embedding Model | `sentence-transformers/all-mpnet-base-v2` |
272
- | Embedding Dimension | 768 |
273
- | Vector Store | FAISS (`IndexFlatIP`) |
274
- | Similarity Metric | Cosine Similarity |
275
- | Chunk Size | 500 characters |
276
- | Chunk Overlap | 80 characters |
277
- | Dense Retrieval Depth | Top 7 |
278
- | BM25 Retrieval Depth | Top 7 |
279
- | Fusion Strategy | Reciprocal Rank Fusion (RRF) |
280
- | Reranker | `cross-encoder/ms-marco-MiniLM-L-6-v2` |
281
- | Reranker Candidate Pool | Up to 20 chunks |
282
- | Final Context Window | Top 7 reranked chunks |
283
- | Retrieval Version | `hybrid_rrf_v1` |
284
 
285
- ---
286
 
287
- # Model Runtime
 
 
 
 
 
 
288
 
289
- PilotMaster supports runtime model selection through a centralized model registry.
290
 
291
- Models are defined in:
292
 
293
- pilotcore/models/registry.py
 
 
294
 
295
- and exposed through:
296
 
297
- GET /docpilot/models/
 
 
 
 
298
 
299
- The frontend dynamically discovers available models from the backend.
300
 
301
- This allows new models to be introduced without modifying frontend code.
302
 
303
- ## Currently Supported Models
 
 
304
 
305
  - Llama 3.1 8B
306
  - Llama 3.3 70B
@@ -309,47 +282,59 @@ This allows new models to be introduced without modifying frontend code.
309
  - GPT OSS 20B
310
  - GPT OSS 120B
311
 
312
- Runtime model selection enables:
313
-
314
- - model benchmarking
315
- - latency comparisons
316
- - grounding comparisons
317
- - retrieval-consistent evaluations
318
 
319
- because every model can be tested against identical retrieved evidence.
 
 
 
320
 
321
  ---
322
 
323
- # Retrieval Observability
324
 
325
- A primary goal of PilotMaster is retrieval introspection.
326
 
327
  ## Per-Chunk Diagnostics
328
 
329
- Every retrieved chunk can expose:
330
 
331
- - dense score
332
- - dense rank
333
- - BM25 score
334
- - BM25 rank
335
- - RRF score
336
- - reranker score
337
- - reranker confidence
338
- - reranker margin
339
- - final rank
340
- - retrieval provenance
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
 
342
  ---
343
 
344
  ## Retrieval Agreement
345
 
346
- TracePilot identifies whether retrieval was:
347
 
348
- - strong
349
- - semantic-dominant
350
- - lexical-dominant
351
 
352
- This makes retrieval behavior substantially easier to debug.
353
 
354
  ---
355
 
@@ -357,51 +342,54 @@ This makes retrieval behavior substantially easier to debug.
357
 
358
  Every execution can be replayed.
359
 
360
- This enables:
361
 
362
- - retrieval debugging
363
- - ranking inspection
364
- - evaluator comparison
365
- - regression testing
366
- - pipeline experimentation
367
 
368
  ---
369
 
370
- # Evaluation System
371
 
372
  PilotMaster evaluates multiple dimensions of answer quality.
373
 
374
- Current metrics include:
375
 
376
  - Retrieval Quality
377
- - Grounding Confidence
 
 
 
378
  - Answerability
379
  - Hallucination Risk
380
 
381
- Evaluation considers:
382
-
383
- - reranker confidence
384
- - reranker margin
385
- - retrieval agreement
386
- - retrieval lineage
387
 
388
- rather than relying exclusively on lexical overlap.
 
 
 
 
 
389
 
390
  ---
391
 
392
  # Comparative Model Evaluation
393
 
394
- PilotMaster supports comparative evaluation across multiple models using identical retrieval context.
395
 
396
- Developers can analyze differences in:
397
 
398
- - grounding
399
- - reasoning
400
- - latency
401
- - retrieval utilization
402
- - answer completeness
403
 
404
- Because retrieval context remains constant, behavioral differences can be attributed primarily to the model rather than retrieval variance.
405
 
406
  ---
407
 
@@ -409,53 +397,54 @@ Because retrieval context remains constant, behavioral differences can be attrib
409
 
410
  ## Retrieval
411
 
412
- - Dense retrieval
413
- - BM25 retrieval
414
- - Hybrid retrieval
415
  - Reciprocal Rank Fusion
416
- - Cross-encoder reranking
417
- - Retrieval lineage tracing
418
 
419
  ## Observability
420
 
421
- - Replayable traces
422
- - Retrieval diagnostics
423
- - Chunk ranking inspection
424
- - Latency tracking
425
- - Span visualization
426
- - Confidence metrics
427
 
428
- ## Model Runtime
429
 
430
- - Runtime model selection
431
- - Dynamic model registry
432
- - Comparative model evaluation
 
433
 
434
  ## Document Intelligence
435
 
436
- - OCR ingestion
437
  - Grounded QA
438
- - Citation-aware responses
439
- - Multi-format document support
440
 
441
  ---
442
 
443
  # Research Directions
444
 
445
- PilotMaster has increasingly evolved into a retrieval engineering platform.
446
 
447
- Current research focuses on:
 
 
 
 
 
 
 
448
 
449
- - semantic chunking
450
- - query rewriting
451
- - query expansion
452
- - multi-query retrieval
453
- - parent-child retrieval
454
- - contextual retrieval
455
- - metadata-aware retrieval
456
- - agentic retrieval
457
 
458
- Recent experiments suggest that retrieval quality is becoming a larger bottleneck than generation quality, making retrieval engineering the primary area of exploration.
459
 
460
  ---
461
 
@@ -463,33 +452,35 @@ Recent experiments suggest that retrieval quality is becoming a larger bottlenec
463
 
464
  ## Retrieval Engineering
465
 
466
- - Query rewriting
467
- - Query expansion
468
- - Multi-query retrieval
469
- - Parent-child retrieval
470
- - Contextual retrieval
471
- - Metadata-aware retrieval
472
- - Semantic chunking
473
- - Agentic retrieval
474
 
475
  ## Evaluation
476
 
477
- - Comparative model evaluation
478
- - Judge ensembles
479
- - Grounding regression testing
480
 
481
  ## Observability
482
 
483
- - Retrieval lineage visualization
484
- - Cross-run trace comparison
485
- - Advanced retrieval diagnostics
486
 
487
- ## Experimental Workspace
488
 
489
- - Runtime retrieval controls
490
- - Runtime enhancement controls
491
- - Retrieval A/B testing
492
- - Side-by-side retrieval comparisons
 
 
493
 
494
  # Tech Stack
495
 
@@ -501,8 +492,8 @@ Recent experiments suggest that retrieval quality is becoming a larger bottlenec
501
  | Vector Engine | FAISS |
502
  | Embeddings | SentenceTransformers |
503
  | Retrieval | Dense + BM25 + RRF |
504
- | Reranker | Cross-Encoder MiniLM |
505
- | LLM Runtime | Groq Multi-Model Runtime |
506
  | Deployment | Hugging Face Spaces + Vercel |
507
 
508
  ---
@@ -517,10 +508,12 @@ _Add screenshot_
517
 
518
  _Add screenshot_
519
 
520
- ## Experimental Workspace
521
 
522
  _Add screenshot_
523
 
 
 
524
  # Local Setup
525
 
526
  ## Backend
@@ -543,51 +536,20 @@ npm run dev
543
 
544
  ---
545
 
546
- # Environment Variables
547
-
548
- ```env
549
- GROQ_API_KEY=
550
- DATABASE_URL=
551
- SECRET_KEY=
552
- TRACEPILOT_URL=
553
- DOCPILOT_URL=
554
- ```
555
-
556
- ---
557
-
558
- # Deployment
559
-
560
- ## Frontend
561
-
562
- - Vercel
563
- - React + Vite
564
-
565
- ## Backend
566
-
567
- - Hugging Face Spaces
568
- - Docker deployment
569
- - Unified FastAPI runtime
570
-
571
- ## Database
572
-
573
- - Neon PostgreSQL
574
-
575
- ---
576
-
577
  # What Makes PilotMaster Different
578
 
579
  Most RAG systems expose only the final answer.
580
 
581
  PilotMaster exposes:
582
 
583
- - how retrieval behaved
584
- - why chunks ranked the way they did
585
- - whether retrievers agreed
586
- - how confident reranking was
587
- - how grounded the answer was
588
- - where hallucination risk emerged
589
- - how different models behave on identical context
590
- - how retrieval quality evolves over time
591
 
592
  The goal is not simply AI generation.
593
 
 
10
 
11
  # PilotMaster
12
 
13
+ **PilotMaster** is a retrieval engineering, document intelligence, and AI observability platform for building, debugging, evaluating, and improving Retrieval-Augmented Generation (RAG) systems.
14
 
15
  Most RAG applications expose only the final answer.
16
 
17
  PilotMaster exposes the entire retrieval journey.
18
 
19
+ From retrieval and reranking to evaluation and trace replay, every major decision can be inspected, analyzed, benchmarked, and improved.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  ---
22
 
23
+ # Platform Overview
 
 
24
 
25
+ PilotMaster consists of three major layers:
26
 
27
+ ## DocPilot
28
 
29
+ The document intelligence workspace.
 
 
 
 
30
 
31
+ Provides:
32
 
33
+ - Document ingestion
34
+ - OCR processing
35
+ - Grounded question answering
36
+ - Citation-aware responses
37
+ - Runtime model selection
38
+ - Retrieval experimentation
39
 
40
+ ## TracePilot
41
 
42
+ The observability workspace.
43
 
44
+ Provides:
45
 
 
 
 
 
 
 
 
46
  - Retrieval diagnostics
47
+ - Chunk lineage inspection
48
  - Replayable traces
49
+ - Reranker analysis
50
+ - Evaluation metrics
51
+ - Hallucination analysis
52
+ - Retrieval agreement analysis
53
 
54
+ ## PilotCore
55
 
56
+ The shared execution kernel.
57
 
58
+ Provides:
59
 
60
+ - Embeddings
61
+ - Retrieval
62
+ - Fusion
63
+ - Reranking
64
+ - Prompt construction
65
+ - Generation
66
+ - Evaluation
67
+ - Tracing
68
 
69
+ ---
 
 
 
 
 
 
 
 
70
 
71
+ # Why PilotMaster Exists
72
 
73
+ Modern GenAI systems frequently behave like black boxes.
74
 
75
+ A document is uploaded.
76
 
77
+ A question is asked.
78
 
79
+ An answer is returned.
80
 
81
+ What remains hidden:
 
 
 
 
 
 
 
82
 
83
+ - What was retrieved?
84
+ - Why did those chunks rank first?
85
+ - Which retriever contributed the evidence?
86
+ - Did BM25 or dense retrieval dominate?
87
+ - How confident was the reranker?
88
+ - Was the answer grounded?
89
+ - Did the model hallucinate?
90
+ - Would another model answer differently using the same evidence?
91
 
92
+ PilotMaster was built to make those decisions observable.
93
 
94
+ ---
95
 
96
+ # Unified Workspace
97
 
98
+ DocPilot and TracePilot operate inside the same platform experience.
99
 
100
+ Typical workflow:
101
 
102
+ 1. Upload a document
103
+ 2. Ask a question
104
+ 3. Review citations
105
+ 4. Inspect retrieved chunks
106
+ 5. Analyze ranking signals
107
+ 6. Evaluate answer quality
108
+ 7. Replay the execution
109
+ 8. Compare retrieval strategies
110
 
111
  ---
112
 
113
+ # Research Workspace
114
 
115
+ PilotMaster includes a dedicated workspace for retrieval engineering.
116
 
117
+ Supported retrieval modes:
118
 
119
+ - Dense Retrieval
120
+ - BM25 Retrieval
121
+ - Hybrid Retrieval
122
+ - Hybrid + RRF
123
+ - Hybrid + RRF + Reranking
 
124
 
125
+ Experimental controls include:
126
 
127
+ - Embedding model selection
128
+ - Reranker selection
129
+ - Retrieval strategy selection
130
+ - Query enhancement testing
131
+ - Model benchmarking
 
 
 
132
 
133
+ Questions the workspace helps answer:
134
 
135
+ - Does reranking improve grounding?
136
+ - When does BM25 outperform dense retrieval?
137
+ - Does RRF improve recall?
138
+ - Which embedding model performs best?
139
+ - Which reranker produces the best ranking quality?
140
 
141
+ ---
142
 
143
+ # High-Level Architecture
144
 
145
+ Dashboard
146
+ FastAPI
147
+ DocPilot
148
+ PilotCore
149
+ Retrieval
150
+ Fusion
151
+ Reranking
152
+ Generation
153
+ Evaluation
154
+ → TracePilot
155
 
156
+ PilotCore acts as the execution kernel shared by every workspace.
157
 
158
  ---
159
 
160
+ # Retrieval Architecture
161
 
162
  ## Retrieval Pipeline
163
 
 
 
164
  Query
165
+ → Dense Retrieval
166
  → BM25 Retrieval
167
+ → Reciprocal Rank Fusion
168
+ → Candidate Pool
169
  → Cross-Encoder Reranking
170
+ → Context Selection
171
  → LLM Generation
172
  → Evaluation
173
+ → Trace Storage
174
 
175
  ---
176
 
 
179
  Semantic retrieval uses:
180
 
181
  - SentenceTransformers
182
+ - Cosine Similarity
183
+ - FAISS
184
+ - IndexFlatIP
185
+
186
+ Responsibilities:
187
 
188
+ - Concept matching
189
+ - Semantic recall
190
+ - Contextual retrieval
191
 
192
  ---
193
 
194
  ## BM25 Retrieval
195
 
196
+ Responsibilities:
197
 
198
+ - Exact terminology
199
+ - Acronyms
200
+ - Keywords
201
+ - Lexical precision
202
+ - Negation-sensitive retrieval
203
 
204
+ BM25 compensates for weaknesses found in purely vector-based systems.
205
 
206
  ---
207
 
208
+ ## Reciprocal Rank Fusion
209
 
210
+ Combines:
211
 
212
+ - Dense rankings
213
  - BM25 rankings
214
 
215
+ Benefits:
216
+
217
+ - Better recall
218
+ - Stable rankings
219
+ - Reduced retriever bias
220
 
221
  ---
222
 
223
  ## Cross-Encoder Reranking
224
 
225
+ Reranking occurs after retrieval and before prompt construction.
226
 
227
+ Supported families:
228
 
229
+ - MiniLM rerankers
230
+ - BGE rerankers
231
+ - Experimental rerankers
232
 
233
+ Responsibilities:
 
 
 
234
 
235
+ - Joint query/chunk evaluation
236
+ - Candidate rescoring
237
+ - Precision improvement
238
+ - Evidence prioritization
239
 
240
  ---
241
 
242
+ # Runtime Retrieval Components
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
+ PilotMaster supports runtime experimentation.
245
 
246
+ ## Embedding Models
247
+
248
+ Examples:
249
+
250
+ - all-mpnet-base-v2
251
+ - BGE family
252
+ - Additional SentenceTransformer models
253
 
254
+ ## Rerankers
255
 
256
+ Examples:
257
 
258
+ - MiniLM
259
+ - BGE Reranker Large
260
+ - BGE Reranker v2 M3
261
 
262
+ ## Retrieval Strategies
263
 
264
+ - Dense
265
+ - BM25
266
+ - Hybrid
267
+ - Hybrid + RRF
268
+ - Hybrid + RRF + Reranking
269
 
270
+ ---
271
 
272
+ # Model Runtime
273
 
274
+ Models are managed through a centralized registry.
275
+
276
+ Currently supported:
277
 
278
  - Llama 3.1 8B
279
  - Llama 3.3 70B
 
282
  - GPT OSS 20B
283
  - GPT OSS 120B
284
 
285
+ Runtime selection enables:
 
 
 
 
 
286
 
287
+ - Latency comparisons
288
+ - Grounding comparisons
289
+ - Retrieval-consistent benchmarking
290
+ - Comparative model evaluation
291
 
292
  ---
293
 
294
+ # TracePilot
295
 
296
+ TracePilot exposes the internal behavior of the system.
297
 
298
  ## Per-Chunk Diagnostics
299
 
300
+ Available metrics:
301
 
302
+ - Dense Score
303
+ - Dense Rank
304
+ - BM25 Score
305
+ - BM25 Rank
306
+ - RRF Score
307
+ - Reranker Score
308
+ - Reranker Confidence
309
+ - Reranker Margin
310
+ - Final Rank
311
+ - Retrieval Provenance
312
+
313
+ ---
314
+
315
+ ## Retrieval Lineage
316
+
317
+ Every chunk records where it originated:
318
+
319
+ - Dense Retrieval
320
+ - BM25 Retrieval
321
+ - Hybrid Retrieval
322
+ - RRF Fusion
323
+ - Reranking
324
+
325
+ This makes ranking behavior significantly easier to debug.
326
 
327
  ---
328
 
329
  ## Retrieval Agreement
330
 
331
+ TracePilot determines whether retrieval was:
332
 
333
+ - Strong
334
+ - Semantic-Dominant
335
+ - Lexical-Dominant
336
 
337
+ Agreement analysis helps explain why a response succeeded or failed.
338
 
339
  ---
340
 
 
342
 
343
  Every execution can be replayed.
344
 
345
+ Replay enables:
346
 
347
+ - Retrieval debugging
348
+ - Regression testing
349
+ - Evaluation comparison
350
+ - Pipeline experimentation
351
+ - Ranking inspection
352
 
353
  ---
354
 
355
+ # Evaluation Framework
356
 
357
  PilotMaster evaluates multiple dimensions of answer quality.
358
 
359
+ Current metrics:
360
 
361
  - Retrieval Quality
362
+ - Grounding
363
+ - Faithfulness
364
+ - Query Coverage
365
+ - Retrieval Agreement
366
  - Answerability
367
  - Hallucination Risk
368
 
369
+ Evaluation incorporates:
 
 
 
 
 
370
 
371
+ - Retrieval confidence
372
+ - Reranker confidence
373
+ - Reranker margin
374
+ - Retrieval agreement
375
+ - Evidence quality
376
+ - Retrieval lineage
377
 
378
  ---
379
 
380
  # Comparative Model Evaluation
381
 
382
+ Multiple models can be tested against identical retrieved evidence.
383
 
384
+ Developers can compare:
385
 
386
+ - Grounding
387
+ - Reasoning quality
388
+ - Latency
389
+ - Retrieval utilization
390
+ - Answer completeness
391
 
392
+ Because retrieval context remains fixed, behavioral differences can be attributed primarily to model behavior.
393
 
394
  ---
395
 
 
397
 
398
  ## Retrieval
399
 
400
+ - Dense Retrieval
401
+ - BM25 Retrieval
402
+ - Hybrid Retrieval
403
  - Reciprocal Rank Fusion
404
+ - Cross-Encoder Reranking
405
+ - Retrieval Lineage Tracking
406
 
407
  ## Observability
408
 
409
+ - Replayable Traces
410
+ - Retrieval Diagnostics
411
+ - Ranking Inspection
412
+ - Latency Tracking
413
+ - Confidence Metrics
414
+ - Evaluation Insights
415
 
416
+ ## Runtime Controls
417
 
418
+ - Runtime Model Selection
419
+ - Runtime Embedding Selection
420
+ - Runtime Reranker Selection
421
+ - Dynamic Model Registry
422
 
423
  ## Document Intelligence
424
 
425
+ - OCR Ingestion
426
  - Grounded QA
427
+ - Citation-Aware Responses
428
+ - Multi-Format Support
429
 
430
  ---
431
 
432
  # Research Directions
433
 
434
+ Current focus areas:
435
 
436
+ - Semantic Chunking
437
+ - Query Rewriting
438
+ - Query Expansion
439
+ - Multi-Query Retrieval
440
+ - Parent-Child Retrieval
441
+ - Contextual Retrieval
442
+ - Metadata-Aware Retrieval
443
+ - Agentic Retrieval
444
 
445
+ Observation:
 
 
 
 
 
 
 
446
 
447
+ Retrieval quality increasingly appears to be a larger bottleneck than generation quality, making retrieval engineering a primary area of exploration.
448
 
449
  ---
450
 
 
452
 
453
  ## Retrieval Engineering
454
 
455
+ - Query Rewriting
456
+ - Query Expansion
457
+ - Multi-Query Retrieval
458
+ - Parent-Child Retrieval
459
+ - Contextual Retrieval
460
+ - Metadata-Aware Retrieval
461
+ - Semantic Chunking
462
+ - Agentic Retrieval
463
 
464
  ## Evaluation
465
 
466
+ - Comparative Evaluation
467
+ - Judge Ensembles
468
+ - Grounding Regression Testing
469
 
470
  ## Observability
471
 
472
+ - Cross-Run Comparisons
473
+ - Retrieval Lineage Visualization
474
+ - Advanced Diagnostics
475
 
476
+ ## Experimentation
477
 
478
+ - Retrieval A/B Testing
479
+ - Embedding Benchmarks
480
+ - Reranker Benchmarks
481
+ - Side-by-Side Comparisons
482
+
483
+ ---
484
 
485
  # Tech Stack
486
 
 
492
  | Vector Engine | FAISS |
493
  | Embeddings | SentenceTransformers |
494
  | Retrieval | Dense + BM25 + RRF |
495
+ | Reranking | Cross-Encoder Models |
496
+ | Runtime | Multi-Model Inference |
497
  | Deployment | Hugging Face Spaces + Vercel |
498
 
499
  ---
 
508
 
509
  _Add screenshot_
510
 
511
+ ## Research Workspace
512
 
513
  _Add screenshot_
514
 
515
+ ---
516
+
517
  # Local Setup
518
 
519
  ## Backend
 
536
 
537
  ---
538
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
539
  # What Makes PilotMaster Different
540
 
541
  Most RAG systems expose only the final answer.
542
 
543
  PilotMaster exposes:
544
 
545
+ - How retrieval behaved
546
+ - Why chunks ranked the way they did
547
+ - Whether retrievers agreed
548
+ - How confident reranking was
549
+ - How grounded the answer was
550
+ - Where hallucination risk emerged
551
+ - How different models behave on identical context
552
+ - How retrieval quality evolves over time
553
 
554
  The goal is not simply AI generation.
555
 
frontend/src/gaugepilot/api.js CHANGED
@@ -1,7 +1,7 @@
1
  import axios from "axios";
2
 
3
  const API = axios.create({
4
- baseURL: "http://127.0.0.1:8000/docpilot",
5
  });
6
 
7
  export async function runBenchmark(payload, token) {
@@ -15,5 +15,23 @@ export async function runBenchmark(payload, token) {
15
  }
16
  );
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  return response.data;
19
  }
 
1
  import axios from "axios";
2
 
3
  const API = axios.create({
4
+ baseURL: "http://127.0.0.1:8000/gaugepilot",
5
  });
6
 
7
  export async function runBenchmark(payload, token) {
 
15
  }
16
  );
17
 
18
+ return response.data;
19
+ }
20
+ export async function uploadDocument(file, token) {
21
+ const formData = new FormData();
22
+
23
+ formData.append("file", file);
24
+
25
+ const response = await API.post(
26
+ "/docs/upload",
27
+ formData,
28
+ {
29
+ headers: {
30
+ Authorization: `Bearer ${token}`,
31
+ "Content-Type": "multipart/form-data",
32
+ },
33
+ }
34
+ );
35
+
36
  return response.data;
37
  }
frontend/src/gaugepilot/pages/ExperimentSetup.jsx CHANGED
@@ -2,7 +2,10 @@ import { useState, useRef } from "react";
2
  import { useBenchmark } from "../hooks/useBenchmark";
3
  import Leaderboards from "./Leaderboards";
4
  import ExperimentSelector from "../components/ExperimentSelector";
5
-
 
 
 
6
  /*const SAMPLE_QUESTIONS = [
7
  "What is the main contribution of this paper?",
8
  "How does the proposed method compare to baselines?",
@@ -22,6 +25,7 @@ export default function ExperimentSetup() {
22
  const [isDragging, setIsDragging] = useState(false);
23
  const [isHoveringUpload, setIsHoveringUpload] = useState(false);
24
  const [isHoveringRun, setIsHoveringRun] = useState(false);
 
25
  const [benchmarkRuns, setBenchmarkRuns] = useState(0);
26
  const [bestScore, setBestScore] = useState(null);
27
  const fileInputRef = useRef(null);
@@ -48,7 +52,36 @@ export default function ExperimentSetup() {
48
  }
49
  };
50
 
51
- const handleFileChange = (file) => { if (file) setUploadedFile(file); };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  const handleDrop = (e) => {
53
  e.preventDefault(); setIsDragging(false);
54
  handleFileChange(e.dataTransfer.files[0]);
@@ -214,42 +247,141 @@ export default function ExperimentSetup() {
214
  pointerEvents: "none",
215
  }} />
216
 
217
- {uploadedFile ? (
218
- <>
219
- <div style={{
220
- width: 60, height: 60, borderRadius: "16px",
221
- background: "rgba(34,197,94,0.15)",
222
- display: "flex", alignItems: "center", justifyContent: "center", fontSize: "28px",
223
- boxShadow: "0 0 20px rgba(34,197,94,0.2)",
224
- }}>✅</div>
225
- <div style={{ textAlign: "center", zIndex: 1 }}>
226
- <p style={{ margin: 0, fontWeight: 700, fontSize: "15px", color: green }}>{uploadedFile.name}</p>
227
- <p style={{ margin: "4px 0 0", fontSize: "12px", color: "rgba(255,255,255,0.35)" }}>
228
- {(uploadedFile.size / 1024).toFixed(1)} KB · Click to replace
229
- </p>
230
- </div>
231
- </>
232
- ) : (
233
- <>
234
- <div style={{
235
- width: 64, height: 64, borderRadius: "18px",
236
- background: isDragging ? `rgba(79,110,247,0.2)` : "rgba(79,110,247,0.1)",
237
- display: "flex", alignItems: "center", justifyContent: "center",
238
- fontSize: "28px", zIndex: 1,
239
- boxShadow: isDragging ? `0 0 24px rgba(79,110,247,0.3)` : "none",
240
- transition: "all 0.2s ease",
241
- }}>⬆️</div>
242
- <div style={{ textAlign: "center", zIndex: 1 }}>
243
- <p style={{ margin: 0, fontWeight: 700, fontSize: "16px", color: "white" }}>
244
- {isDragging ? "Drop to upload" : "Upload Document"}
245
- </p>
246
- <p style={{ margin: "5px 0 0", fontSize: "12px", color: "rgba(255,255,255,0.35)", lineHeight: 1.6 }}>
247
- Drag & drop or click to browse<br />
248
- <span style={{ color: "rgba(255,255,255,0.2)" }}>Any document format supported</span>
249
- </p>
250
- </div>
251
- </>
252
- )}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  </div>
254
 
255
  {/* Benchmark Summary */}
 
2
  import { useBenchmark } from "../hooks/useBenchmark";
3
  import Leaderboards from "./Leaderboards";
4
  import ExperimentSelector from "../components/ExperimentSelector";
5
+ import {
6
+ runBenchmark,
7
+ uploadDocument,
8
+ } from "../api";
9
  /*const SAMPLE_QUESTIONS = [
10
  "What is the main contribution of this paper?",
11
  "How does the proposed method compare to baselines?",
 
25
  const [isDragging, setIsDragging] = useState(false);
26
  const [isHoveringUpload, setIsHoveringUpload] = useState(false);
27
  const [isHoveringRun, setIsHoveringRun] = useState(false);
28
+ const [uploading, setUploading] = useState(false);
29
  const [benchmarkRuns, setBenchmarkRuns] = useState(0);
30
  const [bestScore, setBestScore] = useState(null);
31
  const fileInputRef = useRef(null);
 
52
  }
53
  };
54
 
55
+ const handleFileChange = async (file) => {
56
+ if (!file) return;
57
+
58
+ try {
59
+ setUploading(true);
60
+
61
+ const token = localStorage.getItem("token");
62
+
63
+ await uploadDocument(
64
+ file,
65
+ token
66
+ );
67
+
68
+ setUploadedFile(file);
69
+
70
+ console.log(
71
+ "GaugePilot upload successful"
72
+ );
73
+ } catch (err) {
74
+ console.error(
75
+ "GaugePilot upload failed",
76
+ err
77
+ );
78
+ } finally {
79
+ setUploading(false);
80
+ }
81
+ };
82
+
83
+
84
+
85
  const handleDrop = (e) => {
86
  e.preventDefault(); setIsDragging(false);
87
  handleFileChange(e.dataTransfer.files[0]);
 
247
  pointerEvents: "none",
248
  }} />
249
 
250
+ {uploading ? (
251
+ <>
252
+ <div
253
+ style={{
254
+ width: 60,
255
+ height: 60,
256
+ borderRadius: "16px",
257
+ background: "rgba(79,110,247,0.15)",
258
+ display: "flex",
259
+ alignItems: "center",
260
+ justifyContent: "center",
261
+ fontSize: "28px",
262
+ boxShadow: "0 0 20px rgba(79,110,247,0.2)",
263
+ }}
264
+ >
265
+
266
+ </div>
267
+
268
+ <div style={{ textAlign: "center", zIndex: 1 }}>
269
+ <p
270
+ style={{
271
+ margin: 0,
272
+ fontWeight: 700,
273
+ fontSize: "15px",
274
+ color: "#4f6ef7",
275
+ }}
276
+ >
277
+ Uploading & Indexing...
278
+ </p>
279
+
280
+ <p
281
+ style={{
282
+ margin: "4px 0 0",
283
+ fontSize: "12px",
284
+ color: "rgba(255,255,255,0.35)",
285
+ }}
286
+ >
287
+ Processing document
288
+ </p>
289
+ </div>
290
+ </>
291
+ ) : uploadedFile ? (
292
+ <>
293
+ <div
294
+ style={{
295
+ width: 60,
296
+ height: 60,
297
+ borderRadius: "16px",
298
+ background: "rgba(34,197,94,0.15)",
299
+ display: "flex",
300
+ alignItems: "center",
301
+ justifyContent: "center",
302
+ fontSize: "28px",
303
+ boxShadow: "0 0 20px rgba(34,197,94,0.2)",
304
+ }}
305
+ >
306
+
307
+ </div>
308
+
309
+ <div style={{ textAlign: "center", zIndex: 1 }}>
310
+ <p
311
+ style={{
312
+ margin: 0,
313
+ fontWeight: 700,
314
+ fontSize: "15px",
315
+ color: green,
316
+ }}
317
+ >
318
+ {uploadedFile.name}
319
+ </p>
320
+
321
+ <p
322
+ style={{
323
+ margin: "4px 0 0",
324
+ fontSize: "12px",
325
+ color: "rgba(255,255,255,0.35)",
326
+ }}
327
+ >
328
+ {(uploadedFile.size / 1024).toFixed(1)} KB · Click to replace
329
+ </p>
330
+ </div>
331
+ </>
332
+ ) : (
333
+ <>
334
+ <div
335
+ style={{
336
+ width: 64,
337
+ height: 64,
338
+ borderRadius: "18px",
339
+ background: isDragging
340
+ ? `rgba(79,110,247,0.2)`
341
+ : "rgba(79,110,247,0.1)",
342
+ display: "flex",
343
+ alignItems: "center",
344
+ justifyContent: "center",
345
+ fontSize: "28px",
346
+ zIndex: 1,
347
+ boxShadow: isDragging
348
+ ? `0 0 24px rgba(79,110,247,0.3)`
349
+ : "none",
350
+ transition: "all 0.2s ease",
351
+ }}
352
+ >
353
+ ⬆️
354
+ </div>
355
+
356
+ <div style={{ textAlign: "center", zIndex: 1 }}>
357
+ <p
358
+ style={{
359
+ margin: 0,
360
+ fontWeight: 700,
361
+ fontSize: "16px",
362
+ color: "white",
363
+ }}
364
+ >
365
+ {isDragging
366
+ ? "Drop to upload"
367
+ : "Upload Document"}
368
+ </p>
369
+
370
+ <p
371
+ style={{
372
+ margin: "5px 0 0",
373
+ fontSize: "12px",
374
+ color: "rgba(255,255,255,0.35)",
375
+ lineHeight: 1.6,
376
+ }}
377
+ >
378
+ Drag & drop or click to browse
379
+ <br />
380
+
381
+ </p>
382
+ </div>
383
+ </>
384
+ )}
385
  </div>
386
 
387
  {/* Benchmark Summary */}
main.py CHANGED
@@ -3,6 +3,7 @@ from fastapi.middleware.cors import CORSMiddleware
3
 
4
  from DocPilot.backend.app.main import app as docpilot_app
5
  from TracePilot.backend.app.main import app as tracepilot_app
 
6
 
7
  app = FastAPI(title="PilotMaster")
8
 
@@ -16,6 +17,7 @@ app.add_middleware(
16
 
17
  app.mount("/docpilot", docpilot_app)
18
  app.mount("/tracepilot", tracepilot_app)
 
19
 
20
 
21
  @app.get("/")
 
3
 
4
  from DocPilot.backend.app.main import app as docpilot_app
5
  from TracePilot.backend.app.main import app as tracepilot_app
6
+ from GaugePilot.backend.app.main import app as gaugepilot_app
7
 
8
  app = FastAPI(title="PilotMaster")
9
 
 
17
 
18
  app.mount("/docpilot", docpilot_app)
19
  app.mount("/tracepilot", tracepilot_app)
20
+ app.mount("/gaugepilot", gaugepilot_app)
21
 
22
 
23
  @app.get("/")