# translator

Language & translation microservice: translate ({text,to,from?}) uses an LLM as the PRIMARY engine and gracefully falls back to a small built-in phrase dictionary + passthrough when no model is...


Language & translation microservice. Translate text, detect languages, transliterate scripts, and
localize with a glossary and tone-preservation notes.

`translate` and `batch` use an **LLM as the primary engine** (via `../_shared/llm.js`). When no model
is reachable they gracefully fall back to a small built-in phrase dictionary, then to passthrough —
always tagged with `{ mode, note }` so nothing throws:

- `mode: 'llm'` — a model translated it.
- `mode: 'dictionary'` — partial phrase-dictionary hit (offline). `note` tells you to install a model.
- `mode: 'passthrough'` — source returned unchanged (offline, no dictionary hit). `note` says why.

The other four tools are **pure and fully offline**.

## Tools

| Tool | Input | Returns |
|---|---|---|
| `translate` | `{ text, to, from?, glossary? }` | `{ translation, from, to, mode, note? }` |
| `detectLanguage` | `{ text }` | `{ language, code, confidence, reliable, scores }` |
| `glossaryApply` | `{ text, glossary }` | `{ text, applied, replacements }` |
| `tonePreserveNote` | `{ text }` | `{ register, notes, signals }` — what to keep when translating |
| `batch` | `{ texts:[..], to, from? }` | `{ results:[{translation,mode}], modes }` |
| `romanize` | `{ text }` | `{ text, transliterated, isAscii }` — accented Latin / Cyrillic / Greek → ASCII |

## Usage

```js
import pack from './index.js';

pack.adapters.detectLanguage({ text: 'Le chat est sur la table' });
// -> { language:'French', code:'fr', confidence, reliable:true }

pack.adapters.glossaryApply({ text: 'Our SDK powers the API', glossary: { SDK: 'toolkit', API: 'interface' } });
// -> { text:'Our toolkit powers the interface', applied:[...] }

pack.adapters.romanize({ text: 'Cafédóttir Москва Αθήνα' });
// -> { text:'Cafedottir Moskva Athina', isAscii:true }

await pack.adapters.translate({ text: 'Hello, thank you', to: 'es' });
// with a model -> { mode:'llm', translation:'Hola, gracias' }
// offline      -> { mode:'dictionary', translation:'Hola, gracias', note:'...install a model...' }
```

`to`/`from` accept codes (`es`, `fr`) or names (`spanish`, `French`). Pass `options:{ useLlm:false }`
to force the offline path.

## DRY boundaries

- Generic tokenize / sentiment / readability of prose lives in **`nlp`** / **`a-text`**; hex/base64
  DATA encoding lives in **`a-transformation`**. This pack owns **language** modeling: translation
  routing, language identification, transliteration, glossary/tone localization.
- `detectLanguage` and `glossaryApply` are deterministic and never call the network.
- Self-contained: the only import is `../_shared/llm.js`.


---
Source: shared/engines/adapters/domain/translator/README.md
Canonical: https://docs.leumas.tech/p/adapters/domain/translator
