kiln-ai 0.19.0__py3-none-any.whl → 0.21.0__py3-none-any.whl
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.
Potentially problematic release.
This version of kiln-ai might be problematic. Click here for more details.
- kiln_ai/adapters/__init__.py +8 -2
- kiln_ai/adapters/adapter_registry.py +43 -208
- kiln_ai/adapters/chat/chat_formatter.py +8 -12
- kiln_ai/adapters/chat/test_chat_formatter.py +6 -2
- kiln_ai/adapters/chunkers/__init__.py +13 -0
- kiln_ai/adapters/chunkers/base_chunker.py +42 -0
- kiln_ai/adapters/chunkers/chunker_registry.py +16 -0
- kiln_ai/adapters/chunkers/fixed_window_chunker.py +39 -0
- kiln_ai/adapters/chunkers/helpers.py +23 -0
- kiln_ai/adapters/chunkers/test_base_chunker.py +63 -0
- kiln_ai/adapters/chunkers/test_chunker_registry.py +28 -0
- kiln_ai/adapters/chunkers/test_fixed_window_chunker.py +346 -0
- kiln_ai/adapters/chunkers/test_helpers.py +75 -0
- kiln_ai/adapters/data_gen/test_data_gen_task.py +9 -3
- kiln_ai/adapters/docker_model_runner_tools.py +119 -0
- kiln_ai/adapters/embedding/__init__.py +0 -0
- kiln_ai/adapters/embedding/base_embedding_adapter.py +44 -0
- kiln_ai/adapters/embedding/embedding_registry.py +32 -0
- kiln_ai/adapters/embedding/litellm_embedding_adapter.py +199 -0
- kiln_ai/adapters/embedding/test_base_embedding_adapter.py +283 -0
- kiln_ai/adapters/embedding/test_embedding_registry.py +166 -0
- kiln_ai/adapters/embedding/test_litellm_embedding_adapter.py +1149 -0
- kiln_ai/adapters/eval/base_eval.py +2 -2
- kiln_ai/adapters/eval/eval_runner.py +9 -3
- kiln_ai/adapters/eval/g_eval.py +2 -2
- kiln_ai/adapters/eval/test_base_eval.py +2 -4
- kiln_ai/adapters/eval/test_g_eval.py +4 -5
- kiln_ai/adapters/extractors/__init__.py +18 -0
- kiln_ai/adapters/extractors/base_extractor.py +72 -0
- kiln_ai/adapters/extractors/encoding.py +20 -0
- kiln_ai/adapters/extractors/extractor_registry.py +44 -0
- kiln_ai/adapters/extractors/extractor_runner.py +112 -0
- kiln_ai/adapters/extractors/litellm_extractor.py +386 -0
- kiln_ai/adapters/extractors/test_base_extractor.py +244 -0
- kiln_ai/adapters/extractors/test_encoding.py +54 -0
- kiln_ai/adapters/extractors/test_extractor_registry.py +181 -0
- kiln_ai/adapters/extractors/test_extractor_runner.py +181 -0
- kiln_ai/adapters/extractors/test_litellm_extractor.py +1192 -0
- kiln_ai/adapters/fine_tune/__init__.py +1 -1
- kiln_ai/adapters/fine_tune/openai_finetune.py +14 -4
- kiln_ai/adapters/fine_tune/test_dataset_formatter.py +2 -2
- kiln_ai/adapters/fine_tune/test_fireworks_tinetune.py +2 -6
- kiln_ai/adapters/fine_tune/test_openai_finetune.py +108 -111
- kiln_ai/adapters/fine_tune/test_together_finetune.py +2 -6
- kiln_ai/adapters/ml_embedding_model_list.py +192 -0
- kiln_ai/adapters/ml_model_list.py +761 -37
- kiln_ai/adapters/model_adapters/base_adapter.py +51 -21
- kiln_ai/adapters/model_adapters/litellm_adapter.py +380 -138
- kiln_ai/adapters/model_adapters/test_base_adapter.py +193 -17
- kiln_ai/adapters/model_adapters/test_litellm_adapter.py +407 -2
- kiln_ai/adapters/model_adapters/test_litellm_adapter_tools.py +1103 -0
- kiln_ai/adapters/model_adapters/test_saving_adapter_results.py +5 -5
- kiln_ai/adapters/model_adapters/test_structured_output.py +113 -5
- kiln_ai/adapters/ollama_tools.py +69 -12
- kiln_ai/adapters/parsers/__init__.py +1 -1
- kiln_ai/adapters/provider_tools.py +205 -47
- kiln_ai/adapters/rag/deduplication.py +49 -0
- kiln_ai/adapters/rag/progress.py +252 -0
- kiln_ai/adapters/rag/rag_runners.py +844 -0
- kiln_ai/adapters/rag/test_deduplication.py +195 -0
- kiln_ai/adapters/rag/test_progress.py +785 -0
- kiln_ai/adapters/rag/test_rag_runners.py +2376 -0
- kiln_ai/adapters/remote_config.py +80 -8
- kiln_ai/adapters/repair/test_repair_task.py +12 -9
- kiln_ai/adapters/run_output.py +3 -0
- kiln_ai/adapters/test_adapter_registry.py +657 -85
- kiln_ai/adapters/test_docker_model_runner_tools.py +305 -0
- kiln_ai/adapters/test_ml_embedding_model_list.py +429 -0
- kiln_ai/adapters/test_ml_model_list.py +251 -1
- kiln_ai/adapters/test_ollama_tools.py +340 -1
- kiln_ai/adapters/test_prompt_adaptors.py +13 -6
- kiln_ai/adapters/test_prompt_builders.py +1 -1
- kiln_ai/adapters/test_provider_tools.py +254 -8
- kiln_ai/adapters/test_remote_config.py +651 -58
- kiln_ai/adapters/vector_store/__init__.py +1 -0
- kiln_ai/adapters/vector_store/base_vector_store_adapter.py +83 -0
- kiln_ai/adapters/vector_store/lancedb_adapter.py +389 -0
- kiln_ai/adapters/vector_store/test_base_vector_store.py +160 -0
- kiln_ai/adapters/vector_store/test_lancedb_adapter.py +1841 -0
- kiln_ai/adapters/vector_store/test_vector_store_registry.py +199 -0
- kiln_ai/adapters/vector_store/vector_store_registry.py +33 -0
- kiln_ai/datamodel/__init__.py +39 -34
- kiln_ai/datamodel/basemodel.py +170 -1
- kiln_ai/datamodel/chunk.py +158 -0
- kiln_ai/datamodel/datamodel_enums.py +28 -0
- kiln_ai/datamodel/embedding.py +64 -0
- kiln_ai/datamodel/eval.py +1 -1
- kiln_ai/datamodel/external_tool_server.py +298 -0
- kiln_ai/datamodel/extraction.py +303 -0
- kiln_ai/datamodel/json_schema.py +25 -10
- kiln_ai/datamodel/project.py +40 -1
- kiln_ai/datamodel/rag.py +79 -0
- kiln_ai/datamodel/registry.py +0 -15
- kiln_ai/datamodel/run_config.py +62 -0
- kiln_ai/datamodel/task.py +2 -77
- kiln_ai/datamodel/task_output.py +6 -1
- kiln_ai/datamodel/task_run.py +41 -0
- kiln_ai/datamodel/test_attachment.py +649 -0
- kiln_ai/datamodel/test_basemodel.py +4 -4
- kiln_ai/datamodel/test_chunk_models.py +317 -0
- kiln_ai/datamodel/test_dataset_split.py +1 -1
- kiln_ai/datamodel/test_embedding_models.py +448 -0
- kiln_ai/datamodel/test_eval_model.py +6 -6
- kiln_ai/datamodel/test_example_models.py +175 -0
- kiln_ai/datamodel/test_external_tool_server.py +691 -0
- kiln_ai/datamodel/test_extraction_chunk.py +206 -0
- kiln_ai/datamodel/test_extraction_model.py +470 -0
- kiln_ai/datamodel/test_rag.py +641 -0
- kiln_ai/datamodel/test_registry.py +8 -3
- kiln_ai/datamodel/test_task.py +15 -47
- kiln_ai/datamodel/test_tool_id.py +320 -0
- kiln_ai/datamodel/test_vector_store.py +320 -0
- kiln_ai/datamodel/tool_id.py +105 -0
- kiln_ai/datamodel/vector_store.py +141 -0
- kiln_ai/tools/__init__.py +8 -0
- kiln_ai/tools/base_tool.py +82 -0
- kiln_ai/tools/built_in_tools/__init__.py +13 -0
- kiln_ai/tools/built_in_tools/math_tools.py +124 -0
- kiln_ai/tools/built_in_tools/test_math_tools.py +204 -0
- kiln_ai/tools/mcp_server_tool.py +95 -0
- kiln_ai/tools/mcp_session_manager.py +246 -0
- kiln_ai/tools/rag_tools.py +157 -0
- kiln_ai/tools/test_base_tools.py +199 -0
- kiln_ai/tools/test_mcp_server_tool.py +457 -0
- kiln_ai/tools/test_mcp_session_manager.py +1585 -0
- kiln_ai/tools/test_rag_tools.py +848 -0
- kiln_ai/tools/test_tool_registry.py +562 -0
- kiln_ai/tools/tool_registry.py +85 -0
- kiln_ai/utils/__init__.py +3 -0
- kiln_ai/utils/async_job_runner.py +62 -17
- kiln_ai/utils/config.py +24 -2
- kiln_ai/utils/env.py +15 -0
- kiln_ai/utils/filesystem.py +14 -0
- kiln_ai/utils/filesystem_cache.py +60 -0
- kiln_ai/utils/litellm.py +94 -0
- kiln_ai/utils/lock.py +100 -0
- kiln_ai/utils/mime_type.py +38 -0
- kiln_ai/utils/open_ai_types.py +94 -0
- kiln_ai/utils/pdf_utils.py +38 -0
- kiln_ai/utils/project_utils.py +17 -0
- kiln_ai/utils/test_async_job_runner.py +151 -35
- kiln_ai/utils/test_config.py +138 -1
- kiln_ai/utils/test_env.py +142 -0
- kiln_ai/utils/test_filesystem_cache.py +316 -0
- kiln_ai/utils/test_litellm.py +206 -0
- kiln_ai/utils/test_lock.py +185 -0
- kiln_ai/utils/test_mime_type.py +66 -0
- kiln_ai/utils/test_open_ai_types.py +131 -0
- kiln_ai/utils/test_pdf_utils.py +73 -0
- kiln_ai/utils/test_uuid.py +111 -0
- kiln_ai/utils/test_validation.py +524 -0
- kiln_ai/utils/uuid.py +9 -0
- kiln_ai/utils/validation.py +90 -0
- {kiln_ai-0.19.0.dist-info → kiln_ai-0.21.0.dist-info}/METADATA +12 -5
- kiln_ai-0.21.0.dist-info/RECORD +211 -0
- kiln_ai-0.19.0.dist-info/RECORD +0 -115
- {kiln_ai-0.19.0.dist-info → kiln_ai-0.21.0.dist-info}/WHEEL +0 -0
- {kiln_ai-0.19.0.dist-info → kiln_ai-0.21.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
from unittest.mock import AsyncMock, Mock, patch
|
|
2
|
+
|
|
3
|
+
import httpx
|
|
4
|
+
import openai
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from kiln_ai.adapters.docker_model_runner_tools import (
|
|
8
|
+
DockerModelRunnerConnection,
|
|
9
|
+
docker_model_runner_base_url,
|
|
10
|
+
parse_docker_model_runner_models,
|
|
11
|
+
)
|
|
12
|
+
from kiln_ai.datamodel.datamodel_enums import ModelProviderName
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_docker_model_runner_base_url_default():
|
|
16
|
+
"""Test that the default base URL is returned when no config is set."""
|
|
17
|
+
with patch("kiln_ai.adapters.docker_model_runner_tools.Config") as mock_config:
|
|
18
|
+
mock_config.shared().docker_model_runner_base_url = None
|
|
19
|
+
result = docker_model_runner_base_url()
|
|
20
|
+
assert result == "http://localhost:12434/engines/llama.cpp"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_docker_model_runner_base_url_from_config():
|
|
24
|
+
"""Test that the configured base URL is returned when set."""
|
|
25
|
+
with patch("kiln_ai.adapters.docker_model_runner_tools.Config") as mock_config:
|
|
26
|
+
mock_config.shared().docker_model_runner_base_url = (
|
|
27
|
+
"http://custom:8080/engines/llama.cpp"
|
|
28
|
+
)
|
|
29
|
+
result = docker_model_runner_base_url()
|
|
30
|
+
assert result == "http://custom:8080/engines/llama.cpp"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_parse_docker_model_runner_models_with_supported_models():
|
|
34
|
+
"""Test parsing Docker Model Runner models response with supported models."""
|
|
35
|
+
# Create mock OpenAI Model objects
|
|
36
|
+
mock_models = [
|
|
37
|
+
Mock(id="ai/llama3.2:3B-Q4_K_M"),
|
|
38
|
+
Mock(id="ai/qwen3:8B-Q4_K_M"),
|
|
39
|
+
Mock(id="ai/gemma3n:4B-Q4_K_M"),
|
|
40
|
+
Mock(id="unsupported-model"),
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
with patch(
|
|
44
|
+
"kiln_ai.adapters.docker_model_runner_tools.built_in_models"
|
|
45
|
+
) as mock_built_in_models:
|
|
46
|
+
# Mock built-in models with Docker Model Runner providers
|
|
47
|
+
mock_model = Mock()
|
|
48
|
+
mock_provider = Mock()
|
|
49
|
+
mock_provider.name = ModelProviderName.docker_model_runner
|
|
50
|
+
mock_provider.model_id = "ai/llama3.2:3B-Q4_K_M"
|
|
51
|
+
mock_model.providers = [mock_provider]
|
|
52
|
+
mock_built_in_models.__iter__ = Mock(return_value=iter([mock_model]))
|
|
53
|
+
|
|
54
|
+
result = parse_docker_model_runner_models(mock_models) # type: ignore
|
|
55
|
+
|
|
56
|
+
assert result is not None
|
|
57
|
+
assert result.message == "Docker Model Runner connected"
|
|
58
|
+
assert "ai/llama3.2:3B-Q4_K_M" in result.supported_models
|
|
59
|
+
assert "unsupported-model" in result.untested_models
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_parse_docker_model_runner_models_no_models():
|
|
63
|
+
"""Test parsing Docker Model Runner models response with no models."""
|
|
64
|
+
mock_models = []
|
|
65
|
+
|
|
66
|
+
result = parse_docker_model_runner_models(mock_models)
|
|
67
|
+
|
|
68
|
+
assert result is not None
|
|
69
|
+
assert "no supported models are available" in result.message
|
|
70
|
+
assert len(result.supported_models) == 0
|
|
71
|
+
assert len(result.untested_models) == 0
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_docker_model_runner_connection_all_models():
|
|
75
|
+
"""Test that DockerModelRunnerConnection.all_models() returns both supported and untested models."""
|
|
76
|
+
connection = DockerModelRunnerConnection(
|
|
77
|
+
message="Test",
|
|
78
|
+
supported_models=["model1", "model2"],
|
|
79
|
+
untested_models=["model3", "model4"],
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
all_models = connection.all_models()
|
|
83
|
+
assert all_models == ["model1", "model2", "model3", "model4"]
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@pytest.mark.asyncio
|
|
87
|
+
async def test_docker_model_runner_online_success():
|
|
88
|
+
"""Test that docker_model_runner_online returns True when service is available."""
|
|
89
|
+
with patch(
|
|
90
|
+
"kiln_ai.adapters.docker_model_runner_tools.httpx.AsyncClient"
|
|
91
|
+
) as mock_client_class:
|
|
92
|
+
mock_client = Mock()
|
|
93
|
+
mock_response = Mock()
|
|
94
|
+
mock_response.raise_for_status.return_value = None
|
|
95
|
+
mock_client.get = AsyncMock(return_value=mock_response)
|
|
96
|
+
mock_client_class.return_value.__aenter__.return_value = mock_client
|
|
97
|
+
|
|
98
|
+
from kiln_ai.adapters.docker_model_runner_tools import (
|
|
99
|
+
docker_model_runner_online,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
result = await docker_model_runner_online()
|
|
103
|
+
|
|
104
|
+
assert result is True
|
|
105
|
+
mock_client.get.assert_called_once()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@pytest.mark.asyncio
|
|
109
|
+
async def test_docker_model_runner_online_failure():
|
|
110
|
+
"""Test that docker_model_runner_online returns False when service is unavailable."""
|
|
111
|
+
with patch(
|
|
112
|
+
"kiln_ai.adapters.docker_model_runner_tools.httpx.AsyncClient"
|
|
113
|
+
) as mock_client_class:
|
|
114
|
+
mock_client = Mock()
|
|
115
|
+
mock_client.get = AsyncMock(side_effect=httpx.RequestError("Connection error"))
|
|
116
|
+
mock_client_class.return_value.__aenter__.return_value = mock_client
|
|
117
|
+
|
|
118
|
+
from kiln_ai.adapters.docker_model_runner_tools import (
|
|
119
|
+
docker_model_runner_online,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
result = await docker_model_runner_online()
|
|
123
|
+
|
|
124
|
+
assert result is False
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@pytest.mark.asyncio
|
|
128
|
+
async def test_get_docker_model_runner_connection_success():
|
|
129
|
+
"""Test get_docker_model_runner_connection with successful connection."""
|
|
130
|
+
from kiln_ai.adapters.docker_model_runner_tools import (
|
|
131
|
+
get_docker_model_runner_connection,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
# Mock OpenAI client and models response
|
|
135
|
+
mock_model = Mock()
|
|
136
|
+
mock_model.id = "ai/llama3.2:3B-Q4_K_M"
|
|
137
|
+
mock_models_response = [mock_model]
|
|
138
|
+
|
|
139
|
+
with (
|
|
140
|
+
patch(
|
|
141
|
+
"kiln_ai.adapters.docker_model_runner_tools.openai.OpenAI"
|
|
142
|
+
) as mock_openai,
|
|
143
|
+
patch(
|
|
144
|
+
"kiln_ai.adapters.docker_model_runner_tools.parse_docker_model_runner_models"
|
|
145
|
+
) as mock_parse,
|
|
146
|
+
patch(
|
|
147
|
+
"kiln_ai.adapters.docker_model_runner_tools.docker_model_runner_base_url"
|
|
148
|
+
) as mock_base_url,
|
|
149
|
+
):
|
|
150
|
+
mock_base_url.return_value = "http://localhost:12434/engines"
|
|
151
|
+
mock_client = Mock()
|
|
152
|
+
mock_client.models.list.return_value = mock_models_response
|
|
153
|
+
mock_openai.return_value = mock_client
|
|
154
|
+
|
|
155
|
+
expected_connection = DockerModelRunnerConnection(
|
|
156
|
+
message="Connected",
|
|
157
|
+
supported_models=["ai/llama3.2:3B-Q4_K_M"],
|
|
158
|
+
untested_models=[],
|
|
159
|
+
)
|
|
160
|
+
mock_parse.return_value = expected_connection
|
|
161
|
+
|
|
162
|
+
result = await get_docker_model_runner_connection()
|
|
163
|
+
|
|
164
|
+
assert result == expected_connection
|
|
165
|
+
mock_openai.assert_called_once_with(
|
|
166
|
+
api_key="dummy",
|
|
167
|
+
base_url="http://localhost:12434/engines/v1",
|
|
168
|
+
max_retries=0,
|
|
169
|
+
)
|
|
170
|
+
mock_parse.assert_called_once_with(mock_models_response)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
@pytest.mark.asyncio
|
|
174
|
+
async def test_get_docker_model_runner_connection_with_custom_url():
|
|
175
|
+
"""Test get_docker_model_runner_connection with custom URL."""
|
|
176
|
+
from kiln_ai.adapters.docker_model_runner_tools import (
|
|
177
|
+
get_docker_model_runner_connection,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
# Mock OpenAI client and models response
|
|
181
|
+
mock_model = Mock()
|
|
182
|
+
mock_model.id = "ai/llama3.2:3B-Q4_K_M"
|
|
183
|
+
mock_models_response = [mock_model]
|
|
184
|
+
|
|
185
|
+
with (
|
|
186
|
+
patch(
|
|
187
|
+
"kiln_ai.adapters.docker_model_runner_tools.openai.OpenAI"
|
|
188
|
+
) as mock_openai,
|
|
189
|
+
patch(
|
|
190
|
+
"kiln_ai.adapters.docker_model_runner_tools.parse_docker_model_runner_models"
|
|
191
|
+
) as mock_parse,
|
|
192
|
+
):
|
|
193
|
+
mock_client = Mock()
|
|
194
|
+
mock_client.models.list.return_value = mock_models_response
|
|
195
|
+
mock_openai.return_value = mock_client
|
|
196
|
+
|
|
197
|
+
expected_connection = DockerModelRunnerConnection(
|
|
198
|
+
message="Connected",
|
|
199
|
+
supported_models=["ai/llama3.2:3B-Q4_K_M"],
|
|
200
|
+
untested_models=[],
|
|
201
|
+
)
|
|
202
|
+
mock_parse.return_value = expected_connection
|
|
203
|
+
|
|
204
|
+
custom_url = "http://custom:8080/engines/llama.cpp"
|
|
205
|
+
result = await get_docker_model_runner_connection(custom_url)
|
|
206
|
+
|
|
207
|
+
assert result == expected_connection
|
|
208
|
+
mock_openai.assert_called_once_with(
|
|
209
|
+
api_key="dummy",
|
|
210
|
+
base_url=f"{custom_url}/v1",
|
|
211
|
+
max_retries=0,
|
|
212
|
+
)
|
|
213
|
+
mock_parse.assert_called_once_with(mock_models_response)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@pytest.mark.asyncio
|
|
217
|
+
async def test_get_docker_model_runner_connection_api_error():
|
|
218
|
+
"""Test get_docker_model_runner_connection with API error."""
|
|
219
|
+
from kiln_ai.adapters.docker_model_runner_tools import (
|
|
220
|
+
get_docker_model_runner_connection,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
with patch(
|
|
224
|
+
"kiln_ai.adapters.docker_model_runner_tools.openai.OpenAI"
|
|
225
|
+
) as mock_openai:
|
|
226
|
+
mock_client = Mock()
|
|
227
|
+
mock_client.models.list.side_effect = openai.APIConnectionError(request=Mock())
|
|
228
|
+
mock_openai.return_value = mock_client
|
|
229
|
+
|
|
230
|
+
result = await get_docker_model_runner_connection()
|
|
231
|
+
|
|
232
|
+
assert result is None
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
@pytest.mark.asyncio
|
|
236
|
+
async def test_get_docker_model_runner_connection_connection_error():
|
|
237
|
+
"""Test get_docker_model_runner_connection with connection error."""
|
|
238
|
+
from kiln_ai.adapters.docker_model_runner_tools import (
|
|
239
|
+
get_docker_model_runner_connection,
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
with patch(
|
|
243
|
+
"kiln_ai.adapters.docker_model_runner_tools.openai.OpenAI"
|
|
244
|
+
) as mock_openai:
|
|
245
|
+
mock_client = Mock()
|
|
246
|
+
mock_client.models.list.side_effect = httpx.RequestError("Connection error")
|
|
247
|
+
mock_openai.return_value = mock_client
|
|
248
|
+
|
|
249
|
+
result = await get_docker_model_runner_connection()
|
|
250
|
+
|
|
251
|
+
assert result is None
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
@pytest.mark.asyncio
|
|
255
|
+
async def test_get_docker_model_runner_connection_http_error():
|
|
256
|
+
"""Test get_docker_model_runner_connection with HTTP error."""
|
|
257
|
+
from kiln_ai.adapters.docker_model_runner_tools import (
|
|
258
|
+
get_docker_model_runner_connection,
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
with patch(
|
|
262
|
+
"kiln_ai.adapters.docker_model_runner_tools.openai.OpenAI"
|
|
263
|
+
) as mock_openai:
|
|
264
|
+
mock_client = Mock()
|
|
265
|
+
mock_client.models.list.side_effect = httpx.RequestError("HTTP error")
|
|
266
|
+
mock_openai.return_value = mock_client
|
|
267
|
+
|
|
268
|
+
result = await get_docker_model_runner_connection()
|
|
269
|
+
|
|
270
|
+
assert result is None
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def test_docker_model_runner_model_installed_true():
|
|
274
|
+
"""Test docker_model_runner_model_installed returns True when model is installed."""
|
|
275
|
+
from kiln_ai.adapters.docker_model_runner_tools import (
|
|
276
|
+
docker_model_runner_model_installed,
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
connection = DockerModelRunnerConnection(
|
|
280
|
+
message="Test",
|
|
281
|
+
supported_models=["model1", "model2"],
|
|
282
|
+
untested_models=["model3", "model4"],
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
# Test model in supported_models
|
|
286
|
+
assert docker_model_runner_model_installed(connection, "model1") is True
|
|
287
|
+
|
|
288
|
+
# Test model in untested_models
|
|
289
|
+
assert docker_model_runner_model_installed(connection, "model3") is True
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def test_docker_model_runner_model_installed_false():
|
|
293
|
+
"""Test docker_model_runner_model_installed returns False when model is not installed."""
|
|
294
|
+
from kiln_ai.adapters.docker_model_runner_tools import (
|
|
295
|
+
docker_model_runner_model_installed,
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
connection = DockerModelRunnerConnection(
|
|
299
|
+
message="Test",
|
|
300
|
+
supported_models=["model1", "model2"],
|
|
301
|
+
untested_models=["model3", "model4"],
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
# Test model not in any list
|
|
305
|
+
assert docker_model_runner_model_installed(connection, "nonexistent_model") is False
|