mzidan000 commited on
Commit
6638954
·
verified ·
1 Parent(s): 9f26f45

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +26 -0
app.py CHANGED
@@ -97,6 +97,27 @@ async def _pulse(coro, holder, message, interval: int = 9):
97
  yield _ev(type="commentary", text=f"{message} ({int(time.monotonic() - start)}s)")
98
 
99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  async def _agent_explain(agent, user_text: str, trip: TripRequest, result) -> str:
101
  """Round 2 — Nemotron compares the packages. Best-effort ('' on failure)."""
102
  args_json = json.dumps(trip.model_dump(mode="json"))
@@ -136,6 +157,11 @@ async def plan_trip(user_text: str) -> str:
136
  + Nemotron's explanation). Falls back to the deterministic parser if the
137
  agent is unavailable or hedges.
138
  """
 
 
 
 
 
139
  yield _ev(type="commentary", text="Reading your trip request…")
140
 
141
  agent = None
 
97
  yield _ev(type="commentary", text=f"{message} ({int(time.monotonic() - start)}s)")
98
 
99
 
100
+ # Cached per-boot preflight (N35). Fail-fast ONLY on genuinely-doomed config
101
+ # (missing SerpApi key — build_trip_packages cannot fetch live flights/hotels).
102
+ # Modal cold-start is NOT a hard failure: it streams via _pulse heartbeats and
103
+ # the loop degrades to the deterministic parser, so we don't gate on it.
104
+ _PREFLIGHT_OK: bool | None = None
105
+
106
+
107
+ def _preflight() -> tuple[bool, str]:
108
+ """Return (ok, reason). ``reason`` is empty when ok. Cached positive."""
109
+ global _PREFLIGHT_OK
110
+ if _PREFLIGHT_OK:
111
+ return True, ""
112
+ if not os.environ.get("SERPAPI_API_KEY"):
113
+ return False, (
114
+ "SerpApi key is not set on this Space — live flight & hotel search is "
115
+ "unavailable. Add SERPAPI_API_KEY in Settings → Secrets, then restart."
116
+ )
117
+ _PREFLIGHT_OK = True
118
+ return True, ""
119
+
120
+
121
  async def _agent_explain(agent, user_text: str, trip: TripRequest, result) -> str:
122
  """Round 2 — Nemotron compares the packages. Best-effort ('' on failure)."""
123
  args_json = json.dumps(trip.model_dump(mode="json"))
 
157
  + Nemotron's explanation). Falls back to the deterministic parser if the
158
  agent is unavailable or hedges.
159
  """
160
+ ok, why = _preflight() # N35 — fail-fast on doomed config (missing key)
161
+ if not ok:
162
+ yield _ev(type="error", text=f"⚠️ {why}")
163
+ return
164
+
165
  yield _ev(type="commentary", text="Reading your trip request…")
166
 
167
  agent = None