(
*,
language: Annotated[str, typer.Option(envvar="LANGUAGE")],
en_path: Annotated[Path, typer.Option(envvar="EN_PATH")],
)
| 105 | |
| 106 | @app.command() |
| 107 | def translate_page( |
| 108 | *, |
| 109 | language: Annotated[str, typer.Option(envvar="LANGUAGE")], |
| 110 | en_path: Annotated[Path, typer.Option(envvar="EN_PATH")], |
| 111 | ) -> None: |
| 112 | assert language != "en", ( |
| 113 | "`en` is the source language, choose another language as translation target" |
| 114 | ) |
| 115 | langs = get_langs() |
| 116 | language_name = langs[language] |
| 117 | lang_path = Path(f"docs/{language}") |
| 118 | lang_path.mkdir(exist_ok=True) |
| 119 | lang_prompt_path = lang_path / "llm-prompt.md" |
| 120 | assert lang_prompt_path.exists(), f"Prompt file not found: {lang_prompt_path}" |
| 121 | lang_prompt_content = lang_prompt_path.read_text(encoding="utf-8") |
| 122 | |
| 123 | en_docs_path = Path("docs/en/docs") |
| 124 | assert str(en_path).startswith(str(en_docs_path)), ( |
| 125 | f"Path must be inside {en_docs_path}" |
| 126 | ) |
| 127 | out_path = generate_lang_path(lang=language, path=en_path) |
| 128 | out_path.parent.mkdir(parents=True, exist_ok=True) |
| 129 | original_content = en_path.read_text(encoding="utf-8") |
| 130 | old_translation: str | None = None |
| 131 | if out_path.exists(): |
| 132 | print(f"Found existing translation: {out_path}") |
| 133 | old_translation = out_path.read_text(encoding="utf-8") |
| 134 | print(f"Translating {en_path} to {language} ({language_name})") |
| 135 | agent = Agent("openai-chat:gpt-5.5") |
| 136 | |
| 137 | MAX_ATTEMPTS = 3 |
| 138 | additional_instructions = "" |
| 139 | for attempt_no in range(1, MAX_ATTEMPTS + 1): |
| 140 | print(f"Running agent for {out_path} (attempt {attempt_no}/{MAX_ATTEMPTS})") |
| 141 | prompt = get_prompt( |
| 142 | lang_prompt_content=lang_prompt_content, |
| 143 | old_translation=old_translation, |
| 144 | language=language, |
| 145 | language_name=language_name, |
| 146 | original_content=original_content, |
| 147 | additional_instructions=additional_instructions, |
| 148 | ) |
| 149 | result = agent.run_sync( |
| 150 | prompt.replace( |
| 151 | "[placeholder_for_additional_instructions]", additional_instructions |
| 152 | ) |
| 153 | ) |
| 154 | out_content = f"{result.output.strip()}\n" |
| 155 | try: |
| 156 | check_translation( |
| 157 | doc_lines=out_content.splitlines(), |
| 158 | en_doc_lines=original_content.splitlines(), |
| 159 | lang_code=language, |
| 160 | auto_fix=False, |
| 161 | path=str(out_path), |
| 162 | ) |
| 163 | break # Exit loop if no errors |
| 164 | except ValueError as e: |
no test coverage detected