Upload 89 files
Browse files
app/engine/__pycache__/lexical.cpython-311.pyc
CHANGED
|
Binary files a/app/engine/__pycache__/lexical.cpython-311.pyc and b/app/engine/__pycache__/lexical.cpython-311.pyc differ
|
|
|
app/engine/__pycache__/orchestrator.cpython-311.pyc
CHANGED
|
Binary files a/app/engine/__pycache__/orchestrator.cpython-311.pyc and b/app/engine/__pycache__/orchestrator.cpython-311.pyc differ
|
|
|
app/engine/lexical.py
CHANGED
|
@@ -574,9 +574,21 @@ def refine_sentence(
|
|
| 574 |
except Exception:
|
| 575 |
return LexicalResult(text=source, reason="parse_failed")
|
| 576 |
|
| 577 |
-
|
| 578 |
-
|
| 579 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 580 |
stop_words = set(nlp.Defaults.stop_words)
|
| 581 |
proposals: list[tuple[float, int, float, int, int, str, Any]] = []
|
| 582 |
for token in doc:
|
|
@@ -623,12 +635,14 @@ def refine_sentence(
|
|
| 623 |
)
|
| 624 |
if (
|
| 625 |
best_score < noun_min
|
| 626 |
-
or simplicity_gain < 0.35
|
| 627 |
-
or simplicity_gain > 1.25
|
| 628 |
):
|
| 629 |
continue
|
| 630 |
cand_freq = zipf_frequency(replacement.lower(), "en")
|
| 631 |
-
if cand_freq >= 5.5 and simplicity_gain >=
|
|
|
|
|
|
|
| 632 |
continue
|
| 633 |
if best_score < effective_min:
|
| 634 |
best_score = effective_min
|
|
@@ -656,6 +670,11 @@ def refine_sentence(
|
|
| 656 |
elif len(synsets) == 1:
|
| 657 |
chosen = best_synset
|
| 658 |
best_score = effective_min
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 659 |
elif ENGINE_LEXICAL_PREFER_SIMPLER and best_score == 0.0:
|
| 660 |
trial = _candidate_for_synset(synsets[0], token, doc)
|
| 661 |
gain_need = 0.25 if aggressive else 0.45
|
|
@@ -728,6 +747,30 @@ def refine_sentence(
|
|
| 728 |
confidence=round(confidence, 4),
|
| 729 |
)
|
| 730 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 731 |
changes.sort(key=lambda change: change.token_index)
|
| 732 |
confidence = min(change.confidence for change in changes)
|
| 733 |
return LexicalResult(text=output, changes=changes, confidence=confidence)
|
|
|
|
| 574 |
except Exception:
|
| 575 |
return LexicalResult(text=source, reason="parse_failed")
|
| 576 |
|
| 577 |
+
if aggressive:
|
| 578 |
+
effective_min = max(0.08, min_wsd * 0.7)
|
| 579 |
+
verb_gain_floor = 0.40
|
| 580 |
+
adj_adv_gain_floor = 0.15
|
| 581 |
+
elif polish:
|
| 582 |
+
# Polish mode should feel stronger on any sentence, not only because the
|
| 583 |
+
# sentence earned a larger budget. Keep the same safety rails, but allow
|
| 584 |
+
# slightly weaker-yet-still-supported everyday substitutions.
|
| 585 |
+
effective_min = max(0.10, min_wsd * 0.85)
|
| 586 |
+
verb_gain_floor = 0.30
|
| 587 |
+
adj_adv_gain_floor = 0.10
|
| 588 |
+
else:
|
| 589 |
+
effective_min = min_wsd
|
| 590 |
+
verb_gain_floor = 0.45
|
| 591 |
+
adj_adv_gain_floor = 0.0
|
| 592 |
stop_words = set(nlp.Defaults.stop_words)
|
| 593 |
proposals: list[tuple[float, int, float, int, int, str, Any]] = []
|
| 594 |
for token in doc:
|
|
|
|
| 635 |
)
|
| 636 |
if (
|
| 637 |
best_score < noun_min
|
| 638 |
+
or simplicity_gain < (0.25 if polish and not aggressive else 0.35)
|
| 639 |
+
or simplicity_gain > (1.45 if polish and not aggressive else 1.25)
|
| 640 |
):
|
| 641 |
continue
|
| 642 |
cand_freq = zipf_frequency(replacement.lower(), "en")
|
| 643 |
+
if cand_freq >= 5.5 and simplicity_gain >= (
|
| 644 |
+
0.7 if polish and not aggressive else 0.5
|
| 645 |
+
):
|
| 646 |
continue
|
| 647 |
if best_score < effective_min:
|
| 648 |
best_score = effective_min
|
|
|
|
| 670 |
elif len(synsets) == 1:
|
| 671 |
chosen = best_synset
|
| 672 |
best_score = effective_min
|
| 673 |
+
elif polish and not aggressive and best_score >= effective_min * 0.75:
|
| 674 |
+
trial = _candidate_for_synset(best_synset, token, doc)
|
| 675 |
+
if trial is not None and trial[1] >= adj_adv_gain_floor:
|
| 676 |
+
chosen = best_synset
|
| 677 |
+
best_score = max(best_score, effective_min)
|
| 678 |
elif ENGINE_LEXICAL_PREFER_SIMPLER and best_score == 0.0:
|
| 679 |
trial = _candidate_for_synset(synsets[0], token, doc)
|
| 680 |
gain_need = 0.25 if aggressive else 0.45
|
|
|
|
| 747 |
confidence=round(confidence, 4),
|
| 748 |
)
|
| 749 |
)
|
| 750 |
+
if polish and not aggressive and len(changes) < limit:
|
| 751 |
+
# Polish mode gets one more pass with the aggressive-safe lexical rules.
|
| 752 |
+
extra = refine_sentence(
|
| 753 |
+
output,
|
| 754 |
+
min_wsd=max(0.08, min_wsd * 0.8),
|
| 755 |
+
max_changes=limit - len(changes),
|
| 756 |
+
wordnet=resource,
|
| 757 |
+
aggressive=True,
|
| 758 |
+
polish=False,
|
| 759 |
+
)
|
| 760 |
+
if extra.changes and extra.text != output:
|
| 761 |
+
seen = {
|
| 762 |
+
(change.original.lower(), change.replacement.lower())
|
| 763 |
+
for change in changes
|
| 764 |
+
}
|
| 765 |
+
appended = False
|
| 766 |
+
for change in extra.changes:
|
| 767 |
+
pair = (change.original.lower(), change.replacement.lower())
|
| 768 |
+
if pair not in seen:
|
| 769 |
+
changes.append(change)
|
| 770 |
+
seen.add(pair)
|
| 771 |
+
appended = True
|
| 772 |
+
if appended:
|
| 773 |
+
output = extra.text
|
| 774 |
changes.sort(key=lambda change: change.token_index)
|
| 775 |
confidence = min(change.confidence for change in changes)
|
| 776 |
return LexicalResult(text=output, changes=changes, confidence=confidence)
|
app/engine/orchestrator.py
CHANGED
|
@@ -24,7 +24,11 @@ from app.engine.consistency import apply_consistency
|
|
| 24 |
from app.engine.force import force_cleft_rewrite
|
| 25 |
from app.engine.grammar import repair_sentence
|
| 26 |
from app.engine.ingest import ingest_text
|
| 27 |
-
from app.engine.lexical import
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
from app.engine.models import (
|
| 29 |
DocumentBlock,
|
| 30 |
EngineResult,
|
|
@@ -113,6 +117,64 @@ def _apply_lexical_refinement(
|
|
| 113 |
return record
|
| 114 |
|
| 115 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
def _unchanged(record: SentenceRecord) -> bool:
|
| 117 |
return (
|
| 118 |
record.rewritten.strip().lower().rstrip(".!?")
|
|
@@ -311,15 +373,26 @@ def _finalize_sentence(
|
|
| 311 |
use_minilm=use_minilm,
|
| 312 |
)
|
| 313 |
record = _apply_forced_rewrite(record, enabled=force_enabled)
|
| 314 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 315 |
record,
|
| 316 |
-
enabled=lexical_enabled,
|
| 317 |
min_wsd=lexical_min_wsd,
|
| 318 |
max_changes=lexical_max_changes,
|
| 319 |
safety_min=safety_min,
|
| 320 |
min_confidence=min_confidence,
|
| 321 |
use_minilm=use_minilm,
|
| 322 |
-
polish=lexical_polish,
|
| 323 |
)
|
| 324 |
return _ensure_wording_changed(
|
| 325 |
record,
|
|
|
|
| 24 |
from app.engine.force import force_cleft_rewrite
|
| 25 |
from app.engine.grammar import repair_sentence
|
| 26 |
from app.engine.ingest import ingest_text
|
| 27 |
+
from app.engine.lexical import (
|
| 28 |
+
dynamic_lexical_budget,
|
| 29 |
+
ensure_wording_change,
|
| 30 |
+
refine_sentence,
|
| 31 |
+
)
|
| 32 |
from app.engine.models import (
|
| 33 |
DocumentBlock,
|
| 34 |
EngineResult,
|
|
|
|
| 117 |
return record
|
| 118 |
|
| 119 |
|
| 120 |
+
def _apply_extra_polish(
|
| 121 |
+
record: SentenceRecord,
|
| 122 |
+
*,
|
| 123 |
+
enabled: bool,
|
| 124 |
+
min_wsd: float,
|
| 125 |
+
max_changes: int | None,
|
| 126 |
+
safety_min: float,
|
| 127 |
+
min_confidence: float,
|
| 128 |
+
use_minilm: bool,
|
| 129 |
+
) -> SentenceRecord:
|
| 130 |
+
"""Polish-only extra pass so the UI toggle has a real end-to-end effect."""
|
| 131 |
+
if not enabled or record.sentence_type not in _REWRITEABLE_TYPES:
|
| 132 |
+
return record
|
| 133 |
+
before = record.rewritten
|
| 134 |
+
target_budget = (
|
| 135 |
+
max(1, min(int(max_changes), 15))
|
| 136 |
+
if max_changes is not None
|
| 137 |
+
else dynamic_lexical_budget(before, polish=True)
|
| 138 |
+
)
|
| 139 |
+
remaining = max(0, target_budget - len(record.lexical_changes))
|
| 140 |
+
if remaining <= 0:
|
| 141 |
+
return record
|
| 142 |
+
refined = refine_sentence(
|
| 143 |
+
before,
|
| 144 |
+
min_wsd=min(min_wsd, 0.10),
|
| 145 |
+
max_changes=remaining,
|
| 146 |
+
aggressive=True,
|
| 147 |
+
)
|
| 148 |
+
if not refined.changes or refined.text == before:
|
| 149 |
+
return record
|
| 150 |
+
safety = check_safety(
|
| 151 |
+
before,
|
| 152 |
+
refined.text,
|
| 153 |
+
min_meaning=safety_min,
|
| 154 |
+
min_confidence=min_confidence,
|
| 155 |
+
use_minilm=use_minilm,
|
| 156 |
+
protected_entities=None,
|
| 157 |
+
protected_auxiliaries=None,
|
| 158 |
+
structural_validation=False,
|
| 159 |
+
)
|
| 160 |
+
if not safety.ok:
|
| 161 |
+
return record
|
| 162 |
+
|
| 163 |
+
prior_lex = list(record.lexical_changes)
|
| 164 |
+
record.rewritten = refined.text
|
| 165 |
+
record.lexical_changes = prior_lex + refined.changes
|
| 166 |
+
record.status = "rewritten"
|
| 167 |
+
if not record.template_id:
|
| 168 |
+
record.template_id = "lexical_refine"
|
| 169 |
+
elif "+lexical" not in record.template_id:
|
| 170 |
+
record.template_id = f"{record.template_id}+lexical"
|
| 171 |
+
record.confidence = min(
|
| 172 |
+
safety.confidence,
|
| 173 |
+
record.confidence if record.confidence > 0 else max(min_confidence, 0.55),
|
| 174 |
+
)
|
| 175 |
+
return record
|
| 176 |
+
|
| 177 |
+
|
| 178 |
def _unchanged(record: SentenceRecord) -> bool:
|
| 179 |
return (
|
| 180 |
record.rewritten.strip().lower().rstrip(".!?")
|
|
|
|
| 373 |
use_minilm=use_minilm,
|
| 374 |
)
|
| 375 |
record = _apply_forced_rewrite(record, enabled=force_enabled)
|
| 376 |
+
should_run_second_lexical = lexical_polish or not record.lexical_changes
|
| 377 |
+
if should_run_second_lexical:
|
| 378 |
+
record = _apply_lexical_refinement(
|
| 379 |
+
record,
|
| 380 |
+
enabled=lexical_enabled,
|
| 381 |
+
min_wsd=lexical_min_wsd,
|
| 382 |
+
max_changes=lexical_max_changes,
|
| 383 |
+
safety_min=safety_min,
|
| 384 |
+
min_confidence=min_confidence,
|
| 385 |
+
use_minilm=use_minilm,
|
| 386 |
+
polish=lexical_polish,
|
| 387 |
+
)
|
| 388 |
+
record = _apply_extra_polish(
|
| 389 |
record,
|
| 390 |
+
enabled=lexical_enabled and lexical_polish,
|
| 391 |
min_wsd=lexical_min_wsd,
|
| 392 |
max_changes=lexical_max_changes,
|
| 393 |
safety_min=safety_min,
|
| 394 |
min_confidence=min_confidence,
|
| 395 |
use_minilm=use_minilm,
|
|
|
|
| 396 |
)
|
| 397 |
return _ensure_wording_changed(
|
| 398 |
record,
|