R14-TQ1-R3-R1 claim-local protected-placeholder recovery

#50
Files changed (1) hide show
  1. core/pipeline_agent.py +48 -24
core/pipeline_agent.py CHANGED
@@ -5499,31 +5499,55 @@ Translate headings and terminology naturally. Preserve standard variable abbrevi
5499
  claim_sources={claim_id: source_claim}, keep_claim_markers=True,
5500
  )
5501
  except DeepSeekRequestError as error:
5502
- if not self._is_translation_unowned_numeric_error(error):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5503
  raise
5504
- logging.warning(
5505
- 'Translation claim-local numeric recovery: block=SP-P%s claim=%s error=%s',
5506
- block_id, claim_id, self._safe_source_error(error),
5507
- )
5508
- numeric_prompt = system_prompt + (
5509
- '\nNUMERIC FACT RECOVERY FOR ONE CLAIM. Repair only this claim. Preserve every SP-P, SP-C, and SP-T marker byte-for-byte. '
5510
- 'Do not introduce any Arabic digit, percentage, sample size, scale point, model number, date number, or other numeric surface unless it is represented by an SP-T marker or is directly and unambiguously expressed by an English number-word, ordinal, fold expression, relational quantity, or month name in this source claim. '
5511
- 'If a lexical quantity is not protected by SP-T and you are uncertain, express it lexically in the target language rather than inventing an Arabic digit. '
5512
- 'Do not add, remove, merge, or reinterpret claims. Return only the marked translated claim.'
5513
- + '\n<SEMANTIC_ANCHOR_MANIFEST>\n'
5514
- + json.dumps({block_id: safe_manifest}, ensure_ascii=False)
5515
- + '\n</SEMANTIC_ANCHOR_MANIFEST>'
5516
- )
5517
- retry_result = self.call_deepseek(
5518
- numeric_prompt, marked_source,
5519
- max_tokens=max(1200, min(2600, self._count_tokens(marked_source) * 2 + 900)),
5520
- temp=0.0, model_role='translation', thinking=False, allow_fallback=False,
5521
- )
5522
- retry_parsed = self._parse_marked_translation(retry_result, [block_id])
5523
- restored = self._restore_translation_tokens(
5524
- retry_parsed[block_id], mapping, f'SP-P{block_id}', target_lang,
5525
- claim_sources={claim_id: source_claim}, keep_claim_markers=True,
5526
- )
5527
  clean = self._strip_translation_claim_markers(restored)
5528
  self._validate_translation_block_protected(block_id, source_claim, clean, target_lang)
5529
  _order, segments = self._parse_translation_claim_segments(restored, [claim_id])
 
5499
  claim_sources={claim_id: source_claim}, keep_claim_markers=True,
5500
  )
5501
  except DeepSeekRequestError as error:
5502
+ if str(error or '').startswith('Translation protected placeholder mismatch'):
5503
+ logging.warning(
5504
+ 'Translation claim-local protected-skeleton recovery: block=SP-P%s claim=%s error=%s; strict retry once.',
5505
+ block_id, claim_id, self._safe_source_error(error),
5506
+ )
5507
+ strict_prompt = system_prompt + (
5508
+ '\nSTRICT PROTECTED-SKELETON RECOVERY FOR ONE CLAIM. Re-translate only this one claim from the frozen marked English source. '
5509
+ 'Preserve every SP-P, SP-C, and SP-T marker byte-for-byte and exactly once. Do not delete, duplicate, rename, reorder across claim ownership, translate, normalize, or invent any marker. '
5510
+ 'Do not add, remove, merge, or reinterpret claims or factual content. Return only the marked translated claim.'
5511
+ + '\n<SEMANTIC_ANCHOR_MANIFEST>\n'
5512
+ + json.dumps({block_id: safe_manifest}, ensure_ascii=False)
5513
+ + '\n</SEMANTIC_ANCHOR_MANIFEST>'
5514
+ )
5515
+ strict_result = self.call_deepseek(
5516
+ strict_prompt, marked_source,
5517
+ max_tokens=max(1200, min(2600, self._count_tokens(marked_source) * 2 + 900)),
5518
+ temp=0.0, model_role='translation', thinking=False, allow_fallback=False,
5519
+ )
5520
+ strict_parsed = self._parse_marked_translation(strict_result, [block_id])
5521
+ restored = self._restore_translation_tokens(
5522
+ strict_parsed[block_id], mapping, f'SP-P{block_id}', target_lang,
5523
+ claim_sources={claim_id: source_claim}, keep_claim_markers=True,
5524
+ )
5525
+ elif self._is_translation_unowned_numeric_error(error):
5526
+ logging.warning(
5527
+ 'Translation claim-local numeric recovery: block=SP-P%s claim=%s error=%s',
5528
+ block_id, claim_id, self._safe_source_error(error),
5529
+ )
5530
+ numeric_prompt = system_prompt + (
5531
+ '\nNUMERIC FACT RECOVERY FOR ONE CLAIM. Repair only this claim. Preserve every SP-P, SP-C, and SP-T marker byte-for-byte. '
5532
+ 'Do not introduce any Arabic digit, percentage, sample size, scale point, model number, date number, or other numeric surface unless it is represented by an SP-T marker or is directly and unambiguously expressed by an English number-word, ordinal, fold expression, relational quantity, or month name in this source claim. '
5533
+ 'If a lexical quantity is not protected by SP-T and you are uncertain, express it lexically in the target language rather than inventing an Arabic digit. '
5534
+ 'Do not add, remove, merge, or reinterpret claims. Return only the marked translated claim.'
5535
+ + '\n<SEMANTIC_ANCHOR_MANIFEST>\n'
5536
+ + json.dumps({block_id: safe_manifest}, ensure_ascii=False)
5537
+ + '\n</SEMANTIC_ANCHOR_MANIFEST>'
5538
+ )
5539
+ retry_result = self.call_deepseek(
5540
+ numeric_prompt, marked_source,
5541
+ max_tokens=max(1200, min(2600, self._count_tokens(marked_source) * 2 + 900)),
5542
+ temp=0.0, model_role='translation', thinking=False, allow_fallback=False,
5543
+ )
5544
+ retry_parsed = self._parse_marked_translation(retry_result, [block_id])
5545
+ restored = self._restore_translation_tokens(
5546
+ retry_parsed[block_id], mapping, f'SP-P{block_id}', target_lang,
5547
+ claim_sources={claim_id: source_claim}, keep_claim_markers=True,
5548
+ )
5549
+ else:
5550
  raise
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5551
  clean = self._strip_translation_claim_markers(restored)
5552
  self._validate_translation_block_protected(block_id, source_claim, clean, target_lang)
5553
  _order, segments = self._parse_translation_claim_segments(restored, [claim_id])