mirror of
https://github.com/langgenius/dify.git
synced 2026-09-05 00:31:19 +08:00
fix(knowledge_fs): accept direct unpublished profile activation responses and validate settings
This commit is contained in:
parent
fbc7c85af1
commit
013ddcf034
@ -48,6 +48,7 @@ from services.knowledge_fs.product_dto import (
|
||||
KnowledgeFSDocumentRevisionListResponse,
|
||||
KnowledgeFSDocumentUploadAcceptedResponse,
|
||||
KnowledgeFSDurableDeletionAcceptedResponse,
|
||||
KnowledgeFSEmbeddingSettingsResponse,
|
||||
KnowledgeFSFindQuery,
|
||||
KnowledgeFSGoldenQuestionBulkImportPayload,
|
||||
KnowledgeFSGoldenQuestionBulkImportRemotePayload,
|
||||
@ -93,6 +94,7 @@ from services.knowledge_fs.product_dto import (
|
||||
KnowledgeFSResearchTaskPlanResponse,
|
||||
KnowledgeFSResearchTaskResponse,
|
||||
KnowledgeFSRetrievalProfileUpdatePayload,
|
||||
KnowledgeFSRetrievalSettingsResponse,
|
||||
KnowledgeFSSettingsPayload,
|
||||
KnowledgeFSSettingsResponse,
|
||||
KnowledgeFSSettingsUpdateResponse,
|
||||
@ -561,10 +563,21 @@ class KnowledgeFSDataFacade:
|
||||
)
|
||||
else:
|
||||
raise KnowledgeFSProductRequestRejectedError(status_code=422)
|
||||
return KnowledgeFSSettingsUpdateResponse(
|
||||
migration=KnowledgeFSProfileMigrationResponse.model_validate(migration_raw),
|
||||
settings=current,
|
||||
if isinstance(migration_raw, dict) and ("runState" in migration_raw or "run_state" in migration_raw):
|
||||
return KnowledgeFSSettingsUpdateResponse(
|
||||
migration=KnowledgeFSProfileMigrationResponse.model_validate(migration_raw),
|
||||
settings=current,
|
||||
)
|
||||
if payload.embedding is not None:
|
||||
KnowledgeFSEmbeddingSettingsResponse.model_validate(migration_raw)
|
||||
else:
|
||||
KnowledgeFSRetrievalSettingsResponse.model_validate(migration_raw)
|
||||
refreshed = self.get_settings(
|
||||
tenant_id=tenant_id,
|
||||
account_id=account_id,
|
||||
control_space_id=control_space_id,
|
||||
)
|
||||
return KnowledgeFSSettingsUpdateResponse(settings=refreshed)
|
||||
|
||||
raw = self._interactive(
|
||||
tenant_id=tenant_id,
|
||||
|
||||
@ -1287,6 +1287,77 @@ def test_active_settings_use_durable_profile_migration_routes() -> None:
|
||||
}
|
||||
|
||||
|
||||
def test_active_settings_accept_direct_unpublished_profile_activation() -> None:
|
||||
class DirectActivationRemote(ActiveSettingsRemote):
|
||||
def execute_json(self, request: KnowledgeFSRemoteJSONRequest):
|
||||
if request.operation_id == "updateRetrievalProfile":
|
||||
self.requests.append(request)
|
||||
return {
|
||||
"defaultMode": "fast",
|
||||
"reasoningModel": {
|
||||
"model": "reason-v1",
|
||||
"pluginId": "plugin-1",
|
||||
"provider": "provider-1",
|
||||
},
|
||||
"rerank": {
|
||||
"enabled": True,
|
||||
"model": {
|
||||
"model": "rerank-v1",
|
||||
"pluginId": "plugin-1",
|
||||
"provider": "provider-1",
|
||||
},
|
||||
},
|
||||
"revision": 5,
|
||||
"scoreThreshold": {"enabled": True, "stage": "rerank", "value": 0.51},
|
||||
"topK": 3,
|
||||
}
|
||||
return super().execute_json(request)
|
||||
|
||||
remote = DirectActivationRemote()
|
||||
facade = KnowledgeFSDataFacade(
|
||||
broker=RecordingBroker(),
|
||||
remote=remote,
|
||||
) # type: ignore[arg-type]
|
||||
|
||||
result = facade.update_settings(
|
||||
tenant_id="tenant-1",
|
||||
account_id="account-1",
|
||||
control_space_id="control-1",
|
||||
payload=KnowledgeFSSettingsPayload(
|
||||
expected_revision=9,
|
||||
retrieval=KnowledgeFSProductRetrievalProfile(
|
||||
default_mode="fast",
|
||||
reasoning_model=KnowledgeFSProfileModelSelection(
|
||||
model="reason-v1",
|
||||
plugin_id="plugin-1",
|
||||
provider="provider-1",
|
||||
),
|
||||
rerank=KnowledgeFSProductRerankProfile(
|
||||
enabled=True,
|
||||
model=KnowledgeFSProfileModelSelection(
|
||||
model="rerank-v1",
|
||||
plugin_id="plugin-1",
|
||||
provider="provider-1",
|
||||
),
|
||||
),
|
||||
score_threshold=KnowledgeFSProductScoreThreshold(
|
||||
enabled=True,
|
||||
stage="rerank",
|
||||
value=0.51,
|
||||
),
|
||||
top_k=3,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
assert result.migration is None
|
||||
assert [request.operation_id for request in remote.requests] == [
|
||||
"getSettings",
|
||||
"updateRetrievalProfile",
|
||||
"getSettings",
|
||||
]
|
||||
|
||||
|
||||
def test_setup_required_settings_without_active_profile_use_product_settings_route() -> None:
|
||||
remote = ActiveSettingsRemote(
|
||||
active_profile_available=False,
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
# Accept direct unpublished profile activation responses
|
||||
|
||||
## Summary
|
||||
|
||||
- Accept either an asynchronous profile migration response or a direct profile response from KnowledgeFS profile update operations.
|
||||
- Validate direct embedding and retrieval profile responses, then reload settings so the console receives the committed revision.
|
||||
- Add regression coverage for direct unpublished retrieval profile activation.
|
||||
|
||||
## Verification
|
||||
|
||||
- `uv run --project api pytest api/tests/unit_tests/services/test_knowledge_fs_data_facade.py` (90 passed)
|
||||
- `uv run --project api ruff check api/services/knowledge_fs/data_facade.py api/tests/unit_tests/services/test_knowledge_fs_data_facade.py`
|
||||
- `uv run --project api ruff format --check api/services/knowledge_fs/data_facade.py api/tests/unit_tests/services/test_knowledge_fs_data_facade.py`
|
||||
|
||||
## Deployment note
|
||||
|
||||
Profile activation can synchronously perform model capability preflight. Deployments using the 10-second default `KNOWLEDGE_FS_TIMEOUT_SECONDS` may time out before KnowledgeFS returns; increase the API-side value within its supported 60-second maximum and refresh settings before retrying an ambiguously timed-out mutation.
|
||||
Loading…
Reference in New Issue
Block a user