Spaces:
Running
Running
R14-FM-WA1-R1 Working Abstract Typed Semantic Retry
Browse files- core/pipeline_agent.py +47 -14
core/pipeline_agent.py
CHANGED
|
@@ -46,6 +46,14 @@ class DeepSeekRequestError(DeepSeekAPIError):
|
|
| 46 |
pass
|
| 47 |
|
| 48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
class DeepSeekReasoningOnlyExhaustionError(DeepSeekAPIError):
|
| 50 |
"""Reasoning tokens were emitted but no final answer content arrived."""
|
| 51 |
|
|
@@ -1376,15 +1384,19 @@ Return a concise PROVISIONAL RESEARCH LOGIC CONTRACT in plain English prose. It
|
|
| 1376 |
if cls._front_matter_has_citation(text):
|
| 1377 |
raise DeepSeekRequestError('Working Abstract must not contain citations.')
|
| 1378 |
forbidden = (
|
| 1379 |
-
r'\bwe\s+(?:find|found|show|demonstrate|observe|establish)\b',
|
| 1380 |
-
r'\b(?:results?|findings?)\s+(?:show|indicate|reveal|demonstrate|confirm|support)\b',
|
| 1381 |
-
r'\b(?:supported|rejected)\s+(?:H\d+|hypothes)',
|
| 1382 |
-
r'\bstatistically\s+significant\b',
|
| 1383 |
-
r'(?:β|R²|χ²|ΔR²)\s*(?:=|<|>|≤|≥)',
|
| 1384 |
-
r'\bp\s*(?:=|<|>|≤|≥)\s*(?:\d|\.)',
|
| 1385 |
)
|
| 1386 |
-
|
| 1387 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1388 |
if word_count < 80 or word_count > 180:
|
| 1389 |
logging.warning(
|
| 1390 |
'Working Abstract length diagnostic | words=%s | preferred=80-180 | nonfatal=true',
|
|
@@ -1436,12 +1448,33 @@ Return a concise PROVISIONAL RESEARCH LOGIC CONTRACT in plain English prose. It
|
|
| 1436 |
'Front matter structured-output local retry | phase=%s | attempt=%s/2 | reason=%s',
|
| 1437 |
phase, local_attempt + 1, self._safe_source_error(exc),
|
| 1438 |
)
|
| 1439 |
-
|
| 1440 |
-
|
| 1441 |
-
'
|
| 1442 |
-
'
|
| 1443 |
-
'
|
| 1444 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1445 |
raise DeepSeekRequestError(f'{phase} front matter validation failed: {last_error}')
|
| 1446 |
|
| 1447 |
def generate_working_front_matter(
|
|
|
|
| 46 |
pass
|
| 47 |
|
| 48 |
|
| 49 |
+
class FrontMatterValidationError(DeepSeekRequestError):
|
| 50 |
+
"""Typed local validation failure used only for bounded front-matter recovery."""
|
| 51 |
+
def __init__(self, code, detail):
|
| 52 |
+
self.code = str(code or 'FRONT_MATTER_VALIDATION')
|
| 53 |
+
self.safe_detail = str(detail or '')[:1200]
|
| 54 |
+
super().__init__(f"{self.code}: {self.safe_detail}")
|
| 55 |
+
|
| 56 |
+
|
| 57 |
class DeepSeekReasoningOnlyExhaustionError(DeepSeekAPIError):
|
| 58 |
"""Reasoning tokens were emitted but no final answer content arrived."""
|
| 59 |
|
|
|
|
| 1384 |
if cls._front_matter_has_citation(text):
|
| 1385 |
raise DeepSeekRequestError('Working Abstract must not contain citations.')
|
| 1386 |
forbidden = (
|
| 1387 |
+
('RESULT_ASSERTION', r'\bwe\s+(?:find|found|show|demonstrate|observe|establish)\b'),
|
| 1388 |
+
('RESULT_ASSERTION', r'\b(?:results?|findings?)\s+(?:show|indicate|reveal|demonstrate|confirm|support)\b'),
|
| 1389 |
+
('HYPOTHESIS_OUTCOME_ASSERTION', r'\b(?:supported|rejected)\s+(?:H\d+|hypothes)'),
|
| 1390 |
+
('SIGNIFICANCE_ASSERTION', r'\bstatistically\s+significant\b'),
|
| 1391 |
+
('STATISTICAL_RESULT_ASSERTION', r'(?:β|R²|χ²|ΔR²)\s*(?:=|<|>|≤|≥)'),
|
| 1392 |
+
('STATISTICAL_RESULT_ASSERTION', r'\bp\s*(?:=|<|>|≤|≥)\s*(?:\d|\.)'),
|
| 1393 |
)
|
| 1394 |
+
for failure_code, pattern in forbidden:
|
| 1395 |
+
if re.search(pattern, text, flags=re.I):
|
| 1396 |
+
raise FrontMatterValidationError(
|
| 1397 |
+
failure_code,
|
| 1398 |
+
'Working Abstract asserted a result that is not yet frozen.',
|
| 1399 |
+
)
|
| 1400 |
if word_count < 80 or word_count > 180:
|
| 1401 |
logging.warning(
|
| 1402 |
'Working Abstract length diagnostic | words=%s | preferred=80-180 | nonfatal=true',
|
|
|
|
| 1448 |
'Front matter structured-output local retry | phase=%s | attempt=%s/2 | reason=%s',
|
| 1449 |
phase, local_attempt + 1, self._safe_source_error(exc),
|
| 1450 |
)
|
| 1451 |
+
failure_code = str(getattr(exc, 'code', '') or '').strip().upper()
|
| 1452 |
+
working_result_codes = {
|
| 1453 |
+
'RESULT_ASSERTION',
|
| 1454 |
+
'HYPOTHESIS_OUTCOME_ASSERTION',
|
| 1455 |
+
'SIGNIFICANCE_ASSERTION',
|
| 1456 |
+
'STATISTICAL_RESULT_ASSERTION',
|
| 1457 |
+
}
|
| 1458 |
+
if str(phase).casefold() == 'working' and failure_code in working_result_codes:
|
| 1459 |
+
current_prompt = base_prompt + (
|
| 1460 |
+
f'\n\nLOCAL VALIDATION RETRY — {failure_code}: The previous Working Abstract asserted '
|
| 1461 |
+
'a result that is not yet frozen. Return a fresh complete JSON object only. Preserve the '
|
| 1462 |
+
'research problem, theoretical tension, focal concepts, research question or hypothesis '
|
| 1463 |
+
'architecture, design or method class, and intended contribution domain, but remove every '
|
| 1464 |
+
'claim that results/findings have already been obtained. Do not state effect directions, '
|
| 1465 |
+
'supported/rejected hypotheses, statistical significance, coefficients, p-values, fit '
|
| 1466 |
+
'statistics, substantive findings, or conclusions. Use prospective/non-result language such '
|
| 1467 |
+
'as examines, investigates, asks, develops, evaluates, or is designed to assess. Keep exactly '
|
| 1468 |
+
'a non-empty string field "abstract" and a JSON array field "keywords" containing 4-6 distinct '
|
| 1469 |
+
'non-empty academic terms. Do not describe the correction and do not wrap the JSON in Markdown.'
|
| 1470 |
+
)
|
| 1471 |
+
else:
|
| 1472 |
+
current_prompt = base_prompt + (
|
| 1473 |
+
'\n\nLOCAL VALIDATION RETRY: The previous response failed local JSON/schema/content validation. '
|
| 1474 |
+
'Return a fresh complete JSON object only, with exactly a non-empty string field "abstract" '
|
| 1475 |
+
'and a JSON array field "keywords" containing 4-6 distinct non-empty academic terms. '
|
| 1476 |
+
'Do not describe the correction and do not wrap the JSON in Markdown.'
|
| 1477 |
+
)
|
| 1478 |
raise DeepSeekRequestError(f'{phase} front matter validation failed: {last_error}')
|
| 1479 |
|
| 1480 |
def generate_working_front_matter(
|