Spaces:
Running
Running
Commit ·
195413e
1
Parent(s): f560468
Rename functions for clarity, consolidate format_stats
Browse files_check_and_increment → _is_daily_question_allowed
_remaining → _daily_questions_remaining
_count_todays_traces → _count_traces_uploaded_today
Merge format_stats and format_stats_from_trace into one
function that handles both object and dict inputs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
app.py
CHANGED
|
@@ -63,8 +63,8 @@ BASE_PROMPT = (
|
|
| 63 |
# Global daily counter (initialized from trace repo on startup)
|
| 64 |
# ---------------------------------------------------------------------------
|
| 65 |
|
| 66 |
-
def
|
| 67 |
-
"""
|
| 68 |
if not hf_api or not HF_TRACES_REPO:
|
| 69 |
return 0
|
| 70 |
today_prefix = datetime.now(timezone.utc).strftime("%Y%m%d")
|
|
@@ -76,12 +76,12 @@ def _count_todays_traces() -> int:
|
|
| 76 |
return 0
|
| 77 |
|
| 78 |
|
| 79 |
-
_daily_count =
|
| 80 |
_daily_date = date.today()
|
| 81 |
|
| 82 |
|
| 83 |
-
def
|
| 84 |
-
"""
|
| 85 |
global _daily_count, _daily_date
|
| 86 |
today = date.today()
|
| 87 |
if today != _daily_date:
|
|
@@ -99,7 +99,7 @@ def _reset_counter():
|
|
| 99 |
_daily_date = date.today()
|
| 100 |
|
| 101 |
|
| 102 |
-
def
|
| 103 |
global _daily_count, _daily_date
|
| 104 |
today = date.today()
|
| 105 |
if today != _daily_date:
|
|
@@ -176,31 +176,27 @@ def upload_trace(result: dict) -> None:
|
|
| 176 |
# ---------------------------------------------------------------------------
|
| 177 |
|
| 178 |
|
| 179 |
-
def format_stats(trace
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
|
| 194 |
-
def format_stats_from_trace(trace: dict) -> str:
|
| 195 |
-
cached = trace.get("cached_tokens", 0)
|
| 196 |
cache_str = f" ({cached} cached)" if cached else ""
|
| 197 |
-
model = trace.get("model", "")
|
| 198 |
model_name = model.split("/")[-1] if model else ""
|
| 199 |
-
prompt = trace.get("prompt_tokens", 0)
|
| 200 |
-
completion = trace.get("completion_tokens", 0)
|
| 201 |
-
tool_calls = trace.get("tool_calls", [])
|
| 202 |
-
wall = trace.get("wall_time_s", 0)
|
| 203 |
-
cost = trace.get("cost")
|
| 204 |
parts = [
|
| 205 |
model_name,
|
| 206 |
f"{prompt + completion:,} tokens{cache_str}",
|
|
@@ -220,7 +216,7 @@ def format_stats_from_trace(trace: dict) -> str:
|
|
| 220 |
def chat(message: str, scratch_path: str, session_cost: float):
|
| 221 |
empty = ("", "", scratch_path, session_cost)
|
| 222 |
|
| 223 |
-
if not
|
| 224 |
yield (
|
| 225 |
"The daily question limit has been reached. "
|
| 226 |
"Check back tomorrow, or try it with your own documents on the "
|
|
@@ -308,8 +304,8 @@ def chat(message: str, scratch_path: str, session_cost: float):
|
|
| 308 |
upload_trace(result)
|
| 309 |
trace_html = render_trace(result, max_chars=2000)
|
| 310 |
|
| 311 |
-
remaining =
|
| 312 |
-
remaining_msg = f"\n\n---\n{stats}\n\n*{remaining} question{'s' if remaining != 1 else ''} remaining today*"
|
| 313 |
|
| 314 |
yield (
|
| 315 |
f"{clean_answer}{remaining_msg}",
|
|
@@ -609,7 +605,7 @@ def build_app() -> gr.Blocks:
|
|
| 609 |
"question": data.get("question", ""),
|
| 610 |
"answer": clean_answer,
|
| 611 |
"sources": sources,
|
| 612 |
-
"stats":
|
| 613 |
"source_tag": data.get("source", ""),
|
| 614 |
"trace_html": trace_html,
|
| 615 |
"filename": safe_name,
|
|
@@ -625,7 +621,7 @@ def build_app() -> gr.Blocks:
|
|
| 625 |
|
| 626 |
def stream_question(question: str) -> Generator[str, None, None]:
|
| 627 |
"""Streaming API — yields JSON event strings for the custom chat UI."""
|
| 628 |
-
if not
|
| 629 |
yield json.dumps({"type": "error", "error": "daily_limit", "remaining": 0})
|
| 630 |
return
|
| 631 |
|
|
@@ -687,7 +683,7 @@ def stream_question(question: str) -> Generator[str, None, None]:
|
|
| 687 |
"sources": sources,
|
| 688 |
"stats": format_stats(trace),
|
| 689 |
"trace_html": trace_html,
|
| 690 |
-
"remaining":
|
| 691 |
})
|
| 692 |
|
| 693 |
|
|
|
|
| 63 |
# Global daily counter (initialized from trace repo on startup)
|
| 64 |
# ---------------------------------------------------------------------------
|
| 65 |
|
| 66 |
+
def _count_traces_uploaded_today() -> int:
|
| 67 |
+
"""Initialize the daily counter from trace files already uploaded today."""
|
| 68 |
if not hf_api or not HF_TRACES_REPO:
|
| 69 |
return 0
|
| 70 |
today_prefix = datetime.now(timezone.utc).strftime("%Y%m%d")
|
|
|
|
| 76 |
return 0
|
| 77 |
|
| 78 |
|
| 79 |
+
_daily_count = _count_traces_uploaded_today()
|
| 80 |
_daily_date = date.today()
|
| 81 |
|
| 82 |
|
| 83 |
+
def _is_daily_question_allowed() -> bool:
|
| 84 |
+
"""Check whether the daily question limit has been reached, and if not, count this question."""
|
| 85 |
global _daily_count, _daily_date
|
| 86 |
today = date.today()
|
| 87 |
if today != _daily_date:
|
|
|
|
| 99 |
_daily_date = date.today()
|
| 100 |
|
| 101 |
|
| 102 |
+
def _daily_questions_daily_questions_remaining() -> int:
|
| 103 |
global _daily_count, _daily_date
|
| 104 |
today = date.today()
|
| 105 |
if today != _daily_date:
|
|
|
|
| 176 |
# ---------------------------------------------------------------------------
|
| 177 |
|
| 178 |
|
| 179 |
+
def format_stats(trace) -> str:
|
| 180 |
+
"""Format trace stats for display. Accepts a Trace object or dict."""
|
| 181 |
+
if isinstance(trace, dict):
|
| 182 |
+
cached = trace.get("cached_tokens", 0)
|
| 183 |
+
model = trace.get("model", "")
|
| 184 |
+
prompt = trace.get("prompt_tokens", 0)
|
| 185 |
+
completion = trace.get("completion_tokens", 0)
|
| 186 |
+
tool_calls = trace.get("tool_calls", [])
|
| 187 |
+
wall = trace.get("wall_time_s", 0)
|
| 188 |
+
cost = trace.get("cost")
|
| 189 |
+
else:
|
| 190 |
+
cached = trace.cached_tokens
|
| 191 |
+
model = trace.model
|
| 192 |
+
prompt = trace.prompt_tokens
|
| 193 |
+
completion = trace.completion_tokens
|
| 194 |
+
tool_calls = trace.tool_calls
|
| 195 |
+
wall = trace.wall_time_s
|
| 196 |
+
cost = trace.cost
|
| 197 |
|
|
|
|
|
|
|
| 198 |
cache_str = f" ({cached} cached)" if cached else ""
|
|
|
|
| 199 |
model_name = model.split("/")[-1] if model else ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
parts = [
|
| 201 |
model_name,
|
| 202 |
f"{prompt + completion:,} tokens{cache_str}",
|
|
|
|
| 216 |
def chat(message: str, scratch_path: str, session_cost: float):
|
| 217 |
empty = ("", "", scratch_path, session_cost)
|
| 218 |
|
| 219 |
+
if not _is_daily_question_allowed():
|
| 220 |
yield (
|
| 221 |
"The daily question limit has been reached. "
|
| 222 |
"Check back tomorrow, or try it with your own documents on the "
|
|
|
|
| 304 |
upload_trace(result)
|
| 305 |
trace_html = render_trace(result, max_chars=2000)
|
| 306 |
|
| 307 |
+
remaining = _daily_questions_remaining()
|
| 308 |
+
remaining_msg = f"\n\n---\n*{stats}*\n\n*{remaining} question{'s' if remaining != 1 else ''} remaining today*"
|
| 309 |
|
| 310 |
yield (
|
| 311 |
f"{clean_answer}{remaining_msg}",
|
|
|
|
| 605 |
"question": data.get("question", ""),
|
| 606 |
"answer": clean_answer,
|
| 607 |
"sources": sources,
|
| 608 |
+
"stats": format_stats(trace),
|
| 609 |
"source_tag": data.get("source", ""),
|
| 610 |
"trace_html": trace_html,
|
| 611 |
"filename": safe_name,
|
|
|
|
| 621 |
|
| 622 |
def stream_question(question: str) -> Generator[str, None, None]:
|
| 623 |
"""Streaming API — yields JSON event strings for the custom chat UI."""
|
| 624 |
+
if not _is_daily_question_allowed():
|
| 625 |
yield json.dumps({"type": "error", "error": "daily_limit", "remaining": 0})
|
| 626 |
return
|
| 627 |
|
|
|
|
| 683 |
"sources": sources,
|
| 684 |
"stats": format_stats(trace),
|
| 685 |
"trace_html": trace_html,
|
| 686 |
+
"remaining": _daily_questions_remaining(),
|
| 687 |
})
|
| 688 |
|
| 689 |
|