--- name: add-language-support description: > Guide for adding a new programming language to the multi-language system. Use when extending the aiservice to support a new language (e.g., Rust, Go). Covers directory creation, handler implementation, registry registration, protocol compliance, prompt templates, router updates, and tests. --- # Add Language Support Use this workflow when adding a new programming language to the codeflash-internal optimization system. Follow steps in order — each builds on the previous. ## Step 1: Create Language Directory Create the directory structure under `core/languages/`. 1. Create `core/languages//` with `__init__.py` 2. Create subdirectories for each feature: ``` core/languages// ├── __init__.py # Handler class + @register_handler decorator ├── optimizer/ # Optimization handler │ ├── __init__.py │ └── optimizer.py └── testgen/ # Test generation handler (if supported) ├── __init__.py └── testgen.py ``` 3. Follow existing patterns from `core/languages/python/` or `core/languages/js_ts/` **Checkpoint**: The directory structure should match existing language modules. Verify with `ls core/languages/`. ## Step 2: Implement Handler Class Create the handler class in `core/languages//__init__.py`. 1. Read `core/protocols/base.py` for the `LanguageHandler` protocol 2. Implement the handler: ```python from core.registry import register_handler @register_handler("") class Handler: language = "" supports_testgen = False # Set True if implementing testgen supports_optimizer = True # Set True if implementing optimizer supports_code_repair = False supports_jit_rewrite = False supports_optimization_review = False supports_explanations = False ``` 3. Set `supports_*` flags for each feature you implement 4. The `@register_handler` decorator registers the class with the global registry **Checkpoint**: After this step, `registry.list_available()` should include your language ID. ## Step 3: Register the Module Ensure the handler module is imported so the decorator fires. 1. Read `core/languages/__init__.py` — check how existing languages are imported 2. Add your language import so `@register_handler` fires on startup 3. Import should be at module level or via lazy import pattern **Checkpoint**: Run `python -c "from core.languages import "` to verify no import errors. ## Step 4: Implement Protocol Methods Implement the protocol methods for each supported feature. 1. Read `core/protocols/optimizer.py` — `OptimizerProtocol` requires `optimizer_optimize(request, data)` 2. Read `core/protocols/testgen.py` — `TestGenProtocol` requires `testgen_generate(request, data)` 3. Read `core/protocols/code_repair.py` — `CodeRepairProtocol` requires `code_repair_repair(user_id, optimization_id, ctx)` 4. Follow the pattern from Python/JS handlers: ```python async def optimizer_optimize(self, request, data): # 1. Build context from data.source_code # 2. Call call_llm() with language-specific prompts # 3. Parse response # 4. Return (status_code, response_schema) ``` **Checkpoint**: Each method must be `async def` and return the expected response type. ## Step 5: Create Prompt Templates Create language-specific prompt templates. 1. Create `.md` files alongside the handler modules (e.g., `optimizer/system_prompt.md`) 2. Use Jinja2 templating for dynamic content 3. Prompts should include language-specific context (version, conventions, stdlib) 4. Follow the pattern from `core/languages/python/optimizer/context_utils/` **Checkpoint**: Prompts should produce valid, non-empty system and user messages. ## Step 6: Update Routers Add language dispatch to the shared routers. 1. Edit `core/shared/optimizer_router.py` — add a branch for your language: ```python if data.language == "": from core.languages..optimizer import optimize_ # noqa: PLC0415 return await optimize_(request, data) ``` 2. Edit `core/shared/testgen_router.py` — add the same pattern if testgen is supported 3. Use lazy imports (inside the function body) to avoid circular dependencies **Checkpoint**: Both routers should dispatch correctly for the new language. ## Step 7: Add Tests Write tests for the new language handler. 1. Create `tests//` directory mirroring the source structure 2. Test handler registration: verify `registry.get_handler("")` returns the correct class 3. Test feature dispatch: verify `get_handler_for_feature("", "optimizer")` works 4. Test optimization flow end-to-end (mock LLM calls) 5. Use `@pytest.mark.asyncio` for async tests 6. Run: `uv run pytest tests// -v` **Checkpoint**: All tests must pass. Run `uv run prek run --all-files` for formatting/lint. ## Key Files Reference | File | What to modify | |------|---------------| | `core/languages//` | New handler directory | | `core/registry.py` | No changes needed (decorator handles it) | | `core/dispatcher.py` | No changes needed (dynamic lookup) | | `core/protocols/` | Reference for protocol methods | | `core/shared/optimizer_router.py` | Add language dispatch branch | | `core/shared/testgen_router.py` | Add language dispatch branch (if testgen) | | `core/languages/__init__.py` | Add import for decorator registration |