chore: update to openapi v3 by change dep (#37316)

Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com>
Co-authored-by: Stephen Zhou <hi@hyoban.cc>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Asuka Minato 2026-06-12 16:52:19 +09:00 committed by GitHub
parent 9c25fa1c96
commit 6c0cce4b7f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
67 changed files with 7054 additions and 8673 deletions

View File

@ -1,9 +1,9 @@
"""Helpers for registering Pydantic models with Flask-RESTX namespaces.
Flask-RESTX treats `SchemaModel` bodies as opaque JSON schemas; it does not
promote Pydantic's nested `$defs` into top-level Swagger `definitions`.
promote Pydantic's nested `$defs` into top-level OpenAPI component schemas.
These helpers keep that translation centralized so models registered through
`register_schema_models` emit resolvable Swagger 2.0 references.
`register_schema_models` emit resolvable OpenAPI 3 references.
"""
from collections.abc import Iterable, Mapping
@ -14,7 +14,7 @@ from flask import request
from flask_restx import Namespace
from pydantic import BaseModel, TypeAdapter
DEFAULT_REF_TEMPLATE_SWAGGER_2_0 = "#/definitions/{model}"
DEFAULT_REF_TEMPLATE_OPENAPI_3_0 = "#/components/schemas/{model}"
QueryParamDoc = TypedDict(
@ -48,7 +48,6 @@ class QueryArgs(Protocol):
def _register_json_schema(namespace: Namespace, name: str, schema: dict) -> None:
"""Register a JSON schema and promote any nested Pydantic `$defs`."""
schema = _swagger_2_compatible_schema(schema)
nested_definitions = schema.get("$defs")
schema_to_register = dict(schema)
if isinstance(nested_definitions, dict):
@ -71,41 +70,12 @@ def _register_schema_model(namespace: Namespace, model: type[BaseModel], *, mode
_register_json_schema(
namespace,
model.__name__,
model.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_SWAGGER_2_0, mode=mode),
model.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_OPENAPI_3_0, mode=mode),
)
def _swagger_2_compatible_schema(value: Any) -> Any:
if isinstance(value, list):
return [_swagger_2_compatible_schema(item) for item in value]
if not isinstance(value, dict):
return value
converted = {key: _swagger_2_compatible_schema(child) for key, child in value.items()}
any_of = value.get("anyOf")
if not isinstance(any_of, list):
return converted
non_null_candidates = [
candidate for candidate in any_of if isinstance(candidate, Mapping) and candidate.get("type") != "null"
]
has_null_candidate = any(isinstance(candidate, Mapping) and candidate.get("type") == "null" for candidate in any_of)
if not has_null_candidate or len(non_null_candidates) != 1:
return converted
non_null_schema = _swagger_2_compatible_schema(dict(non_null_candidates[0]))
if not isinstance(non_null_schema, dict):
return converted
converted.pop("anyOf", None)
converted.update(non_null_schema)
converted["x-nullable"] = True
return converted
def register_schema_model(namespace: Namespace, model: type[BaseModel]) -> None:
"""Register a BaseModel and its nested schema definitions for Swagger documentation."""
"""Register a BaseModel and its nested component schemas for OpenAPI documentation."""
_register_schema_model(namespace, model, mode="validation")
@ -146,7 +116,7 @@ def register_enum_models(namespace: Namespace, *models: type[StrEnum]) -> None:
_register_json_schema(
namespace,
model.__name__,
TypeAdapter(model).json_schema(ref_template=DEFAULT_REF_TEMPLATE_SWAGGER_2_0),
TypeAdapter(model).json_schema(ref_template=DEFAULT_REF_TEMPLATE_OPENAPI_3_0),
)
@ -155,10 +125,10 @@ def query_params_from_model(model: type[BaseModel]) -> dict[str, QueryParamDoc]:
`Namespace.expect()` treats Pydantic schema models as request bodies, so GET
endpoints should keep runtime validation on the Pydantic model and feed this
derived mapping to `Namespace.doc(params=...)` for Swagger documentation.
derived mapping to `Namespace.doc(params=...)` for OpenAPI documentation.
"""
schema = model.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_SWAGGER_2_0)
schema = model.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_OPENAPI_3_0)
properties = schema.get("properties", {})
if not isinstance(properties, Mapping):
return {}
@ -203,7 +173,7 @@ def query_params_from_request[ModelT: BaseModel](
def _drop_malformed_defaulted_integer_params(model: type[BaseModel], params: dict[str, Any]) -> None:
properties = model.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_SWAGGER_2_0).get("properties", {})
properties = model.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_OPENAPI_3_0).get("properties", {})
if not isinstance(properties, Mapping):
return
@ -297,7 +267,7 @@ def _nullable_property_schema(property_schema: Mapping[str, Any]) -> Mapping[str
__all__ = [
"DEFAULT_REF_TEMPLATE_SWAGGER_2_0",
"DEFAULT_REF_TEMPLATE_OPENAPI_3_0",
"get_or_create_model",
"query_params_from_model",
"query_params_from_request",

View File

@ -2,6 +2,7 @@ from flask import request
from flask_restx import Resource, fields
from pydantic import BaseModel, Field
from controllers.common.schema import DEFAULT_REF_TEMPLATE_OPENAPI_3_0
from controllers.console import console_ns
from controllers.console.wraps import account_initialization_required, setup_required
from libs.login import login_required
@ -17,7 +18,7 @@ class AdvancedPromptTemplateQuery(BaseModel):
console_ns.schema_model(
AdvancedPromptTemplateQuery.__name__,
AdvancedPromptTemplateQuery.model_json_schema(ref_template="#/definitions/{model}"),
AdvancedPromptTemplateQuery.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_OPENAPI_3_0),
)

View File

@ -7,6 +7,7 @@ from libs.login import login_required
from models import Account
from services.billing_service import BillingService
from ...common.schema import DEFAULT_REF_TEMPLATE_OPENAPI_3_0
from .. import console_ns
from ..wraps import (
account_initialization_required,
@ -23,7 +24,7 @@ class ComplianceDownloadQuery(BaseModel):
console_ns.schema_model(
ComplianceDownloadQuery.__name__,
ComplianceDownloadQuery.model_json_schema(ref_template="#/definitions/{model}"),
ComplianceDownloadQuery.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_OPENAPI_3_0),
)

View File

@ -14,7 +14,7 @@ from models.api_based_extension import APIBasedExtension
from services.api_based_extension_service import APIBasedExtensionService
from services.code_based_extension_service import CodeBasedExtensionService
from ..common.schema import DEFAULT_REF_TEMPLATE_SWAGGER_2_0, register_schema_models
from ..common.schema import DEFAULT_REF_TEMPLATE_OPENAPI_3_0, register_schema_models
from . import console_ns
from .wraps import account_initialization_required, setup_required, with_current_tenant_id
@ -63,7 +63,7 @@ class APIBasedExtensionResponse(ResponseModel):
register_schema_models(console_ns, APIBasedExtensionPayload, CodeBasedExtensionResponse, APIBasedExtensionResponse)
console_ns.schema_model(
"APIBasedExtensionListResponse",
TypeAdapter(list[APIBasedExtensionResponse]).json_schema(ref_template=DEFAULT_REF_TEMPLATE_SWAGGER_2_0),
TypeAdapter(list[APIBasedExtensionResponse]).json_schema(ref_template=DEFAULT_REF_TEMPLATE_OPENAPI_3_0),
)

View File

@ -1,4 +1,4 @@
"""Generate FastOpenAPI OpenAPI 3.0 specs without booting the full backend."""
"""Generate FastOpenAPI OpenAPI 3.1 specs without booting the full backend."""
from __future__ import annotations

View File

@ -1,7 +1,7 @@
"""Generate OpenAPI JSON specs and split Markdown API docs.
The Markdown step uses `swagger-markdown`, the same converter family as the
Swagger Markdown UI, so CI and local regeneration catch converter-incompatible
legacy Markdown UI, so CI and local regeneration catch converter-incompatible
OpenAPI output early.
"""
@ -25,19 +25,21 @@ from dev.generate_swagger_specs import SPEC_TARGETS, generate_specs
logger = logging.getLogger(__name__)
SWAGGER_MARKDOWN_PACKAGE = "swagger-markdown@3.0.0"
CONSOLE_SWAGGER_FILENAME = "console-swagger.json"
CONSOLE_OPENAPI_FILENAME = "console-openapi.json"
STALE_COMBINED_MARKDOWN_FILENAME = "api-reference.md"
def _definition_ref_name(schema: object) -> str | None:
def _schema_ref_name(schema: object) -> str | None:
if not isinstance(schema, dict):
return None
ref = schema.get("$ref")
if not isinstance(ref, str) or not ref.startswith("#/definitions/"):
if not isinstance(ref, str):
return None
return ref.removeprefix("#/definitions/")
if ref.startswith("#/components/schemas/"):
return ref.removeprefix("#/components/schemas/")
return None
def _markdown_anchor(name: str) -> str:
@ -48,7 +50,7 @@ def _schema_markdown_type(schema: object) -> str:
if not isinstance(schema, dict):
return ""
ref_name = _definition_ref_name(schema)
ref_name = _schema_ref_name(schema)
if ref_name is not None:
return f"[{ref_name}](#{_markdown_anchor(ref_name)})"
@ -111,15 +113,16 @@ def _has_union_schema(schema: object) -> bool:
def _patch_union_schema_markdown(markdown: str, spec_path: Path) -> str:
"""Fill Swagger Markdown table cells that `swagger-markdown` leaves blank for union schemas."""
"""Fill Markdown table cells that `swagger-markdown` leaves blank for union schemas."""
spec = json.loads(spec_path.read_text(encoding="utf-8"))
definitions = spec.get("definitions")
if not isinstance(definitions, dict):
components = spec.get("components")
schemas = components.get("schemas") if isinstance(components, dict) else None
if not isinstance(schemas, dict):
return markdown
for definition_name, schema in definitions.items():
if not isinstance(definition_name, str) or not isinstance(schema, dict):
for schema_name, schema in schemas.items():
if not isinstance(schema_name, str) or not isinstance(schema, dict):
continue
properties = schema.get("properties")
@ -128,7 +131,7 @@ def _patch_union_schema_markdown(markdown: str, spec_path: Path) -> str:
if isinstance(property_name, str) and _has_union_schema(property_schema):
markdown = _replace_schema_table_type(
markdown,
definition_name,
schema_name,
property_name,
_schema_markdown_type(property_schema),
)
@ -139,14 +142,14 @@ def _patch_union_schema_markdown(markdown: str, spec_path: Path) -> str:
markdown = _replace_schema_table_type(
markdown,
definition_name,
definition_name,
schema_name,
schema_name,
_schema_markdown_type(schema),
)
for variant in union_variants:
variant_name = _definition_ref_name(variant)
variant_schema = definitions.get(variant_name) if variant_name is not None else None
variant_name = _schema_ref_name(variant)
variant_schema = schemas.get(variant_name) if variant_name is not None else None
if not isinstance(variant_name, str) or not isinstance(variant_schema, dict):
continue
properties = variant_schema.get("properties")
@ -229,7 +232,7 @@ def _append_fastopenapi_markdown(console_markdown_path: Path, fastopenapi_markdo
"\n\n".join(
[
console_markdown,
"## FastOpenAPI Preview (OpenAPI 3.0)",
"## FastOpenAPI Preview (OpenAPI 3.1)",
fastopenapi_markdown,
]
)
@ -239,17 +242,17 @@ def _append_fastopenapi_markdown(console_markdown_path: Path, fastopenapi_markdo
def generate_markdown_docs(
swagger_dir: Path,
openapi_dir: Path,
markdown_dir: Path,
*,
keep_swagger_json: bool = False,
) -> list[Path]:
"""Generate intermediate specs, convert them to split Markdown API docs, and return Markdown paths."""
swagger_paths = generate_specs(swagger_dir)
fastopenapi_paths = generate_fastopenapi_specs(swagger_dir)
spec_paths = [*swagger_paths, *fastopenapi_paths]
swagger_paths_by_name = {path.name: path for path in swagger_paths}
openapi_paths = generate_specs(openapi_dir)
fastopenapi_paths = generate_fastopenapi_specs(openapi_dir)
spec_paths = [*openapi_paths, *fastopenapi_paths]
openapi_paths_by_name = {path.name: path for path in openapi_paths}
fastopenapi_paths_by_name = {path.name: path for path in fastopenapi_paths}
markdown_dir.mkdir(parents=True, exist_ok=True)
@ -260,9 +263,9 @@ def generate_markdown_docs(
temp_markdown_dir = Path(temp_dir)
for target in SPEC_TARGETS:
swagger_path = swagger_paths_by_name[target.filename]
markdown_path = markdown_dir / f"{swagger_path.stem}.md"
_convert_spec_to_markdown(swagger_path, markdown_path)
openapi_path = openapi_paths_by_name[target.filename]
markdown_path = markdown_dir / f"{openapi_path.stem}.md"
_convert_spec_to_markdown(openapi_path, markdown_path)
written_paths.append(markdown_path)
for target in FASTOPENAPI_SPEC_TARGETS: # type: ignore
@ -270,7 +273,7 @@ def generate_markdown_docs(
markdown_path = temp_markdown_dir / f"{fastopenapi_path.stem}.md"
_convert_spec_to_markdown(fastopenapi_path, markdown_path)
console_markdown_path = markdown_dir / f"{Path(CONSOLE_SWAGGER_FILENAME).stem}.md"
console_markdown_path = markdown_dir / f"{Path(CONSOLE_OPENAPI_FILENAME).stem}.md"
_append_fastopenapi_markdown(console_markdown_path, markdown_path)
(markdown_dir / STALE_COMBINED_MARKDOWN_FILENAME).unlink(missing_ok=True)
@ -286,6 +289,8 @@ def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--swagger-dir",
"--openapi-dir",
dest="openapi_dir",
type=Path,
default=Path("openapi"),
help="Directory where intermediate JSON spec files will be written.",
@ -307,7 +312,7 @@ def parse_args() -> argparse.Namespace:
def main() -> int:
args = parse_args()
written_paths = generate_markdown_docs(
args.swagger_dir,
args.openapi_dir,
args.markdown_dir,
keep_swagger_json=args.keep_swagger_json,
)

View File

@ -1,9 +1,9 @@
"""Generate Flask-RESTX Swagger 2.0 specs without booting the full backend.
"""Generate Flask-RESTX OpenAPI 3 specs without booting the full backend.
This helper intentionally avoids `app_factory.create_app()`. The normal backend
startup eagerly initializes database, Redis, Celery, and storage extensions,
which is unnecessary when the goal is only to serialize the Flask-RESTX
`/swagger.json` documents.
`/openapi.json` documents.
"""
from __future__ import annotations
@ -42,10 +42,10 @@ class RestxApi(Protocol):
SPEC_TARGETS: tuple[SpecTarget, ...] = (
SpecTarget(route="/console/api/swagger.json", filename="console-swagger.json", namespace="console"),
SpecTarget(route="/api/swagger.json", filename="web-swagger.json", namespace="web"),
SpecTarget(route="/v1/swagger.json", filename="service-swagger.json", namespace="service"),
SpecTarget(route="/openapi/v1/swagger.json", filename="openapi-swagger.json", namespace="openapi"),
SpecTarget(route="/console/api/openapi.json", filename="console-openapi.json", namespace="console"),
SpecTarget(route="/api/openapi.json", filename="web-openapi.json", namespace="web"),
SpecTarget(route="/v1/openapi.json", filename="service-openapi.json", namespace="service"),
SpecTarget(route="/openapi/v1/openapi.json", filename="openapi-openapi.json", namespace="openapi"),
)
@ -126,7 +126,7 @@ def _inline_model_signature(nested_fields: dict[object, object]) -> object:
def _inline_model_name(nested_fields: dict[object, object]) -> str:
"""Return a stable Swagger model name for an anonymous inline field map."""
"""Return a stable OpenAPI model name for an anonymous inline field map."""
signature = json.dumps(_inline_model_signature(nested_fields), sort_keys=True, separators=(",", ":"))
digest = hashlib.sha1(signature.encode("utf-8")).hexdigest()[:12]
@ -134,7 +134,7 @@ def _inline_model_name(nested_fields: dict[object, object]) -> str:
def apply_runtime_defaults() -> None:
"""Force the small config surface required for Swagger generation."""
"""Force the small config surface required for OpenAPI generation."""
os.environ.setdefault("SECRET_KEY", "spec-export")
os.environ.setdefault("STORAGE_TYPE", "local")
@ -150,7 +150,7 @@ def apply_runtime_defaults() -> None:
def create_spec_app() -> Flask:
"""Build a minimal Flask app that only mounts the Swagger-producing blueprints."""
"""Build a minimal Flask app that only mounts the OpenAPI-producing blueprints."""
apply_runtime_defaults()
@ -182,7 +182,7 @@ def create_spec_app() -> Flask:
def _registered_models(namespace: str) -> dict[str, object]:
"""Return the Flask-RESTX models registered for a Swagger namespace."""
"""Return the Flask-RESTX models registered for an OpenAPI namespace."""
if namespace == "console":
from controllers.console import console_ns
@ -213,7 +213,7 @@ def _registered_models(namespace: str) -> dict[str, object]:
models.update(api.models)
return models
raise ValueError(f"unknown Swagger namespace: {namespace}")
raise ValueError(f"unknown OpenAPI namespace: {namespace}")
def _materialize_inline_model_definitions(api: RestxApi) -> None:
@ -289,7 +289,7 @@ def drop_null_values(value: object) -> object:
def sort_openapi_arrays(value: object, *, parent_key: str | None = None) -> object:
"""Sort order-insensitive Swagger arrays so generated Markdown is stable."""
"""Sort order-insensitive OpenAPI arrays so generated Markdown is stable."""
if isinstance(value, dict):
return {key: sort_openapi_arrays(item, parent_key=key) for key, item in value.items()}
@ -313,23 +313,174 @@ def sort_openapi_arrays(value: object, *, parent_key: str | None = None) -> obje
return sorted_items
def _merge_registered_definitions(payload: dict[str, object], namespace: str) -> dict[str, object]:
"""Include registered but route-indirect models in the exported Swagger definitions."""
def _replace_legacy_refs(value: object) -> object:
if isinstance(value, dict):
replaced: dict[object, object] = {}
for key, item in value.items():
if key == "$ref" and isinstance(item, str) and item.startswith("#/definitions/"):
replaced[key] = item.replace("#/definitions/", "#/components/schemas/", 1)
else:
replaced[key] = _replace_legacy_refs(item)
return replaced
if isinstance(value, list):
return [_replace_legacy_refs(item) for item in value]
return value
definitions = payload.setdefault("definitions", {})
if not isinstance(definitions, dict):
raise RuntimeError("unexpected Swagger definitions payload")
HTTP_METHODS = {"delete", "get", "head", "options", "patch", "post", "put", "trace"}
def _resolve_component_schema(payload: dict[str, object], schema: object) -> dict[str, object] | None:
if not isinstance(schema, dict):
return None
ref = schema.get("$ref")
if isinstance(ref, str) and ref.startswith("#/components/schemas/"):
name = ref.removeprefix("#/components/schemas/")
components = payload.get("components")
if not isinstance(components, dict):
return None
schemas = components.get("schemas")
if not isinstance(schemas, dict):
return None
resolved = schemas.get(name)
return resolved if isinstance(resolved, dict) else None
return schema
def _request_body_schema(request_body: object) -> object | None:
if not isinstance(request_body, dict):
return None
content = request_body.get("content")
if not isinstance(content, dict):
return None
media_type = content.get("application/json")
if not isinstance(media_type, dict):
return None
return media_type.get("schema")
def _query_parameters_from_schema(schema: dict[str, object]) -> list[dict[str, object]]:
properties = schema.get("properties")
if not isinstance(properties, dict):
return []
required = schema.get("required")
required_names = set(required) if isinstance(required, list) else set()
parameters: list[dict[str, object]] = []
for name, property_schema in sorted(properties.items()):
if not isinstance(name, str) or not isinstance(property_schema, dict):
continue
schema_copy = dict(property_schema)
description = schema_copy.get("description")
parameter: dict[str, object] = {
"name": name,
"in": "query",
"required": name in required_names,
"schema": schema_copy,
}
if isinstance(description, str):
parameter["description"] = description
parameters.append(parameter)
return parameters
def _move_get_request_bodies_to_query_parameters(payload: dict[str, object]) -> dict[str, object]:
"""Represent GET request bodies as query parameters in exported specs."""
paths = payload.get("paths")
if not isinstance(paths, dict):
return payload
for path_item in paths.values():
if not isinstance(path_item, dict):
continue
operation = path_item.get("get")
if not isinstance(operation, dict) or "requestBody" not in operation:
continue
schema = _resolve_component_schema(payload, _request_body_schema(operation.get("requestBody")))
existing_parameters = operation.get("parameters")
parameters = list(existing_parameters) if isinstance(existing_parameters, list) else []
existing_query_names = {
parameter.get("name")
for parameter in parameters
if isinstance(parameter, dict) and parameter.get("in") == "query"
}
if schema is not None:
for parameter in _query_parameters_from_schema(schema):
if parameter["name"] not in existing_query_names:
parameters.append(parameter)
if parameters:
operation["parameters"] = parameters
operation.pop("requestBody", None)
return payload
def _deduplicate_operation_ids(payload: dict[str, object]) -> dict[str, object]:
"""Make operationId values unique while preserving already-unique IDs."""
paths = payload.get("paths")
if not isinstance(paths, dict):
return payload
operations_by_id: dict[str, list[tuple[str, str, dict[str, object]]]] = {}
for path, path_item in paths.items():
if not isinstance(path, str) or not isinstance(path_item, dict):
continue
for method, operation in path_item.items():
if method not in HTTP_METHODS or not isinstance(operation, dict):
continue
operation_id = operation.get("operationId")
if isinstance(operation_id, str):
operations_by_id.setdefault(operation_id, []).append((method, path, operation))
for operation_id, operations in operations_by_id.items():
if len(operations) < 2:
continue
for method, path, operation in operations:
digest = hashlib.sha1(f"{method}:{path}".encode()).hexdigest()[:8]
operation["operationId"] = f"{operation_id}_{digest}"
return payload
def _component_schemas(payload: dict[str, object]) -> dict[str, object]:
components = payload.setdefault("components", {})
if not isinstance(components, dict):
raise RuntimeError("unexpected OpenAPI components payload")
schemas = components.setdefault("schemas", {})
if not isinstance(schemas, dict):
raise RuntimeError("unexpected OpenAPI component schemas payload")
return schemas
def _merge_registered_schemas(payload: dict[str, object], namespace: str) -> dict[str, object]:
"""Include registered but route-indirect models in exported OpenAPI schemas."""
schemas = _component_schemas(payload)
for name, model in _registered_models(namespace).items():
schema = getattr(model, "__schema__", None)
if isinstance(schema, dict):
definitions.setdefault(name, schema)
schemas.setdefault(name, _replace_legacy_refs(schema))
payload.pop("definitions", None)
payload = _replace_legacy_refs(payload) # type: ignore[assignment]
return payload
def generate_specs(output_dir: Path) -> list[Path]:
"""Write all Swagger specs to `output_dir` and return the written paths."""
"""Write all OpenAPI specs to `output_dir` and return the written paths."""
output_dir.mkdir(parents=True, exist_ok=True)
@ -345,7 +496,9 @@ def generate_specs(output_dir: Path) -> list[Path]:
payload = response.get_json()
if not isinstance(payload, dict):
raise RuntimeError(f"unexpected response payload for {target.route}")
payload = _merge_registered_definitions(payload, target.namespace)
payload = _merge_registered_schemas(payload, target.namespace)
payload = _move_get_request_bodies_to_query_parameters(payload)
payload = _deduplicate_operation_ids(payload)
payload = drop_null_values(payload)
payload = sort_openapi_arrays(payload)
@ -363,7 +516,7 @@ def parse_args() -> argparse.Namespace:
"--output-dir",
type=Path,
default=Path("openapi"),
help="Directory where the Swagger JSON files will be written.",
help="Directory where the OpenAPI JSON files will be written.",
)
return parser.parse_args()

View File

@ -26,7 +26,7 @@ def init_app(app: DifyApp) -> None:
docs_url=docs_url,
redoc_url=redoc_url,
openapi_url=openapi_url,
openapi_version="3.0.0",
openapi_version="3.1.0",
title="Dify API (FastOpenAPI PoC)",
version="1.0",
description="FastOpenAPI proof of concept for Dify API",

View File

@ -1,8 +1,8 @@
"""Compatibility helpers for Dify's Flask-RESTX Swagger integration.
"""Compatibility helpers for Dify's Flask-RESTX OpenAPI integration.
These helpers are temporary bridges for legacy Flask-RESTX field contracts
while controllers migrate their request and response documentation to Pydantic
models. Keep the behavior centralized so live Swagger endpoints and offline
models. Keep the behavior centralized so live OpenAPI endpoints and offline
spec export fail or succeed in the same way.
"""
@ -91,7 +91,7 @@ def _inline_model_signature(nested_fields: dict[object, object]) -> object:
def _inline_model_name(nested_fields: dict[object, object]) -> str:
"""Return a stable Swagger model name for an anonymous inline field map."""
"""Return a stable OpenAPI model name for an anonymous inline field map."""
signature = json.dumps(_inline_model_signature(nested_fields), sort_keys=True, separators=(",", ":"))
digest = hashlib.sha1(signature.encode("utf-8")).hexdigest()[:12]
@ -99,11 +99,11 @@ def _inline_model_name(nested_fields: dict[object, object]) -> str:
def patch_swagger_for_inline_nested_dicts() -> None:
"""Allow Swagger generation to handle legacy inline Flask-RESTX field dicts.
"""Allow OpenAPI generation to handle legacy inline Flask-RESTX field dicts.
Some existing controllers use raw field mappings in `fields.Nested({...})`
or directly in `@namespace.response(...)`. Runtime marshalling accepts that,
but Flask-RESTX Swagger registration expects a named model. Convert those
but Flask-RESTX registration expects a named model. Convert those
anonymous mappings into temporary named models during docs generation.
"""

View File

