|
| 1 | +import logging |
1 | 2 | from unittest.mock import patch |
2 | 3 |
|
3 | 4 | from iris.domain.chat.chat_pipeline_execution_dto import ChatPipelineExecutionDTO |
|
17 | 18 | from iris.pipeline.abstract_agent_pipeline import AgentPipelineExecutionState |
18 | 19 | from iris.pipeline.chat.iris_chat_mode import IrisChatMode |
19 | 20 | from iris.tools.chat_tool_providers import ( |
| 21 | + provide_lecture_list, |
20 | 22 | provide_lecture_retrieval, |
21 | 23 | provide_switch_chat_context, |
22 | 24 | ) |
@@ -250,6 +252,46 @@ def test_retrieval_stays_on_the_active_lecture_without_a_switch(): |
250 | 252 | assert call["lecture_unit_id"] == 410 |
251 | 253 |
|
252 | 254 |
|
| 255 | +def test_lecture_list_reaches_the_agent_without_indexed_lecture_content(): |
| 256 | + """A course with lectures but no ingested content still allows a switch. |
| 257 | +
|
| 258 | + Indexed lecture content gates retrieval, not discovery. Gating the list as |
| 259 | + well would leave the agent without a target ID, and the prompt forbids |
| 260 | + guessing one, so the lecture switch would never happen in such a course. |
| 261 | + """ |
| 262 | + state = _lecture_chat_state(_dto(lectures=_lectures())) |
| 263 | + state.allow_lecture_tool = False |
| 264 | + |
| 265 | + lecture_list = provide_lecture_list(state) |
| 266 | + |
| 267 | + assert lecture_list is not None |
| 268 | + assert [entry["lecture_id"] for entry in lecture_list()] == [41, 42] |
| 269 | + |
| 270 | + switch = provide_switch_chat_context(state) |
| 271 | + assert "Successfully registered" in switch("LECTURE_CHAT", 42) |
| 272 | + assert state.pending_context_switch == SuggestedContextDTO( |
| 273 | + mode=IrisChatMode.LECTURE, entity_id=42 |
| 274 | + ) |
| 275 | + |
| 276 | + |
| 277 | +def test_lecture_retrieval_stays_gated_on_indexed_lecture_content(): |
| 278 | + """Retrieval reads the vector database, so it keeps the index precondition.""" |
| 279 | + state = _lecture_chat_state(_dto(lectures=_lectures())) |
| 280 | + state.allow_lecture_tool = False |
| 281 | + |
| 282 | + assert provide_lecture_retrieval(state) is None |
| 283 | + |
| 284 | + |
| 285 | +def test_lecture_list_is_absent_without_lectures(caplog): |
| 286 | + state = _lecture_chat_state(_dto(lectures=[])) |
| 287 | + |
| 288 | + with caplog.at_level(logging.WARNING): |
| 289 | + assert provide_lecture_list(state) is None |
| 290 | + |
| 291 | + # Indexed content without lectures in the DTO points at an outdated Artemis. |
| 292 | + assert "carries no lectures" in caplog.text |
| 293 | + |
| 294 | + |
253 | 295 | def test_switch_to_unknown_lecture_is_rejected(): |
254 | 296 | recorded = _RecordedSwitch() |
255 | 297 | tool = create_tool_switch_chat_context(_dto(lectures=_lectures()), recorded) |
|
0 commit comments