|
1 | 1 | """Tests for UiPathEvalRuntime metadata loading functionality. |
2 | 2 |
|
3 | 3 | This module tests: |
4 | | -- _ensure_metadata_loaded() - single runtime creation for both schema and agent model |
5 | 4 | - _get_agent_model() - cached agent model retrieval |
6 | 5 | - get_schema() - cached schema retrieval |
7 | | -- _find_agent_model_in_runtime() - recursive delegate traversal |
8 | | -- LLMAgentRuntimeProtocol - protocol implementation detection |
9 | 6 | """ |
10 | 7 |
|
11 | 8 | import uuid |
|
26 | 23 | from uipath.runtime.schema import UiPathRuntimeSchema |
27 | 24 |
|
28 | 25 | from uipath._cli._evals._runtime import ( |
29 | | - LLMAgentRuntimeProtocol, |
30 | 26 | UiPathEvalContext, |
31 | 27 | UiPathEvalRuntime, |
32 | 28 | ) |
33 | 29 | from uipath._cli.cli_eval import ( |
34 | | - _find_agent_model_in_runtime, |
35 | 30 | _get_agent_model, |
36 | 31 | ) |
37 | 32 | from uipath._events._event_bus import EventBus |
@@ -80,16 +75,6 @@ async def dispose(self) -> None: |
80 | 75 | pass |
81 | 76 |
|
82 | 77 |
|
83 | | -class AgentModelRuntime(BaseTestRuntime): |
84 | | - """Test runtime that implements LLMAgentRuntimeProtocol.""" |
85 | | - |
86 | | - def __init__(self, model: str | None = "gpt-4o-2024-11-20"): |
87 | | - self._model = model |
88 | | - |
89 | | - def get_agent_model(self) -> str | None: |
90 | | - return self._model |
91 | | - |
92 | | - |
93 | 78 | class WrapperRuntime(BaseTestRuntime): |
94 | 79 | """Test runtime that wraps another runtime (like UiPathResumableRuntime).""" |
95 | 80 |
|
@@ -136,123 +121,38 @@ async def dispose(self) -> None: |
136 | 121 | pass |
137 | 122 |
|
138 | 123 |
|
139 | | -class TestLLMAgentRuntimeProtocol: |
140 | | - """Tests for LLMAgentRuntimeProtocol detection.""" |
141 | | - |
142 | | - def test_protocol_detects_implementing_class(self): |
143 | | - """Test that protocol correctly identifies implementing classes.""" |
144 | | - runtime = AgentModelRuntime("gpt-4") |
145 | | - assert isinstance(runtime, LLMAgentRuntimeProtocol) |
146 | | - |
147 | | - def test_protocol_rejects_non_implementing_class(self): |
148 | | - """Test that protocol correctly rejects non-implementing classes.""" |
149 | | - runtime = BaseTestRuntime() |
150 | | - assert not isinstance(runtime, LLMAgentRuntimeProtocol) |
151 | | - |
152 | | - def test_protocol_rejects_wrapper_without_method(self): |
153 | | - """Test that wrapper without get_agent_model is not detected.""" |
154 | | - inner = AgentModelRuntime("gpt-4") |
155 | | - wrapper = WrapperRuntime(inner) |
156 | | - assert not isinstance(wrapper, LLMAgentRuntimeProtocol) |
157 | | - |
158 | | - |
159 | | -class TestFindAgentModelInRuntime: |
160 | | - """Tests for _find_agent_model_in_runtime recursive search.""" |
161 | | - |
162 | | - def test_finds_model_in_direct_runtime(self): |
163 | | - """Test finding agent model directly on runtime.""" |
164 | | - runtime = AgentModelRuntime("gpt-4o") |
165 | | - result = _find_agent_model_in_runtime(runtime) |
166 | | - assert result == "gpt-4o" |
167 | | - |
168 | | - def test_finds_model_in_wrapped_runtime(self): |
169 | | - """Test finding agent model through wrapper's delegate.""" |
170 | | - inner = AgentModelRuntime("claude-3") |
171 | | - wrapper = WrapperRuntime(inner) |
172 | | - result = _find_agent_model_in_runtime(wrapper) |
173 | | - assert result == "claude-3" |
174 | | - |
175 | | - def test_finds_model_in_deeply_wrapped_runtime(self): |
176 | | - """Test finding agent model through multiple wrapper layers.""" |
177 | | - inner = AgentModelRuntime("gpt-4-turbo") |
178 | | - wrapper1 = WrapperRuntime(inner) |
179 | | - wrapper2 = WrapperRuntime(wrapper1) |
180 | | - result = _find_agent_model_in_runtime(wrapper2) |
181 | | - assert result == "gpt-4-turbo" |
182 | | - |
183 | | - def test_finds_model_via_private_delegate(self): |
184 | | - """Test finding agent model through _delegate attribute.""" |
185 | | - inner = AgentModelRuntime("gemini-pro") |
186 | | - wrapper = PrivateDelegateRuntime(inner) |
187 | | - result = _find_agent_model_in_runtime(wrapper) |
188 | | - assert result == "gemini-pro" |
189 | | - |
190 | | - def test_returns_none_when_no_model(self): |
191 | | - """Test returns None when no runtime implements the protocol.""" |
192 | | - runtime = BaseTestRuntime() |
193 | | - result = _find_agent_model_in_runtime(runtime) |
194 | | - assert result is None |
195 | | - |
196 | | - def test_returns_none_for_none_model(self): |
197 | | - """Test returns None when runtime returns None for model.""" |
198 | | - runtime = AgentModelRuntime(None) |
199 | | - result = _find_agent_model_in_runtime(runtime) |
200 | | - assert result is None |
201 | | - |
202 | | - |
203 | 124 | class TestGetAgentModel: |
204 | 125 | """Tests for _get_agent_model function.""" |
205 | 126 |
|
206 | 127 | @pytest.mark.asyncio |
207 | 128 | async def test_returns_agent_model(self): |
208 | 129 | """Test that _get_agent_model returns the correct model from schema.""" |
209 | | - runtime = AgentModelRuntime("gpt-4o-2024-11-20") |
210 | 130 | schema = MockRuntimeSchema() |
211 | 131 | schema.metadata = {"settings": {"model": "gpt-4o-2024-11-20"}} |
212 | 132 |
|
213 | | - model = await _get_agent_model(runtime, schema) |
| 133 | + model = await _get_agent_model(schema) |
214 | 134 | assert model == "gpt-4o-2024-11-20" |
215 | 135 |
|
216 | 136 | @pytest.mark.asyncio |
217 | 137 | async def test_returns_none_when_no_model(self): |
218 | 138 | """Test that _get_agent_model returns None when runtime has no model.""" |
219 | | - runtime = BaseTestRuntime() |
220 | 139 | schema = MockRuntimeSchema() |
221 | 140 |
|
222 | | - model = await _get_agent_model(runtime, schema) |
| 141 | + model = await _get_agent_model(schema) |
223 | 142 | assert model is None |
224 | 143 |
|
225 | 144 | @pytest.mark.asyncio |
226 | 145 | async def test_returns_model_consistently(self): |
227 | 146 | """Test that _get_agent_model returns consistent results.""" |
228 | | - runtime = AgentModelRuntime("consistent-model") |
229 | 147 | schema = MockRuntimeSchema() |
230 | 148 | schema.metadata = {"settings": {"model": "consistent-model"}} |
231 | 149 |
|
232 | 150 | # Multiple calls should return the same value |
233 | | - model1 = await _get_agent_model(runtime, schema) |
234 | | - model2 = await _get_agent_model(runtime, schema) |
| 151 | + model1 = await _get_agent_model(schema) |
| 152 | + model2 = await _get_agent_model(schema) |
235 | 153 |
|
236 | 154 | assert model1 == model2 == "consistent-model" |
237 | 155 |
|
238 | | - @pytest.mark.asyncio |
239 | | - async def test_handles_exception_gracefully(self, monkeypatch): |
240 | | - """Test that _get_agent_model returns None when _find_agent_model_in_runtime raises exception.""" |
241 | | - runtime = BaseTestRuntime() |
242 | | - schema = MockRuntimeSchema() |
243 | | - |
244 | | - # Mock _find_agent_model_in_runtime to raise an exception |
245 | | - def mock_find_agent_model_error(r): |
246 | | - raise RuntimeError("Unexpected error during model lookup") |
247 | | - |
248 | | - monkeypatch.setattr( |
249 | | - "uipath._cli.cli_eval._find_agent_model_in_runtime", |
250 | | - mock_find_agent_model_error, |
251 | | - ) |
252 | | - |
253 | | - model = await _get_agent_model(runtime, schema) |
254 | | - assert model is None |
255 | | - |
256 | 156 |
|
257 | 157 | class TestGetSchema: |
258 | 158 | """Tests for get_schema method.""" |
@@ -314,25 +214,3 @@ async def create_runtime(): |
314 | 214 | # Should be the same object |
315 | 215 | assert schema1 is schema2 |
316 | 216 | assert schema1.file_path == schema2.file_path == "test.py" |
317 | | - |
318 | | - |
319 | | -class TestWrappedRuntimeModelResolution: |
320 | | - """Tests for model resolution through realistic wrapper chains.""" |
321 | | - |
322 | | - def test_resolves_model_through_resumable_telemetry_chain(self): |
323 | | - """Test model resolution through ResumableRuntime -> TelemetryWrapper -> BaseRuntime chain. |
324 | | -
|
325 | | - This mimics the real wrapper chain: |
326 | | - UiPathResumableRuntime -> TelemetryRuntimeWrapper -> AgentsLangGraphRuntime |
327 | | - """ |
328 | | - # Base runtime with model |
329 | | - base_runtime = AgentModelRuntime("gpt-4o-from-agent-json") |
330 | | - |
331 | | - # Simulate TelemetryRuntimeWrapper |
332 | | - telemetry_wrapper = WrapperRuntime(base_runtime) |
333 | | - |
334 | | - # Simulate UiPathResumableRuntime |
335 | | - resumable_runtime = WrapperRuntime(telemetry_wrapper) |
336 | | - |
337 | | - model = _find_agent_model_in_runtime(resumable_runtime) |
338 | | - assert model == "gpt-4o-from-agent-json" |
0 commit comments