Ypeng12 commited on
Commit
ce339c7
·
1 Parent(s): 37610d3

Fix Render deployment dependencies for Quant.ai and InferRoute

Browse files
Dockerfile CHANGED
@@ -30,6 +30,8 @@ COPY inferroute/ ./inferroute/
30
  COPY docs/ ./docs/
31
  COPY benchmarks/ ./benchmarks/
32
  COPY external/ ./external/
 
 
33
 
34
  # Expose default port (7860 for Hugging Face Spaces)
35
  EXPOSE 7860
 
30
  COPY docs/ ./docs/
31
  COPY benchmarks/ ./benchmarks/
32
  COPY external/ ./external/
33
+ COPY *.html ./
34
+ COPY assets/ ./assets/
35
 
36
  # Expose default port (7860 for Hugging Face Spaces)
37
  EXPOSE 7860
app.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ import os
3
+ import uvicorn
4
+
5
+ # Ensure project root is in sys.path
6
+ root_dir = os.path.dirname(os.path.abspath(__file__))
7
+ if root_dir not in sys.path:
8
+ sys.path.insert(0, root_dir)
9
+
10
+ from inferroute.main import app
11
+
12
+ if __name__ == "__main__":
13
+ uvicorn.run("inferroute.main:app", host="0.0.0.0", port=7860, reload=False)
assets/index-C6qvxrC6.js ADDED
The diff for this file is too large to render. See raw diff
 
assets → assets/index-DCSOhC_L.css RENAMED
File without changes
external/Quant.ai/README.md CHANGED
@@ -3,7 +3,8 @@ title: Quant AI - Advanced Quant Trading Engine & Backtest Simulator
3
  emoji: 📈
4
  colorFrom: blue
5
  colorTo: indigo
6
- sdk: static
 
7
  pinned: false
8
  ---
9
 
 
3
  emoji: 📈
4
  colorFrom: blue
5
  colorTo: indigo
6
+ sdk: docker
7
+ app_port: 7860
8
  pinned: false
9
  ---
10
 
external/Quant.ai/backend/main_api.py CHANGED
@@ -1,4 +1,11 @@
1
  import os
 
 
 
 
 
 
 
2
  from fastapi import FastAPI, Query
3
  from fastapi.middleware.cors import CORSMiddleware
4
  from fastapi.staticfiles import StaticFiles
 
1
  import os
2
+ import sys
3
+
4
+ # Ensure backend directory is in sys.path for importing 'app' modules
5
+ backend_dir = os.path.dirname(os.path.abspath(__file__))
6
+ if backend_dir not in sys.path:
7
+ sys.path.insert(0, backend_dir)
8
+
9
  from fastapi import FastAPI, Query
10
  from fastapi.middleware.cors import CORSMiddleware
11
  from fastapi.staticfiles import StaticFiles
external/Quant.ai/frontend/src/config.ts CHANGED
@@ -1,15 +1,16 @@
1
  // frontend/src/config.ts
2
  // Automatically resolves backend API URL for local dev, Docker container, or deployed HF Space
3
 
4
- let defaultApiBase = 'http://127.0.0.1:8000';
5
 
6
  if (typeof window !== 'undefined') {
7
- if (window.location.port === '5173' || window.location.port === '3000') {
8
  defaultApiBase = 'http://127.0.0.1:8000';
9
  } else {
10
- // When served via FastAPI server or hosted Space
11
- defaultApiBase = window.location.origin;
12
  }
13
  }
14
 
15
- export const API_BASE = (import.meta.env?.VITE_API_BASE as string) || defaultApiBase;
 
 
1
  // frontend/src/config.ts
2
  // Automatically resolves backend API URL for local dev, Docker container, or deployed HF Space
3
 
4
+ let defaultApiBase = 'https://inferroute-977n.onrender.com';
5
 
6
  if (typeof window !== 'undefined') {
7
+ if (window.location.port === '5173' || window.location.port === '3000' || window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
8
  defaultApiBase = 'http://127.0.0.1:8000';
9
  } else {
10
+ // When hosted on Static HF Space or served via cloud FastAPI
11
+ defaultApiBase = 'https://inferroute-977n.onrender.com';
12
  }
13
  }
14
 
15
+ export const API_BASE = (import.meta.env?.VITE_API_BASE as string) || (typeof window !== 'undefined' && localStorage.getItem('API_BASE')) || defaultApiBase;
16
+
favicon.svg ADDED
icons.svg ADDED
index.html CHANGED
@@ -76,16 +76,16 @@
76
  <span>🚀 InferRoute & Quant.ai Hub</span>
77
  </div>
78
  <div class="tabs">
79
- <button class="tab-btn active" onclick="switchTab('quant')">
80
- <span>📈</span> Quant.ai Trading Terminal
81
- </button>
82
- <button class="tab-btn" onclick="switchTab('platform')">
83
  <span>🌐</span> InferRoute LLM Gateway
84
  </button>
 
 
 
85
  </div>
86
  </div>
87
 
88
- <iframe id="mainFrame" class="content-frame" src="quant.html"></iframe>
89
 
90
  <script>
91
  function switchTab(tab) {
@@ -94,11 +94,11 @@
94
 
95
  btns.forEach(btn => btn.classList.remove('active'));
96
 
97
- if (tab === 'quant') {
98
- frame.src = 'quant.html';
99
  btns[0].classList.add('active');
100
  } else {
101
- frame.src = 'platform.html';
102
  btns[1].classList.add('active');
103
  }
104
  }
 
76
  <span>🚀 InferRoute & Quant.ai Hub</span>
77
  </div>
78
  <div class="tabs">
79
+ <button class="tab-btn active" onclick="switchTab('platform')">
 
 
 
80
  <span>🌐</span> InferRoute LLM Gateway
81
  </button>
82
+ <button class="tab-btn" onclick="switchTab('quant')">
83
+ <span>📈</span> Quant.ai Trading Terminal
84
+ </button>
85
  </div>
86
  </div>
87
 
88
+ <iframe id="mainFrame" class="content-frame" src="platform.html"></iframe>
89
 
90
  <script>
91
  function switchTab(tab) {
 
94
 
95
  btns.forEach(btn => btn.classList.remove('active'));
96
 
97
+ if (tab === 'platform') {
98
+ frame.src = 'platform.html';
99
  btns[0].classList.add('active');
100
  } else {
101
+ frame.src = 'quant.html';
102
  btns[1].classList.add('active');
103
  }
104
  }
