diff --git a/api/controllers/console/knowledge_fs_proxy.py b/api/controllers/console/knowledge_fs_proxy.py index 59ec6dafc62..bf9ba1587a0 100644 --- a/api/controllers/console/knowledge_fs_proxy.py +++ b/api/controllers/console/knowledge_fs_proxy.py @@ -8,8 +8,9 @@ can be validated explicitly against the pinned KnowledgeFS contract during devel Console auth and contract-specific dataset RBAC run before forwarding. Request bodies are capped at 64 MiB, JSON and binary responses have separate bounds, SSE responses remain streaming with a bounded idle read timeout, and only safe -response headers are exposed. Upstream 401 responses become 502 so they cannot -trigger Dify browser-session recovery; resource-level 403 responses remain 403. +response headers are exposed. Operation-specific upstream error mappings are +applied before Console JSON error handling; the default maps 401 to 502 so it +cannot trigger browser-session recovery and preserves resource-level 403. """ from __future__ import annotations @@ -27,9 +28,11 @@ from werkzeug.exceptions import ( BadGateway, Forbidden, GatewayTimeout, + HTTPException, NotFound, RequestEntityTooLarge, ServiceUnavailable, + default_exceptions, ) from configs import dify_config @@ -41,21 +44,28 @@ from controllers.console.wraps import ( ) from core.helper import ssrf_proxy from libs.login import current_account_with_tenant, login_required +from services.knowledge_fs_operations import KnowledgeFSMethod from services.knowledge_fs_proxy import ( KnowledgeFSAccessDeniedError, + KnowledgeFSAuthorization, KnowledgeFSConfigurationError, - KnowledgeFSMethod, KnowledgeFSRouteNotAllowedError, KnowledgeFSTimeoutError, KnowledgeFSTransportError, KnowledgeFSUpstreamResponse, authorize_knowledge_fs_request, get_knowledge_fs_operation, + proxy_authorized_knowledge_fs_request, proxy_knowledge_fs_request, ) logger = logging.getLogger(__name__) +type _KnowledgeFSRequestForwarder = Callable[ + [str | None, str | None, bytes | None, bytes | None], + KnowledgeFSUpstreamResponse, +] + _MAX_PROXY_BODY_BYTES = 64 * 1024 * 1024 _RESPONSE_HEADER_ALLOWLIST = ( "Cache-Control", @@ -128,27 +138,25 @@ def _translate_proxy_error(exc: Exception, *, tenant_id: str) -> NoReturn: def _knowledge_fs_operation_access_required( - view: Callable[[KnowledgeFSMethod, str], ResponseReturnValue], + view: Callable[[KnowledgeFSAuthorization], ResponseReturnValue], ) -> Callable[[KnowledgeFSMethod, str], ResponseReturnValue]: """Authorize one declared operation before billing and request-body work.""" @wraps(view) def decorated(method: KnowledgeFSMethod, upstream_path: str) -> ResponseReturnValue: - try: - operation = get_knowledge_fs_operation(method, upstream_path) - except KnowledgeFSRouteNotAllowedError as exc: - raise NotFound() from exc - current_user, tenant_id = current_account_with_tenant() try: - authorize_knowledge_fs_request( + authorization = authorize_knowledge_fs_request( account=current_user, tenant_id=tenant_id, - operation=operation, + method=method, + path=upstream_path, ) + except KnowledgeFSRouteNotAllowedError as exc: + raise NotFound() from exc except KnowledgeFSAccessDeniedError as exc: _translate_proxy_error(exc, tenant_id=tenant_id) - return view(method, upstream_path) + return view(authorization) return decorated @@ -190,21 +198,26 @@ def _proxy_response( """Expose raw content, status, and allowlisted headers from KnowledgeFS. Raises: - BadGateway: KnowledgeFS rejects the configured server credential. - Forbidden: KnowledgeFS denies the account access to the requested resource. + HTTPException: KnowledgeFS returns a status normalized by the operation contract. """ upstream = upstream_result.response - if upstream.status_code == HTTPStatus.UNAUTHORIZED: + mapped_status = dict(upstream_result.operation.error_status_map).get(upstream.status_code) + if mapped_status is not None: upstream.close() - logger.error( - "KnowledgeFS rejected the Dify server credential with HTTP %s for tenant_id=%s", - upstream.status_code, - tenant_id, - ) - raise BadGateway("KnowledgeFS authentication failed") - if upstream.status_code == HTTPStatus.FORBIDDEN: - upstream.close() - raise Forbidden() + description = "KnowledgeFS upstream request failed" + if upstream.status_code == HTTPStatus.UNAUTHORIZED: + description = "KnowledgeFS authentication failed" + logger.error( + "KnowledgeFS rejected the Dify server credential with HTTP %s for tenant_id=%s", + upstream.status_code, + tenant_id, + ) + exception_type = default_exceptions.get(mapped_status) + if exception_type is None: + exception = HTTPException(description) + exception.code = mapped_status + raise exception + raise exception_type(description) allowed_header_names = dict.fromkeys( name.lower() for name in (*_RESPONSE_HEADER_ALLOWLIST, *contract_response_headers) @@ -237,26 +250,21 @@ def _proxy_response( return Response(content, status=upstream.status_code, headers=headers) -def _proxy_request(method: KnowledgeFSMethod, upstream_path: str) -> Response: - """Forward the current raw request and return its filtered upstream response. - - The call performs one outbound KnowledgeFS request. Integration failures are - converted to Console HTTP exceptions for the outer JSON error adapter. - """ +def _proxy_current_request( + *, + method: KnowledgeFSMethod, + tenant_id: str, + forward: _KnowledgeFSRequestForwarder, +) -> Response: + """Forward the current raw request through one preconfigured service entry.""" if not dify_config.KNOWLEDGE_FS_ENABLED: raise NotFound() - current_user, tenant_id = current_account_with_tenant() try: - proxy_result = proxy_knowledge_fs_request( - account=current_user, - method=method, - path=upstream_path, - tenant_id=tenant_id, - accept=request.headers.get("Accept"), - content_type=request.content_type, - query=request.query_string or None, - body=_request_body() if method != "GET" else None, - request_headers=request.headers, + proxy_result = forward( + request.headers.get("Accept"), + request.content_type, + request.query_string or None, + _request_body() if method != "GET" else None, ) except ( KnowledgeFSConfigurationError, @@ -274,15 +282,77 @@ def _proxy_request(method: KnowledgeFSMethod, upstream_path: str) -> Response: ) +def _proxy_request( + method: KnowledgeFSMethod, + upstream_path: str, +) -> Response: + """Authorize and forward the current request through the combined service use case.""" + if not dify_config.KNOWLEDGE_FS_ENABLED: + raise NotFound() + current_user, tenant_id = current_account_with_tenant() + + def forward( + accept: str | None, + content_type: str | None, + query: bytes | None, + body: bytes | None, + ) -> KnowledgeFSUpstreamResponse: + return proxy_knowledge_fs_request( + account=current_user, + method=method, + path=upstream_path, + tenant_id=tenant_id, + accept=accept, + content_type=content_type, + query=query, + body=body, + request_headers=request.headers, + ) + + return _proxy_current_request(method=method, tenant_id=tenant_id, forward=forward) + + +def _proxy_authorized_request(authorization: KnowledgeFSAuthorization) -> Response: + """Forward the current request using one previously authorized operation capability. + + Args: + authorization: Request-scoped capability produced before billing and body parsing. + + Returns: + The filtered response returned by KnowledgeFS. + + Raises: + HTTPException: The integration is disabled or forwarding fails. + """ + operation = authorization.operation + tenant_id = authorization.tenant_id + + def forward( + accept: str | None, + content_type: str | None, + query: bytes | None, + body: bytes | None, + ) -> KnowledgeFSUpstreamResponse: + return proxy_authorized_knowledge_fs_request( + authorization=authorization, + accept=accept, + content_type=content_type, + query=query, + body=body, + request_headers=request.headers, + ) + + return _proxy_current_request(method=operation.method, tenant_id=tenant_id, forward=forward) + + @_knowledge_fs_enabled @_knowledge_fs_operation_access_required @cloud_edition_billing_rate_limit_check("knowledge") def _proxy_knowledge_fs_non_get( - method: KnowledgeFSMethod, - upstream_path: str, + authorization: KnowledgeFSAuthorization, ) -> ResponseReturnValue: """Apply knowledge billing checks to one allowlisted non-GET operation.""" - return _proxy_request(method, upstream_path) + return _proxy_authorized_request(authorization) @bp.route( diff --git a/api/dev/generate_knowledge_fs_contract.py b/api/dev/generate_knowledge_fs_contract.py index a753a2c4ba7..d2a06a6db0f 100644 --- a/api/dev/generate_knowledge_fs_contract.py +++ b/api/dev/generate_knowledge_fs_contract.py @@ -12,6 +12,7 @@ import json import subprocess import sys import tempfile +from copy import deepcopy from pathlib import Path from typing import Any, Literal, TypedDict @@ -24,6 +25,16 @@ LOCK_PATH = API_ROOT / "knowledge-fs-contract.lock.json" DEFAULT_REPOSITORY = WORKSPACE_ROOT.parent / "knowledge-fs" OPENAPI_METHODS = ("delete", "get", "head", "options", "patch", "post", "put", "trace") PROXY_METHODS = frozenset({"delete", "get", "patch", "post", "put"}) +CONSOLE_PROXY_ERROR_SCHEMA_NAME = "ConsoleProxyError" +CONSOLE_PROXY_ERROR_SCHEMA: dict[str, Any] = { + "type": "object", + "required": ["code", "message", "status"], + "properties": { + "code": {"type": "string"}, + "message": {"type": "string"}, + "status": {"type": "integer"}, + }, +} class ContractDeclaration(TypedDict): @@ -38,6 +49,7 @@ class ContractDeclaration(TypedDict): request_headers: tuple[str, ...] response_headers: tuple[str, ...] response_media_types: tuple[str, ...] + error_status_map: tuple[tuple[int, int], ...] type DeclarationField = Literal[ @@ -106,8 +118,11 @@ def main() -> None: validate_declarations(document, declarations) if args.output_openapi: + filtered_document = filter_openapi_document(document, declarations) + filtered_document["x-dify-source-openapi-sha256"] = openapi_sha256 + filtered_document["x-dify-console-declarations-sha256"] = contract_declarations_sha256(declarations) args.output_openapi.parent.mkdir(parents=True, exist_ok=True) - args.output_openapi.write_text(json.dumps(filter_openapi_document(document, declarations), indent=2) + "\n") + args.output_openapi.write_text(json.dumps(filtered_document, indent=2) + "\n") if args.update_lock: LOCK_PATH.write_text( @@ -153,8 +168,7 @@ def validate_declarations(document: dict[str, Any], declarations: tuple[Contract raise ValueError(f"KnowledgeFS OpenAPI path must be absolute: {path}") if method not in PROXY_METHODS: raise ValueError(f"KnowledgeFS proxy does not support {method.upper()} {path}") - expected: ContractDeclaration = { - "operation_id": operation_id, + expected: dict[DeclarationField, object] = { "method": method.upper(), "path": path[1:], "required_scope": required_scope(operation), @@ -172,6 +186,7 @@ def validate_declarations(document: dict[str, Any], declarations: tuple[Contract f"KnowledgeFS operation {operation_id} field {field} drifted: " f"expected {expected_value!r}, received {received_value!r}" ) + validate_error_status_map(operation_id, declaration["error_status_map"]) def filter_openapi_document( @@ -191,19 +206,65 @@ def filter_openapi_document( source_path_item = source_paths[path] path_metadata = {key: value for key, value in source_path_item.items() if key not in OPENAPI_METHODS} filtered_path_item = filtered_paths.setdefault(path, path_metadata) - filtered_path_item[method] = source_path_item[method] + filtered_operation = deepcopy(source_path_item[method]) + _rewrite_proxy_error_responses(filtered_operation, declaration["error_status_map"]) + filtered_path_item[method] = filtered_operation filtered_document["paths"] = filtered_paths source_components = document.get("components", {}) filtered_components = {key: value for key, value in source_components.items() if key != "schemas"} source_schemas = source_components.get("schemas", {}) - schema_names = _referenced_schema_names(filtered_paths, source_schemas) - filtered_components["schemas"] = {name: schema for name, schema in source_schemas.items() if name in schema_names} + available_schemas = {**source_schemas, CONSOLE_PROXY_ERROR_SCHEMA_NAME: CONSOLE_PROXY_ERROR_SCHEMA} + schema_names = _referenced_schema_names(filtered_paths, available_schemas) + filtered_components["schemas"] = { + name: schema for name, schema in available_schemas.items() if name in schema_names + } filtered_document["components"] = filtered_components return filtered_document +def validate_error_status_map(operation_id: str, error_status_map: tuple[tuple[int, int], ...]) -> None: + """Validate the status normalization advertised by one Console operation.""" + upstream_statuses: set[int] = set() + for upstream_status, console_status in error_status_map: + if upstream_status in upstream_statuses: + raise ValueError(f"KnowledgeFS operation {operation_id} has duplicate error status: {upstream_status}") + if not 400 <= upstream_status <= 599 or not 400 <= console_status <= 599: + raise ValueError(f"KnowledgeFS operation {operation_id} has invalid error status mapping") + upstream_statuses.add(upstream_status) + + +def _rewrite_proxy_error_responses( + operation: dict[str, Any], + error_status_map: tuple[tuple[int, int], ...], +) -> None: + responses = operation.setdefault("responses", {}) + proxy_error_response = { + "description": "Error normalized by the Dify Console KnowledgeFS proxy.", + "content": { + "application/json": {"schema": {"$ref": f"#/components/schemas/{CONSOLE_PROXY_ERROR_SCHEMA_NAME}"}} + }, + } + for upstream_status, console_status in error_status_map: + existing_target = responses.get(str(console_status)) if upstream_status != console_status else None + responses.pop(str(upstream_status), None) + normalized_response: dict[str, Any] = deepcopy(proxy_error_response) + existing_schema = ( + existing_target.get("content", {}).get("application/json", {}).get("schema") + if isinstance(existing_target, dict) + else None + ) + if existing_schema is not None: + normalized_response["content"]["application/json"]["schema"] = { + "oneOf": [ + deepcopy(existing_schema), + {"$ref": f"#/components/schemas/{CONSOLE_PROXY_ERROR_SCHEMA_NAME}"}, + ] + } + responses[str(console_status)] = normalized_response + + def _referenced_schema_names(value: Any, schemas: dict[str, Any]) -> set[str]: reference_prefix = "#/components/schemas/" selected: set[str] = set() @@ -232,7 +293,7 @@ def _referenced_schema_names(value: Any, schemas: dict[str, Any]) -> set[str]: def console_contract_declarations() -> tuple[ContractDeclaration, ...]: """Return transport declarations from the runtime Console operation registry.""" - from services.knowledge_fs_proxy import KNOWLEDGE_FS_CONSOLE_OPERATIONS + from services.knowledge_fs_operations import KNOWLEDGE_FS_CONSOLE_OPERATIONS return tuple( { @@ -245,11 +306,18 @@ def console_contract_declarations() -> tuple[ContractDeclaration, ...]: "request_headers": operation.request_headers, "response_headers": operation.response_headers, "response_media_types": operation.response_media_types, + "error_status_map": operation.error_status_map, } for operation in KNOWLEDGE_FS_CONSOLE_OPERATIONS ) +def contract_declarations_sha256(declarations: tuple[ContractDeclaration, ...]) -> str: + """Return a stable digest for the runtime Console operation declarations.""" + content = json.dumps(declarations, separators=(",", ":"), sort_keys=True).encode() + return sha256(content) + + def response_kind(operation: dict[str, Any]) -> str: media_types = response_media_types(operation) if "text/event-stream" in media_types: diff --git a/api/knowledge-fs-contract.lock.json b/api/knowledge-fs-contract.lock.json index b45b5e9ec4b..b908f81da62 100644 --- a/api/knowledge-fs-contract.lock.json +++ b/api/knowledge-fs-contract.lock.json @@ -1,5 +1,5 @@ { - "commit": "4310e2d582d25e7de58183f27720afab01e123cf", - "openapiSha256": "5827ca930ce38462bfd1b2bef387efbf37eb7ffcaedde4558af2fbaeccbfbc4b", + "commit": "a0f50470612cc0b3656f89e4f2435aaf412e6e3b", + "openapiSha256": "f18910e9c45a64f0855e0643a7a626fb2889021b4f943458de86c6bd2469facb", "repository": "https://github.com/langgenius/knowledge-fs" } diff --git a/api/services/knowledge_fs_operations.py b/api/services/knowledge_fs_operations.py new file mode 100644 index 00000000000..b8ee5fbd517 --- /dev/null +++ b/api/services/knowledge_fs_operations.py @@ -0,0 +1,502 @@ +"""Product-facing KnowledgeFS operation and authorization declarations. + +This registry is Dify's explicit Console surface. Transport concerns live in +knowledge_fs_proxy so contract review does not require reading proxy mechanics. +""" + +from __future__ import annotations + +from typing import Final, Literal, NamedTuple + +from core.rbac import RBACPermission + +type KnowledgeFSMethod = Literal["DELETE", "GET", "PATCH", "POST", "PUT"] +type KnowledgeFSResponseKind = Literal["binary", "buffered", "stream"] +type KnowledgeFSRequiredScope = Literal["knowledge-spaces:read", "knowledge-spaces:write"] +type KnowledgeFSLegacyRole = Literal["reader", "dataset_editor", "admin"] +type KnowledgeFSErrorStatusMap = tuple[tuple[int, int], ...] + + +class KnowledgeFSOperation(NamedTuple): + operation_id: str + method: KnowledgeFSMethod + path: str + response_kind: KnowledgeFSResponseKind + required_scope: KnowledgeFSRequiredScope + rbac_permission: RBACPermission + legacy_role: KnowledgeFSLegacyRole + max_response_bytes: int + request_headers: tuple[str, ...] + response_headers: tuple[str, ...] + response_media_types: tuple[str, ...] + error_status_map: KnowledgeFSErrorStatusMap + + +def _console_operation( + operation_id: str, + method: KnowledgeFSMethod, + path: str, + *, + rbac_permission: RBACPermission, + legacy_role: KnowledgeFSLegacyRole, + max_response_bytes: int = 1_048_576, + request_headers: tuple[str, ...] = ("x-trace-id",), + response_kind: KnowledgeFSResponseKind = "buffered", + response_media_types: tuple[str, ...] = ("application/json",), + error_status_map: KnowledgeFSErrorStatusMap = ((401, 502), (403, 403)), +) -> KnowledgeFSOperation: + """Declare one contract-pinned operation with an explicit Dify authorization policy.""" + is_read = method == "GET" + return KnowledgeFSOperation( + operation_id=operation_id, + method=method, + path=path, + response_kind=response_kind, + required_scope="knowledge-spaces:read" if is_read else "knowledge-spaces:write", + rbac_permission=rbac_permission, + legacy_role=legacy_role, + max_response_bytes=max_response_bytes, + request_headers=request_headers, + response_headers=("x-trace-id",), + response_media_types=response_media_types, + error_status_map=error_status_map, + ) + + +def _dataset_read_operation(operation_id: str, path: str) -> KnowledgeFSOperation: + """Declare a dataset-readable buffered JSON operation.""" + return _console_operation( + operation_id, + "GET", + path, + rbac_permission=RBACPermission.DATASET_READONLY, + legacy_role="reader", + ) + + +def _dataset_edit_operation( + operation_id: str, + method: KnowledgeFSMethod, + path: str, + *, + request_headers: tuple[str, ...] = ("x-trace-id",), +) -> KnowledgeFSOperation: + """Declare a dataset-editable buffered JSON operation.""" + return _console_operation( + operation_id, + method, + path, + rbac_permission=RBACPermission.DATASET_EDIT, + legacy_role="dataset_editor", + request_headers=request_headers, + ) + + +def _external_source_operation( + operation_id: str, + method: KnowledgeFSMethod, + path: str, + *, + request_headers: tuple[str, ...] = ("x-trace-id",), +) -> KnowledgeFSOperation: + """Declare a source-connection operation restricted to dataset editors.""" + return _console_operation( + operation_id, + method, + path, + rbac_permission=RBACPermission.DATASET_EXTERNAL_CONNECT, + legacy_role="dataset_editor", + request_headers=request_headers, + ) + + +KNOWLEDGE_FS_CONSOLE_OPERATIONS: Final[tuple[KnowledgeFSOperation, ...]] = ( + _console_operation( + operation_id="listKnowledgeSpaces", + method="GET", + path="knowledge-spaces", + rbac_permission=RBACPermission.DATASET_READONLY, + legacy_role="reader", + ), + _console_operation( + operation_id="createKnowledgeSpace", + method="POST", + path="knowledge-spaces", + rbac_permission=RBACPermission.DATASET_CREATE_AND_MANAGEMENT, + legacy_role="dataset_editor", + ), + _console_operation( + operation_id="getKnowledgeSpacesById", + method="GET", + path="knowledge-spaces/{id}", + rbac_permission=RBACPermission.DATASET_READONLY, + legacy_role="reader", + ), + _dataset_edit_operation("patchKnowledgeSpacesById", "PATCH", "knowledge-spaces/{id}"), + _dataset_edit_operation( + "deleteKnowledgeSpacesById", + "DELETE", + "knowledge-spaces/{id}", + request_headers=("idempotency-key", "x-trace-id"), + ), + _dataset_read_operation("getKnowledgeSpacesByIdStats", "knowledge-spaces/{id}/stats"), + _console_operation( + operation_id="getKnowledgeSpacesByIdAccessPolicy", + method="GET", + path="knowledge-spaces/{id}/access-policy", + rbac_permission=RBACPermission.DATASET_READONLY, + legacy_role="reader", + ), + _console_operation( + operation_id="patchKnowledgeSpacesByIdAccessPolicy", + method="PATCH", + path="knowledge-spaces/{id}/access-policy", + rbac_permission=RBACPermission.DATASET_ACCESS_CONFIG, + legacy_role="admin", + ), + _console_operation( + operation_id="getSourceProviders", + method="GET", + path="source-providers", + rbac_permission=RBACPermission.DATASET_EXTERNAL_CONNECT, + legacy_role="dataset_editor", + ), + _console_operation( + operation_id="getKnowledgeSpacesByIdSourceConnections", + method="GET", + path="knowledge-spaces/{id}/source-connections", + rbac_permission=RBACPermission.DATASET_EXTERNAL_CONNECT, + legacy_role="dataset_editor", + ), + _console_operation( + operation_id="postKnowledgeSpacesByIdSourceConnections", + method="POST", + path="knowledge-spaces/{id}/source-connections", + rbac_permission=RBACPermission.DATASET_EXTERNAL_CONNECT, + legacy_role="dataset_editor", + ), + _external_source_operation( + "postKnowledgeSpacesByIdSourceConnectionsOauth", + "POST", + "knowledge-spaces/{id}/source-connections/oauth", + ), + _external_source_operation("postSourceOauthCallback", "POST", "source-oauth/callback"), + _external_source_operation( + "getKnowledgeSpacesByIdSourceConnectionsByConnectionId", + "GET", + "knowledge-spaces/{id}/source-connections/{connectionId}", + ), + _external_source_operation( + "deleteKnowledgeSpacesByIdSourceConnectionsByConnectionId", + "DELETE", + "knowledge-spaces/{id}/source-connections/{connectionId}", + ), + _console_operation( + operation_id="postKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefresh", + method="POST", + path="knowledge-spaces/{id}/source-connections/{connectionId}/refresh", + rbac_permission=RBACPermission.DATASET_EXTERNAL_CONNECT, + legacy_role="dataset_editor", + ), + _console_operation( + operation_id="getKnowledgeSpacesByIdSources", + method="GET", + path="knowledge-spaces/{id}/sources", + rbac_permission=RBACPermission.DATASET_READONLY, + legacy_role="reader", + ), + _console_operation( + operation_id="postKnowledgeSpacesByIdSources", + method="POST", + path="knowledge-spaces/{id}/sources", + rbac_permission=RBACPermission.DATASET_EXTERNAL_CONNECT, + legacy_role="dataset_editor", + ), + _external_source_operation( + "getKnowledgeSpacesByIdSourcesBySourceId", + "GET", + "knowledge-spaces/{id}/sources/{sourceId}", + ), + _external_source_operation( + "patchKnowledgeSpacesByIdSourcesBySourceId", + "PATCH", + "knowledge-spaces/{id}/sources/{sourceId}", + ), + _external_source_operation( + "deleteKnowledgeSpacesByIdSourcesBySourceId", + "DELETE", + "knowledge-spaces/{id}/sources/{sourceId}", + request_headers=("idempotency-key", "x-trace-id"), + ), + _external_source_operation( + "putKnowledgeSpacesByIdSourcesBySourceIdCredentials", + "PUT", + "knowledge-spaces/{id}/sources/{sourceId}/credentials", + ), + _external_source_operation( + "deleteKnowledgeSpacesByIdSourcesBySourceIdCredentials", + "DELETE", + "knowledge-spaces/{id}/sources/{sourceId}/credentials", + ), + _external_source_operation( + "postKnowledgeSpacesByIdSourcesBySourceIdSync", + "POST", + "knowledge-spaces/{id}/sources/{sourceId}/sync", + request_headers=("idempotency-key", "x-trace-id"), + ), + _console_operation( + operation_id="postKnowledgeSpacesByIdSourcesBySourceIdCrawlPreview", + method="POST", + path="knowledge-spaces/{id}/sources/{sourceId}/crawl-preview", + rbac_permission=RBACPermission.DATASET_EXTERNAL_CONNECT, + legacy_role="dataset_editor", + request_headers=("idempotency-key", "x-trace-id"), + ), + _external_source_operation( + "postKnowledgeSpacesByIdSourcesBySourceIdWorkflowImports", + "POST", + "knowledge-spaces/{id}/sources/{sourceId}/workflow-imports", + request_headers=("idempotency-key", "x-trace-id"), + ), + _external_source_operation( + "getKnowledgeSpacesByIdSourcesBySourceIdPages", + "GET", + "knowledge-spaces/{id}/sources/{sourceId}/pages", + ), + _external_source_operation( + "getKnowledgeSpacesByIdSourcesBySourceIdFiles", + "GET", + "knowledge-spaces/{id}/sources/{sourceId}/files", + ), + _external_source_operation( + "postKnowledgeSpacesByIdSourcesBySourceIdCrawl", + "POST", + "knowledge-spaces/{id}/sources/{sourceId}/crawl", + ), + _external_source_operation( + "postKnowledgeSpacesByIdSourcesBySourceIdImport", + "POST", + "knowledge-spaces/{id}/sources/{sourceId}/import", + ), + _external_source_operation( + "postKnowledgeSpacesByIdSourcesBySourceIdTest", + "POST", + "knowledge-spaces/{id}/sources/{sourceId}/test", + ), + _external_source_operation( + "postKnowledgeSpacesByIdSourcesBySourceIdImportFiles", + "POST", + "knowledge-spaces/{id}/sources/{sourceId}/import-files", + ), + _external_source_operation( + "postKnowledgeSpacesByIdSourcesBulk", + "POST", + "knowledge-spaces/{id}/sources/bulk", + request_headers=("idempotency-key", "x-trace-id"), + ), + _external_source_operation( + "getKnowledgeSpacesByIdSourceWorkflows", + "GET", + "knowledge-spaces/{id}/source-workflows", + ), + _console_operation( + operation_id="getKnowledgeSpacesByIdSourceWorkflowsByRunId", + method="GET", + path="knowledge-spaces/{id}/source-workflows/{runId}", + rbac_permission=RBACPermission.DATASET_EXTERNAL_CONNECT, + legacy_role="dataset_editor", + ), + _external_source_operation( + "getKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItems", + "GET", + "knowledge-spaces/{id}/source-workflows/{runId}/bulk-items", + ), + _console_operation( + operation_id="getKnowledgeSpacesByIdSourceWorkflowsByRunIdPages", + method="GET", + path="knowledge-spaces/{id}/source-workflows/{runId}/pages", + rbac_permission=RBACPermission.DATASET_EXTERNAL_CONNECT, + legacy_role="dataset_editor", + ), + _console_operation( + operation_id="postKnowledgeSpacesByIdSourceWorkflowsByRunIdCancel", + method="POST", + path="knowledge-spaces/{id}/source-workflows/{runId}/cancel", + rbac_permission=RBACPermission.DATASET_EXTERNAL_CONNECT, + legacy_role="dataset_editor", + ), + _console_operation( + operation_id="postKnowledgeSpacesByIdSourceWorkflowsByRunIdRetry", + method="POST", + path="knowledge-spaces/{id}/source-workflows/{runId}/retry", + rbac_permission=RBACPermission.DATASET_EXTERNAL_CONNECT, + legacy_role="dataset_editor", + ), + _console_operation( + operation_id="postKnowledgeSpacesByIdSourceWorkflowsByRunIdSelection", + method="POST", + path="knowledge-spaces/{id}/source-workflows/{runId}/selection", + rbac_permission=RBACPermission.DATASET_EXTERNAL_CONNECT, + legacy_role="dataset_editor", + request_headers=("idempotency-key", "x-trace-id"), + ), + _console_operation( + operation_id="getKnowledgeSpacesByIdSourcesBySourceIdSyncPolicy", + method="GET", + path="knowledge-spaces/{id}/sources/{sourceId}/sync-policy", + rbac_permission=RBACPermission.DATASET_READONLY, + legacy_role="reader", + ), + _console_operation( + operation_id="putKnowledgeSpacesByIdSourcesBySourceIdSyncPolicy", + method="PUT", + path="knowledge-spaces/{id}/sources/{sourceId}/sync-policy", + rbac_permission=RBACPermission.DATASET_EDIT, + legacy_role="dataset_editor", + ), + _dataset_read_operation("getKnowledgeSpacesByIdDocuments", "knowledge-spaces/{id}/documents"), + _dataset_edit_operation("postKnowledgeSpacesByIdDocuments", "POST", "knowledge-spaces/{id}/documents"), + _dataset_edit_operation( + "deleteKnowledgeSpacesByIdDocumentsBulk", + "DELETE", + "knowledge-spaces/{id}/documents/bulk", + request_headers=("idempotency-key", "x-trace-id"), + ), + _dataset_edit_operation( + "postKnowledgeSpacesByIdDocumentsBulk", + "POST", + "knowledge-spaces/{id}/documents/bulk", + ), + _dataset_edit_operation( + "postKnowledgeSpacesByIdDocumentsBulkReindex", + "POST", + "knowledge-spaces/{id}/documents/bulk/reindex", + ), + _dataset_read_operation( + "getKnowledgeSpacesByIdDocumentsByDocumentId", + "knowledge-spaces/{id}/documents/{documentId}", + ), + _dataset_edit_operation( + "deleteKnowledgeSpacesByIdDocumentsByDocumentId", + "DELETE", + "knowledge-spaces/{id}/documents/{documentId}", + request_headers=("idempotency-key", "x-trace-id"), + ), + _console_operation( + operation_id="getKnowledgeSpacesByIdLogicalDocuments", + method="GET", + path="knowledge-spaces/{id}/logical-documents", + rbac_permission=RBACPermission.DATASET_READONLY, + legacy_role="reader", + ), + _dataset_edit_operation( + "deleteKnowledgeSpacesByIdLogicalDocumentsByDocumentId", + "DELETE", + "knowledge-spaces/{id}/logical-documents/{documentId}", + request_headers=("idempotency-key", "x-trace-id"), + ), + _dataset_read_operation( + "getKnowledgeSpacesByIdDocumentsByDocumentIdOutline", + "knowledge-spaces/{id}/documents/{documentId}/outline", + ), + _console_operation( + operation_id="getKnowledgeSpacesByIdLogicalDocumentsByDocumentId", + method="GET", + path="knowledge-spaces/{id}/logical-documents/{documentId}", + rbac_permission=RBACPermission.DATASET_READONLY, + legacy_role="reader", + ), + _console_operation( + operation_id="getKnowledgeSpacesByIdDocumentsByDocumentIdRevisions", + method="GET", + path="knowledge-spaces/{id}/documents/{documentId}/revisions", + rbac_permission=RBACPermission.DATASET_READONLY, + legacy_role="reader", + ), + _dataset_edit_operation( + "postKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollback", + "POST", + "knowledge-spaces/{id}/documents/{documentId}/revisions/{revision}/rollback", + ), + _dataset_edit_operation( + "patchKnowledgeSpacesByIdDocumentsByDocumentIdMetadata", + "PATCH", + "knowledge-spaces/{id}/documents/{documentId}/metadata", + ), + _console_operation( + operation_id="getKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunks", + method="GET", + path="knowledge-spaces/{id}/documents/{documentId}/revisions/{revision}/chunks", + rbac_permission=RBACPermission.DATASET_READONLY, + legacy_role="reader", + ), + _dataset_read_operation( + "getKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkId", + "knowledge-spaces/{id}/documents/{documentId}/revisions/{revision}/chunks/{chunkId}", + ), + _dataset_edit_operation( + "postKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdState", + "POST", + "knowledge-spaces/{id}/documents/{documentId}/revisions/{revision}/chunks/{chunkId}/state", + ), + _console_operation( + operation_id="getKnowledgeSpacesByIdProcessingTasks", + method="GET", + path="knowledge-spaces/{id}/processing-tasks", + rbac_permission=RBACPermission.DATASET_READONLY, + legacy_role="reader", + ), + _dataset_read_operation( + "getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasks", + "knowledge-spaces/{id}/documents/{documentId}/processing-tasks", + ), + _dataset_read_operation( + "getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskId", + "knowledge-spaces/{id}/documents/{documentId}/processing-tasks/{taskId}", + ), + _console_operation( + operation_id="getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEvents", + method="GET", + path="knowledge-spaces/{id}/documents/{documentId}/processing-tasks/{taskId}/events", + rbac_permission=RBACPermission.DATASET_READONLY, + legacy_role="reader", + max_response_bytes=67_108_864, + request_headers=("last-event-id", "x-trace-id"), + response_kind="stream", + response_media_types=("text/event-stream",), + ), + _console_operation( + operation_id="deleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskId", + method="DELETE", + path="knowledge-spaces/{id}/documents/{documentId}/processing-tasks/{taskId}", + rbac_permission=RBACPermission.DATASET_EDIT, + legacy_role="dataset_editor", + ), + _console_operation( + operation_id="postKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetry", + method="POST", + path="knowledge-spaces/{id}/documents/{documentId}/processing-tasks/{taskId}/retry", + rbac_permission=RBACPermission.DATASET_EDIT, + legacy_role="dataset_editor", + ), + _dataset_read_operation( + "getKnowledgeSpacesByIdDocumentsByDocumentIdSettings", + "knowledge-spaces/{id}/documents/{documentId}/settings", + ), + _dataset_edit_operation( + "putKnowledgeSpacesByIdDocumentsByDocumentIdSettings", + "PUT", + "knowledge-spaces/{id}/documents/{documentId}/settings", + ), + _dataset_read_operation("getJobsById", "jobs/{id}"), + _dataset_edit_operation("deleteJobsById", "DELETE", "jobs/{id}"), + _dataset_edit_operation("postJobsByIdRetry", "POST", "jobs/{id}/retry"), + _dataset_read_operation("getDeletionJobsByJobId", "deletion-jobs/{jobId}"), + _dataset_edit_operation( + "postDeletionJobsByJobIdRetry", + "POST", + "deletion-jobs/{jobId}/retry", + request_headers=("idempotency-key", "x-trace-id"), + ), + _dataset_read_operation("getBulkJobsById", "bulk-jobs/{id}"), +) diff --git a/api/services/knowledge_fs_proxy.py b/api/services/knowledge_fs_proxy.py index dab2a040d47..1e4f43329ea 100644 --- a/api/services/knowledge_fs_proxy.py +++ b/api/services/knowledge_fs_proxy.py @@ -1,33 +1,32 @@ -"""Transport-only forwarding for the explicitly enabled KnowledgeFS Console operations. +"""Authorize and forward the explicitly enabled KnowledgeFS Console operations. -KnowledgeFS owns the request and response contract. This module binds short-lived -account and workspace identities, enforces Dify's coarse workspace policy, and -normalizes transport failures. Dify deliberately maintains a small product-facing -operation registry instead of exposing the full upstream OpenAPI surface. The -dedicated request path uses Dify's shared SSRF policy, never follows redirects, -bounds buffered responses, and rejects compressed responses. +The dedicated request path uses Dify's shared SSRF policy, never follows redirects, +bounds buffered responses, and rejects compressed streaming responses. """ from __future__ import annotations from collections.abc import Iterable, Mapping +from dataclasses import dataclass from datetime import UTC, datetime, timedelta from http import HTTPStatus -from typing import Final, Literal, NamedTuple, Protocol +from typing import NamedTuple, Protocol import httpx import jwt from configs import dify_config from core.helper import ssrf_proxy -from core.rbac import RBACPermission, RBACResourceScope +from core.rbac import RBACResourceScope from core.tools.errors import ToolSSRFError from models import Account from services.enterprise.rbac_service import RBACService - -type KnowledgeFSMethod = Literal["DELETE", "GET", "PATCH", "POST", "PUT"] -type KnowledgeFSResponseKind = Literal["binary", "buffered", "stream"] -type KnowledgeFSRequiredScope = Literal["knowledge-spaces:read", "knowledge-spaces:write"] +from services.knowledge_fs_operations import ( + KNOWLEDGE_FS_CONSOLE_OPERATIONS, + KnowledgeFSMethod, + KnowledgeFSOperation, + KnowledgeFSResponseKind, +) _JWT_AUDIENCE = "knowledge-fs" _JWT_ISSUER = "dify" @@ -35,56 +34,55 @@ _JWT_TTL_SECONDS = 60 _MAX_BUFFERED_RESPONSE_BYTES = 1024 * 1024 -class KnowledgeFSOperation(NamedTuple): - operation_id: str - method: KnowledgeFSMethod - path: str - response_kind: KnowledgeFSResponseKind - required_scope: KnowledgeFSRequiredScope - rbac_permission: RBACPermission - requires_dataset_editor: bool - max_response_bytes: int - request_headers: tuple[str, ...] - response_headers: tuple[str, ...] - response_media_types: tuple[str, ...] - - -KNOWLEDGE_FS_CONSOLE_OPERATIONS: Final[tuple[KnowledgeFSOperation, ...]] = ( - KnowledgeFSOperation( - operation_id="listKnowledgeSpaces", - method="GET", - path="knowledge-spaces", - response_kind="buffered", - required_scope="knowledge-spaces:read", - rbac_permission=RBACPermission.DATASET_READONLY, - requires_dataset_editor=False, - max_response_bytes=1_048_576, - request_headers=("x-trace-id",), - response_headers=("x-trace-id",), - response_media_types=("application/json",), - ), - KnowledgeFSOperation( - operation_id="createKnowledgeSpace", - method="POST", - path="knowledge-spaces", - response_kind="buffered", - required_scope="knowledge-spaces:write", - rbac_permission=RBACPermission.DATASET_CREATE_AND_MANAGEMENT, - requires_dataset_editor=True, - max_response_bytes=1_048_576, - request_headers=("x-trace-id",), - response_headers=("x-trace-id",), - response_media_types=("application/json",), - ), -) - - class KnowledgeFSUpstreamResponse(NamedTuple): response: httpx.Response response_kind: KnowledgeFSResponseKind operation: KnowledgeFSOperation +_AUTHORIZATION_MARKER = object() + + +@dataclass(eq=False, frozen=True, init=False, slots=True) +class KnowledgeFSAuthorization: + """Single-use forwarding capability created after Dify workspace policy checks. + + Callers obtain this value from :func:`authorize_knowledge_fs_request`. Direct + construction and repeated forwarding are rejected before outbound I/O. + """ + + account_id: str + tenant_id: str + operation: KnowledgeFSOperation + _used: bool + + def __init__( + self, + account_id: str, + tenant_id: str, + operation: KnowledgeFSOperation, + *, + _marker: object | None = None, + ) -> None: + if _marker is not _AUTHORIZATION_MARKER: + raise KnowledgeFSAccessDeniedError("KnowledgeFS authorization must be created by workspace authorization") + object.__setattr__(self, "account_id", account_id) + object.__setattr__(self, "tenant_id", tenant_id) + object.__setattr__(self, "operation", operation) + object.__setattr__(self, "_used", False) + + def consume(self) -> tuple[str, str, KnowledgeFSOperation]: + """Return the authorized principals and canonical operation exactly once. + + Raises: + KnowledgeFSAccessDeniedError: The capability was already consumed. + """ + if self._used: + raise KnowledgeFSAccessDeniedError("KnowledgeFS authorization has already been used") + object.__setattr__(self, "_used", True) + return self.account_id, self.tenant_id, self.operation + + class _RequestHeaders(Protocol): def items(self) -> Iterable[tuple[str, str]]: ... @@ -113,20 +111,29 @@ def authorize_knowledge_fs_request( *, account: Account, tenant_id: str, - operation: KnowledgeFSOperation, -) -> None: + method: KnowledgeFSMethod, + path: str, +) -> KnowledgeFSAuthorization: """Enforce Dify's workspace policy before KFS performs resource authorization. Args: account: Authenticated Dify account with its current workspace role. tenant_id: Current Dify workspace identifier. - operation: Dify-maintained KnowledgeFS operation and policy metadata. + method: Requested upstream HTTP method. + path: Requested relative KnowledgeFS path. Raises: + KnowledgeFSRouteNotAllowedError: The method and path do not resolve to a declared operation. KnowledgeFSAccessDeniedError: The account lacks a required legacy or enterprise permission. + + Returns: + A request-scoped capability binding the authorized account, workspace, and operation. """ - if operation.requires_dataset_editor and not account.is_dataset_editor: - raise KnowledgeFSAccessDeniedError("KnowledgeFS mutations require dataset edit access") + operation = get_knowledge_fs_operation(method, path) + if operation.legacy_role == "dataset_editor" and not account.is_dataset_editor: + raise KnowledgeFSAccessDeniedError("KnowledgeFS operation requires dataset edit access") + if operation.legacy_role == "admin" and not account.is_admin_or_owner: + raise KnowledgeFSAccessDeniedError("KnowledgeFS operation requires workspace administration access") if not RBACService.CheckAccess.check( tenant_id, account.id, @@ -134,6 +141,7 @@ def authorize_knowledge_fs_request( resource_type=RBACResourceScope.DATASET.value, ): raise KnowledgeFSAccessDeniedError("KnowledgeFS operation is denied by workspace RBAC") + return KnowledgeFSAuthorization(account.id, tenant_id, operation, _marker=_AUTHORIZATION_MARKER) def proxy_knowledge_fs_request( @@ -149,20 +157,62 @@ def proxy_knowledge_fs_request( request_headers: _RequestHeaders | None = None, ) -> KnowledgeFSUpstreamResponse: """Authorize and forward one allowlisted KnowledgeFS request as a single use case.""" - operation = get_knowledge_fs_operation(method, path) - authorize_knowledge_fs_request( + authorization = authorize_knowledge_fs_request( account=account, tenant_id=tenant_id, - operation=operation, + method=method, + path=path, ) + + return proxy_authorized_knowledge_fs_request( + authorization=authorization, + accept=accept, + content_type=content_type, + query=query, + body=body, + request_headers=request_headers, + ) + + +def proxy_authorized_knowledge_fs_request( + *, + authorization: KnowledgeFSAuthorization, + accept: str | None = None, + content_type: str | None = None, + query: bytes | None = None, + body: bytes | None = None, + request_headers: _RequestHeaders | None = None, +) -> KnowledgeFSUpstreamResponse: + """Forward one request whose operation and workspace policy were already authorized. + + This performs one outbound KnowledgeFS request and does not repeat Dify RBAC checks. + + Args: + authorization: Request-scoped capability returned by :func:`authorize_knowledge_fs_request`. + accept: Original Accept header, when present. + content_type: Original request Content-Type header, when present. + query: Original encoded query string from the Console request. + body: Original request body, when present. + request_headers: Incoming headers; only names declared by the operation are forwarded. + + Returns: + The bounded KnowledgeFS response together with its transport metadata. + + Raises: + KnowledgeFSConfigurationError: The connection is incomplete or blocked by outbound policy. + KnowledgeFSRouteNotAllowedError: A forwarded request header is outside the operation contract. + KnowledgeFSTimeoutError: KnowledgeFS exceeds the configured timeout. + KnowledgeFSTransportError: The request fails or its response violates transport bounds. + """ + account_id, tenant_id, operation = authorization.consume() incoming_request_headers = {name.lower(): value for name, value in (request_headers or {}).items()} contract_request_headers = { name: incoming_request_headers[name] for name in operation.request_headers if name in incoming_request_headers } return _forward_knowledge_fs_request( - account_id=account.id, - method=method, - path=path, + account_id=account_id, + method=operation.method, + path=operation.path, tenant_id=tenant_id, accept=accept, content_type=content_type, diff --git a/api/tests/unit_tests/controllers/console/test_knowledge_fs_proxy.py b/api/tests/unit_tests/controllers/console/test_knowledge_fs_proxy.py index 41b97e2f028..34a8ca9fec2 100644 --- a/api/tests/unit_tests/controllers/console/test_knowledge_fs_proxy.py +++ b/api/tests/unit_tests/controllers/console/test_knowledge_fs_proxy.py @@ -7,9 +7,11 @@ from unittest.mock import MagicMock import httpx import pytest from flask import Flask, Response +from pydantic import SecretStr from werkzeug.exceptions import ( BadGateway, Forbidden, + HTTPException, NotFound, RequestEntityTooLarge, ServiceUnavailable, @@ -26,12 +28,14 @@ from controllers.console.knowledge_fs_proxy import ( proxy_knowledge_fs_write, ) from controllers.console.wraps import RBACPermission -from services.knowledge_fs_proxy import ( - KnowledgeFSAccessDeniedError, - KnowledgeFSConfigurationError, +from services.knowledge_fs_operations import ( KnowledgeFSMethod, KnowledgeFSOperation, KnowledgeFSResponseKind, +) +from services.knowledge_fs_proxy import ( + KnowledgeFSAccessDeniedError, + KnowledgeFSConfigurationError, KnowledgeFSRouteNotAllowedError, KnowledgeFSUpstreamResponse, get_knowledge_fs_operation, @@ -47,6 +51,7 @@ def _upstream( response: httpx.Response, kind: KnowledgeFSResponseKind = "buffered", *, + error_status_map: tuple[tuple[int, int], ...] = ((401, 502), (403, 403)), max_response_bytes: int | None = None, ) -> KnowledgeFSUpstreamResponse: operation = KnowledgeFSOperation( @@ -56,7 +61,7 @@ def _upstream( response_kind=kind, required_scope="knowledge-spaces:read", rbac_permission=RBACPermission.DATASET_READONLY, - requires_dataset_editor=False, + legacy_role="reader", max_response_bytes=max_response_bytes or (64 * 1024 * 1024 if kind == "stream" else 25 * 1024 * 1024 if kind == "binary" else 1024 * 1024), request_headers=(), @@ -67,6 +72,7 @@ def _upstream( "x-session-id", ), response_media_types=(), + error_status_map=error_status_map, ) return KnowledgeFSUpstreamResponse(response, kind, operation) @@ -93,7 +99,7 @@ def _set_current_workspace( def _bypass_policy_wrappers(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( "controllers.console.knowledge_fs_proxy._proxy_knowledge_fs_non_get", - unwrap(_proxy_knowledge_fs_non_get), + lambda method, path: _proxy_request(method, path), ) @@ -287,10 +293,8 @@ def test_read_post_applies_knowledge_rate_limit_once( monkeypatch.setattr("controllers.console.knowledge_fs_proxy.current_account_with_tenant", current_workspace) monkeypatch.setattr("controllers.console.wraps.current_account_with_tenant", current_workspace) - monkeypatch.setattr( - "services.knowledge_fs_proxy.RBACService.CheckAccess.check", - MagicMock(return_value=True), - ) + check_access = MagicMock(return_value=True) + monkeypatch.setattr("services.knowledge_fs_proxy.RBACService.CheckAccess.check", check_access) monkeypatch.setattr( "controllers.console.wraps.FeatureService.get_knowledge_rate_limit", MagicMock(return_value=MagicMock(enabled=True, limit=10)), @@ -300,14 +304,19 @@ def test_read_post_applies_knowledge_rate_limit_once( monkeypatch.setattr("controllers.console.wraps.redis_client.zremrangebyscore", MagicMock()) monkeypatch.setattr("controllers.console.wraps.redis_client.zcard", MagicMock(return_value=1)) proxy = MagicMock(return_value=Response(status=200)) - monkeypatch.setattr("controllers.console.knowledge_fs_proxy._proxy_request", proxy) + monkeypatch.setattr("controllers.console.knowledge_fs_proxy._proxy_authorized_request", proxy) with app.test_request_context("/console/api/knowledge-fs/knowledge-spaces", method="POST"): response = _proxy_knowledge_fs_non_get("POST", "knowledge-spaces") assert isinstance(response, Response) zadd.assert_called_once() - proxy.assert_called_once_with("POST", "knowledge-spaces") + proxy.assert_called_once() + authorization = proxy.call_args.args[0] + assert authorization.account_id == "account-1" + assert authorization.tenant_id == "tenant-1" + assert authorization.operation.operation_id == "createKnowledgeSpace" + check_access.assert_called_once() def test_denied_write_does_not_consume_the_workspace_rate_limit( @@ -447,6 +456,65 @@ def test_generic_write_forwards_path_raw_body_and_current_tenant( assert response.get_json()["tenantId"] == "tenant-1" +def test_generic_write_forwards_through_the_authorized_production_path( + app: Flask, + monkeypatch: pytest.MonkeyPatch, +) -> None: + account = MagicMock(id="account-1", is_dataset_editor=True) + + def current_workspace() -> tuple[MagicMock, str]: + return account, "tenant-1" + + monkeypatch.setattr("controllers.console.knowledge_fs_proxy.current_account_with_tenant", current_workspace) + monkeypatch.setattr("controllers.console.wraps.current_account_with_tenant", current_workspace) + check_access = MagicMock(return_value=True) + monkeypatch.setattr("services.knowledge_fs_proxy.RBACService.CheckAccess.check", check_access) + monkeypatch.setattr( + "controllers.console.wraps.FeatureService.get_knowledge_rate_limit", + MagicMock(return_value=MagicMock(enabled=False)), + ) + monkeypatch.setattr( + "services.knowledge_fs_proxy.dify_config.KNOWLEDGE_FS_BASE_URL", + "http://knowledge-fs.test", + raising=False, + ) + monkeypatch.setattr( + "services.knowledge_fs_proxy.dify_config.KNOWLEDGE_FS_JWT_SECRET", + SecretStr("production-secret-with-at-least-32-bytes"), + raising=False, + ) + upstream_request = MagicMock( + return_value=httpx.Response( + 201, + content=b'{"id":"space-1","tenantId":"tenant-1"}', + headers={"Content-Type": "application/json"}, + ) + ) + monkeypatch.setattr("services.knowledge_fs_proxy.ssrf_proxy.make_request", upstream_request) + route = unwrap(proxy_knowledge_fs_write) + body = b'{"idempotencyKey":"create-product-docs","name":"Product docs"}' + + with app.test_request_context( + "/console/api/knowledge-fs/knowledge-spaces", + method="POST", + query_string={"source": "console"}, + data=body, + content_type="application/json", + headers={"X-Trace-Id": "trace-1"}, + ): + response = route("knowledge-spaces") + + assert isinstance(response, Response) + assert response.status_code == 201 + assert response.get_json() == {"id": "space-1", "tenantId": "tenant-1"} + check_access.assert_called_once() + assert upstream_request.call_args.kwargs["method"] == "POST" + assert upstream_request.call_args.kwargs["url"] == "http://knowledge-fs.test/knowledge-spaces" + assert upstream_request.call_args.kwargs["params"] == b"source=console" + assert upstream_request.call_args.kwargs["content"] == body + assert upstream_request.call_args.kwargs["headers"]["x-trace-id"] == "trace-1" + + def test_generic_write_forwards_contract_declared_request_headers( app: Flask, monkeypatch: pytest.MonkeyPatch, @@ -617,6 +685,43 @@ def test_resource_authorization_rejection_is_exposed_as_forbidden( route("knowledge-spaces") +def test_proxy_response_applies_operation_specific_error_status_mapping() -> None: + upstream = httpx.Response( + 429, + content=b'{"error":"rate limited"}', + headers={"Content-Type": "application/json"}, + ) + + with pytest.raises(ServiceUnavailable): + _proxy_response( + _upstream(upstream, error_status_map=((429, 503),)), + tenant_id="tenant-1", + contract_response_headers=(), + max_response_bytes=1024 * 1024, + ) + + assert upstream.is_closed + + +def test_proxy_response_preserves_nonstandard_mapped_error_status() -> None: + upstream = httpx.Response( + 429, + content=b'{"error":"rate limited"}', + headers={"Content-Type": "application/json"}, + ) + + with pytest.raises(HTTPException) as exc_info: + _proxy_response( + _upstream(upstream, error_status_map=((429, 499),)), + tenant_id="tenant-1", + contract_response_headers=(), + max_response_bytes=1024 * 1024, + ) + + assert exc_info.value.code == 499 + assert upstream.is_closed + + def test_contract_response_headers_are_deduplicated_case_insensitively() -> None: upstream = httpx.Response( 200, @@ -671,6 +776,7 @@ def test_disallowed_non_get_route_is_hidden_as_not_found( monkeypatch: pytest.MonkeyPatch, method: KnowledgeFSMethod, ) -> None: + _set_current_workspace(monkeypatch) route = unwrap(proxy_knowledge_fs_write) with app.test_request_context("/console/api/knowledge-fs/not-a-route", method=method): diff --git a/api/tests/unit_tests/dev/test_generate_knowledge_fs_contract.py b/api/tests/unit_tests/dev/test_generate_knowledge_fs_contract.py index 007e88eb672..5123f45524c 100644 --- a/api/tests/unit_tests/dev/test_generate_knowledge_fs_contract.py +++ b/api/tests/unit_tests/dev/test_generate_knowledge_fs_contract.py @@ -2,6 +2,7 @@ import json import os +import re import subprocess import sys from pathlib import Path @@ -15,7 +16,7 @@ from dev.generate_knowledge_fs_contract import ( filter_openapi_document, validate_declarations, ) -from services.knowledge_fs_proxy import KNOWLEDGE_FS_CONSOLE_OPERATIONS, KnowledgeFSOperation +from services.knowledge_fs_operations import KNOWLEDGE_FS_CONSOLE_OPERATIONS, KnowledgeFSOperation def test_contract_cli_updates_checks_and_detects_openapi_drift(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: @@ -111,7 +112,7 @@ def test_contract_script_loads_runtime_registry_outside_api_directory(tmp_path: text=True, ) - assert result.stdout.strip() == "2" + assert result.stdout.strip() == str(len(KNOWLEDGE_FS_CONSOLE_OPERATIONS)) def test_validate_declarations_accepts_matching_contract() -> None: @@ -178,47 +179,115 @@ def test_filter_openapi_document_keeps_only_declared_operations_and_referenced_s assert set(filtered["paths"]) == {"/knowledge-spaces"} assert set(filtered["paths"]["/knowledge-spaces"]) == {"get"} - assert set(filtered["components"]["schemas"]) == {"KnowledgeSpaceList", "KnowledgeSpace"} + assert set(filtered["components"]["schemas"]) == { + "ConsoleProxyError", + "KnowledgeSpaceList", + "KnowledgeSpace", + } assert filtered["components"]["securitySchemes"] == document["components"]["securitySchemes"] -def test_console_operation_registry_matches_contract() -> None: - list_route = operation("knowledge-spaces:read", "listKnowledgeSpaces") - create_route = operation("knowledge-spaces:write", "createKnowledgeSpace") - for route in (list_route, create_route): - route["parameters"] = [{"in": "header", "name": "X-Trace-Id"}] - route["responses"] = { - "200": { - "content": {"application/json": {}}, - "headers": {"X-Trace-Id": {}}, - } - } +def test_filter_openapi_document_keeps_sse_for_streaming_orpc_contracts() -> None: + json_declaration = declaration() + stream_declaration = declaration( + operation_id="streamTask", + path="tasks/{id}/events", + response_kind="stream", + response_media_types=("text/event-stream",), + ) + json_operation = operation("knowledge-spaces:read", "listKnowledgeSpaces") + stream_operation = operation( + "knowledge-spaces:read", + "streamTask", + responses={"200": {"content": {"text/event-stream": {"schema": {"$ref": "#/components/schemas/TaskEvent"}}}}}, + ) - validate_declarations( + filtered = filter_openapi_document( { "paths": { - "/knowledge-spaces": { - "get": list_route, - "post": create_route, - } - } + "/knowledge-spaces": {"get": json_operation}, + "/tasks/{id}/events": {"get": stream_operation}, + }, + "components": {"schemas": {"TaskEvent": {"type": "object"}}}, }, + (json_declaration, stream_declaration), + ) + + assert set(filtered["paths"]) == {"/knowledge-spaces", "/tasks/{id}/events"} + assert filtered["components"]["schemas"]["TaskEvent"] == {"type": "object"} + + +def test_filter_openapi_document_rewrites_proxy_error_responses() -> None: + route = operation("knowledge-spaces:read", "listKnowledgeSpaces") + route["responses"] = { + "200": {"content": {"application/json": {}}}, + "401": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}}, + "403": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}}, + } + document = { + "paths": {"/knowledge-spaces": {"get": route}}, + "components": {"schemas": {"ErrorResponse": {"type": "object"}}}, + } + + filtered = filter_openapi_document( + document, + (declaration(error_status_map=((401, 502), (403, 403))),), + ) + + responses = filtered["paths"]["/knowledge-spaces"]["get"]["responses"] + assert "401" not in responses + assert responses["403"]["content"]["application/json"]["schema"] == { + "$ref": "#/components/schemas/ConsoleProxyError" + } + assert responses["502"]["content"]["application/json"]["schema"] == { + "$ref": "#/components/schemas/ConsoleProxyError" + } + assert filtered["components"]["schemas"]["ConsoleProxyError"]["required"] == ["code", "message", "status"] + + +def test_console_operation_registry_matches_contract() -> None: + validate_declarations( + console_registry_document(), tuple(_contract_declaration(operation) for operation in KNOWLEDGE_FS_CONSOLE_OPERATIONS), ) +def test_generated_contract_metadata_matches_current_pin_and_registry() -> None: + metadata = ( + contract_validator.WORKSPACE_ROOT / "packages/contracts/generated/knowledge-fs/metadata.gen.ts" + ).read_text() + lock = json.loads(contract_validator.LOCK_PATH.read_text()) + + assert _metadata_string(metadata, "knowledgeFsSourceOpenapiSha256") == lock["openapiSha256"] + assert _metadata_string( + metadata, + "knowledgeFsConsoleDeclarationsSha256", + ) == contract_validator.contract_declarations_sha256(contract_validator.console_contract_declarations()) + + +def _metadata_string(source: str, export_name: str) -> str: + match = re.search(rf"export const {export_name}\s*=\s*'([0-9a-f]{{64}})'", source) + assert match is not None, f"missing generated metadata export: {export_name}" + return match.group(1) + + def console_registry_document() -> dict[str, object]: - list_route = operation("knowledge-spaces:read", "listKnowledgeSpaces") - create_route = operation("knowledge-spaces:write", "createKnowledgeSpace") - for route in (list_route, create_route): - route["parameters"] = [{"in": "header", "name": "X-Trace-Id"}] - route["responses"] = { - "200": { - "content": {"application/json": {}}, - "headers": {"X-Trace-Id": {}}, - } - } - return {"paths": {"/knowledge-spaces": {"get": list_route, "post": create_route}}} + paths: dict[str, dict[str, object]] = {} + for console_operation in KNOWLEDGE_FS_CONSOLE_OPERATIONS: + route = operation( + console_operation.required_scope, + console_operation.operation_id, + parameters=[{"in": "header", "name": name} for name in console_operation.request_headers], + responses={ + "200": { + "content": {media_type: {} for media_type in console_operation.response_media_types}, + "headers": {name: {} for name in console_operation.response_headers}, + } + }, + ) + route["x-knowledge-fs-max-response-bytes"] = console_operation.max_response_bytes + paths.setdefault(f"/{console_operation.path}", {})[console_operation.method.lower()] = route + return {"paths": paths} @pytest.mark.parametrize( @@ -377,6 +446,7 @@ def declaration(**overrides: object) -> ContractDeclaration: "request_headers": (), "response_headers": (), "response_media_types": ("application/json",), + "error_status_map": ((401, 502), (403, 403)), } value.update(overrides) return cast(ContractDeclaration, value) @@ -393,6 +463,7 @@ def _contract_declaration(operation: KnowledgeFSOperation) -> ContractDeclaratio "request_headers": operation.request_headers, "response_headers": operation.response_headers, "response_media_types": operation.response_media_types, + "error_status_map": operation.error_status_map, } diff --git a/api/tests/unit_tests/services/test_knowledge_fs_proxy.py b/api/tests/unit_tests/services/test_knowledge_fs_proxy.py index 8ffc18d0eef..1033c76f13d 100644 --- a/api/tests/unit_tests/services/test_knowledge_fs_proxy.py +++ b/api/tests/unit_tests/services/test_knowledge_fs_proxy.py @@ -10,16 +10,21 @@ from pydantic import SecretStr from core.helper import ssrf_proxy from core.rbac import RBACPermission from core.tools.errors import ToolSSRFError -from services.knowledge_fs_proxy import ( +from services.knowledge_fs_operations import ( KNOWLEDGE_FS_CONSOLE_OPERATIONS, - KnowledgeFSAccessDeniedError, - KnowledgeFSConfigurationError, KnowledgeFSMethod, + KnowledgeFSOperation, +) +from services.knowledge_fs_proxy import ( + KnowledgeFSAccessDeniedError, + KnowledgeFSAuthorization, + KnowledgeFSConfigurationError, KnowledgeFSRouteNotAllowedError, KnowledgeFSTimeoutError, KnowledgeFSTransportError, authorize_knowledge_fs_request, get_knowledge_fs_operation, + proxy_authorized_knowledge_fs_request, proxy_knowledge_fs_request, ) from services.knowledge_fs_proxy import ( @@ -28,16 +33,178 @@ from services.knowledge_fs_proxy import ( _JWT_SECRET = "production-secret-with-at-least-32-bytes" +_HAPPY_PATH_OPERATION_IDS = ( + "listKnowledgeSpaces", + "createKnowledgeSpace", + "getKnowledgeSpacesById", + "getKnowledgeSpacesByIdAccessPolicy", + "patchKnowledgeSpacesByIdAccessPolicy", + "getSourceProviders", + "getKnowledgeSpacesByIdSourceConnections", + "postKnowledgeSpacesByIdSourceConnections", + "postKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefresh", + "getKnowledgeSpacesByIdSources", + "postKnowledgeSpacesByIdSources", + "postKnowledgeSpacesByIdSourcesBySourceIdCrawlPreview", + "getKnowledgeSpacesByIdSourceWorkflowsByRunId", + "getKnowledgeSpacesByIdSourceWorkflowsByRunIdPages", + "postKnowledgeSpacesByIdSourceWorkflowsByRunIdCancel", + "postKnowledgeSpacesByIdSourceWorkflowsByRunIdRetry", + "postKnowledgeSpacesByIdSourceWorkflowsByRunIdSelection", + "getKnowledgeSpacesByIdSourcesBySourceIdSyncPolicy", + "putKnowledgeSpacesByIdSourcesBySourceIdSyncPolicy", + "getKnowledgeSpacesByIdLogicalDocuments", + "getKnowledgeSpacesByIdLogicalDocumentsByDocumentId", + "getKnowledgeSpacesByIdDocumentsByDocumentIdRevisions", + "getKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunks", + "getKnowledgeSpacesByIdProcessingTasks", + "getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEvents", + "deleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskId", + "postKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetry", +) + +_REQUIRED_EXPANDED_HAPPY_PATH_OPERATION_IDS = { + "patchKnowledgeSpacesById", + "deleteKnowledgeSpacesById", + "getKnowledgeSpacesByIdStats", + "postKnowledgeSpacesByIdSourceConnectionsOauth", + "postSourceOauthCallback", + "getKnowledgeSpacesByIdSourceConnectionsByConnectionId", + "deleteKnowledgeSpacesByIdSourceConnectionsByConnectionId", + "getKnowledgeSpacesByIdSourcesBySourceId", + "patchKnowledgeSpacesByIdSourcesBySourceId", + "deleteKnowledgeSpacesByIdSourcesBySourceId", + "putKnowledgeSpacesByIdSourcesBySourceIdCredentials", + "deleteKnowledgeSpacesByIdSourcesBySourceIdCredentials", + "postKnowledgeSpacesByIdSourcesBySourceIdSync", + "postKnowledgeSpacesByIdSourcesBySourceIdWorkflowImports", + "getKnowledgeSpacesByIdSourcesBySourceIdPages", + "getKnowledgeSpacesByIdSourcesBySourceIdFiles", + "postKnowledgeSpacesByIdSourcesBySourceIdCrawl", + "postKnowledgeSpacesByIdSourcesBySourceIdImport", + "postKnowledgeSpacesByIdSourcesBySourceIdTest", + "postKnowledgeSpacesByIdSourcesBySourceIdImportFiles", + "postKnowledgeSpacesByIdSourcesBulk", + "getKnowledgeSpacesByIdSourceWorkflows", + "getKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItems", + "getKnowledgeSpacesByIdDocuments", + "postKnowledgeSpacesByIdDocuments", + "deleteKnowledgeSpacesByIdDocumentsBulk", + "postKnowledgeSpacesByIdDocumentsBulk", + "postKnowledgeSpacesByIdDocumentsBulkReindex", + "getKnowledgeSpacesByIdDocumentsByDocumentId", + "deleteKnowledgeSpacesByIdDocumentsByDocumentId", + "deleteKnowledgeSpacesByIdLogicalDocumentsByDocumentId", + "getKnowledgeSpacesByIdDocumentsByDocumentIdOutline", + "postKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollback", + "patchKnowledgeSpacesByIdDocumentsByDocumentIdMetadata", + "getKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkId", + "postKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdState", + "getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasks", + "getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskId", + "getKnowledgeSpacesByIdDocumentsByDocumentIdSettings", + "putKnowledgeSpacesByIdDocumentsByDocumentIdSettings", + "getJobsById", + "deleteJobsById", + "postJobsByIdRetry", + "getDeletionJobsByJobId", + "postDeletionJobsByJobIdRetry", + "getBulkJobsById", +} + +_EXPANDED_EXTERNAL_SOURCE_OPERATION_IDS = { + operation_id + for operation_id in _REQUIRED_EXPANDED_HAPPY_PATH_OPERATION_IDS + if "Source" in operation_id or operation_id == "postSourceOauthCallback" +} + +_OPERATION_AUTHORIZATION_POLICIES = { + "listKnowledgeSpaces": (RBACPermission.DATASET_READONLY, "reader"), + "createKnowledgeSpace": (RBACPermission.DATASET_CREATE_AND_MANAGEMENT, "dataset_editor"), + "getKnowledgeSpacesById": (RBACPermission.DATASET_READONLY, "reader"), + "getKnowledgeSpacesByIdAccessPolicy": (RBACPermission.DATASET_READONLY, "reader"), + "patchKnowledgeSpacesByIdAccessPolicy": (RBACPermission.DATASET_ACCESS_CONFIG, "admin"), + "getSourceProviders": (RBACPermission.DATASET_EXTERNAL_CONNECT, "dataset_editor"), + "getKnowledgeSpacesByIdSourceConnections": (RBACPermission.DATASET_EXTERNAL_CONNECT, "dataset_editor"), + "postKnowledgeSpacesByIdSourceConnections": (RBACPermission.DATASET_EXTERNAL_CONNECT, "dataset_editor"), + "postKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefresh": ( + RBACPermission.DATASET_EXTERNAL_CONNECT, + "dataset_editor", + ), + "getKnowledgeSpacesByIdSources": (RBACPermission.DATASET_READONLY, "reader"), + "postKnowledgeSpacesByIdSources": (RBACPermission.DATASET_EXTERNAL_CONNECT, "dataset_editor"), + "postKnowledgeSpacesByIdSourcesBySourceIdCrawlPreview": ( + RBACPermission.DATASET_EXTERNAL_CONNECT, + "dataset_editor", + ), + "getKnowledgeSpacesByIdSourceWorkflowsByRunId": ( + RBACPermission.DATASET_EXTERNAL_CONNECT, + "dataset_editor", + ), + "getKnowledgeSpacesByIdSourceWorkflowsByRunIdPages": ( + RBACPermission.DATASET_EXTERNAL_CONNECT, + "dataset_editor", + ), + "postKnowledgeSpacesByIdSourceWorkflowsByRunIdCancel": ( + RBACPermission.DATASET_EXTERNAL_CONNECT, + "dataset_editor", + ), + "postKnowledgeSpacesByIdSourceWorkflowsByRunIdRetry": ( + RBACPermission.DATASET_EXTERNAL_CONNECT, + "dataset_editor", + ), + "postKnowledgeSpacesByIdSourceWorkflowsByRunIdSelection": ( + RBACPermission.DATASET_EXTERNAL_CONNECT, + "dataset_editor", + ), + "getKnowledgeSpacesByIdSourcesBySourceIdSyncPolicy": (RBACPermission.DATASET_READONLY, "reader"), + "putKnowledgeSpacesByIdSourcesBySourceIdSyncPolicy": (RBACPermission.DATASET_EDIT, "dataset_editor"), + "getKnowledgeSpacesByIdLogicalDocuments": (RBACPermission.DATASET_READONLY, "reader"), + "getKnowledgeSpacesByIdLogicalDocumentsByDocumentId": (RBACPermission.DATASET_READONLY, "reader"), + "getKnowledgeSpacesByIdDocumentsByDocumentIdRevisions": (RBACPermission.DATASET_READONLY, "reader"), + "getKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunks": ( + RBACPermission.DATASET_READONLY, + "reader", + ), + "getKnowledgeSpacesByIdProcessingTasks": (RBACPermission.DATASET_READONLY, "reader"), + "getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEvents": ( + RBACPermission.DATASET_READONLY, + "reader", + ), + "deleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskId": ( + RBACPermission.DATASET_EDIT, + "dataset_editor", + ), + "postKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetry": ( + RBACPermission.DATASET_EDIT, + "dataset_editor", + ), +} + + +def _materialized_path(operation: KnowledgeFSOperation) -> str: + segments = [] + for segment in operation.path.split("/"): + if segment == "{revision}": + segments.append("1") + elif segment.startswith("{"): + segments.append("00000000-0000-4000-8000-000000000001") + else: + segments.append(segment) + return "/".join(segments) + def _set_config( monkeypatch: pytest.MonkeyPatch, *, base_url: str | None = "http://knowledge-fs.test", + sse_read_timeout_seconds: float = 90.0, timeout_seconds: float = 7.5, jwt_secret: str | None = _JWT_SECRET, ) -> None: values = { "KNOWLEDGE_FS_BASE_URL": base_url, + "KNOWLEDGE_FS_SSE_READ_TIMEOUT_SECONDS": sse_read_timeout_seconds, "KNOWLEDGE_FS_TIMEOUT_SECONDS": timeout_seconds, "KNOWLEDGE_FS_JWT_SECRET": SecretStr(jwt_secret) if jwt_secret is not None else None, } @@ -45,43 +212,68 @@ def _set_config( monkeypatch.setattr(f"services.knowledge_fs_proxy.dify_config.{name}", value, raising=False) -def test_console_registry_starts_with_list_and_create_operations() -> None: - assert tuple(operation.operation_id for operation in KNOWLEDGE_FS_CONSOLE_OPERATIONS) == ( - "listKnowledgeSpaces", - "createKnowledgeSpace", +def _processing_task_events_path() -> str: + operation = next( + operation + for operation in KNOWLEDGE_FS_CONSOLE_OPERATIONS + if operation.operation_id == "getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEvents" + ) + return _materialized_path(operation) + + +def test_console_registry_exposes_only_the_new_rag_happy_path_operations() -> None: + operation_ids = {operation.operation_id for operation in KNOWLEDGE_FS_CONSOLE_OPERATIONS} + + assert operation_ids == set(_HAPPY_PATH_OPERATION_IDS) | _REQUIRED_EXPANDED_HAPPY_PATH_OPERATION_IDS + + +def test_console_registry_exposes_existing_upstream_contracts_needed_by_all_happy_path_pages() -> None: + operation_ids = {operation.operation_id for operation in KNOWLEDGE_FS_CONSOLE_OPERATIONS} + + assert operation_ids >= _REQUIRED_EXPANDED_HAPPY_PATH_OPERATION_IDS + + +def test_console_registry_preserves_explicit_scope_and_authorization_policies() -> None: + for operation in KNOWLEDGE_FS_CONSOLE_OPERATIONS: + is_read = operation.method == "GET" + assert operation.required_scope == f"knowledge-spaces:{'read' if is_read else 'write'}" + expected_policy = _OPERATION_AUTHORIZATION_POLICIES.get(operation.operation_id) + if expected_policy is None and operation.operation_id in _EXPANDED_EXTERNAL_SOURCE_OPERATION_IDS: + expected_policy = (RBACPermission.DATASET_EXTERNAL_CONNECT, "dataset_editor") + if expected_policy is None: + expected_policy = ( + (RBACPermission.DATASET_READONLY, "reader") + if is_read + else (RBACPermission.DATASET_EDIT, "dataset_editor") + ) + assert (operation.rbac_permission, operation.legacy_role) == expected_policy + assert operation.response_headers == ("x-trace-id",) + + +def test_console_registry_preserves_special_transport_contracts() -> None: + crawl_preview = get_knowledge_fs_operation( + "POST", + "knowledge-spaces/00000000-0000-4000-8000-000000000001/sources/" + "00000000-0000-4000-8000-000000000002/crawl-preview", + ) + selection = get_knowledge_fs_operation( + "POST", + "knowledge-spaces/00000000-0000-4000-8000-000000000001/source-workflows/" + "00000000-0000-4000-8000-000000000002/selection", + ) + events = get_knowledge_fs_operation( + "GET", + "knowledge-spaces/00000000-0000-4000-8000-000000000001/documents/" + "00000000-0000-4000-8000-000000000002/processing-tasks/" + "00000000-0000-4000-8000-000000000003/events", ) - -@pytest.mark.parametrize( - ("method", "operation_id", "scope", "permission", "requires_dataset_editor"), - [ - ("GET", "listKnowledgeSpaces", "knowledge-spaces:read", RBACPermission.DATASET_READONLY, False), - ( - "POST", - "createKnowledgeSpace", - "knowledge-spaces:write", - RBACPermission.DATASET_CREATE_AND_MANAGEMENT, - True, - ), - ], -) -def test_console_registry_preserves_contract_and_policy( - method: KnowledgeFSMethod, - operation_id: str, - scope: str, - permission: RBACPermission, - requires_dataset_editor: bool, -) -> None: - operation = get_knowledge_fs_operation(method, "knowledge-spaces") - - assert operation.operation_id == operation_id - assert operation.required_scope == scope - assert operation.rbac_permission == permission - assert operation.requires_dataset_editor is requires_dataset_editor - assert operation.max_response_bytes == 1_048_576 - assert operation.request_headers == ("x-trace-id",) - assert operation.response_headers == ("x-trace-id",) - assert operation.response_media_types == ("application/json",) + assert crawl_preview.request_headers == ("idempotency-key", "x-trace-id") + assert selection.request_headers == ("idempotency-key", "x-trace-id") + assert events.response_kind == "stream" + assert events.max_response_bytes == 67_108_864 + assert events.request_headers == ("last-event-id", "x-trace-id") + assert events.response_media_types == ("text/event-stream",) def test_unconfigured_kfs_is_rejected_before_external_io(monkeypatch: pytest.MonkeyPatch) -> None: @@ -148,7 +340,112 @@ def test_proxy_forwards_only_registry_declared_headers(monkeypatch: pytest.Monke assert forward.call_args.kwargs["request_headers"] == {"x-trace-id": "trace-1"} -def test_authorization_rejects_workspace_rbac_denial(monkeypatch: pytest.MonkeyPatch) -> None: +def test_authorized_proxy_does_not_repeat_workspace_rbac(monkeypatch: pytest.MonkeyPatch) -> None: + account = MagicMock(id="account-1", is_dataset_editor=True) + check_access = MagicMock(return_value=True) + forward = MagicMock(return_value=MagicMock()) + monkeypatch.setattr("services.knowledge_fs_proxy.RBACService.CheckAccess.check", check_access) + monkeypatch.setattr("services.knowledge_fs_proxy._forward_knowledge_fs_request", forward) + operation = get_knowledge_fs_operation("POST", "knowledge-spaces") + authorization = authorize_knowledge_fs_request( + account=account, + tenant_id="tenant-1", + method=operation.method, + path=_materialized_path(operation), + ) + + proxy_authorized_knowledge_fs_request(authorization=authorization) + + check_access.assert_called_once() + assert forward.call_args.kwargs["account_id"] == "account-1" + assert forward.call_args.kwargs["tenant_id"] == "tenant-1" + assert forward.call_args.kwargs["method"] == "POST" + assert forward.call_args.kwargs["path"] == "knowledge-spaces" + + +def test_authorization_capability_cannot_be_constructed_directly() -> None: + operation = get_knowledge_fs_operation("POST", "knowledge-spaces") + + with pytest.raises(KnowledgeFSAccessDeniedError, match="must be created by workspace authorization"): + KnowledgeFSAuthorization("account-1", "tenant-1", operation) + + +def test_authorization_resolves_the_canonical_operation_policy(monkeypatch: pytest.MonkeyPatch) -> None: + account = MagicMock(id="account-1", is_dataset_editor=False, is_admin_or_owner=False) + check_access = MagicMock(return_value=True) + monkeypatch.setattr("services.knowledge_fs_proxy.RBACService.CheckAccess.check", check_access) + + with pytest.raises(KnowledgeFSAccessDeniedError, match="dataset edit access"): + authorize_knowledge_fs_request( + account=account, + tenant_id="tenant-1", + method="POST", + path="knowledge-spaces", + ) + + check_access.assert_not_called() + + +@pytest.mark.parametrize( + ("attribute", "value"), + [ + ("account_id", "account-2"), + ("tenant_id", "tenant-2"), + ("operation", get_knowledge_fs_operation("GET", "knowledge-spaces")), + ], +) +def test_authorization_capability_binding_cannot_be_mutated( + monkeypatch: pytest.MonkeyPatch, + attribute: str, + value: object, +) -> None: + account = MagicMock(id="account-1", is_dataset_editor=True) + monkeypatch.setattr( + "services.knowledge_fs_proxy.RBACService.CheckAccess.check", + MagicMock(return_value=True), + ) + authorization = authorize_knowledge_fs_request( + account=account, + tenant_id="tenant-1", + method="POST", + path="knowledge-spaces", + ) + + with pytest.raises(AttributeError): + setattr(authorization, attribute, value) + + assert authorization.account_id == "account-1" + assert authorization.tenant_id == "tenant-1" + assert authorization.operation == get_knowledge_fs_operation("POST", "knowledge-spaces") + + +def test_authorization_capability_cannot_be_reused(monkeypatch: pytest.MonkeyPatch) -> None: + account = MagicMock(id="account-1", is_dataset_editor=True) + forward = MagicMock(return_value=MagicMock()) + monkeypatch.setattr( + "services.knowledge_fs_proxy.RBACService.CheckAccess.check", + MagicMock(return_value=True), + ) + monkeypatch.setattr("services.knowledge_fs_proxy._forward_knowledge_fs_request", forward) + authorization = authorize_knowledge_fs_request( + account=account, + tenant_id="tenant-1", + method="POST", + path="knowledge-spaces", + ) + + proxy_authorized_knowledge_fs_request(authorization=authorization) + + with pytest.raises(KnowledgeFSAccessDeniedError, match="already been used"): + proxy_authorized_knowledge_fs_request(authorization=authorization) + forward.assert_called_once() + + +@pytest.mark.parametrize("operation", KNOWLEDGE_FS_CONSOLE_OPERATIONS, ids=lambda operation: operation.operation_id) +def test_authorization_rejects_workspace_rbac_denial( + monkeypatch: pytest.MonkeyPatch, + operation: KnowledgeFSOperation, +) -> None: account = MagicMock(id="account-1", is_dataset_editor=True) check_access = MagicMock(return_value=False) monkeypatch.setattr("services.knowledge_fs_proxy.RBACService.CheckAccess.check", check_access) @@ -157,19 +454,28 @@ def test_authorization_rejects_workspace_rbac_denial(monkeypatch: pytest.MonkeyP authorize_knowledge_fs_request( account=account, tenant_id="tenant-1", - operation=get_knowledge_fs_operation("GET", "knowledge-spaces"), + method=operation.method, + path=_materialized_path(operation), ) check_access.assert_called_once_with( "tenant-1", "account-1", - scene="dataset_readonly", + scene=operation.rbac_permission.value, resource_type="dataset", ) -def test_create_rejects_non_dataset_editor_before_rbac(monkeypatch: pytest.MonkeyPatch) -> None: - account = MagicMock(id="account-1", is_dataset_editor=False) +@pytest.mark.parametrize( + "operation", + tuple(operation for operation in KNOWLEDGE_FS_CONSOLE_OPERATIONS if operation.legacy_role == "dataset_editor"), + ids=lambda operation: operation.operation_id, +) +def test_dataset_editor_operations_reject_legacy_viewers_before_rbac( + monkeypatch: pytest.MonkeyPatch, + operation: KnowledgeFSOperation, +) -> None: + account = MagicMock(id="account-1", is_dataset_editor=False, is_admin_or_owner=False) check_access = MagicMock(return_value=True) monkeypatch.setattr("services.knowledge_fs_proxy.RBACService.CheckAccess.check", check_access) @@ -177,41 +483,66 @@ def test_create_rejects_non_dataset_editor_before_rbac(monkeypatch: pytest.Monke authorize_knowledge_fs_request( account=account, tenant_id="tenant-1", - operation=get_knowledge_fs_operation("POST", "knowledge-spaces"), + method=operation.method, + path=_materialized_path(operation), ) check_access.assert_not_called() -def test_authorization_uses_the_declared_editor_policy(monkeypatch: pytest.MonkeyPatch) -> None: - account = MagicMock(id="account-1", is_dataset_editor=False) +def test_admin_operation_rejects_legacy_editors_before_rbac(monkeypatch: pytest.MonkeyPatch) -> None: + account = MagicMock(id="account-1", is_dataset_editor=True, is_admin_or_owner=False) check_access = MagicMock(return_value=True) monkeypatch.setattr("services.knowledge_fs_proxy.RBACService.CheckAccess.check", check_access) - operation = get_knowledge_fs_operation("POST", "knowledge-spaces")._replace(requires_dataset_editor=False) + operation = get_knowledge_fs_operation( + "PATCH", "knowledge-spaces/00000000-0000-4000-8000-000000000001/access-policy" + ) - authorize_knowledge_fs_request(account=account, tenant_id="tenant-1", operation=operation) + with pytest.raises(KnowledgeFSAccessDeniedError, match="administration access"): + authorize_knowledge_fs_request( + account=account, + tenant_id="tenant-1", + method=operation.method, + path=_materialized_path(operation), + ) + + check_access.assert_not_called() + + +def test_authorization_uses_the_declared_reader_policy(monkeypatch: pytest.MonkeyPatch) -> None: + account = MagicMock(id="account-1", is_dataset_editor=False, is_admin_or_owner=False) + check_access = MagicMock(return_value=True) + monkeypatch.setattr("services.knowledge_fs_proxy.RBACService.CheckAccess.check", check_access) + operation = get_knowledge_fs_operation("GET", "knowledge-spaces") + + authorize_knowledge_fs_request( + account=account, + tenant_id="tenant-1", + method=operation.method, + path=_materialized_path(operation), + ) check_access.assert_called_once() -@pytest.mark.parametrize( - ("method", "expected_scope"), - [("GET", "knowledge-spaces:read"), ("POST", "knowledge-spaces:write")], -) +@pytest.mark.parametrize("operation", KNOWLEDGE_FS_CONSOLE_OPERATIONS, ids=lambda operation: operation.operation_id) def test_auth_signs_current_principals_and_declared_scope( monkeypatch: pytest.MonkeyPatch, - method: KnowledgeFSMethod, - expected_scope: str, + operation: KnowledgeFSOperation, ) -> None: _set_config(monkeypatch) - response = httpx.Response(200, content=b'{"items":[]}', headers={"Content-Type": "application/json"}) + response = httpx.Response( + 200, + content=b"data" if operation.response_kind == "stream" else b'{"items":[]}', + headers={"Content-Type": operation.response_media_types[0]}, + ) request = MagicMock(return_value=response) monkeypatch.setattr("services.knowledge_fs_proxy.ssrf_proxy.make_request", request) forward_knowledge_fs_request( account_id="account-1", - method=method, - path="knowledge-spaces", + method=operation.method, + path=_materialized_path(operation), tenant_id="tenant-1", ) @@ -226,7 +557,7 @@ def test_auth_signs_current_principals_and_declared_scope( assert claims["dify_account_id"] == "dify-account:account-1" assert claims["sub"] == "dify-workspace:tenant-1" assert claims["tenant_id"] == "tenant-1" - assert claims["scopes"] == [expected_scope] + assert claims["scopes"] == [operation.required_scope] assert claims["caller_kind"] == "interactive" assert claims["exp"] - claims["iat"] == 60 @@ -244,6 +575,69 @@ def test_buffered_response_rejects_non_empty_body_without_content_type(monkeypat assert response.is_closed +def test_sse_response_remains_streaming_and_uses_the_dedicated_read_timeout( + monkeypatch: pytest.MonkeyPatch, +) -> None: + _set_config(monkeypatch, sse_read_timeout_seconds=120.0) + request = httpx.Request( + "GET", + "http://knowledge-fs.test/events", + extensions={"timeout": {"connect": 7.5, "read": 7.5}}, + ) + response = httpx.Response( + 200, + headers={"Content-Type": "text/event-stream"}, + request=request, + stream=httpx.ByteStream(b"event: progress\n\n"), + ) + monkeypatch.setattr("services.knowledge_fs_proxy.ssrf_proxy.make_request", MagicMock(return_value=response)) + buffer_response = MagicMock() + monkeypatch.setattr("services.knowledge_fs_proxy.ssrf_proxy.buffer_response", buffer_response) + + result = forward_knowledge_fs_request( + account_id="account-dev", + method="GET", + path=_processing_task_events_path(), + tenant_id="tenant-dev", + ) + + assert result.response is response + assert result.response_kind == "stream" + assert request.extensions["timeout"]["read"] == 120.0 + assert not response.is_closed + buffer_response.assert_not_called() + + +@pytest.mark.parametrize( + ("headers", "message"), + [ + ({"Content-Type": "application/json"}, "unsupported media type"), + ( + {"Content-Type": "text/event-stream", "Content-Encoding": "gzip"}, + "unsupported encoding", + ), + ], +) +def test_sse_response_rejects_invalid_stream_headers_and_closes_upstream( + monkeypatch: pytest.MonkeyPatch, + headers: dict[str, str], + message: str, +) -> None: + _set_config(monkeypatch) + response = httpx.Response(200, headers=headers, stream=httpx.ByteStream(b"data")) + monkeypatch.setattr("services.knowledge_fs_proxy.ssrf_proxy.make_request", MagicMock(return_value=response)) + + with pytest.raises(KnowledgeFSTransportError, match=message): + forward_knowledge_fs_request( + account_id="account-dev", + method="GET", + path=_processing_task_events_path(), + tenant_id="tenant-dev", + ) + + assert response.is_closed + + @pytest.mark.parametrize( ("error", "expected_exception"), [ @@ -277,10 +671,10 @@ def test_transport_failures_are_normalized( ("method", "path"), [ ("GET", "openapi.json"), - ("GET", "knowledge-spaces/space-1"), + ("GET", "knowledge-spaces/space-1/manifest"), ("PATCH", "knowledge-spaces"), ("POST", "queries"), - ("POST", "knowledge-spaces/space-1/documents"), + ("POST", "knowledge-spaces/space-1/uploads"), ], ) def test_unregistered_route_is_rejected_before_external_io( diff --git a/packages/contracts/generated/knowledge-fs/metadata.gen.ts b/packages/contracts/generated/knowledge-fs/metadata.gen.ts new file mode 100644 index 00000000000..ecbe25e5b49 --- /dev/null +++ b/packages/contracts/generated/knowledge-fs/metadata.gen.ts @@ -0,0 +1,12 @@ +// This file is auto-generated by scripts/generate-knowledge-fs-contract.mjs. +// Do not edit it manually. + +export const knowledgeFsSourceOpenapiSha256 = + 'f18910e9c45a64f0855e0643a7a626fb2889021b4f943458de86c6bd2469facb' +export const knowledgeFsConsoleDeclarationsSha256 = + '8bd1924747fdd0d478ca085817cbe000eb7e8630b2c6a03f4f13a6a0fac07946' +export const knowledgeFsGeneratedArtifactSha256 = { + 'orpc.gen.ts': 'e0d9954f817e97a4e95dd38c4522fb403c8659d741ce485fa671b1b4ce90a540', + 'types.gen.ts': 'a558ab80f32a8555bb5b44b7a596ef4a4a7a8cb7904390993aabcc587915f530', + 'zod.gen.ts': '6aa3d3e768fe0008ca405ecbe423ee325bd8f65f745dd2d1c86f2bdb887a97fd', +} as const diff --git a/packages/contracts/generated/knowledge-fs/orpc.gen.ts b/packages/contracts/generated/knowledge-fs/orpc.gen.ts index ac9a0c47f88..97816509fc2 100644 --- a/packages/contracts/generated/knowledge-fs/orpc.gen.ts +++ b/packages/contracts/generated/knowledge-fs/orpc.gen.ts @@ -1,14 +1,270 @@ // This file is auto-generated by @hey-api/openapi-ts -import { oc } from '@orpc/contract' +import { eventIterator, oc } from '@orpc/contract' import * as z from 'zod' import { zCreateKnowledgeSpaceBody, zCreateKnowledgeSpaceHeaders, zCreateKnowledgeSpaceResponse, + zDeleteJobsByIdHeaders, + zDeleteJobsByIdPath, + zDeleteJobsByIdResponse, + zDeleteKnowledgeSpacesByIdBody, + zDeleteKnowledgeSpacesByIdDocumentsBulkBody, + zDeleteKnowledgeSpacesByIdDocumentsBulkHeaders, + zDeleteKnowledgeSpacesByIdDocumentsBulkPath, + zDeleteKnowledgeSpacesByIdDocumentsBulkResponse, + zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdBody, + zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdHeaders, + zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdPath, + zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdHeaders, + zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdPath, + zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponse, + zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdResponse, + zDeleteKnowledgeSpacesByIdHeaders, + zDeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdBody, + zDeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdHeaders, + zDeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdPath, + zDeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponse, + zDeleteKnowledgeSpacesByIdPath, + zDeleteKnowledgeSpacesByIdResponse, + zDeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdHeaders, + zDeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdPath, + zDeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdQuery, + zDeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponse, + zDeleteKnowledgeSpacesByIdSourcesBySourceIdBody, + zDeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsHeaders, + zDeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsPath, + zDeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsQuery, + zDeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponse, + zDeleteKnowledgeSpacesByIdSourcesBySourceIdHeaders, + zDeleteKnowledgeSpacesByIdSourcesBySourceIdPath, + zDeleteKnowledgeSpacesByIdSourcesBySourceIdQuery, + zDeleteKnowledgeSpacesByIdSourcesBySourceIdResponse, + zGetBulkJobsByIdHeaders, + zGetBulkJobsByIdPath, + zGetBulkJobsByIdResponse, + zGetDeletionJobsByJobIdHeaders, + zGetDeletionJobsByJobIdPath, + zGetDeletionJobsByJobIdResponse, + zGetJobsByIdHeaders, + zGetJobsByIdPath, + zGetJobsByIdResponse, + zGetKnowledgeSpacesByIdAccessPolicyHeaders, + zGetKnowledgeSpacesByIdAccessPolicyPath, + zGetKnowledgeSpacesByIdAccessPolicyResponse, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdHeaders, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineHeaders, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdOutlinePath, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineResponse, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdPath, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsHeaders, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsPath, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsResponse, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdHeaders, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdPath, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponse, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksHeaders, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksPath, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksQuery, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksResponse, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdResponse, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdHeaders, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdPath, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdResponse, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksHeaders, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksPath, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksQuery, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksResponse, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsHeaders, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsPath, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsQuery, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsResponse, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsHeaders, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsPath, + zGetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponse, + zGetKnowledgeSpacesByIdDocumentsHeaders, + zGetKnowledgeSpacesByIdDocumentsPath, + zGetKnowledgeSpacesByIdDocumentsQuery, + zGetKnowledgeSpacesByIdDocumentsResponse, + zGetKnowledgeSpacesByIdHeaders, + zGetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdHeaders, + zGetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdPath, + zGetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponse, + zGetKnowledgeSpacesByIdLogicalDocumentsHeaders, + zGetKnowledgeSpacesByIdLogicalDocumentsPath, + zGetKnowledgeSpacesByIdLogicalDocumentsQuery, + zGetKnowledgeSpacesByIdLogicalDocumentsResponse, + zGetKnowledgeSpacesByIdPath, + zGetKnowledgeSpacesByIdProcessingTasksHeaders, + zGetKnowledgeSpacesByIdProcessingTasksPath, + zGetKnowledgeSpacesByIdProcessingTasksQuery, + zGetKnowledgeSpacesByIdProcessingTasksResponse, + zGetKnowledgeSpacesByIdResponse, + zGetKnowledgeSpacesByIdSourceConnectionsByConnectionIdHeaders, + zGetKnowledgeSpacesByIdSourceConnectionsByConnectionIdPath, + zGetKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponse, + zGetKnowledgeSpacesByIdSourceConnectionsHeaders, + zGetKnowledgeSpacesByIdSourceConnectionsPath, + zGetKnowledgeSpacesByIdSourceConnectionsQuery, + zGetKnowledgeSpacesByIdSourceConnectionsResponse, + zGetKnowledgeSpacesByIdSourcesBySourceIdFilesHeaders, + zGetKnowledgeSpacesByIdSourcesBySourceIdFilesPath, + zGetKnowledgeSpacesByIdSourcesBySourceIdFilesQuery, + zGetKnowledgeSpacesByIdSourcesBySourceIdFilesResponse, + zGetKnowledgeSpacesByIdSourcesBySourceIdHeaders, + zGetKnowledgeSpacesByIdSourcesBySourceIdPagesHeaders, + zGetKnowledgeSpacesByIdSourcesBySourceIdPagesPath, + zGetKnowledgeSpacesByIdSourcesBySourceIdPagesQuery, + zGetKnowledgeSpacesByIdSourcesBySourceIdPagesResponse, + zGetKnowledgeSpacesByIdSourcesBySourceIdPath, + zGetKnowledgeSpacesByIdSourcesBySourceIdResponse, + zGetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyHeaders, + zGetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyPath, + zGetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponse, + zGetKnowledgeSpacesByIdSourcesHeaders, + zGetKnowledgeSpacesByIdSourcesPath, + zGetKnowledgeSpacesByIdSourcesQuery, + zGetKnowledgeSpacesByIdSourcesResponse, + zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsHeaders, + zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsPath, + zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsQuery, + zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsResponse, + zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdHeaders, + zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesHeaders, + zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesPath, + zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesQuery, + zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesResponse, + zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPath, + zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdResponse, + zGetKnowledgeSpacesByIdSourceWorkflowsHeaders, + zGetKnowledgeSpacesByIdSourceWorkflowsPath, + zGetKnowledgeSpacesByIdSourceWorkflowsQuery, + zGetKnowledgeSpacesByIdSourceWorkflowsResponse, + zGetKnowledgeSpacesByIdStatsHeaders, + zGetKnowledgeSpacesByIdStatsPath, + zGetKnowledgeSpacesByIdStatsQuery, + zGetKnowledgeSpacesByIdStatsResponse, + zGetSourceProvidersHeaders, + zGetSourceProvidersResponse, zListKnowledgeSpacesHeaders, zListKnowledgeSpacesQuery, zListKnowledgeSpacesResponse, + zPatchKnowledgeSpacesByIdAccessPolicyBody, + zPatchKnowledgeSpacesByIdAccessPolicyHeaders, + zPatchKnowledgeSpacesByIdAccessPolicyPath, + zPatchKnowledgeSpacesByIdAccessPolicyResponse, + zPatchKnowledgeSpacesByIdBody, + zPatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataBody, + zPatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataHeaders, + zPatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataPath, + zPatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataResponse, + zPatchKnowledgeSpacesByIdHeaders, + zPatchKnowledgeSpacesByIdPath, + zPatchKnowledgeSpacesByIdResponse, + zPatchKnowledgeSpacesByIdSourcesBySourceIdBody, + zPatchKnowledgeSpacesByIdSourcesBySourceIdHeaders, + zPatchKnowledgeSpacesByIdSourcesBySourceIdPath, + zPatchKnowledgeSpacesByIdSourcesBySourceIdResponse, + zPostDeletionJobsByJobIdRetryHeaders, + zPostDeletionJobsByJobIdRetryPath, + zPostDeletionJobsByJobIdRetryResponse, + zPostJobsByIdRetryHeaders, + zPostJobsByIdRetryPath, + zPostJobsByIdRetryResponse, + zPostKnowledgeSpacesByIdDocumentsBody, + zPostKnowledgeSpacesByIdDocumentsBulkBody, + zPostKnowledgeSpacesByIdDocumentsBulkHeaders, + zPostKnowledgeSpacesByIdDocumentsBulkPath, + zPostKnowledgeSpacesByIdDocumentsBulkReindexBody, + zPostKnowledgeSpacesByIdDocumentsBulkReindexHeaders, + zPostKnowledgeSpacesByIdDocumentsBulkReindexPath, + zPostKnowledgeSpacesByIdDocumentsBulkReindexResponse, + zPostKnowledgeSpacesByIdDocumentsBulkResponse, + zPostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryHeaders, + zPostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryPath, + zPostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryResponse, + zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateBody, + zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateHeaders, + zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStatePath, + zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateResponse, + zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackBody, + zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackHeaders, + zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackPath, + zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackResponse, + zPostKnowledgeSpacesByIdDocumentsHeaders, + zPostKnowledgeSpacesByIdDocumentsPath, + zPostKnowledgeSpacesByIdDocumentsResponse, + zPostKnowledgeSpacesByIdSourceConnectionsBody, + zPostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshBody, + zPostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshHeaders, + zPostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshPath, + zPostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshResponse, + zPostKnowledgeSpacesByIdSourceConnectionsHeaders, + zPostKnowledgeSpacesByIdSourceConnectionsOauthBody, + zPostKnowledgeSpacesByIdSourceConnectionsOauthHeaders, + zPostKnowledgeSpacesByIdSourceConnectionsOauthPath, + zPostKnowledgeSpacesByIdSourceConnectionsOauthResponse, + zPostKnowledgeSpacesByIdSourceConnectionsPath, + zPostKnowledgeSpacesByIdSourceConnectionsResponse, + zPostKnowledgeSpacesByIdSourcesBody, + zPostKnowledgeSpacesByIdSourcesBulkBody, + zPostKnowledgeSpacesByIdSourcesBulkHeaders, + zPostKnowledgeSpacesByIdSourcesBulkPath, + zPostKnowledgeSpacesByIdSourcesBulkResponse, + zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlHeaders, + zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlPath, + zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewHeaders, + zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewPath, + zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewResponse, + zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlResponse, + zPostKnowledgeSpacesByIdSourcesBySourceIdImportBody, + zPostKnowledgeSpacesByIdSourcesBySourceIdImportFilesBody, + zPostKnowledgeSpacesByIdSourcesBySourceIdImportFilesHeaders, + zPostKnowledgeSpacesByIdSourcesBySourceIdImportFilesPath, + zPostKnowledgeSpacesByIdSourcesBySourceIdImportFilesResponse, + zPostKnowledgeSpacesByIdSourcesBySourceIdImportHeaders, + zPostKnowledgeSpacesByIdSourcesBySourceIdImportPath, + zPostKnowledgeSpacesByIdSourcesBySourceIdImportResponse, + zPostKnowledgeSpacesByIdSourcesBySourceIdSyncHeaders, + zPostKnowledgeSpacesByIdSourcesBySourceIdSyncPath, + zPostKnowledgeSpacesByIdSourcesBySourceIdSyncResponse, + zPostKnowledgeSpacesByIdSourcesBySourceIdTestHeaders, + zPostKnowledgeSpacesByIdSourcesBySourceIdTestPath, + zPostKnowledgeSpacesByIdSourcesBySourceIdTestResponse, + zPostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsBody, + zPostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsHeaders, + zPostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsPath, + zPostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsResponse, + zPostKnowledgeSpacesByIdSourcesHeaders, + zPostKnowledgeSpacesByIdSourcesPath, + zPostKnowledgeSpacesByIdSourcesResponse, + zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelBody, + zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelHeaders, + zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelPath, + zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelResponse, + zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryHeaders, + zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryPath, + zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryResponse, + zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionBody, + zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionHeaders, + zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionPath, + zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionResponse, + zPostSourceOauthCallbackBody, + zPostSourceOauthCallbackHeaders, + zPostSourceOauthCallbackResponse, + zPutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsBody, + zPutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsHeaders, + zPutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsPath, + zPutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponse, + zPutKnowledgeSpacesByIdSourcesBySourceIdCredentialsBody, + zPutKnowledgeSpacesByIdSourcesBySourceIdCredentialsHeaders, + zPutKnowledgeSpacesByIdSourcesBySourceIdCredentialsPath, + zPutKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponse, + zPutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyBody, + zPutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyHeaders, + zPutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyPath, + zPutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponse, } from './zod.gen' export const listKnowledgeSpaces = oc @@ -41,7 +297,1272 @@ export const createKnowledgeSpace = oc ) .output(zCreateKnowledgeSpaceResponse) +export const deleteKnowledgeSpacesById = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteKnowledgeSpacesById', + path: '/knowledge-fs/knowledge-spaces/{id}', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zDeleteKnowledgeSpacesByIdBody, + headers: zDeleteKnowledgeSpacesByIdHeaders, + params: zDeleteKnowledgeSpacesByIdPath, + }), + ) + .output(zDeleteKnowledgeSpacesByIdResponse) + +export const getKnowledgeSpacesById = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesById', + path: '/knowledge-fs/knowledge-spaces/{id}', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdHeaders.optional(), + params: zGetKnowledgeSpacesByIdPath, + }), + ) + .output(zGetKnowledgeSpacesByIdResponse) + +export const patchKnowledgeSpacesById = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchKnowledgeSpacesById', + path: '/knowledge-fs/knowledge-spaces/{id}', + tags: ['default'], + }) + .input( + z.object({ + body: zPatchKnowledgeSpacesByIdBody, + headers: zPatchKnowledgeSpacesByIdHeaders.optional(), + params: zPatchKnowledgeSpacesByIdPath, + }), + ) + .output(zPatchKnowledgeSpacesByIdResponse) + +export const getKnowledgeSpacesByIdStats = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdStats', + path: '/knowledge-fs/knowledge-spaces/{id}/stats', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdStatsHeaders.optional(), + params: zGetKnowledgeSpacesByIdStatsPath, + query: zGetKnowledgeSpacesByIdStatsQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdStatsResponse) + +export const getKnowledgeSpacesByIdAccessPolicy = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdAccessPolicy', + path: '/knowledge-fs/knowledge-spaces/{id}/access-policy', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdAccessPolicyHeaders.optional(), + params: zGetKnowledgeSpacesByIdAccessPolicyPath, + }), + ) + .output(zGetKnowledgeSpacesByIdAccessPolicyResponse) + +export const patchKnowledgeSpacesByIdAccessPolicy = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchKnowledgeSpacesByIdAccessPolicy', + path: '/knowledge-fs/knowledge-spaces/{id}/access-policy', + tags: ['default'], + }) + .input( + z.object({ + body: zPatchKnowledgeSpacesByIdAccessPolicyBody, + headers: zPatchKnowledgeSpacesByIdAccessPolicyHeaders.optional(), + params: zPatchKnowledgeSpacesByIdAccessPolicyPath, + }), + ) + .output(zPatchKnowledgeSpacesByIdAccessPolicyResponse) + +export const getSourceProviders = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getSourceProviders', + path: '/knowledge-fs/source-providers', + tags: ['default'], + }) + .input(z.object({ headers: zGetSourceProvidersHeaders.optional() })) + .output(zGetSourceProvidersResponse) + +export const getKnowledgeSpacesByIdSourceConnections = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdSourceConnections', + path: '/knowledge-fs/knowledge-spaces/{id}/source-connections', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdSourceConnectionsHeaders.optional(), + params: zGetKnowledgeSpacesByIdSourceConnectionsPath, + query: zGetKnowledgeSpacesByIdSourceConnectionsQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdSourceConnectionsResponse) + +export const postKnowledgeSpacesByIdSourceConnections = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourceConnections', + path: '/knowledge-fs/knowledge-spaces/{id}/source-connections', + successStatus: 201, + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdSourceConnectionsBody, + headers: zPostKnowledgeSpacesByIdSourceConnectionsHeaders.optional(), + params: zPostKnowledgeSpacesByIdSourceConnectionsPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourceConnectionsResponse) + +export const postKnowledgeSpacesByIdSourceConnectionsOauth = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourceConnectionsOauth', + path: '/knowledge-fs/knowledge-spaces/{id}/source-connections/oauth', + successStatus: 201, + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdSourceConnectionsOauthBody, + headers: zPostKnowledgeSpacesByIdSourceConnectionsOauthHeaders.optional(), + params: zPostKnowledgeSpacesByIdSourceConnectionsOauthPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourceConnectionsOauthResponse) + +export const postSourceOauthCallback = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postSourceOauthCallback', + path: '/knowledge-fs/source-oauth/callback', + tags: ['default'], + }) + .input( + z.object({ + body: zPostSourceOauthCallbackBody, + headers: zPostSourceOauthCallbackHeaders.optional(), + }), + ) + .output(zPostSourceOauthCallbackResponse) + +export const deleteKnowledgeSpacesByIdSourceConnectionsByConnectionId = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteKnowledgeSpacesByIdSourceConnectionsByConnectionId', + path: '/knowledge-fs/knowledge-spaces/{id}/source-connections/{connectionId}', + tags: ['default'], + }) + .input( + z.object({ + headers: zDeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdHeaders.optional(), + params: zDeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdPath, + query: zDeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdQuery, + }), + ) + .output(zDeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponse) + +export const getKnowledgeSpacesByIdSourceConnectionsByConnectionId = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdSourceConnectionsByConnectionId', + path: '/knowledge-fs/knowledge-spaces/{id}/source-connections/{connectionId}', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdSourceConnectionsByConnectionIdHeaders.optional(), + params: zGetKnowledgeSpacesByIdSourceConnectionsByConnectionIdPath, + }), + ) + .output(zGetKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponse) + +export const postKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefresh = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefresh', + path: '/knowledge-fs/knowledge-spaces/{id}/source-connections/{connectionId}/refresh', + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshBody, + headers: zPostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshHeaders.optional(), + params: zPostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshResponse) + +export const getKnowledgeSpacesByIdSources = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdSources', + path: '/knowledge-fs/knowledge-spaces/{id}/sources', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdSourcesHeaders.optional(), + params: zGetKnowledgeSpacesByIdSourcesPath, + query: zGetKnowledgeSpacesByIdSourcesQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdSourcesResponse) + +export const postKnowledgeSpacesByIdSources = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSources', + path: '/knowledge-fs/knowledge-spaces/{id}/sources', + successStatus: 201, + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdSourcesBody, + headers: zPostKnowledgeSpacesByIdSourcesHeaders.optional(), + params: zPostKnowledgeSpacesByIdSourcesPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourcesResponse) + +export const deleteKnowledgeSpacesByIdSourcesBySourceId = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteKnowledgeSpacesByIdSourcesBySourceId', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zDeleteKnowledgeSpacesByIdSourcesBySourceIdBody, + headers: zDeleteKnowledgeSpacesByIdSourcesBySourceIdHeaders, + params: zDeleteKnowledgeSpacesByIdSourcesBySourceIdPath, + query: zDeleteKnowledgeSpacesByIdSourcesBySourceIdQuery.optional(), + }), + ) + .output(zDeleteKnowledgeSpacesByIdSourcesBySourceIdResponse) + +export const getKnowledgeSpacesByIdSourcesBySourceId = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdSourcesBySourceId', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdSourcesBySourceIdHeaders.optional(), + params: zGetKnowledgeSpacesByIdSourcesBySourceIdPath, + }), + ) + .output(zGetKnowledgeSpacesByIdSourcesBySourceIdResponse) + +export const patchKnowledgeSpacesByIdSourcesBySourceId = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchKnowledgeSpacesByIdSourcesBySourceId', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}', + tags: ['default'], + }) + .input( + z.object({ + body: zPatchKnowledgeSpacesByIdSourcesBySourceIdBody, + headers: zPatchKnowledgeSpacesByIdSourcesBySourceIdHeaders.optional(), + params: zPatchKnowledgeSpacesByIdSourcesBySourceIdPath, + }), + ) + .output(zPatchKnowledgeSpacesByIdSourcesBySourceIdResponse) + +export const deleteKnowledgeSpacesByIdSourcesBySourceIdCredentials = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteKnowledgeSpacesByIdSourcesBySourceIdCredentials', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/credentials', + tags: ['default'], + }) + .input( + z.object({ + headers: zDeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsHeaders.optional(), + params: zDeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsPath, + query: zDeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsQuery, + }), + ) + .output(zDeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponse) + +export const putKnowledgeSpacesByIdSourcesBySourceIdCredentials = oc + .route({ + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putKnowledgeSpacesByIdSourcesBySourceIdCredentials', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/credentials', + tags: ['default'], + }) + .input( + z.object({ + body: zPutKnowledgeSpacesByIdSourcesBySourceIdCredentialsBody, + headers: zPutKnowledgeSpacesByIdSourcesBySourceIdCredentialsHeaders.optional(), + params: zPutKnowledgeSpacesByIdSourcesBySourceIdCredentialsPath, + }), + ) + .output(zPutKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponse) + +export const postKnowledgeSpacesByIdSourcesBySourceIdSync = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourcesBySourceIdSync', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/sync', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + headers: zPostKnowledgeSpacesByIdSourcesBySourceIdSyncHeaders, + params: zPostKnowledgeSpacesByIdSourcesBySourceIdSyncPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourcesBySourceIdSyncResponse) + +export const postKnowledgeSpacesByIdSourcesBySourceIdCrawlPreview = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourcesBySourceIdCrawlPreview', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/crawl-preview', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + headers: zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewHeaders, + params: zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewResponse) + +export const postKnowledgeSpacesByIdSourcesBySourceIdWorkflowImports = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourcesBySourceIdWorkflowImports', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/workflow-imports', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsBody, + headers: zPostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsHeaders, + params: zPostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsResponse) + +export const getKnowledgeSpacesByIdSourcesBySourceIdPages = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdSourcesBySourceIdPages', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/pages', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdSourcesBySourceIdPagesHeaders.optional(), + params: zGetKnowledgeSpacesByIdSourcesBySourceIdPagesPath, + query: zGetKnowledgeSpacesByIdSourcesBySourceIdPagesQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdSourcesBySourceIdPagesResponse) + +export const getKnowledgeSpacesByIdSourcesBySourceIdFiles = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdSourcesBySourceIdFiles', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/files', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdSourcesBySourceIdFilesHeaders.optional(), + params: zGetKnowledgeSpacesByIdSourcesBySourceIdFilesPath, + query: zGetKnowledgeSpacesByIdSourcesBySourceIdFilesQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdSourcesBySourceIdFilesResponse) + +export const postKnowledgeSpacesByIdSourcesBySourceIdCrawl = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourcesBySourceIdCrawl', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/crawl', + tags: ['default'], + }) + .input( + z.object({ + headers: zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlHeaders.optional(), + params: zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlResponse) + +export const postKnowledgeSpacesByIdSourcesBySourceIdImport = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourcesBySourceIdImport', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/import', + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdSourcesBySourceIdImportBody, + headers: zPostKnowledgeSpacesByIdSourcesBySourceIdImportHeaders.optional(), + params: zPostKnowledgeSpacesByIdSourcesBySourceIdImportPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourcesBySourceIdImportResponse) + +export const postKnowledgeSpacesByIdSourcesBySourceIdTest = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourcesBySourceIdTest', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/test', + tags: ['default'], + }) + .input( + z.object({ + headers: zPostKnowledgeSpacesByIdSourcesBySourceIdTestHeaders.optional(), + params: zPostKnowledgeSpacesByIdSourcesBySourceIdTestPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourcesBySourceIdTestResponse) + +export const postKnowledgeSpacesByIdSourcesBySourceIdImportFiles = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourcesBySourceIdImportFiles', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/import-files', + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdSourcesBySourceIdImportFilesBody, + headers: zPostKnowledgeSpacesByIdSourcesBySourceIdImportFilesHeaders.optional(), + params: zPostKnowledgeSpacesByIdSourcesBySourceIdImportFilesPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourcesBySourceIdImportFilesResponse) + +export const postKnowledgeSpacesByIdSourcesBulk = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourcesBulk', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/bulk', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdSourcesBulkBody, + headers: zPostKnowledgeSpacesByIdSourcesBulkHeaders, + params: zPostKnowledgeSpacesByIdSourcesBulkPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourcesBulkResponse) + +export const getKnowledgeSpacesByIdSourceWorkflows = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdSourceWorkflows', + path: '/knowledge-fs/knowledge-spaces/{id}/source-workflows', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdSourceWorkflowsHeaders.optional(), + params: zGetKnowledgeSpacesByIdSourceWorkflowsPath, + query: zGetKnowledgeSpacesByIdSourceWorkflowsQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdSourceWorkflowsResponse) + +export const getKnowledgeSpacesByIdSourceWorkflowsByRunId = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdSourceWorkflowsByRunId', + path: '/knowledge-fs/knowledge-spaces/{id}/source-workflows/{runId}', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdHeaders.optional(), + params: zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPath, + }), + ) + .output(zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdResponse) + +export const getKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItems = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItems', + path: '/knowledge-fs/knowledge-spaces/{id}/source-workflows/{runId}/bulk-items', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsHeaders.optional(), + params: zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsPath, + query: zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsResponse) + +export const getKnowledgeSpacesByIdSourceWorkflowsByRunIdPages = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdSourceWorkflowsByRunIdPages', + path: '/knowledge-fs/knowledge-spaces/{id}/source-workflows/{runId}/pages', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesHeaders.optional(), + params: zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesPath, + query: zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesResponse) + +export const postKnowledgeSpacesByIdSourceWorkflowsByRunIdCancel = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourceWorkflowsByRunIdCancel', + path: '/knowledge-fs/knowledge-spaces/{id}/source-workflows/{runId}/cancel', + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelBody, + headers: zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelHeaders.optional(), + params: zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelResponse) + +export const postKnowledgeSpacesByIdSourceWorkflowsByRunIdRetry = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourceWorkflowsByRunIdRetry', + path: '/knowledge-fs/knowledge-spaces/{id}/source-workflows/{runId}/retry', + tags: ['default'], + }) + .input( + z.object({ + headers: zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryHeaders.optional(), + params: zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryResponse) + +export const postKnowledgeSpacesByIdSourceWorkflowsByRunIdSelection = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdSourceWorkflowsByRunIdSelection', + path: '/knowledge-fs/knowledge-spaces/{id}/source-workflows/{runId}/selection', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionBody, + headers: zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionHeaders, + params: zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionPath, + }), + ) + .output(zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionResponse) + +export const getKnowledgeSpacesByIdSourcesBySourceIdSyncPolicy = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdSourcesBySourceIdSyncPolicy', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/sync-policy', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyHeaders.optional(), + params: zGetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyPath, + }), + ) + .output(zGetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponse) + +export const putKnowledgeSpacesByIdSourcesBySourceIdSyncPolicy = oc + .route({ + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putKnowledgeSpacesByIdSourcesBySourceIdSyncPolicy', + path: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/sync-policy', + tags: ['default'], + }) + .input( + z.object({ + body: zPutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyBody, + headers: zPutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyHeaders.optional(), + params: zPutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyPath, + }), + ) + .output(zPutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponse) + +export const getKnowledgeSpacesByIdDocuments = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdDocuments', + path: '/knowledge-fs/knowledge-spaces/{id}/documents', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdDocumentsHeaders.optional(), + params: zGetKnowledgeSpacesByIdDocumentsPath, + query: zGetKnowledgeSpacesByIdDocumentsQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdDocumentsResponse) + +export const postKnowledgeSpacesByIdDocuments = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdDocuments', + path: '/knowledge-fs/knowledge-spaces/{id}/documents', + successStatus: 201, + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdDocumentsBody, + headers: zPostKnowledgeSpacesByIdDocumentsHeaders.optional(), + params: zPostKnowledgeSpacesByIdDocumentsPath, + }), + ) + .output(zPostKnowledgeSpacesByIdDocumentsResponse) + +export const deleteKnowledgeSpacesByIdDocumentsBulk = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteKnowledgeSpacesByIdDocumentsBulk', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/bulk', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zDeleteKnowledgeSpacesByIdDocumentsBulkBody, + headers: zDeleteKnowledgeSpacesByIdDocumentsBulkHeaders, + params: zDeleteKnowledgeSpacesByIdDocumentsBulkPath, + }), + ) + .output(zDeleteKnowledgeSpacesByIdDocumentsBulkResponse) + +export const postKnowledgeSpacesByIdDocumentsBulk = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdDocumentsBulk', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/bulk', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdDocumentsBulkBody, + headers: zPostKnowledgeSpacesByIdDocumentsBulkHeaders.optional(), + params: zPostKnowledgeSpacesByIdDocumentsBulkPath, + }), + ) + .output(zPostKnowledgeSpacesByIdDocumentsBulkResponse) + +export const postKnowledgeSpacesByIdDocumentsBulkReindex = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdDocumentsBulkReindex', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/bulk/reindex', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdDocumentsBulkReindexBody, + headers: zPostKnowledgeSpacesByIdDocumentsBulkReindexHeaders.optional(), + params: zPostKnowledgeSpacesByIdDocumentsBulkReindexPath, + }), + ) + .output(zPostKnowledgeSpacesByIdDocumentsBulkReindexResponse) + +export const deleteKnowledgeSpacesByIdDocumentsByDocumentId = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteKnowledgeSpacesByIdDocumentsByDocumentId', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdBody, + headers: zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdHeaders, + params: zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdPath, + }), + ) + .output(zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdResponse) + +export const getKnowledgeSpacesByIdDocumentsByDocumentId = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdDocumentsByDocumentId', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdDocumentsByDocumentIdHeaders.optional(), + params: zGetKnowledgeSpacesByIdDocumentsByDocumentIdPath, + }), + ) + .output(zGetKnowledgeSpacesByIdDocumentsByDocumentIdResponse) + +export const getKnowledgeSpacesByIdLogicalDocuments = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdLogicalDocuments', + path: '/knowledge-fs/knowledge-spaces/{id}/logical-documents', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdLogicalDocumentsHeaders.optional(), + params: zGetKnowledgeSpacesByIdLogicalDocumentsPath, + query: zGetKnowledgeSpacesByIdLogicalDocumentsQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdLogicalDocumentsResponse) + +export const deleteKnowledgeSpacesByIdLogicalDocumentsByDocumentId = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteKnowledgeSpacesByIdLogicalDocumentsByDocumentId', + path: '/knowledge-fs/knowledge-spaces/{id}/logical-documents/{documentId}', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zDeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdBody, + headers: zDeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdHeaders, + params: zDeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdPath, + }), + ) + .output(zDeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponse) + +export const getKnowledgeSpacesByIdLogicalDocumentsByDocumentId = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdLogicalDocumentsByDocumentId', + path: '/knowledge-fs/knowledge-spaces/{id}/logical-documents/{documentId}', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdHeaders.optional(), + params: zGetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdPath, + }), + ) + .output(zGetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponse) + +export const getKnowledgeSpacesByIdDocumentsByDocumentIdOutline = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdDocumentsByDocumentIdOutline', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/outline', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineHeaders.optional(), + params: zGetKnowledgeSpacesByIdDocumentsByDocumentIdOutlinePath, + }), + ) + .output(zGetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineResponse) + +export const getKnowledgeSpacesByIdDocumentsByDocumentIdRevisions = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdDocumentsByDocumentIdRevisions', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/revisions', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsHeaders.optional(), + params: zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsPath, + query: zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsResponse) + +export const postKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollback = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollback', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/revisions/{revision}/rollback', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackBody, + headers: + zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackHeaders.optional(), + params: zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackPath, + }), + ) + .output(zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackResponse) + +export const patchKnowledgeSpacesByIdDocumentsByDocumentIdMetadata = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchKnowledgeSpacesByIdDocumentsByDocumentIdMetadata', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/metadata', + tags: ['default'], + }) + .input( + z.object({ + body: zPatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataBody, + headers: zPatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataHeaders.optional(), + params: zPatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataPath, + }), + ) + .output(zPatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataResponse) + +export const getKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunks = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunks', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/revisions/{revision}/chunks', + tags: ['default'], + }) + .input( + z.object({ + headers: + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksHeaders.optional(), + params: zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksPath, + query: zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksResponse) + +export const getKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkId = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkId', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/revisions/{revision}/chunks/{chunkId}', + tags: ['default'], + }) + .input( + z.object({ + headers: + zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdHeaders.optional(), + params: zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdPath, + }), + ) + .output(zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdResponse) + +export const postKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdState = + oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: + 'postKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdState', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/revisions/{revision}/chunks/{chunkId}/state', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateBody, + headers: + zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateHeaders.optional(), + params: + zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStatePath, + }), + ) + .output( + zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateResponse, + ) + +export const getKnowledgeSpacesByIdProcessingTasks = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdProcessingTasks', + path: '/knowledge-fs/knowledge-spaces/{id}/processing-tasks', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdProcessingTasksHeaders.optional(), + params: zGetKnowledgeSpacesByIdProcessingTasksPath, + query: zGetKnowledgeSpacesByIdProcessingTasksQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdProcessingTasksResponse) + +export const getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasks = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasks', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/processing-tasks', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksHeaders.optional(), + params: zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksPath, + query: zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksQuery.optional(), + }), + ) + .output(zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksResponse) + +export const deleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskId = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskId', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/processing-tasks/{taskId}', + tags: ['default'], + }) + .input( + z.object({ + headers: + zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdHeaders.optional(), + params: zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdPath, + }), + ) + .output(zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponse) + +export const getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskId = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskId', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/processing-tasks/{taskId}', + tags: ['default'], + }) + .input( + z.object({ + headers: + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdHeaders.optional(), + params: zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdPath, + }), + ) + .output(zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponse) + +export const getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEvents = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEvents', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/processing-tasks/{taskId}/events', + tags: ['default'], + }) + .input( + z.object({ + headers: + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsHeaders.optional(), + params: zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsPath, + }), + ) + .output( + eventIterator( + zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsResponse, + ), + ) + +export const postKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetry = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetry', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/processing-tasks/{taskId}/retry', + tags: ['default'], + }) + .input( + z.object({ + headers: + zPostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryHeaders.optional(), + params: zPostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryPath, + }), + ) + .output(zPostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryResponse) + +export const getKnowledgeSpacesByIdDocumentsByDocumentIdSettings = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getKnowledgeSpacesByIdDocumentsByDocumentIdSettings', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/settings', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsHeaders.optional(), + params: zGetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsPath, + }), + ) + .output(zGetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponse) + +export const putKnowledgeSpacesByIdDocumentsByDocumentIdSettings = oc + .route({ + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putKnowledgeSpacesByIdDocumentsByDocumentIdSettings', + path: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/settings', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + body: zPutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsBody, + headers: zPutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsHeaders.optional(), + params: zPutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsPath, + }), + ) + .output(zPutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponse) + +export const deleteJobsById = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteJobsById', + path: '/knowledge-fs/jobs/{id}', + tags: ['default'], + }) + .input(z.object({ headers: zDeleteJobsByIdHeaders.optional(), params: zDeleteJobsByIdPath })) + .output(zDeleteJobsByIdResponse) + +export const getJobsById = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getJobsById', + path: '/knowledge-fs/jobs/{id}', + tags: ['default'], + }) + .input(z.object({ headers: zGetJobsByIdHeaders.optional(), params: zGetJobsByIdPath })) + .output(zGetJobsByIdResponse) + +export const postJobsByIdRetry = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postJobsByIdRetry', + path: '/knowledge-fs/jobs/{id}/retry', + tags: ['default'], + }) + .input( + z.object({ headers: zPostJobsByIdRetryHeaders.optional(), params: zPostJobsByIdRetryPath }), + ) + .output(zPostJobsByIdRetryResponse) + +export const getDeletionJobsByJobId = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDeletionJobsByJobId', + path: '/knowledge-fs/deletion-jobs/{jobId}', + tags: ['default'], + }) + .input( + z.object({ + headers: zGetDeletionJobsByJobIdHeaders.optional(), + params: zGetDeletionJobsByJobIdPath, + }), + ) + .output(zGetDeletionJobsByJobIdResponse) + +export const postDeletionJobsByJobIdRetry = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDeletionJobsByJobIdRetry', + path: '/knowledge-fs/deletion-jobs/{jobId}/retry', + successStatus: 202, + tags: ['default'], + }) + .input( + z.object({ + headers: zPostDeletionJobsByJobIdRetryHeaders, + params: zPostDeletionJobsByJobIdRetryPath, + }), + ) + .output(zPostDeletionJobsByJobIdRetryResponse) + +export const getBulkJobsById = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getBulkJobsById', + path: '/knowledge-fs/bulk-jobs/{id}', + tags: ['default'], + }) + .input(z.object({ headers: zGetBulkJobsByIdHeaders.optional(), params: zGetBulkJobsByIdPath })) + .output(zGetBulkJobsByIdResponse) + export const contract = { listKnowledgeSpaces, createKnowledgeSpace, + deleteKnowledgeSpacesById, + getKnowledgeSpacesById, + patchKnowledgeSpacesById, + getKnowledgeSpacesByIdStats, + getKnowledgeSpacesByIdAccessPolicy, + patchKnowledgeSpacesByIdAccessPolicy, + getSourceProviders, + getKnowledgeSpacesByIdSourceConnections, + postKnowledgeSpacesByIdSourceConnections, + postKnowledgeSpacesByIdSourceConnectionsOauth, + postSourceOauthCallback, + deleteKnowledgeSpacesByIdSourceConnectionsByConnectionId, + getKnowledgeSpacesByIdSourceConnectionsByConnectionId, + postKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefresh, + getKnowledgeSpacesByIdSources, + postKnowledgeSpacesByIdSources, + deleteKnowledgeSpacesByIdSourcesBySourceId, + getKnowledgeSpacesByIdSourcesBySourceId, + patchKnowledgeSpacesByIdSourcesBySourceId, + deleteKnowledgeSpacesByIdSourcesBySourceIdCredentials, + putKnowledgeSpacesByIdSourcesBySourceIdCredentials, + postKnowledgeSpacesByIdSourcesBySourceIdSync, + postKnowledgeSpacesByIdSourcesBySourceIdCrawlPreview, + postKnowledgeSpacesByIdSourcesBySourceIdWorkflowImports, + getKnowledgeSpacesByIdSourcesBySourceIdPages, + getKnowledgeSpacesByIdSourcesBySourceIdFiles, + postKnowledgeSpacesByIdSourcesBySourceIdCrawl, + postKnowledgeSpacesByIdSourcesBySourceIdImport, + postKnowledgeSpacesByIdSourcesBySourceIdTest, + postKnowledgeSpacesByIdSourcesBySourceIdImportFiles, + postKnowledgeSpacesByIdSourcesBulk, + getKnowledgeSpacesByIdSourceWorkflows, + getKnowledgeSpacesByIdSourceWorkflowsByRunId, + getKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItems, + getKnowledgeSpacesByIdSourceWorkflowsByRunIdPages, + postKnowledgeSpacesByIdSourceWorkflowsByRunIdCancel, + postKnowledgeSpacesByIdSourceWorkflowsByRunIdRetry, + postKnowledgeSpacesByIdSourceWorkflowsByRunIdSelection, + getKnowledgeSpacesByIdSourcesBySourceIdSyncPolicy, + putKnowledgeSpacesByIdSourcesBySourceIdSyncPolicy, + getKnowledgeSpacesByIdDocuments, + postKnowledgeSpacesByIdDocuments, + deleteKnowledgeSpacesByIdDocumentsBulk, + postKnowledgeSpacesByIdDocumentsBulk, + postKnowledgeSpacesByIdDocumentsBulkReindex, + deleteKnowledgeSpacesByIdDocumentsByDocumentId, + getKnowledgeSpacesByIdDocumentsByDocumentId, + getKnowledgeSpacesByIdLogicalDocuments, + deleteKnowledgeSpacesByIdLogicalDocumentsByDocumentId, + getKnowledgeSpacesByIdLogicalDocumentsByDocumentId, + getKnowledgeSpacesByIdDocumentsByDocumentIdOutline, + getKnowledgeSpacesByIdDocumentsByDocumentIdRevisions, + postKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollback, + patchKnowledgeSpacesByIdDocumentsByDocumentIdMetadata, + getKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunks, + getKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkId, + postKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdState, + getKnowledgeSpacesByIdProcessingTasks, + getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasks, + deleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskId, + getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskId, + getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEvents, + postKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetry, + getKnowledgeSpacesByIdDocumentsByDocumentIdSettings, + putKnowledgeSpacesByIdDocumentsByDocumentIdSettings, + deleteJobsById, + getJobsById, + postJobsByIdRetry, + getDeletionJobsByJobId, + postDeletionJobsByJobIdRetry, + getBulkJobsById, } diff --git a/packages/contracts/generated/knowledge-fs/types.gen.ts b/packages/contracts/generated/knowledge-fs/types.gen.ts index d0b1886e100..dc7be0b1fa7 100644 --- a/packages/contracts/generated/knowledge-fs/types.gen.ts +++ b/packages/contracts/generated/knowledge-fs/types.gen.ts @@ -74,6 +74,592 @@ export type KnowledgeSpaceList = { nextCursor?: string } +export type KnowledgeSpaceStats = { + cache: { + available: boolean + entries: number + totalBytes: number + } + commits: { + failedRetryable: number + failedTerminal: number + sampled: number + truncated: boolean + } + generatedAt: string + knowledgeSpaceId: string + metrics: { + available: boolean + reason?: string + } + projections: { + denseVector: { + building: number + failed: number + ready: number + stale: number + total: number + } + fts: { + building: number + failed: number + ready: number + stale: number + total: number + } + graph: { + building: number + failed: number + ready: number + stale: number + total: number + } + metadata: { + building: number + failed: number + ready: number + stale: number + total: number + } + projectionVersion: number + } + runtime: { + activeLeaseSampleCount: number + activeSessionSampleCount: number + truncated: boolean + } + storage: { + documentCount: number + rawDocumentBytes: number + } + tenantId: string + window: { + end: string + minutes: number + start: string + } +} + +export type DurableDeletionJob = { + checkpoint: + | 'requested' + | 'quiescing' + | 'deleting_objects' + | 'deleting_derived_data' + | 'deleting_primary_data' + | 'completed' + completedAt?: string + createdAt: string + error?: { + code: string + message: string + retryable: boolean + } + id: string + knowledgeSpaceId: string + mode?: 'cascade' | 'keep' + progress?: { + completedItems: number + currentItemKind?: string + totalItems?: number + } + retryAt?: string + runState: + | 'dispatch_pending' + | 'queued' + | 'running' + | 'retry_wait' + | 'completed' + | 'failed' + | 'canceled' + targetId: string + targetType: 'knowledge_space' | 'source' | 'document' | 'logical_document' + updatedAt: string +} + +export type DurableDeletionAccepted = { + job: DurableDeletionJob + statusUrl: string +} + +export type DurableBulkDeletionAccepted = { + items: Array<{ + documentId: string + job: DurableDeletionJob + statusUrl: string + }> + total: number +} + +export type DocumentAsset = { + createdAt: string + filename: string + id: string + knowledgeSpaceId: string + metadata?: { + [key: string]: unknown + } + mimeType: string + objectKey: string + parserStatus: 'pending' | 'parsed' | 'failed' + sha256: string + sizeBytes: number + sourceId?: string + updatedAt?: string + version: number +} + +export type DocumentAssetList = { + items: Array + nextCursor?: string +} + +export type DocumentOutlineNode = { + childNodeIds?: Array + children?: Array<{ + [key: string]: unknown + }> + endOffset?: number + endPage?: number + id: string + level: number + metadata: { + [key: string]: unknown + } + sectionPath?: Array + sourceElementIds?: Array + sourceNodeIds?: Array + startOffset?: number + startPage?: number + summary?: string + title: string + titleLocation?: { + [key: string]: unknown + } + tocSource: string +} + +export type DocumentOutline = { + artifactHash: string + createdAt: string + documentAssetId: string + id: string + knowledgeSpaceId: string + metadata: { + [key: string]: unknown + } + nodes: Array + outlineVersion: string + parseArtifactId: string + updatedAt?: string + version: number +} + +export type LogicalDocumentRevision = { + activatedAt?: string + contentHash: string + createdAt: string + documentAssetId: string + documentAssetVersion: number + documentId: string + knowledgeSpaceId: string + mimeType: string + revision: number + sizeBytes: number + state: 'candidate' | 'active' | 'superseded' | 'failed' +} | null + +export type LogicalDocument = { + active: LogicalDocumentRevision + activeRevision?: number + createdAt: string + id: string + knowledgeSpaceId: string + providerItemId?: string + rowVersion: number + sourceId?: string + status: 'pending' | 'ready' | 'failed' | 'deleting' + title: string + updatedAt: string + userMetadata: { + [key: string]: unknown + } +} + +export type LogicalDocumentList = { + items: Array + nextCursor?: string +} + +export type DocumentRevisionList = { + items: Array< + LogicalDocumentRevision & { + [key: string]: unknown + } + > + nextCursor?: string +} + +export type DocumentProcessingTask = { + completedAt?: string + createdAt: string + documentId: string + documentRevision: number + errorCode?: string + errorMessage?: string + id: string + knowledgeSpaceId: string + progressPercent: number + retryAt?: string + stage: + | 'queued' + | 'parsed' + | 'outline_built' + | 'nodes_generated' + | 'projection_built' + | 'smoke_eval_passed' + | 'published' + state: + | 'dispatch_pending' + | 'queued' + | 'running' + | 'retry_wait' + | 'succeeded' + | 'failed' + | 'canceled' + | 'superseded' + updatedAt: string +} + +export type DocumentRevisionChunk = { + createdAt: string + documentId: string + documentRevision: number + enabled: boolean + id: string + knowledgeSpaceId: string + ordinal: number + parentChunkId?: string + text: string + tokenCount: number + userMetadata: { + [key: string]: unknown + } +} + +export type DocumentChunkList = { + items: Array + nextCursor?: string +} + +export type DocumentChunkStateChangeAccepted = { + candidateFingerprint?: string + candidatePublicationId?: string + chunkId: string + compilationAttemptId: string + createdAt: string + documentId: string + documentRevision: number + enabled: boolean + id: string + knowledgeSpaceId: string + state: 'candidate' + statusUrl: string +} + +export type DocumentProcessingTaskList = { + items: Array + nextCursor?: string +} + +export type DocumentProcessingTaskEvent = + | { + data: { + progressPercent: number + stage: + | 'queued' + | 'parsed' + | 'outline_built' + | 'nodes_generated' + | 'projection_built' + | 'smoke_eval_passed' + | 'published' + state: + | 'dispatch_pending' + | 'queued' + | 'running' + | 'retry_wait' + | 'succeeded' + | 'failed' + | 'canceled' + | 'superseded' + updatedAt: string + } + event: 'progress' + } + | { + data: { + errorCode?: string + state: 'succeeded' | 'failed' | 'canceled' | 'superseded' + } + event: 'terminal' + } + +export type DocumentSettingsHead = { + activeRevision: number + profile: { + activatedAt?: string + createdAt: string + revision: number + settings: { + chunkOverlap: number + chunkSize: number + enableGraph: boolean + enablePageIndex: boolean + language?: string + } + state: 'active' + } + rowVersion: number + updatedAt: string +} + +export type DocumentReindexAccepted = { + attemptId: string + compilationAttemptId: string + settingsRevision: number + state: 'running' + statusUrl: string +} + +export type DocumentCompilationJob = { + baseHeadRevision?: number + candidateFingerprint?: string + candidatePublicationId?: string + completedAt?: number + createdAt: number + documentAssetId: string + error?: string + executionAttempts?: number + id: string + knowledgeSpaceId: string + leaseExpiresAt?: number + maxExecutionAttempts?: number + publicationGenerationId?: string + queueJobId?: string + retryAt?: number + runState?: + | 'dispatch_pending' + | 'queued' + | 'running' + | 'retry_wait' + | 'succeeded' + | 'failed' + | 'canceled' + | 'superseded' + stage: + | 'queued' + | 'parsed' + | 'outline_built' + | 'nodes_generated' + | 'projection_built' + | 'smoke_eval_passed' + | 'published' + | 'failed' + | 'canceled' + tenantId: string + updatedAt: number + version: number +} + +export type BulkOperationProgress = { + completedItems: number + createdAt: string + failedItemIds: Array + failedItems: number + id: string + knowledgeSpaceId: string + status: 'running' | 'completed' | 'failed' + totalItems: number + type: 'document_upload' | 'document_delete' | 'document_reindex' + updatedAt: string +} + +export type BulkDocumentReindexResult = { + bulkJobId: string + items: Array< + | { + asset: DocumentAsset + compilationJob: { + id: string + stage: 'queued' + } + status: 'queued' + statusUrl: string + } + | { + documentId: string + status: 'not_found' + } + > + total: number +} + +export type DocumentUploadAccepted = { + asset: DocumentAsset + assetStatusUrl?: string + compilationJob: { + id: string + stage: 'queued' + } + logicalDocument: { + id: string + revision: number + } + logicalDocumentId: string + documentRevision: number + statusUrl: string + status?: 'accepted' +} + +export type BulkDocumentUploadAccepted = { + accepted: number + bulkJobId: string + excluded: number + items: Array< + | DocumentUploadAccepted + | { + filename: string + index: number + mimeType: string + reason: + | 'batch_byte_limit_exceeded' + | 'document_not_found' + | 'file_count_limit_exceeded' + | 'file_too_large' + | 'invalid_file' + | 'invalid_target' + | 'processing_failed' + | 'quota_exceeded' + | 'revision_conflict' + | 'unsupported_mime_type' + sizeBytes: number + status: 'excluded' + } + > + total: number +} + +export type SourceWorkflowRun = { + canceledAt?: string + checkpoint: string + completedAt?: string + createdAt: string + cursor?: string + executionAttempts: number + id: string + knowledgeSpaceId: string + kind: string + lastErrorCode?: string + maxExecutionAttempts: number + progressCompleted: number + progressFailed: number + progressSkipped: number + progressTotal?: number + sourceId?: string + state: string + updatedAt: string +} + +export type Source = { + connectionId?: string + createdAt: string + id: string + knowledgeSpaceId: string + metadata: { + [key: string]: unknown + } + name: string + permissionScope?: Array + status: 'active' | 'syncing' | 'error' | 'disabled' + type: 'upload' | 'object-storage' | 'connector' | 'web' + updatedAt: string + uri: string + version?: number + credentialConfigured?: boolean +} + +export type WebsiteCrawlResult = { + completed?: number + failed?: number + imported?: number + pages: Array<{ + content: string + description?: string + sourceUrl: string + title?: string + }> + replaced?: number + skipped?: number + status?: string + total?: number +} + +export type OnlineDocumentPages = { + nextCursor?: string + workspaces: Array<{ + pages: Array<{ + lastEditedTime?: string + pageId: string + pageName: string + parentId?: string + type: string + }> + total?: number + workspaceId?: string + workspaceName?: string + }> +} + +export type SourceImportResult = { + documents: Array<{ + documentAssetId: string + filename: string + }> + failed: Array<{ + code: string + error: string + filename: string + }> + skipped: Array +} + +export type SourceCredentialTest = { + code?: string + error?: string + valid: boolean +} + +export type OnlineDriveFiles = { + buckets: Array<{ + bucket?: string + continuationToken?: string + files: Array<{ + id: string + name: string + size?: number + type: string + }> + isTruncated?: boolean + }> +} + +export type ConsoleProxyError = { + code: string + message: string + status: number +} + export type ListKnowledgeSpacesData = { body?: never headers?: { @@ -89,8 +675,8 @@ export type ListKnowledgeSpacesData = { export type ListKnowledgeSpacesErrors = { 400: ErrorResponse - 401: ErrorResponse - 403: ErrorResponse + 403: ConsoleProxyError + 502: ConsoleProxyError } export type ListKnowledgeSpacesError = ListKnowledgeSpacesErrors[keyof ListKnowledgeSpacesErrors] @@ -120,11 +706,11 @@ export type CreateKnowledgeSpaceErrors = { mode: 'fast' | 'research' | 'deep' } | ErrorResponse - 401: ErrorResponse - 403: ErrorResponse + 403: ConsoleProxyError 409: ErrorResponse 422: ErrorResponse 429: ErrorResponse + 502: ConsoleProxyError 503: ErrorResponse } @@ -136,3 +722,2581 @@ export type CreateKnowledgeSpaceResponses = { export type CreateKnowledgeSpaceResponse = CreateKnowledgeSpaceResponses[keyof CreateKnowledgeSpaceResponses] + +export type DeleteKnowledgeSpacesByIdData = { + body: { + challenge: string + expectedRevision: number + } + headers: { + 'idempotency-key': string + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}' +} + +export type DeleteKnowledgeSpacesByIdErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type DeleteKnowledgeSpacesByIdError = + DeleteKnowledgeSpacesByIdErrors[keyof DeleteKnowledgeSpacesByIdErrors] + +export type DeleteKnowledgeSpacesByIdResponses = { + 202: DurableDeletionAccepted +} + +export type DeleteKnowledgeSpacesByIdResponse = + DeleteKnowledgeSpacesByIdResponses[keyof DeleteKnowledgeSpacesByIdResponses] + +export type GetKnowledgeSpacesByIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}' +} + +export type GetKnowledgeSpacesByIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdError = + GetKnowledgeSpacesByIdErrors[keyof GetKnowledgeSpacesByIdErrors] + +export type GetKnowledgeSpacesByIdResponses = { + 200: KnowledgeSpace +} + +export type GetKnowledgeSpacesByIdResponse = + GetKnowledgeSpacesByIdResponses[keyof GetKnowledgeSpacesByIdResponses] + +export type PatchKnowledgeSpacesByIdData = { + body: { + description?: string + expectedRevision: number + iconRef?: string | null + name?: string + slug?: string + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}' +} + +export type PatchKnowledgeSpacesByIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type PatchKnowledgeSpacesByIdError = + PatchKnowledgeSpacesByIdErrors[keyof PatchKnowledgeSpacesByIdErrors] + +export type PatchKnowledgeSpacesByIdResponses = { + 200: KnowledgeSpace +} + +export type PatchKnowledgeSpacesByIdResponse = + PatchKnowledgeSpacesByIdResponses[keyof PatchKnowledgeSpacesByIdResponses] + +export type GetKnowledgeSpacesByIdStatsData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: { + windowMinutes?: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/stats' +} + +export type GetKnowledgeSpacesByIdStatsErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdStatsError = + GetKnowledgeSpacesByIdStatsErrors[keyof GetKnowledgeSpacesByIdStatsErrors] + +export type GetKnowledgeSpacesByIdStatsResponses = { + 200: KnowledgeSpaceStats +} + +export type GetKnowledgeSpacesByIdStatsResponse = + GetKnowledgeSpacesByIdStatsResponses[keyof GetKnowledgeSpacesByIdStatsResponses] + +export type GetKnowledgeSpacesByIdAccessPolicyData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/access-policy' +} + +export type GetKnowledgeSpacesByIdAccessPolicyErrors = { + 400: ErrorResponse & { + [key: string]: unknown + } + 403: ConsoleProxyError + 404: ErrorResponse & { + [key: string]: unknown + } + 409: ErrorResponse & { + [key: string]: unknown + } + 429: ErrorResponse & { + [key: string]: unknown + } + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdAccessPolicyError = + GetKnowledgeSpacesByIdAccessPolicyErrors[keyof GetKnowledgeSpacesByIdAccessPolicyErrors] + +export type GetKnowledgeSpacesByIdAccessPolicyResponses = { + 200: { + id: string + ownerSubjectId: string + partialMemberSubjectIds: Array + revision: number + visibility: 'only_me' | 'all_members' | 'partial_members' + } +} + +export type GetKnowledgeSpacesByIdAccessPolicyResponse = + GetKnowledgeSpacesByIdAccessPolicyResponses[keyof GetKnowledgeSpacesByIdAccessPolicyResponses] + +export type PatchKnowledgeSpacesByIdAccessPolicyData = { + body: { + expectedRevision: number + partialMemberSubjectIds?: Array + visibility: 'only_me' | 'all_members' | 'partial_members' + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/access-policy' +} + +export type PatchKnowledgeSpacesByIdAccessPolicyErrors = { + 400: ErrorResponse & { + [key: string]: unknown + } + 403: ConsoleProxyError + 404: ErrorResponse & { + [key: string]: unknown + } + 409: ErrorResponse & { + [key: string]: unknown + } + 429: ErrorResponse & { + [key: string]: unknown + } + 502: ConsoleProxyError +} + +export type PatchKnowledgeSpacesByIdAccessPolicyError = + PatchKnowledgeSpacesByIdAccessPolicyErrors[keyof PatchKnowledgeSpacesByIdAccessPolicyErrors] + +export type PatchKnowledgeSpacesByIdAccessPolicyResponses = { + 200: { + id: string + ownerSubjectId: string + partialMemberSubjectIds: Array + revision: number + visibility: 'only_me' | 'all_members' | 'partial_members' + } +} + +export type PatchKnowledgeSpacesByIdAccessPolicyResponse = + PatchKnowledgeSpacesByIdAccessPolicyResponses[keyof PatchKnowledgeSpacesByIdAccessPolicyResponses] + +export type GetSourceProvidersData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path?: never + query?: never + url: '/knowledge-fs/source-providers' +} + +export type GetSourceProvidersErrors = { + 403: ConsoleProxyError + 502: ConsoleProxyError +} + +export type GetSourceProvidersError = GetSourceProvidersErrors[keyof GetSourceProvidersErrors] + +export type GetSourceProvidersResponses = { + 200: { + items: Array<{ + authKinds: Array<'api-key' | 'endpoint' | 'oauth2'> + available: boolean + capabilities: Array<'website-crawl' | 'online-document' | 'online-drive'> + configuration: Array<{ + description?: string + format?: 'password' | 'uri' + name: string + required: boolean + secret: boolean + type: 'boolean' | 'integer' | 'string' + }> + displayName: string + id: string + unavailableReason?: string + }> + } +} + +export type GetSourceProvidersResponse = + GetSourceProvidersResponses[keyof GetSourceProvidersResponses] + +export type GetKnowledgeSpacesByIdSourceConnectionsData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: { + cursor?: string + limit?: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/source-connections' +} + +export type GetKnowledgeSpacesByIdSourceConnectionsErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdSourceConnectionsError = + GetKnowledgeSpacesByIdSourceConnectionsErrors[keyof GetKnowledgeSpacesByIdSourceConnectionsErrors] + +export type GetKnowledgeSpacesByIdSourceConnectionsResponses = { + 200: { + items: Array<{ + authKind: 'api-key' | 'endpoint' | 'oauth2' + configuration: { + [key: string]: boolean | number | string + } + createdAt: string + errorCode?: string + expiresAt?: string + id: string + knowledgeSpaceId: string + name: string + providerId: string + scopes: Array + status: 'provisioning' | 'active' | 'expired' | 'error' | 'revoked' + updatedAt: string + version: number + }> + nextCursor?: string + } +} + +export type GetKnowledgeSpacesByIdSourceConnectionsResponse = + GetKnowledgeSpacesByIdSourceConnectionsResponses[keyof GetKnowledgeSpacesByIdSourceConnectionsResponses] + +export type PostKnowledgeSpacesByIdSourceConnectionsData = { + body: { + authKind: 'api-key' | 'endpoint' + configuration?: { + [key: string]: boolean | number | string + } + credentials: { + [key: string]: unknown + } + name: string + providerId: string + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/source-connections' +} + +export type PostKnowledgeSpacesByIdSourceConnectionsErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ErrorResponse | ConsoleProxyError + 503: ErrorResponse +} + +export type PostKnowledgeSpacesByIdSourceConnectionsError = + PostKnowledgeSpacesByIdSourceConnectionsErrors[keyof PostKnowledgeSpacesByIdSourceConnectionsErrors] + +export type PostKnowledgeSpacesByIdSourceConnectionsResponses = { + 201: { + authKind: 'api-key' | 'endpoint' | 'oauth2' + configuration: { + [key: string]: boolean | number | string + } + createdAt: string + errorCode?: string + expiresAt?: string + id: string + knowledgeSpaceId: string + name: string + providerId: string + scopes: Array + status: 'provisioning' | 'active' | 'expired' | 'error' | 'revoked' + updatedAt: string + version: number + } +} + +export type PostKnowledgeSpacesByIdSourceConnectionsResponse = + PostKnowledgeSpacesByIdSourceConnectionsResponses[keyof PostKnowledgeSpacesByIdSourceConnectionsResponses] + +export type PostKnowledgeSpacesByIdSourceConnectionsOauthData = { + body: { + configuration?: { + [key: string]: boolean | number | string + } + name: string + providerId: string + redirectUri: string + scopes?: Array + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/source-connections/oauth' +} + +export type PostKnowledgeSpacesByIdSourceConnectionsOauthErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 502: ErrorResponse | ConsoleProxyError + 503: ErrorResponse +} + +export type PostKnowledgeSpacesByIdSourceConnectionsOauthError = + PostKnowledgeSpacesByIdSourceConnectionsOauthErrors[keyof PostKnowledgeSpacesByIdSourceConnectionsOauthErrors] + +export type PostKnowledgeSpacesByIdSourceConnectionsOauthResponses = { + 201: { + authorizationUrl: string + connection: { + authKind: 'api-key' | 'endpoint' | 'oauth2' + configuration: { + [key: string]: boolean | number | string + } + createdAt: string + errorCode?: string + expiresAt?: string + id: string + knowledgeSpaceId: string + name: string + providerId: string + scopes: Array + status: 'provisioning' | 'active' | 'expired' | 'error' | 'revoked' + updatedAt: string + version: number + } + } +} + +export type PostKnowledgeSpacesByIdSourceConnectionsOauthResponse = + PostKnowledgeSpacesByIdSourceConnectionsOauthResponses[keyof PostKnowledgeSpacesByIdSourceConnectionsOauthResponses] + +export type PostSourceOauthCallbackData = { + body: { + code: string + state: string + } + headers?: { + 'x-trace-id'?: string + } + path?: never + query?: never + url: '/knowledge-fs/source-oauth/callback' +} + +export type PostSourceOauthCallbackErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 409: ErrorResponse + 502: ErrorResponse | ConsoleProxyError + 503: ErrorResponse +} + +export type PostSourceOauthCallbackError = + PostSourceOauthCallbackErrors[keyof PostSourceOauthCallbackErrors] + +export type PostSourceOauthCallbackResponses = { + 200: { + authKind: 'api-key' | 'endpoint' | 'oauth2' + configuration: { + [key: string]: boolean | number | string + } + createdAt: string + errorCode?: string + expiresAt?: string + id: string + knowledgeSpaceId: string + name: string + providerId: string + scopes: Array + status: 'provisioning' | 'active' | 'expired' | 'error' | 'revoked' + updatedAt: string + version: number + } +} + +export type PostSourceOauthCallbackResponse = + PostSourceOauthCallbackResponses[keyof PostSourceOauthCallbackResponses] + +export type DeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + connectionId: string + } + query: { + expectedVersion: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/source-connections/{connectionId}' +} + +export type DeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type DeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdError = + DeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdErrors[keyof DeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdErrors] + +export type DeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponses = { + 200: { + authKind: 'api-key' | 'endpoint' | 'oauth2' + configuration: { + [key: string]: boolean | number | string + } + createdAt: string + errorCode?: string + expiresAt?: string + id: string + knowledgeSpaceId: string + name: string + providerId: string + scopes: Array + status: 'provisioning' | 'active' | 'expired' | 'error' | 'revoked' + updatedAt: string + version: number + } +} + +export type DeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponse = + DeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponses[keyof DeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponses] + +export type GetKnowledgeSpacesByIdSourceConnectionsByConnectionIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + connectionId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/source-connections/{connectionId}' +} + +export type GetKnowledgeSpacesByIdSourceConnectionsByConnectionIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdSourceConnectionsByConnectionIdError = + GetKnowledgeSpacesByIdSourceConnectionsByConnectionIdErrors[keyof GetKnowledgeSpacesByIdSourceConnectionsByConnectionIdErrors] + +export type GetKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponses = { + 200: { + authKind: 'api-key' | 'endpoint' | 'oauth2' + configuration: { + [key: string]: boolean | number | string + } + createdAt: string + errorCode?: string + expiresAt?: string + id: string + knowledgeSpaceId: string + name: string + providerId: string + scopes: Array + status: 'provisioning' | 'active' | 'expired' | 'error' | 'revoked' + updatedAt: string + version: number + } +} + +export type GetKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponse = + GetKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponses[keyof GetKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponses] + +export type PostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshData = { + body: { + expectedVersion: number + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + connectionId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/source-connections/{connectionId}/refresh' +} + +export type PostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ErrorResponse | ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshError = + PostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshErrors[keyof PostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshErrors] + +export type PostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshResponses = { + 200: { + authKind: 'api-key' | 'endpoint' | 'oauth2' + configuration: { + [key: string]: boolean | number | string + } + createdAt: string + errorCode?: string + expiresAt?: string + id: string + knowledgeSpaceId: string + name: string + providerId: string + scopes: Array + status: 'provisioning' | 'active' | 'expired' | 'error' | 'revoked' + updatedAt: string + version: number + } +} + +export type PostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshResponse = + PostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshResponses[keyof PostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshResponses] + +export type GetKnowledgeSpacesByIdSourcesData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: { + cursor?: string + limit?: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/sources' +} + +export type GetKnowledgeSpacesByIdSourcesErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError + 503: { + code: 'CANDIDATE_VISIBILITY_SCAN_BUDGET_EXCEEDED' + error: 'Candidate visibility scan budget exceeded' + } +} + +export type GetKnowledgeSpacesByIdSourcesError = + GetKnowledgeSpacesByIdSourcesErrors[keyof GetKnowledgeSpacesByIdSourcesErrors] + +export type GetKnowledgeSpacesByIdSourcesResponses = { + 200: { + items: Array + nextCursor?: string + } +} + +export type GetKnowledgeSpacesByIdSourcesResponse = + GetKnowledgeSpacesByIdSourcesResponses[keyof GetKnowledgeSpacesByIdSourcesResponses] + +export type PostKnowledgeSpacesByIdSourcesData = { + body: { + connectionId?: string + credentials?: { + [key: string]: unknown + } + metadata?: { + [key: string]: unknown + } + name: string + permissionScope?: Array + status?: 'active' | 'syncing' | 'error' | 'disabled' + type: 'upload' | 'object-storage' | 'connector' | 'web' + uri: string + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources' +} + +export type PostKnowledgeSpacesByIdSourcesErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 429: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type PostKnowledgeSpacesByIdSourcesError = + PostKnowledgeSpacesByIdSourcesErrors[keyof PostKnowledgeSpacesByIdSourcesErrors] + +export type PostKnowledgeSpacesByIdSourcesResponses = { + 201: Source +} + +export type PostKnowledgeSpacesByIdSourcesResponse = + PostKnowledgeSpacesByIdSourcesResponses[keyof PostKnowledgeSpacesByIdSourcesResponses] + +export type DeleteKnowledgeSpacesByIdSourcesBySourceIdData = { + body: { + expectedRevision: number + } + headers: { + 'idempotency-key': string + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: { + documents?: 'cascade' | 'keep' + } + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}' +} + +export type DeleteKnowledgeSpacesByIdSourcesBySourceIdErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type DeleteKnowledgeSpacesByIdSourcesBySourceIdError = + DeleteKnowledgeSpacesByIdSourcesBySourceIdErrors[keyof DeleteKnowledgeSpacesByIdSourcesBySourceIdErrors] + +export type DeleteKnowledgeSpacesByIdSourcesBySourceIdResponses = { + 202: DurableDeletionAccepted +} + +export type DeleteKnowledgeSpacesByIdSourcesBySourceIdResponse = + DeleteKnowledgeSpacesByIdSourcesBySourceIdResponses[keyof DeleteKnowledgeSpacesByIdSourcesBySourceIdResponses] + +export type GetKnowledgeSpacesByIdSourcesBySourceIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}' +} + +export type GetKnowledgeSpacesByIdSourcesBySourceIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdSourcesBySourceIdError = + GetKnowledgeSpacesByIdSourcesBySourceIdErrors[keyof GetKnowledgeSpacesByIdSourcesBySourceIdErrors] + +export type GetKnowledgeSpacesByIdSourcesBySourceIdResponses = { + 200: Source +} + +export type GetKnowledgeSpacesByIdSourcesBySourceIdResponse = + GetKnowledgeSpacesByIdSourcesBySourceIdResponses[keyof GetKnowledgeSpacesByIdSourcesBySourceIdResponses] + +export type PatchKnowledgeSpacesByIdSourcesBySourceIdData = { + body: { + expectedVersion?: number + metadata?: { + [key: string]: unknown + } + name?: string + status?: 'active' | 'syncing' | 'error' | 'disabled' + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}' +} + +export type PatchKnowledgeSpacesByIdSourcesBySourceIdErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type PatchKnowledgeSpacesByIdSourcesBySourceIdError = + PatchKnowledgeSpacesByIdSourcesBySourceIdErrors[keyof PatchKnowledgeSpacesByIdSourcesBySourceIdErrors] + +export type PatchKnowledgeSpacesByIdSourcesBySourceIdResponses = { + 200: Source +} + +export type PatchKnowledgeSpacesByIdSourcesBySourceIdResponse = + PatchKnowledgeSpacesByIdSourcesBySourceIdResponses[keyof PatchKnowledgeSpacesByIdSourcesBySourceIdResponses] + +export type DeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query: { + expectedVersion: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/credentials' +} + +export type DeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type DeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsError = + DeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsErrors[keyof DeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsErrors] + +export type DeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponses = { + 200: Source +} + +export type DeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponse = + DeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponses[keyof DeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponses] + +export type PutKnowledgeSpacesByIdSourcesBySourceIdCredentialsData = { + body: { + credentials: { + [key: string]: unknown + } + expectedVersion: number + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/credentials' +} + +export type PutKnowledgeSpacesByIdSourcesBySourceIdCredentialsErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type PutKnowledgeSpacesByIdSourcesBySourceIdCredentialsError = + PutKnowledgeSpacesByIdSourcesBySourceIdCredentialsErrors[keyof PutKnowledgeSpacesByIdSourcesBySourceIdCredentialsErrors] + +export type PutKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponses = { + 200: Source +} + +export type PutKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponse = + PutKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponses[keyof PutKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponses] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdSyncData = { + body?: never + headers: { + 'Idempotency-Key': string + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/sync' +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdSyncErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdSyncError = + PostKnowledgeSpacesByIdSourcesBySourceIdSyncErrors[keyof PostKnowledgeSpacesByIdSourcesBySourceIdSyncErrors] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdSyncResponses = { + 202: SourceWorkflowRun +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdSyncResponse = + PostKnowledgeSpacesByIdSourcesBySourceIdSyncResponses[keyof PostKnowledgeSpacesByIdSourcesBySourceIdSyncResponses] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewData = { + body?: never + headers: { + 'Idempotency-Key': string + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/crawl-preview' +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewError = + PostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewErrors[keyof PostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewErrors] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewResponses = { + 202: SourceWorkflowRun +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewResponse = + PostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewResponses[keyof PostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewResponses] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsData = { + body: + | { + items: Array<{ + etag?: string + lastEditedTime?: string + name?: string + pageId: string + providerItemId: string + type: string + workspaceId: string + }> + kind: 'online-document-import' + } + | { + items: Array<{ + bucket?: string + etag?: string + id: string + mimeType?: string + name: string + providerItemId: string + }> + kind: 'online-drive-import' + } + headers: { + 'Idempotency-Key': string + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/workflow-imports' +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsError = + PostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsErrors[keyof PostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsErrors] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsResponses = { + 202: SourceWorkflowRun +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsResponse = + PostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsResponses[keyof PostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsResponses] + +export type GetKnowledgeSpacesByIdSourcesBySourceIdPagesData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: { + cursor?: string + limit?: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/pages' +} + +export type GetKnowledgeSpacesByIdSourcesBySourceIdPagesErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 501: ErrorResponse + 502: ErrorResponse | ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdSourcesBySourceIdPagesError = + GetKnowledgeSpacesByIdSourcesBySourceIdPagesErrors[keyof GetKnowledgeSpacesByIdSourcesBySourceIdPagesErrors] + +export type GetKnowledgeSpacesByIdSourcesBySourceIdPagesResponses = { + 200: OnlineDocumentPages +} + +export type GetKnowledgeSpacesByIdSourcesBySourceIdPagesResponse = + GetKnowledgeSpacesByIdSourcesBySourceIdPagesResponses[keyof GetKnowledgeSpacesByIdSourcesBySourceIdPagesResponses] + +export type GetKnowledgeSpacesByIdSourcesBySourceIdFilesData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: { + bucket?: string + continuationToken?: string + maxKeys?: number + prefix?: string + } + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/files' +} + +export type GetKnowledgeSpacesByIdSourcesBySourceIdFilesErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 501: ErrorResponse + 502: ErrorResponse | ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdSourcesBySourceIdFilesError = + GetKnowledgeSpacesByIdSourcesBySourceIdFilesErrors[keyof GetKnowledgeSpacesByIdSourcesBySourceIdFilesErrors] + +export type GetKnowledgeSpacesByIdSourcesBySourceIdFilesResponses = { + 200: OnlineDriveFiles +} + +export type GetKnowledgeSpacesByIdSourcesBySourceIdFilesResponse = + GetKnowledgeSpacesByIdSourcesBySourceIdFilesResponses[keyof GetKnowledgeSpacesByIdSourcesBySourceIdFilesResponses] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdCrawlData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/crawl' +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdCrawlErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 501: ErrorResponse + 502: ErrorResponse | ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdCrawlError = + PostKnowledgeSpacesByIdSourcesBySourceIdCrawlErrors[keyof PostKnowledgeSpacesByIdSourcesBySourceIdCrawlErrors] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdCrawlResponses = { + 200: WebsiteCrawlResult +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdCrawlResponse = + PostKnowledgeSpacesByIdSourcesBySourceIdCrawlResponses[keyof PostKnowledgeSpacesByIdSourcesBySourceIdCrawlResponses] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdImportData = { + body: { + pages: Array<{ + lastEditedTime?: string + name?: string + pageId: string + type: string + workspaceId: string + }> + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/import' +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdImportErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 501: ErrorResponse + 502: ErrorResponse | ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdImportError = + PostKnowledgeSpacesByIdSourcesBySourceIdImportErrors[keyof PostKnowledgeSpacesByIdSourcesBySourceIdImportErrors] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdImportResponses = { + 200: SourceImportResult +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdImportResponse = + PostKnowledgeSpacesByIdSourcesBySourceIdImportResponses[keyof PostKnowledgeSpacesByIdSourcesBySourceIdImportResponses] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdTestData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/test' +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdTestErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 501: ErrorResponse + 502: ErrorResponse | ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdTestError = + PostKnowledgeSpacesByIdSourcesBySourceIdTestErrors[keyof PostKnowledgeSpacesByIdSourcesBySourceIdTestErrors] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdTestResponses = { + 200: SourceCredentialTest +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdTestResponse = + PostKnowledgeSpacesByIdSourcesBySourceIdTestResponses[keyof PostKnowledgeSpacesByIdSourcesBySourceIdTestResponses] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdImportFilesData = { + body: { + files: Array<{ + bucket?: string + id: string + mimeType?: string + name: string + }> + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/import-files' +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdImportFilesErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 501: ErrorResponse + 502: ErrorResponse | ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdImportFilesError = + PostKnowledgeSpacesByIdSourcesBySourceIdImportFilesErrors[keyof PostKnowledgeSpacesByIdSourcesBySourceIdImportFilesErrors] + +export type PostKnowledgeSpacesByIdSourcesBySourceIdImportFilesResponses = { + 200: SourceImportResult +} + +export type PostKnowledgeSpacesByIdSourcesBySourceIdImportFilesResponse = + PostKnowledgeSpacesByIdSourcesBySourceIdImportFilesResponses[keyof PostKnowledgeSpacesByIdSourcesBySourceIdImportFilesResponses] + +export type PostKnowledgeSpacesByIdSourcesBulkData = { + body: { + action: 'sync' | 'disable' | 'remove' + sourceIds: Array + } + headers: { + 'Idempotency-Key': string + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/bulk' +} + +export type PostKnowledgeSpacesByIdSourcesBulkErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdSourcesBulkError = + PostKnowledgeSpacesByIdSourcesBulkErrors[keyof PostKnowledgeSpacesByIdSourcesBulkErrors] + +export type PostKnowledgeSpacesByIdSourcesBulkResponses = { + 202: SourceWorkflowRun +} + +export type PostKnowledgeSpacesByIdSourcesBulkResponse = + PostKnowledgeSpacesByIdSourcesBulkResponses[keyof PostKnowledgeSpacesByIdSourcesBulkResponses] + +export type GetKnowledgeSpacesByIdSourceWorkflowsData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: { + cursor?: string + limit?: number + sourceId?: string + } + url: '/knowledge-fs/knowledge-spaces/{id}/source-workflows' +} + +export type GetKnowledgeSpacesByIdSourceWorkflowsErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdSourceWorkflowsError = + GetKnowledgeSpacesByIdSourceWorkflowsErrors[keyof GetKnowledgeSpacesByIdSourceWorkflowsErrors] + +export type GetKnowledgeSpacesByIdSourceWorkflowsResponses = { + 200: { + items: Array + nextCursor?: string + } +} + +export type GetKnowledgeSpacesByIdSourceWorkflowsResponse = + GetKnowledgeSpacesByIdSourceWorkflowsResponses[keyof GetKnowledgeSpacesByIdSourceWorkflowsResponses] + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + runId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/source-workflows/{runId}' +} + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdError = + GetKnowledgeSpacesByIdSourceWorkflowsByRunIdErrors[keyof GetKnowledgeSpacesByIdSourceWorkflowsByRunIdErrors] + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdResponses = { + 200: SourceWorkflowRun +} + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdResponse = + GetKnowledgeSpacesByIdSourceWorkflowsByRunIdResponses[keyof GetKnowledgeSpacesByIdSourceWorkflowsByRunIdResponses] + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + runId: string + } + query?: { + cursor?: string + limit?: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/source-workflows/{runId}/bulk-items' +} + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsError = + GetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsErrors[keyof GetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsErrors] + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsResponses = { + 200: { + items: Array<{ + action: 'sync' | 'disable' | 'remove' + errorCode?: string + id: string + reason?: string + sourceId: string + status: 'eligible' | 'running' | 'skipped' | 'failed' | 'completed' + updatedAt: string + }> + nextCursor?: string + } +} + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsResponse = + GetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsResponses[keyof GetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsResponses] + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + runId: string + } + query?: { + cursor?: string + limit?: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/source-workflows/{runId}/pages' +} + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesError = + GetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesErrors[keyof GetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesErrors] + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesResponses = { + 200: { + items: Array<{ + description?: string + etag?: string + pageId: string + sourceUrl: string + title?: string + }> + nextCursor?: string + } +} + +export type GetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesResponse = + GetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesResponses[keyof GetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesResponses] + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelData = { + body: { + reason?: string + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + runId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/source-workflows/{runId}/cancel' +} + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelError = + PostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelErrors[keyof PostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelErrors] + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelResponses = { + 200: SourceWorkflowRun +} + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelResponse = + PostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelResponses[keyof PostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelResponses] + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + runId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/source-workflows/{runId}/retry' +} + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryError = + PostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryErrors[keyof PostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryErrors] + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryResponses = { + 200: SourceWorkflowRun +} + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryResponse = + PostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryResponses[keyof PostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryResponses] + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionData = { + body: { + pageIds: Array + } + headers: { + 'Idempotency-Key': string + 'x-trace-id'?: string + } + path: { + id: string + runId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/source-workflows/{runId}/selection' +} + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionError = + PostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionErrors[keyof PostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionErrors] + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionResponses = { + 202: SourceWorkflowRun +} + +export type PostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionResponse = + PostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionResponses[keyof PostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionResponses] + +export type GetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/sync-policy' +} + +export type GetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyError = + GetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyErrors[keyof GetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyErrors] + +export type GetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponses = { + 200: { + createdAt: string + customIntervalSeconds?: number + enabled: boolean + expectedSourceVersion: number + id: string + knowledgeSpaceId: string + mode: 'provider' | 'manual' | 'interval' | 'custom' + nextRunAt?: string + revision: number + sourceId: string + updatedAt: string + } +} + +export type GetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponse = + GetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponses[keyof GetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponses] + +export type PutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyData = { + body: { + customIntervalSeconds?: number + enabled: boolean + expectedRevision: number + expectedSourceVersion: number + mode: 'provider' | 'manual' | 'interval' | 'custom' + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + sourceId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/sources/{sourceId}/sync-policy' +} + +export type PutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type PutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyError = + PutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyErrors[keyof PutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyErrors] + +export type PutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponses = { + 200: { + createdAt: string + customIntervalSeconds?: number + enabled: boolean + expectedSourceVersion: number + id: string + knowledgeSpaceId: string + mode: 'provider' | 'manual' | 'interval' | 'custom' + nextRunAt?: string + revision: number + sourceId: string + updatedAt: string + } +} + +export type PutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponse = + PutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponses[keyof PutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponses] + +export type GetKnowledgeSpacesByIdDocumentsData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: { + cursor?: string + limit?: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/documents' +} + +export type GetKnowledgeSpacesByIdDocumentsErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError + 503: { + code: 'CANDIDATE_VISIBILITY_SCAN_BUDGET_EXCEEDED' + error: 'Candidate visibility scan budget exceeded' + } +} + +export type GetKnowledgeSpacesByIdDocumentsError = + GetKnowledgeSpacesByIdDocumentsErrors[keyof GetKnowledgeSpacesByIdDocumentsErrors] + +export type GetKnowledgeSpacesByIdDocumentsResponses = { + 200: DocumentAssetList +} + +export type GetKnowledgeSpacesByIdDocumentsResponse = + GetKnowledgeSpacesByIdDocumentsResponses[keyof GetKnowledgeSpacesByIdDocumentsResponses] + +export type PostKnowledgeSpacesByIdDocumentsData = { + body: { + documentId?: string + expectedActiveRevision?: number | 'null' + expectedDocumentRowVersion?: number | null + file: Blob | File + sourceId?: string + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents' +} + +export type PostKnowledgeSpacesByIdDocumentsErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 413: ErrorResponse + 429: ErrorResponse + 500: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type PostKnowledgeSpacesByIdDocumentsError = + PostKnowledgeSpacesByIdDocumentsErrors[keyof PostKnowledgeSpacesByIdDocumentsErrors] + +export type PostKnowledgeSpacesByIdDocumentsResponses = { + 201: DocumentAsset + 202: DocumentUploadAccepted +} + +export type PostKnowledgeSpacesByIdDocumentsResponse = + PostKnowledgeSpacesByIdDocumentsResponses[keyof PostKnowledgeSpacesByIdDocumentsResponses] + +export type DeleteKnowledgeSpacesByIdDocumentsBulkData = { + body: { + documents: Array<{ + documentId: string + expectedRevision: number + }> + } + headers: { + 'idempotency-key': string + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/bulk' +} + +export type DeleteKnowledgeSpacesByIdDocumentsBulkErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type DeleteKnowledgeSpacesByIdDocumentsBulkError = + DeleteKnowledgeSpacesByIdDocumentsBulkErrors[keyof DeleteKnowledgeSpacesByIdDocumentsBulkErrors] + +export type DeleteKnowledgeSpacesByIdDocumentsBulkResponses = { + 202: DurableBulkDeletionAccepted +} + +export type DeleteKnowledgeSpacesByIdDocumentsBulkResponse = + DeleteKnowledgeSpacesByIdDocumentsBulkResponses[keyof DeleteKnowledgeSpacesByIdDocumentsBulkResponses] + +export type PostKnowledgeSpacesByIdDocumentsBulkData = { + body: { + files: Array + targets?: string + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/bulk' +} + +export type PostKnowledgeSpacesByIdDocumentsBulkErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 413: ErrorResponse + 429: ErrorResponse + 500: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type PostKnowledgeSpacesByIdDocumentsBulkError = + PostKnowledgeSpacesByIdDocumentsBulkErrors[keyof PostKnowledgeSpacesByIdDocumentsBulkErrors] + +export type PostKnowledgeSpacesByIdDocumentsBulkResponses = { + 202: BulkDocumentUploadAccepted +} + +export type PostKnowledgeSpacesByIdDocumentsBulkResponse = + PostKnowledgeSpacesByIdDocumentsBulkResponses[keyof PostKnowledgeSpacesByIdDocumentsBulkResponses] + +export type PostKnowledgeSpacesByIdDocumentsBulkReindexData = { + body: { + all?: boolean + documentIds?: Array + } + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/bulk/reindex' +} + +export type PostKnowledgeSpacesByIdDocumentsBulkReindexErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 413: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type PostKnowledgeSpacesByIdDocumentsBulkReindexError = + PostKnowledgeSpacesByIdDocumentsBulkReindexErrors[keyof PostKnowledgeSpacesByIdDocumentsBulkReindexErrors] + +export type PostKnowledgeSpacesByIdDocumentsBulkReindexResponses = { + 202: BulkDocumentReindexResult +} + +export type PostKnowledgeSpacesByIdDocumentsBulkReindexResponse = + PostKnowledgeSpacesByIdDocumentsBulkReindexResponses[keyof PostKnowledgeSpacesByIdDocumentsBulkReindexResponses] + +export type DeleteKnowledgeSpacesByIdDocumentsByDocumentIdData = { + body: { + expectedRevision: number + } + headers: { + 'idempotency-key': string + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}' +} + +export type DeleteKnowledgeSpacesByIdDocumentsByDocumentIdErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type DeleteKnowledgeSpacesByIdDocumentsByDocumentIdError = + DeleteKnowledgeSpacesByIdDocumentsByDocumentIdErrors[keyof DeleteKnowledgeSpacesByIdDocumentsByDocumentIdErrors] + +export type DeleteKnowledgeSpacesByIdDocumentsByDocumentIdResponses = { + 202: DurableDeletionAccepted +} + +export type DeleteKnowledgeSpacesByIdDocumentsByDocumentIdResponse = + DeleteKnowledgeSpacesByIdDocumentsByDocumentIdResponses[keyof DeleteKnowledgeSpacesByIdDocumentsByDocumentIdResponses] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}' +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdError = + GetKnowledgeSpacesByIdDocumentsByDocumentIdErrors[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdErrors] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdResponses = { + 200: DocumentAsset +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdResponse = + GetKnowledgeSpacesByIdDocumentsByDocumentIdResponses[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdResponses] + +export type GetKnowledgeSpacesByIdLogicalDocumentsData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: { + cursor?: string + limit?: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/logical-documents' +} + +export type GetKnowledgeSpacesByIdLogicalDocumentsErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdLogicalDocumentsError = + GetKnowledgeSpacesByIdLogicalDocumentsErrors[keyof GetKnowledgeSpacesByIdLogicalDocumentsErrors] + +export type GetKnowledgeSpacesByIdLogicalDocumentsResponses = { + 200: LogicalDocumentList +} + +export type GetKnowledgeSpacesByIdLogicalDocumentsResponse = + GetKnowledgeSpacesByIdLogicalDocumentsResponses[keyof GetKnowledgeSpacesByIdLogicalDocumentsResponses] + +export type DeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdData = { + body: { + expectedRevision: number + } + headers: { + 'idempotency-key': string + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/logical-documents/{documentId}' +} + +export type DeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type DeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdError = + DeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdErrors[keyof DeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdErrors] + +export type DeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponses = { + 202: DurableDeletionAccepted +} + +export type DeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponse = + DeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponses[keyof DeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponses] + +export type GetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/logical-documents/{documentId}' +} + +export type GetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdError = + GetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdErrors[keyof GetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdErrors] + +export type GetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponses = { + 200: LogicalDocument +} + +export type GetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponse = + GetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponses[keyof GetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponses] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/outline' +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineError = + GetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineErrors[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineErrors] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineResponses = { + 200: DocumentOutline +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineResponse = + GetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineResponses[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineResponses] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + } + query?: { + cursor?: string + limit?: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/revisions' +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsError = + GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsErrors[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsErrors] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsResponses = { + 200: DocumentRevisionList +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsResponse = + GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsResponses[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsResponses] + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackData = { + body: { + expectedActiveRevision: number + expectedRowVersion: number + } + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + revision: number + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/revisions/{revision}/rollback' +} + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackError = + PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackErrors[keyof PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackErrors] + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackResponses = { + 202: DocumentProcessingTask +} + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackResponse = + PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackResponses[keyof PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackResponses] + +export type PatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataData = { + body: { + expectedRowVersion: number + patch: { + [key: string]: unknown + } + } + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/metadata' +} + +export type PatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type PatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataError = + PatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataErrors[keyof PatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataErrors] + +export type PatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataResponses = { + 200: LogicalDocument +} + +export type PatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataResponse = + PatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataResponses[keyof PatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataResponses] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + revision: number + } + query?: { + cursor?: string + limit?: number + query?: string + } + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/revisions/{revision}/chunks' +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksError = + GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksErrors[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksErrors] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksResponses = { + 200: DocumentChunkList +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksResponse = + GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksResponses[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksResponses] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + revision: number + chunkId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/revisions/{revision}/chunks/{chunkId}' +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdError = + GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdErrors[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdErrors] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdResponses = + { + 200: DocumentRevisionChunk + } + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdResponse = + GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdResponses[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdResponses] + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateData = + { + body: { + enabled: boolean + } + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + revision: number + chunkId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/revisions/{revision}/chunks/{chunkId}/state' + } + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateErrors = + { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse + } + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateError = + PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateErrors[keyof PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateErrors] + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateResponses = + { + 202: DocumentChunkStateChangeAccepted + } + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateResponse = + PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateResponses[keyof PostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateResponses] + +export type GetKnowledgeSpacesByIdProcessingTasksData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: { + cursor?: string + limit?: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/processing-tasks' +} + +export type GetKnowledgeSpacesByIdProcessingTasksErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdProcessingTasksError = + GetKnowledgeSpacesByIdProcessingTasksErrors[keyof GetKnowledgeSpacesByIdProcessingTasksErrors] + +export type GetKnowledgeSpacesByIdProcessingTasksResponses = { + 200: DocumentProcessingTaskList +} + +export type GetKnowledgeSpacesByIdProcessingTasksResponse = + GetKnowledgeSpacesByIdProcessingTasksResponses[keyof GetKnowledgeSpacesByIdProcessingTasksResponses] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + } + query?: { + cursor?: string + limit?: number + } + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/processing-tasks' +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksErrors = { + 400: ErrorResponse + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksError = + GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksErrors[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksErrors] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksResponses = { + 200: DocumentProcessingTaskList +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksResponse = + GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksResponses[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksResponses] + +export type DeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + taskId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/processing-tasks/{taskId}' +} + +export type DeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type DeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdError = + DeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdErrors[keyof DeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdErrors] + +export type DeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponses = { + 200: DocumentProcessingTask +} + +export type DeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponse = + DeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponses[keyof DeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponses] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + taskId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/processing-tasks/{taskId}' +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdError = + GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdErrors[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdErrors] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponses = { + 200: DocumentProcessingTask +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponse = + GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponses[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponses] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsData = { + body?: never + headers?: { + 'last-event-id'?: string + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + taskId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/processing-tasks/{taskId}/events' +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsError = + GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsErrors[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsErrors] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsResponses = { + 200: DocumentProcessingTaskEvent +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsResponse = + GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsResponses[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsResponses] + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + taskId: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/processing-tasks/{taskId}/retry' +} + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError +} + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryError = + PostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryErrors[keyof PostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryErrors] + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryResponses = { + 200: DocumentProcessingTask +} + +export type PostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryResponse = + PostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryResponses[keyof PostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryResponses] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/settings' +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsError = + GetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsErrors[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsErrors] + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponses = { + 200: DocumentSettingsHead +} + +export type GetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponse = + GetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponses[keyof GetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponses] + +export type PutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsData = { + body: { + expectedSettingsHeadRevision: number | null + settings: { + chunkOverlap: number + chunkSize: number + enableGraph: boolean + enablePageIndex: boolean + language?: string + } + } + headers?: { + 'x-trace-id'?: string + } + path: { + documentId: string + id: string + } + query?: never + url: '/knowledge-fs/knowledge-spaces/{id}/documents/{documentId}/settings' +} + +export type PutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type PutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsError = + PutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsErrors[keyof PutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsErrors] + +export type PutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponses = { + 202: DocumentReindexAccepted +} + +export type PutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponse = + PutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponses[keyof PutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponses] + +export type DeleteJobsByIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/jobs/{id}' +} + +export type DeleteJobsByIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type DeleteJobsByIdError = DeleteJobsByIdErrors[keyof DeleteJobsByIdErrors] + +export type DeleteJobsByIdResponses = { + 200: DocumentCompilationJob +} + +export type DeleteJobsByIdResponse = DeleteJobsByIdResponses[keyof DeleteJobsByIdResponses] + +export type GetJobsByIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/jobs/{id}' +} + +export type GetJobsByIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type GetJobsByIdError = GetJobsByIdErrors[keyof GetJobsByIdErrors] + +export type GetJobsByIdResponses = { + 200: DocumentCompilationJob +} + +export type GetJobsByIdResponse = GetJobsByIdResponses[keyof GetJobsByIdResponses] + +export type PostJobsByIdRetryData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/jobs/{id}/retry' +} + +export type PostJobsByIdRetryErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type PostJobsByIdRetryError = PostJobsByIdRetryErrors[keyof PostJobsByIdRetryErrors] + +export type PostJobsByIdRetryResponses = { + 200: DocumentCompilationJob +} + +export type PostJobsByIdRetryResponse = PostJobsByIdRetryResponses[keyof PostJobsByIdRetryResponses] + +export type GetDeletionJobsByJobIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + jobId: string + } + query?: never + url: '/knowledge-fs/deletion-jobs/{jobId}' +} + +export type GetDeletionJobsByJobIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError +} + +export type GetDeletionJobsByJobIdError = + GetDeletionJobsByJobIdErrors[keyof GetDeletionJobsByJobIdErrors] + +export type GetDeletionJobsByJobIdResponses = { + 200: DurableDeletionJob +} + +export type GetDeletionJobsByJobIdResponse = + GetDeletionJobsByJobIdResponses[keyof GetDeletionJobsByJobIdResponses] + +export type PostDeletionJobsByJobIdRetryData = { + body?: never + headers: { + 'idempotency-key': string + 'x-trace-id'?: string + } + path: { + jobId: string + } + query?: never + url: '/knowledge-fs/deletion-jobs/{jobId}/retry' +} + +export type PostDeletionJobsByJobIdRetryErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 409: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type PostDeletionJobsByJobIdRetryError = + PostDeletionJobsByJobIdRetryErrors[keyof PostDeletionJobsByJobIdRetryErrors] + +export type PostDeletionJobsByJobIdRetryResponses = { + 202: DurableDeletionAccepted +} + +export type PostDeletionJobsByJobIdRetryResponse = + PostDeletionJobsByJobIdRetryResponses[keyof PostDeletionJobsByJobIdRetryResponses] + +export type GetBulkJobsByIdData = { + body?: never + headers?: { + 'x-trace-id'?: string + } + path: { + id: string + } + query?: never + url: '/knowledge-fs/bulk-jobs/{id}' +} + +export type GetBulkJobsByIdErrors = { + 403: ConsoleProxyError + 404: ErrorResponse + 502: ConsoleProxyError + 503: ErrorResponse +} + +export type GetBulkJobsByIdError = GetBulkJobsByIdErrors[keyof GetBulkJobsByIdErrors] + +export type GetBulkJobsByIdResponses = { + 200: BulkOperationProgress +} + +export type GetBulkJobsByIdResponse = GetBulkJobsByIdResponses[keyof GetBulkJobsByIdResponses] diff --git a/packages/contracts/generated/knowledge-fs/zod.gen.ts b/packages/contracts/generated/knowledge-fs/zod.gen.ts index 776479ad6e9..a4ef693c8b0 100644 --- a/packages/contracts/generated/knowledge-fs/zod.gen.ts +++ b/packages/contracts/generated/knowledge-fs/zod.gen.ts @@ -105,6 +105,623 @@ export const zKnowledgeSpaceList = z.object({ nextCursor: z.string().optional(), }) +export const zKnowledgeSpaceStats = z.object({ + cache: z.object({ + available: z.boolean(), + entries: z.int().gte(0), + totalBytes: z.int().gte(0), + }), + commits: z.object({ + failedRetryable: z.int().gte(0), + failedTerminal: z.int().gte(0), + sampled: z.int().gte(0), + truncated: z.boolean(), + }), + generatedAt: z.iso.datetime(), + knowledgeSpaceId: z.uuid(), + metrics: z.object({ + available: z.boolean(), + reason: z.string().optional(), + }), + projections: z.object({ + denseVector: z.object({ + building: z.int().gte(0), + failed: z.int().gte(0), + ready: z.int().gte(0), + stale: z.int().gte(0), + total: z.int().gte(0), + }), + fts: z.object({ + building: z.int().gte(0), + failed: z.int().gte(0), + ready: z.int().gte(0), + stale: z.int().gte(0), + total: z.int().gte(0), + }), + graph: z.object({ + building: z.int().gte(0), + failed: z.int().gte(0), + ready: z.int().gte(0), + stale: z.int().gte(0), + total: z.int().gte(0), + }), + metadata: z.object({ + building: z.int().gte(0), + failed: z.int().gte(0), + ready: z.int().gte(0), + stale: z.int().gte(0), + total: z.int().gte(0), + }), + projectionVersion: z.int().gt(0), + }), + runtime: z.object({ + activeLeaseSampleCount: z.int().gte(0), + activeSessionSampleCount: z.int().gte(0), + truncated: z.boolean(), + }), + storage: z.object({ + documentCount: z.int().gte(0), + rawDocumentBytes: z.int().gte(0), + }), + tenantId: z.string(), + window: z.object({ + end: z.iso.datetime(), + minutes: z.int().gt(0).lte(1440), + start: z.iso.datetime(), + }), +}) + +export const zDurableDeletionJob = z.object({ + checkpoint: z.enum([ + 'requested', + 'quiescing', + 'deleting_objects', + 'deleting_derived_data', + 'deleting_primary_data', + 'completed', + ]), + completedAt: z.iso.datetime().optional(), + createdAt: z.iso.datetime(), + error: z + .object({ + code: z.string().regex(/^[A-Z][A-Z0-9_]{0,63}$/), + message: z.string().min(1).max(256), + retryable: z.boolean(), + }) + .optional(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + mode: z.enum(['cascade', 'keep']).optional(), + progress: z + .object({ + completedItems: z.int().gte(0), + currentItemKind: z.string().min(1).optional(), + totalItems: z.int().gte(0).optional(), + }) + .optional(), + retryAt: z.iso.datetime().optional(), + runState: z.enum([ + 'dispatch_pending', + 'queued', + 'running', + 'retry_wait', + 'completed', + 'failed', + 'canceled', + ]), + targetId: z.uuid(), + targetType: z.enum(['knowledge_space', 'source', 'document', 'logical_document']), + updatedAt: z.iso.datetime(), +}) + +export const zDurableDeletionAccepted = z.object({ + job: zDurableDeletionJob, + statusUrl: z.string().min(1), +}) + +export const zDurableBulkDeletionAccepted = z.object({ + items: z.array( + z.object({ + documentId: z.uuid(), + job: zDurableDeletionJob, + statusUrl: z.string().min(1), + }), + ), + total: z.int().gt(0), +}) + +export const zDocumentAsset = z.object({ + createdAt: z.iso.datetime(), + filename: z.string().min(1).max(512), + id: z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/), + knowledgeSpaceId: z + .string() + .regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/), + metadata: z.record(z.string(), z.unknown()).optional().default({}), + mimeType: z.string().min(1), + objectKey: z.string().min(1), + parserStatus: z.enum(['pending', 'parsed', 'failed']), + sha256: z.string().regex(/^[0-9a-f]{64}$/), + sizeBytes: z.int().gte(0), + sourceId: z + .string() + .regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/) + .optional(), + updatedAt: z.iso.datetime().optional(), + version: z.int().gt(0), +}) + +export const zDocumentAssetList = z.object({ + items: z.array(zDocumentAsset), + nextCursor: z.uuid().optional(), +}) + +export const zDocumentOutlineNode = z.object({ + childNodeIds: z.array(z.string()).optional().default([]), + children: z.array(z.record(z.string(), z.unknown())).optional().default([]), + endOffset: z.int().gte(0).optional(), + endPage: z.int().gt(0).optional(), + id: z.string(), + level: z.int().gt(0), + metadata: z.record(z.string(), z.unknown()), + sectionPath: z.array(z.string()).optional().default([]), + sourceElementIds: z.array(z.string()).optional().default([]), + sourceNodeIds: z.array(z.string()).optional().default([]), + startOffset: z.int().gte(0).optional(), + startPage: z.int().gt(0).optional(), + summary: z.string().optional(), + title: z.string(), + titleLocation: z.record(z.string(), z.unknown()).optional(), + tocSource: z.string(), +}) + +export const zDocumentOutline = z.object({ + artifactHash: z.string(), + createdAt: z.string(), + documentAssetId: z.uuid(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + metadata: z.record(z.string(), z.unknown()), + nodes: z.array(zDocumentOutlineNode), + outlineVersion: z.string(), + parseArtifactId: z.uuid(), + updatedAt: z.string().optional(), + version: z.int().gt(0), +}) + +export const zLogicalDocumentRevision = z + .object({ + activatedAt: z.string().optional(), + contentHash: z.string().length(64), + createdAt: z.string(), + documentAssetId: z.uuid(), + documentAssetVersion: z.int().gt(0), + documentId: z.uuid(), + knowledgeSpaceId: z.uuid(), + mimeType: z.string(), + revision: z.int().gt(0), + sizeBytes: z.int().gte(0), + state: z.enum(['candidate', 'active', 'superseded', 'failed']), + }) + .nullable() + +export const zLogicalDocument = z.object({ + active: zLogicalDocumentRevision, + activeRevision: z.int().gt(0).optional(), + createdAt: z.string(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + providerItemId: z.string().optional(), + rowVersion: z.int().gte(0), + sourceId: z.uuid().optional(), + status: z.enum(['pending', 'ready', 'failed', 'deleting']), + title: z.string(), + updatedAt: z.string(), + userMetadata: z.record(z.string(), z.unknown()), +}) + +export const zLogicalDocumentList = z.object({ + items: z.array(zLogicalDocument), + nextCursor: z.string().optional(), +}) + +export const zDocumentRevisionList = z.object({ + items: z.array(zLogicalDocumentRevision.and(z.record(z.string(), z.unknown()))), + nextCursor: z.string().optional(), +}) + +export const zDocumentProcessingTask = z.object({ + completedAt: z.string().optional(), + createdAt: z.string(), + documentId: z.uuid(), + documentRevision: z.int().gt(0), + errorCode: z.string().optional(), + errorMessage: z.string().optional(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + progressPercent: z.int().gte(0).lte(100), + retryAt: z.string().optional(), + stage: z.enum([ + 'queued', + 'parsed', + 'outline_built', + 'nodes_generated', + 'projection_built', + 'smoke_eval_passed', + 'published', + ]), + state: z.enum([ + 'dispatch_pending', + 'queued', + 'running', + 'retry_wait', + 'succeeded', + 'failed', + 'canceled', + 'superseded', + ]), + updatedAt: z.string(), +}) + +export const zDocumentRevisionChunk = z.object({ + createdAt: z.string(), + documentId: z.uuid(), + documentRevision: z.int().gt(0), + enabled: z.boolean(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + ordinal: z.int().gte(0), + parentChunkId: z.uuid().optional(), + text: z.string(), + tokenCount: z.int().gte(0), + userMetadata: z.record(z.string(), z.unknown()), +}) + +export const zDocumentChunkList = z.object({ + items: z.array(zDocumentRevisionChunk), + nextCursor: z.string().optional(), +}) + +export const zDocumentChunkStateChangeAccepted = z.object({ + candidateFingerprint: z.string().optional(), + candidatePublicationId: z.uuid().optional(), + chunkId: z.uuid(), + compilationAttemptId: z.uuid(), + createdAt: z.string(), + documentId: z.uuid(), + documentRevision: z.int().gt(0), + enabled: z.boolean(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + state: z.enum(['candidate']), + statusUrl: z.string().min(1), +}) + +export const zDocumentProcessingTaskList = z.object({ + items: z.array(zDocumentProcessingTask), + nextCursor: z.string().optional(), +}) + +export const zDocumentProcessingTaskEvent = z.union([ + z.object({ + data: z.object({ + progressPercent: z.int().gte(0).lte(100), + stage: z.enum([ + 'queued', + 'parsed', + 'outline_built', + 'nodes_generated', + 'projection_built', + 'smoke_eval_passed', + 'published', + ]), + state: z.enum([ + 'dispatch_pending', + 'queued', + 'running', + 'retry_wait', + 'succeeded', + 'failed', + 'canceled', + 'superseded', + ]), + updatedAt: z.string(), + }), + event: z.enum(['progress']), + }), + z.object({ + data: z.object({ + errorCode: z.string().optional(), + state: z.enum(['succeeded', 'failed', 'canceled', 'superseded']), + }), + event: z.enum(['terminal']), + }), +]) + +export const zDocumentSettingsHead = z.object({ + activeRevision: z.int().gt(0), + profile: z.object({ + activatedAt: z.string().optional(), + createdAt: z.string(), + revision: z.int().gt(0), + settings: z.object({ + chunkOverlap: z.int().gte(0).lte(8191), + chunkSize: z.int().gte(128).lte(8192), + enableGraph: z.boolean(), + enablePageIndex: z.boolean(), + language: z.string().min(2).max(64).optional(), + }), + state: z.enum(['active']), + }), + rowVersion: z.int().gte(0), + updatedAt: z.string(), +}) + +export const zDocumentReindexAccepted = z.object({ + attemptId: z.uuid(), + compilationAttemptId: z.uuid(), + settingsRevision: z.int().gt(0), + state: z.enum(['running']), + statusUrl: z.string(), +}) + +export const zDocumentCompilationJob = z.object({ + baseHeadRevision: z.int().gte(0).optional(), + candidateFingerprint: z.string().min(1).optional(), + candidatePublicationId: z.uuid().optional(), + completedAt: z.number().optional(), + createdAt: z.number(), + documentAssetId: z.string().min(1), + error: z.string().optional(), + executionAttempts: z.int().gte(0).optional(), + id: z.string().min(1), + knowledgeSpaceId: z.string().min(1), + leaseExpiresAt: z.number().optional(), + maxExecutionAttempts: z.int().gt(0).optional(), + publicationGenerationId: z + .string() + .regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/) + .optional(), + queueJobId: z.string().min(1).optional(), + retryAt: z.number().optional(), + runState: z + .enum([ + 'dispatch_pending', + 'queued', + 'running', + 'retry_wait', + 'succeeded', + 'failed', + 'canceled', + 'superseded', + ]) + .optional(), + stage: z.enum([ + 'queued', + 'parsed', + 'outline_built', + 'nodes_generated', + 'projection_built', + 'smoke_eval_passed', + 'published', + 'failed', + 'canceled', + ]), + tenantId: z.string().min(1).max(255), + updatedAt: z.number(), + version: z.int().gt(0), +}) + +export const zBulkOperationProgress = z.object({ + completedItems: z.int().gte(0), + createdAt: z.string(), + failedItemIds: z.array(z.string().min(1)), + failedItems: z.int().gte(0), + id: z.string().min(1), + knowledgeSpaceId: z.string().min(1), + status: z.enum(['running', 'completed', 'failed']), + totalItems: z.int().gte(0), + type: z.enum(['document_upload', 'document_delete', 'document_reindex']), + updatedAt: z.string(), +}) + +export const zBulkDocumentReindexResult = z.object({ + bulkJobId: z.string().min(1), + items: z.array( + z.union([ + z.object({ + asset: zDocumentAsset, + compilationJob: z.object({ + id: z.string().min(1), + stage: z.enum(['queued']), + }), + status: z.enum(['queued']), + statusUrl: z.string().min(1), + }), + z.object({ + documentId: z.uuid(), + status: z.enum(['not_found']), + }), + ]), + ), + total: z.int().gte(0), +}) + +export const zDocumentUploadAccepted = z.object({ + asset: zDocumentAsset, + assetStatusUrl: z.string().min(1).optional(), + compilationJob: z.object({ + id: z.string().min(1), + stage: z.enum(['queued']), + }), + logicalDocument: z.object({ + id: z.uuid(), + revision: z.int().gt(0), + }), + logicalDocumentId: z.uuid(), + documentRevision: z.int().gt(0), + statusUrl: z.string().min(1), + status: z.enum(['accepted']).optional(), +}) + +export const zBulkDocumentUploadAccepted = z.object({ + accepted: z.int().gte(0), + bulkJobId: z.string().min(1), + excluded: z.int().gte(0), + items: z.array( + z.union([ + zDocumentUploadAccepted, + z.object({ + filename: z.string(), + index: z.int().gte(0), + mimeType: z.string(), + reason: z.enum([ + 'batch_byte_limit_exceeded', + 'document_not_found', + 'file_count_limit_exceeded', + 'file_too_large', + 'invalid_file', + 'invalid_target', + 'processing_failed', + 'quota_exceeded', + 'revision_conflict', + 'unsupported_mime_type', + ]), + sizeBytes: z.int().gte(0), + status: z.enum(['excluded']), + }), + ]), + ), + total: z.int().gte(0), +}) + +export const zSourceWorkflowRun = z.object({ + canceledAt: z.string().optional(), + checkpoint: z.string(), + completedAt: z.string().optional(), + createdAt: z.string(), + cursor: z.string().optional(), + executionAttempts: z.int(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + kind: z.string(), + lastErrorCode: z.string().optional(), + maxExecutionAttempts: z.int(), + progressCompleted: z.int(), + progressFailed: z.int(), + progressSkipped: z.int(), + progressTotal: z.int().optional(), + sourceId: z.uuid().optional(), + state: z.string(), + updatedAt: z.string(), +}) + +export const zSource = z.object({ + connectionId: z + .string() + .regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/) + .optional(), + createdAt: z.iso.datetime(), + id: z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/), + knowledgeSpaceId: z + .string() + .regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/), + metadata: z.record(z.string(), z.unknown()), + name: z.string().min(1).max(200), + permissionScope: z.array(z.string().min(1)).optional().default([]), + status: z.enum(['active', 'syncing', 'error', 'disabled']), + type: z.enum(['upload', 'object-storage', 'connector', 'web']), + updatedAt: z.iso.datetime(), + uri: z.string().min(1), + version: z.int().gte(1).optional().default(1), + credentialConfigured: z.boolean().optional(), +}) + +export const zWebsiteCrawlResult = z.object({ + completed: z.number().optional(), + failed: z.number().optional(), + imported: z.number().optional(), + pages: z.array( + z.object({ + content: z.string(), + description: z.string().optional(), + sourceUrl: z.string(), + title: z.string().optional(), + }), + ), + replaced: z.number().optional(), + skipped: z.number().optional(), + status: z.string().optional(), + total: z.number().optional(), +}) + +export const zOnlineDocumentPages = z.object({ + nextCursor: z.string().optional(), + workspaces: z.array( + z.object({ + pages: z.array( + z.object({ + lastEditedTime: z.string().optional(), + pageId: z.string(), + pageName: z.string(), + parentId: z.string().optional(), + type: z.string(), + }), + ), + total: z.number().optional(), + workspaceId: z.string().optional(), + workspaceName: z.string().optional(), + }), + ), +}) + +export const zSourceImportResult = z.object({ + documents: z.array( + z.object({ + documentAssetId: z.string(), + filename: z.string(), + }), + ), + failed: z.array( + z.object({ + code: z.string(), + error: z.string(), + filename: z.string(), + }), + ), + skipped: z.array(z.string()), +}) + +export const zSourceCredentialTest = z.object({ + code: z.string().optional(), + error: z.string().optional(), + valid: z.boolean(), +}) + +export const zOnlineDriveFiles = z.object({ + buckets: z.array( + z.object({ + bucket: z.string().optional(), + continuationToken: z.string().optional(), + files: z.array( + z.object({ + id: z.string(), + name: z.string(), + size: z.number().optional(), + type: z.string(), + }), + ), + isTruncated: z.boolean().optional(), + }), + ), +}) + +export const zConsoleProxyError = z.object({ + code: z.string(), + message: z.string(), + status: z.int(), +}) + export const zListKnowledgeSpacesHeaders = z.object({ 'x-trace-id': z.string().optional(), }) @@ -129,3 +746,1512 @@ export const zCreateKnowledgeSpaceHeaders = z.object({ * Created knowledge space */ export const zCreateKnowledgeSpaceResponse = zKnowledgeSpaceCreationResponse + +export const zDeleteKnowledgeSpacesByIdBody = z.object({ + challenge: z.string().min(1).max(160), + expectedRevision: z.int().gt(0), +}) + +export const zDeleteKnowledgeSpacesByIdHeaders = z.object({ + 'idempotency-key': z.string().min(8).max(255), + 'x-trace-id': z.string().optional(), +}) + +export const zDeleteKnowledgeSpacesByIdPath = z.object({ + id: z.uuid(), +}) + +/** + * Durable deletion accepted + */ +export const zDeleteKnowledgeSpacesByIdResponse = zDurableDeletionAccepted + +export const zGetKnowledgeSpacesByIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdPath = z.object({ + id: z.uuid(), +}) + +/** + * Knowledge space + */ +export const zGetKnowledgeSpacesByIdResponse = zKnowledgeSpace + +export const zPatchKnowledgeSpacesByIdBody = z.object({ + description: z.string().max(2000).optional(), + expectedRevision: z.int().gt(0), + iconRef: z + .string() + .max(72) + .regex(/^builtin:[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/) + .nullish(), + name: z.string().min(1).max(160).optional(), + slug: z + .string() + .max(160) + .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/) + .optional(), +}) + +export const zPatchKnowledgeSpacesByIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPatchKnowledgeSpacesByIdPath = z.object({ + id: z.uuid(), +}) + +/** + * Updated knowledge space + */ +export const zPatchKnowledgeSpacesByIdResponse = zKnowledgeSpace + +export const zGetKnowledgeSpacesByIdStatsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdStatsPath = z.object({ + id: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdStatsQuery = z.object({ + windowMinutes: z.int().gte(1).lte(1440).optional(), +}) + +/** + * Low-cardinality KnowledgeSpace statistics + */ +export const zGetKnowledgeSpacesByIdStatsResponse = zKnowledgeSpaceStats + +export const zGetKnowledgeSpacesByIdAccessPolicyHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdAccessPolicyPath = z.object({ + id: z.uuid(), +}) + +/** + * Knowledge space visibility policy + */ +export const zGetKnowledgeSpacesByIdAccessPolicyResponse = z.object({ + id: z.string().min(1), + ownerSubjectId: z.string().min(1).max(255), + partialMemberSubjectIds: z.array(z.string().min(1).max(255)), + revision: z.int().gt(0), + visibility: z.enum(['only_me', 'all_members', 'partial_members']), +}) + +export const zPatchKnowledgeSpacesByIdAccessPolicyBody = z.object({ + expectedRevision: z.int().gt(0), + partialMemberSubjectIds: z.array(z.string().min(1).max(255)).max(500).optional().default([]), + visibility: z.enum(['only_me', 'all_members', 'partial_members']), +}) + +export const zPatchKnowledgeSpacesByIdAccessPolicyHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPatchKnowledgeSpacesByIdAccessPolicyPath = z.object({ + id: z.uuid(), +}) + +/** + * Updated knowledge space visibility policy + */ +export const zPatchKnowledgeSpacesByIdAccessPolicyResponse = z.object({ + id: z.string().min(1), + ownerSubjectId: z.string().min(1).max(255), + partialMemberSubjectIds: z.array(z.string().min(1).max(255)), + revision: z.int().gt(0), + visibility: z.enum(['only_me', 'all_members', 'partial_members']), +}) + +export const zGetSourceProvidersHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +/** + * Source provider capability catalog + */ +export const zGetSourceProvidersResponse = z.object({ + items: z.array( + z.object({ + authKinds: z.array(z.enum(['api-key', 'endpoint', 'oauth2'])), + available: z.boolean(), + capabilities: z.array(z.enum(['website-crawl', 'online-document', 'online-drive'])), + configuration: z.array( + z.object({ + description: z.string().optional(), + format: z.enum(['password', 'uri']).optional(), + name: z.string(), + required: z.boolean(), + secret: z.boolean(), + type: z.enum(['boolean', 'integer', 'string']), + }), + ), + displayName: z.string(), + id: z.string(), + unavailableReason: z.string().optional(), + }), + ), +}) + +export const zGetKnowledgeSpacesByIdSourceConnectionsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourceConnectionsPath = z.object({ + id: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdSourceConnectionsQuery = z.object({ + cursor: z.string().max(4096).optional(), + limit: z.int().gte(1).lte(200).optional().default(50), +}) + +/** + * Source connections + */ +export const zGetKnowledgeSpacesByIdSourceConnectionsResponse = z.object({ + items: z.array( + z.object({ + authKind: z.enum(['api-key', 'endpoint', 'oauth2']), + configuration: z.record(z.string(), z.union([z.boolean(), z.number(), z.string()])), + createdAt: z.string(), + errorCode: z.string().optional(), + expiresAt: z.string().optional(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + name: z.string(), + providerId: z.string(), + scopes: z.array(z.string()), + status: z.enum(['provisioning', 'active', 'expired', 'error', 'revoked']), + updatedAt: z.string(), + version: z.int(), + }), + ), + nextCursor: z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourceConnectionsBody = z.object({ + authKind: z.enum(['api-key', 'endpoint']), + configuration: z.record(z.string(), z.union([z.boolean(), z.number(), z.string()])).optional(), + credentials: z.record(z.string(), z.unknown()), + name: z.string().min(1).max(160), + providerId: z.string().min(1).max(128), +}) + +export const zPostKnowledgeSpacesByIdSourceConnectionsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourceConnectionsPath = z.object({ + id: z.uuid(), +}) + +/** + * Source connection created + */ +export const zPostKnowledgeSpacesByIdSourceConnectionsResponse = z.object({ + authKind: z.enum(['api-key', 'endpoint', 'oauth2']), + configuration: z.record(z.string(), z.union([z.boolean(), z.number(), z.string()])), + createdAt: z.string(), + errorCode: z.string().optional(), + expiresAt: z.string().optional(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + name: z.string(), + providerId: z.string(), + scopes: z.array(z.string()), + status: z.enum(['provisioning', 'active', 'expired', 'error', 'revoked']), + updatedAt: z.string(), + version: z.int(), +}) + +export const zPostKnowledgeSpacesByIdSourceConnectionsOauthBody = z.object({ + configuration: z.record(z.string(), z.union([z.boolean(), z.number(), z.string()])).optional(), + name: z.string().min(1).max(160), + providerId: z.string().min(1).max(128), + redirectUri: z.string().min(1).max(2048), + scopes: z.array(z.string().min(1).max(255)).max(100).optional().default([]), +}) + +export const zPostKnowledgeSpacesByIdSourceConnectionsOauthHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourceConnectionsOauthPath = z.object({ + id: z.uuid(), +}) + +/** + * OAuth authorization started + */ +export const zPostKnowledgeSpacesByIdSourceConnectionsOauthResponse = z.object({ + authorizationUrl: z.string(), + connection: z.object({ + authKind: z.enum(['api-key', 'endpoint', 'oauth2']), + configuration: z.record(z.string(), z.union([z.boolean(), z.number(), z.string()])), + createdAt: z.string(), + errorCode: z.string().optional(), + expiresAt: z.string().optional(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + name: z.string(), + providerId: z.string(), + scopes: z.array(z.string()), + status: z.enum(['provisioning', 'active', 'expired', 'error', 'revoked']), + updatedAt: z.string(), + version: z.int(), + }), +}) + +export const zPostSourceOauthCallbackBody = z.object({ + code: z.string().min(1).max(8192), + state: z.string().min(32).max(256), +}) + +export const zPostSourceOauthCallbackHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +/** + * OAuth connection activated + */ +export const zPostSourceOauthCallbackResponse = z.object({ + authKind: z.enum(['api-key', 'endpoint', 'oauth2']), + configuration: z.record(z.string(), z.union([z.boolean(), z.number(), z.string()])), + createdAt: z.string(), + errorCode: z.string().optional(), + expiresAt: z.string().optional(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + name: z.string(), + providerId: z.string(), + scopes: z.array(z.string()), + status: z.enum(['provisioning', 'active', 'expired', 'error', 'revoked']), + updatedAt: z.string(), + version: z.int(), +}) + +export const zDeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zDeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdPath = z.object({ + id: z.uuid(), + connectionId: z.uuid(), +}) + +export const zDeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdQuery = z.object({ + expectedVersion: z.int().gte(1), +}) + +/** + * Source connection locally revoked + */ +export const zDeleteKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponse = z.object({ + authKind: z.enum(['api-key', 'endpoint', 'oauth2']), + configuration: z.record(z.string(), z.union([z.boolean(), z.number(), z.string()])), + createdAt: z.string(), + errorCode: z.string().optional(), + expiresAt: z.string().optional(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + name: z.string(), + providerId: z.string(), + scopes: z.array(z.string()), + status: z.enum(['provisioning', 'active', 'expired', 'error', 'revoked']), + updatedAt: z.string(), + version: z.int(), +}) + +export const zGetKnowledgeSpacesByIdSourceConnectionsByConnectionIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourceConnectionsByConnectionIdPath = z.object({ + id: z.uuid(), + connectionId: z.uuid(), +}) + +/** + * Source connection + */ +export const zGetKnowledgeSpacesByIdSourceConnectionsByConnectionIdResponse = z.object({ + authKind: z.enum(['api-key', 'endpoint', 'oauth2']), + configuration: z.record(z.string(), z.union([z.boolean(), z.number(), z.string()])), + createdAt: z.string(), + errorCode: z.string().optional(), + expiresAt: z.string().optional(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + name: z.string(), + providerId: z.string(), + scopes: z.array(z.string()), + status: z.enum(['provisioning', 'active', 'expired', 'error', 'revoked']), + updatedAt: z.string(), + version: z.int(), +}) + +export const zPostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshBody = z.object({ + expectedVersion: z.int().gte(1), +}) + +export const zPostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshPath = z.object({ + id: z.uuid(), + connectionId: z.uuid(), +}) + +/** + * Source connection refreshed + */ +export const zPostKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefreshResponse = z.object({ + authKind: z.enum(['api-key', 'endpoint', 'oauth2']), + configuration: z.record(z.string(), z.union([z.boolean(), z.number(), z.string()])), + createdAt: z.string(), + errorCode: z.string().optional(), + expiresAt: z.string().optional(), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + name: z.string(), + providerId: z.string(), + scopes: z.array(z.string()), + status: z.enum(['provisioning', 'active', 'expired', 'error', 'revoked']), + updatedAt: z.string(), + version: z.int(), +}) + +export const zGetKnowledgeSpacesByIdSourcesHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourcesPath = z.object({ + id: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdSourcesQuery = z.object({ + cursor: z.string().optional(), + limit: z.int().gte(1).lte(200).optional(), +}) + +/** + * Knowledge space sources + */ +export const zGetKnowledgeSpacesByIdSourcesResponse = z.object({ + items: z.array(zSource), + nextCursor: z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourcesBody = z.object({ + connectionId: z.uuid().optional(), + credentials: z.record(z.string(), z.unknown()).optional(), + metadata: z.record(z.string(), z.unknown()).optional(), + name: z.string().min(1).max(200), + permissionScope: z.array(z.string().min(1)).optional(), + status: z.enum(['active', 'syncing', 'error', 'disabled']).optional(), + type: z.enum(['upload', 'object-storage', 'connector', 'web']), + uri: z.string().min(1), +}) + +export const zPostKnowledgeSpacesByIdSourcesHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourcesPath = z.object({ + id: z.uuid(), +}) + +/** + * Created source + */ +export const zPostKnowledgeSpacesByIdSourcesResponse = zSource + +export const zDeleteKnowledgeSpacesByIdSourcesBySourceIdBody = z.object({ + expectedRevision: z.int().gt(0), +}) + +export const zDeleteKnowledgeSpacesByIdSourcesBySourceIdHeaders = z.object({ + 'idempotency-key': z.string().min(8).max(255), + 'x-trace-id': z.string().optional(), +}) + +export const zDeleteKnowledgeSpacesByIdSourcesBySourceIdPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +export const zDeleteKnowledgeSpacesByIdSourcesBySourceIdQuery = z.object({ + documents: z.enum(['cascade', 'keep']).optional().default('cascade'), +}) + +/** + * Durable deletion accepted + */ +export const zDeleteKnowledgeSpacesByIdSourcesBySourceIdResponse = zDurableDeletionAccepted + +export const zGetKnowledgeSpacesByIdSourcesBySourceIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourcesBySourceIdPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +/** + * Source + */ +export const zGetKnowledgeSpacesByIdSourcesBySourceIdResponse = zSource + +export const zPatchKnowledgeSpacesByIdSourcesBySourceIdBody = z.object({ + expectedVersion: z.int().gte(1).optional(), + metadata: z.record(z.string(), z.unknown()).optional(), + name: z.string().min(1).max(200).optional(), + status: z.enum(['active', 'syncing', 'error', 'disabled']).optional(), +}) + +export const zPatchKnowledgeSpacesByIdSourcesBySourceIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPatchKnowledgeSpacesByIdSourcesBySourceIdPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +/** + * Updated source + */ +export const zPatchKnowledgeSpacesByIdSourcesBySourceIdResponse = zSource + +export const zDeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zDeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +export const zDeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsQuery = z.object({ + expectedVersion: z.int().gte(1), +}) + +/** + * Revoked source credentials + */ +export const zDeleteKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponse = zSource + +export const zPutKnowledgeSpacesByIdSourcesBySourceIdCredentialsBody = z.object({ + credentials: z.record(z.string(), z.unknown()), + expectedVersion: z.int().gte(1), +}) + +export const zPutKnowledgeSpacesByIdSourcesBySourceIdCredentialsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPutKnowledgeSpacesByIdSourcesBySourceIdCredentialsPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +/** + * Rotated source credentials; secret bytes are returned neither here nor later + */ +export const zPutKnowledgeSpacesByIdSourcesBySourceIdCredentialsResponse = zSource + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdSyncHeaders = z.object({ + 'Idempotency-Key': z.string().min(1).max(255), + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdSyncPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +/** + * Durable source sync accepted + */ +export const zPostKnowledgeSpacesByIdSourcesBySourceIdSyncResponse = zSourceWorkflowRun + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewHeaders = z.object({ + 'Idempotency-Key': z.string().min(1).max(255), + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +/** + * Durable crawl preview accepted + */ +export const zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlPreviewResponse = zSourceWorkflowRun + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsBody = z.union([ + z.object({ + items: z + .array( + z.object({ + etag: z.string().max(2048).optional(), + lastEditedTime: z.string().max(2048).optional(), + name: z.string().max(500).optional(), + pageId: z.string().min(1).max(2048), + providerItemId: z.string().min(1).max(2048), + type: z.string().min(1).max(128), + workspaceId: z.string().min(1).max(2048), + }), + ) + .min(1) + .max(200), + kind: z.enum(['online-document-import']), + }), + z.object({ + items: z + .array( + z.object({ + bucket: z.string().max(2048).optional(), + etag: z.string().max(2048).optional(), + id: z.string().min(1).max(2048), + mimeType: z.string().max(255).optional(), + name: z.string().min(1).max(500), + providerItemId: z.string().min(1).max(2048), + }), + ) + .min(1) + .max(200), + kind: z.enum(['online-drive-import']), + }), +]) + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsHeaders = z.object({ + 'Idempotency-Key': z.string().min(1).max(255), + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +/** + * Durable provider import accepted + */ +export const zPostKnowledgeSpacesByIdSourcesBySourceIdWorkflowImportsResponse = zSourceWorkflowRun + +export const zGetKnowledgeSpacesByIdSourcesBySourceIdPagesHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourcesBySourceIdPagesPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdSourcesBySourceIdPagesQuery = z.object({ + cursor: z.string().min(1).max(4096).optional(), + limit: z.int().gte(1).lte(200).optional().default(50), +}) + +/** + * Authorized online-document pages + */ +export const zGetKnowledgeSpacesByIdSourcesBySourceIdPagesResponse = zOnlineDocumentPages + +export const zGetKnowledgeSpacesByIdSourcesBySourceIdFilesHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourcesBySourceIdFilesPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdSourcesBySourceIdFilesQuery = z.object({ + bucket: z.string().optional(), + continuationToken: z.string().min(1).max(4096).optional(), + maxKeys: z.int().gte(1).lte(1000).optional(), + prefix: z.string().optional(), +}) + +/** + * Online-drive files + */ +export const zGetKnowledgeSpacesByIdSourcesBySourceIdFilesResponse = zOnlineDriveFiles + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +/** + * Website crawl result + */ +export const zPostKnowledgeSpacesByIdSourcesBySourceIdCrawlResponse = zWebsiteCrawlResult + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdImportBody = z.object({ + pages: z + .array( + z.object({ + lastEditedTime: z.string().min(1).optional(), + name: z.string().min(1).max(200).optional(), + pageId: z.string().min(1), + type: z.string().min(1), + workspaceId: z.string().min(1), + }), + ) + .min(1) + .max(200), +}) + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdImportHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdImportPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +/** + * Imported online-document pages + */ +export const zPostKnowledgeSpacesByIdSourcesBySourceIdImportResponse = zSourceImportResult + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdTestHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdTestPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +/** + * Source credential validation result + */ +export const zPostKnowledgeSpacesByIdSourcesBySourceIdTestResponse = zSourceCredentialTest + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdImportFilesBody = z.object({ + files: z + .array( + z.object({ + bucket: z.string().optional(), + id: z.string().min(1), + mimeType: z.string().optional(), + name: z.string().min(1).max(255), + }), + ) + .min(1) + .max(200), +}) + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdImportFilesHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourcesBySourceIdImportFilesPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +/** + * Imported online-drive files + */ +export const zPostKnowledgeSpacesByIdSourcesBySourceIdImportFilesResponse = zSourceImportResult + +export const zPostKnowledgeSpacesByIdSourcesBulkBody = z.object({ + action: z.enum(['sync', 'disable', 'remove']), + sourceIds: z.array(z.uuid()).min(1).max(200), +}) + +export const zPostKnowledgeSpacesByIdSourcesBulkHeaders = z.object({ + 'Idempotency-Key': z.string().min(1).max(255), + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourcesBulkPath = z.object({ + id: z.uuid(), +}) + +/** + * Durable bulk source workflow accepted + */ +export const zPostKnowledgeSpacesByIdSourcesBulkResponse = zSourceWorkflowRun + +export const zGetKnowledgeSpacesByIdSourceWorkflowsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourceWorkflowsPath = z.object({ + id: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdSourceWorkflowsQuery = z.object({ + cursor: z.string().max(4096).optional(), + limit: z.int().gte(1).lte(200).optional().default(50), + sourceId: z.uuid().optional(), +}) + +/** + * Source workflow history + */ +export const zGetKnowledgeSpacesByIdSourceWorkflowsResponse = z.object({ + items: z.array(zSourceWorkflowRun), + nextCursor: z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPath = z.object({ + id: z.uuid(), + runId: z.uuid(), +}) + +/** + * Source workflow + */ +export const zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdResponse = zSourceWorkflowRun + +export const zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsPath = z.object({ + id: z.uuid(), + runId: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsQuery = z.object({ + cursor: z.string().max(4096).optional(), + limit: z.int().gte(1).lte(200).optional().default(50), +}) + +/** + * Per-source bulk workflow results + */ +export const zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdBulkItemsResponse = z.object({ + items: z.array( + z.object({ + action: z.enum(['sync', 'disable', 'remove']), + errorCode: z.string().optional(), + id: z.uuid(), + reason: z.string().optional(), + sourceId: z.uuid(), + status: z.enum(['eligible', 'running', 'skipped', 'failed', 'completed']), + updatedAt: z.string(), + }), + ), + nextCursor: z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesPath = z.object({ + id: z.uuid(), + runId: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesQuery = z.object({ + cursor: z.string().max(4096).optional(), + limit: z.int().gte(1).lte(200).optional().default(50), +}) + +/** + * Crawl preview pages (content excluded) + */ +export const zGetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesResponse = z.object({ + items: z.array( + z.object({ + description: z.string().optional(), + etag: z.string().optional(), + pageId: z.string(), + sourceUrl: z.string(), + title: z.string().optional(), + }), + ), + nextCursor: z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelBody = z.object({ + reason: z.string().max(1000).optional(), +}) + +export const zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelPath = z.object({ + id: z.uuid(), + runId: z.uuid(), +}) + +/** + * Source workflow canceled + */ +export const zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdCancelResponse = zSourceWorkflowRun + +export const zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryPath = z.object({ + id: z.uuid(), + runId: z.uuid(), +}) + +/** + * Source workflow retried + */ +export const zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdRetryResponse = zSourceWorkflowRun + +export const zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionBody = z.object({ + pageIds: z.array(z.string().min(1).max(128)).min(1).max(200), +}) + +export const zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionHeaders = z.object({ + 'Idempotency-Key': z.string().min(1).max(255), + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionPath = z.object({ + id: z.uuid(), + runId: z.uuid(), +}) + +/** + * Crawl import selection accepted + */ +export const zPostKnowledgeSpacesByIdSourceWorkflowsByRunIdSelectionResponse = zSourceWorkflowRun + +export const zGetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +/** + * Source sync policy + */ +export const zGetKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponse = z.object({ + createdAt: z.string(), + customIntervalSeconds: z.int().optional(), + enabled: z.boolean(), + expectedSourceVersion: z.int().gte(1), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + mode: z.enum(['provider', 'manual', 'interval', 'custom']), + nextRunAt: z.string().optional(), + revision: z.int().gte(1), + sourceId: z.uuid(), + updatedAt: z.string(), +}) + +export const zPutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyBody = z.object({ + customIntervalSeconds: z.int().gte(3600).lte(2592000).optional(), + enabled: z.boolean(), + expectedRevision: z.int().gte(0), + expectedSourceVersion: z.int().gte(1), + mode: z.enum(['provider', 'manual', 'interval', 'custom']), +}) + +export const zPutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyPath = z.object({ + id: z.uuid(), + sourceId: z.uuid(), +}) + +/** + * Source sync policy updated + */ +export const zPutKnowledgeSpacesByIdSourcesBySourceIdSyncPolicyResponse = z.object({ + createdAt: z.string(), + customIntervalSeconds: z.int().optional(), + enabled: z.boolean(), + expectedSourceVersion: z.int().gte(1), + id: z.uuid(), + knowledgeSpaceId: z.uuid(), + mode: z.enum(['provider', 'manual', 'interval', 'custom']), + nextRunAt: z.string().optional(), + revision: z.int().gte(1), + sourceId: z.uuid(), + updatedAt: z.string(), +}) + +export const zGetKnowledgeSpacesByIdDocumentsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdDocumentsPath = z.object({ + id: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdDocumentsQuery = z.object({ + cursor: z.uuid().optional(), + limit: z.int().gte(1).lte(100).optional(), +}) + +/** + * Document assets + */ +export const zGetKnowledgeSpacesByIdDocumentsResponse = zDocumentAssetList + +export const zPostKnowledgeSpacesByIdDocumentsBody = z.object({ + documentId: z.uuid().optional(), + expectedActiveRevision: z.union([z.int().gt(0), z.enum(['null'])]).optional(), + expectedDocumentRowVersion: z.int().gte(0).nullish(), + file: z.string(), + sourceId: z.uuid().optional(), +}) + +export const zPostKnowledgeSpacesByIdDocumentsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdDocumentsPath = z.object({ + id: z.uuid(), +}) + +export const zPostKnowledgeSpacesByIdDocumentsResponse = z.union([ + zDocumentAsset, + zDocumentUploadAccepted, +]) + +export const zDeleteKnowledgeSpacesByIdDocumentsBulkBody = z.object({ + documents: z + .array( + z.object({ + documentId: z.uuid(), + expectedRevision: z.int().gt(0), + }), + ) + .min(1), +}) + +export const zDeleteKnowledgeSpacesByIdDocumentsBulkHeaders = z.object({ + 'idempotency-key': z.string().min(8).max(255), + 'x-trace-id': z.string().optional(), +}) + +export const zDeleteKnowledgeSpacesByIdDocumentsBulkPath = z.object({ + id: z.uuid(), +}) + +/** + * Per-document durable deletions accepted + */ +export const zDeleteKnowledgeSpacesByIdDocumentsBulkResponse = zDurableBulkDeletionAccepted + +export const zPostKnowledgeSpacesByIdDocumentsBulkBody = z.object({ + files: z.array(z.string()).min(1), + targets: z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdDocumentsBulkHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdDocumentsBulkPath = z.object({ + id: z.uuid(), +}) + +/** + * Accepted bulk document upload for durable compilation + */ +export const zPostKnowledgeSpacesByIdDocumentsBulkResponse = zBulkDocumentUploadAccepted + +export const zPostKnowledgeSpacesByIdDocumentsBulkReindexBody = z.object({ + all: z.boolean().optional(), + documentIds: z.array(z.uuid()).min(1).optional(), +}) + +export const zPostKnowledgeSpacesByIdDocumentsBulkReindexHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostKnowledgeSpacesByIdDocumentsBulkReindexPath = z.object({ + id: z.uuid(), +}) + +/** + * Accepted bulk document reindex + */ +export const zPostKnowledgeSpacesByIdDocumentsBulkReindexResponse = zBulkDocumentReindexResult + +export const zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdBody = z.object({ + expectedRevision: z.int().gt(0), +}) + +export const zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdHeaders = z.object({ + 'idempotency-key': z.string().min(8).max(255), + 'x-trace-id': z.string().optional(), +}) + +export const zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdPath = z.object({ + documentId: z.uuid(), + id: z.uuid(), +}) + +/** + * Durable deletion accepted + */ +export const zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdResponse = zDurableDeletionAccepted + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdPath = z.object({ + documentId: z.uuid(), + id: z.uuid(), +}) + +/** + * Document asset + */ +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdResponse = zDocumentAsset + +export const zGetKnowledgeSpacesByIdLogicalDocumentsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdLogicalDocumentsPath = z.object({ + id: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdLogicalDocumentsQuery = z.object({ + cursor: z.string().min(1).max(2048).optional(), + limit: z.int().gte(1).lte(100).optional(), +}) + +/** + * Logical documents + */ +export const zGetKnowledgeSpacesByIdLogicalDocumentsResponse = zLogicalDocumentList + +export const zDeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdBody = z.object({ + expectedRevision: z.int().gt(0), +}) + +export const zDeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdHeaders = z.object({ + 'idempotency-key': z.string().min(8).max(255), + 'x-trace-id': z.string().optional(), +}) + +export const zDeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdPath = z.object({ + documentId: z.uuid(), + id: z.uuid(), +}) + +/** + * Durable deletion accepted + */ +export const zDeleteKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponse = + zDurableDeletionAccepted + +export const zGetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdPath = z.object({ + documentId: z.uuid(), + id: z.uuid(), +}) + +/** + * Logical document + */ +export const zGetKnowledgeSpacesByIdLogicalDocumentsByDocumentIdResponse = zLogicalDocument + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdOutlinePath = z.object({ + documentId: z.uuid(), + id: z.uuid(), +}) + +/** + * Document outline + */ +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdOutlineResponse = zDocumentOutline + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsPath = z.object({ + documentId: z.uuid(), + id: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsQuery = z.object({ + cursor: z.string().min(1).max(2048).optional(), + limit: z.int().gte(1).lte(100).optional(), +}) + +/** + * Immutable document revision history + */ +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsResponse = zDocumentRevisionList + +export const zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackBody = + z.object({ + expectedActiveRevision: z.int().gt(0), + expectedRowVersion: z.int().gte(0), + }) + +export const zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackHeaders = + z.object({ + 'x-trace-id': z.string().optional(), + }) + +export const zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackPath = + z.object({ + documentId: z.uuid(), + id: z.uuid(), + revision: z.int().gt(0), + }) + +/** + * Rollback candidate compilation accepted + */ +export const zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionRollbackResponse = + zDocumentProcessingTask + +export const zPatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataBody = z.object({ + expectedRowVersion: z.int().gte(0), + patch: z.record(z.string(), z.unknown()), +}) + +export const zPatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataPath = z.object({ + documentId: z.uuid(), + id: z.uuid(), +}) + +/** + * Updated user metadata + */ +export const zPatchKnowledgeSpacesByIdDocumentsByDocumentIdMetadataResponse = zLogicalDocument + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksHeaders = + z.object({ + 'x-trace-id': z.string().optional(), + }) + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksPath = z.object({ + documentId: z.uuid(), + id: z.uuid(), + revision: z.int().gt(0), +}) + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksQuery = z.object({ + cursor: z.string().min(1).max(2048).optional(), + limit: z.int().gte(1).lte(100).optional(), + query: z.string().min(1).max(512).optional(), +}) + +/** + * Revision-scoped chunks + */ +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksResponse = + zDocumentChunkList + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdHeaders = + z.object({ + 'x-trace-id': z.string().optional(), + }) + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdPath = + z.object({ + documentId: z.uuid(), + id: z.uuid(), + revision: z.int().gt(0), + chunkId: z.uuid(), + }) + +/** + * Revision-scoped chunk + */ +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdResponse = + zDocumentRevisionChunk + +export const zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateBody = + z.object({ + enabled: z.boolean(), + }) + +export const zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateHeaders = + z.object({ + 'x-trace-id': z.string().optional(), + }) + +export const zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStatePath = + z.object({ + documentId: z.uuid(), + id: z.uuid(), + revision: z.int().gt(0), + chunkId: z.uuid(), + }) + +/** + * Candidate publication accepted + */ +export const zPostKnowledgeSpacesByIdDocumentsByDocumentIdRevisionsByRevisionChunksByChunkIdStateResponse = + zDocumentChunkStateChangeAccepted + +export const zGetKnowledgeSpacesByIdProcessingTasksHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdProcessingTasksPath = z.object({ + id: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdProcessingTasksQuery = z.object({ + cursor: z.string().min(1).max(2048).optional(), + limit: z.int().gte(1).lte(100).optional(), +}) + +/** + * Space processing tasks + */ +export const zGetKnowledgeSpacesByIdProcessingTasksResponse = zDocumentProcessingTaskList + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksPath = z.object({ + documentId: z.uuid(), + id: z.uuid(), +}) + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksQuery = z.object({ + cursor: z.string().min(1).max(2048).optional(), + limit: z.int().gte(1).lte(100).optional(), +}) + +/** + * Document processing tasks + */ +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksResponse = + zDocumentProcessingTaskList + +export const zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdHeaders = + z.object({ + 'x-trace-id': z.string().optional(), + }) + +export const zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdPath = z.object({ + documentId: z.uuid(), + id: z.uuid(), + taskId: z.uuid(), +}) + +/** + * Canceled processing task + */ +export const zDeleteKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponse = + zDocumentProcessingTask + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdPath = z.object({ + documentId: z.uuid(), + id: z.uuid(), + taskId: z.uuid(), +}) + +/** + * Processing task polling snapshot + */ +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdResponse = + zDocumentProcessingTask + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsHeaders = + z.object({ + 'last-event-id': z.string().optional(), + 'x-trace-id': z.string().optional(), + }) + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsPath = + z.object({ + documentId: z.uuid(), + id: z.uuid(), + taskId: z.uuid(), + }) + +/** + * Progress SSE snapshot; reconnect using polling or Last-Event-ID + */ +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEventsResponse = + zDocumentProcessingTaskEvent + +export const zPostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryHeaders = + z.object({ + 'x-trace-id': z.string().optional(), + }) + +export const zPostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryPath = + z.object({ + documentId: z.uuid(), + id: z.uuid(), + taskId: z.uuid(), + }) + +/** + * Retried processing task + */ +export const zPostKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdRetryResponse = + zDocumentProcessingTask + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsPath = z.object({ + documentId: z.uuid(), + id: z.uuid(), +}) + +/** + * Active document index settings + */ +export const zGetKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponse = zDocumentSettingsHead + +export const zPutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsBody = z.object({ + expectedSettingsHeadRevision: z.int().gt(0).nullable(), + settings: z.object({ + chunkOverlap: z.int().gte(0).lte(8191), + chunkSize: z.int().gte(128).lte(8192), + enableGraph: z.boolean(), + enablePageIndex: z.boolean(), + language: z.string().min(2).max(64).optional(), + }), +}) + +export const zPutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsPath = z.object({ + documentId: z.uuid(), + id: z.uuid(), +}) + +/** + * Versioned settings reindex accepted + */ +export const zPutKnowledgeSpacesByIdDocumentsByDocumentIdSettingsResponse = zDocumentReindexAccepted + +export const zDeleteJobsByIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zDeleteJobsByIdPath = z.object({ + id: z.string().min(1), +}) + +/** + * Canceled document compilation job + */ +export const zDeleteJobsByIdResponse = zDocumentCompilationJob + +export const zGetJobsByIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetJobsByIdPath = z.object({ + id: z.string().min(1), +}) + +/** + * Document compilation job status + */ +export const zGetJobsByIdResponse = zDocumentCompilationJob + +export const zPostJobsByIdRetryHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zPostJobsByIdRetryPath = z.object({ + id: z.string().min(1), +}) + +/** + * Reactivated document compilation attempt + */ +export const zPostJobsByIdRetryResponse = zDocumentCompilationJob + +export const zGetDeletionJobsByJobIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetDeletionJobsByJobIdPath = z.object({ + jobId: z.uuid(), +}) + +/** + * Durable deletion status + */ +export const zGetDeletionJobsByJobIdResponse = zDurableDeletionJob + +export const zPostDeletionJobsByJobIdRetryHeaders = z.object({ + 'idempotency-key': z.string().min(8).max(255), + 'x-trace-id': z.string().optional(), +}) + +export const zPostDeletionJobsByJobIdRetryPath = z.object({ + jobId: z.uuid(), +}) + +/** + * Durable deletion accepted + */ +export const zPostDeletionJobsByJobIdRetryResponse = zDurableDeletionAccepted + +export const zGetBulkJobsByIdHeaders = z.object({ + 'x-trace-id': z.string().optional(), +}) + +export const zGetBulkJobsByIdPath = z.object({ + id: z.string().min(1), +}) + +/** + * Bulk operation progress + */ +export const zGetBulkJobsByIdResponse = zBulkOperationProgress diff --git a/packages/contracts/knowledge-fs-contract.test.mjs b/packages/contracts/knowledge-fs-contract.test.mjs new file mode 100644 index 00000000000..f88da6b1eb8 --- /dev/null +++ b/packages/contracts/knowledge-fs-contract.test.mjs @@ -0,0 +1,47 @@ +import { createHash } from 'node:crypto' +import { readFile } from 'node:fs/promises' +import { dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' +import { describe, expect, it } from 'vitest' +import { + knowledgeFsGeneratedArtifactSha256, + knowledgeFsSourceOpenapiSha256, +} from './generated/knowledge-fs/metadata.gen' +import { getStreamingOperationIds } from './scripts/knowledge-fs-contract-utils.mjs' + +const packageRoot = dirname(fileURLToPath(import.meta.url)) + +describe('KnowledgeFS contract generation', () => { + it.each(['200', '2XX'])('detects an SSE response declared with %s', (status) => { + expect( + getStreamingOperationIds({ + paths: { + '/tasks/{id}/events': { + get: { + operationId: 'streamTaskEvents', + responses: { + [status]: { + content: { + 'text/event-stream': {}, + }, + }, + }, + }, + }, + }, + }), + ).toEqual(['streamTaskEvents']) + }) + + it('matches the pinned source contract and committed generated artifacts', async () => { + const lock = JSON.parse( + await readFile(join(packageRoot, '../../api/knowledge-fs-contract.lock.json'), 'utf8'), + ) + + expect(knowledgeFsSourceOpenapiSha256).toBe(lock.openapiSha256) + for (const [fileName, expectedSha256] of Object.entries(knowledgeFsGeneratedArtifactSha256)) { + const content = await readFile(join(packageRoot, 'generated/knowledge-fs', fileName)) + expect(createHash('sha256').update(content).digest('hex'), fileName).toBe(expectedSha256) + } + }) +}) diff --git a/packages/contracts/scripts/generate-knowledge-fs-contract.mjs b/packages/contracts/scripts/generate-knowledge-fs-contract.mjs index c23e133b384..962f51c6c0a 100644 --- a/packages/contracts/scripts/generate-knowledge-fs-contract.mjs +++ b/packages/contracts/scripts/generate-knowledge-fs-contract.mjs @@ -1,8 +1,10 @@ import { execFileSync } from 'node:child_process' -import { mkdtemp, rm } from 'node:fs/promises' +import { createHash } from 'node:crypto' +import { mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { dirname, join, resolve } from 'node:path' import { fileURLToPath } from 'node:url' +import { getStreamingOperationIds } from './knowledge-fs-contract-utils.mjs' const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..') const workspaceRoot = resolve(packageRoot, '../..') @@ -31,11 +33,83 @@ try { run('pnpm', ['exec', 'openapi-ts', '-f', 'openapi-ts.knowledge-fs.config.ts'], packageRoot, { KNOWLEDGE_FS_OPENAPI: openapiPath, }) + await patchStreamingContracts(openapiPath) run('pnpm', ['exec', 'vp', 'fmt', 'generated/knowledge-fs'], packageRoot) + await writeContractMetadata(openapiPath, await generatedArtifactSha256()) + run('pnpm', ['exec', 'vp', 'fmt', 'generated/knowledge-fs/metadata.gen.ts'], packageRoot) } finally { await rm(temporaryDirectory, { force: true, recursive: true }) } +async function patchStreamingContracts(openapiPath) { + const document = JSON.parse(await readFile(openapiPath, 'utf8')) + const streamingOperationIds = getStreamingOperationIds(document) + if (streamingOperationIds.length === 0) return + + const outputPath = join(packageRoot, 'generated/knowledge-fs/orpc.gen.ts') + let source = await readFile(outputPath, 'utf8') + source = replaceOnce( + source, + "import { oc } from '@orpc/contract'", + "import { eventIterator, oc } from '@orpc/contract'", + ) + + for (const operationId of streamingOperationIds) { + const responseSchema = `z${capitalize(operationId)}Response` + source = replaceOnce( + source, + `.output(${responseSchema})`, + `.output(eventIterator(${responseSchema}))`, + ) + } + + await writeFile(outputPath, source) +} + +function capitalize(value) { + return value.charAt(0).toUpperCase() + value.slice(1) +} + +function replaceOnce(source, target, replacement) { + const firstIndex = source.indexOf(target) + if (firstIndex === -1 || source.indexOf(target, firstIndex + target.length) !== -1) + throw new Error(`Expected exactly one generated occurrence of ${target}`) + + return source.slice(0, firstIndex) + replacement + source.slice(firstIndex + target.length) +} + +async function generatedArtifactSha256() { + const generatedDirectory = join(packageRoot, 'generated/knowledge-fs') + const fileNames = (await readdir(generatedDirectory)) + .filter((fileName) => fileName.endsWith('.gen.ts') && fileName !== 'metadata.gen.ts') + .sort() + + return Object.fromEntries( + await Promise.all( + fileNames.map(async (fileName) => [ + fileName, + createHash('sha256') + .update(await readFile(join(generatedDirectory, fileName))) + .digest('hex'), + ]), + ), + ) +} + +async function writeContractMetadata(openapiPath, artifactSha256) { + const document = JSON.parse(await readFile(openapiPath, 'utf8')) + const source = [ + '// This file is auto-generated by scripts/generate-knowledge-fs-contract.mjs.', + '// Do not edit it manually.', + '', + `export const knowledgeFsSourceOpenapiSha256 = ${JSON.stringify(document['x-dify-source-openapi-sha256'])}`, + `export const knowledgeFsConsoleDeclarationsSha256 = ${JSON.stringify(document['x-dify-console-declarations-sha256'])}`, + `export const knowledgeFsGeneratedArtifactSha256 = ${JSON.stringify(artifactSha256, null, 2)} as const`, + '', + ].join('\n') + await writeFile(join(packageRoot, 'generated/knowledge-fs/metadata.gen.ts'), source) +} + function run(command, args, cwd, extraEnv = {}) { execFileSync(command, args, { cwd, diff --git a/packages/contracts/scripts/knowledge-fs-contract-utils.mjs b/packages/contracts/scripts/knowledge-fs-contract-utils.mjs new file mode 100644 index 00000000000..3f607516f25 --- /dev/null +++ b/packages/contracts/scripts/knowledge-fs-contract-utils.mjs @@ -0,0 +1,19 @@ +export function getStreamingOperationIds(document) { + return Object.values(document.paths ?? {}) + .flatMap((pathItem) => + Object.values(pathItem).flatMap((operation) => { + if (typeof operation !== 'object' || operation === null) return [] + const isEventStream = Object.entries(operation.responses ?? {}).some( + ([status, response]) => + (status === '2XX' || /^2\d\d$/.test(status)) && + typeof response === 'object' && + response !== null && + 'text/event-stream' in (response.content ?? {}), + ) + return isEventStream && typeof operation.operationId === 'string' + ? [operation.operationId] + : [] + }), + ) + .sort() +} diff --git a/web/service/client.spec.ts b/web/service/client.spec.ts index 2c00ba8560d..460ee6f846e 100644 --- a/web/service/client.spec.ts +++ b/web/service/client.spec.ts @@ -1,5 +1,6 @@ import type { ApiBasedExtensionResponse } from '@dify/contracts/api/console/api-based-extension/types.gen' import type { TagResponse as Tag } from '@dify/contracts/api/console/tags/types.gen' +import type { DocumentProcessingTaskEvent } from '@dify/contracts/knowledge-fs/types.gen' import type { MutationFunctionContext, QueryFunctionContext } from '@tanstack/react-query' import type { consoleQuery as ConsoleQuery } from './client' import { QueryClient } from '@tanstack/react-query' @@ -358,6 +359,74 @@ describe('consoleQuery transport context', () => { ) expect(request.mock.calls[0]![0]).not.toContain('ids%5B0%5D') }) + + it('should consume KnowledgeFS processing events through the generated stream contract', async () => { + const request = vi.fn().mockResolvedValue( + new Response( + [ + 'id: task-1:1', + 'event: message', + 'data: {"event":"progress","data":{"progressPercent":25,"stage":"parsed","state":"running","updatedAt":"2026-07-22T10:00:00.000Z"}}', + '', + 'id: task-1:terminal', + 'event: message', + 'data: {"event":"terminal","data":{"state":"succeeded"}}', + '', + '', + ].join('\n'), + { + status: 200, + headers: { + 'content-type': 'text/event-stream', + }, + }, + ), + ) + const consoleQuery = await loadConsoleQueryWithRequest(request) + const queryOptions = + consoleQuery.knowledgeFs.getKnowledgeSpacesByIdDocumentsByDocumentIdProcessingTasksByTaskIdEvents.experimental_streamedOptions( + { + input: { + headers: { + 'last-event-id': 'task-1:0', + }, + params: { + documentId: 'document-1', + id: 'space-1', + taskId: 'task-1', + }, + }, + }, + ) + + const events = await queryOptions.queryFn({ + client: new QueryClient(), + signal: new AbortController().signal, + } as QueryFunctionContext) + + expectTypeOf(events[0]!).toMatchTypeOf() + expect(events).toEqual([ + { + data: { + progressPercent: 25, + stage: 'parsed', + state: 'running', + updatedAt: '2026-07-22T10:00:00.000Z', + }, + event: 'progress', + }, + { data: { state: 'succeeded' }, event: 'terminal' }, + ]) + expect(request).toHaveBeenCalledWith( + expect.stringContaining( + '/knowledge-fs/knowledge-spaces/space-1/documents/document-1/processing-tasks/task-1/events', + ), + expect.any(Object), + expect.objectContaining({ + fetchCompat: true, + }), + ) + }) }) // Scenario: console OpenAPI query arrays follow backend parser expectations.