fix(agent): complete knowledge model dependencies

This commit is contained in:
林玮 (Jade Lin) committed 2026-09-09 15:53:17 +08:00
1 parent da6e012d71
commit a29f58aa8f
2 files changed
+139 -9

No files matched your search

+40 -8
View File
@@ -1,9 +1,46 @@
"""Plugin dependency discovery shared by portable Agent formats."""
from models.agent_config_entities import AgentSoulConfig
from models.agent_config_entities import (
AgentKnowledgeMetadataFilteringConfig,
AgentKnowledgeRetrievalConfig,
AgentSoulConfig,
)
from services.plugin.dependencies_analysis import DependenciesAnalysisService
def _extract_knowledge_retrieval_dependencies(retrieval: AgentKnowledgeRetrievalConfig) -> list[str]:
if retrieval.mode == "single":
if retrieval.model is None:
return []
return [DependenciesAnalysisService.analyze_model_provider_dependency(retrieval.model.provider)]
if not retrieval.reranking_enable:
return []
if retrieval.reranking_mode == "reranking_model":
if retrieval.reranking_model is None:
return []
return [DependenciesAnalysisService.analyze_model_provider_dependency(retrieval.reranking_model.provider)]
if retrieval.reranking_mode == "weighted_score" and retrieval.weights is not None:
vector_setting = retrieval.weights.vector_setting
embedding_provider = vector_setting.get("embedding_provider_name") if vector_setting is not None else None
if embedding_provider:
return [DependenciesAnalysisService.analyze_model_provider_dependency(embedding_provider)]
return []
def _extract_metadata_filtering_dependencies(
metadata_filtering: AgentKnowledgeMetadataFilteringConfig,
) -> list[str]:
if metadata_filtering.mode != "automatic" or metadata_filtering.metadata_model_config is None:
return []
return [
DependenciesAnalysisService.analyze_model_provider_dependency(metadata_filtering.metadata_model_config.provider)
]
def extract_agent_soul_dependencies(soul: AgentSoulConfig) -> list[str]:
dependencies: list[str] = []
if soul.model is not None:
@@ -20,13 +57,8 @@ def extract_agent_soul_dependencies(soul: AgentSoulConfig) -> list[str]:
if provider_id:
dependencies.append(DependenciesAnalysisService.analyze_tool_dependency(provider_id))
for knowledge_set in soul.knowledge.sets:
retrieval = knowledge_set.retrieval
if retrieval.model is not None:
dependencies.append(DependenciesAnalysisService.analyze_model_provider_dependency(retrieval.model.provider))
if retrieval.reranking_model is not None:
dependencies.append(
DependenciesAnalysisService.analyze_model_provider_dependency(retrieval.reranking_model.provider)
)
dependencies.extend(_extract_knowledge_retrieval_dependencies(knowledge_set.retrieval))
dependencies.extend(_extract_metadata_filtering_dependencies(knowledge_set.metadata_filtering))
return dependencies
@@ -573,9 +573,49 @@ def test_extract_package_dependencies_covers_models_features_tools_and_knowledge
"retrieval": {
"mode": "single",
"model": {"provider": "provider/retrieval", "name": "embed", "mode": "embedding"},
},
"metadata_filtering": {
"mode": "automatic",
"model_config": {
"provider": "provider/metadata",
"name": "metadata-model",
"mode": "chat",
},
},
},
{
"id": "set-2",
"name": "Reranked Set",
"datasets": [{"id": "dataset-2", "name": "Reranked Docs"}],
"query": {"mode": "user_query", "value": "query"},
"retrieval": {
"mode": "multiple",
"top_k": 5,
"reranking_enable": True,
"reranking_mode": "reranking_model",
"reranking_model": {"provider": "provider/rerank", "model": "rerank"},
},
}
},
{
"id": "set-3",
"name": "Weighted Set",
"datasets": [{"id": "dataset-3", "name": "Weighted Docs"}],
"query": {"mode": "user_query", "value": "query"},
"retrieval": {
"mode": "multiple",
"top_k": 5,
"reranking_enable": True,
"reranking_mode": "weighted_score",
"weights": {
"vector_setting": {
"embedding_provider_name": "provider/embedding",
"embedding_model_name": "embedding-model",
"vector_weight": 0.7,
},
"keyword_setting": {"keyword_weight": 0.3},
},
},
},
]
},
}
@@ -591,10 +631,68 @@ def test_extract_package_dependencies_covers_models_features_tools_and_knowledge
"tool:provider/tool",
"tool:plugin-id/fallback-provider",
"model:provider/retrieval",
"model:provider/metadata",
"model:provider/rerank",
"model:provider/embedding",
]
def test_extract_package_dependencies_ignores_inactive_knowledge_models(
monkeypatch: pytest.MonkeyPatch, unbound_session: Session
) -> None:
model_dependency = Mock(side_effect=lambda provider: f"model:{provider}")
monkeypatch.setattr(
"services.agent.dependency_service.DependenciesAnalysisService.analyze_model_provider_dependency",
model_dependency,
)
soul = AgentSoulConfig.model_validate(
{
"knowledge": {
"sets": [
{
"id": "set-1",
"name": "Set",
"datasets": [{"id": "dataset-1", "name": "Docs"}],
"query": {"mode": "user_query", "value": "query"},
"retrieval": {
"mode": "multiple",
"top_k": 5,
"reranking_enable": False,
"reranking_mode": "weighted_score",
"reranking_model": {"provider": "provider/inactive-rerank", "model": "rerank"},
"weights": {
"vector_setting": {
"embedding_provider_name": "provider/inactive-embedding",
}
},
"model": {
"provider": "provider/inactive-retrieval",
"name": "retrieval-model",
"mode": "chat",
},
},
"metadata_filtering": {
"mode": "disabled",
"model_config": {
"provider": "provider/inactive-metadata",
"name": "metadata-model",
"mode": "chat",
},
},
}
]
}
}
)
dependencies = AgentDslService(unbound_session).extract_package_dependencies(
{"agent_1": make_portable_agent_package(_agent(), soul)}
)
assert dependencies == []
model_dependency.assert_not_called()
def test_create_imported_inline_agent_uses_import_provenance(unbound_session: Session) -> None:
service = AgentDslService(unbound_session)
soul = AgentSoulConfig(config_note="inline")