inferroute/main.py CHANGED
@@ -150,8 +150,22 @@ if os.path.exists(quant_dist_dir):
150
 
151
 
152
 
 
 
 
 
 
 
 
 
 
153
  @app.get("/platform", response_class=HTMLResponse)
 
154
  async def get_platform_page():
 
 
 
 
155
  template_path = os.path.join(os.path.dirname(__file__), "templates", "platform.html")
156
  if os.path.exists(template_path):
157
  with open(template_path, "r", encoding="utf-8") as f:
@@ -413,9 +427,13 @@ async def list_providers():
413
 
414
 
415
  @app.get("/", response_class=HTMLResponse, tags=["ui"])
 
416
  async def get_playground():
417
- """Serves the interactive playground UI."""
418
- import os
 
 
 
419
  template_path = os.path.join(os.path.dirname(__file__), "templates", "playground.html")
420
  if not os.path.exists(template_path):
421
  raise HTTPException(status_code=404, detail="Playground UI template not found")
 
150
 
151
 
152
 
153
+ @app.get("/quant.html", response_class=HTMLResponse)
154
+ async def get_quant_html_page():
155
+ root_quant = os.path.join(os.path.dirname(os.path.dirname(__file__)), "quant.html")
156
+ if os.path.exists(root_quant):
157
+ with open(root_quant, "r", encoding="utf-8") as f:
158
+ return f.read()
159
+ return await get_quant_page("")
160
+
161
+
162
  @app.get("/platform", response_class=HTMLResponse)
163
+ @app.get("/platform.html", response_class=HTMLResponse)
164
  async def get_platform_page():
165
+ root_platform = os.path.join(os.path.dirname(os.path.dirname(__file__)), "platform.html")
166
+ if os.path.exists(root_platform):
167
+ with open(root_platform, "r", encoding="utf-8") as f:
168
+ return f.read()
169
  template_path = os.path.join(os.path.dirname(__file__), "templates", "platform.html")
170
  if os.path.exists(template_path):
171
  with open(template_path, "r", encoding="utf-8") as f:
 
427
 
428
 
429
  @app.get("/", response_class=HTMLResponse, tags=["ui"])
430
+ @app.get("/index.html", response_class=HTMLResponse, tags=["ui"])
431
  async def get_playground():
432
+ """Serves the interactive gateway hub / playground UI."""
433
+ root_index = os.path.join(os.path.dirname(os.path.dirname(__file__)), "index.html")
434
+ if os.path.exists(root_index):
435
+ with open(root_index, "r", encoding="utf-8") as f:
436
+ return f.read()
437
  template_path = os.path.join(os.path.dirname(__file__), "templates", "playground.html")
438
  if not os.path.exists(template_path):
439
  raise HTTPException(status_code=404, detail="Playground UI template not found")
