Spaces:
Running
Running
Commit ·
f560468
1
Parent(s): e491b0b
Security: auth on trace endpoints, pin litellm, sanitize errors
Browse filesTrace list and replay require admin token. Pin litellm to d251238.
Generic error messages to client, full details logged server-side.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- app.py +16 -9
- requirements.txt +1 -1
app.py
CHANGED
|
@@ -559,11 +559,14 @@ def build_app() -> gr.Blocks:
|
|
| 559 |
doc_btn = gr.Button(visible=False)
|
| 560 |
doc_btn.click(api_get_doc, inputs=doc_input, outputs=doc_output, api_name="doc")
|
| 561 |
|
| 562 |
-
# Trace list endpoint
|
| 563 |
-
|
|
|
|
| 564 |
traces_output = gr.Textbox(visible=False)
|
| 565 |
|
| 566 |
-
def api_list_traces(query):
|
|
|
|
|
|
|
| 567 |
if not hf_api or not HF_TRACES_REPO:
|
| 568 |
return json.dumps({"error": "traces not configured"})
|
| 569 |
try:
|
|
@@ -580,13 +583,16 @@ def build_app() -> gr.Blocks:
|
|
| 580 |
return json.dumps({"error": str(exc)})
|
| 581 |
|
| 582 |
traces_btn = gr.Button(visible=False)
|
| 583 |
-
traces_btn.click(api_list_traces, inputs=
|
| 584 |
|
| 585 |
-
# Trace replay endpoint
|
| 586 |
-
|
|
|
|
| 587 |
replay_output = gr.Textbox(visible=False)
|
| 588 |
|
| 589 |
-
def api_get_trace(filename):
|
|
|
|
|
|
|
| 590 |
if not hf_api or not HF_TRACES_REPO or not filename:
|
| 591 |
return json.dumps({"error": "not found"})
|
| 592 |
safe_name = Path(filename).name
|
|
@@ -612,7 +618,7 @@ def build_app() -> gr.Blocks:
|
|
| 612 |
return json.dumps({"error": str(exc)})
|
| 613 |
|
| 614 |
replay_btn = gr.Button(visible=False)
|
| 615 |
-
replay_btn.click(api_get_trace, inputs=
|
| 616 |
|
| 617 |
return demo
|
| 618 |
|
|
@@ -655,7 +661,8 @@ def stream_question(question: str) -> Generator[str, None, None]:
|
|
| 655 |
tool_call_count += 1
|
| 656 |
yield json.dumps({"type": "tool_call", "count": tool_call_count, "name": event.name})
|
| 657 |
except Exception as exc:
|
| 658 |
-
|
|
|
|
| 659 |
return
|
| 660 |
|
| 661 |
trace = agent_run.trace
|
|
|
|
| 559 |
doc_btn = gr.Button(visible=False)
|
| 560 |
doc_btn.click(api_get_doc, inputs=doc_input, outputs=doc_output, api_name="doc")
|
| 561 |
|
| 562 |
+
# Trace list endpoint (admin-only)
|
| 563 |
+
traces_token_input = gr.Textbox(visible=False)
|
| 564 |
+
traces_query_input = gr.Textbox(visible=False)
|
| 565 |
traces_output = gr.Textbox(visible=False)
|
| 566 |
|
| 567 |
+
def api_list_traces(token, query):
|
| 568 |
+
if not ADMIN_TOKEN or not hmac.compare_digest(token, ADMIN_TOKEN):
|
| 569 |
+
return json.dumps({"error": "unauthorized"})
|
| 570 |
if not hf_api or not HF_TRACES_REPO:
|
| 571 |
return json.dumps({"error": "traces not configured"})
|
| 572 |
try:
|
|
|
|
| 583 |
return json.dumps({"error": str(exc)})
|
| 584 |
|
| 585 |
traces_btn = gr.Button(visible=False)
|
| 586 |
+
traces_btn.click(api_list_traces, inputs=[traces_token_input, traces_query_input], outputs=traces_output, api_name="traces")
|
| 587 |
|
| 588 |
+
# Trace replay endpoint (admin-only)
|
| 589 |
+
replay_token_input = gr.Textbox(visible=False)
|
| 590 |
+
replay_filename_input = gr.Textbox(visible=False)
|
| 591 |
replay_output = gr.Textbox(visible=False)
|
| 592 |
|
| 593 |
+
def api_get_trace(token, filename):
|
| 594 |
+
if not ADMIN_TOKEN or not hmac.compare_digest(token, ADMIN_TOKEN):
|
| 595 |
+
return json.dumps({"error": "unauthorized"})
|
| 596 |
if not hf_api or not HF_TRACES_REPO or not filename:
|
| 597 |
return json.dumps({"error": "not found"})
|
| 598 |
safe_name = Path(filename).name
|
|
|
|
| 618 |
return json.dumps({"error": str(exc)})
|
| 619 |
|
| 620 |
replay_btn = gr.Button(visible=False)
|
| 621 |
+
replay_btn.click(api_get_trace, inputs=[replay_token_input, replay_filename_input], outputs=replay_output, api_name="replay")
|
| 622 |
|
| 623 |
return demo
|
| 624 |
|
|
|
|
| 661 |
tool_call_count += 1
|
| 662 |
yield json.dumps({"type": "tool_call", "count": tool_call_count, "name": event.name})
|
| 663 |
except Exception as exc:
|
| 664 |
+
print(f"ERROR in stream_question: {exc}")
|
| 665 |
+
yield json.dumps({"type": "error", "error": "An error occurred during processing."})
|
| 666 |
return
|
| 667 |
|
| 668 |
trace = agent_run.trace
|
requirements.txt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
click>=8.1
|
| 2 |
-
litellm @ git+https://github.com/BerriAI/litellm.git
|
| 3 |
a-simple-llm-harness @ git+https://github.com/chuckfinca/a-simple-llm-harness.git@25e7e15
|
| 4 |
e2b-code-interpreter>=2.5
|
| 5 |
huggingface-hub
|
|
|
|
| 1 |
click>=8.1
|
| 2 |
+
litellm @ git+https://github.com/BerriAI/litellm.git@d251238
|
| 3 |
a-simple-llm-harness @ git+https://github.com/chuckfinca/a-simple-llm-harness.git@25e7e15
|
| 4 |
e2b-code-interpreter>=2.5
|
| 5 |
huggingface-hub
|