|
7 | 7 | from astrbot.core.provider.provider import EmbeddingProvider |
8 | 8 | from astrbot.dashboard.api.knowledge_bases import ( |
9 | 9 | list_knowledge_bases, |
| 10 | + retrieve_knowledge_base, |
10 | 11 | ) |
11 | 12 | from astrbot.dashboard.schemas import ( |
12 | 13 | KnowledgeBaseRequest, |
| 14 | + KnowledgeBaseRetrieveRequest, |
13 | 15 | ) |
14 | 16 | from astrbot.dashboard.services.knowledge_base_service import ( |
15 | 17 | KnowledgeBaseService, |
@@ -254,6 +256,88 @@ async def test_create_kb_raises_when_embedding_provider_is_missing(): |
254 | 256 | await service.create_kb({"kb_name": "Test KB"}) |
255 | 257 |
|
256 | 258 |
|
| 259 | +@pytest.mark.asyncio |
| 260 | +async def test_retrieve_resolves_kb_id_from_path_parameter(): |
| 261 | + kb = make_kb("kb-1", "Docs") |
| 262 | + kb_manager = MagicMock() |
| 263 | + kb_manager.get_kb = AsyncMock(return_value=SimpleNamespace(kb=kb)) |
| 264 | + kb_manager.retrieve = AsyncMock(return_value={"results": [{"chunk_id": "c-1"}]}) |
| 265 | + service = make_service(kb_manager) |
| 266 | + |
| 267 | + result = await service.retrieve({"kb_id": "kb-1", "query": "hello", "top_k": 3}) |
| 268 | + |
| 269 | + kb_manager.get_kb.assert_awaited_once_with("kb-1") |
| 270 | + kb_manager.retrieve.assert_awaited_once_with( |
| 271 | + query="hello", |
| 272 | + kb_names=["Docs"], |
| 273 | + top_m_final=3, |
| 274 | + ) |
| 275 | + assert result == { |
| 276 | + "results": [{"chunk_id": "c-1"}], |
| 277 | + "total": 1, |
| 278 | + "query": "hello", |
| 279 | + } |
| 280 | + |
| 281 | + |
| 282 | +@pytest.mark.asyncio |
| 283 | +async def test_retrieve_route_passes_kb_id_to_service(): |
| 284 | + kb = make_kb("kb-1", "Docs") |
| 285 | + kb_manager = MagicMock() |
| 286 | + kb_manager.get_kb = AsyncMock(return_value=SimpleNamespace(kb=kb)) |
| 287 | + kb_manager.retrieve = AsyncMock(return_value={"results": []}) |
| 288 | + service = make_service(kb_manager) |
| 289 | + |
| 290 | + response = await retrieve_knowledge_base( |
| 291 | + "kb-1", |
| 292 | + KnowledgeBaseRetrieveRequest(query="hello"), |
| 293 | + _auth=object(), |
| 294 | + service=service, |
| 295 | + ) |
| 296 | + |
| 297 | + assert response["status"] == "ok" |
| 298 | + kb_manager.retrieve.assert_awaited_once_with( |
| 299 | + query="hello", |
| 300 | + kb_names=["Docs"], |
| 301 | + top_m_final=5, |
| 302 | + ) |
| 303 | + |
| 304 | + |
| 305 | +@pytest.mark.asyncio |
| 306 | +async def test_retrieve_still_accepts_explicit_kb_names(): |
| 307 | + kb_manager = MagicMock() |
| 308 | + kb_manager.get_kb = AsyncMock() |
| 309 | + kb_manager.retrieve = AsyncMock(return_value={"results": []}) |
| 310 | + service = make_service(kb_manager) |
| 311 | + |
| 312 | + await service.retrieve({"query": "hello", "kb_names": ["Docs", "Notes"]}) |
| 313 | + |
| 314 | + kb_manager.get_kb.assert_not_awaited() |
| 315 | + kb_manager.retrieve.assert_awaited_once_with( |
| 316 | + query="hello", |
| 317 | + kb_names=["Docs", "Notes"], |
| 318 | + top_m_final=5, |
| 319 | + ) |
| 320 | + |
| 321 | + |
| 322 | +@pytest.mark.asyncio |
| 323 | +async def test_retrieve_raises_when_kb_id_is_unknown(): |
| 324 | + kb_manager = MagicMock() |
| 325 | + kb_manager.get_kb = AsyncMock(return_value=None) |
| 326 | + service = make_service(kb_manager) |
| 327 | + |
| 328 | + with pytest.raises(KnowledgeBaseServiceError, match="知识库不存在"): |
| 329 | + await service.retrieve({"kb_id": "missing", "query": "hello"}) |
| 330 | + |
| 331 | + |
| 332 | +@pytest.mark.asyncio |
| 333 | +async def test_retrieve_raises_when_no_knowledge_base_is_specified(): |
| 334 | + kb_manager = MagicMock() |
| 335 | + service = make_service(kb_manager) |
| 336 | + |
| 337 | + with pytest.raises(KnowledgeBaseServiceError, match="缺少参数 kb_names 或格式错误"): |
| 338 | + await service.retrieve({"query": "hello"}) |
| 339 | + |
| 340 | + |
257 | 341 | @pytest.mark.asyncio |
258 | 342 | async def test_create_kb_raises_when_embedding_provider_is_invalid(): |
259 | 343 | kb_manager = MagicMock() |
|
0 commit comments