@ -3,523 +3,485 @@ User-scoped programmatic API (bearer auth)
## Version: 1.0
### Security
**Bearer**
| apiKey | *API Key* |
| ------ | --------- |
| Description | Type: Bearer {your-api-key} |
| In | header |
| Name | Authorization |
### Available authorizations
#### Bearer (API Key Authentication)
Type: Bearer {your-api-key}
**Name:** Authorization
**In:** header
---
## openapi
User-scoped operations
### /_health
#### GET
##### Responses
### [GET] /_health
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Health check | [HealthResponse](#healthresponse) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Health check | **application/json**: [HealthResponse](#healthresponse)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /_version
#### GET
##### Responses
### [GET] /_version
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Server version | [ServerVersionResponse](#serverversionresponse) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Server version | **application/json**: [ServerVersionResponse](#serverversionresponse)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /account
#### GET
##### Responses
### [GET] /account
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Account info | [AccountResponse](#accountresponse) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Account info | **application/json**: [AccountResponse](#accountresponse)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /account/sessions
#### GET
##### Parameters
### [GET] /account/sessions
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| limit | query | | No | integer |
| page | query | | No | integer |
| limit | query | | No | integer, <br>**Default:** 100 |
| page | query | | No | integer, <br>**Default:** 1 |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Session list | [SessionListResponse](#sessionlistresponse) |
| 422 | Validation error | [ErrorBody](#errorbody) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Session list | **application/json**: [SessionListResponse](#sessionlistresponse)<br> |
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /account/sessions/self
#### DELETE
##### Responses
### [DELETE] /account/sessions/self
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Session revoked | [RevokeResponse](#revokeresponse) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Session revoked | **application/json**: [RevokeResponse](#revokeresponse)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /account/sessions/{session_id}
#### DELETE
##### Parameters
### [DELETE] /account/sessions/{session_id}
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| session_id | path | | Yes | string |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Session revoked | [RevokeResponse](#revokeresponse) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Session revoked | **application/json**: [RevokeResponse](#revokeresponse)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /apps
#### GET
##### Parameters
### [GET] /apps
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| limit | query | | No | integer |
| limit | query | | No | integer, <br>**Default:** 20 |
| mode | query | | No | string |
| name | query | | No | string |
| page | query | | No | integer |
| page | query | | No | integer, <br>**Default:** 1 |
| tag | query | | No | string |
| workspace_id | query | | Yes | string |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | App list | [AppListResponse](#applistresponse) |
| 422 | Validation error | [ErrorBody](#errorbody) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | App list | **application/json**: [AppListResponse](#applistresponse)<br> |
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /apps/{app_id}/check-dependencies
#### GET
##### Parameters
### [GET] /apps/{app_id}/check-dependencies
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| app_id | path | | Yes | string |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Dependencies checked | [CheckDependenciesResult](#checkdependenciesresult) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Dependencies checked | **application/json**: [CheckDependenciesResult](#checkdependenciesresult)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /apps/{app_id}/describe
#### GET
##### Parameters
### [GET] /apps/{app_id}/describe
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| app_id | path | | Yes | string |
| fields | query | | No | string |
| app_id | path | | Yes | string |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | App description | [AppDescribeResponse](#appdescriberesponse) |
| 422 | Validation error | [ErrorBody](#errorbody) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | App description | **application/json**: [AppDescribeResponse](#appdescriberesponse)<br> |
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /apps/{app_id}/export
#### GET
##### Parameters
### [GET] /apps/{app_id}/export
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| app_id | path | | Yes | string |
| include_secret | query | Include encrypted secret values in the exported DSL | No | boolean |
| workflow_id | query | Export a specific workflow version instead of the current draft | No | string |
| app_id | path | | Yes | string |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Export successful | [AppDslExportResponse](#appdslexportresponse) |
| 422 | Validation error | [ErrorBody](#errorbody) |
| default | Error | [ErrorBody](#errorbody) |
### /apps/{app_id}/files/upload
#### POST
##### Description
| 200 | Export successful | **application/json**: [AppDslExportResponse](#appdslexportresponse)<br> |
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### [POST] /apps/{app_id}/files/upload
Upload a file to use as an input variable when running the app
##### Parameters
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| app_id | path | | Yes | string |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 201 | File uploaded successfully | [FileResponse](#fileresponse) |
| 201 | File uploaded successfully | **application/json**: [FileResponse](#fileresponse)<br> |
| 400 | Bad request — no file or filename missing | |
| 401 | Unauthorized — invalid or expired bearer token | |
| 413 | File too large | |
| 415 | Unsupported file type or blocked extension | |
| default | Error | [ErrorBody](#errorbody) |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /apps/{app_id}/form/human_input/{form_token}
#### GET
##### Parameters
### [GET] /apps/{app_id}/form/human_input/{form_token}
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| app_id | path | | Yes | string |
| form_token | path | | Yes | string |
##### Responses
#### Responses
| Code | Description |
| ---- | ----------- |
| 200 | Form definition |
#### POST
##### Parameters
### [POST] /apps/{app_id}/form/human_input/{form_token}
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| app_id | path | | Yes | string |
| form_token | path | | Yes | string |
| payload | body | | Yes | [HumanInputFormSubmitPayload](#humaninputformsubmitpayload) |
##### Responses
#### Request Body
| Required | Schema |
| -------- | ------ |
| Yes | **application/json**: [HumanInputFormSubmitPayload](#humaninputformsubmitpayload)<br> |
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Form submitted | [FormSubmitResponse](#formsubmitresponse) |
| 422 | Validation error | [ErrorBody](#errorbody) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Form submitted | **application/json**: [FormSubmitResponse](#formsubmitresponse)<br> |
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /apps/{app_id}/run
#### POST
##### Parameters
### [POST] /apps/{app_id}/run
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| app_id | path | | Yes | string |
| payload | body | | Yes | [AppRunRequest](#apprunrequest) |
##### Responses
#### Request Body
| Required | Schema |
| -------- | ------ |
| Yes | **application/json**: [AppRunRequest](#apprunrequest)<br> |
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Run result (SSE stream) | |
| 422 | Validation error | [ErrorBody](#errorbody) |
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)<br> |
### /apps/{app_id}/tasks/{task_id}/events
#### GET
##### Parameters
### [GET] /apps/{app_id}/tasks/{task_id}/events
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| app_id | path | | Yes | string |
| task_id | path | | Yes | string |
##### Responses
#### Responses
| Code | Description |
| ---- | ----------- |
| 200 | SSE event stream |
### /apps/{app_id}/tasks/{task_id}/stop
#### POST
##### Parameters
### [POST] /apps/{app_id}/tasks/{task_id}/stop
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| app_id | path | | Yes | string |
| task_id | path | | Yes | string |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Task stopped | [TaskStopResponse](#taskstopresponse) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Task stopped | **application/json**: [TaskStopResponse](#taskstopresponse)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /oauth/device/approve
### [POST] /oauth/device/approve
#### Request Body
#### POST
##### Parameters
| Required | Schema |
| -------- | ------ |
| Yes | **application/json**: [DeviceMutateRequest](#devicemutaterequest)<br> |
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| payload | body | | Yes | [DeviceMutateRequest](#devicemutaterequest) |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Approved | [DeviceMutateResponse](#devicemutateresponse) |
| 200 | Approved | **application/json**: [DeviceMutateResponse](#devicemutateresponse)<br> |
### /oauth/device/code
### [POST] /oauth/device/code
#### Request Body
#### POST
##### Parameters
| Required | Schema |
| -------- | ------ |
| Yes | **application/json**: [DeviceCodeRequest](#devicecoderequest)<br> |
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| payload | body | | Yes | [DeviceCodeRequest](#devicecoderequest) |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Device code created | [DeviceCodeResponse](#devicecoderesponse) |
| 200 | Device code created | **application/json**: [DeviceCodeResponse](#devicecoderesponse)<br> |
### /oauth/device/deny
### [POST] /oauth/device/deny
#### Request Body
#### POST
##### Parameters
| Required | Schema |
| -------- | ------ |
| Yes | **application/json**: [DeviceMutateRequest](#devicemutaterequest)<br> |
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| payload | body | | Yes | [DeviceMutateRequest](#devicemutaterequest) |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Denied | [DeviceMutateResponse](#devicemutateresponse) |
| 200 | Denied | **application/json**: [DeviceMutateResponse](#devicemutateresponse)<br> |
### /oauth/device/lookup
#### GET
##### Parameters
### [GET] /oauth/device/lookup
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| user_code | query | | Yes | string |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Device lookup result | [DeviceLookupResponse](#devicelookupresponse) |
| 200 | Device lookup result | **application/json**: [DeviceLookupResponse](#devicelookupresponse)<br> |
### /oauth/device/token
### [POST] /oauth/device/token
#### Request Body
#### POST
##### Parameters
| Required | Schema |
| -------- | ------ |
| Yes | **application/json**: [DevicePollRequest](#devicepollrequest)<br> |
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| payload | body | | Yes | [DevicePollRequest](#devicepollrequest) |
##### Responses
#### Responses
| Code | Description |
| ---- | ----------- |
| 200 | Success |
### /permitted-external-apps
#### GET
##### Parameters
### [GET] /permitted-external-apps
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| limit | query | | No | integer |
| limit | query | | No | integer, <br>**Default:** 20 |
| mode | query | | No | string |
| name | query | | No | string |
| page | query | | No | integer |
| page | query | | No | integer, <br>**Default:** 1 |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Permitted external apps list | [PermittedExternalAppsListResponse](#permittedexternalappslistresponse) |
| 422 | Validation error | [ErrorBody](#errorbody) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Permitted external apps list | **application/json**: [PermittedExternalAppsListResponse](#permittedexternalappslistresponse)<br> |
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /workspaces
#### GET
##### Responses
### [GET] /workspaces
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Workspace list | [WorkspaceListResponse](#workspacelistresponse) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Workspace list | **application/json**: [WorkspaceListResponse](#workspacelistresponse)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /workspaces/{workspace_id}
#### GET
##### Parameters
### [GET] /workspaces/{workspace_id}
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| workspace_id | path | | Yes | string |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Workspace detail | [WorkspaceDetailResponse](#workspacedetailresponse) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Workspace detail | **application/json**: [WorkspaceDetailResponse](#workspacedetailresponse)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /workspaces/{workspace_id}/apps/imports
#### POST
##### Parameters
### [POST] /workspaces/{workspace_id}/apps/imports
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| workspace_id | path | | Yes | string |
| payload | body | | Yes | [AppDslImportPayload](#appdslimportpayload) |
##### Responses
#### Request Body
| Required | Schema |
| -------- | ------ |
| Yes | **application/json**: [AppDslImportPayload](#appdslimportpayload)<br> |
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Import completed | [Import](#import) |
| 202 | Import pending confirmation | [Import](#import) |
| 400 | Import failed | [Import](#import) |
| 422 | Validation error | [ErrorBody](#errorbody) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Import completed | **application/json**: [Import](#import)<br> |
| 202 | Import pending confirmation | **application/json**: [Import](#import)<br> |
| 400 | Import failed | **application/json**: [Import](#import)<br> |
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /workspaces/{workspace_id}/apps/imports/{import_id}/confirm
#### POST
##### Parameters
### [POST] /workspaces/{workspace_id}/apps/imports/{import_id}/confirm
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| import_id | path | | Yes | string |
| workspace_id | path | | Yes | string |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Import confirmed | [Import](#import) |
| 400 | Import failed | [Import](#import) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Import confirmed | **application/json**: [Import](#import)<br> |
| 400 | Import failed | **application/json**: [Import](#import)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /workspaces/{workspace_id}/members
### [GET] /workspaces/{workspace_id}/members
#### Parameters
#### GET
##### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| limit | query | | No | integer, <br>**Default:** 20 |
| page | query | | No | integer, <br>**Default:** 1 |
| workspace_id | path | | Yes | string |
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Member list | **application/json**: [MemberListResponse](#memberlistresponse)<br> |
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### [POST] /workspaces/{workspace_id}/members
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| workspace_id | path | | Yes | string |
| limit | query | | No | integer |
| page | query | | No | integer |
##### Responses
#### Request Body
| Required | Schema |
| -------- | ------ |
| Yes | **application/json**: [MemberInvitePayload](#memberinvitepayload)<br> |
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Member list | [MemberListResponse](#memberlistresponse) |
| 422 | Validation error | [ErrorBody](#errorbody) |
| default | Error | [ErrorBody](#errorbody) |
| 201 | Member invited | **application/json**: [MemberInviteResponse](#memberinviteresponse)<br> |
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
#### POST
##### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| workspace_id | path | | Yes | string |
| payload | body | | Yes | [MemberInvitePayload](#memberinvitepayload) |
##### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 201 | Member invited | [MemberInviteResponse](#memberinviteresponse) |
| 422 | Validation error | [ErrorBody](#errorbody) |
| default | Error | [ErrorBody](#errorbody) |
### /workspaces/{workspace_id}/members/{member_id}
#### DELETE
##### Parameters
### [DELETE] /workspaces/{workspace_id}/members/{member_id}
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| member_id | path | | Yes | string |
| workspace_id | path | | Yes | string |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Member removed | [MemberActionResponse](#memberactionresponse) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Member removed | **application/json**: [MemberActionResponse](#memberactionresponse)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /workspaces/{workspace_id}/members/{member_id}/role
#### PUT
##### Parameters
### [PUT] /workspaces/{workspace_id}/members/{member_id}/role
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| member_id | path | | Yes | string |
| workspace_id | path | | Yes | string |
| payload | body | | Yes | [MemberRoleUpdatePayload](#memberroleupdatepayload) |
##### Responses
#### Request Body
| Required | Schema |
| -------- | ------ |
| Yes | **application/json**: [MemberRoleUpdatePayload](#memberroleupdatepayload)<br> |
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Role updated | [MemberActionResponse](#memberactionresponse) |
| 422 | Validation error | [ErrorBody](#errorbody) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Role updated | **application/json**: [MemberActionResponse](#memberactionresponse)<br> |
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
### /workspaces/{workspace_id}/switch
#### POST
##### Parameters
### [POST] /workspaces/{workspace_id}/switch
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| workspace_id | path | | Yes | string |
##### Responses
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Workspace detail | [WorkspaceDetailResponse](#workspacedetailresponse) |
| default | Error | [ErrorBody](#errorbody) |
| 200 | Workspace detail | **application/json**: [WorkspaceDetailResponse](#workspacedetailresponse)<br> |
| default | Error | **application/json**: [ErrorBody](#errorbody)<br> |
---
### Models
### Schemas
#### AccountPayload
@ -538,7 +500,7 @@ Upload a file to use as an input variable when running the app
| subject_email | string | | No |
| subject_issuer | string | | No |
| subject_type | string | | Yes |
| workspaces | [ [WorkspacePayload](#workspacepayload) ] | | No |
| workspaces | [ [WorkspacePayload](#workspacepayload) ], <br>**Default:** | | No |
#### AppDescribeInfo
@ -551,7 +513,7 @@ Upload a file to use as an input variable when running the app
| mode | string | | Yes |
| name | string | | Yes |
| service_api_enabled | boolean | | Yes |
| tags | [ [TagItem](#tagitem) ] | | No |
| tags | [ [TagItem](#tagitem) ], <br>**Default:** | | No |
| updated_at | string | | No |
#### AppDescribeQuery
@ -600,7 +562,7 @@ Request body for POST /workspaces/<workspace_id>/apps/imports.
| icon | string | | No |
| icon_background | string | | No |
| icon_type | string | | No |
| mode | string | Import mode: yaml-content or yaml-url<br>*Enum:* `"yaml-content"`, `"yaml-url"` | Yes |
| mode | string, <br>**Available values:** "yaml-content", "yaml-url" | Import mode: yaml-content or yaml-url<br>*Enum:* `"yaml-content"`, `"yaml-url"` | Yes |
| name | string | Override the app name from the DSL | No |
| yaml_content | string | Inline YAML DSL string (required when mode is yaml-content) | No |
| yaml_url | string | Remote URL to fetch YAML from (required when mode is yaml-url) | No |
@ -614,7 +576,7 @@ Request body for POST /workspaces/<workspace_id>/apps/imports.
| id | string | | Yes |
| mode | string | | Yes |
| name | string | | Yes |
| tags | [ [TagItem](#tagitem) ] | | No |
| tags | [ [TagItem](#tagitem) ], <br>**Default:** | | No |
#### AppListQuery
@ -622,10 +584,10 @@ mode is a closed enum.
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| limit | integer | | No |
| limit | integer, <br>**Default:** 20 | | No |
| mode | [AppMode](#appmode) | | No |
| name | string | | No |
| page | integer | | No |
| page | integer, <br>**Default:** 1 | | No |
| tag | string | | No |
| workspace_id | string | | Yes |
@ -648,7 +610,7 @@ mode is a closed enum.
| id | string | | Yes |
| mode | [AppMode](#appmode) | | Yes |
| name | string | | Yes |
| tags | [ [TagItem](#tagitem) ] | | No |
| tags | [ [TagItem](#tagitem) ], <br>**Default:** | | No |
| updated_at | string | | No |
| workspace_id | string | | No |
| workspace_name | string | | No |
@ -663,7 +625,7 @@ mode is a closed enum.
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| auto_generate_name | boolean | | No |
| auto_generate_name | boolean, <br>**Default:** true | | No |
| conversation_id | string | | No |
| files | [ object ] | | No |
| inputs | object | | Yes |
@ -745,7 +707,7 @@ future server adds a code. Formatter tests pin emitted values to the enum.
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| loc | [ ] | | No |
| loc | [ ], <br>**Default:** | | No |
| msg | string | | Yes |
| type | string | | Yes |
@ -808,7 +770,7 @@ Liveness payload for `GET /openapi/v1/_health` — no auth required.
| ---- | ---- | ----------- | -------- |
| app_id | string | | No |
| app_mode | string | | No |
| current_dsl_version | string | | No |
| current_dsl_version | string, <br>**Default:** 0.6.0 | | No |
| error | string | | No |
| id | string | | Yes |
| imported_dsl_version | string | | No |
@ -837,14 +799,14 @@ Liveness payload for `GET /openapi/v1/_health` — no auth required.
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| result | string | | No |
| result | string, <br>**Default:** success | | No |
#### MemberInvitePayload
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| email | string | | Yes |
| role | string | *Enum:* `"admin"`, `"normal"` | Yes |
| role | string, <br>**Available values:** "admin", "normal" | *Enum:* `"admin"`, `"normal"` | Yes |
#### MemberInviteResponse
@ -853,7 +815,7 @@ Liveness payload for `GET /openapi/v1/_health` — no auth required.
| email | string | | Yes |
| invite_url | string | | Yes |
| member_id | string | | Yes |
| result | string | | No |
| result | string, <br>**Default:** success | | No |
| role | string | | Yes |
| tenant_id | string | | Yes |
@ -863,8 +825,8 @@ Strict (extra='forbid').
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| limit | integer | | No |
| page | integer | | No |
| limit | integer, <br>**Default:** 20 | | No |
| page | integer, <br>**Default:** 1 | | No |
#### MemberListResponse
@ -891,13 +853,13 @@ Strict (extra='forbid').
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| role | string | *Enum:* `"admin"`, `"normal"` | Yes |
| role | string, <br>**Available values:** "admin", "normal" | *Enum:* `"admin"`, `"normal"` | Yes |
#### MessageMetadata
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| retriever_resources | [ object ] | | No |
| retriever_resources | [ object ], <br>**Default:** | | No |
| usage | [UsageInfo](#usageinfo) | | No |
#### OpenApiErrorCode
@ -919,10 +881,10 @@ Strict (extra='forbid').
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| limit | integer | | No |
| limit | integer, <br>**Default:** 20 | | No |
| mode | [AppMode](#appmode) | | No |
| name | string | | No |
| page | integer | | No |
| page | integer, <br>**Default:** 1 | | No |
#### PermittedExternalAppsListResponse
@ -954,7 +916,7 @@ Meta endpoint payload for `GET /openapi/v1/_version` — no auth required.
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| edition | string | *Enum:* `"CLOUD"`, `"SELF_HOSTED"` | Yes |
| edition | string, <br>**Available values:** "CLOUD", "SELF_HOSTED" | *Enum:* `"CLOUD"`, `"SELF_HOSTED"` | Yes |
| version | string | | Yes |
#### SessionListQuery
@ -963,8 +925,8 @@ Pagination for GET /account/sessions. Strict (extra='forbid').
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| limit | integer | | No |
| page | integer | | No |
| limit | integer, <br>**Default:** 100 | | No |
| page | integer, <br>**Default:** 1 | | No |
#### SessionListResponse

View File

@ -60,6 +60,7 @@ exclude = ["providers/vdb/__pycache__", "providers/trace/__pycache__"]
[tool.uv.sources]
dify-agent = { path = "../dify-agent", editable = true }
flask-restx = { git = "https://github.com/asukaminato0721/flask-restx", rev = "27758e26f8f740d7525d5039c51a9e524b6e2b68" }
dify-vdb-alibabacloud-mysql = { workspace = true }
dify-vdb-analyticdb = { workspace = true }
dify-vdb-baidu = { workspace = true }

View File

@ -22,7 +22,7 @@ def _load_generate_swagger_markdown_docs_module():
def test_generate_markdown_docs_keeps_split_docs_and_merges_fastopenapi_into_console(tmp_path, monkeypatch):
module = _load_generate_swagger_markdown_docs_module()
swagger_dir = tmp_path / "openapi"
openapi_dir = tmp_path / "openapi"
markdown_dir = tmp_path / "markdown"
stale_combined_doc = markdown_dir / "api-reference.md"
markdown_dir.mkdir()
@ -50,23 +50,23 @@ def test_generate_markdown_docs_keeps_split_docs_and_merges_fastopenapi_into_con
monkeypatch.setattr(module, "generate_fastopenapi_specs", write_fastopenapi_specs)
monkeypatch.setattr(module, "_convert_spec_to_markdown", convert_spec_to_markdown)
written_paths = module.generate_markdown_docs(swagger_dir, markdown_dir)
written_paths = module.generate_markdown_docs(openapi_dir, markdown_dir)
assert [path.name for path in written_paths] == [
"console-swagger.md",
"web-swagger.md",
"service-swagger.md",
"openapi-swagger.md",
"console-openapi.md",
"web-openapi.md",
"service-openapi.md",
"openapi-openapi.md",
]
assert not stale_combined_doc.exists()
assert not list(swagger_dir.glob("*.json"))
assert not list(openapi_dir.glob("*.json"))
console_markdown = (markdown_dir / "console-swagger.md").read_text(encoding="utf-8")
assert "## FastOpenAPI Preview (OpenAPI 3.0)" in console_markdown
console_markdown = (markdown_dir / "console-openapi.md").read_text(encoding="utf-8")
assert "## FastOpenAPI Preview (OpenAPI 3.1)" in console_markdown
assert "### fastopenapi-console-openapi" in console_markdown
assert "#### Routes" in console_markdown
assert "FastOpenAPI Preview" not in (markdown_dir / "web-swagger.md").read_text(encoding="utf-8")
assert "FastOpenAPI Preview" not in (markdown_dir / "service-swagger.md").read_text(encoding="utf-8")
assert "FastOpenAPI Preview" not in (markdown_dir / "web-openapi.md").read_text(encoding="utf-8")
assert "FastOpenAPI Preview" not in (markdown_dir / "service-openapi.md").read_text(encoding="utf-8")
def test_generate_markdown_docs_only_removes_generated_specs_from_separate_swagger_dir(tmp_path, monkeypatch):
@ -107,39 +107,41 @@ def test_generate_markdown_docs_only_removes_generated_specs_from_separate_swagg
def test_patch_union_schema_markdown_fills_converter_blank_schema_types(tmp_path):
module = _load_generate_swagger_markdown_docs_module()
spec_path = tmp_path / "console-swagger.json"
spec_path = tmp_path / "console-openapi.json"
spec_path.write_text(
json.dumps(
{
"definitions": {
"FormInputConfig": {
"oneOf": [
{"$ref": "#/definitions/ParagraphInputConfig"},
{"$ref": "#/definitions/SelectInputConfig"},
{"$ref": "#/definitions/FileInputConfig"},
],
},
"ParagraphInputConfig": {
"properties": {
"default": {
"anyOf": [
{"$ref": "#/definitions/StringSource"},
{"type": "null"},
],
"components": {
"schemas": {
"FormInputConfig": {
"oneOf": [
{"$ref": "#/components/schemas/ParagraphInputConfig"},
{"$ref": "#/components/schemas/SelectInputConfig"},
{"$ref": "#/components/schemas/FileInputConfig"},
],
},
"ParagraphInputConfig": {
"properties": {
"default": {
"anyOf": [
{"$ref": "#/components/schemas/StringSource"},
{"type": "null"},
],
},
"output_variable_name": {"type": "string"},
},
"output_variable_name": {"type": "string"},
},
},
"SelectInputConfig": {
"properties": {
"option_source": {"$ref": "#/definitions/StringListSource"},
"SelectInputConfig": {
"properties": {
"option_source": {"$ref": "#/components/schemas/StringListSource"},
},
},
},
"FileInputConfig": {
"properties": {
"allowed_file_types": {
"type": "array",
"items": {"$ref": "#/definitions/FileType"},
"FileInputConfig": {
"properties": {
"allowed_file_types": {
"type": "array",
"items": {"$ref": "#/components/schemas/FileType"},
},
},
},
},
@ -188,24 +190,26 @@ def test_patch_union_schema_markdown_fills_converter_blank_schema_types(tmp_path
assert "| allowed_file_types | [ [FileType](#filetype) ] | | No |" in patched
def test_patch_union_schema_markdown_fills_regular_definition_union_property(tmp_path):
def test_patch_union_schema_markdown_fills_regular_schema_union_property(tmp_path):
module = _load_generate_swagger_markdown_docs_module()
spec_path = tmp_path / "service-swagger.json"
spec_path = tmp_path / "service-openapi.json"
spec_path.write_text(
json.dumps(
{
"definitions": {
"DocumentMetadataResponse": {
"properties": {
"id": {"type": "string"},
"value": {
"anyOf": [
{"type": "string"},
{"type": "integer"},
{"type": "number"},
{"type": "boolean"},
{"type": "null"},
],
"components": {
"schemas": {
"DocumentMetadataResponse": {
"properties": {
"id": {"type": "string"},
"value": {
"anyOf": [
{"type": "string"},
{"type": "integer"},
{"type": "number"},
{"type": "boolean"},
{"type": "null"},
],
},
},
},
},
@ -227,9 +231,9 @@ def test_patch_union_schema_markdown_fills_regular_definition_union_property(tmp
assert "| value | string<br>integer<br>number<br>boolean | | No |" in patched
def test_patch_union_schema_markdown_ignores_specs_without_definitions(tmp_path):
def test_patch_union_schema_markdown_ignores_specs_without_schemas(tmp_path):
module = _load_generate_swagger_markdown_docs_module()
spec_path = tmp_path / "console-swagger.json"
spec_path = tmp_path / "console-openapi.json"
spec_path.write_text("{}", encoding="utf-8")
assert module._patch_union_schema_markdown("unchanged", spec_path) == "unchanged"
@ -237,27 +241,29 @@ def test_patch_union_schema_markdown_ignores_specs_without_definitions(tmp_path)
def test_patch_union_schema_markdown_ignores_unrenderable_shapes(tmp_path):
module = _load_generate_swagger_markdown_docs_module()
spec_path = tmp_path / "console-swagger.json"
spec_path = tmp_path / "console-openapi.json"
spec_path.write_text(
json.dumps(
{
"definitions": {
"NotAMapping": [],
"BrokenUnion": {
"oneOf": [
{},
{"$ref": "#/definitions/Missing"},
{"$ref": "#/definitions/NoPropertyMapping"},
],
"components": {
"schemas": {
"NotAMapping": [],
"BrokenUnion": {
"oneOf": [
{},
{"$ref": "#/components/schemas/Missing"},
{"$ref": "#/components/schemas/NoPropertyMapping"},
],
},
"NoPropertyMapping": {"properties": []},
},
"NoPropertyMapping": {"properties": []},
}
}
),
encoding="utf-8",
)
assert module._definition_ref_name(None) is None
assert module._schema_ref_name(None) is None
assert module._schema_markdown_type(None) == ""
assert module._schema_markdown_type({"anyOf": [{"type": "null"}]}) == ""
assert module._replace_schema_table_type("unchanged", "Definition", "field", "") == "unchanged"
@ -280,24 +286,26 @@ def test_patch_union_schema_markdown_ignores_unrenderable_shapes(tmp_path):
def test_convert_spec_to_markdown_patches_generated_union_tables(tmp_path, monkeypatch):
module = _load_generate_swagger_markdown_docs_module()
spec_path = tmp_path / "console-swagger.json"
output_path = tmp_path / "console-swagger.md"
spec_path = tmp_path / "console-openapi.json"
output_path = tmp_path / "console-openapi.md"
spec_path.write_text(
json.dumps(
{
"definitions": {
"FormInputConfig": {
"oneOf": [
{"$ref": "#/definitions/ParagraphInputConfig"},
],
},
"ParagraphInputConfig": {
"properties": {
"default": {
"anyOf": [
{"$ref": "#/definitions/StringSource"},
{"type": "null"},
],
"components": {
"schemas": {
"FormInputConfig": {
"oneOf": [
{"$ref": "#/components/schemas/ParagraphInputConfig"},
],
},
"ParagraphInputConfig": {
"properties": {
"default": {
"anyOf": [
{"$ref": "#/components/schemas/StringSource"},
{"type": "null"},
],
},
},
},
},

View File

@ -1,4 +1,4 @@
"""Unit tests for the standalone Swagger export helper."""
"""Unit tests for the standalone OpenAPI export helper."""
import importlib.util
import json
@ -30,42 +30,82 @@ def _load_generate_swagger_specs_module():
return module
def test_generate_specs_writes_console_web_and_service_swagger_files(tmp_path):
def _operation_ids(payload):
methods = {"delete", "get", "head", "options", "patch", "post", "put", "trace"}
for path_item in payload["paths"].values():
for method, operation in path_item.items():
if method in methods and isinstance(operation, dict) and "operationId" in operation:
yield operation["operationId"]
def _get_operations(payload):
for path_item in payload["paths"].values():
operation = path_item.get("get")
if isinstance(operation, dict):
yield operation
def test_generate_specs_writes_console_web_and_service_openapi_files(tmp_path):
module = _load_generate_swagger_specs_module()
written_paths = module.generate_specs(tmp_path)
assert [path.name for path in written_paths] == [
"console-swagger.json",
"web-swagger.json",
"service-swagger.json",
"openapi-swagger.json",
"console-openapi.json",
"web-openapi.json",
"service-openapi.json",
"openapi-openapi.json",
]
for path in written_paths:
payload = json.loads(path.read_text(encoding="utf-8"))
assert payload["swagger"] == "2.0"
assert payload["openapi"].startswith("3.")
assert "paths" in payload
def test_generate_specs_writes_swagger_with_resolvable_references_and_no_nulls(tmp_path):
def test_generate_specs_writes_openapi_with_resolvable_references_and_no_nulls(tmp_path):
module = _load_generate_swagger_specs_module()
written_paths = module.generate_specs(tmp_path)
for path in written_paths:
payload = json.loads(path.read_text(encoding="utf-8"))
definitions = payload["definitions"]
schemas = payload["components"]["schemas"]
refs = {
item["$ref"].removeprefix("#/definitions/")
item["$ref"].removeprefix("#/components/schemas/")
for item in _walk_values(payload)
if isinstance(item, dict) and isinstance(item.get("$ref"), str)
if isinstance(item, dict)
and isinstance(item.get("$ref"), str)
and item["$ref"].startswith("#/components/schemas/")
}
assert refs <= set(definitions)
assert refs <= set(schemas)
assert all(value is not None for value in _walk_values(payload))
def test_generate_specs_writes_unique_operation_ids(tmp_path):
module = _load_generate_swagger_specs_module()
written_paths = module.generate_specs(tmp_path)
for path in written_paths:
payload = json.loads(path.read_text(encoding="utf-8"))
operation_ids = list(_operation_ids(payload))
assert len(operation_ids) == len(set(operation_ids))
def test_generate_specs_moves_get_request_bodies_to_query_parameters(tmp_path):
module = _load_generate_swagger_specs_module()
written_paths = module.generate_specs(tmp_path)
for path in written_paths:
payload = json.loads(path.read_text(encoding="utf-8"))
assert all("requestBody" not in operation for operation in _get_operations(payload))
def test_generate_specs_is_idempotent(tmp_path):
module = _load_generate_swagger_specs_module()

View File

@ -78,9 +78,9 @@ def mock_console_ns():
def test_default_ref_template_value():
from controllers.common.schema import DEFAULT_REF_TEMPLATE_SWAGGER_2_0
from controllers.common.schema import DEFAULT_REF_TEMPLATE_OPENAPI_3_0
assert DEFAULT_REF_TEMPLATE_SWAGGER_2_0 == "#/definitions/{model}"
assert DEFAULT_REF_TEMPLATE_OPENAPI_3_0 == "#/components/schemas/{model}"
def test_register_schema_model_calls_namespace_schema_model():
@ -100,7 +100,7 @@ def test_register_schema_model_calls_namespace_schema_model():
def test_register_schema_model_passes_schema_from_pydantic():
from controllers.common.schema import DEFAULT_REF_TEMPLATE_SWAGGER_2_0, register_schema_model
from controllers.common.schema import DEFAULT_REF_TEMPLATE_OPENAPI_3_0, register_schema_model
namespace = MagicMock(spec=Namespace)
@ -108,24 +108,24 @@ def test_register_schema_model_passes_schema_from_pydantic():
schema = namespace.schema_model.call_args.args[1]
expected_schema = UserModel.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_SWAGGER_2_0)
expected_schema = UserModel.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_OPENAPI_3_0)
assert schema == expected_schema
def test_register_schema_model_promotes_nested_pydantic_definitions():
from controllers.common.schema import DEFAULT_REF_TEMPLATE_SWAGGER_2_0, register_schema_model
from controllers.common.schema import DEFAULT_REF_TEMPLATE_OPENAPI_3_0, register_schema_model
namespace = MagicMock(spec=Namespace)
register_schema_model(namespace, ParentModel)
called_schemas = {call.args[0]: call.args[1] for call in namespace.schema_model.call_args_list}
parent_schema = ParentModel.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_SWAGGER_2_0)
parent_schema = ParentModel.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_OPENAPI_3_0)
assert set(called_schemas) == {"ParentModel", "ChildModel"}
assert "$defs" not in called_schemas["ParentModel"]
assert called_schemas["ParentModel"]["properties"]["child"]["$ref"] == "#/definitions/ChildModel"
assert called_schemas["ParentModel"]["properties"]["child"]["$ref"] == "#/components/schemas/ChildModel"
assert called_schemas["ChildModel"] == parent_schema["$defs"]["ChildModel"]
@ -179,7 +179,7 @@ def test_register_response_schema_model_uses_serialized_field_names():
assert "internal_name" not in schema["properties"]
def test_register_schema_model_flattens_simple_nullable_any_of_for_swagger_2():
def test_register_schema_model_preserves_openapi_nullable_unions():
from controllers.common.schema import register_schema_model
namespace = MagicMock(spec=Namespace)
@ -189,14 +189,9 @@ def test_register_schema_model_flattens_simple_nullable_any_of_for_swagger_2():
called_schemas = {call.args[0]: call.args[1] for call in namespace.schema_model.call_args_list}
properties = called_schemas["NullableSchemaModel"]["properties"]
assert properties["name"]["type"] == "string"
assert properties["name"]["x-nullable"] is True
assert "anyOf" not in properties["name"]
assert properties["tags"]["type"] == "array"
assert properties["tags"]["items"] == {"type": "string"}
assert properties["tags"]["x-nullable"] is True
assert properties["owner"]["$ref"] == "#/definitions/UserModel"
assert properties["owner"]["x-nullable"] is True
assert properties["name"]["anyOf"] == [{"type": "string"}, {"type": "null"}]
assert properties["tags"]["anyOf"] == [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}]
assert properties["owner"]["anyOf"] == [{"$ref": "#/components/schemas/UserModel"}, {"type": "null"}]
assert "anyOf" in properties["ambiguous"]

View File

@ -1,20 +1,20 @@
"""Swagger JSON rendering tests for Flask-RESTX API blueprints."""
"""OpenAPI JSON rendering tests for Flask-RESTX API blueprints."""
import pytest
from flask import Flask
def _definition_refs(value: object) -> set[str]:
def _schema_refs(value: object) -> set[str]:
refs: set[str] = set()
if isinstance(value, dict):
ref = value.get("$ref")
if isinstance(ref, str) and ref.startswith("#/definitions/"):
refs.add(ref.removeprefix("#/definitions/"))
if isinstance(ref, str) and ref.startswith("#/components/schemas/"):
refs.add(ref.removeprefix("#/components/schemas/"))
for item in value.values():
refs.update(_definition_refs(item))
refs.update(_schema_refs(item))
elif isinstance(value, list):
for item in value:
refs.update(_definition_refs(item))
refs.update(_schema_refs(item))
return refs
@ -31,6 +31,18 @@ def _parameters_by_name(operation: dict[str, object]) -> dict[str, dict[str, obj
return result
def _multipart_form_schema(operation: dict[str, object]) -> dict[str, object]:
request_body = operation.get("requestBody")
assert isinstance(request_body, dict)
content = request_body.get("content")
assert isinstance(content, dict)
multipart = content.get("multipart/form-data")
assert isinstance(multipart, dict)
schema = multipart.get("schema")
assert isinstance(schema, dict)
return schema
@pytest.mark.parametrize(
("first_kwargs", "second_kwargs"),
[
@ -53,7 +65,7 @@ def test_inline_model_name_includes_list_constraints(
assert _inline_model_name(first_inline_model) != _inline_model_name(second_inline_model)
def test_swagger_json_endpoints_render(monkeypatch: pytest.MonkeyPatch):
def test_openapi_json_endpoints_render(monkeypatch: pytest.MonkeyPatch):
from configs import dify_config
from controllers.console import bp as console_bp
from controllers.service_api import bp as service_api_bp
@ -70,17 +82,17 @@ def test_swagger_json_endpoints_render(monkeypatch: pytest.MonkeyPatch):
client = app.test_client()
for route in ("/console/api/swagger.json", "/api/swagger.json", "/v1/swagger.json"):
for route in ("/console/api/openapi.json", "/api/openapi.json", "/v1/openapi.json"):
response = client.get(route)
assert response.status_code == 200
payload = response.get_json()
assert payload["swagger"] == "2.0"
assert payload["openapi"].startswith("3.")
assert "paths" in payload
assert "definitions" in payload
assert isinstance(payload["definitions"], dict)
missing_refs = _definition_refs(payload) - set(payload["definitions"])
assert not sorted(ref for ref in missing_refs if ref.startswith("_AnonymousInlineModel"))
assert "schemas" in payload["components"]
assert isinstance(payload["components"]["schemas"], dict)
missing_refs = _schema_refs(payload) - set(payload["components"]["schemas"])
assert not missing_refs
assert app.config["RESTX_INCLUDE_ALL_MODELS"] is True
@ -96,17 +108,17 @@ def test_service_document_file_routes_document_multipart_form_data(monkeypatch:
app.config["RESTX_INCLUDE_ALL_MODELS"] = True
app.register_blueprint(service_api_bp)
payload = app.test_client().get("/v1/swagger.json").get_json()
payload = app.test_client().get("/v1/openapi.json").get_json()
paths = payload["paths"]
create_operation = paths["/datasets/{dataset_id}/document/create-by-file"]["post"]
create_params = _parameters_by_name(create_operation)
assert create_operation["consumes"] == ["multipart/form-data"]
assert create_params["file"]["in"] == "formData"
assert create_params["file"]["type"] == "file"
assert create_params["file"]["required"] is True
assert create_params["data"]["in"] == "formData"
assert create_params["data"]["type"] == "string"
create_schema = _multipart_form_schema(create_operation)
create_properties = create_schema["properties"]
assert isinstance(create_properties, dict)
assert create_properties["file"] == {"type": "string", "format": "binary"}
assert create_properties["data"] == {"type": "string"}
assert create_schema["required"] == ["file"]
assert create_operation["requestBody"]["required"] is True
for path in (
"/datasets/{dataset_id}/documents/{document_id}",
@ -114,13 +126,13 @@ def test_service_document_file_routes_document_multipart_form_data(monkeypatch:
"/datasets/{dataset_id}/documents/{document_id}/update_by_file",
):
update_operation = paths[path]["patch" if path.endswith("{document_id}") else "post"]
update_params = _parameters_by_name(update_operation)
assert update_operation["consumes"] == ["multipart/form-data"]
assert update_params["file"]["in"] == "formData"
assert update_params["file"]["type"] == "file"
assert update_params["file"]["required"] is False
assert update_params["data"]["in"] == "formData"
assert update_params["data"]["type"] == "string"
update_schema = _multipart_form_schema(update_operation)
update_properties = update_schema["properties"]
assert isinstance(update_properties, dict)
assert update_properties["file"] == {"type": "string", "format": "binary"}
assert update_properties["data"] == {"type": "string"}
assert "required" not in update_schema
assert update_operation["requestBody"]["required"] is False
def test_service_document_list_documents_query_params_render(monkeypatch: pytest.MonkeyPatch):
@ -134,7 +146,7 @@ def test_service_document_list_documents_query_params_render(monkeypatch: pytest
app.config["RESTX_INCLUDE_ALL_MODELS"] = True
app.register_blueprint(service_api_bp)
payload = app.test_client().get("/v1/swagger.json").get_json()
payload = app.test_client().get("/v1/openapi.json").get_json()
operation = payload["paths"]["/datasets/{dataset_id}/documents"]["get"]
params = _parameters_by_name(operation)
@ -153,7 +165,7 @@ def test_console_account_avatar_query_param_renders_as_query(monkeypatch: pytest
app.config["RESTX_INCLUDE_ALL_MODELS"] = True
app.register_blueprint(console_bp)
payload = app.test_client().get("/console/api/swagger.json").get_json()
payload = app.test_client().get("/console/api/openapi.json").get_json()
operation = payload["paths"]["/account/avatar"]["get"]
params = _parameters_by_name(operation)

10
api/uv.lock generated
View File

@ -1630,7 +1630,7 @@ requires-dist = [
{ name = "flask-login", specifier = "==0.6.3" },
{ name = "flask-migrate", specifier = ">=4.1.0,<5.0.0" },
{ name = "flask-orjson", specifier = ">=2.0.0,<3.0.0" },
{ name = "flask-restx", specifier = ">=1.3.2,<2.0.0" },
{ name = "flask-restx", git = "https://github.com/asukaminato0721/flask-restx?rev=27758e26f8f740d7525d5039c51a9e524b6e2b68" },
{ name = "gevent", specifier = ">=26.4.0,<26.5.0" },
{ name = "gevent-websocket", specifier = "==0.10.1" },
{ name = "gmpy2", specifier = ">=2.3.0,<3.0.0" },
@ -2570,8 +2570,8 @@ wheels = [
[[package]]
name = "flask-restx"
version = "1.3.2"
source = { registry = "https://pypi.org/simple" }
version = "1.3.3.dev0"
source = { git = "https://github.com/asukaminato0721/flask-restx?rev=27758e26f8f740d7525d5039c51a9e524b6e2b68#27758e26f8f740d7525d5039c51a9e524b6e2b68" }
dependencies = [
{ name = "aniso8601" },
{ name = "flask" },
@ -2580,10 +2580,6 @@ dependencies = [
{ name = "referencing" },
{ name = "werkzeug" },
]
sdist = { url = "https://files.pythonhosted.org/packages/43/89/9b9ca58cbb8e9ec46f4a510ba93878e0c88d518bf03c350e3b1b7ad85cbe/flask-restx-1.3.2.tar.gz", hash = "sha256:0ae13d77e7d7e4dce513970cfa9db45364aef210e99022de26d2b73eb4dbced5", size = 2814719, upload-time = "2025-09-23T20:34:25.21Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7a/3f/b82cd8e733a355db1abb8297afbf59ec972c00ef90bf8d4eed287958b204/flask_restx-1.3.2-py2.py3-none-any.whl", hash = "sha256:6e035496e8223668044fc45bf769e526352fd648d9e159bd631d94fd645a687b", size = 2799859, upload-time = "2025-09-23T20:34:23.055Z" },
]
[[package]]
name = "flask-sqlalchemy"

View File

@ -36,6 +36,12 @@ export type ImportAppResult = {
readonly leakedDependencies: readonly PluginDependency[]
}
type PluginDependencyLabelInput = {
readonly current_identifier?: string | null
readonly type?: PluginDependency['type']
readonly value?: unknown
}
export async function runImportApp(opts: ImportAppOptions, deps: ImportAppDeps): Promise<ImportAppResult> {
const env = deps.envLookup ?? getEnv
const io = deps.io ?? nullStreams()
@ -124,7 +130,7 @@ export async function runImportApp(opts: ImportAppOptions, deps: ImportAppDeps):
// `value` is a loosely-typed wire object (Github | Marketplace | Package); narrow it here to
// surface a human-readable identifier without depending on which variant the server returned.
export function pluginDependencyLabel(dep: PluginDependency): string {
export function pluginDependencyLabel(dep: PluginDependencyLabelInput): string {
const value = dep.value
if (typeof value === 'object' && value !== null) {
const fields = value as Record<string, unknown>

View File

@ -21,7 +21,7 @@ export const zAccountAvatarPayload = z.object({
*/
export const zAccount = z.object({
avatar: z.string().nullish(),
avatar_url: z.string().readonly().nullable(),
avatar_url: z.string().nullable(),
created_at: z.int().nullish(),
email: z.string(),
id: z.string(),

View File

@ -18,7 +18,7 @@ export type ActivationResponse = {
}
export type ActivationCheckResponse = {
data?: ActivationCheckData
data?: ActivationCheckData | null
is_valid: boolean
}

View File

@ -34,7 +34,7 @@ export const zActivationCheckData = z.object({
* ActivationCheckResponse
*/
export const zActivationCheckResponse = z.object({
data: zActivationCheckData.optional(),
data: zActivationCheckData.nullish(),
is_valid: z.boolean(),
})

View File

@ -17,14 +17,14 @@ export type RosterAgentCreatePayload = {
description?: string
icon?: string | null
icon_background?: string | null
icon_type?: AgentIconType
icon_type?: AgentIconType | null
name: string
role?: string
version_note?: string | null
}
export type AgentRosterResponse = {
active_config_snapshot?: AgentConfigSnapshotSummaryResponse
active_config_snapshot?: AgentConfigSnapshotSummaryResponse | null
active_config_snapshot_id?: string | null
agent_kind: AgentKind
app_id?: string | null
@ -35,7 +35,7 @@ export type AgentRosterResponse = {
description: string
icon?: string | null
icon_background?: string | null
icon_type?: AgentIconType
icon_type?: AgentIconType | null
id: string
name: string
published_node_reference_count?: number
@ -63,7 +63,7 @@ export type RosterAgentUpdatePayload = {
description?: string | null
icon?: string | null
icon_background?: string | null
icon_type?: AgentIconType
icon_type?: AgentIconType | null
name?: string | null
role?: string | null
}
@ -92,7 +92,7 @@ export type AgentSoulConfig = {
knowledge?: AgentSoulKnowledgeConfig
memory?: AgentSoulMemoryConfig
misc_legacy?: AgentSoulAppFeaturesConfig
model?: AgentSoulModelConfig
model?: AgentSoulModelConfig | null
prompt?: AgentSoulPromptConfig
sandbox?: AgentSoulSandboxConfig
schema_version?: number
@ -130,7 +130,7 @@ export type AgentSource = 'agent_app' | 'imported' | 'system' | 'workflow'
export type AgentStatus = 'active' | 'archived'
export type AgentInviteOptionResponse = {
active_config_snapshot?: AgentConfigSnapshotSummaryResponse
active_config_snapshot?: AgentConfigSnapshotSummaryResponse | null
active_config_snapshot_id?: string | null
agent_kind: AgentKind
app_id?: string | null
@ -142,7 +142,7 @@ export type AgentInviteOptionResponse = {
existing_node_ids?: Array<string>
icon?: string | null
icon_background?: string | null
icon_type?: AgentIconType
icon_type?: AgentIconType | null
id: string
in_current_workflow_count?: number
is_in_current_workflow?: boolean
@ -174,12 +174,12 @@ export type AgentConfigRevisionResponse = {
export type AgentSoulAppFeaturesConfig = {
opening_statement?: string | null
retriever_resource?: AgentFeatureToggleConfig
sensitive_word_avoidance?: AgentSensitiveWordAvoidanceFeatureConfig
speech_to_text?: AgentFeatureToggleConfig
retriever_resource?: AgentFeatureToggleConfig | null
sensitive_word_avoidance?: AgentSensitiveWordAvoidanceFeatureConfig | null
speech_to_text?: AgentFeatureToggleConfig | null
suggested_questions?: Array<string> | null
suggested_questions_after_answer?: AgentSuggestedQuestionsAfterAnswerFeatureConfig
text_to_speech?: AgentTextToSpeechFeatureConfig
suggested_questions_after_answer?: AgentSuggestedQuestionsAfterAnswerFeatureConfig | null
text_to_speech?: AgentTextToSpeechFeatureConfig | null
[key: string]: unknown
}
@ -203,7 +203,7 @@ export type AgentSoulHumanConfig = {
export type AgentSoulKnowledgeConfig = {
datasets?: Array<AgentKnowledgeDatasetConfig>
query_config?: AgentKnowledgeQueryConfig
query_mode?: AgentKnowledgeQueryMode
query_mode?: AgentKnowledgeQueryMode | null
}
export type AgentSoulMemoryConfig = {
@ -213,7 +213,7 @@ export type AgentSoulMemoryConfig = {
}
export type AgentSoulModelConfig = {
credential_ref?: AgentSoulModelCredentialRef
credential_ref?: AgentSoulModelCredentialRef | null
model: string
model_provider: string
model_settings?: AgentSoulModelSettings
@ -252,7 +252,7 @@ export type AgentFeatureToggleConfig = {
}
export type AgentSensitiveWordAvoidanceFeatureConfig = {
config?: AgentModerationProviderConfig
config?: AgentModerationProviderConfig | null
enabled?: boolean
type?: string | null
[key: string]: unknown
@ -260,7 +260,7 @@ export type AgentSensitiveWordAvoidanceFeatureConfig = {
export type AgentSuggestedQuestionsAfterAnswerFeatureConfig = {
enabled?: boolean
model?: AgentSoulModelConfig
model?: AgentSoulModelConfig | null
prompt?: string | null
[key: string]: unknown
}
@ -279,7 +279,7 @@ export type AgentSecretRefConfig = {
id?: string | null
key?: string | null
name?: string | null
permission?: AgentPermissionConfig
permission?: AgentPermissionConfig | null
permission_status?: string | null
provider?: string | null
provider_credential_id?: string | null
@ -290,13 +290,31 @@ export type AgentSecretRefConfig = {
}
export type AgentEnvVariableConfig = {
default?: unknown
default?:
| string
| number
| number
| boolean
| Array<string>
| Array<number>
| Array<number>
| Array<boolean>
| null
env_name?: string | null
key?: string | null
name?: string | null
required?: boolean
type?: string | null
value?: unknown
value?:
| string
| number
| number
| boolean
| Array<string>
| Array<number>
| Array<number>
| Array<boolean>
| null
variable?: string | null
[key: string]: unknown
}
@ -356,7 +374,7 @@ export type AgentSoulModelSettings = {
frequency_penalty?: number | null
max_tokens?: number | null
presence_penalty?: number | null
response_format?: AgentModelResponseFormatConfig
response_format?: AgentModelResponseFormatConfig | null
stop?: Array<string> | null
temperature?: number | null
top_p?: number | null
@ -395,7 +413,7 @@ export type AgentSkillRefConfig = {
export type AgentCliToolConfig = {
approved?: boolean
authorization_status?: AgentCliToolAuthorizationStatus
authorization_status?: AgentCliToolAuthorizationStatus | null
command?: string | null
dangerous?: boolean
dangerous_accepted?: boolean
@ -413,18 +431,18 @@ export type AgentCliToolConfig = {
}
label?: string | null
name?: string | null
permission?: AgentPermissionConfig
permission?: AgentPermissionConfig | null
pre_authorized?: boolean | null
requires_confirmation?: boolean
risk_accepted?: boolean
risk_level?: AgentCliToolRiskLevel
risk_level?: AgentCliToolRiskLevel | null
setup_command?: string | null
tool_name?: string | null
[key: string]: unknown
}
export type AgentSoulDifyToolConfig = {
credential_ref?: AgentSoulDifyToolCredentialRef
credential_ref?: AgentSoulDifyToolCredentialRef | null
credential_type?: 'api-key' | 'oauth2' | 'unauthorized'
description?: string | null
enabled?: boolean
@ -434,16 +452,25 @@ export type AgentSoulDifyToolConfig = {
provider_id?: string | null
provider_type?: string
runtime_parameters?: {
[key: string]: unknown
[key: string]:
| string
| number
| number
| boolean
| Array<string>
| Array<number>
| Array<number>
| Array<boolean>
| null
}
tool_name?: string | null
}
export type AgentModerationProviderConfig = {
api_based_extension_id?: string | null
inputs_config?: AgentModerationIoConfig
inputs_config?: AgentModerationIoConfig | null
keywords?: string | null
outputs_config?: AgentModerationIoConfig
outputs_config?: AgentModerationIoConfig | null
[key: string]: unknown
}
@ -546,9 +573,7 @@ export type DeleteAgentsByAgentIdData = {
}
export type DeleteAgentsByAgentIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteAgentsByAgentIdResponse

View File

@ -16,7 +16,7 @@ export const zRosterAgentUpdatePayload = z.object({
description: z.string().nullish(),
icon: z.string().max(255).nullish(),
icon_background: z.string().max(255).nullish(),
icon_type: zAgentIconType.optional(),
icon_type: zAgentIconType.nullish(),
name: z.string().min(1).max(255).nullish(),
role: z.string().max(255).nullish(),
})
@ -88,7 +88,7 @@ export const zAgentStatus = z.enum(['active', 'archived'])
* AgentRosterResponse
*/
export const zAgentRosterResponse = z.object({
active_config_snapshot: zAgentConfigSnapshotSummaryResponse.optional(),
active_config_snapshot: zAgentConfigSnapshotSummaryResponse.nullish(),
active_config_snapshot_id: z.string().nullish(),
agent_kind: zAgentKind,
app_id: z.string().nullish(),
@ -99,7 +99,7 @@ export const zAgentRosterResponse = z.object({
description: z.string(),
icon: z.string().nullish(),
icon_background: z.string().nullish(),
icon_type: zAgentIconType.optional(),
icon_type: zAgentIconType.nullish(),
id: z.string(),
name: z.string(),
published_node_reference_count: z.int().optional().default(0),
@ -130,7 +130,7 @@ export const zAgentRosterListResponse = z.object({
* AgentInviteOptionResponse
*/
export const zAgentInviteOptionResponse = z.object({
active_config_snapshot: zAgentConfigSnapshotSummaryResponse.optional(),
active_config_snapshot: zAgentConfigSnapshotSummaryResponse.nullish(),
active_config_snapshot_id: z.string().nullish(),
agent_kind: zAgentKind,
app_id: z.string().nullish(),
@ -142,7 +142,7 @@ export const zAgentInviteOptionResponse = z.object({
existing_node_ids: z.array(z.string()).optional(),
icon: z.string().nullish(),
icon_background: z.string().nullish(),
icon_type: zAgentIconType.optional(),
icon_type: zAgentIconType.nullish(),
id: z.string(),
in_current_workflow_count: z.int().optional().default(0),
is_in_current_workflow: z.boolean().optional().default(false),
@ -237,13 +237,35 @@ export const zAgentTextToSpeechFeatureConfig = z.object({
* AgentEnvVariableConfig
*/
export const zAgentEnvVariableConfig = z.object({
default: z.unknown().optional(),
default: z
.union([
z.string(),
z.int(),
z.number(),
z.boolean(),
z.array(z.string()),
z.array(z.int()),
z.array(z.number()),
z.array(z.boolean()),
])
.nullish(),
env_name: z.string().max(255).nullish(),
key: z.string().max(255).nullish(),
name: z.string().max(255).nullish(),
required: z.boolean().optional().default(false),
type: z.string().max(64).nullish(),
value: z.unknown().optional(),
value: z
.union([
z.string(),
z.int(),
z.number(),
z.boolean(),
z.array(z.string()),
z.array(z.int()),
z.array(z.number()),
z.array(z.boolean()),
])
.nullish(),
variable: z.string().max(255).nullish(),
})
@ -309,7 +331,7 @@ export const zAgentKnowledgeQueryMode = z.enum(['generated_query', 'user_query']
export const zAgentSoulKnowledgeConfig = z.object({
datasets: z.array(zAgentKnowledgeDatasetConfig).optional(),
query_config: zAgentKnowledgeQueryConfig.optional(),
query_mode: zAgentKnowledgeQueryMode.optional(),
query_mode: zAgentKnowledgeQueryMode.nullish(),
})
/**
@ -413,7 +435,7 @@ export const zAgentSecretRefConfig = z.object({
id: z.string().max(255).nullish(),
key: z.string().max(255).nullish(),
name: z.string().max(255).nullish(),
permission: zAgentPermissionConfig.optional(),
permission: zAgentPermissionConfig.nullish(),
permission_status: z.string().max(64).nullish(),
provider: z.string().max(255).nullish(),
provider_credential_id: z.string().max(255).nullish(),
@ -444,7 +466,7 @@ export const zAgentSoulModelSettings = z.object({
frequency_penalty: z.number().nullish(),
max_tokens: z.int().nullish(),
presence_penalty: z.number().nullish(),
response_format: zAgentModelResponseFormatConfig.optional(),
response_format: zAgentModelResponseFormatConfig.nullish(),
stop: z.array(z.string()).nullish(),
temperature: z.number().nullish(),
top_p: z.number().nullish(),
@ -456,7 +478,7 @@ export const zAgentSoulModelSettings = z.object({
* Stable model selection for Agent runtime without storing secret values.
*/
export const zAgentSoulModelConfig = z.object({
credential_ref: zAgentSoulModelCredentialRef.optional(),
credential_ref: zAgentSoulModelCredentialRef.nullish(),
model: z.string().min(1).max(255),
model_provider: z.string().min(1).max(255),
model_settings: zAgentSoulModelSettings.optional(),
@ -468,7 +490,7 @@ export const zAgentSoulModelConfig = z.object({
*/
export const zAgentSuggestedQuestionsAfterAnswerFeatureConfig = z.object({
enabled: z.boolean().optional().default(false),
model: zAgentSoulModelConfig.optional(),
model: zAgentSoulModelConfig.nullish(),
prompt: z.string().nullish(),
})
@ -512,7 +534,7 @@ export const zAgentCliToolRiskLevel = z.enum(['dangerous', 'safe', 'unknown'])
*/
export const zAgentCliToolConfig = z.object({
approved: z.boolean().optional().default(false),
authorization_status: zAgentCliToolAuthorizationStatus.optional(),
authorization_status: zAgentCliToolAuthorizationStatus.nullish(),
command: z.string().nullish(),
dangerous: z.boolean().optional().default(false),
dangerous_accepted: z.boolean().optional().default(false),
@ -528,11 +550,11 @@ export const zAgentCliToolConfig = z.object({
invoke_metadata: z.record(z.string(), z.unknown()).optional(),
label: z.string().max(255).nullish(),
name: z.string().max(255).nullish(),
permission: zAgentPermissionConfig.optional(),
permission: zAgentPermissionConfig.nullish(),
pre_authorized: z.boolean().nullish(),
requires_confirmation: z.boolean().optional().default(false),
risk_accepted: z.boolean().optional().default(false),
risk_level: zAgentCliToolRiskLevel.optional(),
risk_level: zAgentCliToolRiskLevel.nullish(),
setup_command: z.string().nullish(),
tool_name: z.string().max(255).nullish(),
})
@ -563,7 +585,7 @@ export const zAgentSoulDifyToolCredentialRef = z.object({
* new callers should send ``plugin_id`` + ``provider`` when available.
*/
export const zAgentSoulDifyToolConfig = z.object({
credential_ref: zAgentSoulDifyToolCredentialRef.optional(),
credential_ref: zAgentSoulDifyToolCredentialRef.nullish(),
credential_type: z.enum(['api-key', 'oauth2', 'unauthorized']).optional().default('api-key'),
description: z.string().nullish(),
enabled: z.boolean().optional().default(true),
@ -572,7 +594,23 @@ export const zAgentSoulDifyToolConfig = z.object({
provider: z.string().max(255).nullish(),
provider_id: z.string().max(255).nullish(),
provider_type: z.string().optional().default('plugin'),
runtime_parameters: z.record(z.string(), z.unknown()).optional(),
runtime_parameters: z
.record(
z.string(),
z
.union([
z.string(),
z.int(),
z.number(),
z.boolean(),
z.array(z.string()),
z.array(z.int()),
z.array(z.number()),
z.array(z.boolean()),
])
.nullable(),
)
.optional(),
tool_name: z.string().min(1).max(255).nullish(),
})
@ -597,16 +635,16 @@ export const zAgentModerationIoConfig = z.object({
*/
export const zAgentModerationProviderConfig = z.object({
api_based_extension_id: z.string().nullish(),
inputs_config: zAgentModerationIoConfig.optional(),
inputs_config: zAgentModerationIoConfig.nullish(),
keywords: z.string().nullish(),
outputs_config: zAgentModerationIoConfig.optional(),
outputs_config: zAgentModerationIoConfig.nullish(),
})
/**
* AgentSensitiveWordAvoidanceFeatureConfig
*/
export const zAgentSensitiveWordAvoidanceFeatureConfig = z.object({
config: zAgentModerationProviderConfig.optional(),
config: zAgentModerationProviderConfig.nullish(),
enabled: z.boolean().optional().default(false),
type: z.string().nullish(),
})
@ -616,12 +654,12 @@ export const zAgentSensitiveWordAvoidanceFeatureConfig = z.object({
*/
export const zAgentSoulAppFeaturesConfig = z.object({
opening_statement: z.string().nullish(),
retriever_resource: zAgentFeatureToggleConfig.optional(),
sensitive_word_avoidance: zAgentSensitiveWordAvoidanceFeatureConfig.optional(),
speech_to_text: zAgentFeatureToggleConfig.optional(),
retriever_resource: zAgentFeatureToggleConfig.nullish(),
sensitive_word_avoidance: zAgentSensitiveWordAvoidanceFeatureConfig.nullish(),
speech_to_text: zAgentFeatureToggleConfig.nullish(),
suggested_questions: z.array(z.string()).nullish(),
suggested_questions_after_answer: zAgentSuggestedQuestionsAfterAnswerFeatureConfig.optional(),
text_to_speech: zAgentTextToSpeechFeatureConfig.optional(),
suggested_questions_after_answer: zAgentSuggestedQuestionsAfterAnswerFeatureConfig.nullish(),
text_to_speech: zAgentTextToSpeechFeatureConfig.nullish(),
})
/**
@ -635,7 +673,7 @@ export const zAgentSoulConfig = z.object({
knowledge: zAgentSoulKnowledgeConfig.optional(),
memory: zAgentSoulMemoryConfig.optional(),
misc_legacy: zAgentSoulAppFeaturesConfig.optional(),
model: zAgentSoulModelConfig.optional(),
model: zAgentSoulModelConfig.nullish(),
prompt: zAgentSoulPromptConfig.optional(),
sandbox: zAgentSoulSandboxConfig.optional(),
schema_version: z.int().optional().default(1),
@ -651,7 +689,7 @@ export const zRosterAgentCreatePayload = z.object({
description: z.string().optional().default(''),
icon: z.string().max(255).nullish(),
icon_background: z.string().max(255).nullish(),
icon_type: zAgentIconType.optional(),
icon_type: zAgentIconType.nullish(),
name: z.string().min(1).max(255),
role: z.string().max(255).optional().default(''),
version_note: z.string().nullish(),
@ -709,7 +747,7 @@ export const zDeleteAgentsByAgentIdPath = z.object({
/**
* Agent archived
*/
export const zDeleteAgentsByAgentIdResponse = z.record(z.string(), z.never())
export const zDeleteAgentsByAgentIdResponse = z.void()
export const zGetAgentsByAgentIdPath = z.object({
agent_id: z.string(),

View File

@ -58,9 +58,7 @@ export type DeleteApiBasedExtensionByIdData = {
}
export type DeleteApiBasedExtensionByIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteApiBasedExtensionByIdResponse

View File

@ -43,7 +43,7 @@ export const zDeleteApiBasedExtensionByIdPath = z.object({
/**
* Extension deleted successfully
*/
export const zDeleteApiBasedExtensionByIdResponse = z.record(z.string(), z.never())
export const zDeleteApiBasedExtensionByIdResponse = z.void()
export const zGetApiBasedExtensionByIdPath = z.object({
id: z.string(),

View File

@ -65,9 +65,7 @@ export type DeleteApiKeyAuthDataSourceByBindingIdData = {
}
export type DeleteApiKeyAuthDataSourceByBindingIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteApiKeyAuthDataSourceByBindingIdResponse

View File

@ -49,4 +49,4 @@ export const zDeleteApiKeyAuthDataSourceByBindingIdPath = z.object({
/**
* Binding deleted successfully
*/
export const zDeleteApiKeyAuthDataSourceByBindingIdResponse = z.record(z.string(), z.never())
export const zDeleteApiKeyAuthDataSourceByBindingIdResponse = z.void()

View File

@ -1450,16 +1450,10 @@ export const annotations = {
/**
* Enable or disable app API
*
* Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.
*
* @deprecated
*/
export const post19 = oc
.route({
deprecated: true,
description:
'Enable or disable app API\n\nGenerated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.',
description: 'Enable or disable app API',
inputStructure: 'detailed',
method: 'POST',
operationId: 'postAppsByAppIdApiEnable',
@ -1510,16 +1504,10 @@ export const delete3 = oc
/**
* Get chat conversation details
*
* Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.
*
* @deprecated
*/
export const get17 = oc
.route({
deprecated: true,
description:
'Get chat conversation details\n\nGenerated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.',
description: 'Get chat conversation details',
inputStructure: 'detailed',
method: 'GET',
operationId: 'getAppsByAppIdChatConversationsByConversationId',
@ -1607,16 +1595,10 @@ export const byTaskId = {
/**
* Get chat messages for a conversation with pagination
*
* Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.
*
* @deprecated
*/
export const get20 = oc
.route({
deprecated: true,
description:
'Get chat messages for a conversation with pagination\n\nGenerated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.',
description: 'Get chat messages for a conversation with pagination',
inputStructure: 'detailed',
method: 'GET',
operationId: 'getAppsByAppIdChatMessages',
@ -1652,16 +1634,10 @@ export const delete4 = oc
/**
* Get completion conversation details with messages
*
* Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.
*
* @deprecated
*/
export const get21 = oc
.route({
deprecated: true,
description:
'Get completion conversation details with messages\n\nGenerated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.',
description: 'Get completion conversation details with messages',
inputStructure: 'detailed',
method: 'GET',
operationId: 'getAppsByAppIdCompletionConversationsByConversationId',
@ -1813,16 +1789,10 @@ export const convertToWorkflow = {
* Copy app
*
* Create a copy of an existing application
*
* Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.
*
* @deprecated
*/
export const post25 = oc
.route({
deprecated: true,
description:
'Create a copy of an existing application\n\nGenerated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.',
description: 'Create a copy of an existing application',
inputStructure: 'detailed',
method: 'POST',
operationId: 'postAppsByAppIdCopy',
@ -1939,16 +1909,10 @@ export const icon = {
/**
* Get message details by ID
*
* Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.
*
* @deprecated
*/
export const get26 = oc
.route({
deprecated: true,
description:
'Get message details by ID\n\nGenerated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.',
description: 'Get message details by ID',
inputStructure: 'detailed',
method: 'GET',
operationId: 'getAppsByAppIdMessagesByMessageId',
@ -1998,16 +1962,10 @@ export const modelConfig = {
/**
* Check if app name is available
*
* Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.
*
* @deprecated
*/
export const post29 = oc
.route({
deprecated: true,
description:
'Check if app name is available\n\nGenerated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.',
description: 'Check if app name is available',
inputStructure: 'detailed',
method: 'POST',
operationId: 'postAppsByAppIdName',
@ -2151,16 +2109,10 @@ export const site = {
/**
* Enable or disable app site
*
* Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.
*
* @deprecated
*/
export const post34 = oc
.route({
deprecated: true,
description:
'Enable or disable app site\n\nGenerated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.',
description: 'Enable or disable app site',
inputStructure: 'detailed',
method: 'POST',
operationId: 'postAppsByAppIdSiteEnable',
@ -4614,16 +4566,9 @@ export const published = {
/**
* Get webhook trigger for a node
*
* Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.
*
* @deprecated
*/
export const get77 = oc
.route({
deprecated: true,
description:
'Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.',
inputStructure: 'detailed',
method: 'GET',
operationId: 'getAppsByAppIdWorkflowsTriggersWebhook',
@ -4791,16 +4736,10 @@ export const delete12 = oc
* Get app detail
*
* Get application details
*
* Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.
*
* @deprecated
*/
export const get79 = oc
.route({
deprecated: true,
description:
'Get application details\n\nGenerated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.',
description: 'Get application details',
inputStructure: 'detailed',
method: 'GET',
operationId: 'getAppsByAppId',
@ -4815,16 +4754,10 @@ export const get79 = oc
* Update app
*
* Update application details
*
* Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.
*
* @deprecated
*/
export const put7 = oc
.route({
deprecated: true,
description:
'Update application details\n\nGenerated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.',
description: 'Update application details',
inputStructure: 'detailed',
method: 'PUT',
operationId: 'putAppsByAppId',
@ -5006,16 +4939,10 @@ export const get82 = oc
* Create app
*
* Create a new application
*
* Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.
*
* @deprecated
*/
export const post64 = oc
.route({
deprecated: true,
description:
'Create a new application\n\nGenerated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.',
description: 'Create a new application',
inputStructure: 'detailed',
method: 'POST',
operationId: 'postApps',

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@ export type DataSourceIntegrateResponse = {
is_bound: boolean
link: string
provider: string
source_info: DataSourceIntegrateWorkspaceResponse
source_info: DataSourceIntegrateWorkspaceResponse | null
}
export type DataSourceIntegrateWorkspaceResponse = {
@ -31,7 +31,7 @@ export type DataSourceIntegrateWorkspaceResponse = {
}
export type DataSourceIntegratePageResponse = {
page_icon: DataSourceIntegrateIconResponse
page_icon: DataSourceIntegrateIconResponse | null
page_id: string
page_name: string
parent_id: string

View File

@ -22,7 +22,7 @@ export const zDataSourceIntegrateIconResponse = z.object({
* DataSourceIntegratePageResponse
*/
export const zDataSourceIntegratePageResponse = z.object({
page_icon: zDataSourceIntegrateIconResponse,
page_icon: zDataSourceIntegrateIconResponse.nullable(),
page_id: z.string(),
page_name: z.string(),
parent_id: z.string(),
@ -50,7 +50,7 @@ export const zDataSourceIntegrateResponse = z.object({
is_bound: z.boolean(),
link: z.string(),
provider: z.string(),
source_info: zDataSourceIntegrateWorkspaceResponse,
source_info: zDataSourceIntegrateWorkspaceResponse.nullable(),
})
/**

View File

@ -18,7 +18,7 @@ export type DatasetCreatePayload = {
external_knowledge_id?: string | null
indexing_technique?: string | null
name: string
permission?: PermissionEnum
permission?: PermissionEnum | null
provider?: string
}
@ -39,7 +39,7 @@ export type DatasetDetailResponse = {
embedding_model_provider: string | null
enable_api: boolean
external_knowledge_info?: DatasetExternalKnowledgeInfoResponse
external_retrieval_model: DatasetExternalRetrievalModelResponse
external_retrieval_model: DatasetExternalRetrievalModelResponse | null
icon_info?: DatasetIconInfoResponse
id: string
indexing_technique: string | null
@ -169,7 +169,7 @@ export type IndexingEstimateResponse = {
}
export type KnowledgeConfig = {
data_source?: DataSource
data_source?: DataSource | null
doc_form?: string
doc_language?: string
duplicate?: boolean
@ -179,8 +179,8 @@ export type KnowledgeConfig = {
is_multimodal?: boolean
name?: string | null
original_document_id?: string | null
process_rule?: ProcessRule
retrieval_model?: RetrievalModel
process_rule?: ProcessRule | null
retrieval_model?: RetrievalModel | null
summary_index_setting?: {
[key: string]: unknown
} | null
@ -234,7 +234,7 @@ export type DatasetDetailWithPartialMembersResponse = {
embedding_model_provider: string | null
enable_api: boolean
external_knowledge_info?: DatasetExternalKnowledgeInfoResponse
external_retrieval_model: DatasetExternalRetrievalModelResponse
external_retrieval_model: DatasetExternalRetrievalModelResponse | null
icon_info?: DatasetIconInfoResponse
id: string
indexing_technique: string | null
@ -274,7 +274,7 @@ export type DatasetUpdatePayload = {
partial_member_list?: Array<{
[key: string]: string
}> | null
permission?: PermissionEnum
permission?: PermissionEnum | null
retrieval_model?: {
[key: string]: unknown
} | null
@ -454,7 +454,7 @@ export type HitTestingPayload = {
[key: string]: unknown
} | null
query: string
retrieval_model?: RetrievalModel
retrieval_model?: RetrievalModel | null
}
export type HitTestingResponse = {
@ -524,7 +524,7 @@ export type DatasetListItemResponse = {
embedding_model_provider: string | null
enable_api: boolean
external_knowledge_info?: DatasetExternalKnowledgeInfoResponse
external_retrieval_model: DatasetExternalRetrievalModelResponse
external_retrieval_model: DatasetExternalRetrievalModelResponse | null
icon_info?: DatasetIconInfoResponse
id: string
indexing_technique: string | null
@ -582,7 +582,7 @@ export type DatasetRetrievalModelResponse = {
score_threshold_enabled: boolean
search_method: string
top_k: number
weights?: DatasetWeightedScoreResponse
weights?: DatasetWeightedScoreResponse | null
}
export type DatasetSummaryIndexSettingResponse = {
@ -665,19 +665,19 @@ export type DataSource = {
export type ProcessRule = {
mode: ProcessRuleMode
rules?: Rule
rules?: Rule | null
}
export type RetrievalModel = {
metadata_filtering_conditions?: MetadataFilteringCondition
metadata_filtering_conditions?: MetadataFilteringCondition | null
reranking_enable: boolean
reranking_mode?: string | null
reranking_model?: RerankingModel
reranking_model?: RerankingModel | null
score_threshold?: number | null
score_threshold_enabled: boolean
search_method: RetrievalMethod
top_k: number
weights?: WeightModel
weights?: WeightModel | null
}
export type DatasetResponse = {
@ -747,7 +747,7 @@ export type DocumentMetadataResponse = {
id: string
name: string
type: string
value?: unknown
value?: string | number | number | boolean | null
}
export type SegmentResponse = {
@ -806,7 +806,7 @@ export type HitTestingRecord = {
score: number | null
segment: HitTestingSegment
summary: string | null
tsne_position: unknown
tsne_position: unknown | null
}
export type DatasetMetadataListItemResponse = {
@ -861,9 +861,9 @@ export type DatasetWeightedScore = {
export type InfoList = {
data_source_type: 'notion_import' | 'upload_file' | 'website_crawl'
file_info_list?: FileInfo
file_info_list?: FileInfo | null
notion_info_list?: Array<NotionInfo> | null
website_info_list?: WebsiteInfo
website_info_list?: WebsiteInfo | null
}
export type ProcessRuleMode = 'automatic' | 'custom' | 'hierarchical'
@ -871,8 +871,8 @@ export type ProcessRuleMode = 'automatic' | 'custom' | 'hierarchical'
export type Rule = {
parent_mode?: 'full-doc' | 'paragraph' | null
pre_processing_rules?: Array<PreProcessingRule> | null
segmentation?: Segmentation
subchunk_segmentation?: Segmentation
segmentation?: Segmentation | null
subchunk_segmentation?: Segmentation | null
}
export type MetadataFilteringCondition = {
@ -892,15 +892,15 @@ export type RetrievalMethod
| 'semantic_search'
export type WeightModel = {
keyword_setting?: WeightKeywordSetting
vector_setting?: WeightVectorSetting
keyword_setting?: WeightKeywordSetting | null
vector_setting?: WeightVectorSetting | null
weight_type?: 'customized' | 'keyword_first' | 'semantic_first' | null
}
export type MetadataDetail = {
id: string
name: string
value?: unknown
value?: string | number | number | null
}
export type SegmentAttachmentResponse = {
@ -957,7 +957,7 @@ export type HitTestingSegment = {
export type DatasetQueryContentResponse = {
content: string
content_type: string
file_info?: DatasetQueryFileInfoResponse
file_info?: DatasetQueryFileInfoResponse | null
}
export type DatasetKeywordSettingResponse = {
@ -1029,7 +1029,7 @@ export type Condition = {
| '≤'
| '≥'
name: string
value?: unknown
value?: string | Array<string> | number | number | null
}
export type WeightKeywordSetting = {
@ -1044,7 +1044,7 @@ export type WeightVectorSetting = {
export type HitTestingDocument = {
data_source_type: string
doc_metadata: unknown
doc_metadata: unknown | null
doc_type: string | null
id: string
name: string
@ -1060,7 +1060,7 @@ export type DatasetQueryFileInfoResponse = {
}
export type NotionPage = {
page_icon?: NotionIcon
page_icon?: NotionIcon | null
page_id: string
page_name: string
type: string
@ -1173,9 +1173,7 @@ export type DeleteDatasetsApiKeysByApiKeyIdData = {
}
export type DeleteDatasetsApiKeysByApiKeyIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsApiKeysByApiKeyIdResponse
@ -1284,9 +1282,7 @@ export type DeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdData = {
}
export type DeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse
@ -1474,9 +1470,7 @@ export type DeleteDatasetsByDatasetIdData = {
}
export type DeleteDatasetsByDatasetIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByDatasetIdResponse
@ -1626,9 +1620,7 @@ export type DeleteDatasetsByDatasetIdDocumentsData = {
}
export type DeleteDatasetsByDatasetIdDocumentsResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByDatasetIdDocumentsResponse
@ -1732,9 +1724,7 @@ export type PostDatasetsByDatasetIdDocumentsMetadataData = {
}
export type PostDatasetsByDatasetIdDocumentsMetadataResponses = {
204: {
[key: string]: never
}
204: void
}
export type PostDatasetsByDatasetIdDocumentsMetadataResponse
@ -1768,9 +1758,7 @@ export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdData = {
}
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse
@ -1956,9 +1944,7 @@ export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseData = {
}
export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseResponses = {
204: {
[key: string]: never
}
204: void
}
export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseResponse
@ -1975,9 +1961,7 @@ export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeData =
}
export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeResponses = {
204: {
[key: string]: never
}
204: void
}
export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeResponse
@ -2080,9 +2064,7 @@ export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsData = {
}
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse
@ -2158,9 +2140,7 @@ export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdDat
}
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse
@ -2257,9 +2237,7 @@ export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChi
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses
= {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse
@ -2473,9 +2451,7 @@ export type PostDatasetsByDatasetIdMetadataBuiltInByActionData = {
}
export type PostDatasetsByDatasetIdMetadataBuiltInByActionResponses = {
204: {
[key: string]: never
}
204: void
}
export type PostDatasetsByDatasetIdMetadataBuiltInByActionResponse
@ -2492,9 +2468,7 @@ export type DeleteDatasetsByDatasetIdMetadataByMetadataIdData = {
}
export type DeleteDatasetsByDatasetIdMetadataByMetadataIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByDatasetIdMetadataByMetadataIdResponse
@ -2603,9 +2577,7 @@ export type PostDatasetsByDatasetIdRetryData = {
}
export type PostDatasetsByDatasetIdRetryResponses = {
204: {
[key: string]: never
}
204: void
}
export type PostDatasetsByDatasetIdRetryResponse
@ -2679,9 +2651,7 @@ export type DeleteDatasetsByResourceIdApiKeysByApiKeyIdData = {
}
export type DeleteDatasetsByResourceIdApiKeysByApiKeyIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByResourceIdApiKeysByApiKeyIdResponse

View File

@ -298,7 +298,7 @@ export const zDatasetCreatePayload = z.object({
external_knowledge_id: z.string().nullish(),
indexing_technique: z.string().nullish(),
name: z.string().min(1).max(40),
permission: zPermissionEnum.optional(),
permission: zPermissionEnum.nullish().default('only_me'),
provider: z.string().optional().default('vendor'),
})
@ -317,7 +317,7 @@ export const zDatasetUpdatePayload = z.object({
is_multimodal: z.boolean().nullish().default(false),
name: z.string().min(1).max(40).nullish(),
partial_member_list: z.array(z.record(z.string(), z.string())).nullish(),
permission: zPermissionEnum.optional(),
permission: zPermissionEnum.nullish(),
retrieval_model: z.record(z.string(), z.unknown()).nullish(),
summary_index_setting: z.record(z.string(), z.unknown()).nullish(),
})
@ -509,7 +509,7 @@ export const zDocumentMetadataResponse = z.object({
id: z.string(),
name: z.string(),
type: z.string(),
value: z.unknown().optional(),
value: z.union([z.string(), z.int(), z.number(), z.boolean()]).nullish(),
})
/**
@ -740,7 +740,7 @@ export const zRetrievalMethod = z.enum([
export const zMetadataDetail = z.object({
id: z.string(),
name: z.string(),
value: z.unknown().optional(),
value: z.union([z.string(), z.int(), z.number()]).nullish(),
})
/**
@ -883,7 +883,7 @@ export const zDatasetRetrievalModelResponse = z.object({
score_threshold_enabled: z.boolean(),
search_method: z.string(),
top_k: z.int(),
weights: zDatasetWeightedScoreResponse.optional(),
weights: zDatasetWeightedScoreResponse.nullish(),
})
/**
@ -906,7 +906,7 @@ export const zDatasetDetailResponse = z.object({
embedding_model_provider: z.string().nullable(),
enable_api: z.boolean(),
external_knowledge_info: zDatasetExternalKnowledgeInfoResponse.optional(),
external_retrieval_model: zDatasetExternalRetrievalModelResponse,
external_retrieval_model: zDatasetExternalRetrievalModelResponse.nullable(),
icon_info: zDatasetIconInfoResponse.optional(),
id: z.string(),
indexing_technique: z.string().nullable(),
@ -947,7 +947,7 @@ export const zDatasetDetailWithPartialMembersResponse = z.object({
embedding_model_provider: z.string().nullable(),
enable_api: z.boolean(),
external_knowledge_info: zDatasetExternalKnowledgeInfoResponse.optional(),
external_retrieval_model: zDatasetExternalRetrievalModelResponse,
external_retrieval_model: zDatasetExternalRetrievalModelResponse.nullable(),
icon_info: zDatasetIconInfoResponse.optional(),
id: z.string(),
indexing_technique: z.string().nullable(),
@ -989,7 +989,7 @@ export const zDatasetListItemResponse = z.object({
embedding_model_provider: z.string().nullable(),
enable_api: z.boolean(),
external_knowledge_info: zDatasetExternalKnowledgeInfoResponse.optional(),
external_retrieval_model: zDatasetExternalRetrievalModelResponse,
external_retrieval_model: zDatasetExternalRetrievalModelResponse.nullable(),
icon_info: zDatasetIconInfoResponse.optional(),
id: z.string(),
indexing_technique: z.string().nullable(),
@ -1127,8 +1127,8 @@ export const zSegmentation = z.object({
export const zRule = z.object({
parent_mode: z.enum(['full-doc', 'paragraph']).nullish(),
pre_processing_rules: z.array(zPreProcessingRule).nullish(),
segmentation: zSegmentation.optional(),
subchunk_segmentation: zSegmentation.optional(),
segmentation: zSegmentation.nullish(),
subchunk_segmentation: zSegmentation.nullish(),
})
/**
@ -1136,7 +1136,7 @@ export const zRule = z.object({
*/
export const zProcessRule = z.object({
mode: zProcessRuleMode,
rules: zRule.optional(),
rules: zRule.nullish(),
})
/**
@ -1166,7 +1166,7 @@ export const zCondition = z.object({
'≥',
]),
name: z.string(),
value: z.unknown().optional(),
value: z.union([z.string(), z.array(z.string()), z.int(), z.number()]).nullish(),
})
/**
@ -1199,8 +1199,8 @@ export const zWeightVectorSetting = z.object({
* WeightModel
*/
export const zWeightModel = z.object({
keyword_setting: zWeightKeywordSetting.optional(),
vector_setting: zWeightVectorSetting.optional(),
keyword_setting: zWeightKeywordSetting.nullish(),
vector_setting: zWeightVectorSetting.nullish(),
weight_type: z.enum(['customized', 'keyword_first', 'semantic_first']).nullish(),
})
@ -1208,15 +1208,15 @@ export const zWeightModel = z.object({
* RetrievalModel
*/
export const zRetrievalModel = z.object({
metadata_filtering_conditions: zMetadataFilteringCondition.optional(),
metadata_filtering_conditions: zMetadataFilteringCondition.nullish(),
reranking_enable: z.boolean(),
reranking_mode: z.string().nullish(),
reranking_model: zRerankingModel.optional(),
reranking_model: zRerankingModel.nullish(),
score_threshold: z.number().nullish(),
score_threshold_enabled: z.boolean(),
search_method: zRetrievalMethod,
top_k: z.int(),
weights: zWeightModel.optional(),
weights: zWeightModel.nullish(),
})
/**
@ -1226,7 +1226,7 @@ export const zHitTestingPayload = z.object({
attachment_ids: z.array(z.string()).nullish(),
external_retrieval_model: z.record(z.string(), z.unknown()).nullish(),
query: z.string().max(250),
retrieval_model: zRetrievalModel.optional(),
retrieval_model: zRetrievalModel.nullish(),
})
/**
@ -1234,7 +1234,7 @@ export const zHitTestingPayload = z.object({
*/
export const zHitTestingDocument = z.object({
data_source_type: z.string(),
doc_metadata: z.unknown(),
doc_metadata: z.unknown().nullable(),
doc_type: z.string().nullable(),
id: z.string(),
name: z.string(),
@ -1278,7 +1278,7 @@ export const zHitTestingRecord = z.object({
score: z.number().nullable(),
segment: zHitTestingSegment,
summary: z.string().nullable(),
tsne_position: z.unknown(),
tsne_position: z.unknown().nullable(),
})
/**
@ -1307,7 +1307,7 @@ export const zDatasetQueryFileInfoResponse = z.object({
export const zDatasetQueryContentResponse = z.object({
content: z.string(),
content_type: z.string(),
file_info: zDatasetQueryFileInfoResponse.optional(),
file_info: zDatasetQueryFileInfoResponse.nullish(),
})
/**
@ -1347,7 +1347,7 @@ export const zNotionIcon = z.object({
* NotionPage
*/
export const zNotionPage = z.object({
page_icon: zNotionIcon.optional(),
page_icon: zNotionIcon.nullish(),
page_id: z.string(),
page_name: z.string(),
type: z.string(),
@ -1367,9 +1367,9 @@ export const zNotionInfo = z.object({
*/
export const zInfoList = z.object({
data_source_type: z.enum(['notion_import', 'upload_file', 'website_crawl']),
file_info_list: zFileInfo.optional(),
file_info_list: zFileInfo.nullish(),
notion_info_list: z.array(zNotionInfo).nullish(),
website_info_list: zWebsiteInfo.optional(),
website_info_list: zWebsiteInfo.nullish(),
})
/**
@ -1383,7 +1383,7 @@ export const zDataSource = z.object({
* KnowledgeConfig
*/
export const zKnowledgeConfig = z.object({
data_source: zDataSource.optional(),
data_source: zDataSource.nullish(),
doc_form: z.string().optional().default('text_model'),
doc_language: z.string().optional().default('English'),
duplicate: z.boolean().optional().default(true),
@ -1393,8 +1393,8 @@ export const zKnowledgeConfig = z.object({
is_multimodal: z.boolean().optional().default(false),
name: z.string().nullish(),
original_document_id: z.string().nullish(),
process_rule: zProcessRule.optional(),
retrieval_model: zRetrievalModel.optional(),
process_rule: zProcessRule.nullish(),
retrieval_model: zRetrievalModel.nullish(),
summary_index_setting: z.record(z.string(), z.unknown()).nullish(),
})
@ -1441,7 +1441,7 @@ export const zDeleteDatasetsApiKeysByApiKeyIdPath = z.object({
/**
* API key deleted successfully
*/
export const zDeleteDatasetsApiKeysByApiKeyIdResponse = z.record(z.string(), z.never())
export const zDeleteDatasetsApiKeysByApiKeyIdResponse = z.void()
export const zGetDatasetsBatchImportStatusByJobIdPath = z.object({
job_id: z.string(),
@ -1495,10 +1495,7 @@ export const zDeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdPath = z
/**
* External knowledge API deleted successfully
*/
export const zDeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse = z.void()
export const zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdPath = z.object({
external_knowledge_api_id: z.string(),
@ -1593,7 +1590,7 @@ export const zDeleteDatasetsByDatasetIdPath = z.object({
/**
* Dataset deleted successfully
*/
export const zDeleteDatasetsByDatasetIdResponse = z.record(z.string(), z.never())
export const zDeleteDatasetsByDatasetIdResponse = z.void()
export const zGetDatasetsByDatasetIdPath = z.object({
dataset_id: z.string(),
@ -1664,7 +1661,7 @@ export const zDeleteDatasetsByDatasetIdDocumentsPath = z.object({
/**
* Documents deleted successfully
*/
export const zDeleteDatasetsByDatasetIdDocumentsResponse = z.record(z.string(), z.never())
export const zDeleteDatasetsByDatasetIdDocumentsResponse = z.void()
export const zGetDatasetsByDatasetIdDocumentsPath = z.object({
dataset_id: z.string(),
@ -1729,7 +1726,7 @@ export const zPostDatasetsByDatasetIdDocumentsMetadataPath = z.object({
/**
* Documents metadata updated successfully
*/
export const zPostDatasetsByDatasetIdDocumentsMetadataResponse = z.record(z.string(), z.never())
export const zPostDatasetsByDatasetIdDocumentsMetadataResponse = z.void()
export const zPatchDatasetsByDatasetIdDocumentsStatusByActionBatchPath = z.object({
action: z.string(),
@ -1749,10 +1746,7 @@ export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdPath = z.object({
/**
* Document deleted successfully
*/
export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse = z.void()
export const zGetDatasetsByDatasetIdDocumentsByDocumentIdPath = z.object({
dataset_id: z.string(),
@ -1850,10 +1844,7 @@ export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPausePath =
/**
* Document paused successfully
*/
export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseResponse = z.record(
z.string(),
z.never(),
)
export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseResponse = z.void()
export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumePath = z.object({
dataset_id: z.string(),
@ -1863,10 +1854,7 @@ export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumePath
/**
* Document resumed successfully
*/
export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeResponse = z.record(
z.string(),
z.never(),
)
export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeResponse = z.void()
export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionPath = z.object({
action: z.string(),
@ -1932,10 +1920,7 @@ export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsQuery = z.ob
/**
* Segments deleted successfully
*/
export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse = z.void()
export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath = z.object({
dataset_id: z.string(),
@ -1991,10 +1976,7 @@ export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdP
/**
* Segment deleted successfully
*/
export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse = z.void()
export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdBody
= zSegmentUpdatePayload
@ -2075,7 +2057,7 @@ export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdC
* Child chunk deleted successfully
*/
export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse
= z.record(z.string(), z.never())
= z.void()
export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdBody
= zChildChunkUpdatePayload
@ -2185,10 +2167,7 @@ export const zPostDatasetsByDatasetIdMetadataBuiltInByActionPath = z.object({
/**
* Action completed successfully
*/
export const zPostDatasetsByDatasetIdMetadataBuiltInByActionResponse = z.record(
z.string(),
z.never(),
)
export const zPostDatasetsByDatasetIdMetadataBuiltInByActionResponse = z.void()
export const zDeleteDatasetsByDatasetIdMetadataByMetadataIdPath = z.object({
dataset_id: z.string(),
@ -2198,10 +2177,7 @@ export const zDeleteDatasetsByDatasetIdMetadataByMetadataIdPath = z.object({
/**
* Metadata deleted successfully
*/
export const zDeleteDatasetsByDatasetIdMetadataByMetadataIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteDatasetsByDatasetIdMetadataByMetadataIdResponse = z.void()
export const zPatchDatasetsByDatasetIdMetadataByMetadataIdBody = zMetadataUpdatePayload
@ -2260,7 +2236,7 @@ export const zPostDatasetsByDatasetIdRetryPath = z.object({
/**
* Documents retry started successfully
*/
export const zPostDatasetsByDatasetIdRetryResponse = z.record(z.string(), z.never())
export const zPostDatasetsByDatasetIdRetryResponse = z.void()
export const zGetDatasetsByDatasetIdUseCheckPath = z.object({
dataset_id: z.string(),
@ -2297,4 +2273,4 @@ export const zDeleteDatasetsByResourceIdApiKeysByApiKeyIdPath = z.object({
/**
* API key deleted successfully
*/
export const zDeleteDatasetsByResourceIdApiKeysByApiKeyIdResponse = z.record(z.string(), z.never())
export const zDeleteDatasetsByResourceIdApiKeysByApiKeyIdResponse = z.void()

View File

@ -10,7 +10,7 @@ export type RecommendedAppListResponse = {
}
export type RecommendedAppResponse = {
app?: RecommendedAppInfoResponse
app?: RecommendedAppInfoResponse | null
app_id: string
can_trial?: boolean | null
categories?: Array<string>

View File

@ -18,7 +18,7 @@ export const zRecommendedAppInfoResponse = z.object({
* RecommendedAppResponse
*/
export const zRecommendedAppResponse = z.object({
app: zRecommendedAppInfoResponse.optional(),
app: zRecommendedAppInfoResponse.nullish(),
app_id: z.string(),
can_trial: z.boolean().nullish(),
categories: z.array(z.string()).optional(),

View File

@ -22,7 +22,7 @@ export type FeatureModel = {
model_load_balancing_enabled: boolean
next_credit_reset_date: number
trigger_event: Quota
vector_space: LimitationModel
vector_space: LimitationModel | null
webapp_copyright_enabled: boolean
workspace_members: LicenseLimitationModel
}

View File

@ -60,33 +60,48 @@ export const zSubscriptionModel = z.object({
*/
export const zBillingModel = z.object({
enabled: z.boolean().default(false),
subscription: zSubscriptionModel,
subscription: zSubscriptionModel.default({ interval: '', plan: 'sandbox' }),
})
/**
* FeatureModel
*/
export const zFeatureModel = z.object({
annotation_quota_limit: zLimitationModel,
api_rate_limit: zQuota,
apps: zLimitationModel,
billing: zBillingModel,
annotation_quota_limit: zLimitationModel.default({ limit: 10, size: 0 }),
api_rate_limit: zQuota.default({
limit: 5000,
reset_date: 0,
usage: 0,
}),
apps: zLimitationModel.default({ limit: 10, size: 0 }),
billing: zBillingModel.default({
enabled: false,
subscription: { interval: '', plan: 'sandbox' },
}),
can_replace_logo: z.boolean().default(false),
dataset_operator_enabled: z.boolean().default(false),
docs_processing: z.string().default('standard'),
documents_upload_quota: zLimitationModel,
education: zEducationModel,
documents_upload_quota: zLimitationModel.default({ limit: 50, size: 0 }),
education: zEducationModel.default({ activated: false, enabled: false }),
human_input_email_delivery_enabled: z.boolean().default(false),
is_allow_transfer_workspace: z.boolean().default(true),
knowledge_pipeline: zKnowledgePipeline,
knowledge_pipeline: zKnowledgePipeline.default({ publish_enabled: false }),
knowledge_rate_limit: z.int().default(10),
members: zLimitationModel,
members: zLimitationModel.default({ limit: 1, size: 0 }),
model_load_balancing_enabled: z.boolean().default(false),
next_credit_reset_date: z.int().default(0),
trigger_event: zQuota,
vector_space: zLimitationModel,
trigger_event: zQuota.default({
limit: 3000,
reset_date: 0,
usage: 0,
}),
vector_space: zLimitationModel.nullable().default({ limit: 5, size: 0 }),
webapp_copyright_enabled: z.boolean().default(false),
workspace_members: zLicenseLimitationModel,
workspace_members: zLicenseLimitationModel.default({
enabled: false,
limit: 0,
size: 0,
}),
})
/**

View File

@ -6,7 +6,7 @@ export type ClientOptions = {
export type TenantInfoResponse = {
created_at?: number | null
custom_config?: WorkspaceCustomConfigResponse
custom_config?: WorkspaceCustomConfigResponse | null
id: string
in_trial?: boolean | null
name?: string | null

View File

@ -15,7 +15,7 @@ export const zWorkspaceCustomConfigResponse = z.object({
*/
export const zTenantInfoResponse = z.object({
created_at: z.int().nullish(),
custom_config: zWorkspaceCustomConfigResponse.optional(),
custom_config: zWorkspaceCustomConfigResponse.nullish(),
id: z.string(),
in_trial: z.boolean().nullish(),
name: z.string().nullish(),

View File

@ -143,9 +143,7 @@ export type DeleteInstalledAppsByInstalledAppIdData = {
}
export type DeleteInstalledAppsByInstalledAppIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteInstalledAppsByInstalledAppIdResponse
@ -288,9 +286,7 @@ export type DeleteInstalledAppsByInstalledAppIdConversationsByCIdData = {
}
export type DeleteInstalledAppsByInstalledAppIdConversationsByCIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteInstalledAppsByInstalledAppIdConversationsByCIdResponse
@ -510,9 +506,7 @@ export type DeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdData = {
}
export type DeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdResponse

View File

@ -155,7 +155,7 @@ export const zDeleteInstalledAppsByInstalledAppIdPath = z.object({
/**
* App uninstalled successfully
*/
export const zDeleteInstalledAppsByInstalledAppIdResponse = z.record(z.string(), z.never())
export const zDeleteInstalledAppsByInstalledAppIdResponse = z.void()
export const zPatchInstalledAppsByInstalledAppIdPath = z.object({
installed_app_id: z.string(),
@ -255,10 +255,7 @@ export const zDeleteInstalledAppsByInstalledAppIdConversationsByCIdPath = z.obje
/**
* Conversation deleted successfully
*/
export const zDeleteInstalledAppsByInstalledAppIdConversationsByCIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteInstalledAppsByInstalledAppIdConversationsByCIdResponse = z.void()
export const zPostInstalledAppsByInstalledAppIdConversationsByCIdNameBody
= zConversationRenamePayload
@ -407,10 +404,7 @@ export const zDeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdPath =
/**
* Saved message deleted successfully
*/
export const zDeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdResponse = z.void()
export const zPostInstalledAppsByInstalledAppIdTextToAudioBody = zTextToAudioPayload

View File

@ -21,7 +21,7 @@ export type NotionIntegrateWorkspaceResponse = {
export type NotionIntegratePageResponse = {
is_bound: boolean
page_icon: DataSourceIntegrateIconResponse
page_icon: DataSourceIntegrateIconResponse | null
page_id: string
page_name: string
parent_id: string | null

View File

@ -23,7 +23,7 @@ export const zDataSourceIntegrateIconResponse = z.object({
*/
export const zNotionIntegratePageResponse = z.object({
is_bound: z.boolean(),
page_icon: zDataSourceIntegrateIconResponse,
page_icon: zDataSourceIntegrateIconResponse.nullable(),
page_id: z.string(),
page_name: z.string(),
parent_id: z.string().nullable(),

View File

@ -47,7 +47,7 @@ export type DatasetDetailResponse = {
embedding_model_provider: string | null
enable_api: boolean
external_knowledge_info?: DatasetExternalKnowledgeInfoResponse
external_retrieval_model: DatasetExternalRetrievalModelResponse
external_retrieval_model: DatasetExternalRetrievalModelResponse | null
icon_info?: DatasetIconInfoResponse
id: string
indexing_technique: string | null
@ -115,8 +115,8 @@ export type SimpleResultResponse = {
export type WorkflowRunDetailResponse = {
created_at?: number | null
created_by_account?: SimpleAccount
created_by_end_user?: SimpleEndUser
created_by_account?: SimpleAccount | null
created_by_end_user?: SimpleEndUser | null
created_by_role?: string | null
elapsed_time?: number | null
error?: string | null
@ -146,7 +146,7 @@ export type WorkflowPaginationResponse = {
export type WorkflowResponse = {
conversation_variables: Array<WorkflowConversationVariableResponse>
created_at: number
created_by?: SimpleAccount
created_by?: SimpleAccount | null
environment_variables: Array<WorkflowEnvironmentVariableResponse>
features: {
[key: string]: unknown
@ -161,7 +161,7 @@ export type WorkflowResponse = {
rag_pipeline_variables: Array<PipelineVariableResponse>
tool_published: boolean
updated_at: number
updated_by?: SimpleAccount
updated_by?: SimpleAccount | null
version: string
}
@ -190,8 +190,8 @@ export type DatasourceVariablesPayload = {
export type WorkflowRunNodeExecutionResponse = {
created_at?: number | null
created_by_account?: SimpleAccount
created_by_end_user?: SimpleEndUser
created_by_account?: SimpleAccount | null
created_by_end_user?: SimpleEndUser | null
created_by_role?: string | null
elapsed_time?: number | null
error?: string | null
@ -238,7 +238,7 @@ export type DraftWorkflowRunPayload = {
export type WorkflowDraftVariablePatchPayload = {
name?: string | null
value?: unknown
value?: unknown | null
}
export type RagPipelineWorkflowPublishResponse = {
@ -304,7 +304,7 @@ export type DatasetRetrievalModelResponse = {
score_threshold_enabled: boolean
search_method: string
top_k: number
weights?: DatasetWeightedScoreResponse
weights?: DatasetWeightedScoreResponse | null
}
export type DatasetSummaryIndexSettingResponse = {
@ -336,12 +336,12 @@ export type PipelineTemplateItemResponse = {
export type PluginDependency = {
current_identifier?: string | null
type: Type
value: unknown
value: Github | Marketplace | Package
}
export type WorkflowRunForListResponse = {
created_at?: number | null
created_by_account?: SimpleAccount
created_by_account?: SimpleAccount | null
elapsed_time?: number | null
exceptions_count?: number | null
finished_at?: number | null
@ -455,9 +455,7 @@ export type DeleteRagPipelineCustomizedTemplatesByTemplateIdData = {
}
export type DeleteRagPipelineCustomizedTemplatesByTemplateIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteRagPipelineCustomizedTemplatesByTemplateIdResponse
@ -473,9 +471,7 @@ export type PatchRagPipelineCustomizedTemplatesByTemplateIdData = {
}
export type PatchRagPipelineCustomizedTemplatesByTemplateIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type PatchRagPipelineCustomizedTemplatesByTemplateIdResponse
@ -681,9 +677,7 @@ export type PostRagPipelinesByPipelineIdCustomizedPublishData = {
}
export type PostRagPipelinesByPipelineIdCustomizedPublishResponses = {
204: {
[key: string]: never
}
204: void
}
export type PostRagPipelinesByPipelineIdCustomizedPublishResponse
@ -1360,9 +1354,7 @@ export type DeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdData = {
}
export type DeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponse

View File

@ -118,7 +118,7 @@ export const zDraftWorkflowRunPayload = z.object({
*/
export const zWorkflowDraftVariablePatchPayload = z.object({
name: z.string().nullish(),
value: z.unknown().optional(),
value: z.unknown().nullish(),
})
/**
@ -261,7 +261,7 @@ export const zSimpleAccount = z.object({
*/
export const zWorkflowRunForListResponse = z.object({
created_at: z.int().nullish(),
created_by_account: zSimpleAccount.optional(),
created_by_account: zSimpleAccount.nullish(),
elapsed_time: z.number().nullish(),
exceptions_count: z.int().nullish(),
finished_at: z.int().nullish(),
@ -297,8 +297,8 @@ export const zSimpleEndUser = z.object({
*/
export const zWorkflowRunDetailResponse = z.object({
created_at: z.int().nullish(),
created_by_account: zSimpleAccount.optional(),
created_by_end_user: zSimpleEndUser.optional(),
created_by_account: zSimpleAccount.nullish(),
created_by_end_user: zSimpleEndUser.nullish(),
created_by_role: z.string().nullish(),
elapsed_time: z.number().nullish(),
error: z.string().nullish(),
@ -319,8 +319,8 @@ export const zWorkflowRunDetailResponse = z.object({
*/
export const zWorkflowRunNodeExecutionResponse = z.object({
created_at: z.int().nullish(),
created_by_account: zSimpleAccount.optional(),
created_by_end_user: zSimpleEndUser.optional(),
created_by_account: zSimpleAccount.nullish(),
created_by_end_user: zSimpleEndUser.nullish(),
created_by_role: z.string().nullish(),
elapsed_time: z.number().nullish(),
error: z.string().nullish(),
@ -397,7 +397,7 @@ export const zPipelineVariableResponse = z.object({
export const zWorkflowResponse = z.object({
conversation_variables: z.array(zWorkflowConversationVariableResponse),
created_at: z.int(),
created_by: zSimpleAccount.optional(),
created_by: zSimpleAccount.nullish(),
environment_variables: z.array(zWorkflowEnvironmentVariableResponse),
features: z.record(z.string(), z.unknown()),
graph: z.record(z.string(), z.unknown()),
@ -408,7 +408,7 @@ export const zWorkflowResponse = z.object({
rag_pipeline_variables: z.array(zPipelineVariableResponse),
tool_published: z.boolean(),
updated_at: z.int(),
updated_by: zSimpleAccount.optional(),
updated_by: zSimpleAccount.nullish(),
version: z.string(),
})
@ -435,22 +435,6 @@ export const zDatasetRerankingModelResponse = z.object({
*/
export const zType = z.enum(['github', 'marketplace', 'package'])
/**
* PluginDependency
*/
export const zPluginDependency = z.object({
current_identifier: z.string().nullish(),
type: zType,
value: z.unknown(),
})
/**
* RagPipelineImportCheckDependenciesResponse
*/
export const zRagPipelineImportCheckDependenciesResponse = z.object({
leaked_dependencies: z.array(zPluginDependency).optional(),
})
/**
* Github
*/
@ -477,6 +461,22 @@ export const zPackage = z.object({
version: z.string().nullish(),
})
/**
* PluginDependency
*/
export const zPluginDependency = z.object({
current_identifier: z.string().nullish(),
type: zType,
value: z.union([zGithub, zMarketplace, zPackage]),
})
/**
* RagPipelineImportCheckDependenciesResponse
*/
export const zRagPipelineImportCheckDependenciesResponse = z.object({
leaked_dependencies: z.array(zPluginDependency).optional(),
})
/**
* DatasetKeywordSettingResponse
*/
@ -513,7 +513,7 @@ export const zDatasetRetrievalModelResponse = z.object({
score_threshold_enabled: z.boolean(),
search_method: z.string(),
top_k: z.int(),
weights: zDatasetWeightedScoreResponse.optional(),
weights: zDatasetWeightedScoreResponse.nullish(),
})
/**
@ -536,7 +536,7 @@ export const zDatasetDetailResponse = z.object({
embedding_model_provider: z.string().nullable(),
enable_api: z.boolean(),
external_knowledge_info: zDatasetExternalKnowledgeInfoResponse.optional(),
external_retrieval_model: zDatasetExternalRetrievalModelResponse,
external_retrieval_model: zDatasetExternalRetrievalModelResponse.nullable(),
icon_info: zDatasetIconInfoResponse.optional(),
id: z.string(),
indexing_technique: z.string().nullable(),
@ -564,10 +564,7 @@ export const zDeleteRagPipelineCustomizedTemplatesByTemplateIdPath = z.object({
/**
* Pipeline template deleted
*/
export const zDeleteRagPipelineCustomizedTemplatesByTemplateIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteRagPipelineCustomizedTemplatesByTemplateIdResponse = z.void()
export const zPatchRagPipelineCustomizedTemplatesByTemplateIdBody
= zCustomizedPipelineTemplatePayload
@ -579,10 +576,7 @@ export const zPatchRagPipelineCustomizedTemplatesByTemplateIdPath = z.object({
/**
* Pipeline template updated
*/
export const zPatchRagPipelineCustomizedTemplatesByTemplateIdResponse = z.record(
z.string(),
z.never(),
)
export const zPatchRagPipelineCustomizedTemplatesByTemplateIdResponse = z.void()
export const zPostRagPipelineCustomizedTemplatesByTemplateIdPath = z.object({
template_id: z.string(),
@ -685,10 +679,7 @@ export const zPostRagPipelinesByPipelineIdCustomizedPublishPath = z.object({
/**
* Pipeline template published
*/
export const zPostRagPipelinesByPipelineIdCustomizedPublishResponse = z.record(
z.string(),
z.never(),
)
export const zPostRagPipelinesByPipelineIdCustomizedPublishResponse = z.void()
export const zGetRagPipelinesByPipelineIdExportsPath = z.object({
pipeline_id: z.string(),
@ -1134,10 +1125,7 @@ export const zDeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdPath = z.object
/**
* Workflow deleted successfully
*/
export const zDeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponse = z.void()
export const zPatchRagPipelinesByPipelineIdWorkflowsByWorkflowIdPath = z.object({
pipeline_id: z.string(),

View File

@ -12,8 +12,8 @@ export type WorkflowRunPaginationResponse = {
export type WorkflowRunDetailResponse = {
created_at?: number | null
created_by_account?: SimpleAccount
created_by_end_user?: SimpleEndUser
created_by_account?: SimpleAccount | null
created_by_end_user?: SimpleEndUser | null
created_by_role?: string | null
elapsed_time?: number | null
error?: string | null
@ -43,7 +43,7 @@ export type WorkflowPaginationResponse = {
export type SnippetWorkflowResponse = {
conversation_variables: Array<WorkflowConversationVariableResponse>
created_at: number
created_by?: SimpleAccount
created_by?: SimpleAccount | null
environment_variables: Array<WorkflowEnvironmentVariableResponse>
features: {
[key: string]: unknown
@ -61,7 +61,7 @@ export type SnippetWorkflowResponse = {
rag_pipeline_variables: Array<PipelineVariableResponse>
tool_published: boolean
updated_at: number
updated_by?: SimpleAccount
updated_by?: SimpleAccount | null
version: string
}
@ -96,8 +96,8 @@ export type SnippetLoopNodeRunPayload = {
export type WorkflowRunNodeExecutionResponse = {
created_at?: number | null
created_by_account?: SimpleAccount
created_by_end_user?: SimpleEndUser
created_by_account?: SimpleAccount | null
created_by_end_user?: SimpleEndUser | null
created_by_role?: string | null
elapsed_time?: number | null
error?: string | null
@ -165,7 +165,7 @@ export type WorkflowDraftVariable = {
export type WorkflowDraftVariableUpdatePayload = {
name?: string | null
value?: unknown
value?: unknown | null
}
export type PublishWorkflowPayload = {
@ -176,7 +176,7 @@ export type PublishWorkflowPayload = {
export type WorkflowRunForListResponse = {
created_at?: number | null
created_by_account?: SimpleAccount
created_by_account?: SimpleAccount | null
elapsed_time?: number | null
exceptions_count?: number | null
finished_at?: number | null
@ -204,7 +204,7 @@ export type SimpleEndUser = {
export type WorkflowResponse = {
conversation_variables: Array<WorkflowConversationVariableResponse>
created_at: number
created_by?: SimpleAccount
created_by?: SimpleAccount | null
environment_variables: Array<WorkflowEnvironmentVariableResponse>
features: {
[key: string]: unknown
@ -219,7 +219,7 @@ export type WorkflowResponse = {
rag_pipeline_variables: Array<PipelineVariableResponse>
tool_published: boolean
updated_at: number
updated_by?: SimpleAccount
updated_by?: SimpleAccount | null
version: string
}
@ -630,9 +630,7 @@ export type DeleteSnippetsBySnippetIdWorkflowsDraftNodesByNodeIdVariablesData =
}
export type DeleteSnippetsBySnippetIdWorkflowsDraftNodesByNodeIdVariablesResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteSnippetsBySnippetIdWorkflowsDraftNodesByNodeIdVariablesResponse
@ -708,9 +706,7 @@ export type DeleteSnippetsBySnippetIdWorkflowsDraftVariablesData = {
}
export type DeleteSnippetsBySnippetIdWorkflowsDraftVariablesResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteSnippetsBySnippetIdWorkflowsDraftVariablesResponse
@ -755,9 +751,7 @@ export type DeleteSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdError
= DeleteSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdErrors[keyof DeleteSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdErrors]
export type DeleteSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdResponse
@ -836,9 +830,7 @@ export type PutSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdResetError
export type PutSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdResetResponses = {
200: WorkflowDraftVariable
204: {
[key: string]: never
}
204: void
}
export type PutSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdResetResponse

View File

@ -76,7 +76,7 @@ export const zWorkflowDraftVariableList = z.object({
*/
export const zWorkflowDraftVariableUpdatePayload = z.object({
name: z.string().nullish(),
value: z.unknown().optional(),
value: z.unknown().nullish(),
})
/**
@ -102,7 +102,7 @@ export const zSimpleAccount = z.object({
*/
export const zWorkflowRunForListResponse = z.object({
created_at: z.int().nullish(),
created_by_account: zSimpleAccount.optional(),
created_by_account: zSimpleAccount.nullish(),
elapsed_time: z.number().nullish(),
exceptions_count: z.int().nullish(),
finished_at: z.int().nullish(),
@ -138,8 +138,8 @@ export const zSimpleEndUser = z.object({
*/
export const zWorkflowRunDetailResponse = z.object({
created_at: z.int().nullish(),
created_by_account: zSimpleAccount.optional(),
created_by_end_user: zSimpleEndUser.optional(),
created_by_account: zSimpleAccount.nullish(),
created_by_end_user: zSimpleEndUser.nullish(),
created_by_role: z.string().nullish(),
elapsed_time: z.number().nullish(),
error: z.string().nullish(),
@ -160,8 +160,8 @@ export const zWorkflowRunDetailResponse = z.object({
*/
export const zWorkflowRunNodeExecutionResponse = z.object({
created_at: z.int().nullish(),
created_by_account: zSimpleAccount.optional(),
created_by_end_user: zSimpleEndUser.optional(),
created_by_account: zSimpleAccount.nullish(),
created_by_end_user: zSimpleEndUser.nullish(),
created_by_role: z.string().nullish(),
elapsed_time: z.number().nullish(),
error: z.string().nullish(),
@ -238,7 +238,7 @@ export const zPipelineVariableResponse = z.object({
export const zSnippetWorkflowResponse = z.object({
conversation_variables: z.array(zWorkflowConversationVariableResponse),
created_at: z.int(),
created_by: zSimpleAccount.optional(),
created_by: zSimpleAccount.nullish(),
environment_variables: z.array(zWorkflowEnvironmentVariableResponse),
features: z.record(z.string(), z.unknown()),
graph: z.record(z.string(), z.unknown()),
@ -250,7 +250,7 @@ export const zSnippetWorkflowResponse = z.object({
rag_pipeline_variables: z.array(zPipelineVariableResponse),
tool_published: z.boolean(),
updated_at: z.int(),
updated_by: zSimpleAccount.optional(),
updated_by: zSimpleAccount.nullish(),
version: z.string(),
})
@ -260,7 +260,7 @@ export const zSnippetWorkflowResponse = z.object({
export const zWorkflowResponse = z.object({
conversation_variables: z.array(zWorkflowConversationVariableResponse),
created_at: z.int(),
created_by: zSimpleAccount.optional(),
created_by: zSimpleAccount.nullish(),
environment_variables: z.array(zWorkflowEnvironmentVariableResponse),
features: z.record(z.string(), z.unknown()),
graph: z.record(z.string(), z.unknown()),
@ -271,7 +271,7 @@ export const zWorkflowResponse = z.object({
rag_pipeline_variables: z.array(zPipelineVariableResponse),
tool_published: z.boolean(),
updated_at: z.int(),
updated_by: zSimpleAccount.optional(),
updated_by: zSimpleAccount.nullish(),
version: z.string(),
})
@ -487,10 +487,7 @@ export const zDeleteSnippetsBySnippetIdWorkflowsDraftNodesByNodeIdVariablesPath
/**
* Node variables deleted successfully
*/
export const zDeleteSnippetsBySnippetIdWorkflowsDraftNodesByNodeIdVariablesResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteSnippetsBySnippetIdWorkflowsDraftNodesByNodeIdVariablesResponse = z.void()
export const zGetSnippetsBySnippetIdWorkflowsDraftNodesByNodeIdVariablesPath = z.object({
node_id: z.string(),
@ -531,10 +528,7 @@ export const zDeleteSnippetsBySnippetIdWorkflowsDraftVariablesPath = z.object({
/**
* Workflow variables deleted successfully
*/
export const zDeleteSnippetsBySnippetIdWorkflowsDraftVariablesResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteSnippetsBySnippetIdWorkflowsDraftVariablesResponse = z.void()
export const zGetSnippetsBySnippetIdWorkflowsDraftVariablesPath = z.object({
snippet_id: z.string(),
@ -559,10 +553,7 @@ export const zDeleteSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdPath =
/**
* Variable deleted successfully
*/
export const zDeleteSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdResponse = z.void()
export const zGetSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdPath = z.object({
snippet_id: z.string(),
@ -596,7 +587,7 @@ export const zPutSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdResetPath
export const zPutSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdResetResponse = z.union([
zWorkflowDraftVariable,
z.record(z.string(), z.never()),
z.void(),
])
export const zGetSnippetsBySnippetIdWorkflowsPublishPath = z.object({

View File

@ -43,8 +43,12 @@ export const zLicenseLimitationModel = z.object({
*/
export const zLicenseModel = z.object({
expired_at: z.string().default(''),
status: zLicenseStatus,
workspaces: zLicenseLimitationModel,
status: zLicenseStatus.default('none'),
workspaces: zLicenseLimitationModel.default({
enabled: false,
limit: 0,
size: 0,
}),
})
/**
@ -61,7 +65,7 @@ export const zPluginInstallationScope = z.enum([
* PluginInstallationPermissionModel
*/
export const zPluginInstallationPermissionModel = z.object({
plugin_installation_scope: zPluginInstallationScope,
plugin_installation_scope: zPluginInstallationScope.default('all'),
restrict_to_marketplace_only: z.boolean().default(false),
})
@ -80,14 +84,20 @@ export const zWebAppAuthModel = z.object({
allow_email_password_login: z.boolean().default(false),
allow_sso: z.boolean().default(false),
enabled: z.boolean().default(false),
sso_config: zWebAppAuthSsoModel,
sso_config: zWebAppAuthSsoModel.default({ protocol: '' }),
})
/**
* SystemFeatureModel
*/
export const zSystemFeatureModel = z.object({
branding: zBrandingModel,
branding: zBrandingModel.default({
application_title: '',
enabled: false,
favicon: '',
login_page_logo: '',
workspace_logo: '',
}),
enable_change_email: z.boolean().default(true),
enable_collaboration_mode: z.boolean().default(true),
enable_creators_platform: z.boolean().default(false),
@ -100,13 +110,30 @@ export const zSystemFeatureModel = z.object({
is_allow_create_workspace: z.boolean().default(false),
is_allow_register: z.boolean().default(false),
is_email_setup: z.boolean().default(false),
license: zLicenseModel,
license: zLicenseModel.default({
expired_at: '',
status: 'none',
workspaces: {
enabled: false,
limit: 0,
size: 0,
},
}),
max_plugin_package_size: z.int().default(15728640),
plugin_installation_permission: zPluginInstallationPermissionModel,
plugin_manager: zPluginManagerModel,
plugin_installation_permission: zPluginInstallationPermissionModel.default({
plugin_installation_scope: 'all',
restrict_to_marketplace_only: false,
}),
plugin_manager: zPluginManagerModel.default({ enabled: false }),
sso_enforced_for_signin: z.boolean().default(false),
sso_enforced_for_signin_protocol: z.string().default(''),
webapp_auth: zWebAppAuthModel,
webapp_auth: zWebAppAuthModel.default({
allow_email_code_login: false,
allow_email_password_login: false,
allow_sso: false,
enabled: false,
sso_config: { protocol: '' },
}),
})
/**

View File

@ -61,9 +61,7 @@ export type DeleteTagsByTagIdData = {
}
export type DeleteTagsByTagIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteTagsByTagIdResponse = DeleteTagsByTagIdResponses[keyof DeleteTagsByTagIdResponses]

View File

@ -58,7 +58,7 @@ export const zDeleteTagsByTagIdPath = z.object({
/**
* Tag deleted successfully
*/
export const zDeleteTagsByTagIdResponse = z.record(z.string(), z.never())
export const zDeleteTagsByTagIdResponse = z.void()
export const zPatchTagsByTagIdBody = zTagUpdateRequestPayload

View File

@ -32,7 +32,7 @@ export const get = oc
.input(
z.object({
params: zGetWebsiteCrawlStatusByJobIdPath,
query: zGetWebsiteCrawlStatusByJobIdQuery,
query: zGetWebsiteCrawlStatusByJobIdQuery.optional(),
}),
)
.output(zGetWebsiteCrawlStatusByJobIdResponse)

View File

@ -40,8 +40,8 @@ export type GetWebsiteCrawlStatusByJobIdData = {
path: {
job_id: string
}
query: {
provider: 'firecrawl' | 'jinareader' | 'watercrawl'
query?: {
provider?: string
}
url: '/website/crawl/status/{job_id}'
}

View File

@ -23,7 +23,7 @@ export const zGetWebsiteCrawlStatusByJobIdPath = z.object({
})
export const zGetWebsiteCrawlStatusByJobIdQuery = z.object({
provider: z.enum(['firecrawl', 'jinareader', 'watercrawl']),
provider: z.string().optional(),
})
/**

View File

@ -18,7 +18,7 @@ export type PausedNodeResponse = {
export type HumanInputPauseTypeResponse = {
backstage_input_url?: string | null
form_id: string
type: string
type: 'human_input'
}
export type GetWorkflowByWorkflowRunIdEventsData = {

View File

@ -8,7 +8,7 @@ import * as z from 'zod'
export const zHumanInputPauseTypeResponse = z.object({
backstage_input_url: z.string().nullish(),
form_id: z.string(),
type: z.string(),
type: z.literal('human_input'),
})
/**

View File

@ -6,7 +6,7 @@ export type ClientOptions = {
export type TenantInfoResponse = {
created_at?: number | null
custom_config?: WorkspaceCustomConfigResponse
custom_config?: WorkspaceCustomConfigResponse | null
id: string
in_trial?: boolean | null
name?: string | null
@ -32,7 +32,7 @@ export type CreateSnippetPayload = {
graph?: {
[key: string]: unknown
} | null
icon_info?: IconInfo
icon_info?: IconInfo | null
input_fields?: Array<InputFieldDefinition> | null
name: string
type?: 'group' | 'node'
@ -77,7 +77,7 @@ export type SnippetImportPayload = {
export type UpdateSnippetPayload = {
description?: string | null
icon_info?: IconInfo
icon_info?: IconInfo | null
name?: string | null
}
@ -85,6 +85,8 @@ export type AccountWithRoleList = {
accounts: Array<AccountWithRole>
}
export type ModelType = 'llm' | 'moderation' | 'rerank' | 'speech2text' | 'text-embedding' | 'tts'
export type ParserPostDefault = {
model_settings: Array<Inner>
}
@ -223,7 +225,7 @@ export type ParserDeleteModels = {
export type ParserPostModels = {
config_from?: string | null
credential_id?: string | null
load_balancing?: LoadBalancingPayload
load_balancing?: LoadBalancingPayload | null
model: string
model_type: ModelType
}
@ -459,7 +461,7 @@ export type McpProviderCreatePayload = {
icon: string
icon_background?: string
icon_type: string
identity_mode?: IdentityMode
identity_mode?: IdentityMode | null
name: string
server_identifier: string
server_url: string
@ -478,7 +480,7 @@ export type McpProviderUpdatePayload = {
icon: string
icon_background?: string
icon_type: string
identity_mode?: IdentityMode
identity_mode?: IdentityMode | null
name: string
provider_id: string
server_identifier: string
@ -641,8 +643,6 @@ export type Inner = {
export type TenantAccountRole = 'admin' | 'dataset_operator' | 'editor' | 'normal' | 'owner'
export type ModelType = 'llm' | 'moderation' | 'rerank' | 'speech2text' | 'text-embedding' | 'tts'
export type LoadBalancingPayload = {
configs?: Array<{
[key: string]: unknown
@ -866,9 +866,7 @@ export type DeleteWorkspacesCurrentCustomizedSnippetsBySnippetIdError
= DeleteWorkspacesCurrentCustomizedSnippetsBySnippetIdErrors[keyof DeleteWorkspacesCurrentCustomizedSnippetsBySnippetIdErrors]
export type DeleteWorkspacesCurrentCustomizedSnippetsBySnippetIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteWorkspacesCurrentCustomizedSnippetsBySnippetIdResponse
@ -1026,7 +1024,7 @@ export type GetWorkspacesCurrentDefaultModelData = {
body?: never
path?: never
query: {
model_type: string
model_type: ModelType
}
url: '/workspaces/current/default-model'
}
@ -1393,7 +1391,7 @@ export type GetWorkspacesCurrentModelProvidersData = {
body?: never
path?: never
query?: {
model_type?: string | null
model_type?: ModelType | null
}
url: '/workspaces/current/model-providers'
}
@ -1435,9 +1433,7 @@ export type DeleteWorkspacesCurrentModelProvidersByProviderCredentialsData = {
}
export type DeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponse
@ -1543,9 +1539,7 @@ export type DeleteWorkspacesCurrentModelProvidersByProviderModelsData = {
}
export type DeleteWorkspacesCurrentModelProvidersByProviderModelsResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteWorkspacesCurrentModelProvidersByProviderModelsResponse
@ -1597,9 +1591,7 @@ export type DeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsData
}
export type DeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse
@ -1614,7 +1606,7 @@ export type GetWorkspacesCurrentModelProvidersByProviderModelsCredentialsData =
config_from?: string | null
credential_id?: string | null
model: string
model_type: string
model_type: ModelType
}
url: '/workspaces/current/model-providers/{provider}/models/credentials'
}

View File

@ -16,6 +16,20 @@ export const zSnippetImportPayload = z.object({
yaml_url: z.string().nullish(),
})
/**
* ModelType
*
* Enum class for model type.
*/
export const zModelType = z.enum([
'llm',
'moderation',
'rerank',
'speech2text',
'text-embedding',
'tts',
])
/**
* SimpleResultResponse
*/
@ -189,6 +203,71 @@ export const zParserCredentialValidate = z.object({
credentials: z.record(z.string(), z.unknown()),
})
/**
* ParserDeleteModels
*/
export const zParserDeleteModels = z.object({
model: z.string(),
model_type: zModelType,
})
/**
* ParserDeleteCredential
*/
export const zParserDeleteCredential = z.object({
credential_id: z.string(),
model: z.string(),
model_type: zModelType,
})
/**
* ParserCreateCredential
*/
export const zParserCreateCredential = z.object({
credentials: z.record(z.string(), z.unknown()),
model: z.string(),
model_type: zModelType,
name: z.string().max(30).nullish(),
})
/**
* ParserUpdateCredential
*/
export const zParserUpdateCredential = z.object({
credential_id: z.string(),
credentials: z.record(z.string(), z.unknown()),
model: z.string(),
model_type: zModelType,
name: z.string().max(30).nullish(),
})
/**
* ParserSwitch
*/
export const zParserSwitch = z.object({
credential_id: z.string(),
model: z.string(),
model_type: zModelType,
})
/**
* ParserValidate
*/
export const zParserValidate = z.object({
credentials: z.record(z.string(), z.unknown()),
model: z.string(),
model_type: zModelType,
})
/**
* LoadBalancingCredentialPayload
*/
export const zLoadBalancingCredentialPayload = z.object({
credentials: z.record(z.string(), z.unknown()),
model: z.string(),
model_type: zModelType,
})
/**
* ParserPreferredProviderType
*/
@ -433,7 +512,7 @@ export const zWorkspaceCustomConfigResponse = z.object({
*/
export const zTenantInfoResponse = z.object({
created_at: z.int().nullish(),
custom_config: zWorkspaceCustomConfigResponse.optional(),
custom_config: zWorkspaceCustomConfigResponse.nullish(),
id: z.string(),
in_trial: z.boolean().nullish(),
name: z.string().nullish(),
@ -465,7 +544,7 @@ export const zIconInfo = z.object({
*/
export const zUpdateSnippetPayload = z.object({
description: z.string().max(2000).nullish(),
icon_info: zIconInfo.optional(),
icon_info: zIconInfo.nullish(),
name: z.string().min(1).max(255).nullish(),
})
@ -493,7 +572,7 @@ export const zInputFieldDefinition = z.object({
export const zCreateSnippetPayload = z.object({
description: z.string().max(2000).nullish(),
graph: z.record(z.string(), z.unknown()).nullish(),
icon_info: zIconInfo.optional(),
icon_info: zIconInfo.nullish(),
input_fields: z.array(zInputFieldDefinition).nullish(),
name: z.string().min(1).max(255),
type: z.enum(['group', 'node']).optional().default('node'),
@ -576,99 +655,6 @@ export const zAccountWithRoleList = z.object({
accounts: z.array(zAccountWithRole),
})
/**
* TenantAccountRole
*/
export const zTenantAccountRole = z.enum(['admin', 'dataset_operator', 'editor', 'normal', 'owner'])
/**
* MemberInvitePayload
*/
export const zMemberInvitePayload = z.object({
emails: z.array(z.string()).optional(),
language: z.string().nullish(),
role: zTenantAccountRole,
})
/**
* ModelType
*
* Enum class for model type.
*/
export const zModelType = z.enum([
'llm',
'moderation',
'rerank',
'speech2text',
'text-embedding',
'tts',
])
/**
* ParserDeleteModels
*/
export const zParserDeleteModels = z.object({
model: z.string(),
model_type: zModelType,
})
/**
* ParserDeleteCredential
*/
export const zParserDeleteCredential = z.object({
credential_id: z.string(),
model: z.string(),
model_type: zModelType,
})
/**
* ParserCreateCredential
*/
export const zParserCreateCredential = z.object({
credentials: z.record(z.string(), z.unknown()),
model: z.string(),
model_type: zModelType,
name: z.string().max(30).nullish(),
})
/**
* ParserUpdateCredential
*/
export const zParserUpdateCredential = z.object({
credential_id: z.string(),
credentials: z.record(z.string(), z.unknown()),
model: z.string(),
model_type: zModelType,
name: z.string().max(30).nullish(),
})
/**
* ParserSwitch
*/
export const zParserSwitch = z.object({
credential_id: z.string(),
model: z.string(),
model_type: zModelType,
})
/**
* ParserValidate
*/
export const zParserValidate = z.object({
credentials: z.record(z.string(), z.unknown()),
model: z.string(),
model_type: zModelType,
})
/**
* LoadBalancingCredentialPayload
*/
export const zLoadBalancingCredentialPayload = z.object({
credentials: z.record(z.string(), z.unknown()),
model: z.string(),
model_type: zModelType,
})
/**
* Inner
*/
@ -685,6 +671,20 @@ export const zParserPostDefault = z.object({
model_settings: z.array(zInner),
})
/**
* TenantAccountRole
*/
export const zTenantAccountRole = z.enum(['admin', 'dataset_operator', 'editor', 'normal', 'owner'])
/**
* MemberInvitePayload
*/
export const zMemberInvitePayload = z.object({
emails: z.array(z.string()).optional(),
language: z.string().nullish(),
role: zTenantAccountRole,
})
/**
* LoadBalancingPayload
*/
@ -699,7 +699,7 @@ export const zLoadBalancingPayload = z.object({
export const zParserPostModels = z.object({
config_from: z.string().nullish(),
credential_id: z.string().nullish(),
load_balancing: zLoadBalancingPayload.optional(),
load_balancing: zLoadBalancingPayload.nullish(),
model: z.string(),
model_type: zModelType,
})
@ -726,8 +726,8 @@ export const zParserPermissionChange = z.object({
* PluginPermissionSettingsPayload
*/
export const zPluginPermissionSettingsPayload = z.object({
debug_permission: zDebugPermission.optional(),
install_permission: zInstallPermission.optional(),
debug_permission: zDebugPermission.optional().default('everyone'),
install_permission: zInstallPermission.optional().default('everyone'),
})
/**
@ -815,7 +815,7 @@ export const zMcpProviderCreatePayload = z.object({
icon: z.string(),
icon_background: z.string().optional().default(''),
icon_type: z.string(),
identity_mode: zIdentityMode.optional(),
identity_mode: zIdentityMode.nullish(),
name: z.string(),
server_identifier: z.string(),
server_url: z.string(),
@ -831,7 +831,7 @@ export const zMcpProviderUpdatePayload = z.object({
icon: z.string(),
icon_background: z.string().optional().default(''),
icon_type: z.string(),
identity_mode: zIdentityMode.optional(),
identity_mode: zIdentityMode.nullish(),
name: z.string(),
provider_id: z.string(),
server_identifier: z.string(),
@ -854,8 +854,8 @@ export const zUpgradeMode = z.enum(['all', 'exclude', 'partial'])
export const zPluginAutoUpgradeSettingsPayload = z.object({
exclude_plugins: z.array(z.string()).optional(),
include_plugins: z.array(z.string()).optional(),
strategy_setting: zStrategySetting.optional(),
upgrade_mode: zUpgradeMode.optional(),
strategy_setting: zStrategySetting.optional().default('fix_only'),
upgrade_mode: zUpgradeMode.optional().default('exclude'),
upgrade_time_of_day: z.int().optional().default(0),
})
@ -987,10 +987,7 @@ export const zDeleteWorkspacesCurrentCustomizedSnippetsBySnippetIdPath = z.objec
/**
* Snippet deleted successfully
*/
export const zDeleteWorkspacesCurrentCustomizedSnippetsBySnippetIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteWorkspacesCurrentCustomizedSnippetsBySnippetIdResponse = z.void()
export const zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdPath = z.object({
snippet_id: z.string(),
@ -1052,7 +1049,7 @@ export const zPostWorkspacesCurrentCustomizedSnippetsBySnippetIdUseCountIncremen
export const zGetWorkspacesCurrentDatasetOperatorsResponse = zAccountWithRoleList
export const zGetWorkspacesCurrentDefaultModelQuery = z.object({
model_type: z.string(),
model_type: zModelType,
})
/**
@ -1104,7 +1101,7 @@ export const zPostWorkspacesCurrentEndpointsEnableResponse = zEndpointEnableResp
export const zGetWorkspacesCurrentEndpointsListQuery = z.object({
page: z.int().gte(1),
page_size: z.int(),
page_size: z.int().gt(0),
})
/**
@ -1114,7 +1111,7 @@ export const zGetWorkspacesCurrentEndpointsListResponse = zEndpointListResponse
export const zGetWorkspacesCurrentEndpointsListPluginQuery = z.object({
page: z.int().gte(1),
page_size: z.int(),
page_size: z.int().gt(0),
plugin_id: z.string(),
})
@ -1216,7 +1213,7 @@ export const zPutWorkspacesCurrentMembersByMemberIdUpdateRoleResponse = z.record
)
export const zGetWorkspacesCurrentModelProvidersQuery = z.object({
model_type: z.string().nullish(),
model_type: zModelType.nullish(),
})
/**
@ -1246,10 +1243,7 @@ export const zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsPath = z
/**
* Credential deleted successfully
*/
export const zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponse = z.void()
export const zGetWorkspacesCurrentModelProvidersByProviderCredentialsPath = z.object({
provider: z.string(),
@ -1332,10 +1326,7 @@ export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsPath = z.obje
/**
* Model deleted successfully
*/
export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsResponse = z.void()
export const zGetWorkspacesCurrentModelProvidersByProviderModelsPath = z.object({
provider: z.string(),
@ -1373,10 +1364,7 @@ export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsPa
/**
* Credential deleted successfully
*/
export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse = z.void()
export const zGetWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath = z.object({
provider: z.string(),
@ -1386,7 +1374,7 @@ export const zGetWorkspacesCurrentModelProvidersByProviderModelsCredentialsQuery
config_from: z.string().nullish(),
credential_id: z.string().nullish(),
model: z.string(),
model_type: z.string(),
model_type: zModelType,
})
/**

View File

@ -11,7 +11,7 @@ export type AccountPayload = {
}
export type AccountResponse = {
account?: AccountPayload
account?: AccountPayload | null
default_workspace_id?: string | null
subject_email?: string | null
subject_issuer?: string | null
@ -36,7 +36,7 @@ export type AppDescribeQuery = {
}
export type AppDescribeResponse = {
info?: AppDescribeInfo
info?: AppDescribeInfo | null
input_schema?: {
[key: string]: unknown
} | null
@ -77,7 +77,7 @@ export type AppInfoResponse = {
export type AppListQuery = {
limit?: number
mode?: AppMode
mode?: AppMode | null
name?: string | null
page?: number
tag?: string | null
@ -177,7 +177,7 @@ export type ErrorBody = {
}
export type ErrorDetail = {
loc?: Array<unknown>
loc?: Array<string | number>
msg: string
type: string
}
@ -242,7 +242,7 @@ export type Marketplace = {
}
export type MemberActionResponse = {
result?: string
result?: 'success'
}
export type MemberInvitePayload = {
@ -254,7 +254,7 @@ export type MemberInviteResponse = {
email: string
invite_url: string
member_id: string
result?: string
result?: 'success'
role: string
tenant_id: string
}
@ -289,7 +289,7 @@ export type MessageMetadata = {
retriever_resources?: Array<{
[key: string]: unknown
}>
usage?: UsageInfo
usage?: UsageInfo | null
}
export type OpenApiErrorCode
@ -330,7 +330,7 @@ export type Package = {
export type PermittedExternalAppsListQuery = {
limit?: number
mode?: AppMode
mode?: AppMode | null
name?: string | null
page?: number
}
@ -346,7 +346,7 @@ export type PermittedExternalAppsListResponse = {
export type PluginDependency = {
current_identifier?: string | null
type: Type
value: unknown
value: Github | Marketplace | Package
}
export type RevokeResponse = {
@ -386,7 +386,7 @@ export type TagItem = {
}
export type TaskStopResponse = {
result: string
result: 'success'
}
export type Type = 'github' | 'marketplace' | 'package'

View File

@ -79,7 +79,7 @@ export const zAppMode = z.enum([
*/
export const zAppListQuery = z.object({
limit: z.int().gte(1).lte(200).optional().default(20),
mode: zAppMode.optional(),
mode: zAppMode.nullish(),
name: z.string().max(200).nullish(),
page: z.int().gte(1).optional().default(1),
tag: z.string().max(100).nullish(),
@ -160,7 +160,10 @@ export const zDevicePollRequest = z.object({
* ErrorDetail
*/
export const zErrorDetail = z.object({
loc: z.array(z.unknown()).optional().default([]),
loc: z
.array(z.union([z.string(), z.int()]))
.optional()
.default([]),
msg: z.string(),
type: z.string(),
})
@ -269,7 +272,7 @@ export const zMarketplace = z.object({
* MemberActionResponse
*/
export const zMemberActionResponse = z.object({
result: z.string().optional().default('success'),
result: z.literal('success').optional().default('success'),
})
/**
@ -287,7 +290,7 @@ export const zMemberInviteResponse = z.object({
email: z.string(),
invite_url: z.string(),
member_id: z.string(),
result: z.string().optional().default('success'),
result: z.literal('success').optional().default('success'),
role: z.string(),
tenant_id: z.string(),
})
@ -382,7 +385,7 @@ export const zPackage = z.object({
*/
export const zPermittedExternalAppsListQuery = z.object({
limit: z.int().gte(1).lte(200).optional().default(20),
mode: zAppMode.optional(),
mode: zAppMode.nullish(),
name: z.string().max(200).nullish(),
page: z.int().gte(1).optional().default(1),
})
@ -464,7 +467,7 @@ export const zAppDescribeInfo = z.object({
* AppDescribeResponse
*/
export const zAppDescribeResponse = z.object({
info: zAppDescribeInfo.optional(),
info: zAppDescribeInfo.nullish(),
input_schema: z.record(z.string(), z.unknown()).nullish(),
parameters: z.record(z.string(), z.unknown()).nullish(),
})
@ -526,7 +529,7 @@ export const zPermittedExternalAppsListResponse = z.object({
* types it as a required `'success'` rather than an optional field.
*/
export const zTaskStopResponse = z.object({
result: z.string(),
result: z.literal('success'),
})
/**
@ -540,7 +543,7 @@ export const zType = z.enum(['github', 'marketplace', 'package'])
export const zPluginDependency = z.object({
current_identifier: z.string().nullish(),
type: zType,
value: z.unknown(),
value: z.union([zGithub, zMarketplace, zPackage]),
})
/**
@ -564,7 +567,7 @@ export const zUsageInfo = z.object({
*/
export const zMessageMetadata = z.object({
retriever_resources: z.array(z.record(z.string(), z.unknown())).optional().default([]),
usage: zUsageInfo.optional(),
usage: zUsageInfo.nullish(),
})
/**
@ -608,7 +611,7 @@ export const zWorkspacePayload = z.object({
* AccountResponse
*/
export const zAccountResponse = z.object({
account: zAccountPayload.optional(),
account: zAccountPayload.nullish(),
default_workspace_id: z.string().nullish(),
subject_email: z.string().nullish(),
subject_issuer: z.string().nullish(),

View File

@ -132,7 +132,7 @@ export type Condition = {
| '≤'
| '≥'
name: string
value?: unknown
value?: string | Array<string> | number | number | null
}
export type ConversationListQuery = {
@ -190,9 +190,9 @@ export type DatasetCreatePayload = {
external_knowledge_id?: string | null
indexing_technique?: 'economy' | 'high_quality' | null
name: string
permission?: PermissionEnum
permission?: PermissionEnum | null
provider?: string
retrieval_model?: RetrievalModel
retrieval_model?: RetrievalModel | null
summary_index_setting?: {
[key: string]: unknown
} | null
@ -215,7 +215,7 @@ export type DatasetDetailResponse = {
embedding_model_provider: string | null
enable_api: boolean
external_knowledge_info?: DatasetExternalKnowledgeInfoResponse
external_retrieval_model: DatasetExternalRetrievalModelResponse
external_retrieval_model: DatasetExternalRetrievalModelResponse | null
icon_info?: DatasetIconInfoResponse
id: string
indexing_technique: string | null
@ -253,7 +253,7 @@ export type DatasetDetailWithPartialMembersResponse = {
embedding_model_provider: string | null
enable_api: boolean
external_knowledge_info?: DatasetExternalKnowledgeInfoResponse
external_retrieval_model: DatasetExternalRetrievalModelResponse
external_retrieval_model: DatasetExternalRetrievalModelResponse | null
icon_info?: DatasetIconInfoResponse
id: string
indexing_technique: string | null
@ -365,7 +365,7 @@ export type DatasetRetrievalModelResponse = {
score_threshold_enabled: boolean
search_method: string
top_k: number
weights?: DatasetWeightedScoreResponse
weights?: DatasetWeightedScoreResponse | null
}
export type DatasetSummaryIndexSettingResponse = {
@ -395,8 +395,8 @@ export type DatasetUpdatePayload = {
partial_member_list?: Array<{
[key: string]: string
}> | null
permission?: PermissionEnum
retrieval_model?: RetrievalModel
permission?: PermissionEnum | null
retrieval_model?: RetrievalModel | null
}
export type DatasetVectorSettingResponse = {
@ -454,7 +454,7 @@ export type DocumentMetadataResponse = {
id: string
name: string
type: string
value?: unknown
value?: string | number | number | boolean | null
}
export type DocumentResponse = {
@ -511,8 +511,8 @@ export type DocumentTextCreatePayload = {
indexing_technique?: string | null
name: string
original_document_id?: string | null
process_rule?: ProcessRule
retrieval_model?: RetrievalModel
process_rule?: ProcessRule | null
retrieval_model?: RetrievalModel | null
text: string
}
@ -520,8 +520,8 @@ export type DocumentTextUpdate = {
doc_form?: string
doc_language?: string
name?: string | null
process_rule?: ProcessRule
retrieval_model?: RetrievalModel
process_rule?: ProcessRule | null
retrieval_model?: RetrievalModel | null
text?: string | null
}
@ -574,7 +574,7 @@ export type HitTestingChildChunk = {
export type HitTestingDocument = {
data_source_type: string
doc_metadata: unknown
doc_metadata: unknown | null
doc_type: string | null
id: string
name: string
@ -595,7 +595,7 @@ export type HitTestingPayload = {
[key: string]: unknown
} | null
query: string
retrieval_model?: RetrievalModel
retrieval_model?: RetrievalModel | null
}
export type HitTestingQuery = {
@ -608,7 +608,7 @@ export type HitTestingRecord = {
score: number | null
segment: HitTestingSegment
summary: string | null
tsne_position: unknown
tsne_position: unknown | null
}
export type HitTestingResponse = {
@ -685,7 +685,7 @@ export type MetadataArgs = {
export type MetadataDetail = {
id: string
name: string
value?: unknown
value?: string | number | number | null
}
export type MetadataFilteringCondition = {
@ -723,7 +723,7 @@ export type PreProcessingRule = {
export type ProcessRule = {
mode: ProcessRuleMode
rules?: Rule
rules?: Rule | null
}
export type ProcessRuleMode = 'automatic' | 'custom' | 'hierarchical'
@ -744,22 +744,22 @@ export type RetrievalMethod
| 'semantic_search'
export type RetrievalModel = {
metadata_filtering_conditions?: MetadataFilteringCondition
metadata_filtering_conditions?: MetadataFilteringCondition | null
reranking_enable: boolean
reranking_mode?: string | null
reranking_model?: RerankingModel
reranking_model?: RerankingModel | null
score_threshold?: number | null
score_threshold_enabled: boolean
search_method: RetrievalMethod
top_k: number
weights?: WeightModel
weights?: WeightModel | null
}
export type Rule = {
parent_mode?: 'full-doc' | 'paragraph' | null
pre_processing_rules?: Array<PreProcessingRule> | null
segmentation?: Segmentation
subchunk_segmentation?: Segmentation
segmentation?: Segmentation | null
subchunk_segmentation?: Segmentation | null
}
export type SegmentAttachmentResponse = {
@ -937,8 +937,8 @@ export type WeightKeywordSetting = {
}
export type WeightModel = {
keyword_setting?: WeightKeywordSetting
vector_setting?: WeightVectorSetting
keyword_setting?: WeightKeywordSetting | null
vector_setting?: WeightVectorSetting | null
weight_type?: 'customized' | 'keyword_first' | 'semantic_first' | null
}
@ -958,13 +958,22 @@ export type WorkflowAppLogPaginationResponse = {
export type WorkflowAppLogPartialResponse = {
created_at?: number | null
created_by_account?: SimpleAccount
created_by_end_user?: SimpleEndUser
created_by_account?: SimpleAccount | null
created_by_end_user?: SimpleEndUser | null
created_by_role?: string | null
created_from?: string | null
details?: unknown
details?:
| {
[key: string]: unknown
}
| Array<unknown>
| string
| number
| number
| boolean
| null
id: string
workflow_run?: WorkflowRunForLogResponse
workflow_run?: WorkflowRunForLogResponse | null
}
export type WorkflowLogQuery = {
@ -980,7 +989,7 @@ export type WorkflowLogQuery = {
export type WorkflowRunForLogResponse = {
created_at?: number | null
elapsed_time?: unknown
elapsed_time?: number | number | null
error?: string | null
exceptions_count?: number | null
finished_at?: number | null
@ -1005,11 +1014,20 @@ export type WorkflowRunPayload = {
export type WorkflowRunResponse = {
created_at?: number | null
elapsed_time?: unknown
elapsed_time?: number | number | null
error?: string | null
finished_at?: number | null
id: string
inputs?: unknown
inputs?:
| {
[key: string]: unknown
}
| Array<unknown>
| string
| number
| number
| boolean
| null
outputs?: {
[key: string]: unknown
}
@ -1205,9 +1223,7 @@ export type DeleteAppsAnnotationsByAnnotationIdError
= DeleteAppsAnnotationsByAnnotationIdErrors[keyof DeleteAppsAnnotationsByAnnotationIdErrors]
export type DeleteAppsAnnotationsByAnnotationIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteAppsAnnotationsByAnnotationIdResponse
@ -1456,9 +1472,7 @@ export type DeleteConversationsByCIdError
= DeleteConversationsByCIdErrors[keyof DeleteConversationsByCIdErrors]
export type DeleteConversationsByCIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteConversationsByCIdResponse
@ -1662,9 +1676,7 @@ export type DeleteDatasetsTagsErrors = {
export type DeleteDatasetsTagsError = DeleteDatasetsTagsErrors[keyof DeleteDatasetsTagsErrors]
export type DeleteDatasetsTagsResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsTagsResponse
@ -1759,9 +1771,7 @@ export type PostDatasetsTagsBindingError
= PostDatasetsTagsBindingErrors[keyof PostDatasetsTagsBindingErrors]
export type PostDatasetsTagsBindingResponses = {
204: {
[key: string]: never
}
204: void
}
export type PostDatasetsTagsBindingResponse
@ -1787,9 +1797,7 @@ export type PostDatasetsTagsUnbindingError
= PostDatasetsTagsUnbindingErrors[keyof PostDatasetsTagsUnbindingErrors]
export type PostDatasetsTagsUnbindingResponses = {
204: {
[key: string]: never
}
204: void
}
export type PostDatasetsTagsUnbindingResponse
@ -1820,9 +1828,7 @@ export type DeleteDatasetsByDatasetIdError
= DeleteDatasetsByDatasetIdErrors[keyof DeleteDatasetsByDatasetIdErrors]
export type DeleteDatasetsByDatasetIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByDatasetIdResponse
@ -2192,9 +2198,7 @@ export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdError
= DeleteDatasetsByDatasetIdDocumentsByDocumentIdErrors[keyof DeleteDatasetsByDatasetIdDocumentsByDocumentIdErrors]
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse
@ -2388,9 +2392,7 @@ export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdErr
= DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdErrors[keyof DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdErrors]
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse
@ -2548,9 +2550,7 @@ export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChi
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses
= {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse
@ -2873,9 +2873,7 @@ export type DeleteDatasetsByDatasetIdMetadataByMetadataIdError
= DeleteDatasetsByDatasetIdMetadataByMetadataIdErrors[keyof DeleteDatasetsByDatasetIdMetadataByMetadataIdErrors]
export type DeleteDatasetsByDatasetIdMetadataByMetadataIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteDatasetsByDatasetIdMetadataByMetadataIdResponse

View File

@ -170,7 +170,7 @@ export const zCondition = z.object({
'≥',
]),
name: z.string(),
value: z.unknown().optional(),
value: z.union([z.string(), z.array(z.string()), z.int(), z.number()]).nullish(),
})
/**
@ -408,7 +408,7 @@ export const zDatasetRetrievalModelResponse = z.object({
score_threshold_enabled: z.boolean(),
search_method: z.string(),
top_k: z.int(),
weights: zDatasetWeightedScoreResponse.optional(),
weights: zDatasetWeightedScoreResponse.nullish(),
})
/**
@ -431,7 +431,7 @@ export const zDatasetDetailResponse = z.object({
embedding_model_provider: z.string().nullable(),
enable_api: z.boolean(),
external_knowledge_info: zDatasetExternalKnowledgeInfoResponse.optional(),
external_retrieval_model: zDatasetExternalRetrievalModelResponse,
external_retrieval_model: zDatasetExternalRetrievalModelResponse.nullable(),
icon_info: zDatasetIconInfoResponse.optional(),
id: z.string(),
indexing_technique: z.string().nullable(),
@ -472,7 +472,7 @@ export const zDatasetDetailWithPartialMembersResponse = z.object({
embedding_model_provider: z.string().nullable(),
enable_api: z.boolean(),
external_knowledge_info: zDatasetExternalKnowledgeInfoResponse.optional(),
external_retrieval_model: zDatasetExternalRetrievalModelResponse,
external_retrieval_model: zDatasetExternalRetrievalModelResponse.nullable(),
icon_info: zDatasetIconInfoResponse.optional(),
id: z.string(),
indexing_technique: z.string().nullable(),
@ -541,7 +541,7 @@ export const zDocumentMetadataResponse = z.object({
id: z.string(),
name: z.string(),
type: z.string(),
value: z.unknown().optional(),
value: z.union([z.string(), z.int(), z.number(), z.boolean()]).nullish(),
})
/**
@ -691,7 +691,7 @@ export const zHitTestingChildChunk = z.object({
*/
export const zHitTestingDocument = z.object({
data_source_type: z.string(),
doc_metadata: z.unknown(),
doc_metadata: z.unknown().nullable(),
doc_type: z.string().nullable(),
id: z.string(),
name: z.string(),
@ -754,7 +754,7 @@ export const zHitTestingRecord = z.object({
score: z.number().nullable(),
segment: zHitTestingSegment,
summary: z.string().nullable(),
tsne_position: z.unknown(),
tsne_position: z.unknown().nullable(),
})
/**
@ -830,7 +830,7 @@ export const zMetadataArgs = z.object({
export const zMetadataDetail = z.object({
id: z.string(),
name: z.string(),
value: z.unknown().optional(),
value: z.union([z.string(), z.int(), z.number()]).nullish(),
})
/**
@ -1062,8 +1062,8 @@ export const zSegmentation = z.object({
export const zRule = z.object({
parent_mode: z.enum(['full-doc', 'paragraph']).nullish(),
pre_processing_rules: z.array(zPreProcessingRule).nullish(),
segmentation: zSegmentation.optional(),
subchunk_segmentation: zSegmentation.optional(),
segmentation: zSegmentation.nullish(),
subchunk_segmentation: zSegmentation.nullish(),
})
/**
@ -1071,7 +1071,7 @@ export const zRule = z.object({
*/
export const zProcessRule = z.object({
mode: zProcessRuleMode,
rules: zRule.optional(),
rules: zRule.nullish(),
})
/**
@ -1121,7 +1121,7 @@ export const zSite = z.object({
icon: z.string().nullish(),
icon_background: z.string().nullish(),
icon_type: z.string().nullish(),
icon_url: z.string().readonly().nullable(),
icon_url: z.string().nullable(),
privacy_policy: z.string().nullish(),
show_workflow_steps: z.boolean(),
title: z.string(),
@ -1206,8 +1206,8 @@ export const zWeightVectorSetting = z.object({
* WeightModel
*/
export const zWeightModel = z.object({
keyword_setting: zWeightKeywordSetting.optional(),
vector_setting: zWeightVectorSetting.optional(),
keyword_setting: zWeightKeywordSetting.nullish(),
vector_setting: zWeightVectorSetting.nullish(),
weight_type: z.enum(['customized', 'keyword_first', 'semantic_first']).nullish(),
})
@ -1215,15 +1215,15 @@ export const zWeightModel = z.object({
* RetrievalModel
*/
export const zRetrievalModel = z.object({
metadata_filtering_conditions: zMetadataFilteringCondition.optional(),
metadata_filtering_conditions: zMetadataFilteringCondition.nullish(),
reranking_enable: z.boolean(),
reranking_mode: z.string().nullish(),
reranking_model: zRerankingModel.optional(),
reranking_model: zRerankingModel.nullish(),
score_threshold: z.number().nullish(),
score_threshold_enabled: z.boolean(),
search_method: zRetrievalMethod,
top_k: z.int(),
weights: zWeightModel.optional(),
weights: zWeightModel.nullish(),
})
/**
@ -1237,9 +1237,9 @@ export const zDatasetCreatePayload = z.object({
external_knowledge_id: z.string().nullish(),
indexing_technique: z.enum(['economy', 'high_quality']).nullish(),
name: z.string().min(1).max(40),
permission: zPermissionEnum.optional(),
permission: zPermissionEnum.nullish().default('only_me'),
provider: z.string().optional().default('vendor'),
retrieval_model: zRetrievalModel.optional(),
retrieval_model: zRetrievalModel.nullish(),
summary_index_setting: z.record(z.string(), z.unknown()).nullish(),
})
@ -1256,8 +1256,8 @@ export const zDatasetUpdatePayload = z.object({
indexing_technique: z.enum(['economy', 'high_quality']).nullish(),
name: z.string().min(1).max(40).nullish(),
partial_member_list: z.array(z.record(z.string(), z.string())).nullish(),
permission: zPermissionEnum.optional(),
retrieval_model: zRetrievalModel.optional(),
permission: zPermissionEnum.nullish(),
retrieval_model: zRetrievalModel.nullish(),
})
/**
@ -1271,8 +1271,8 @@ export const zDocumentTextCreatePayload = z.object({
indexing_technique: z.string().nullish(),
name: z.string(),
original_document_id: z.string().nullish(),
process_rule: zProcessRule.optional(),
retrieval_model: zRetrievalModel.optional(),
process_rule: zProcessRule.nullish(),
retrieval_model: zRetrievalModel.nullish(),
text: z.string(),
})
@ -1283,8 +1283,8 @@ export const zDocumentTextUpdate = z.object({
doc_form: z.string().optional().default('text_model'),
doc_language: z.string().optional().default('English'),
name: z.string().nullish(),
process_rule: zProcessRule.optional(),
retrieval_model: zRetrievalModel.optional(),
process_rule: zProcessRule.nullish(),
retrieval_model: zRetrievalModel.nullish(),
text: z.string().nullish(),
})
@ -1295,7 +1295,7 @@ export const zHitTestingPayload = z.object({
attachment_ids: z.array(z.string()).nullish(),
external_retrieval_model: z.record(z.string(), z.unknown()).nullish(),
query: z.string().max(250),
retrieval_model: zRetrievalModel.optional(),
retrieval_model: zRetrievalModel.nullish(),
})
/**
@ -1317,7 +1317,7 @@ export const zWorkflowLogQuery = z.object({
*/
export const zWorkflowRunForLogResponse = z.object({
created_at: z.int().nullish(),
elapsed_time: z.unknown().optional(),
elapsed_time: z.union([z.number(), z.int()]).nullish(),
error: z.string().nullish(),
exceptions_count: z.int().nullish(),
finished_at: z.int().nullish(),
@ -1334,13 +1334,22 @@ export const zWorkflowRunForLogResponse = z.object({
*/
export const zWorkflowAppLogPartialResponse = z.object({
created_at: z.int().nullish(),
created_by_account: zSimpleAccount.optional(),
created_by_end_user: zSimpleEndUser.optional(),
created_by_account: zSimpleAccount.nullish(),
created_by_end_user: zSimpleEndUser.nullish(),
created_by_role: z.string().nullish(),
created_from: z.string().nullish(),
details: z.unknown().optional(),
details: z
.union([
z.record(z.string(), z.unknown()),
z.array(z.unknown()),
z.string(),
z.int(),
z.number(),
z.boolean(),
])
.nullish(),
id: z.string(),
workflow_run: zWorkflowRunForLogResponse.optional(),
workflow_run: zWorkflowRunForLogResponse.nullish(),
})
/**
@ -1369,11 +1378,20 @@ export const zWorkflowRunPayload = z.object({
*/
export const zWorkflowRunResponse = z.object({
created_at: z.int().nullish(),
elapsed_time: z.unknown().optional(),
elapsed_time: z.union([z.number(), z.int()]).nullish(),
error: z.string().nullish(),
finished_at: z.int().nullish(),
id: z.string(),
inputs: z.unknown().optional(),
inputs: z
.union([
z.record(z.string(), z.unknown()),
z.array(z.unknown()),
z.string(),
z.int(),
z.number(),
z.boolean(),
])
.nullish(),
outputs: z.record(z.string(), z.unknown()).optional(),
status: z.string(),
total_steps: z.int().nullish(),
@ -1464,7 +1482,7 @@ export const zDeleteAppsAnnotationsByAnnotationIdPath = z.object({
/**
* Annotation deleted successfully
*/
export const zDeleteAppsAnnotationsByAnnotationIdResponse = z.record(z.string(), z.never())
export const zDeleteAppsAnnotationsByAnnotationIdResponse = z.void()
export const zPutAppsAnnotationsByAnnotationIdBody = zAnnotationCreatePayload
@ -1535,7 +1553,7 @@ export const zDeleteConversationsByCIdPath = z.object({
/**
* Conversation deleted successfully
*/
export const zDeleteConversationsByCIdResponse = z.record(z.string(), z.never())
export const zDeleteConversationsByCIdResponse = z.void()
export const zPostConversationsByCIdNameBody = zConversationRenamePayload
@ -1606,7 +1624,7 @@ export const zDeleteDatasetsTagsBody = zTagDeletePayload
/**
* Tag deleted successfully
*/
export const zDeleteDatasetsTagsResponse = z.record(z.string(), z.never())
export const zDeleteDatasetsTagsResponse = z.void()
/**
* Tags retrieved successfully
@ -1632,14 +1650,14 @@ export const zPostDatasetsTagsBindingBody = zTagBindingPayload
/**
* Tags bound successfully
*/
export const zPostDatasetsTagsBindingResponse = z.record(z.string(), z.never())
export const zPostDatasetsTagsBindingResponse = z.void()
export const zPostDatasetsTagsUnbindingBody = zTagUnbindingPayload
/**
* Tags unbound successfully
*/
export const zPostDatasetsTagsUnbindingResponse = z.record(z.string(), z.never())
export const zPostDatasetsTagsUnbindingResponse = z.void()
export const zDeleteDatasetsByDatasetIdPath = z.object({
dataset_id: z.string(),
@ -1648,7 +1666,7 @@ export const zDeleteDatasetsByDatasetIdPath = z.object({
/**
* Dataset deleted successfully
*/
export const zDeleteDatasetsByDatasetIdResponse = z.record(z.string(), z.never())
export const zDeleteDatasetsByDatasetIdResponse = z.void()
export const zGetDatasetsByDatasetIdPath = z.object({
dataset_id: z.string(),
@ -1790,10 +1808,7 @@ export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdPath = z.object({
/**
* Document deleted successfully
*/
export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse = z.void()
export const zGetDatasetsByDatasetIdDocumentsByDocumentIdPath = z.object({
dataset_id: z.string(),
@ -1872,10 +1887,7 @@ export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdP
/**
* Segment deleted successfully
*/
export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse = z.void()
export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath = z.object({
dataset_id: z.string(),
@ -1952,7 +1964,7 @@ export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdC
* Child chunk deleted successfully
*/
export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse
= z.record(z.string(), z.never())
= z.void()
export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdBody
= zChildChunkUpdatePayload
@ -2088,10 +2100,7 @@ export const zDeleteDatasetsByDatasetIdMetadataByMetadataIdPath = z.object({
/**
* Metadata deleted successfully
*/
export const zDeleteDatasetsByDatasetIdMetadataByMetadataIdResponse = z.record(
z.string(),
z.never(),
)
export const zDeleteDatasetsByDatasetIdMetadataByMetadataIdResponse = z.void()
export const zPatchDatasetsByDatasetIdMetadataByMetadataIdBody = zMetadataUpdatePayload

View File

@ -539,9 +539,7 @@ export type DeleteConversationsByCIdError
= DeleteConversationsByCIdErrors[keyof DeleteConversationsByCIdErrors]
export type DeleteConversationsByCIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteConversationsByCIdResponse
@ -1378,9 +1376,7 @@ export type DeleteSavedMessagesByMessageIdError
= DeleteSavedMessagesByMessageIdErrors[keyof DeleteSavedMessagesByMessageIdErrors]
export type DeleteSavedMessagesByMessageIdResponses = {
204: {
[key: string]: never
}
204: void
}
export type DeleteSavedMessagesByMessageIdResponse

View File

@ -213,8 +213,12 @@ export const zLicenseStatus = z.enum(['active', 'expired', 'expiring', 'inactive
*/
export const zLicenseModel = z.object({
expired_at: z.string().default(''),
status: zLicenseStatus,
workspaces: zLicenseLimitationModel,
status: zLicenseStatus.default('none'),
workspaces: zLicenseLimitationModel.default({
enabled: false,
limit: 0,
size: 0,
}),
})
/**
@ -271,7 +275,7 @@ export const zPluginInstallationScope = z.enum([
* PluginInstallationPermissionModel
*/
export const zPluginInstallationPermissionModel = z.object({
plugin_installation_scope: zPluginInstallationScope,
plugin_installation_scope: zPluginInstallationScope.default('all'),
restrict_to_marketplace_only: z.boolean().default(false),
})
@ -375,14 +379,20 @@ export const zWebAppAuthModel = z.object({
allow_email_password_login: z.boolean().default(false),
allow_sso: z.boolean().default(false),
enabled: z.boolean().default(false),
sso_config: zWebAppAuthSsoModel,
sso_config: zWebAppAuthSsoModel.default({ protocol: '' }),
})
/**
* SystemFeatureModel
*/
export const zSystemFeatureModel = z.object({
branding: zBrandingModel,
branding: zBrandingModel.default({
application_title: '',
enabled: false,
favicon: '',
login_page_logo: '',
workspace_logo: '',
}),
enable_change_email: z.boolean().default(true),
enable_collaboration_mode: z.boolean().default(true),
enable_creators_platform: z.boolean().default(false),
@ -395,13 +405,30 @@ export const zSystemFeatureModel = z.object({
is_allow_create_workspace: z.boolean().default(false),
is_allow_register: z.boolean().default(false),
is_email_setup: z.boolean().default(false),
license: zLicenseModel,
license: zLicenseModel.default({
expired_at: '',
status: 'none',
workspaces: {
enabled: false,
limit: 0,
size: 0,
},
}),
max_plugin_package_size: z.int().default(15728640),
plugin_installation_permission: zPluginInstallationPermissionModel,
plugin_manager: zPluginManagerModel,
plugin_installation_permission: zPluginInstallationPermissionModel.default({
plugin_installation_scope: 'all',
restrict_to_marketplace_only: false,
}),
plugin_manager: zPluginManagerModel.default({ enabled: false }),
sso_enforced_for_signin: z.boolean().default(false),
sso_enforced_for_signin_protocol: z.string().default(''),
webapp_auth: zWebAppAuthModel,
webapp_auth: zWebAppAuthModel.default({
allow_email_code_login: false,
allow_email_password_login: false,
allow_sso: false,
enabled: false,
sso_config: { protocol: '' },
}),
})
/**
@ -471,7 +498,7 @@ export const zDeleteConversationsByCIdPath = z.object({
/**
* Conversation deleted successfully
*/
export const zDeleteConversationsByCIdResponse = z.record(z.string(), z.never())
export const zDeleteConversationsByCIdResponse = z.void()
export const zPostConversationsByCIdNamePath = z.object({
c_id: z.string(),
@ -696,7 +723,7 @@ export const zDeleteSavedMessagesByMessageIdPath = z.object({
/**
* Message removed successfully
*/
export const zDeleteSavedMessagesByMessageIdResponse = z.record(z.string(), z.never())
export const zDeleteSavedMessagesByMessageIdResponse = z.void()
/**
* Success

View File

@ -7,23 +7,31 @@ import { $, defineConfig } from '@hey-api/openapi-ts'
type JsonObject = Record<string, unknown>
type SwaggerSchema = JsonObject & {
'$defs'?: Record<string, SwaggerSchema>
'$ref'?: string
'x-nullable'?: boolean
'additionalProperties'?: unknown
'allOf'?: SwaggerSchema[]
'anyOf'?: SwaggerSchema[]
'const'?: unknown
'default'?: unknown
'definitions'?: Record<string, SwaggerSchema>
'description'?: string
'enum'?: unknown[]
'format'?: string
'items'?: SwaggerSchema
'oneOf'?: SwaggerSchema[]
'properties'?: Record<string, SwaggerSchema>
'required'?: string[]
'type'?: string
$ref?: string
additionalProperties?: unknown
allOf?: SwaggerSchema[]
anyOf?: SwaggerSchema[]
description?: string
enum?: unknown[]
items?: SwaggerSchema
oneOf?: SwaggerSchema[]
properties?: Record<string, SwaggerSchema>
required?: string[]
type?: string
}
type OpenApiMediaType = JsonObject & {
schema?: SwaggerSchema
}
type OpenApiRequestBody = JsonObject & {
content?: Record<string, OpenApiMediaType>
description?: string
required?: boolean
}
type OpenApiComponents = JsonObject & {
schemas?: Record<string, SwaggerSchema>
}
type SwaggerParameter = JsonObject & {
@ -31,12 +39,11 @@ type SwaggerParameter = JsonObject & {
name?: string
required?: boolean
schema?: SwaggerSchema
type?: string
}
type SwaggerResponse = JsonObject & {
content?: Record<string, OpenApiMediaType>
description?: string
schema?: SwaggerSchema
}
type SwaggerOperation = JsonObject & {
@ -44,11 +51,13 @@ type SwaggerOperation = JsonObject & {
description?: string
operationId?: string
parameters?: SwaggerParameter[]
requestBody?: OpenApiRequestBody | null
responses?: Record<string, SwaggerResponse>
}
type SwaggerDocument = JsonObject & {
definitions?: Record<string, SwaggerSchema>
components?: OpenApiComponents
openapi?: string
paths?: Record<string, Record<string, unknown>>
}
@ -97,10 +106,10 @@ const requestBodyMethods = new Set(['delete', 'patch', 'post', 'put'])
const noBodyResponseStatuses = new Set(['204', '205', '304'])
const apiSpecs: ApiSpec[] = [
{ filename: 'console-swagger.json', name: 'console' },
{ filename: 'web-swagger.json', name: 'web' },
{ filename: 'service-swagger.json', name: 'service' },
{ filename: 'openapi-swagger.json', name: 'openapi' },
{ filename: 'console-openapi.json', name: 'console' },
{ filename: 'web-openapi.json', name: 'web' },
{ filename: 'service-openapi.json', name: 'service' },
{ filename: 'openapi-openapi.json', name: 'openapi' },
]
const inaccurateGeneratedContractDescription = 'Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.'
@ -115,13 +124,6 @@ const unknownObjectSchema = (): SwaggerSchema => ({
type: 'object',
})
const noContentSchema = (): SwaggerSchema => ({
// Hey API's Swagger 2.0 pipeline currently needs a response schema symbol even for no-content responses.
additionalProperties: false,
properties: {},
type: 'object',
})
const toWords = (value: string) => {
return value
.replace(/[{}]/g, '')
@ -190,6 +192,48 @@ const clone = <T>(value: T): T => {
return JSON.parse(JSON.stringify(value)) as T
}
const componentSchemaRefPrefix = '#/components/schemas/'
const schemaNameFromRef = (ref: string) => {
if (ref.startsWith(componentSchemaRefPrefix))
return ref.slice(componentSchemaRefPrefix.length)
return undefined
}
const getDocumentSchemas = (document: SwaggerDocument) => {
const components = document.components ??= {}
return components.schemas ??= {}
}
const firstContentSchema = (
content: Record<string, OpenApiMediaType> | undefined,
preferredMediaTypes: string[],
) => {
if (!isObject(content))
return undefined
for (const mediaType of preferredMediaTypes) {
const media = content[mediaType]
if (isObject(media?.schema))
return media.schema
}
for (const media of Object.values(content)) {
if (isObject(media?.schema))
return media.schema
}
return undefined
}
const getRequestBodySchema = (operation: SwaggerOperation) => {
return firstContentSchema(operation.requestBody?.content, ['application/json'])
}
const getResponseSchema = (response: SwaggerResponse) => {
return firstContentSchema(response.content, ['application/json'])
}
const apiOperationKey = (surface: string, method: string, routePath: string) => {
return `${surface}:${method.toLowerCase()}:${routePath}`
}
@ -358,7 +402,7 @@ const collectRuntimeBodyOperationKeys = () => {
const runtimeBodyOperationKeys = collectRuntimeBodyOperationKeys()
const collectDefinitionRefs = (value: unknown, refs: Set<string>, visited = new WeakSet<object>()) => {
const collectSchemaRefs = (value: unknown, refs: Set<string>, visited = new WeakSet<object>()) => {
if (!value || typeof value !== 'object')
return
@ -368,120 +412,38 @@ const collectDefinitionRefs = (value: unknown, refs: Set<string>, visited = new
visited.add(value)
if (Array.isArray(value)) {
value.forEach(item => collectDefinitionRefs(item, refs, visited))
value.forEach(item => collectSchemaRefs(item, refs, visited))
return
}
const objectValue = value as JsonObject
const ref = objectValue.$ref
if (typeof ref === 'string' && ref.startsWith('#/definitions/'))
refs.add(ref.slice('#/definitions/'.length))
Object.values(objectValue).forEach(item => collectDefinitionRefs(item, refs, visited))
}
const removeNullDefaults = (value: unknown, visited = new WeakSet<object>()) => {
if (!value || typeof value !== 'object' || visited.has(value))
return
visited.add(value)
if (Array.isArray(value)) {
value.forEach(item => removeNullDefaults(item, visited))
return
if (typeof ref === 'string') {
const refName = schemaNameFromRef(ref)
if (refName)
refs.add(refName)
}
const schema = value as SwaggerSchema
if (schema.default === null)
delete schema.default
Object.values(schema).forEach(item => removeNullDefaults(item, visited))
Object.values(objectValue).forEach(item => collectSchemaRefs(item, refs, visited))
}
const isNullSchema = (schema: SwaggerSchema) => {
return schema.type === 'null'
}
const normalizeNullableAnyOf = (value: unknown, visited = new WeakSet<object>()) => {
if (!value || typeof value !== 'object' || visited.has(value))
return
visited.add(value)
if (Array.isArray(value)) {
value.forEach(item => normalizeNullableAnyOf(item, visited))
return
}
const schema = value as SwaggerSchema
if (Array.isArray(schema.anyOf)) {
const nonNullSchemas = schema.anyOf.filter(item => !isNullSchema(item))
const hasNullSchema = nonNullSchemas.length !== schema.anyOf.length
if (hasNullSchema && nonNullSchemas.length === 1) {
const { anyOf: _anyOf, ...rest } = schema
Object.keys(schema).forEach(key => delete schema[key])
Object.assign(schema, rest, nonNullSchemas[0], { 'x-nullable': true })
}
}
Object.values(schema).forEach(item => normalizeNullableAnyOf(item, visited))
}
const hoistNestedDefinitions = (definitions: Record<string, SwaggerSchema>) => {
const visited = new WeakSet<object>()
const visit = (value: unknown) => {
if (!value || typeof value !== 'object' || visited.has(value))
return
visited.add(value)
if (Array.isArray(value)) {
value.forEach(visit)
return
}
const schema = value as SwaggerSchema
for (const key of ['$defs', 'definitions'] as const) {
const nestedDefinitions = schema[key]
if (!isObject(nestedDefinitions))
continue
for (const [name, nestedSchema] of Object.entries(nestedDefinitions)) {
definitions[name] ??= nestedSchema
visit(nestedSchema)
}
delete schema[key]
}
Object.values(schema).forEach(visit)
}
Object.values(definitions).forEach(visit)
}
const ensureReferencedDefinitions = (document: SwaggerDocument) => {
const definitions = document.definitions ??= {}
const refs = new Set<string>()
collectDefinitionRefs(document, refs)
for (const refName of refs)
definitions[refName] ??= unknownObjectSchema()
}
const resolveDefinitionRef = (
const resolveSchemaRef = (
schema: SwaggerSchema | undefined,
definitions: Record<string, SwaggerSchema>,
schemas: Record<string, SwaggerSchema>,
): SwaggerSchema | undefined => {
const ref = schema?.$ref
if (!ref?.startsWith('#/definitions/'))
if (!ref)
return schema
return definitions[ref.slice('#/definitions/'.length)] ?? schema
const refName = schemaNameFromRef(ref)
if (!refName)
return schema
return schemas[refName] ?? schema
}
const withoutNullableWrapper = (schema: SwaggerSchema | undefined): SwaggerSchema => {
@ -499,22 +461,6 @@ const withoutNullableWrapper = (schema: SwaggerSchema | undefined): SwaggerSchem
}
}
const isNullEnumItem = (item: unknown) => {
return isObject(item) && (item.type === 'null' || item.const === null)
}
const markNullableEnumSchema = (ctx: { schema: JsonObject }): undefined => {
const items = ctx.schema.items
if (ctx.schema['x-nullable'] !== true || !Array.isArray(items) || items.some(isNullEnumItem))
return undefined
// Hey API's enum visitors infer nullable from a null enum item, not x-nullable.
ctx.schema.items = [...items, { const: null, type: 'null' }]
return undefined
}
const queryParameterFromSchema = (
name: string,
schema: SwaggerSchema | undefined,
@ -525,45 +471,12 @@ const queryParameterFromSchema = (
in: 'query',
name,
required,
schema: querySchema,
}
if (querySchema.default !== undefined)
parameter.default = querySchema.default
if (querySchema.description)
parameter.description = querySchema.description
if (querySchema.enum)
parameter.enum = querySchema.enum
if (querySchema.format)
parameter.format = querySchema.format
if (querySchema.items)
parameter.items = querySchema.items
for (const key of [
'exclusiveMaximum',
'exclusiveMinimum',
'maxItems',
'maxLength',
'maximum',
'minItems',
'minLength',
'minimum',
'multipleOf',
'pattern',
'uniqueItems',
'x-nullable',
]) {
if (querySchema[key] !== undefined)
parameter[key] = querySchema[key]
}
parameter.type = ['array', 'boolean', 'integer', 'number', 'string'].includes(querySchema.type ?? '')
? querySchema.type
: 'string'
return parameter
}
@ -596,15 +509,12 @@ const mergeQueryParameter = (
const normalizeGetBodyParameters = (
operation: SwaggerOperation,
definitions: Record<string, SwaggerSchema>,
schemas: Record<string, SwaggerSchema>,
) => {
if (!Array.isArray(operation.parameters))
return
const bodyParameters: SwaggerParameter[] = []
const normalizedParameters: SwaggerParameter[] = []
for (const parameter of operation.parameters) {
for (const parameter of operation.parameters ?? []) {
if (parameter.in === 'body') {
bodyParameters.push(parameter)
continue
@ -613,8 +523,18 @@ const normalizeGetBodyParameters = (
normalizedParameters.push(parameter)
}
const requestBodySchema = getRequestBodySchema(operation)
if (requestBodySchema) {
bodyParameters.push({
in: 'body',
name: 'payload',
required: Boolean(operation.requestBody?.required),
schema: requestBodySchema,
})
}
for (const parameter of bodyParameters) {
const schema = resolveDefinitionRef(parameter.schema, definitions)
const schema = resolveSchemaRef(parameter.schema, schemas)
const properties = schema?.properties ?? {}
const required = new Set(schema?.required ?? [])
@ -627,6 +547,7 @@ const normalizeGetBodyParameters = (
}
operation.parameters = normalizedParameters
delete operation.requestBody
}
const normalizeResponses = (operation: SwaggerOperation) => {
@ -634,18 +555,26 @@ const normalizeResponses = (operation: SwaggerOperation) => {
for (const [status, response] of Object.entries(responses)) {
if (noBodyResponseStatuses.has(status)) {
response.schema = noContentSchema()
delete response.content
continue
}
if (!response.schema)
response.schema = unknownObjectSchema()
const schema = getResponseSchema(response) ?? unknownObjectSchema()
response.content = {
'application/json': {
schema,
},
}
}
if (!Object.keys(responses).some(status => /^2\d\d$/.test(status))) {
responses['200'] = {
content: {
'application/json': {
schema: unknownObjectSchema(),
},
},
description: 'Success',
schema: unknownObjectSchema(),
}
}
}
@ -678,7 +607,7 @@ const isLooseObjectSchema = (schema: SwaggerSchema) => {
const hasLooseSchema = (
schema: SwaggerSchema | undefined,
definitions: Record<string, SwaggerSchema>,
schemas: Record<string, SwaggerSchema>,
visitedRefs = new Set<string>(),
): boolean => {
if (!schema)
@ -688,37 +617,40 @@ const hasLooseSchema = (
return false
const ref = schema?.$ref
if (ref?.startsWith('#/definitions/')) {
const refName = ref.slice('#/definitions/'.length)
if (ref) {
const refName = schemaNameFromRef(ref)
if (!refName)
return false
if (visitedRefs.has(refName))
return false
return hasLooseSchema(definitions[refName], definitions, new Set([...visitedRefs, refName]))
return hasLooseSchema(schemas[refName], schemas, new Set([...visitedRefs, refName]))
}
const normalizedSchema = withoutNullableWrapper(schema)
for (const variants of [normalizedSchema.allOf, normalizedSchema.anyOf, normalizedSchema.oneOf]) {
if (Array.isArray(variants) && variants.some(item => !isNullSchema(item) && hasLooseSchema(item, definitions, visitedRefs)))
if (Array.isArray(variants) && variants.some(item => !isNullSchema(item) && hasLooseSchema(item, schemas, visitedRefs)))
return true
}
if (normalizedSchema.type === 'array')
return hasLooseSchema(normalizedSchema.items, definitions, visitedRefs)
return hasLooseSchema(normalizedSchema.items, schemas, visitedRefs)
if (isLooseObjectSchema(normalizedSchema))
return true
if (isObject(normalizedSchema.additionalProperties) && hasLooseSchema(normalizedSchema.additionalProperties, definitions, visitedRefs))
if (isObject(normalizedSchema.additionalProperties) && hasLooseSchema(normalizedSchema.additionalProperties, schemas, visitedRefs))
return true
return Object.values(normalizedSchema.properties ?? {})
.some(property => hasLooseSchema(property, definitions, visitedRefs))
.some(property => hasLooseSchema(property, schemas, visitedRefs))
}
const hasPossiblyInaccurateGeneratedContractTypes = (
operation: SwaggerOperation,
definitions: Record<string, SwaggerSchema>,
schemas: Record<string, SwaggerSchema>,
context: ApiOperationContext,
) => {
const successResponses = Object.entries(operation.responses ?? {})
@ -728,15 +660,17 @@ const hasPossiblyInaccurateGeneratedContractTypes = (
return true
const successResponsesWithBody = successResponses.filter(([status]) => !noBodyResponseStatuses.has(status))
if (successResponsesWithBody.some(([, response]) => hasLooseSchema(response.schema, definitions)))
if (successResponsesWithBody.some(([, response]) => hasLooseSchema(getResponseSchema(response), schemas)))
return true
if (context.runtimeBodyRequired && !operation.parameters?.some(parameter => parameter.in === 'body'))
const requestBodySchema = getRequestBodySchema(operation)
const legacyBodyParameter = operation.parameters?.find(parameter => parameter.in === 'body')
if (context.runtimeBodyRequired && !requestBodySchema && !legacyBodyParameter)
return true
return operation.parameters?.some((parameter) => {
return parameter.in === 'body' && hasLooseSchema(parameter.schema, definitions)
}) ?? false
const bodySchema = requestBodySchema ?? legacyBodyParameter?.schema
return bodySchema ? hasLooseSchema(bodySchema, schemas) : false
}
const appendOperationDescription = (operation: SwaggerOperation, description: string) => {
@ -766,7 +700,7 @@ const formatPercent = (ready: number, total: number) => {
}
const normalizeOperations = (document: SwaggerDocument, surface: string) => {
const definitions = document.definitions ??= {}
const schemas = getDocumentSchemas(document)
for (const [routePath, pathItem] of Object.entries(document.paths ?? {})) {
for (const [method, operation] of Object.entries(pathItem)) {
@ -776,17 +710,16 @@ const normalizeOperations = (document: SwaggerDocument, surface: string) => {
const swaggerOperation = operation as SwaggerOperation
swaggerOperation.operationId = operationId(method, routePath)
if (method === 'get')
normalizeGetBodyParameters(swaggerOperation, schemas)
normalizeResponses(swaggerOperation)
const hasPossiblyInaccurateTypes = hasPossiblyInaccurateGeneratedContractTypes(swaggerOperation, definitions, {
const hasPossiblyInaccurateTypes = hasPossiblyInaccurateGeneratedContractTypes(swaggerOperation, schemas, {
method,
routePath,
runtimeBodyRequired: runtimeBodyOperationKeys.has(apiOperationKey(surface, method, routePath)),
})
recordApiReadiness(surface, !hasPossiblyInaccurateTypes)
if (method === 'get')
normalizeGetBodyParameters(swaggerOperation, definitions)
if (hasPossiblyInaccurateTypes)
markPossiblyInaccurateGeneratedContract(swaggerOperation)
}
@ -794,14 +727,6 @@ const normalizeOperations = (document: SwaggerDocument, surface: string) => {
}
const normalizeApiSwagger = (document: SwaggerDocument, surface: string) => {
document.definitions ??= {}
// Flask-RESTX emits Pydantic nested $defs inside individual schemas while
// refs point at the root Swagger 2.0 definitions object.
hoistNestedDefinitions(document.definitions)
ensureReferencedDefinitions(document)
normalizeNullableAnyOf(document)
removeNullDefaults(document)
normalizeOperations(document, surface)
return document
@ -836,13 +761,13 @@ const topLevelPathSegment = (routePath: string) => {
return routePath.split('/').filter(Boolean)[0] ?? 'root'
}
const selectReferencedDefinitions = (
definitions: Record<string, SwaggerSchema>,
const selectReferencedSchemas = (
schemas: Record<string, SwaggerSchema>,
paths: Record<string, Record<string, unknown>>,
) => {
const selectedDefinitions: Record<string, SwaggerSchema> = {}
const selectedSchemas: Record<string, SwaggerSchema> = {}
const pendingRefs = new Set<string>()
collectDefinitionRefs(paths, pendingRefs)
collectSchemaRefs(paths, pendingRefs)
while (pendingRefs.size > 0) {
const refName = pendingRefs.values().next().value
@ -851,32 +776,36 @@ const selectReferencedDefinitions = (
pendingRefs.delete(refName)
if (selectedDefinitions[refName])
if (selectedSchemas[refName])
continue
selectedDefinitions[refName] = definitions[refName] ?? unknownObjectSchema()
selectedSchemas[refName] = schemas[refName] ?? unknownObjectSchema()
const nestedRefs = new Set<string>()
collectDefinitionRefs(selectedDefinitions[refName], nestedRefs)
collectSchemaRefs(selectedSchemas[refName], nestedRefs)
for (const nestedRef of nestedRefs) {
if (!selectedDefinitions[nestedRef])
if (!selectedSchemas[nestedRef])
pendingRefs.add(nestedRef)
}
}
return selectedDefinitions
return selectedSchemas
}
const cloneDocumentWithPaths = (
document: SwaggerDocument,
paths: Record<string, Record<string, unknown>>,
) => {
const { definitions: _definitions, paths: _paths, ...metadata } = document
const { components: _components, paths: _paths, ...metadata } = document
const clonedPaths = clone(paths)
const components = clone(document.components ?? {})
const sourceSchemas = getDocumentSchemas(document)
components.schemas = selectReferencedSchemas(sourceSchemas, clonedPaths)
return {
...clone(metadata),
definitions: selectReferencedDefinitions(document.definitions ?? {}, clonedPaths),
components,
paths: clonedPaths,
} satisfies SwaggerDocument
}
@ -977,16 +906,12 @@ const createApiConfig = (job: ApiJob): UserConfig => ({
},
plugins: job.plugins ?? [
{
'comments': false,
'name': '@hey-api/typescript',
'~resolvers': {
enum: markNullableEnumSchema,
},
comments: false,
name: '@hey-api/typescript',
},
{
'name': 'zod',
'~resolvers': {
enum: markNullableEnumSchema,
string: (ctx) => {
if (ctx.schema.format !== 'binary')
return undefined