@llm-translate/cli 1.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +51 -0
- package/.env.example +33 -0
- package/.github/workflows/docs-pages.yml +57 -0
- package/.github/workflows/release.yml +49 -0
- package/.translaterc.json +44 -0
- package/CLAUDE.md +243 -0
- package/Dockerfile +55 -0
- package/README.md +371 -0
- package/RFC.md +1595 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +4494 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +1152 -0
- package/dist/index.js +3841 -0
- package/dist/index.js.map +1 -0
- package/docker-compose.yml +56 -0
- package/docs/.vitepress/config.ts +161 -0
- package/docs/api/agent.md +262 -0
- package/docs/api/engine.md +274 -0
- package/docs/api/index.md +171 -0
- package/docs/api/providers.md +304 -0
- package/docs/changelog.md +64 -0
- package/docs/cli/dir.md +243 -0
- package/docs/cli/file.md +213 -0
- package/docs/cli/glossary.md +273 -0
- package/docs/cli/index.md +129 -0
- package/docs/cli/init.md +158 -0
- package/docs/cli/serve.md +211 -0
- package/docs/glossary.json +235 -0
- package/docs/guide/chunking.md +272 -0
- package/docs/guide/configuration.md +139 -0
- package/docs/guide/cost-optimization.md +237 -0
- package/docs/guide/docker.md +371 -0
- package/docs/guide/getting-started.md +150 -0
- package/docs/guide/glossary.md +241 -0
- package/docs/guide/index.md +86 -0
- package/docs/guide/ollama.md +515 -0
- package/docs/guide/prompt-caching.md +221 -0
- package/docs/guide/providers.md +232 -0
- package/docs/guide/quality-control.md +206 -0
- package/docs/guide/vitepress-integration.md +265 -0
- package/docs/index.md +63 -0
- package/docs/ja/api/agent.md +262 -0
- package/docs/ja/api/engine.md +274 -0
- package/docs/ja/api/index.md +171 -0
- package/docs/ja/api/providers.md +304 -0
- package/docs/ja/changelog.md +64 -0
- package/docs/ja/cli/dir.md +243 -0
- package/docs/ja/cli/file.md +213 -0
- package/docs/ja/cli/glossary.md +273 -0
- package/docs/ja/cli/index.md +111 -0
- package/docs/ja/cli/init.md +158 -0
- package/docs/ja/guide/chunking.md +271 -0
- package/docs/ja/guide/configuration.md +139 -0
- package/docs/ja/guide/cost-optimization.md +30 -0
- package/docs/ja/guide/getting-started.md +150 -0
- package/docs/ja/guide/glossary.md +214 -0
- package/docs/ja/guide/index.md +32 -0
- package/docs/ja/guide/ollama.md +410 -0
- package/docs/ja/guide/prompt-caching.md +221 -0
- package/docs/ja/guide/providers.md +232 -0
- package/docs/ja/guide/quality-control.md +137 -0
- package/docs/ja/guide/vitepress-integration.md +265 -0
- package/docs/ja/index.md +58 -0
- package/docs/ko/api/agent.md +262 -0
- package/docs/ko/api/engine.md +274 -0
- package/docs/ko/api/index.md +171 -0
- package/docs/ko/api/providers.md +304 -0
- package/docs/ko/changelog.md +64 -0
- package/docs/ko/cli/dir.md +243 -0
- package/docs/ko/cli/file.md +213 -0
- package/docs/ko/cli/glossary.md +273 -0
- package/docs/ko/cli/index.md +111 -0
- package/docs/ko/cli/init.md +158 -0
- package/docs/ko/guide/chunking.md +271 -0
- package/docs/ko/guide/configuration.md +139 -0
- package/docs/ko/guide/cost-optimization.md +30 -0
- package/docs/ko/guide/getting-started.md +150 -0
- package/docs/ko/guide/glossary.md +214 -0
- package/docs/ko/guide/index.md +32 -0
- package/docs/ko/guide/ollama.md +410 -0
- package/docs/ko/guide/prompt-caching.md +221 -0
- package/docs/ko/guide/providers.md +232 -0
- package/docs/ko/guide/quality-control.md +137 -0
- package/docs/ko/guide/vitepress-integration.md +265 -0
- package/docs/ko/index.md +58 -0
- package/docs/zh/api/agent.md +262 -0
- package/docs/zh/api/engine.md +274 -0
- package/docs/zh/api/index.md +171 -0
- package/docs/zh/api/providers.md +304 -0
- package/docs/zh/changelog.md +64 -0
- package/docs/zh/cli/dir.md +243 -0
- package/docs/zh/cli/file.md +213 -0
- package/docs/zh/cli/glossary.md +273 -0
- package/docs/zh/cli/index.md +111 -0
- package/docs/zh/cli/init.md +158 -0
- package/docs/zh/guide/chunking.md +271 -0
- package/docs/zh/guide/configuration.md +139 -0
- package/docs/zh/guide/cost-optimization.md +30 -0
- package/docs/zh/guide/getting-started.md +150 -0
- package/docs/zh/guide/glossary.md +214 -0
- package/docs/zh/guide/index.md +32 -0
- package/docs/zh/guide/ollama.md +410 -0
- package/docs/zh/guide/prompt-caching.md +221 -0
- package/docs/zh/guide/providers.md +232 -0
- package/docs/zh/guide/quality-control.md +137 -0
- package/docs/zh/guide/vitepress-integration.md +265 -0
- package/docs/zh/index.md +58 -0
- package/package.json +91 -0
- package/release.config.mjs +15 -0
- package/schemas/glossary.schema.json +110 -0
- package/src/cli/commands/dir.ts +469 -0
- package/src/cli/commands/file.ts +291 -0
- package/src/cli/commands/glossary.ts +221 -0
- package/src/cli/commands/init.ts +68 -0
- package/src/cli/commands/serve.ts +60 -0
- package/src/cli/index.ts +64 -0
- package/src/cli/options.ts +59 -0
- package/src/core/agent.ts +1119 -0
- package/src/core/chunker.ts +391 -0
- package/src/core/engine.ts +634 -0
- package/src/errors.ts +188 -0
- package/src/index.ts +147 -0
- package/src/integrations/vitepress.ts +549 -0
- package/src/parsers/markdown.ts +383 -0
- package/src/providers/claude.ts +259 -0
- package/src/providers/interface.ts +109 -0
- package/src/providers/ollama.ts +379 -0
- package/src/providers/openai.ts +308 -0
- package/src/providers/registry.ts +153 -0
- package/src/server/index.ts +152 -0
- package/src/server/middleware/auth.ts +93 -0
- package/src/server/middleware/logger.ts +90 -0
- package/src/server/routes/health.ts +84 -0
- package/src/server/routes/translate.ts +210 -0
- package/src/server/types.ts +138 -0
- package/src/services/cache.ts +899 -0
- package/src/services/config.ts +217 -0
- package/src/services/glossary.ts +247 -0
- package/src/types/analysis.ts +164 -0
- package/src/types/index.ts +265 -0
- package/src/types/modes.ts +121 -0
- package/src/types/mqm.ts +157 -0
- package/src/utils/logger.ts +141 -0
- package/src/utils/tokens.ts +116 -0
- package/tests/fixtures/glossaries/ml-glossary.json +53 -0
- package/tests/fixtures/input/lynq-installation.ko.md +350 -0
- package/tests/fixtures/input/lynq-installation.md +350 -0
- package/tests/fixtures/input/simple.ko.md +27 -0
- package/tests/fixtures/input/simple.md +27 -0
- package/tests/unit/chunker.test.ts +229 -0
- package/tests/unit/glossary.test.ts +146 -0
- package/tests/unit/markdown.test.ts +205 -0
- package/tests/unit/tokens.test.ts +81 -0
- package/tsconfig.json +28 -0
- package/tsup.config.ts +34 -0
- package/vitest.config.ts +16 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Providers
|
|
2
|
+
|
|
3
|
+
::: info Translations
|
|
4
|
+
All non-English documentation is automatically translated using Claude Sonnet 4.
|
|
5
|
+
:::
|
|
6
|
+
|
|
7
|
+
llm-translate supports multiple LLM providers. Each has different strengths and trade-offs.
|
|
8
|
+
|
|
9
|
+
## Supported Providers
|
|
10
|
+
|
|
11
|
+
| Provider | Caching | Best For | Setup Complexity |
|
|
12
|
+
|----------|---------|----------|------------------|
|
|
13
|
+
| Claude | Full | Quality + Cost | Easy |
|
|
14
|
+
| OpenAI | Automatic | Ecosystem | Easy |
|
|
15
|
+
| Ollama | None | Privacy/Offline | Medium |
|
|
16
|
+
|
|
17
|
+
## Claude (Recommended)
|
|
18
|
+
|
|
19
|
+
### Why Claude?
|
|
20
|
+
|
|
21
|
+
- **Prompt caching**: Up to 90% cost reduction
|
|
22
|
+
- **High quality**: Excellent translation accuracy
|
|
23
|
+
- **Long context**: 200K token context window
|
|
24
|
+
- **Multiple tiers**: Haiku (fast), Sonnet (balanced), Opus (best)
|
|
25
|
+
|
|
26
|
+
### Setup
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
export ANTHROPIC_API_KEY=sk-ant-xxxxx
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Model Selection
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Fast and cheap (default)
|
|
36
|
+
llm-translate file doc.md --target ko --model claude-haiku-4-5-20251001
|
|
37
|
+
|
|
38
|
+
# Balanced quality/cost
|
|
39
|
+
llm-translate file doc.md --target ko --model claude-sonnet-4-5-20250929
|
|
40
|
+
|
|
41
|
+
# Highest quality
|
|
42
|
+
llm-translate file doc.md --target ko --model claude-opus-4-5-20251101
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### When to Use Each Model
|
|
46
|
+
|
|
47
|
+
| Model | Use Case |
|
|
48
|
+
|-------|----------|
|
|
49
|
+
| Haiku | README files, simple docs, high volume |
|
|
50
|
+
| Sonnet | Technical documentation, API references |
|
|
51
|
+
| Opus | Legal, marketing, nuanced content |
|
|
52
|
+
|
|
53
|
+
## OpenAI
|
|
54
|
+
|
|
55
|
+
### Setup
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
export OPENAI_API_KEY=sk-xxxxx
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Usage
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
llm-translate file doc.md --target ko --provider openai --model gpt-4o
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Available Models
|
|
68
|
+
|
|
69
|
+
| Model | Speed | Quality | Cost |
|
|
70
|
+
|-------|-------|---------|------|
|
|
71
|
+
| gpt-4o-mini | Fast | Good | Very Low |
|
|
72
|
+
| gpt-4o | Medium | Excellent | Medium |
|
|
73
|
+
| gpt-4-turbo | Medium | Excellent | High |
|
|
74
|
+
|
|
75
|
+
### When to Use
|
|
76
|
+
|
|
77
|
+
- Already using OpenAI for other services
|
|
78
|
+
- Need specific OpenAI features
|
|
79
|
+
- Prefer Azure OpenAI (set custom baseUrl)
|
|
80
|
+
|
|
81
|
+
## Ollama
|
|
82
|
+
|
|
83
|
+
Local, self-hosted LLMs for privacy or offline use. No API keys required.
|
|
84
|
+
|
|
85
|
+
::: warning Quality Varies by Model
|
|
86
|
+
Ollama translation quality is **highly dependent on model selection**. For reliable translation results:
|
|
87
|
+
|
|
88
|
+
- **Minimum**: 14B+ parameter models (e.g., `qwen2.5:14b`, `llama3.1:14b`)
|
|
89
|
+
- **Recommended**: 32B+ models (e.g., `qwen2.5:32b`, `llama3.3:70b`)
|
|
90
|
+
- **Not recommended**: Models under 7B produce inconsistent and often unusable translations
|
|
91
|
+
|
|
92
|
+
Smaller models (3B, 7B) may work for simple content but frequently fail on technical documentation, produce incomplete outputs, or ignore formatting instructions.
|
|
93
|
+
:::
|
|
94
|
+
|
|
95
|
+
### Quick Setup
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# 1. Install (macOS)
|
|
99
|
+
brew install ollama
|
|
100
|
+
|
|
101
|
+
# 2. Pull qwen2.5:14b (recommended)
|
|
102
|
+
ollama pull qwen2.5:14b
|
|
103
|
+
|
|
104
|
+
# 3. Translate
|
|
105
|
+
llm-translate file doc.md -s en -t ko --provider ollama --model qwen2.5:14b
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Recommended Models
|
|
109
|
+
|
|
110
|
+
| Model | RAM | Quality | Best For |
|
|
111
|
+
|-------|-----|---------|----------|
|
|
112
|
+
| `qwen2.5:14b` | 16GB | Very Good | **Best balance (recommended)** |
|
|
113
|
+
| `qwen2.5:32b` | 32GB | Excellent | Higher quality |
|
|
114
|
+
| `llama3.1:8b` | 8GB | Good | Lighter weight |
|
|
115
|
+
| `llama3.2` | 4GB | Fair | Simple content only |
|
|
116
|
+
|
|
117
|
+
### When to Use
|
|
118
|
+
|
|
119
|
+
- Sensitive/private documents
|
|
120
|
+
- Offline environments
|
|
121
|
+
- Cost optimization (no API fees)
|
|
122
|
+
- Simple to moderate complexity content
|
|
123
|
+
|
|
124
|
+
::: tip Full Guide
|
|
125
|
+
See [Local Translation with Ollama](./ollama) for complete setup instructions, GPU optimization, troubleshooting, and advanced configuration.
|
|
126
|
+
:::
|
|
127
|
+
|
|
128
|
+
## Provider Comparison
|
|
129
|
+
|
|
130
|
+
### Quality
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
Opus > Sonnet ≈ GPT-4o > Haiku ≈ GPT-4o-mini > Qwen2.5:32b > Qwen2.5:14b
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Cost (per 1M tokens)
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
Ollama ($0) < GPT-4o-mini ($0.15) < Haiku ($1) < GPT-4o ($2.5) < Sonnet ($3) < Opus ($15)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Speed
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
Haiku ≈ GPT-4o-mini > Sonnet ≈ GPT-4o > Opus > Ollama (varies with hardware)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Switching Providers
|
|
149
|
+
|
|
150
|
+
### CLI
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Different providers
|
|
154
|
+
llm-translate file doc.md -s en -t ko --provider claude
|
|
155
|
+
llm-translate file doc.md -s en -t ko --provider openai
|
|
156
|
+
llm-translate file doc.md -s en -t ko --provider ollama
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Config File
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"provider": {
|
|
164
|
+
"name": "openai",
|
|
165
|
+
"model": "gpt-4o"
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Programmatic
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import {
|
|
174
|
+
createClaudeProvider,
|
|
175
|
+
createOpenAIProvider,
|
|
176
|
+
createOllamaProvider,
|
|
177
|
+
TranslationEngine,
|
|
178
|
+
} from '@llm-translate/cli';
|
|
179
|
+
|
|
180
|
+
// Switch providers easily
|
|
181
|
+
const providers = {
|
|
182
|
+
claude: createClaudeProvider(),
|
|
183
|
+
openai: createOpenAIProvider(),
|
|
184
|
+
ollama: createOllamaProvider(),
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const engine = new TranslationEngine({
|
|
188
|
+
provider: providers[selectedProvider],
|
|
189
|
+
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Fallback Configuration
|
|
193
|
+
|
|
194
|
+
Configure fallback providers for reliability:
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"provider": {
|
|
199
|
+
"name": "claude",
|
|
200
|
+
"model": "claude-haiku-4-5-20251001",
|
|
201
|
+
"fallback": [
|
|
202
|
+
{ "name": "openai", "model": "gpt-4o-mini" },
|
|
203
|
+
{ "name": "ollama", "model": "llama3.1" }
|
|
204
|
+
]
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Custom Endpoints
|
|
210
|
+
|
|
211
|
+
### Azure OpenAI
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"provider": {
|
|
216
|
+
"name": "openai",
|
|
217
|
+
"baseUrl": "https://your-resource.openai.azure.com",
|
|
218
|
+
"apiKey": "your-azure-key"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Self-Hosted
|
|
224
|
+
|
|
225
|
+
```json
|
|
226
|
+
{
|
|
227
|
+
"provider": {
|
|
228
|
+
"name": "ollama",
|
|
229
|
+
"baseUrl": "https://your-server.com:11434"
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Quality Control
|
|
2
|
+
|
|
3
|
+
::: info Translations
|
|
4
|
+
All non-English documentation is automatically translated using Claude Sonnet 4.
|
|
5
|
+
:::
|
|
6
|
+
|
|
7
|
+
llm-translate uses a Self-Refine algorithm to ensure translation quality meets your requirements.
|
|
8
|
+
|
|
9
|
+
## How Self-Refine Works
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌─────────────────┐
|
|
13
|
+
│ Initial Translate│
|
|
14
|
+
└────────┬────────┘
|
|
15
|
+
▼
|
|
16
|
+
┌─────────────────┐
|
|
17
|
+
│ Evaluate Quality │◀──────────────┐
|
|
18
|
+
└────────┬────────┘ │
|
|
19
|
+
▼ │
|
|
20
|
+
Score >= Threshold? │
|
|
21
|
+
│ │
|
|
22
|
+
No │ Yes │
|
|
23
|
+
│ │ │
|
|
24
|
+
▼ ▼ │
|
|
25
|
+
┌─────────┐ ┌──────┐ │
|
|
26
|
+
│ Reflect │ │ Done │ │
|
|
27
|
+
└────┬────┘ └──────┘ │
|
|
28
|
+
▼ │
|
|
29
|
+
┌─────────────────┐ │
|
|
30
|
+
│ Improve │───────────────┘
|
|
31
|
+
└─────────────────┘
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 1. Initial Translation
|
|
35
|
+
|
|
36
|
+
The first translation is generated with:
|
|
37
|
+
- Full glossary context
|
|
38
|
+
- Document structure information
|
|
39
|
+
- Previous chunk context (for continuity)
|
|
40
|
+
|
|
41
|
+
### 2. Quality Evaluation
|
|
42
|
+
|
|
43
|
+
Each translation is scored on four criteria:
|
|
44
|
+
|
|
45
|
+
| Criterion | Weight | Description |
|
|
46
|
+
|-----------|--------|-------------|
|
|
47
|
+
| Semantic Accuracy | 40% | Does it convey the correct meaning? |
|
|
48
|
+
| Fluency | 25% | Does it read naturally in target language? |
|
|
49
|
+
| Glossary Compliance | 20% | Are all glossary terms applied correctly? |
|
|
50
|
+
| Format Preservation | 15% | Is markdown/HTML structure maintained? |
|
|
51
|
+
|
|
52
|
+
### 3. Reflection
|
|
53
|
+
|
|
54
|
+
If quality is below threshold, the LLM analyzes:
|
|
55
|
+
- What specific issues exist
|
|
56
|
+
- Which glossary terms were missed
|
|
57
|
+
- Where fluency can be improved
|
|
58
|
+
|
|
59
|
+
### 4. Improvement
|
|
60
|
+
|
|
61
|
+
Targeted fixes are applied based on reflection feedback, then the cycle repeats.
|
|
62
|
+
|
|
63
|
+
## Configuration
|
|
64
|
+
|
|
65
|
+
### Quality Threshold
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# CLI
|
|
69
|
+
llm-translate file doc.md -o doc.ko.md -s en -t ko --quality 90
|
|
70
|
+
|
|
71
|
+
# Config file
|
|
72
|
+
{
|
|
73
|
+
"translation": {
|
|
74
|
+
"qualityThreshold": 90
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Maximum Iterations
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# CLI
|
|
83
|
+
llm-translate file doc.md -o doc.ko.md -s en -t ko --max-iterations 6
|
|
84
|
+
|
|
85
|
+
# Config file
|
|
86
|
+
{
|
|
87
|
+
"translation": {
|
|
88
|
+
"maxIterations": 6
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Strict Mode
|
|
94
|
+
|
|
95
|
+
Fail if quality threshold is not met:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
llm-translate file doc.md -o doc.ko.md -s en -t ko --strict-quality
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Exit codes:
|
|
102
|
+
- `0` - Success
|
|
103
|
+
- `4` - Quality threshold not met (strict mode)
|
|
104
|
+
|
|
105
|
+
## Quality Score Interpretation
|
|
106
|
+
|
|
107
|
+
| Score | Quality Level | Description |
|
|
108
|
+
|-------|--------------|-------------|
|
|
109
|
+
| 95-100 | Excellent | Publication-ready |
|
|
110
|
+
| 85-94 | Good | Minor issues, acceptable for most uses |
|
|
111
|
+
| 75-84 | Fair | Noticeable issues, may need review |
|
|
112
|
+
| 60-74 | Poor | Significant issues, needs manual review |
|
|
113
|
+
| < 60 | Unacceptable | Major problems, consider re-translation |
|
|
114
|
+
|
|
115
|
+
## Understanding the Output
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
✓ Translation complete
|
|
119
|
+
Quality: 92/85 (threshold met)
|
|
120
|
+
Breakdown:
|
|
121
|
+
- Accuracy: 38/40
|
|
122
|
+
- Fluency: 24/25
|
|
123
|
+
- Glossary: 18/20
|
|
124
|
+
- Format: 12/15
|
|
125
|
+
Iterations: 2
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Breakdown Analysis
|
|
129
|
+
|
|
130
|
+
- **Accuracy (38/40)**: Translation is semantically correct
|
|
131
|
+
- **Fluency (24/25)**: Reads naturally in target language
|
|
132
|
+
- **Glossary (18/20)**: Most terms applied, some variations
|
|
133
|
+
- **Format (12/15)**: Minor formatting adjustments needed
|
|
134
|
+
|
|
135
|
+
## Tuning Quality
|
|
136
|
+
|
|
137
|
+
### For Higher Quality
|
|
138
|
+
|
|
139
|
+
1. **Increase threshold**: `--quality 95`
|
|
140
|
+
2. **Allow more iterations**: `--max-iterations 6`
|
|
141
|
+
3. **Use better model**: `--model claude-sonnet-4-5-20250929`
|
|
142
|
+
4. **Provide more context**: Add document purpose in config
|
|
143
|
+
|
|
144
|
+
### For Faster Processing
|
|
145
|
+
|
|
146
|
+
1. **Lower threshold**: `--quality 75`
|
|
147
|
+
2. **Reduce iterations**: `--max-iterations 2`
|
|
148
|
+
3. **Use faster model**: `--model claude-haiku-4-5-20251001`
|
|
149
|
+
|
|
150
|
+
### Cost vs Quality Trade-offs
|
|
151
|
+
|
|
152
|
+
| Setting | Cost | Time | Quality |
|
|
153
|
+
|---------|------|------|---------|
|
|
154
|
+
| threshold=70, iterations=2 | Low | Fast | Draft |
|
|
155
|
+
| threshold=85, iterations=4 | Medium | Moderate | Standard |
|
|
156
|
+
| threshold=95, iterations=6 | High | Slow | Premium |
|
|
157
|
+
|
|
158
|
+
## Quality Issues and Fixes
|
|
159
|
+
|
|
160
|
+
### Low Accuracy Score
|
|
161
|
+
|
|
162
|
+
**Causes:**
|
|
163
|
+
- Ambiguous source text
|
|
164
|
+
- Missing context
|
|
165
|
+
- Complex technical content
|
|
166
|
+
|
|
167
|
+
**Fixes:**
|
|
168
|
+
- Add context to glossary terms
|
|
169
|
+
- Use a more capable model
|
|
170
|
+
- Break complex sentences into simpler ones
|
|
171
|
+
|
|
172
|
+
### Low Fluency Score
|
|
173
|
+
|
|
174
|
+
**Causes:**
|
|
175
|
+
- Literal translation
|
|
176
|
+
- Unnatural phrasing
|
|
177
|
+
- Wrong register (formal/informal)
|
|
178
|
+
|
|
179
|
+
**Fixes:**
|
|
180
|
+
- Increase max iterations
|
|
181
|
+
- Use native-quality model (Sonnet/GPT-4)
|
|
182
|
+
- Review source text for clarity
|
|
183
|
+
|
|
184
|
+
### Low Glossary Compliance
|
|
185
|
+
|
|
186
|
+
**Causes:**
|
|
187
|
+
- Terms not in glossary
|
|
188
|
+
- Case sensitivity mismatch
|
|
189
|
+
- Term appears in different form
|
|
190
|
+
|
|
191
|
+
**Fixes:**
|
|
192
|
+
- Add missing terms to glossary
|
|
193
|
+
- Check `caseSensitive` setting
|
|
194
|
+
- Add term variations
|
|
195
|
+
|
|
196
|
+
### Low Format Score
|
|
197
|
+
|
|
198
|
+
**Causes:**
|
|
199
|
+
- Complex nested structures
|
|
200
|
+
- Code blocks with comments
|
|
201
|
+
- Tables with formatting
|
|
202
|
+
|
|
203
|
+
**Fixes:**
|
|
204
|
+
- Ensure chunking respects structure
|
|
205
|
+
- Review markdown source
|
|
206
|
+
- Consider pre-processing complex content
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# VitePress Integration
|
|
2
|
+
|
|
3
|
+
::: info Translations
|
|
4
|
+
All non-English documentation is automatically translated using Claude Sonnet 4.
|
|
5
|
+
:::
|
|
6
|
+
|
|
7
|
+
llm-translate provides helper functions to automatically generate VitePress i18n configuration based on your translated document structure.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
After translating your documentation with `llm-translate dir`, you can use the built-in VitePress helpers to auto-generate navigation and sidebar configuration for each locale.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @llm-translate/cli
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Basic Usage
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// docs/.vitepress/config.ts
|
|
23
|
+
import { defineConfig } from 'vitepress';
|
|
24
|
+
import { fileURLToPath } from 'node:url';
|
|
25
|
+
import { dirname, resolve } from 'node:path';
|
|
26
|
+
import { generateLocaleConfig } from '@llm-translate/cli';
|
|
27
|
+
|
|
28
|
+
// Get docs directory path relative to this config file
|
|
29
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
30
|
+
const docsDir = resolve(__dirname, '..');
|
|
31
|
+
|
|
32
|
+
const locales = generateLocaleConfig(docsDir, {
|
|
33
|
+
defaultLocale: 'en',
|
|
34
|
+
locales: ['ko', 'ja'],
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export default defineConfig({
|
|
38
|
+
title: 'My Project',
|
|
39
|
+
locales,
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
::: tip Why use absolute paths?
|
|
44
|
+
VitePress config runs from the project root, so relative paths like `'./docs'` may not resolve correctly. Using `import.meta.url` ensures the path is calculated relative to the config file location.
|
|
45
|
+
:::
|
|
46
|
+
|
|
47
|
+
This will:
|
|
48
|
+
1. Scan your `./docs` directory structure
|
|
49
|
+
2. Auto-detect sidebar directories (guide, api, cli, etc.)
|
|
50
|
+
3. Generate nav and sidebar for each locale
|
|
51
|
+
4. Apply default translations for UI elements
|
|
52
|
+
|
|
53
|
+
## Configuration Options
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
interface GenerateOptions {
|
|
57
|
+
/** Default locale code (e.g., 'en') - defaults to 'en' */
|
|
58
|
+
defaultLocale?: string;
|
|
59
|
+
|
|
60
|
+
/** List of locale codes to generate (auto-detected if omitted) */
|
|
61
|
+
locales?: string[];
|
|
62
|
+
|
|
63
|
+
/** Locale display labels */
|
|
64
|
+
labels?: Record<string, string>;
|
|
65
|
+
|
|
66
|
+
/** Locale lang codes for HTML */
|
|
67
|
+
langCodes?: Record<string, string>;
|
|
68
|
+
|
|
69
|
+
/** Locale descriptions */
|
|
70
|
+
descriptions?: Record<string, string>;
|
|
71
|
+
|
|
72
|
+
/** Directories to include in sidebar (auto-detected if omitted) */
|
|
73
|
+
sidebarDirs?: string[];
|
|
74
|
+
|
|
75
|
+
/** Use title from file's first heading (default: true) */
|
|
76
|
+
useTitleFromHeading?: boolean;
|
|
77
|
+
|
|
78
|
+
/** Custom locale translations */
|
|
79
|
+
translations?: Record<string, LocaleTranslations>;
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Examples
|
|
84
|
+
|
|
85
|
+
### Auto-detect Locales
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { generateLocaleConfig, detectLocales } from '@llm-translate/cli';
|
|
89
|
+
|
|
90
|
+
// Automatically detect locales from directory structure
|
|
91
|
+
// (looks for 2-letter directories like 'ko', 'ja', 'zh')
|
|
92
|
+
const locales = generateLocaleConfig('./docs');
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Custom Labels and Descriptions
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
const locales = generateLocaleConfig('./docs', {
|
|
99
|
+
defaultLocale: 'en',
|
|
100
|
+
locales: ['ko', 'ja'],
|
|
101
|
+
labels: {
|
|
102
|
+
en: 'English',
|
|
103
|
+
ko: '한국어',
|
|
104
|
+
ja: '日本語',
|
|
105
|
+
},
|
|
106
|
+
descriptions: {
|
|
107
|
+
en: 'Documentation for My Project',
|
|
108
|
+
ko: 'My Project 문서',
|
|
109
|
+
ja: 'My Projectのドキュメント',
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Specify Sidebar Directories
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const locales = generateLocaleConfig('./docs', {
|
|
118
|
+
sidebarDirs: ['guide', 'api', 'examples'],
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Custom Translations
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
const locales = generateLocaleConfig('./docs', {
|
|
126
|
+
translations: {
|
|
127
|
+
ko: {
|
|
128
|
+
editLinkText: 'GitHub에서 편집',
|
|
129
|
+
docFooter: { prev: '이전', next: '다음' },
|
|
130
|
+
outline: { label: '목차' },
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Sidebar-Only Generation
|
|
137
|
+
|
|
138
|
+
If you want to manually configure nav but auto-generate sidebar:
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { defineConfig } from 'vitepress';
|
|
142
|
+
import { generateSidebarConfig } from '@llm-translate/cli';
|
|
143
|
+
|
|
144
|
+
const sidebars = generateSidebarConfig('./docs', {
|
|
145
|
+
defaultLocale: 'en',
|
|
146
|
+
locales: ['ko'],
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
export default defineConfig({
|
|
150
|
+
locales: {
|
|
151
|
+
root: {
|
|
152
|
+
label: 'English',
|
|
153
|
+
themeConfig: {
|
|
154
|
+
nav: [/* custom nav */],
|
|
155
|
+
sidebar: sidebars.root,
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
ko: {
|
|
159
|
+
label: '한국어',
|
|
160
|
+
themeConfig: {
|
|
161
|
+
nav: [/* custom nav */],
|
|
162
|
+
sidebar: sidebars.ko,
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Single Locale Generation
|
|
170
|
+
|
|
171
|
+
Generate config for a single locale:
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
import { generateLocale } from '@llm-translate/cli';
|
|
175
|
+
|
|
176
|
+
const koConfig = generateLocale('./docs', 'ko', {
|
|
177
|
+
defaultLocale: 'en',
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Use in your config
|
|
181
|
+
export default defineConfig({
|
|
182
|
+
locales: {
|
|
183
|
+
ko: koConfig,
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Utility Functions
|
|
189
|
+
|
|
190
|
+
### detectLocales
|
|
191
|
+
|
|
192
|
+
Auto-detect available locales by scanning for locale directories:
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
import { detectLocales } from '@llm-translate/cli';
|
|
196
|
+
|
|
197
|
+
const locales = detectLocales('./docs', 'en');
|
|
198
|
+
// Returns: ['ko', 'ja', 'zh'] (based on directories found)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### detectSidebarDirs
|
|
202
|
+
|
|
203
|
+
Auto-detect directories that should appear in the sidebar:
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
import { detectSidebarDirs } from '@llm-translate/cli';
|
|
207
|
+
|
|
208
|
+
const dirs = detectSidebarDirs('./docs');
|
|
209
|
+
// Returns: ['guide', 'api', 'cli'] (excludes locale dirs, assets, etc.)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Title Extraction
|
|
213
|
+
|
|
214
|
+
The helper extracts page titles in this order:
|
|
215
|
+
1. Frontmatter `title` field
|
|
216
|
+
2. First `#` heading in the file
|
|
217
|
+
3. File name converted to Title Case
|
|
218
|
+
|
|
219
|
+
Example frontmatter:
|
|
220
|
+
```yaml
|
|
221
|
+
---
|
|
222
|
+
title: Getting Started
|
|
223
|
+
---
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Default Translations
|
|
227
|
+
|
|
228
|
+
Built-in translations are provided for common locales:
|
|
229
|
+
|
|
230
|
+
| Locale | Label | Doc Footer | Outline |
|
|
231
|
+
|--------|-------|------------|---------|
|
|
232
|
+
| ko | 한국어 | 이전/다음 페이지 | 목차 |
|
|
233
|
+
| ja | 日本語 | 前/次のページ | 目次 |
|
|
234
|
+
| zh | 中文 | 上/下一页 | 目录 |
|
|
235
|
+
|
|
236
|
+
## Workflow
|
|
237
|
+
|
|
238
|
+
Typical workflow for multilingual documentation:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
# 1. Write documentation in English
|
|
242
|
+
docs/
|
|
243
|
+
guide/
|
|
244
|
+
getting-started.md
|
|
245
|
+
configuration.md
|
|
246
|
+
api/
|
|
247
|
+
index.md
|
|
248
|
+
|
|
249
|
+
# 2. Translate to Korean
|
|
250
|
+
llm-translate dir ./docs ./docs/ko --target-lang ko --glossary glossary.json
|
|
251
|
+
|
|
252
|
+
# 3. Update VitePress config to use auto-generation
|
|
253
|
+
# (see examples above)
|
|
254
|
+
|
|
255
|
+
# 4. Build and preview
|
|
256
|
+
npm run docs:build
|
|
257
|
+
npm run docs:preview
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Caveats
|
|
261
|
+
|
|
262
|
+
- **Use absolute paths**: Always resolve the docs directory path using `import.meta.url` as shown in Basic Usage. Relative paths may not work correctly since VitePress runs from the project root.
|
|
263
|
+
- Locale directories must use 2-letter codes (e.g., `ko`, `ja`, `zh`)
|
|
264
|
+
- The helper assumes translated docs mirror the source structure
|
|
265
|
+
- Custom nav items (external links, dropdowns) need manual configuration
|