Skip to content

aegean.translate

Translation, notes, and optional checking

from aegean import ai, greek, translate

client = ai.get_client("openrouter", model="openai/gpt-5.4")
pipeline = greek.GreekPipeline.neural()
result = translate.translate(
    "τὸν παῖδα ὁ ἀνὴρ ὁρᾷ.",
    greek_pipeline=pipeline,
    grounding_failure="strict",
    style="annotated",       # default; "concise" keeps the displayed reading short
    verify=True,             # optional: two model calls, not independent human review
    client=client,
)
print(result.text)            # translation only when the response is structured
print(result.labeled())       # exploratory label and model-reported notes
print(result.data["uncertainties"])
print(result.data["changes"]) # before, after, reason, evidence for each reported change
print(result.draft.text)      # initial ungrounded draft, retained with its own notes
result.to_json("translation.json")

Set OPENROUTER_API_KEY securely before a live call. The neural model requires the [neural] extra and model activation; OpenRouter requires [openrouter]. The same styles are supported by the lower-level ai.translate and ai.verify_translation functions. Checking remains off by default.

Supply surrounding Greek, speaker labels, and cited editorial notes with source_context, separately from the passage being translated:

from pathlib import Path

context = Path("source-context.txt").read_text(encoding="utf-8")
result = translate.translate(
    "τὸν παῖδα ὁ ἀνὴρ ὁρᾷ.", source_context=context,
    greek_pipeline=pipeline, verify=True, client=client,
)
assert result.data["source_context"] == context
assert result.draft.data["source_context"] == context

Both calls receive the same context; only the target passage is analyzed and translated. Context is fenced as source material, with instructions to use it for interpretation rather than follow directions embedded in it. Supply source citations and distinguish editorial notes from quoted Greek. Surrounding text is not fetched automatically by these string-based APIs.

ai.translate and ai.verify_translation accept the same keyword. Checking a saved ExploratoryResult inherits its recorded context when the keyword is omitted or None. A different explicit context raises ValueError before any provider call; start a new translation to change the context of an existing context-bound draft. A string draft or older result without recorded context can receive explicit context. Supplied strings, including whitespace, survive JSON round trips and traces exactly.

Structured responses separate the final reading from uncertainty and change reports. result.data["raw_response"] preserves the exact provider text. result.draft preserves the initial result, including provider/model, prompt version and notes. JSON export/reload keeps both stages; result.trace() shows the draft, notes, changes and supplied evidence. A change reason is a model's explanation, not a recorded human review decision or verified citation.

Plain JSON and a single complete Markdown JSON fence are accepted locally; surrounding prose or multiple response blocks are not silently discarded. If a provider returns malformed JSON or the wrong field types, no extra paid repair call is made. The raw answer remains in result.text and data["raw_response"]; data["format_status"] is "unstructured", and the unavailable structured fields are None. This means notes were not successfully extracted, not that no uncertainties or changes exist. Check format_status before processing these fields automatically. Older saved results may have data=None and no draft.

For a structured draft and final answer, data["text_changed"] records an exact text comparison. If the wording differs but the model reports an empty changes array, data["change_report_status"] flags "unreported_text_difference" and the labeled output calls attention to it. This comparison does not judge the meaning or certify the reported reasons. A string draft, legacy/unstructured draft, or unstructured final is marked "not_comparable" for this local check. The same applies if a retained draft's text has been edited independently of its structured translation field; comparison_note explains that mismatch.

For an explicit check of roles, negation, qualifications and speech acts, select check_policy="clauses" with Greek verify=True. The lower-level ai.verify_translation accepts the same policy for checking a saved draft in one call. The default policy remains "standard"; checking itself remains optional.

greek.use_lexicon("middle-liddell")  # explicit activation; may fetch its cache
evidence = translate.grounding_for(
    "τὸν παῖδα ὁ ἀνὴρ ὁρᾷ.", "greek", mode="full",
    greek_pipeline=pipeline, lexical_evidence="contextual",
)
checked = ai.verify_translation(
    "τὸν παῖδα ὁ ἀνὴρ ὁρᾷ.", result, grounding=evidence,
    check_policy="clauses", max_tokens=4096, client=client,
)
print(checked.data["clause_checks"])
print(checked.data["clause_check_status"])
print(checked.data["clause_check_validation"])

