Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions tools/v2/individual/email-translator/docs/CORE_CONTRACT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Email Translator Core Contract

This document describes the folder-local Email Translator core engine. The
implementation is deterministic and offline: it uses a local phrasebook and word
maps for reviewable behavior, and it does not call live translation APIs, LLMs,
mailboxes, databases, wallets, Stellar services, or production systems.

## Inputs

`translateEmail(request, options)` accepts:

- `id`: stable local request identifier.
- `sourceText`: required email body text.
- `sourceLanguage`: language code or `auto`.
- `targetLanguage`: required language code.

Supported language codes are `en`, `es`, `fr`, `de`, and `pt`. The local mock
provider intentionally supports only a small set of pairs. Unsupported pairs
return a structured error instead of making a network call.

`options.now` fixes the generated timestamp for deterministic tests.
`options.maxTextChars` clips large source text for local review.

## Outputs

Successful calls return:

- `status: "ready"`
- `isLoading: false`
- `error: null`
- `result.provider: "local-deterministic-phrasebook"`
- `result.sourceLanguage` and `result.targetLanguage`
- `result.detectedLanguage` and `result.detectionConfidence`
- `result.translatedText`
- `result.segments` preserving paragraph separators for future UI rendering
- `result.untranslatedTerms` for reviewer follow-up
- `result.warnings` for clipping or preserved terms
- `result.metrics` with character counts, word counts, replacements, and
confidence
- `result.reviewRequired` when confidence is low or terms remain untranslated

## Loading State

`createEmailTranslatorLoadingState(message)` returns:

- `status: "loading"`
- `isLoading: true`
- `error: null`
- `result: null`
- `message`: caller-visible progress text.

## Error State

Invalid requests do not throw. They return:

- `status: "error"`
- `isLoading: false`
- `error.code: "email-translator-error"`
- `error.messages`: validation or translation contract messages.
- `result: null`
- `requestId`: local request id when available.

The validator rejects empty source text, unsupported languages, overly large
input, and active markup such as script tags or `javascript:` URLs.

## Local Review Command

Run from the repository root:

```bash
node --test tools/v2/individual/email-translator/tests/email-translator-core.test.mjs
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"tool": "email-translator",
"runContext": {
"now": "2026-07-01T00:00:00.000Z",
"source": "synthetic-folder-local-fixture"
},
"sourceRequests": [
{
"id": "translation-en-es-001",
"sourceLanguage": "en",
"targetLanguage": "es",
"sourceText": "Hello team,\n\nPlease review the meeting notes and send the invoice tomorrow.\n\nThank you"
},
{
"id": "translation-en-fr-002",
"sourceLanguage": "auto",
"targetLanguage": "fr",
"sourceText": "Good morning,\n\nPlease confirm the next steps for the project update."
},
{
"id": "translation-es-en-003",
"sourceLanguage": "auto",
"targetLanguage": "en",
"sourceText": "Hola equipo,\n\nPor favor revise la factura y el plazo."
}
],
"expectedOutcomes": [
{
"id": "translation-en-es-001",
"sourceLanguage": "en",
"targetLanguage": "es",
"requiredText": ["Hola", "equipo", "factura"]
},
{
"id": "translation-en-fr-002",
"sourceLanguage": "en",
"targetLanguage": "fr",
"requiredText": ["Bonjour", "Veuillez confirmer", "prochaines etapes"]
},
{
"id": "translation-es-en-003",
"sourceLanguage": "es",
"targetLanguage": "en",
"requiredText": ["Hello", "Please review", "invoice", "deadline"]
}
]
}
11 changes: 11 additions & 0 deletions tools/v2/individual/email-translator/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export {
SUPPORTED_LANGUAGES,
createEmailTranslatorErrorState,
createEmailTranslatorLoadingState,
detectLanguage,
emailTranslatorCore,
getSupportedLanguagePairs,
translateEmail,
translateEmailBatch,
validateTranslationRequest,
} from "./services/email-translator.service.mjs";
Loading