feat(knowledge-fs): fix CI.

This commit is contained in:
FFXN 2026-09-04 16:55:47 +08:00
parent d4d51e0e20
commit 40e30d9fa6
5 changed files with 127 additions and 15 deletions

View File

@ -146,6 +146,7 @@ from services.knowledge_fs.product_dto import (
KnowledgeFSIdempotencyHeader,
KnowledgeFSInitialSourcePreviewJobCreateResponse,
KnowledgeFSInitialSourcePreviewJobResponse,
KnowledgeFSInitialSourcePreviewPageResponse,
KnowledgeFSInitialSourcePreviewPayload,
KnowledgeFSInitialSourcePreviewResponse,
KnowledgeFSInitialWebsiteSourcePreviewPayload,
@ -893,7 +894,7 @@ class KnowledgeFSInitialSourcePreviewJobsApi(Resource):
)
return dump_response(
KnowledgeFSInitialSourcePreviewJobCreateResponse,
KnowledgeFSInitialSourcePreviewJobCreateResponse(jobId=result.job_id),
KnowledgeFSInitialSourcePreviewJobCreateResponse(job_id=result.job_id),
), HTTPStatus.ACCEPTED
@ -914,20 +915,27 @@ class KnowledgeFSInitialSourcePreviewJobApi(Resource):
remote = _console_services().facade.get_namespace_source_preview(
tenant_id=tenant_id, account_id=account.id, job_id=job_id
)
status: Literal["pending", "running", "completed", "failed", "canceled"]
if remote.status == "queued":
status = "pending"
elif remote.status == "consumed":
status = "completed"
else:
status = remote.status
result = KnowledgeFSInitialSourcePreviewJobResponse(
jobId=remote.job_id,
status={"queued": "pending", "consumed": "completed"}.get(remote.status, remote.status),
job_id=remote.job_id,
status=status,
result=(
KnowledgeFSInitialSourcePreviewResponse(
kind="website_crawl",
configurationFingerprint=remote.configuration_fingerprint,
configuration_fingerprint=remote.configuration_fingerprint,
pages=[
{
"pageId": page.page_id,
"sourceUrl": page.source_url,
"title": page.title,
"description": page.description,
}
KnowledgeFSInitialSourcePreviewPageResponse(
page_id=page.page_id,
source_url=page.source_url,
title=page.title,
description=page.description,
)
for page in remote.pages
],
)
@ -954,10 +962,14 @@ class KnowledgeFSInitialSourcePreviewJobApi(Resource):
remote = _console_services().facade.cancel_namespace_source_preview(
tenant_id=tenant_id, account_id=account.id, job_id=job_id
)
result = KnowledgeFSInitialSourcePreviewJobResponse(
jobId=remote.job_id,
status={"queued": "pending", "consumed": "completed"}.get(remote.status, remote.status),
)
status: Literal["pending", "running", "completed", "failed", "canceled"]
if remote.status == "queued":
status = "pending"
elif remote.status == "consumed":
status = "completed"
else:
status = remote.status
result = KnowledgeFSInitialSourcePreviewJobResponse(job_id=remote.job_id, status=status)
except KnowledgeFSProductResourceNotFoundError as exc:
raise NotFound() from exc
return dump_response(KnowledgeFSInitialSourcePreviewJobResponse, result)

View File

@ -2559,7 +2559,11 @@ class KnowledgeFSDataFacade:
capability_token=issued.token,
trace_id=issued.trace_id,
payload=payload,
query=(),
bind_space_in_body=False,
resource_id=None,
path_parameters=path_parameters,
headers=(),
)
def _interactive_child(

View File

@ -286,6 +286,7 @@ def _start_workflow(
not selection.page_id for selection in payload.selection
):
raise ValueError("Website namespace preview selection requires page IDs and fingerprint")
page_ids = [selection.page_id for selection in payload.selection if selection.page_id is not None]
imported = facade.consume_namespace_source_preview(
tenant_id=tenant_id,
account_id=account_id,
@ -293,7 +294,7 @@ def _start_workflow(
source_id=source_id,
payload=KnowledgeFSNamespacePreviewConsumePayload(
previewJobId=payload.preview_job_id,
pageIds=[selection.page_id for selection in payload.selection],
pageIds=page_ids,
configurationFingerprint=payload.preview_configuration_fingerprint,
),
idempotency_key=f"{request_id}:crawl-import",

View File

@ -33,6 +33,8 @@ from services.knowledge_fs.product_dto import (
KnowledgeFSDocumentStagedUploadAcceptedResponse,
KnowledgeFSDocumentUploadAcceptedResponse,
KnowledgeFSDurableDeletionAcceptedResponse,
KnowledgeFSNamespacePreviewJobResponse,
KnowledgeFSNamespacePreviewPageResponse,
KnowledgeFSSmallFileUploadResponse,
KnowledgeFSSpaceCreatePayload,
KnowledgeFSStagedUploadResponse,
@ -157,6 +159,95 @@ def test_console_and_service_api_routes_are_registered() -> None:
}
def test_initial_website_preview_job_routes_delegate_to_namespace_capabilities(
monkeypatch: pytest.MonkeyPatch,
) -> None:
account = SimpleNamespace(id="account-1")
preview_service = SimpleNamespace(require_visible_credential=MagicMock())
facade = SimpleNamespace(
create_namespace_source_preview=MagicMock(return_value=SimpleNamespace(job_id="job-1")),
get_namespace_source_preview=MagicMock(
return_value=KnowledgeFSNamespacePreviewJobResponse(
job_id="job-1",
status="completed",
configuration_fingerprint="f" * 64,
expires_at="2030-01-01T00:00:00Z",
pages=[
KnowledgeFSNamespacePreviewPageResponse(
page_id="page-1",
source_url="https://example.com/page",
title="Page",
)
],
)
),
cancel_namespace_source_preview=MagicMock(
return_value=KnowledgeFSNamespacePreviewJobResponse(
job_id="job-1",
status="consumed",
configuration_fingerprint="f" * 64,
expires_at="2030-01-01T00:00:00Z",
)
),
)
monkeypatch.setattr(console_resources, "current_account_with_tenant", lambda: (account, "tenant-1"))
monkeypatch.setattr(console_resources, "KnowledgeFSInitialSourcePreviewService", lambda _: preview_service)
monkeypatch.setattr(console_resources, "_console_services", lambda: SimpleNamespace(facade=facade))
app = Flask(__name__)
with app.test_request_context(
method="POST",
json={
"kind": "website_crawl",
"credentialId": "credential-1",
"datasource": "website",
"pluginId": "plugin-1",
"provider": "firecrawl",
"parameters": {"url": "https://example.com"},
},
):
response, status = inspect.unwrap(console_resources.KnowledgeFSInitialSourcePreviewJobsApi.post)(
console_resources.KnowledgeFSInitialSourcePreviewJobsApi()
)
assert status == 202
assert response == {"job_id": "job-1", "status": "pending"}
preview_service.require_visible_credential.assert_called_once()
facade.create_namespace_source_preview.assert_called_once()
with app.test_request_context():
response = inspect.unwrap(console_resources.KnowledgeFSInitialSourcePreviewJobApi.get)(
console_resources.KnowledgeFSInitialSourcePreviewJobApi(), "job-1"
)
assert response["status"] == "completed"
assert response["result"]["pages"] == [
{
"description": None,
"page_id": "page-1",
"source_url": "https://example.com/page",
"title": "Page",
}
]
facade.get_namespace_source_preview.return_value = KnowledgeFSNamespacePreviewJobResponse(
job_id="job-1",
status="queued",
configuration_fingerprint="f" * 64,
expires_at="2030-01-01T00:00:00Z",
)
with app.test_request_context():
response = inspect.unwrap(console_resources.KnowledgeFSInitialSourcePreviewJobApi.get)(
console_resources.KnowledgeFSInitialSourcePreviewJobApi(), "job-1"
)
assert response["status"] == "pending"
assert response["result"] is None
with app.test_request_context(method="DELETE"):
response = inspect.unwrap(console_resources.KnowledgeFSInitialSourcePreviewJobApi.delete)(
console_resources.KnowledgeFSInitialSourcePreviewJobApi(), "job-1"
)
assert response == {"job_id": "job-1", "result": None, "status": "completed"}
@pytest.mark.parametrize(
("api_class", "method_name", "path_args"),
[

View File

@ -35,6 +35,7 @@ def test_ready_product_operations_exactly_match_capability_method_path_and_actio
"bulkDeleteLogicalDocuments",
"cancelBackgroundTask",
"cancelCompilationJob",
"cancelNamespaceSourcePreview",
"cancelResearchTask",
"cancelSourceWorkflow",
"captureWorkflowFailedRetrieval",
@ -44,6 +45,7 @@ def test_ready_product_operations_exactly_match_capability_method_path_and_actio
"createDocument",
"createGoldenQuestion",
"createMetadataField",
"createNamespaceSourcePreview",
"createQuery",
"createQualityBadCase",
"createQualityReplay",
@ -51,6 +53,7 @@ def test_ready_product_operations_exactly_match_capability_method_path_and_actio
"createSource",
"createSourceConnection",
"createUploadSession",
"consumeNamespaceSourcePreview",
"deleteDocument",
"deleteGoldenQuestion",
"deleteLogicalDocument",
@ -68,6 +71,7 @@ def test_ready_product_operations_exactly_match_capability_method_path_and_actio
"getQualityBadCaseTraceReference",
"getQualityReplay",
"getLogicalDocument",
"getNamespaceSourcePreview",
"getOverviewHealth",
"getOverviewInventory",
"getOverviewQueryOutcomes",