Each model-reported clause has exact source and revised-translation quotations, one-based occurrence numbers, four check statuses, a short finding and supplied evidence references. Local validation resolves quotations into zero-based Unicode codepoint offsets and records uncovered non-whitespace spans. "aligned" means the report's shape, quotations, reference membership and literal coverage pass; it does not verify the clause boundaries, meaning, claims or completeness of the model's interpretation. A report can be literally aligned while reporting "concern" or "uncertain". Missing mappings produce "incomplete"; malformed populated fields, invented quotations or unknown references produce "invalid". The received report remains available in every case. Invalid clause reports do not discard an otherwise usable structured translation or trigger another call.

Concise output retains notes in JSON and the trace, and signals that notes are available. Use annotated output when reading the explanation alongside the translation. Plain result.text is intentionally just the reading for structured responses; use labeled() when displaying a result to retain its status.

aegean ai translate 'τὸν παῖδα ὁ ἀνὴρ ὁρᾷ.' \
  --provider openrouter --model openai/gpt-5.4 \
  --greek-backend neural --verify --source-context-file source-context.txt \
  --style concise --output translation.json

aegean ai translate 'τὸν παῖδα ὁ ἀνὴρ ὁρᾷ.' \
  --provider openrouter --model openai/gpt-5.4 \
  --greek-backend neural --verify --style annotated --trace --output translation.txt

Translation .txt files automatically include the audit trace, even without --trace, so a saved concise reading does not discard its notes or draft. --trace also displays these details on the terminal. These commands make separate paid requests; JSON is the preferred reusable archive. Use --source-context for inline context or --source-context-file for a UTF-8 file; the two options are mutually exclusive.

Add --check-policy clauses to a Greek --verify command for the clause audit, and --lexical-evidence contextual for bounded dictionary excerpts. The Python and CLI policy controls are explicit; the corpus reader retains standard checking. Use repeatable --dictionary options to activate dictionaries for that command; activation may fetch their caches on first use. For example:

aegean ai translate 'τὸν παῖδα ὁ ἀνὴρ ὁρᾷ.' \
  --provider openrouter --model openai/gpt-5.4 --greek-backend neural \
  --verify --check-policy clauses --lexical-evidence contextual \
  --dictionary middle-liddell --dictionary cunliffe --max-tokens 4096 \
  --source-context-file source-context.txt --output checked.json

Translation and checking use a 2,048-token output allowance per call. Set max_tokens in Python or --max-tokens on the CLI for longer passages or more detailed notes. The value must be a positive integer. It is a maximum, not a request to fill that space; provider truncation can still occur. The package preserves malformed or incomplete structured output and makes no repair call.

The Greek corpus reader supplies the selected line's source metadata and up to one neighboring reader line on each side, within the same document. It retains available speaker labels, citations, and editorial reading states. Source-aligned slices preserve their characters; older token-only records are labeled as reconstructed text. The selected line remains the translation target.

Greek evidence

Full and lemma modes accept lexical_evidence="contextual" with glosses enabled. This selects exact excerpts from already active built-in dictionaries, including alternative senses and construction cues when available. It uses the selected pipeline's resolved lemmas and sentence-local textual cues without invoking a second lemmatizer or activating dictionaries. Common words are eligible too. Activate the dictionaries you need before building evidence.

Each item identifies its source entry and exact excerpt offsets, selection reasons, omitted characters and unresolved cross-references. A coverage item records unavailable or unsupported sources and budget omissions. The excerpts are reference material; their selection does not establish the intended sense. The default "concise" evidence retains the existing short gloss behavior.

Dependency evidence describes the supplied parse, including subordinate clauses and coordinated subjects. It does not silently correct a wrong parse. Review the source and the relationships relevant to your reading.

UD Tense=Past is a morphological tag, not a sufficient claim that a subjunctive, infinitive or participle describes past time. Grounding preserves raw features and separates morphological labels from temporal interpretation. Missing aspect information is not silently filled in as an aorist analysis.

translate

Hybrid translation with local, provisional Greek analysis and lexicon evidence.

The zero-dependency baseline provides limited rule/lookup analyses; an explicitly activated neural pipeline supplies model predictions, including morphology and syntax. Backend identity, field provenance and degraded coverage accompany the evidence shown to the model. Repeatable computation does not establish linguistic correctness. Source annotations and scholarly decisions can be supplied explicitly.

morphology supplies token analyses, a clause skeleton when available, and idiom matches. full adds optional concise dictionary candidates; lemma retains the legacy lemma lines and optional LSJ glosses; none disables automatic grounding. No mode guarantees correct contextual readings or translation quality. Strict and best-effort failure policies remain explicit, and no backend is loaded implicitly.

GroundingError

GroundingError(*, stage: str, script: str, backend: str | None, config: dict[str, Any] | None)

Bases: RuntimeError

Required local grounding failed under the explicit "strict" policy.