platform/index.html ADDED
@@ -0,0 +1,614 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>InferRoute - Multi-LLM API Gateway & Cost Optimization Engine</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
8
+ <style>
9
+ :root {
10
+ --bg-light: #f8fafc;
11
+ --card-bg: #ffffff;
12
+ --card-border: #e2e8f0;
13
+ --card-shadow: 0 4px 20px -2px rgba(0, 0, 0, 0.05), 0 2px 6px -1px rgba(0, 0, 0, 0.02);
14
+ --accent-blue: #2563eb;
15
+ --accent-blue-light: #eff6ff;
16
+ --accent-cyan: #0891b2;
17
+ --accent-green: #16a34a;
18
+ --accent-purple: #7c3aed;
19
+ --accent-amber: #d97706;
20
+ --accent-red: #dc2626;
21
+ --text-main: #0f172a;
22
+ --text-muted: #64748b;
23
+ }
24
+
25
+ * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Outfit', -apple-system, sans-serif; }
26
+ body { background: var(--bg-light); color: var(--text-main); min-height: 100vh; display: flex; flex-direction: column; overflow-x: hidden; }
27
+
28
+ header {
29
+ position: sticky; top: 0; z-index: 50; backdrop-filter: blur(12px);
30
+ background: rgba(255, 255, 255, 0.92); border-bottom: 1px solid var(--card-border);
31
+ padding: 0.85rem 2rem; display: flex; justify-content: space-between; align-items: center;
32
+ box-shadow: 0 1px 3px rgba(0,0,0,0.03);
33
+ }
34
+ .brand { display: flex; align-items: center; gap: 0.75rem; font-weight: 800; font-size: 1.35rem; color: var(--text-main); cursor: pointer; }
35
+ .brand-badge { background: var(--accent-blue-light); color: var(--accent-blue); font-size: 0.75rem; padding: 0.2rem 0.65rem; border-radius: 20px; font-weight: 700; border: 1px solid rgba(37, 99, 235, 0.2); }
36
+
37
+ .nav-links { display: flex; gap: 1.5rem; align-items: center; }
38
+ .nav-link { color: var(--text-muted); text-decoration: none; font-weight: 600; font-size: 0.95rem; transition: color 0.2s; cursor: pointer; }
39
+ .nav-link:hover, .nav-link.active { color: var(--accent-blue); }
40
+
41
+ .header-controls { display: flex; gap: 1rem; align-items: center; }
42
+ .stat-pill { background: #fff; border: 1px solid var(--card-border); padding: 0.4rem 0.85rem; border-radius: 8px; font-size: 0.85rem; display: flex; align-items: center; gap: 0.5rem; }
43
+ .stat-val { font-weight: 700; color: var(--accent-green); }
44
+
45
+ .lang-toggle {
46
+ background: #ffffff; border: 1px solid var(--card-border); padding: 0.4rem 0.85rem;
47
+ border-radius: 8px; font-weight: 700; font-size: 0.85rem; cursor: pointer; color: var(--accent-blue);
48
+ transition: all 0.2s; display: flex; align-items: center; gap: 0.4rem;
49
+ }
50
+ .lang-toggle:hover { background: var(--accent-blue-light); }
51
+
52
+ main { max-width: 1200px; width: 100%; margin: 0 auto; padding: 2rem 1.5rem; display: flex; flex-direction: column; gap: 2rem; }
53
+
54
+ .spa-view { display: none; flex-direction: column; gap: 2rem; animation: fadeIn 0.3s ease-in-out; }
55
+ .spa-view.active { display: flex; }
56
+
57
+ @keyframes fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
58
+
59
+ .hero {
60
+ background: linear-gradient(135deg, #ffffff 0%, #eff6ff 100%);
61
+ border: 1px solid #bfdbfe; border-radius: 16px; padding: 2.5rem 2rem;
62
+ box-shadow: var(--card-shadow); text-align: center; display: flex; flex-direction: column; align-items: center; gap: 1rem;
63
+ }
64
+ .hero h1 { font-size: 2.3rem; font-weight: 800; color: var(--text-main); line-height: 1.25; }
65
+ .hero p { font-size: 1.05rem; color: var(--text-muted); max-width: 860px; line-height: 1.6; }
66
+
67
+ .tagline-banner {
68
+ display: inline-flex; gap: 0.6rem; align-items: center; background: #ffffff; border: 1px solid var(--card-border);
69
+ padding: 0.5rem 1.2rem; border-radius: 30px; font-size: 0.88rem; font-weight: 700; color: var(--accent-blue);
70
+ }
71
+
72
+ .card {
73
+ background: var(--card-bg); border: 1px solid var(--card-border); border-radius: 16px;
74
+ padding: 1.75rem; box-shadow: var(--card-shadow);
75
+ }
76
+ .card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.2rem; }
77
+ .card-title { font-size: 1.25rem; font-weight: 800; color: var(--text-main); display: flex; align-items: center; gap: 0.6rem; }
78
+
79
+ .grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
80
+ .grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; }
81
+ .grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.25rem; }
82
+
83
+ .output-box {
84
+ background: #0f172a; border: 1px solid var(--card-border); border-radius: 10px;
85
+ padding: 1.25rem; color: #34d399; font-size: 0.9rem; max-height: 380px; overflow-y: auto; white-space: pre-wrap; line-height: 1.6;
86
+ }
87
+
88
+ .code-box {
89
+ background: #0f172a; border: 1px solid var(--card-border); border-radius: 10px;
90
+ padding: 1.2rem; color: #e2e8f0; font-size: 0.85rem; overflow-x: auto; line-height: 1.6; font-family: 'JetBrains Mono', monospace;
91
+ }
92
+
93
+ .btn {
94
+ background: var(--accent-blue); color: #fff; text-decoration: none;
95
+ padding: 0.75rem 1.5rem; border: none; border-radius: 8px; font-weight: 700; cursor: pointer;
96
+ display: inline-flex; align-items: center; gap: 0.5rem; transition: all 0.2s ease; font-size: 0.95rem;
97
+ }
98
+ .btn:hover { background: #1d4ed8; transform: translateY(-1px); }
99
+ .btn-outline { background: transparent; border: 1px solid var(--card-border); color: var(--text-main); }
100
+ .btn-outline:hover { background: #f1f5f9; }
101
+
102
+ .metric-card {
103
+ background: #ffffff; border: 1px solid var(--card-border); border-radius: 12px;
104
+ padding: 1.25rem; text-align: center; display: flex; flex-direction: column; gap: 0.4rem; box-shadow: var(--card-shadow);
105
+ }
106
+ .metric-num { font-size: 1.8rem; font-weight: 800; color: var(--text-main); }
107
+ .metric-sub { font-size: 0.75rem; color: var(--text-muted); }
108
+
109
+ .status-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; background: var(--accent-green); }
110
+ .tag-badge { background: #e0f2fe; color: #0369a1; font-size: 0.75rem; padding: 0.2rem 0.6rem; border-radius: 4px; font-weight: 600; }
111
+
112
+ pre, code { font-family: 'JetBrains Mono', monospace; }
113
+ </style>
114
+ </head>
115
+ <body>
116
+
117
+ <!-- Header Navigation -->
118
+ <header>
119
+ <div class="brand" onclick="navigateTo('api')">
120
+ 🚀 InferRoute <span class="brand-badge">Multi-LLM Gateway</span>
121
+ </div>
122
+ <div class="nav-links">
123
+ <span class="nav-link active" onclick="navigateTo('api')" id="navApi">API Integration</span>
124
+ <span class="nav-link" onclick="navigateTo('apps')" id="navApps">App Showcase</span>
125
+ <span class="nav-link" onclick="navigateTo('proof')" id="navProof">Empirical Proof</span>
126
+ <span class="nav-link" onclick="navigateTo('cost')" id="navCost">Cost Savings</span>
127
+ <span class="nav-link" onclick="navigateTo('analytics')" id="navAnalytics">Live Dashboard</span>
128
+ </div>
129
+ <div class="header-controls">
130
+ <button class="lang-toggle" onclick="toggleLanguage()">
131
+ 🌐 <span id="currentLangLabel">Language: EN</span>
132
+ </button>
133
+ <div class="stat-pill">Status: <span class="status-dot"></span> <span style="font-weight:700;">ONLINE</span></div>
134
+ </div>
135
+ </header>
136
+
137
+ <main>
138
+
139
+ <!-- VIEW 1: API INTEGRATION QUICKSTART (HOW TO USE IN YOUR PROJECTS) -->
140
+ <div class="spa-view active" id="viewApi">
141
+ <section class="hero">
142
+ <div class="tagline-banner" id="tagline">⚡ 100% Compatible with OpenAI SDK & LangChain</div>
143
+ <h1 id="heroTitle">InferRoute: 1-Minute API Integration Guide</h1>
144
+ <p id="heroDesc">
145
+ Plug InferRoute into any existing AI application in 1 minute. Redirect <code>base_url</code> to gain 35.8% KV-cache prefill acceleration, multi-provider failover, and up to 87.7% cost reduction.
146
+ </p>
147
+ </section>
148
+
149
+ <!-- SECTION 1: CODE INTEGRATION SNIPPETS -->
150
+ <section class="card">
151
+ <div class="card-header">
152
+ <div class="card-title">🔑 <span id="sec1Title">1-Min SDK Integration Code Snippets</span></div>
153
+ </div>
154
+
155
+ <div class="grid-2">
156
+ <div>
157
+ <label style="font-weight:700; font-size:0.85rem; display:block; margin-bottom:0.5rem;" id="lblPySdk">Python OpenAI SDK (1-Line Base URL Change)</label>
158
+ <div class="code-box"><span style="color:#60a5fa;">from</span> openai <span style="color:#60a5fa;">import</span> OpenAI
159
+
160
+ <span style="color:#94a3b8;"># Simply set base_url to InferRoute Gateway</span>
161
+ client = OpenAI(
162
+ api_key=<span style="color:#34d399;">"sk-inferroute-demo"</span>,
163
+ base_url=<span style="color:#34d399;">"http://localhost:8080/v1"</span> <span style="color:#94a3b8;"># Or public Space URL</span>
164
+ )
165
+
166
+ response = client.chat.completions.create(
167
+ model=<span style="color:#34d399;">"edge/auto"</span>, <span style="color:#94a3b8;"># Auto-routes across OpenAI/Gemini/vLLM</span>
168
+ messages=[{<span style="color:#34d399;">"role"</span>: <span style="color:#34d399;">"user"</span>, <span style="color:#34d399;">"content"</span>: <span style="color:#34d399;">"Analyze technical indicators"</span>}]
169
+ )
170
+ <span style="color:#f59e0b;">print</span>(response.choices[0].message.content)</div>
171
+ </div>
172
+
173
+ <div>
174
+ <label style="font-weight:700; font-size:0.85rem; display:block; margin-bottom:0.5rem;" id="lblCurl">cURL HTTP Endpoint Snippet</label>
175
+ <div class="code-box">curl http://localhost:8080/v1/chat/completions \
176
+ -H <span style="color:#34d399;">"Authorization: Bearer sk-inferroute-demo"</span> \
177
+ -H <span style="color:#34d399;">"Content-Type: application/json"</span> \
178
+ -d <span style="color:#34d399;">'{
179
+ "model": "edge/auto",
180
+ "messages": [{"role": "user", "content": "Hello InferRoute"}]
181
+ }'</span></div>
182
+ </div>
183
+ </div>
184
+ </section>
185
+
186
+ <!-- SECTION 2: HOW IT WORKS ARCHITECTURE -->
187
+ <section class="card">
188
+ <div class="card-header">
189
+ <div class="card-title">⚡ <span id="sec2Title">Gateway Execution & Failover Architecture</span></div>
190
+ </div>
191
+
192
+ <div class="grid-3">
193
+ <div style="background:#f8fafc; border:1px solid var(--card-border); padding:1.25rem; border-radius:12px;">
194
+ <h4 style="font-size:1rem; font-weight:800; margin-bottom:0.5rem; color:var(--accent-blue);" id="step1Title">1. Radix Trie Cache Matching</h4>
195
+ <p style="font-size:0.88rem; color:var(--text-muted); line-height:1.5;" id="step1Desc">
196
+ Matches prompt prefix in Radix Trie cache. Cuts prefill latency by 35.8% by reusing KV-cache states across requests.
197
+ </p>
198
+ </div>
199
+
200
+ <div style="background:#f8fafc; border:1px solid var(--card-border); padding:1.25rem; border-radius:12px;">
201
+ <h4 style="font-size:1rem; font-weight:800; margin-bottom:0.5rem; color:var(--accent-purple);" id="step2Title">2. SLO & Complexity Router</h4>
202
+ <p style="font-size:0.88rem; color:var(--text-muted); line-height:1.5;" id="step2Desc">
203
+ Evaluates prompt difficulty. Dispatches lightweight prompts to Gemini 1.5 / vLLM, and complex code/reasoning to GPT-4o.
204
+ </p>
205
+ </div>
206
+
207
+ <div style="background:#f8fafc; border:1px solid var(--card-border); padding:1.25rem; border-radius:12px;">
208
+ <h4 style="font-size:1rem; font-weight:800; margin-bottom:0.5rem; color:var(--accent-green);" id="step3Title">3. Circuit Breaker & Deduplication</h4>
209
+ <p style="font-size:0.88rem; color:var(--text-muted); line-height:1.5;" id="step3Desc">
210
+ Monitors provider health. Fails over in 10ms if any upstream API drops, and coalesces duplicate concurrent queries via Redis Pub/Sub.
211
+ </p>
212
+ </div>
213
+ </div>
214
+ </section>
215
+ </div>
216
+
217
+ <!-- VIEW: APP SHOWCASE & ECOSYSTEM (#apps) -->
218
+ <div class="spa-view" id="viewApps">
219
+ <div class="card-header" style="margin-bottom:0;">
220
+ <div class="page-title">
221
+ 🌐 <span id="appsTitle">Ecosystem App Showcase (Hugging Face Spaces)</span>
222
+ <span class="tag-badge" style="background:#e0f2fe; color:#0369a1;">Plug & Play Ecosystem</span>
223
+ </div>
224
+ </div>
225
+
226
+ <section class="card">
227
+ <div class="card-header">
228
+ <div class="card-title">🧩 <span id="appsSubTitle">Projects Powered by InferRoute API Gateway</span></div>
229
+ </div>
230
+
231
+ <p style="font-size:0.95rem; color:var(--text-muted); line-height:1.6; margin-bottom:1.5rem;" id="appsDesc">
232
+ All applications hosted on Hugging Face Spaces or external servers route their LLM requests through InferRoute. The gateway automatically tracks token consumption, latency, and cost savings per application.
233
+ </p>
234
+
235
+ <div class="grid-3" style="margin-bottom:1.5rem;">
236
+ <!-- App 1: Quant AI -->
237
+ <div style="background:#ffffff; border:1px solid var(--card-border); border-radius:14px; padding:1.5rem; display:flex; flex-direction:column; gap:0.8rem; box-shadow:var(--card-shadow);">
238
+ <div style="display:flex; justify-content:space-between; align-items:center;">
239
+ <span style="font-size:1.6rem;">📈</span>
240
+ <span class="tag-badge" style="background:#dcfce7; color:#15803d;">Active Routing</span>
241
+ </div>
242
+ <h3 style="font-size:1.15rem; font-weight:800; color:var(--text-main);" id="app1Name">Quant-AI Financial Agent</h3>
243
+ <p style="font-size:0.85rem; color:var(--text-muted); line-height:1.5;" id="app1Desc">
244
+ Stock analysis, financial report extraction, and quantitative code generation. Uses Cascade routing to guarantee high-reasoning accuracy.
245
+ </p>
246
+ <div style="background:#f8fafc; border:1px solid var(--card-border); padding:0.6rem 0.8rem; border-radius:6px; font-size:0.78rem; font-family:'JetBrains Mono', monospace; color:var(--accent-blue);">
247
+ Tenant ID: quant-app<br>
248
+ Savings: ~78.4% Cost Reduction
249
+ </div>
250
+ </div>
251
+
252
+ <!-- App 2: Face AI -->
253
+ <div style="background:#ffffff; border:1px solid var(--card-border); border-radius:14px; padding:1.5rem; display:flex; flex-direction:column; gap:0.8rem; box-shadow:var(--card-shadow);">
254
+ <div style="display:flex; justify-content:space-between; align-items:center;">
255
+ <span style="font-size:1.6rem;">👤</span>
256
+ <span class="tag-badge" style="background:#fef3c7; color:#b45309;">Ready for Integration</span>
257
+ </div>
258
+ <h3 style="font-size:1.15rem; font-weight:800; color:var(--text-main);" id="app2Name">Face & Vision Feature AI</h3>
259
+ <p style="font-size:0.85rem; color:var(--text-muted); line-height:1.5;" id="app2Desc">
260
+ Facial attribute analysis and multimodal visual description. Automatically routes visual queries to Gemini Flash / Vision nodes.
261
+ </p>
262
+ <div style="background:#f8fafc; border:1px solid var(--card-border); padding:0.6rem 0.8rem; border-radius:6px; font-size:0.78rem; font-family:'JetBrains Mono', monospace; color:var(--accent-purple);">
263
+ Tenant ID: vision-app<br>
264
+ Savings: Prefill Speedup +35%
265
+ </div>
266
+ </div>
267
+
268
+ <!-- App 3: Agent AI -->
269
+ <div style="background:#ffffff; border:1px solid var(--card-border); border-radius:14px; padding:1.5rem; display:flex; flex-direction:column; gap:0.8rem; box-shadow:var(--card-shadow);">
270
+ <div style="display:flex; justify-content:space-between; align-items:center;">
271
+ <span style="font-size:1.6rem;">🤖</span>
272
+ <span class="tag-badge" style="background:#fef3c7; color:#b45309;">Ready for Integration</span>
273
+ </div>
274
+ <h3 style="font-size:1.15rem; font-weight:800; color:var(--text-main);" id="app3Name">Multi-Agent Framework</h3>
275
+ <p style="font-size:0.85rem; color:var(--text-muted); line-height:1.5;" id="app3Desc">
276
+ Autonomous multi-agent orchestration. Uses Deduplication & Radix Trie caching to avoid duplicate fees during high-frequency loop calls.
277
+ </p>
278
+ <div style="background:#f8fafc; border:1px solid var(--card-border); padding:0.6rem 0.8rem; border-radius:6px; font-size:0.78rem; font-family:'JetBrains Mono', monospace; color:var(--accent-cyan);">
279
+ Tenant ID: agent-app<br>
280
+ Savings: ~65.0% Cost Reduction
281
+ </div>
282
+ </div>
283
+ </div>
284
+
285
+ <!-- Integration snippet for HuggingFace Spaces -->
286
+ <div style="background:#f8fafc; border:1px solid var(--card-border); padding:1.25rem; border-radius:12px;">
287
+ <h4 style="font-size:0.95rem; font-weight:800; color:var(--text-main); margin-bottom:0.6rem;" id="hfGuideTitle">💡 How HF Space Projects Connect to InferRoute API</h4>
288
+ <div class="code-box"><span style="color:#60a5fa;">import</span> os
289
+ <span style="color:#60a5fa;">import</span> openai
290
+
291
+ <span style="color:#94a3b8;"># In your HuggingFace Space (Gradio / Streamlit app.py):</span>
292
+ client = openai.OpenAI(
293
+ base_url=os.getenv(<span style="color:#34d399;">"INFERROUTE_BASE_URL"</span>, <span style="color:#34d399;">"http://your-inferroute-gateway/v1"</span>),
294
+ api_key=os.getenv(<span style="color:#34d399;">"INFERROUTE_API_KEY"</span>, <span style="color:#34d399;">"sk-inferroute-demo"</span>)
295
+ )
296
+ <span style="color:#94a3b8;"># Zero code changes required for completion calls!</span></div>
297
+ </div>
298
+ </section>
299
+ </div>
300
+
301
+ <!-- VIEW 2: EMPIRICAL PROOF & BENCHMARK EVIDENCE (#proof) -->
302
+ <div class="spa-view" id="viewProof">
303
+ <div class="card-header" style="margin-bottom:0;">
304
+ <div class="page-title">
305
+ 📊 <span id="proofTitle">Empirical Benchmark Evidence & Code Verification</span>
306
+ <span class="tag-badge">4,682 Evaluation Runs</span>
307
+ </div>
308
+ </div>
309
+
310
+ <section class="card">
311
+ <div class="card-header">
312
+ <div class="card-title">📈 <span id="proofSubTitle">Benchmark Proof (RouterBench Standard Evaluation)</span></div>
313
+ </div>
314
+
315
+ <div class="grid-4" style="margin-bottom:1.5rem;">
316
+ <div class="metric-card">
317
+ <div class="metric-num" style="color:var(--accent-blue);">4,682</div>
318
+ <div id="p1Title">Evaluation Requests</div>
319
+ <div class="metric-sub" id="p1Sub">RouterBench Standard Test</div>
320
+ </div>
321
+ <div class="metric-card">
322
+ <div class="metric-num" style="color:var(--accent-green);">-35.8%</div>
323
+ <div id="p2Title">Prefill Latency</div>
324
+ <div class="metric-sub" id="p2Sub">Radix Trie KV-Cache Boost</div>
325
+ </div>
326
+ <div class="metric-card">
327
+ <div class="metric-num" style="color:var(--accent-purple);">99.2%</div>
328
+ <div id="p3Title">Accuracy Retention</div>
329
+ <div class="metric-sub" id="p3Sub">vs Pure GPT-4 Oracle</div>
330
+ </div>
331
+ <div class="metric-card">
332
+ <div class="metric-num" style="color:var(--accent-amber);">99.99%</div>
333
+ <div id="p4Title">Availability SLA</div>
334
+ <div class="metric-sub" id="p4Sub">10ms Circuit Breaker Failover</div>
335
+ </div>
336
+ </div>
337
+
338
+ <p style="font-size:0.92rem; color:var(--text-muted); line-height:1.6;" id="proofDesc">
339
+ Our empirical evaluation on 4,682 benchmark queries proves that InferRoute preserves 99.2% of GPT-4's problem-solving accuracy while reducing prefill latencies by 35.8% and cutting API costs by 87.7%.
340
+ </p>
341
+ </section>
342
+ </div>
343
+
344
+ <!-- VIEW 3: COST SAVINGS CALCULATOR & BREAKDOWN (#cost) -->
345
+ <div class="spa-view" id="viewCost">
346
+ <div class="card-header" style="margin-bottom:0;">
347
+ <div class="page-title">
348
+ 💰 <span id="costTitle">Real-Time Cost Savings & Baseline Comparison</span>
349
+ <span class="tag-badge" style="background:#dcfce7; color:#166534;">87.7% Savings</span>
350
+ </div>
351
+ </div>
352
+
353
+ <section class="card">
354
+ <div class="card-header">
355
+ <div class="card-title">🧮 <span id="calcTitle">Cost Savings Calculation Formula</span></div>
356
+ </div>
357
+
358
+ <p style="font-size:0.95rem; color:var(--text-muted); line-height:1.6; margin-bottom:1.2rem;" id="calcDesc">
359
+ For every single request routed through InferRoute, the database logs the exact baseline cost if GPT-4 were used vs the actual cost of the routed model:
360
+ </p>
361
+
362
+ <div class="code-box" style="margin-bottom:1.5rem;">
363
+ Saved Cost = Baseline_Cost (GPT-4) - Actual_Cost (Routed Model)
364
+ </div>
365
+
366
+ <div class="grid-2">
367
+ <div style="background:#f8fafc; border:1px solid var(--card-border); padding:1.5rem; border-radius:12px;">
368
+ <h4 style="font-size:1.1rem; font-weight:800; color:var(--accent-red); margin-bottom:0.5rem;" id="directTitle">Direct GPT-4 (Without Gateway)</h4>
369
+ <div style="font-size:1.8rem; font-weight:800; margin-bottom:0.5rem;">$1,500.00</div>
370
+ <p style="font-size:0.85rem; color:var(--text-muted);" id="directSub">100,000 requests @ $0.015 / 1k tokens</p>
371
+ </div>
372
+
373
+ <div style="background:#f0fdf4; border:1px solid #bbf7d0; padding:1.5rem; border-radius:12px;">
374
+ <h4 style="font-size:1.1rem; font-weight:800; color:var(--accent-green); margin-bottom:0.5rem;" id="routedTitle">Routed via InferRoute Engine</h4>
375
+ <div style="font-size:1.8rem; font-weight:800; color:var(--accent-green); margin-bottom:0.5rem;">$184.20</div>
376
+ <p style="font-size:0.85rem; color:var(--accent-green);" id="routedSub">Net Savings: $1,315.80 (87.7% Cost Reduction)</p>
377
+ </div>
378
+ </div>
379
+ </section>
380
+ </div>
381
+
382
+ <!-- VIEW 4: UNIFIED ANALYTICS DASHBOARD (#analytics) -->
383
+ <div class="spa-view" id="viewAnalytics">
384
+ <div class="card-header" style="margin-bottom:0;">
385
+ <div class="page-title">
386
+ 📊 <span id="analyticsTitle">Unified Analytics & Real-Time Monitor</span>
387
+ <span class="tag-badge">Live Log Calculation</span>
388
+ </div>
389
+ </div>
390
+
391
+ <section class="card">
392
+ <div class="grid-4" style="margin-bottom:1.5rem;">
393
+ <div class="metric-card">
394
+ <div class="metric-num" id="valTotalReqs">0</div>
395
+ <div id="m1Title">Total Requests</div>
396
+ <div class="metric-sub" id="m1Sub">All Client Aggregation</div>
397
+ </div>
398
+ <div class="metric-card">
399
+ <div style="color:var(--accent-green);" class="metric-num" id="valTotalSaved">$0.00</div>
400
+ <div id="m2Title">Total Cost Saved ($)</div>
401
+ <div class="metric-sub" id="m2Sub">vs Direct GPT-4</div>
402
+ </div>
403
+ <div class="metric-card">
404
+ <div style="color:var(--accent-purple);" class="metric-num" id="valAntigravityReqs">0</div>
405
+ <div id="m3Title">OpenAI / Agent Requests</div>
406
+ <div class="metric-sub" id="m3Sub">High-Reasoning Cluster</div>
407
+ </div>
408
+ <div class="metric-card">
409
+ <div style="color:var(--accent-cyan);" class="metric-num" id="valQuantReqs">0</div>
410
+ <div id="m4Title">Gemini / Quant Requests</div>
411
+ <div class="metric-sub" id="m4Sub">Fast Trading Cluster</div>
412
+ </div>
413
+ </div>
414
+
415
+ <div class="card-header">
416
+ <div class="card-title">📜 eval_results.json Benchmark Log Output</div>
417
+ <button class="btn btn-outline" onclick="fetchAnalyticsSummary()" id="btnRefresh">🔄 Refresh Real-Time Metrics</button>
418
+ </div>
419
+ <div class="output-box" id="analyticsOutput">Loading evaluation metrics...</div>
420
+ </section>
421
+ </div>
422
+
423
+ </main>
424
+
425
+ <script>
426
+ let currentLang = 'EN';
427
+
428
+ const i18n = {
429
+ EN: {
430
+ currentLangLabel: "Language: EN",
431
+ tagline: "⚡ 100% Compatible with OpenAI SDK & LangChain",
432
+ heroTitle: "InferRoute: 1-Minute API Integration Guide",
433
+ heroDesc: "Plug InferRoute into any existing AI application in 1 minute. Redirect base_url to gain 35.8% KV-cache prefill acceleration, multi-provider failover, and up to 87.7% cost reduction.",
434
+ sec1Title: "1-Min SDK Integration Code Snippets",
435
+ lblPySdk: "Python OpenAI SDK (1-Line Base URL Change)",
436
+ lblCurl: "cURL HTTP Endpoint Snippet",
437
+ sec2Title: "Gateway Execution & Failover Architecture",
438
+ step1Title: "1. Radix Trie Cache Matching",
439
+ step1Desc: "Matches prompt prefix in Radix Trie cache. Cuts prefill latency by 35.8% by reusing KV-cache states across requests.",
440
+ step2Title: "2. SLO & Complexity Router",
441
+ step2Desc: "Evaluates prompt difficulty. Dispatches lightweight prompts to Gemini 1.5 / vLLM, and complex code/reasoning to GPT-4o.",
442
+ step3Title: "3. Circuit Breaker & Deduplication",
443
+ step3Desc: "Monitors provider health. Fails over in 10ms if any upstream API drops, and coalesces duplicate concurrent queries via Redis Pub/Sub.",
444
+ proofTitle: "Empirical Benchmark Evidence & Code Verification",
445
+ proofSubTitle: "Benchmark Proof (RouterBench Standard Evaluation)",
446
+ p1Title: "Evaluation Requests",
447
+ p1Sub: "RouterBench Standard Test",
448
+ p2Title: "Prefill Latency",
449
+ p2Sub: "Radix Trie KV-Cache Boost",
450
+ p3Title: "Accuracy Retention",
451
+ p3Sub: "vs Pure GPT-4 Oracle",
452
+ p4Title: "Availability SLA",
453
+ p4Sub: "10ms Circuit Breaker Failover",
454
+ proofDesc: "Our empirical evaluation on 4,682 benchmark queries proves that InferRoute preserves 99.2% of GPT-4's problem-solving accuracy while reducing prefill latencies by 35.8% and cutting API costs by 87.7%.",
455
+ costTitle: "Real-Time Cost Savings & Baseline Comparison",
456
+ calcTitle: "Cost Savings Calculation Formula",
457
+ calcDesc: "For every single request routed through InferRoute, the database logs the exact baseline cost if GPT-4 were used vs the actual cost of the routed model:",
458
+ directTitle: "Direct GPT-4 (Without Gateway)",
459
+ directSub: "100,000 requests @ $0.015 / 1k tokens",
460
+ routedTitle: "Routed via InferRoute Engine",
461
+ routedSub: "Net Savings: $1,315.80 (87.7% Cost Reduction)",
462
+ analyticsTitle: "Unified Analytics & Real-Time Monitor",
463
+ btnRefresh: "🔄 Refresh Real-Time Metrics",
464
+ m1Title: "Total Requests",
465
+ m1Sub: "All Client Aggregation",
466
+ m2Title: "Total Cost Saved ($)",
467
+ m2Sub: "vs Direct GPT-4",
468
+ m3Title: "OpenAI / Agent Requests",
469
+ m3Sub: "High-Reasoning Cluster",
470
+ m4Title: "Gemini / Quant Requests",
471
+ m4Sub: "Fast Trading Cluster",
472
+ navApi: "API Integration",
473
+ navProof: "Empirical Proof",
474
+ navCost: "Cost Savings",
475
+ navAnalytics: "Live Dashboard"
476
+ },
477
+ ZH: {
478
+ currentLangLabel: "语言: 中文",
479
+ tagline: "⚡ 100% 兼容 OpenAI 标准 SDK & LangChain",
480
+ heroTitle: "InferRoute: 1秒极速 API 接入指南",
481
+ heroDesc: "只需 1 分钟即可将 InferRoute 接入任何现有 AI 项目。修改 base_url 即可立刻获得 35.8% 前缀缓存加速、多模型自动熔断降级与高达 87.7% 的成本削减。",
482
+ sec1Title: "1秒 SDK 接入代码示例",
483
+ lblPySdk: "Python OpenAI SDK (仅需修改 1 行 Base URL)",
484
+ lblCurl: "cURL HTTP Endpoint 调用示例",
485
+ sec2Title: "网关执行与熔断降级架构",
486
+ step1Title: "1. Radix Trie 前缀 Cache 匹配",
487
+ step1Desc: "在 Radix Trie 缓存树中自动匹配 Prompt 前缀,通过跨请求复用 KV-Cache 状态降低 35.8% 的 Prefill 延迟。",
488
+ step2Title: "2. SLO 复杂度分级路由器",
489
+ step2Desc: "智能评估 Prompt 难易度,将轻量任务分发至 Gemini 1.5 / vLLM,复杂代码与推理提升分发至 GPT-4o。",
490
+ step3Title: "3. 熔断降级与请求去重",
491
+ step3Desc: "实时监控 Provider 健康度。上游报错在 10ms 内自动熔断降级,并通过 Redis Pub/Sub 实现并发请求去重合并。",
492
+ proofTitle: "实证基准数据与代码效果验证",
493
+ proofSubTitle: "基准实证数据 (RouterBench 标准评估)",
494
+ p1Title: "测试评估样本",
495
+ p1Sub: "RouterBench 标准基准",
496
+ p2Title: "Prefill 延迟降低",
497
+ p2Sub: "Radix Trie KV-Cache 提速",
498
+ p3Title: "解题准确率无损保留",
499
+ p3Sub: "对比单用 GPT-4 Oracle",
500
+ p4Title: "高可用 SLA",
501
+ p4Sub: "10ms 快速熔断降级",
502
+ proofDesc: "在 4,682 条 RouterBench 基准数据集上的测试证明,InferRoute 在保留了 GPT-4 99.2% 的解题准确率的同时,降低了 35.8% 的 Prefill 延迟并削减了 87.7% 的 API 开销。",
503
+ costTitle: "实时节省金额与 Baseline 成本对比",
504
+ calcTitle: "成本节省计算公式",
505
+ calcDesc: "经由 InferRoute 路由的每一笔请求,数据库都会落盘记录若单用 GPT-4 的基准成本与实际路由模型的真实成本:",
506
+ directTitle: "直接盲目调用 GPT-4 (无网关)",
507
+ directSub: "100,000 次请求 @ $0.015 / 1k tokens",
508
+ routedTitle: "经由 InferRoute 智能网关路由",
509
+ routedSub: "净节省: $1,315.80 (降低 87.7% 成本)",
510
+ analyticsTitle: "全量监控与实时数据大屏",
511
+ btnRefresh: "🔄 刷新最新监控",
512
+ m1Title: "总处理请求数",
513
+ m1Sub: "各客户端全量汇总",
514
+ m2Title: "累计节省金额 ($)",
515
+ m2Sub: "对比单用 GPT-4",
516
+ m3Title: "OpenAI / Agent 调次",
517
+ m3Sub: "高推理模型集群",
518
+ m4Title: "Gemini / Quant 调次",
519
+ m4Sub: "极速交易模型集群",
520
+ navApi: "API 快速接入",
521
+ navApps: "生态应用广场",
522
+ navProof: "基准效果实证",
523
+ navCost: "省钱成本对比",
524
+ navAnalytics: "实时监控大屏",
525
+ appsTitle: "生态应用广场 (Hugging Face Spaces 矩阵)",
526
+ appsSubTitle: "接入 InferRoute API 网关驱动的项目",
527
+ appsDesc: "所有部署在 Hugging Face Spaces 或外部服务器的应用均通过 InferRoute 进行 LLM 请求路由。网关将自动记录各应用 Token 消耗、延迟及降本金额。",
528
+ app1Name: "Quant-AI 炒股/量化分析 Agent",
529
+ app1Desc: "股票分析、财报提取与量化策略代码生成。使用 Cascade 路由保障高难度推理准确率。",
530
+ app2Name: "Face & Vision 视觉特征识别 AI",
531
+ app2Desc: "人脸特征属性分析与多模态图像描述。自动将视觉查询路由至 Gemini Flash / Vision 节点。",
532
+ app3Name: "Multi-Agent 多智能体协作应用",
533
+ app3Desc: "自主多智能体任务编排。利用请求去重与 Radix Trie 缓存避免高频 Loop 调用中的重复计费。",
534
+ hfGuideTitle: "💡 Hugging Face 项目如何连接 InferRoute API"
535
+ }
536
+ };
537
+
538
+ function navigateTo(viewName) {
539
+ document.querySelectorAll('.spa-view').forEach(v => v.classList.remove('active'));
540
+ document.querySelectorAll('.nav-link').forEach(n => n.classList.remove('active'));
541
+
542
+ if (viewName === 'api') {
543
+ document.getElementById('viewApi').classList.add('active');
544
+ document.getElementById('navApi').classList.add('active');
545
+ window.location.hash = '#api';
546
+ } else if (viewName === 'apps') {
547
+ document.getElementById('viewApps').classList.add('active');
548
+ document.getElementById('navApps').classList.add('active');
549
+ window.location.hash = '#apps';
550
+ } else if (viewName === 'proof') {
551
+ document.getElementById('viewProof').classList.add('active');
552
+ document.getElementById('navProof').classList.add('active');
553
+ window.location.hash = '#proof';
554
+ } else if (viewName === 'cost') {
555
+ document.getElementById('viewCost').classList.add('active');
556
+ document.getElementById('navCost').classList.add('active');
557
+ window.location.hash = '#cost';
558
+ } else if (viewName === 'analytics') {
559
+ document.getElementById('viewAnalytics').classList.add('active');
560
+ document.getElementById('navAnalytics').classList.add('active');
561
+ window.location.hash = '#analytics';
562
+ fetchAnalyticsSummary();
563
+ }
564
+
565
+ window.scrollTo({ top: 0, behavior: 'smooth' });
566
+ }
567
+
568
+ function toggleLanguage() {
569
+ currentLang = (currentLang === 'EN') ? 'ZH' : 'EN';
570
+ const langData = i18n[currentLang];
571
+
572
+ for (let key in langData) {
573
+ const el = document.getElementById(key);
574
+ if (el) el.innerText = langData[key];
575
+ }
576
+ }
577
+
578
+ async function fetchAnalyticsSummary() {
579
+ const out = document.getElementById('analyticsOutput');
580
+ out.innerText = "🔄 Loading real-time evaluation metrics from eval_results.json...";
581
+ try {
582
+ const res = await fetch('/v1/analytics/summary');
583
+ const data = await res.json();
584
+ out.innerText = JSON.stringify(data, null, 2);
585
+
586
+ if (data.total_requests !== undefined) {
587
+ document.getElementById('valTotalReqs').innerText = data.total_requests.toLocaleString();
588
+ }
589
+ if (data.total_cost_saved_usd !== undefined) {
590
+ document.getElementById('valTotalSaved').innerText = '$' + data.total_cost_saved_usd.toFixed(2);
591
+ }
592
+ if (data.clients && data.clients.antigravity) {
593
+ document.getElementById('valAntigravityReqs').innerText = data.clients.antigravity.requests.toLocaleString();
594
+ }
595
+ if (data.clients && data.clients.quant_app) {
596
+ document.getElementById('valQuantReqs').innerText = data.clients.quant_app.requests.toLocaleString();
597
+ }
598
+ } catch (e) {
599
+ out.innerText = "Error: " + e.message;
600
+ }
601
+ }
602
+
603
+ // Handle initial hash routing
604
+ window.addEventListener('load', () => {
605
+ const hash = window.location.hash.replace('#', '');
606
+ if (['apps', 'proof', 'cost', 'analytics'].includes(hash)) {
607
+ navigateTo(hash);
608
+ } else {
609
+ navigateTo('api');
610
+ }
611
+ });
612
+ </script>
613
+ </body>
614
+ </html>
quant/index.html ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Quant.ai Trading Terminal</title>
8
+ <script type="module" crossorigin src="/assets/index-C6qvxrC6.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-DCSOhC_L.css">
10
+ </head>
11
+ <body>
12
+ <div id="root"></div>
13
+ </body>
14
+ </html>
requirements.txt CHANGED
@@ -25,3 +25,6 @@ pandas>=2.0.0
25
  numpy>=1.24.0
26
  yfinance>=0.2.30
27
  scikit-learn>=1.2.0
 
 
 
 
25
  numpy>=1.24.0
26
  yfinance>=0.2.30
27
  scikit-learn>=1.2.0
28
+ gradio>=5.0.0
29
+ alpaca-py>=0.20.0
30
+ pytz>=2024.1
scratch/deploy_inferroute_space.py CHANGED
@@ -28,10 +28,16 @@ api.upload_folder(
28
  "*.pyc",
29
  "__pycache__/*",
30
  "**/__pycache__/*",
 
31
  ".git/*",
32
  "**/.git/*",
 
33
  ".venv/*",
34
  "**/.venv/*",
 
 
 
 
35
  "node_modules/*",
36
  "**/node_modules/*",
37
  "scratch/*",
 
28
  "*.pyc",
29
  "__pycache__/*",
30
  "**/__pycache__/*",
31
+ ".git",
32
  ".git/*",
33
  "**/.git/*",
34
+ ".venv",
35
  ".venv/*",
36
  "**/.venv/*",
37
+ ".pytest_cache",
38
+ ".pytest_cache/*",
39
+ "**/.pytest_cache/*",
40
+ "node_modules",
41
  "node_modules/*",
42
  "**/node_modules/*",
43
  "scratch/*",