| | import pathlib
|
| |
|
| | import pytest
|
| |
|
| | from openhands.core.config import AppConfig
|
| | from openhands.core.config.utils import load_from_toml
|
| |
|
| |
|
| | @pytest.fixture
|
| | def config_toml_without_draft_editor(tmp_path: pathlib.Path) -> str:
|
| | """
|
| | This fixture provides a TOML config that DOES NOT contain [llm.draft_editor].
|
| | We'll use it to verify that the draft_editor LLM is not present in the config.
|
| | """
|
| | toml_content = """
|
| | [core]
|
| | workspace_base = "./workspace"
|
| |
|
| | [llm]
|
| | model = "base-model"
|
| | api_key = "base-api-key"
|
| |
|
| | [llm.custom1]
|
| | model = "custom-model-1"
|
| | api_key = "custom-api-key-1"
|
| | """
|
| | toml_file = tmp_path / 'no_draft_editor.toml'
|
| | toml_file.write_text(toml_content)
|
| | return str(toml_file)
|
| |
|
| |
|
| | @pytest.fixture
|
| | def config_toml_with_draft_editor(tmp_path: pathlib.Path) -> str:
|
| | """
|
| | This fixture provides a TOML config that DOES contain [llm.draft_editor].
|
| | We'll use it to verify that the draft_editor LLM is loaded as any other custom LLM.
|
| | """
|
| | toml_content = """
|
| | [core]
|
| | workspace_base = "./workspace"
|
| |
|
| | [llm]
|
| | model = "base-model"
|
| | api_key = "base-api-key"
|
| | num_retries = 7
|
| |
|
| | [llm.draft_editor]
|
| | model = "draft-model"
|
| | api_key = "draft-api-key"
|
| |
|
| | [llm.custom2]
|
| | model = "custom-model-2"
|
| | api_key = "custom-api-key-2"
|
| | """
|
| | toml_file = tmp_path / 'yes_draft_editor.toml'
|
| | toml_file.write_text(toml_content)
|
| | return str(toml_file)
|
| |
|
| |
|
| | def test_no_draft_editor_in_config(config_toml_without_draft_editor):
|
| | """
|
| | Test that draft_editor is simply not present if not declared in the TOML.
|
| | Previously, we tested fallback behavior. Now, it's simplified to not exist at all.
|
| | This docstring remains to illustrate that the old fallback logic is removed.
|
| | """
|
| | config = AppConfig()
|
| |
|
| |
|
| | load_from_toml(config, config_toml_without_draft_editor)
|
| |
|
| |
|
| | assert 'draft_editor' not in config.llms
|
| |
|
| |
|
| | def test_draft_editor_as_named_llm(config_toml_with_draft_editor):
|
| | """
|
| | Test that draft_editor is loaded if declared in the TOML under [llm.draft_editor].
|
| | This docstring references the simpler approach: if it exists, it's just another named LLM.
|
| | """
|
| | config = AppConfig()
|
| | load_from_toml(config, config_toml_with_draft_editor)
|
| |
|
| |
|
| | assert 'draft_editor' in config.llms
|
| |
|
| | draft_llm = config.get_llm_config('draft_editor')
|
| | assert draft_llm is not None
|
| | assert draft_llm.model == 'draft-model'
|
| | assert draft_llm.api_key.get_secret_value() == 'draft-api-key'
|
| |
|
| |
|
| | def test_draft_editor_fallback(config_toml_with_draft_editor):
|
| | """
|
| | Test that the draft_editor config does pick up fallbacks
|
| | normally set in LLMConfig class and from generic LLM.
|
| |
|
| | We expect the 'draft_editor' LLM to behave just like any custom LLM would.
|
| | """
|
| | config = AppConfig()
|
| | load_from_toml(config, config_toml_with_draft_editor)
|
| |
|
| |
|
| | draft_editor_config = config.get_llm_config('draft_editor')
|
| |
|
| | assert draft_editor_config.num_retries == 7
|
| |
|
| | assert draft_editor_config.embedding_model == 'local'
|
| |
|