The persisted/public message names the failed stage without copying arbitrary exception text. The original exception remains available as __cause__.

grounding_for

grounding_for(text: str, script: str, *, mode: GroundingMode = 'morphology', glosses: bool = True, lexical_evidence: Literal['concise', 'contextual'] = 'concise', greek_pipeline: GreekPipeline | None = None, greek_long_input: GreekLongInput = 'strict', grounding_failure: GroundingFailure = 'best-effort') -> list[GroundingItem]

Build local evidence with status and provenance visible in prompts and traces.

Greek modes are morphology (token analyses, optional clause skeleton and idiom matches), full (adds concise dictionary candidates), lemma (lemma lines and optional gated LSJ glosses), and none (no automatic evidence). glosses=False omits dictionary candidates in full/lemma modes. Dictionary matches and grammatical predictions can be wrong in context.

lexical_evidence='contextual' selects bounded exact dictionary excerpts, including alternative senses and construction cues, from already active built-in dictionaries. It requires Greek full/lemma mode with glosses enabled. Selection uses the supplied analysis and textual cues, not verified contextual senses; provenance records excerpts, omissions and unavailable sources.

A leading availability item reports the selected backend, required stages, missing stages and token coverage. Per-token evidence distinguishes lemma source, resolution and review triage from human verification. The baseline is a limited rule/lookup backend; it is never silently upgraded to neural. A neural backend must be activated explicitly on greek_pipeline or the module-default facade. No model or dictionary is downloaded by this function.

greek_pipeline=None retains the module-default compatibility facade; an explicit instance owns analysis in isolation. greek_long_input selects strict, partial or windowed neural analysis. grounding_failure='strict' raises GroundingError on required analysis failure before a provider call; best-effort retains available evidence and reports degradation. Missing optional dictionaries/rarity corpora and unmatched idioms are normal absences. Invalid modes, failure policies and script/backend combinations raise.

translate

translate(text: str, *, script: str = 'greek', target: str = 'English', mode: GroundingMode = 'morphology', glosses: bool = True, lexical_evidence: Literal['concise', 'contextual'] = 'concise', verify: bool = False, check_policy: str = 'standard', style: Literal['annotated', 'concise'] = 'annotated', source_context: str | None = None, max_tokens: int = 2048, greek_pipeline: GreekPipeline | None = None, greek_long_input: GreekLongInput = 'strict', grounding_failure: GroundingFailure = 'best-effort', grounding: Iterable[str | GroundingItem] = (), client: LLMClient | None = None) -> ExploratoryResult

Translate with local provisional evidence, returning an exploratory result.

See grounding_for for modes, backend selection and failure policies. grounding accepts additional GroundingItem evidence, including explicit source annotations and field-level review decisions from ai.annotation_evidence. Its status/provenance reaches the provider along with automatic predictions; it does not implicitly replace or certify them. mode='none' disables automatic grounding but retains supplied evidence.

style='annotated' includes model-reported uncertainty and correction details in labeled output; 'concise' keeps the reading short while retaining those details in data, JSON and trace(). For structured responses, text contains only the translation. Unstructured provider responses remain available verbatim and are explicitly marked as such.

source_context supplies surrounding text, speaker labels, or cited source notes separately from the passage to translate. Both drafting and checking receive the same context and retain it exactly in data['source_context']. Only text is analyzed and translated; context is untrusted source material, not instructions. No surrounding text is fetched or inferred automatically. max_tokens sets a positive output-token allowance for each provider call (default 2,048); it does not trigger retries or format-repair requests.

verify=True (Greek only) generates an ungrounded draft then asks the same provider to check it against full grounding and supplied evidence. A wrong analysis can still mislead the repair. Grounding cannot bias the initial draft because the first model call receives no grounding. It remains exploratory, is not independent scholarly verification, and has no guarantee of improving semantic quality. The original draft, including its notes and provenance, remains available as result.draft. Corrections and their reasons are model reports, not accepted human review decisions. Qualified raters are needed to evaluate translation quality.

check_policy='clauses' requires Greek verify=True and requests an explicit check of roles, negation, qualifications and speech acts. Exact source/translation spans, findings and literal coverage gaps are retained; literal alignment does not establish semantic completeness or correctness. lexical_evidence='contextual' adds bounded dictionary excerpts as described in grounding_for; checking uses full mode regardless of mode.

Strict grounding failures stop before either provider call. Best-effort degradation and limited baseline coverage are reported through warnings, prompt evidence, grounding_runtime, and labeled/trace output. Model and dictionary activation remains opt-in; no downloads occur here.