Spaces:
Running on Zero
Running on Zero
zhiyi commited on
Commit ·
73fc26e
1
Parent(s): 4d2437d
Prevent truncated evidence card responses
Browse files- app.py +37 -12
- tests/test_app.py +8 -1
app.py
CHANGED
|
@@ -444,18 +444,29 @@ def validate_stage_with_repairs(
|
|
| 444 |
raise RuntimeError(f"{stage_name} validation failed")
|
| 445 |
|
| 446 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 447 |
def build_report(
|
| 448 |
request: ResearchRequest,
|
| 449 |
papers: list[dict[str, Any]],
|
| 450 |
deep_texts: dict[str, str],
|
| 451 |
english_understanding: dict[str, Any],
|
| 452 |
) -> dict[str, Any]:
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
item = {k: paper.get(k) for k in ("id", "title", "summary", "authors", "published", "updated", "url")}
|
| 456 |
-
if paper["id"] in deep_texts:
|
| 457 |
-
item["selected_text_extract"] = deep_texts[paper["id"]]
|
| 458 |
-
raw_evidence.append(item)
|
| 459 |
|
| 460 |
if raw_evidence:
|
| 461 |
card_payload = {
|
|
@@ -468,12 +479,26 @@ def build_report(
|
|
| 468 |
"schema": EvidenceCardsEnvelope.model_json_schema(),
|
| 469 |
},
|
| 470 |
}
|
| 471 |
-
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
|
| 475 |
-
|
| 476 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 477 |
cards = validate_stage_with_repairs(
|
| 478 |
cards_result,
|
| 479 |
EvidenceCardsEnvelope,
|
|
|
|
| 444 |
raise RuntimeError(f"{stage_name} validation failed")
|
| 445 |
|
| 446 |
|
| 447 |
+
def prepare_evidence_inputs(
|
| 448 |
+
papers: list[dict[str, Any]], deep_texts: dict[str, str], limit: int
|
| 449 |
+
) -> list[dict[str, Any]]:
|
| 450 |
+
"""Prioritize deeply read papers and bound evidence-card output size."""
|
| 451 |
+
selected_ids = set(deep_texts)
|
| 452 |
+
ordered = sorted(papers, key=lambda paper: paper.get("id") not in selected_ids)
|
| 453 |
+
evidence_inputs = []
|
| 454 |
+
for paper in ordered[:limit]:
|
| 455 |
+
item = {k: paper.get(k) for k in ("id", "title", "summary", "authors", "published", "updated", "url")}
|
| 456 |
+
if paper.get("id") in deep_texts:
|
| 457 |
+
item["selected_text_extract"] = deep_texts[paper["id"]][:9000]
|
| 458 |
+
evidence_inputs.append(item)
|
| 459 |
+
return evidence_inputs
|
| 460 |
+
|
| 461 |
+
|
| 462 |
def build_report(
|
| 463 |
request: ResearchRequest,
|
| 464 |
papers: list[dict[str, Any]],
|
| 465 |
deep_texts: dict[str, str],
|
| 466 |
english_understanding: dict[str, Any],
|
| 467 |
) -> dict[str, Any]:
|
| 468 |
+
evidence_limit = min(8, DEPTHS[request.depth]["deep"])
|
| 469 |
+
raw_evidence = prepare_evidence_inputs(papers, deep_texts, evidence_limit)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 470 |
|
| 471 |
if raw_evidence:
|
| 472 |
card_payload = {
|
|
|
|
| 479 |
"schema": EvidenceCardsEnvelope.model_json_schema(),
|
| 480 |
},
|
| 481 |
}
|
| 482 |
+
card_prompt = json.dumps(card_payload, ensure_ascii=False)
|
| 483 |
+
try:
|
| 484 |
+
cards_result = chat_json(
|
| 485 |
+
"Create one compact evidence card per supplied paper. Keep only decision-relevant experimental conditions "
|
| 486 |
+
"and limitations. Do not invent results, citations, or paper IDs. Return a complete JSON object; stay concise.",
|
| 487 |
+
card_prompt,
|
| 488 |
+
3600,
|
| 489 |
+
)
|
| 490 |
+
except RuntimeError as first_error:
|
| 491 |
+
cards_result = chat_json(
|
| 492 |
+
"The previous evidence-card response was incomplete or invalid JSON. Regenerate it more concisely. "
|
| 493 |
+
"Return exactly one short card per supplied paper as a complete JSON object with no markdown or commentary.",
|
| 494 |
+
json.dumps({
|
| 495 |
+
"previous_error": str(first_error),
|
| 496 |
+
"request": request.model_dump(),
|
| 497 |
+
"papers": [{k: item.get(k) for k in ("id", "title", "summary", "published")} for item in raw_evidence],
|
| 498 |
+
"schema": EvidenceCardsEnvelope.model_json_schema(),
|
| 499 |
+
}, ensure_ascii=False),
|
| 500 |
+
3000,
|
| 501 |
+
)
|
| 502 |
cards = validate_stage_with_repairs(
|
| 503 |
cards_result,
|
| 504 |
EvidenceCardsEnvelope,
|
tests/test_app.py
CHANGED
|
@@ -2,7 +2,7 @@ import unittest
|
|
| 2 |
|
| 3 |
from pydantic import ValidationError
|
| 4 |
|
| 5 |
-
from app import ResearchReport, deduplicate, render_presentation, render_section_content, render_value, safe_slug
|
| 6 |
|
| 7 |
|
| 8 |
def base_report(section):
|
|
@@ -23,6 +23,13 @@ class AppTests(unittest.TestCase):
|
|
| 23 |
def test_deduplicate_versions(self):
|
| 24 |
self.assertEqual(len(deduplicate([{"id": "1234.5678v1"}, {"id": "1234.5678v2"}])), 1)
|
| 25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
def test_render_is_downloadable_document(self):
|
| 27 |
section = {"title": "Scope", "purpose": "Define the technical decision boundary.", "takeaway": "The boundary determines the useful evidence.", "layout": "text", "content": {"points": ["A meaningful point", "Another meaningful point"]}, "source_ids": []}
|
| 28 |
output = render_presentation(base_report(section), [], "2026-01-01")
|
|
|
|
| 2 |
|
| 3 |
from pydantic import ValidationError
|
| 4 |
|
| 5 |
+
from app import ResearchReport, deduplicate, prepare_evidence_inputs, render_presentation, render_section_content, render_value, safe_slug
|
| 6 |
|
| 7 |
|
| 8 |
def base_report(section):
|
|
|
|
| 23 |
def test_deduplicate_versions(self):
|
| 24 |
self.assertEqual(len(deduplicate([{"id": "1234.5678v1"}, {"id": "1234.5678v2"}])), 1)
|
| 25 |
|
| 26 |
+
def test_evidence_inputs_are_bounded_and_prioritize_deep_reads(self):
|
| 27 |
+
papers = [{"id": str(i), "title": f"Paper {i}", "summary": "Summary"} for i in range(10)]
|
| 28 |
+
result = prepare_evidence_inputs(papers, {"8": "deep text", "9": "deep text"}, 3)
|
| 29 |
+
self.assertEqual(len(result), 3)
|
| 30 |
+
self.assertEqual([item["id"] for item in result[:2]], ["8", "9"])
|
| 31 |
+
self.assertIn("selected_text_extract", result[0])
|
| 32 |
+
|
| 33 |
def test_render_is_downloadable_document(self):
|
| 34 |
section = {"title": "Scope", "purpose": "Define the technical decision boundary.", "takeaway": "The boundary determines the useful evidence.", "layout": "text", "content": {"points": ["A meaningful point", "Another meaningful point"]}, "source_ids": []}
|
| 35 |
output = render_presentation(base_report(section), [], "2026-01-01")
|