Azizahalq commited on
Commit
b0b80a0
·
verified ·
1 Parent(s): 5ce2255

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -15
app.py CHANGED
@@ -3,15 +3,21 @@ import os, re, json, textwrap, traceback
3
  from decimal import Decimal
4
  from typing import List, Tuple
5
 
6
- from flask import Flask, request, render_template
7
  from flask_cors import CORS
8
- from rag_mini import search, ensure_ready, DEFAULT_TOPK
 
 
 
 
 
 
9
 
10
  # ------------ LLM config ------------
11
- LLM_PROVIDER = (os.getenv("LLM_PROVIDER") or "openai").strip().lower()
12
- LLM_MODEL = (os.getenv("LLM_MODEL") or "gpt-4o-mini").strip()
13
- LLM_API_KEY = os.getenv("OPENAI_API_KEY") or os.getenv("LLM_API_KEY")
14
- OPENAI_BASE_URL = os.getenv("OPENAI_BASE_URL") # optional
15
 
16
  app = Flask(__name__)
17
  app.secret_key = os.getenv("FLASK_SECRET_KEY", "change-me-please")
@@ -24,8 +30,8 @@ Return two things:
24
  "candidates": [
25
  {
26
  "name": "string",
27
- "score": 0, // 0..400
28
- "score_pct": 0, // 0..100
29
  "reasons": ["..."],
30
  "tradeoffs": ["..."],
31
  "citations": ["[1]", "[2]"]
@@ -36,7 +42,7 @@ Return two things:
36
  Rules:
37
  - Use only the provided context; cite with [1], [2]. No fabrication.
38
  - Utilities per criterion are in [0,1]. Cost utility increases as cost decreases.
39
- - Weights are independent 0..100 (not normalized).
40
  """
41
 
42
  ANSWER_TEMPLATE = """User constraints:
@@ -148,6 +154,10 @@ def healthz():
148
  "has_api_key": bool(LLM_API_KEY),
149
  }, 200
150
 
 
 
 
 
151
  @app.get("/")
152
  def index():
153
  return render_template("index.html", default_k=DEFAULT_TOPK)
@@ -175,15 +185,14 @@ def recommend():
175
  f"Consider budget={budget} and process={process}. "
176
  f"Rank by performance, stability, cost, and availability.")
177
 
178
- # RAG search can fail if embeddings libs are missing – catch it
179
  try:
180
  hits = search(question, k=k)
 
181
  except Exception as e:
182
  app.logger.exception("RAG search failed")
183
  hits = []
184
  rag_error = f"RAG error: {type(e).__name__}: {e}"
185
- else:
186
- rag_error = ""
187
 
188
  ctx, cites = format_context(hits)
189
 
@@ -195,7 +204,7 @@ def recommend():
195
  context=ctx, citations=cites
196
  )
197
 
198
- # LLM call catch and show the error text instead of 500
199
  raw = ""
200
  try:
201
  raw = call_llm_cloud(SYSTEM_RULES, user_prompt)
@@ -206,7 +215,6 @@ def recommend():
206
  parsed = extract_json_block(raw) if raw else None
207
  candidates = (parsed or {}).get("candidates", []) if parsed else []
208
 
209
- # Append any RAG error to the raw output so you see it in UI
210
  if rag_error:
211
  raw = f"{rag_error}\n\n{raw}"
212
 
@@ -219,7 +227,6 @@ def recommend():
219
  raw_output=raw or "",
220
  )
221
  except Exception as e:
222
- # Last-resort guard: never return 500 to the user without context
223
  app.logger.exception("recommend() hard failure")
224
  tb = traceback.format_exc()
225
  return render_template(
 
3
  from decimal import Decimal
4
  from typing import List, Tuple
5
 
6
+ from flask import Flask, request, render_template, url_for
7
  from flask_cors import CORS
8
+
9
+ from rag_mini import (
10
+ search,
11
+ ensure_ready,
12
+ DEFAULT_TOPK,
13
+ rag_debug_info, # for /debug/rag
14
+ )
15
 
16
  # ------------ LLM config ------------
17
+ LLM_PROVIDER = (os.getenv("LLM_PROVIDER") or "openai").strip().lower()
18
+ LLM_MODEL = (os.getenv("LLM_MODEL") or "gpt-4o-mini").strip()
19
+ LLM_API_KEY = os.getenv("OPENAI_API_KEY") or os.getenv("LLM_API_KEY")
20
+ OPENAI_BASE_URL = os.getenv("OPENAI_BASE_URL") # optional (Azure/proxy)
21
 
22
  app = Flask(__name__)
23
  app.secret_key = os.getenv("FLASK_SECRET_KEY", "change-me-please")
 
30
  "candidates": [
31
  {
32
  "name": "string",
33
+ "score": 0, // 0..400 (sum of 4 independent 0..100 utilities)
34
+ "score_pct": 0, // 0..100 normalized display
35
  "reasons": ["..."],
36
  "tradeoffs": ["..."],
37
  "citations": ["[1]", "[2]"]
 
42
  Rules:
43
  - Use only the provided context; cite with [1], [2]. No fabrication.
44
  - Utilities per criterion are in [0,1]. Cost utility increases as cost decreases.
45
+ - Weights (performance, stability, cost, availability) are independent 0..100 (NOT normalized).
46
  """
47
 
48
  ANSWER_TEMPLATE = """User constraints:
 
154
  "has_api_key": bool(LLM_API_KEY),
155
  }, 200
156
 
157
+ @app.get("/debug/rag")
158
+ def debug_rag():
159
+ return rag_debug_info(), 200
160
+
161
  @app.get("/")
162
  def index():
163
  return render_template("index.html", default_k=DEFAULT_TOPK)
 
185
  f"Consider budget={budget} and process={process}. "
186
  f"Rank by performance, stability, cost, and availability.")
187
 
188
+ # RAG search (never crash UI)
189
  try:
190
  hits = search(question, k=k)
191
+ rag_error = ""
192
  except Exception as e:
193
  app.logger.exception("RAG search failed")
194
  hits = []
195
  rag_error = f"RAG error: {type(e).__name__}: {e}"
 
 
196
 
197
  ctx, cites = format_context(hits)
198
 
 
204
  context=ctx, citations=cites
205
  )
206
 
207
+ # LLM call (never crash UI)
208
  raw = ""
209
  try:
210
  raw = call_llm_cloud(SYSTEM_RULES, user_prompt)
 
215
  parsed = extract_json_block(raw) if raw else None
216
  candidates = (parsed or {}).get("candidates", []) if parsed else []
217
 
 
218
  if rag_error:
219
  raw = f"{rag_error}\n\n{raw}"
220
 
 
227
  raw_output=raw or "",
228
  )
229
  except Exception as e:
 
230
  app.logger.exception("recommend() hard failure")
231
  tb = traceback.format_exc()
232
  return render_template(