diff --git a/.agents/skills/frontend-query-mutation/SKILL.md b/.agents/skills/frontend-query-mutation/SKILL.md index 49888bdb66..10c49d222e 100644 --- a/.agents/skills/frontend-query-mutation/SKILL.md +++ b/.agents/skills/frontend-query-mutation/SKILL.md @@ -1,6 +1,6 @@ --- name: frontend-query-mutation -description: Guide for implementing Dify frontend query and mutation patterns with TanStack Query and oRPC. Trigger when creating or updating contracts in web/contract, wiring router composition, consuming consoleQuery or marketplaceQuery in components or services, deciding whether to call queryOptions() directly or extract a helper or use-* hook, handling conditional queries, cache invalidation, mutation error handling, or migrating legacy service calls to contract-first query and mutation helpers. +description: Guide for implementing Dify frontend query and mutation patterns with TanStack Query and oRPC. Trigger when creating or updating contracts in web/contract, wiring router composition, consuming consoleQuery or marketplaceQuery in components or services, deciding whether to call queryOptions()/mutationOptions() directly or extract a helper or use-* hook, configuring oRPC experimental_defaults/default options, handling conditional queries, cache updates/invalidation, mutation error handling, or migrating legacy service calls to contract-first query and mutation helpers. --- # Frontend Query & Mutation @@ -9,22 +9,24 @@ description: Guide for implementing Dify frontend query and mutation patterns wi - Keep contract as the single source of truth in `web/contract/*`. - Prefer contract-shaped `queryOptions()` and `mutationOptions()`. -- Keep invalidation and mutation flow knowledge in the service layer. +- Keep default cache behavior with `consoleQuery`/`marketplaceQuery` setup, and keep business orchestration in feature vertical hooks when direct contract calls are not enough. +- Treat `web/service/use-*` query or mutation wrappers as legacy migration targets, not the preferred destination. - Keep abstractions minimal to preserve TypeScript inference. ## Workflow 1. Identify the change surface. - Read `references/contract-patterns.md` for contract files, router composition, client helpers, and query or mutation call-site shape. - - Read `references/runtime-rules.md` for conditional queries, invalidation, error handling, and legacy migrations. + - Read `references/runtime-rules.md` for conditional queries, default options, cache updates/invalidation, error handling, and legacy migrations. - Read both references when a task spans contract shape and runtime behavior. 2. Implement the smallest abstraction that fits the task. - Default to direct `useQuery(...)` or `useMutation(...)` calls with oRPC helpers at the call site. - Extract a small shared query helper only when multiple call sites share the same extra options. - - Create `web/service/use-{domain}.ts` only for orchestration or shared domain behavior. + - Create or keep feature hooks only for real orchestration or shared domain behavior. + - When touching thin `web/service/use-*` wrappers, migrate them away when feasible. 3. Preserve Dify conventions. - Keep contract inputs in `{ params, query?, body? }` shape. - - Bind invalidation in the service-layer mutation definition. + - Bind default cache updates/invalidation in `createTanstackQueryUtils(...experimental_defaults...)`; use feature hooks only for workflows that cannot be expressed as default operation behavior. - Prefer `mutate(...)`; use `mutateAsync(...)` only when Promise semantics are required. ## Files Commonly Touched @@ -33,7 +35,7 @@ description: Guide for implementing Dify frontend query and mutation patterns wi - `web/contract/marketplace.ts` - `web/contract/router.ts` - `web/service/client.ts` -- `web/service/use-*.ts` +- legacy `web/service/use-*.ts` files when migrating wrappers away - component and hook call sites using `consoleQuery` or `marketplaceQuery` ## References diff --git a/.agents/skills/frontend-query-mutation/agents/openai.yaml b/.agents/skills/frontend-query-mutation/agents/openai.yaml index 87f7ae6ea4..79e7e7d214 100644 --- a/.agents/skills/frontend-query-mutation/agents/openai.yaml +++ b/.agents/skills/frontend-query-mutation/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "Frontend Query & Mutation" - short_description: "Dify TanStack Query and oRPC patterns" - default_prompt: "Use this skill when implementing or reviewing Dify frontend contracts, query and mutation call sites, conditional queries, invalidation, or legacy query/mutation migrations." + short_description: "Dify TanStack Query, oRPC, and default option patterns" + default_prompt: "Use this skill when implementing or reviewing Dify frontend contracts, query and mutation call sites, oRPC default options, conditional queries, cache updates/invalidation, or legacy query/mutation migrations." diff --git a/.agents/skills/frontend-query-mutation/references/contract-patterns.md b/.agents/skills/frontend-query-mutation/references/contract-patterns.md index 08016ed2cc..25ccfc81d7 100644 --- a/.agents/skills/frontend-query-mutation/references/contract-patterns.md +++ b/.agents/skills/frontend-query-mutation/references/contract-patterns.md @@ -7,6 +7,7 @@ - Core workflow - Query usage decision rule - Mutation usage decision rule +- Thin hook decision rule - Anti-patterns - Contract rules - Type export @@ -55,9 +56,13 @@ const invoiceQuery = useQuery(consoleQuery.billing.invoices.queryOptions({ 1. Default to direct `*.queryOptions(...)` usage at the call site. 2. If 3 or more call sites share the same extra options, extract a small query helper, not a `use-*` passthrough hook. -3. Create `web/service/use-{domain}.ts` only for orchestration. +3. Create or keep feature hooks only for orchestration. - Combine multiple queries or mutations. - Share domain-level derived state or invalidation helpers. + - Prefer `web/features/{domain}/hooks/*` for feature-owned workflows. +4. Treat `web/service/use-{domain}.ts` as legacy. + - Do not create new thin service wrappers for oRPC contracts. + - When touching existing wrappers, inline direct `consoleQuery` or `marketplaceQuery` consumption when the wrapper is only a passthrough. ```typescript const invoicesBaseQueryOptions = () => @@ -74,11 +79,37 @@ const invoiceQuery = useQuery({ 1. Default to mutation helpers from `consoleQuery` or `marketplaceQuery`, for example `useMutation(consoleQuery.billing.bindPartnerStack.mutationOptions(...))`. 2. If the mutation flow is heavily custom, use oRPC clients as `mutationFn`, for example `consoleClient.xxx` or `marketplaceClient.xxx`, instead of handwritten non-oRPC mutation logic. +```typescript +const createTagMutation = useMutation(consoleQuery.tags.create.mutationOptions()) +``` + +## Thin Hook Decision Rule + +Remove thin hooks when they only rename a single oRPC query or mutation helper. +Keep hooks when they orchestrate business behavior across multiple operations, own local workflow state, or normalize a feature-specific API. +Prefer feature vertical hooks for kept orchestration. Do not move new contract-first wrappers into `web/service/use-*`. + +Use: + +```typescript +const deleteTagMutation = useMutation(consoleQuery.tags.delete.mutationOptions()) +``` + +Keep: + +```typescript +const applyTagBindingsMutation = useApplyTagBindingsMutation() +``` + +`useApplyTagBindingsMutation` is acceptable because it coordinates bind and unbind requests, computes deltas, and exposes a feature-level workflow rather than a single endpoint passthrough. + ## Anti-Patterns - Do not wrap `useQuery` with `options?: Partial`. - Do not split local `queryKey` and `queryFn` when oRPC `queryOptions` already exists and fits the use case. - Do not create thin `use-*` passthrough hooks for a single endpoint. +- Do not create business-layer helpers whose only purpose is to call `consoleQuery.xxx.mutationOptions()` or `queryOptions()`. +- Do not introduce new `web/service/use-*` files for oRPC contract passthroughs. - These patterns can degrade inference, especially around `throwOnError` and `select`, and add unnecessary indirection. ## Contract Rules diff --git a/.agents/skills/frontend-query-mutation/references/runtime-rules.md b/.agents/skills/frontend-query-mutation/references/runtime-rules.md index 73d6fbdded..91b484d438 100644 --- a/.agents/skills/frontend-query-mutation/references/runtime-rules.md +++ b/.agents/skills/frontend-query-mutation/references/runtime-rules.md @@ -3,6 +3,7 @@ ## Table of Contents - Conditional queries +- oRPC default options - Cache invalidation - Key API guide - `mutate` vs `mutateAsync` @@ -35,9 +36,50 @@ function useBadAccessMode(appId: string | undefined) { } ``` +## oRPC Default Options + +Use `experimental_defaults` in `createTanstackQueryUtils` when a contract operation should always carry shared TanStack Query behavior, such as default stale time, mutation cache writes, or invalidation. + +Place defaults at the query utility creation point in `web/service/client.ts`: + +```typescript +export const consoleQuery = createTanstackQueryUtils(consoleClient, { + path: ['console'], + experimental_defaults: { + tags: { + create: { + mutationOptions: { + onSuccess: (tag, _variables, _result, context) => { + context.client.setQueryData( + consoleQuery.tags.list.queryKey({ + input: { + query: { + type: tag.type, + }, + }, + }), + (oldTags: Tag[] | undefined) => oldTags ? [tag, ...oldTags] : oldTags, + ) + }, + }, + }, + }, + }, +}) +``` + +Rules: + +- Keep defaults inline in the `consoleQuery` or `marketplaceQuery` initialization when they need sibling oRPC key builders. +- Do not create a wrapper function solely to host `createTanstackQueryUtils`. +- Do not split defaults into a vertical feature file if that forces handwritten operation paths such as `generateOperationKey(['console', ...])`. +- Keep feature-level orchestration in the feature vertical; keep query utility lifecycle defaults with the query utility. +- Prefer call-site callbacks for UI feedback only; shared cache behavior belongs in oRPC defaults when it is tied to a contract operation. + ## Cache Invalidation -Bind invalidation in the service-layer mutation definition. +Bind shared invalidation in oRPC defaults when it is tied to a contract operation. +Use feature vertical hooks only for multi-operation workflows or domain orchestration that cannot live in a single operation default. Components may add UI feedback in call-site callbacks, but they should not decide which queries to invalidate. Use: @@ -49,7 +91,7 @@ Use: Do not use deprecated `useInvalid` from `use-base.ts`. ```typescript -// Service layer owns cache invalidation. +// Feature orchestration owns cache invalidation only when defaults are not enough. export const useUpdateAccessMode = () => { const queryClient = useQueryClient() @@ -124,7 +166,7 @@ When touching old code, migrate it toward these rules: | Old pattern | New pattern | |---|---| -| `useInvalid(key)` in service layer | `queryClient.invalidateQueries(...)` inside mutation `onSuccess` | -| component-triggered invalidation after mutation | move invalidation into the service-layer mutation definition | +| `useInvalid(key)` in service wrappers | oRPC defaults, or a feature vertical hook for real orchestration | +| component-triggered invalidation after mutation | move invalidation into oRPC defaults or a feature vertical hook | | imperative fetch plus manual invalidation | wrap it in `useMutation(...mutationOptions(...))` | | `await mutateAsync()` without `try/catch` | switch to `mutate(...)` or add `try/catch` | diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 94e857f93a..98b7e9f119 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,6 +6,9 @@ * @crazywoola @laipz8200 @Yeuoly +# ESLint suppression file is maintained by autofix.ci pruning. +/eslint-suppressions.json + # CODEOWNERS file /.github/CODEOWNERS @laipz8200 @crazywoola diff --git a/.github/actions/setup-web/action.yml b/.github/actions/setup-web/action.yml index 673155bcf7..085b39ebfb 100644 --- a/.github/actions/setup-web/action.yml +++ b/.github/actions/setup-web/action.yml @@ -4,7 +4,7 @@ runs: using: composite steps: - name: Setup Vite+ - uses: voidzero-dev/setup-vp@20553a7a7429c429a74894104a2835d7fed28a72 # v1.3.0 + uses: voidzero-dev/setup-vp@4f5aa3e38c781f1b01e78fb9255527cee8a6efa6 # v1.8.0 with: node-version-file: .nvmrc cache: true diff --git a/.github/labeler.yml b/.github/labeler.yml index 3b9dc24749..e226bafccc 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -6,5 +6,4 @@ web: - 'package.json' - 'pnpm-lock.yaml' - 'pnpm-workspace.yaml' - - '.npmrc' - '.nvmrc' diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index 8a1719da3c..76fbd18f47 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -43,7 +43,6 @@ jobs: package.json pnpm-lock.yaml pnpm-workspace.yaml - .npmrc .nvmrc - name: Check api inputs if: github.event_name != 'merge_group' @@ -114,7 +113,7 @@ jobs: find . -name "*.py.bak" -type f -delete - name: Setup web environment - if: github.event_name != 'merge_group' && steps.web-changes.outputs.any_changed == 'true' + if: github.event_name != 'merge_group' uses: ./.github/actions/setup-web - name: ESLint autofix diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 2d8bde8080..915ed6cfe8 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -74,7 +74,7 @@ jobs: password: ${{ env.DOCKERHUB_TOKEN }} - name: Set up Depot CLI - uses: depot/setup-action@v1 + uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1 - name: Extract metadata for Docker id: meta @@ -84,7 +84,7 @@ jobs: - name: Build Docker image id: build - uses: depot/build-push-action@v1 + uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0 with: project: ${{ vars.DEPOT_PROJECT_ID }} context: ${{ matrix.build_context }} @@ -124,10 +124,10 @@ jobs: file: "web/Dockerfile" steps: - name: Set up Docker Buildx - uses: docker/setup-buildx-action@98e3b2c9eab4f4f98a95c0c0a3ea5e5e672fd2a8 # v3.10.0 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Validate Docker image - uses: docker/build-push-action@5cd29d66b4a8d8e6f4d5dfe2e9329f0b1d446289 # v6.18.0 + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 with: push: false context: ${{ matrix.build_context }} diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index b0022b863b..5144510be5 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -44,10 +44,10 @@ jobs: file: "web/Dockerfile" steps: - name: Set up Depot CLI - uses: depot/setup-action@v1 + uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1 - name: Build Docker Image - uses: depot/build-push-action@v1 + uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0 with: project: ${{ vars.DEPOT_PROJECT_ID }} push: false @@ -71,10 +71,10 @@ jobs: file: "web/Dockerfile" steps: - name: Set up Docker Buildx - uses: docker/setup-buildx-action@98e3b2c9eab4f4f98a95c0c0a3ea5e5e672fd2a8 # v3.10.0 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Build Docker Image - uses: docker/build-push-action@5cd29d66b4a8d8e6f4d5dfe2e9329f0b1d446289 # v6.18.0 + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 with: push: false context: ${{ matrix.context }} diff --git a/.github/workflows/main-ci.yml b/.github/workflows/main-ci.yml index 278f2ed8d1..8071d6204d 100644 --- a/.github/workflows/main-ci.yml +++ b/.github/workflows/main-ci.yml @@ -69,7 +69,6 @@ jobs: - 'package.json' - 'pnpm-lock.yaml' - 'pnpm-workspace.yaml' - - '.npmrc' - '.nvmrc' - '.github/workflows/web-tests.yml' - '.github/actions/setup-web/**' @@ -83,7 +82,6 @@ jobs: - 'package.json' - 'pnpm-lock.yaml' - 'pnpm-workspace.yaml' - - '.npmrc' - '.nvmrc' - 'docker/docker-compose.middleware.yaml' - 'docker/middleware.env.example' diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 6b00899cf0..4ce121ba60 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -83,7 +83,6 @@ jobs: package.json pnpm-lock.yaml pnpm-workspace.yaml - .npmrc .nvmrc .github/workflows/style.yml .github/actions/setup-web/** diff --git a/.github/workflows/tool-test-sdks.yaml b/.github/workflows/tool-test-sdks.yaml index 79fddb1853..adaf99f33a 100644 --- a/.github/workflows/tool-test-sdks.yaml +++ b/.github/workflows/tool-test-sdks.yaml @@ -9,7 +9,6 @@ on: - package.json - pnpm-lock.yaml - pnpm-workspace.yaml - - .npmrc concurrency: group: sdk-tests-${{ github.head_ref || github.run_id }} diff --git a/.github/workflows/translate-i18n-claude.yml b/.github/workflows/translate-i18n-claude.yml index 5f48c22c56..7bb6fc1bbd 100644 --- a/.github/workflows/translate-i18n-claude.yml +++ b/.github/workflows/translate-i18n-claude.yml @@ -158,7 +158,7 @@ jobs: - name: Run Claude Code for Translation Sync if: steps.context.outputs.CHANGED_FILES != '' - uses: anthropics/claude-code-action@567fe954a4527e81f132d87d1bdbcc94f7737434 # v1.0.107 + uses: anthropics/claude-code-action@fefa07e9c665b7320f08c3b525980457f22f58aa # v1.0.111 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 836bddbb49..dc3b3f284f 100644 --- a/.gitignore +++ b/.gitignore @@ -219,6 +219,9 @@ node_modules # plugin migrate plugins.jsonl +# generated API OpenAPI specs +packages/contracts/openapi/ + # mise mise.toml diff --git a/.npmrc b/.npmrc deleted file mode 100644 index cffe8cdef1..0000000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -save-exact=true diff --git a/README.md b/README.md index 778028fc76..e6f8d84931 100644 --- a/README.md +++ b/README.md @@ -76,10 +76,11 @@ The easiest way to start the Dify server is through [Docker Compose](docker/dock ```bash cd dify cd docker -cp .env.example .env -docker compose up -d +./dify-compose up -d ``` +On Windows PowerShell, run `.\dify-compose.ps1 up -d` from the `docker` directory. + After running, you can access the Dify dashboard in your browser at [http://localhost/install](http://localhost/install) and start the initialization process. #### Seeking help @@ -137,7 +138,7 @@ Star Dify on GitHub and be instantly notified of new releases. ### Custom configurations -If you need to customize the configuration, please refer to the comments in our [.env.example](docker/.env.example) file and update the corresponding values in your `.env` file. Additionally, you might need to make adjustments to the `docker-compose.yaml` file itself, such as changing image versions, port mappings, or volume mounts, based on your specific deployment environment and requirements. After making any changes, please re-run `docker compose up -d`. You can find the full list of available environment variables [here](https://docs.dify.ai/getting-started/install-self-hosted/environments). +If you need to customize the configuration, add only the values you want to override to `docker/.env`. The default values live in [`docker/.env.default`](docker/.env.default), and the full reference remains in [`docker/.env.example`](docker/.env.example). After making any changes, re-run `./dify-compose up -d` or `.\dify-compose.ps1 up -d` from the `docker` directory. You can find the full list of available environment variables [here](https://docs.dify.ai/getting-started/install-self-hosted/environments). ### Metrics Monitoring with Grafana diff --git a/api/commands/account.py b/api/commands/account.py index 761323a73d..0d99ce7a0f 100644 --- a/api/commands/account.py +++ b/api/commands/account.py @@ -113,8 +113,18 @@ def create_tenant(email: str, language: str | None = None, name: str | None = No # Validates name encoding for non-Latin characters. name = name.strip().encode("utf-8").decode("utf-8") if name else None - # generate random password - new_password = secrets.token_urlsafe(16) + # Generate a random password that satisfies the password policy. + # The iteration limit guards against infinite loops caused by unexpected bugs in valid_password. + for _ in range(100): + new_password = secrets.token_urlsafe(16) + try: + valid_password(new_password) + break + except Exception: + continue + else: + click.echo(click.style("Failed to generate a valid password. Please try again.", fg="red")) + return # register account account = RegisterService.register( diff --git a/api/controllers/common/helpers.py b/api/controllers/common/helpers.py index ef89e66980..84903733b5 100644 --- a/api/controllers/common/helpers.py +++ b/api/controllers/common/helpers.py @@ -41,7 +41,8 @@ def guess_file_info_from_response(response: httpx.Response): # Try to extract filename from URL parsed_url = urllib.parse.urlparse(url) url_path = parsed_url.path - filename = os.path.basename(url_path) + # Decode percent-encoded characters in the path segment + filename = urllib.parse.unquote(os.path.basename(url_path)) # If filename couldn't be extracted, use Content-Disposition header if not filename: diff --git a/api/controllers/console/app/app.py b/api/controllers/console/app/app.py index a736fc8bc8..c8334bfd18 100644 --- a/api/controllers/console/app/app.py +++ b/api/controllers/console/app/app.py @@ -1,4 +1,5 @@ import logging +import re import uuid from datetime import datetime from typing import Any, Literal @@ -8,6 +9,7 @@ from flask_restx import Resource from pydantic import AliasChoices, BaseModel, Field, computed_field, field_validator from sqlalchemy import select from sqlalchemy.orm import Session +from werkzeug.datastructures import MultiDict from werkzeug.exceptions import BadRequest from controllers.common.helpers import FileInfo @@ -57,6 +59,7 @@ ALLOW_CREATE_APP_MODES = ["chat", "agent-chat", "advanced-chat", "workflow", "co register_enum_models(console_ns, IconType) _logger = logging.getLogger(__name__) +_TAG_IDS_BRACKET_PATTERN = re.compile(r"^tag_ids\[(\d+)\]$") class AppListQuery(BaseModel): @@ -66,22 +69,19 @@ class AppListQuery(BaseModel): default="all", description="App mode filter" ) name: str | None = Field(default=None, description="Filter by app name") - tag_ids: list[str] | None = Field(default=None, description="Comma-separated tag IDs") + tag_ids: list[str] | None = Field(default=None, description="Filter by tag IDs") is_created_by_me: bool | None = Field(default=None, description="Filter by creator") @field_validator("tag_ids", mode="before") @classmethod - def validate_tag_ids(cls, value: str | list[str] | None) -> list[str] | None: + def validate_tag_ids(cls, value: list[str] | None) -> list[str] | None: if not value: return None - if isinstance(value, str): - items = [item.strip() for item in value.split(",") if item.strip()] - elif isinstance(value, list): - items = [str(item).strip() for item in value if item and str(item).strip()] - else: - raise TypeError("Unsupported tag_ids type.") + if not isinstance(value, list): + raise ValueError("Unsupported tag_ids type.") + items = [str(item).strip() for item in value if item and str(item).strip()] if not items: return None @@ -91,6 +91,26 @@ class AppListQuery(BaseModel): raise ValueError("Invalid UUID format in tag_ids.") from exc +def _normalize_app_list_query_args(query_args: MultiDict[str, str]) -> dict[str, str | list[str]]: + normalized: dict[str, str | list[str]] = {} + indexed_tag_ids: list[tuple[int, str]] = [] + + for key in query_args: + match = _TAG_IDS_BRACKET_PATTERN.fullmatch(key) + if match: + indexed_tag_ids.extend((int(match.group(1)), value) for value in query_args.getlist(key)) + continue + + value = query_args.get(key) + if value is not None: + normalized[key] = value + + if indexed_tag_ids: + normalized["tag_ids"] = [value for _, value in sorted(indexed_tag_ids)] + + return normalized + + class CreateAppPayload(BaseModel): name: str = Field(..., min_length=1, description="App name") description: str | None = Field(default=None, description="App description (max 400 chars)", max_length=400) @@ -455,7 +475,7 @@ class AppListApi(Resource): """Get app list""" current_user, current_tenant_id = current_account_with_tenant() - args = AppListQuery.model_validate(request.args.to_dict(flat=True)) # type: ignore + args = AppListQuery.model_validate(_normalize_app_list_query_args(request.args)) args_dict = args.model_dump() # get app list diff --git a/api/controllers/console/app/workflow.py b/api/controllers/console/app/workflow.py index 478f783eb0..68dd8b7a8d 100644 --- a/api/controllers/console/app/workflow.py +++ b/api/controllers/console/app/workflow.py @@ -60,7 +60,8 @@ _file_access_controller = DatabaseFileAccessController() LISTENING_RETRY_IN = 2000 DEFAULT_REF_TEMPLATE_SWAGGER_2_0 = "#/definitions/{model}" RESTORE_SOURCE_WORKFLOW_MUST_BE_PUBLISHED_MESSAGE = "source workflow must be published" -MAX_WORKFLOW_ONLINE_USERS_QUERY_IDS = 50 +MAX_WORKFLOW_ONLINE_USERS_REQUEST_IDS = 1000 +WORKFLOW_ONLINE_USERS_REDIS_BATCH_SIZE = 50 # Register models for flask_restx to avoid dict type issues in Swagger # Register in dependency order: base models first, then dependent models @@ -158,8 +159,13 @@ class WorkflowFeaturesPayload(BaseModel): features: dict[str, Any] = Field(..., description="Workflow feature configuration") -class WorkflowOnlineUsersQuery(BaseModel): - app_ids: str = Field(..., description="Comma-separated app IDs") +class WorkflowOnlineUsersPayload(BaseModel): + app_ids: list[str] = Field(default_factory=list, description="App IDs") + + @field_validator("app_ids") + @classmethod + def normalize_app_ids(cls, app_ids: list[str]) -> list[str]: + return list(dict.fromkeys(app_id.strip() for app_id in app_ids if app_id.strip())) class DraftWorkflowTriggerRunPayload(BaseModel): @@ -186,7 +192,7 @@ reg(ConvertToWorkflowPayload) reg(WorkflowListQuery) reg(WorkflowUpdatePayload) reg(WorkflowFeaturesPayload) -reg(WorkflowOnlineUsersQuery) +reg(WorkflowOnlineUsersPayload) reg(DraftWorkflowTriggerRunPayload) reg(DraftWorkflowTriggerRunAllPayload) @@ -1384,19 +1390,19 @@ class DraftWorkflowTriggerRunAllApi(Resource): @console_ns.route("/apps/workflows/online-users") class WorkflowOnlineUsersApi(Resource): - @console_ns.expect(console_ns.models[WorkflowOnlineUsersQuery.__name__]) + @console_ns.expect(console_ns.models[WorkflowOnlineUsersPayload.__name__]) @console_ns.doc("get_workflow_online_users") @console_ns.doc(description="Get workflow online users") @setup_required @login_required @account_initialization_required @marshal_with(online_user_list_fields) - def get(self): - args = WorkflowOnlineUsersQuery.model_validate(request.args.to_dict(flat=True)) # type: ignore + def post(self): + args = WorkflowOnlineUsersPayload.model_validate(console_ns.payload or {}) - app_ids = list(dict.fromkeys(app_id.strip() for app_id in args.app_ids.split(",") if app_id.strip())) - if len(app_ids) > MAX_WORKFLOW_ONLINE_USERS_QUERY_IDS: - raise BadRequest(f"Maximum {MAX_WORKFLOW_ONLINE_USERS_QUERY_IDS} app_ids are allowed per request.") + app_ids = args.app_ids + if len(app_ids) > MAX_WORKFLOW_ONLINE_USERS_REQUEST_IDS: + raise BadRequest(f"Maximum {MAX_WORKFLOW_ONLINE_USERS_REQUEST_IDS} app_ids are allowed per request.") if not app_ids: return {"data": []} @@ -1404,13 +1410,24 @@ class WorkflowOnlineUsersApi(Resource): _, current_tenant_id = current_account_with_tenant() workflow_service = WorkflowService() accessible_app_ids = workflow_service.get_accessible_app_ids(app_ids, current_tenant_id) + ordered_accessible_app_ids = [app_id for app_id in app_ids if app_id in accessible_app_ids] + + users_json_by_app_id: dict[str, Any] = {} + for start_index in range(0, len(ordered_accessible_app_ids), WORKFLOW_ONLINE_USERS_REDIS_BATCH_SIZE): + app_id_batch = ordered_accessible_app_ids[ + start_index : start_index + WORKFLOW_ONLINE_USERS_REDIS_BATCH_SIZE + ] + pipe = redis_client.pipeline(transaction=False) + for app_id in app_id_batch: + pipe.hgetall(f"{WORKFLOW_ONLINE_USERS_PREFIX}{app_id}") + + users_json_batch = pipe.execute() + for app_id, users_json in zip(app_id_batch, users_json_batch): + users_json_by_app_id[app_id] = users_json results = [] - for app_id in app_ids: - if app_id not in accessible_app_ids: - continue - - users_json = redis_client.hgetall(f"{WORKFLOW_ONLINE_USERS_PREFIX}{app_id}") + for app_id in ordered_accessible_app_ids: + users_json = users_json_by_app_id.get(app_id, {}) users = [] for _, user_info_json in users_json.items(): diff --git a/api/controllers/console/app/workflow_draft_variable.py b/api/controllers/console/app/workflow_draft_variable.py index e32ba5f66c..c688a69074 100644 --- a/api/controllers/console/app/workflow_draft_variable.py +++ b/api/controllers/console/app/workflow_draft_variable.py @@ -75,14 +75,15 @@ console_ns.schema_model( def _convert_values_to_json_serializable_object(value: Segment): - if isinstance(value, FileSegment): - return value.value.model_dump() - elif isinstance(value, ArrayFileSegment): - return [i.model_dump() for i in value.value] - elif isinstance(value, SegmentGroup): - return [_convert_values_to_json_serializable_object(i) for i in value.value] - else: - return value.value + match value: + case FileSegment(): + return value.value.model_dump() + case ArrayFileSegment(): + return [i.model_dump() for i in value.value] + case SegmentGroup(): + return [_convert_values_to_json_serializable_object(i) for i in value.value] + case _: + return value.value def _serialize_var_value(variable: WorkflowDraftVariable): diff --git a/api/controllers/console/tag/tags.py b/api/controllers/console/tag/tags.py index f73e2da54e..b9e876c906 100644 --- a/api/controllers/console/tag/tags.py +++ b/api/controllers/console/tag/tags.py @@ -32,12 +32,7 @@ class TagBindingPayload(BaseModel): class TagBindingRemovePayload(BaseModel): - tag_id: str = Field(description="Tag ID to remove") - target_id: str = Field(description="Target ID to unbind tag from") - type: TagType = Field(description="Tag type") - - -class TagBindingItemDeletePayload(BaseModel): + tag_ids: list[str] = Field(description="Tag IDs to remove", min_length=1) target_id: str = Field(description="Target ID to unbind tag from") type: TagType = Field(description="Tag type") @@ -75,7 +70,6 @@ register_schema_models( TagBasePayload, TagBindingPayload, TagBindingRemovePayload, - TagBindingItemDeletePayload, TagListQueryParam, TagResponse, ) @@ -184,13 +178,13 @@ def _create_tag_bindings() -> tuple[dict[str, str], int]: return {"result": "success"}, 200 -def _remove_tag_binding() -> tuple[dict[str, str], int]: +def _remove_tag_bindings() -> tuple[dict[str, str], int]: _require_tag_binding_edit_permission() payload = TagBindingRemovePayload.model_validate(console_ns.payload or {}) TagService.delete_tag_binding( TagBindingDeletePayload( - tag_id=payload.tag_id, + tag_ids=payload.tag_ids, target_id=payload.target_id, type=payload.type, ) @@ -211,54 +205,15 @@ class TagBindingCollectionApi(Resource): return _create_tag_bindings() -@console_ns.route("/tag-bindings/") -class TagBindingItemApi(Resource): - """Canonical item resource for tag binding deletion.""" - - @console_ns.doc("delete_tag_binding") - @console_ns.doc(params={"id": "Tag ID"}) - @console_ns.expect(console_ns.models[TagBindingItemDeletePayload.__name__]) - @setup_required - @login_required - @account_initialization_required - def delete(self, id): - _require_tag_binding_edit_permission() - payload = TagBindingItemDeletePayload.model_validate(console_ns.payload or {}) - TagService.delete_tag_binding( - TagBindingDeletePayload( - tag_id=str(id), - target_id=payload.target_id, - type=payload.type, - ) - ) - return {"result": "success"}, 200 - - -@console_ns.route("/tag-bindings/create") -class DeprecatedTagBindingCreateApi(Resource): - """Deprecated verb-based alias for tag binding creation.""" - - @console_ns.doc("create_tag_binding_deprecated") - @console_ns.doc(deprecated=True) - @console_ns.doc(description="Deprecated legacy alias. Use POST /tag-bindings instead.") - @console_ns.expect(console_ns.models[TagBindingPayload.__name__]) - @setup_required - @login_required - @account_initialization_required - def post(self): - return _create_tag_bindings() - - @console_ns.route("/tag-bindings/remove") -class DeprecatedTagBindingRemoveApi(Resource): - """Deprecated verb-based alias for tag binding deletion.""" +class TagBindingRemoveApi(Resource): + """Batch resource for tag binding deletion.""" - @console_ns.doc("delete_tag_binding_deprecated") - @console_ns.doc(deprecated=True) - @console_ns.doc(description="Deprecated legacy alias. Use DELETE /tag-bindings/{id} instead.") + @console_ns.doc("remove_tag_bindings") + @console_ns.doc(description="Remove one or more tag bindings from a target.") @console_ns.expect(console_ns.models[TagBindingRemovePayload.__name__]) @setup_required @login_required @account_initialization_required def post(self): - return _remove_tag_binding() + return _remove_tag_bindings() diff --git a/api/controllers/console/workspace/account.py b/api/controllers/console/workspace/account.py index c01286cc59..d69a59ecb7 100644 --- a/api/controllers/console/workspace/account.py +++ b/api/controllers/console/workspace/account.py @@ -8,6 +8,7 @@ from flask import request from flask_restx import Resource from pydantic import BaseModel, Field, field_validator, model_validator from sqlalchemy import select +from werkzeug.exceptions import NotFound from configs import dify_config from constants.languages import supported_language @@ -45,6 +46,8 @@ from libs.helper import EmailStr, extract_remote_ip, timezone from libs.login import current_account_with_tenant, login_required from models import AccountIntegrate, InvitationCode from models.account import AccountStatus, InvitationCodeStatus +from models.enums import CreatorUserRole +from models.model import UploadFile from services.account_service import AccountService from services.billing_service import BillingService from services.errors.account import CurrentPasswordIncorrectError as ServiceCurrentPasswordIncorrectError @@ -322,9 +325,24 @@ class AccountAvatarApi(Resource): @login_required @account_initialization_required def get(self): + current_user, current_tenant_id = current_account_with_tenant() args = AccountAvatarQuery.model_validate(request.args.to_dict(flat=True)) # type: ignore + avatar = args.avatar - avatar_url = file_helpers.get_signed_file_url(args.avatar) + if avatar.startswith(("http://", "https://")): + return {"avatar_url": avatar} + + upload_file = db.session.scalar(select(UploadFile).where(UploadFile.id == avatar).limit(1)) + if upload_file is None: + raise NotFound("Avatar file not found") + + if upload_file.tenant_id != current_tenant_id: + raise NotFound("Avatar file not found") + + if upload_file.created_by_role != CreatorUserRole.ACCOUNT or upload_file.created_by != current_user.id: + raise NotFound("Avatar file not found") + + avatar_url = file_helpers.get_signed_file_url(upload_file_id=upload_file.id) return {"avatar_url": avatar_url} @console_ns.expect(console_ns.models[AccountAvatarPayload.__name__]) diff --git a/api/controllers/service_api/dataset/dataset.py b/api/controllers/service_api/dataset/dataset.py index 76519cad0a..3eb773fa7c 100644 --- a/api/controllers/service_api/dataset/dataset.py +++ b/api/controllers/service_api/dataset/dataset.py @@ -2,7 +2,7 @@ from typing import Any, Literal, cast from flask import request from flask_restx import marshal -from pydantic import BaseModel, Field, TypeAdapter, field_validator +from pydantic import BaseModel, Field, TypeAdapter, field_validator, model_validator from werkzeug.exceptions import Forbidden, NotFound import services @@ -100,9 +100,27 @@ class TagBindingPayload(BaseModel): class TagUnbindingPayload(BaseModel): - tag_id: str + """Accept the legacy single-tag Service API payload while exposing a normalized tag_ids list internally.""" + + tag_ids: list[str] = Field(default_factory=list) + tag_id: str | None = None target_id: str + @model_validator(mode="before") + @classmethod + def normalize_legacy_tag_id(cls, data: object) -> object: + if not isinstance(data, dict): + return data + if not data.get("tag_ids") and data.get("tag_id"): + return {**data, "tag_ids": [data["tag_id"]]} + return data + + @model_validator(mode="after") + def validate_tag_ids(self) -> "TagUnbindingPayload": + if not self.tag_ids: + raise ValueError("Tag IDs is required.") + return self + class DatasetListQuery(BaseModel): page: int = Field(default=1, description="Page number") @@ -601,11 +619,11 @@ class DatasetTagBindingApi(DatasetApiResource): @service_api_ns.route("/datasets/tags/unbinding") class DatasetTagUnbindingApi(DatasetApiResource): @service_api_ns.expect(service_api_ns.models[TagUnbindingPayload.__name__]) - @service_api_ns.doc("unbind_dataset_tag") - @service_api_ns.doc(description="Unbind a tag from a dataset") + @service_api_ns.doc("unbind_dataset_tags") + @service_api_ns.doc(description="Unbind tags from a dataset") @service_api_ns.doc( responses={ - 204: "Tag unbound successfully", + 204: "Tags unbound successfully", 401: "Unauthorized - invalid API token", 403: "Forbidden - insufficient permissions", } @@ -618,7 +636,7 @@ class DatasetTagUnbindingApi(DatasetApiResource): payload = TagUnbindingPayload.model_validate(service_api_ns.payload or {}) TagService.delete_tag_binding( - TagBindingDeletePayload(tag_id=payload.tag_id, target_id=payload.target_id, type=TagType.KNOWLEDGE) + TagBindingDeletePayload(tag_ids=payload.tag_ids, target_id=payload.target_id, type=TagType.KNOWLEDGE) ) return "", 204 diff --git a/api/controllers/service_api/dataset/document.py b/api/controllers/service_api/dataset/document.py index bc28ecb6b7..0b09facf58 100644 --- a/api/controllers/service_api/dataset/document.py +++ b/api/controllers/service_api/dataset/document.py @@ -468,15 +468,98 @@ class DocumentAddByFileApi(DatasetApiResource): return documents_and_batch_fields, 200 +def _update_document_by_file(tenant_id: str, dataset_id: UUID, document_id: UUID) -> tuple[Mapping[str, object], int]: + """Update a document from an uploaded file for canonical and deprecated routes.""" + dataset_id_str = str(dataset_id) + tenant_id_str = str(tenant_id) + dataset = db.session.scalar( + select(Dataset).where(Dataset.tenant_id == tenant_id_str, Dataset.id == dataset_id_str).limit(1) + ) + + if not dataset: + raise ValueError("Dataset does not exist.") + + if dataset.provider == "external": + raise ValueError("External datasets are not supported.") + + args: dict[str, object] = {} + if "data" in request.form: + args = json.loads(request.form["data"]) + if "doc_form" not in args: + args["doc_form"] = dataset.chunk_structure or "text_model" + if "doc_language" not in args: + args["doc_language"] = "English" + + # indexing_technique is already set in dataset since this is an update + args["indexing_technique"] = dataset.indexing_technique + + if "file" in request.files: + # save file info + file = request.files["file"] + + if len(request.files) > 1: + raise TooManyFilesError() + + if not file.filename: + raise FilenameNotExistsError + + if not current_user: + raise ValueError("current_user is required") + + try: + upload_file = FileService(db.engine).upload_file( + filename=file.filename, + content=file.read(), + mimetype=file.mimetype, + user=current_user, + source="datasets", + ) + except services.errors.file.FileTooLargeError as file_too_large_error: + raise FileTooLargeError(file_too_large_error.description) + except services.errors.file.UnsupportedFileTypeError: + raise UnsupportedFileTypeError() + data_source = { + "type": "upload_file", + "info_list": {"data_source_type": "upload_file", "file_info_list": {"file_ids": [upload_file.id]}}, + } + args["data_source"] = data_source + + # validate args + args["original_document_id"] = str(document_id) + + knowledge_config = KnowledgeConfig.model_validate(args) + DocumentService.document_create_args_validate(knowledge_config) + + try: + documents, _ = DocumentService.save_document_with_dataset_id( + dataset=dataset, + knowledge_config=knowledge_config, + account=dataset.created_by_account, + dataset_process_rule=dataset.latest_process_rule if "process_rule" not in args else None, + created_from="api", + ) + except ProviderTokenNotInitError as ex: + raise ProviderNotInitializeError(ex.description) + document = documents[0] + documents_and_batch_fields = {"document": marshal(document, document_fields), "batch": document.batch} + return documents_and_batch_fields, 200 + + @service_api_ns.route( "/datasets//documents//update_by_file", "/datasets//documents//update-by-file", ) -class DocumentUpdateByFileApi(DatasetApiResource): - """Resource for update documents.""" +class DeprecatedDocumentUpdateByFileApi(DatasetApiResource): + """Deprecated resource aliases for file document updates.""" - @service_api_ns.doc("update_document_by_file") - @service_api_ns.doc(description="Update an existing document by uploading a file") + @service_api_ns.doc("update_document_by_file_deprecated") + @service_api_ns.doc(deprecated=True) + @service_api_ns.doc( + description=( + "Deprecated legacy alias for updating an existing document by uploading a file. " + "Use PATCH /datasets/{dataset_id}/documents/{document_id} instead." + ) + ) @service_api_ns.doc(params={"dataset_id": "Dataset ID", "document_id": "Document ID"}) @service_api_ns.doc( responses={ @@ -487,82 +570,9 @@ class DocumentUpdateByFileApi(DatasetApiResource): ) @cloud_edition_billing_resource_check("vector_space", "dataset") @cloud_edition_billing_rate_limit_check("knowledge", "dataset") - def post(self, tenant_id, dataset_id, document_id): - """Update document by upload file.""" - dataset = db.session.scalar( - select(Dataset).where(Dataset.tenant_id == tenant_id, Dataset.id == dataset_id).limit(1) - ) - - if not dataset: - raise ValueError("Dataset does not exist.") - - if dataset.provider == "external": - raise ValueError("External datasets are not supported.") - - args = {} - if "data" in request.form: - args = json.loads(request.form["data"]) - if "doc_form" not in args: - args["doc_form"] = dataset.chunk_structure or "text_model" - if "doc_language" not in args: - args["doc_language"] = "English" - - # get dataset info - dataset_id = str(dataset_id) - tenant_id = str(tenant_id) - - # indexing_technique is already set in dataset since this is an update - args["indexing_technique"] = dataset.indexing_technique - - if "file" in request.files: - # save file info - file = request.files["file"] - - if len(request.files) > 1: - raise TooManyFilesError() - - if not file.filename: - raise FilenameNotExistsError - - if not current_user: - raise ValueError("current_user is required") - - try: - upload_file = FileService(db.engine).upload_file( - filename=file.filename, - content=file.read(), - mimetype=file.mimetype, - user=current_user, - source="datasets", - ) - except services.errors.file.FileTooLargeError as file_too_large_error: - raise FileTooLargeError(file_too_large_error.description) - except services.errors.file.UnsupportedFileTypeError: - raise UnsupportedFileTypeError() - data_source = { - "type": "upload_file", - "info_list": {"data_source_type": "upload_file", "file_info_list": {"file_ids": [upload_file.id]}}, - } - args["data_source"] = data_source - # validate args - args["original_document_id"] = str(document_id) - - knowledge_config = KnowledgeConfig.model_validate(args) - DocumentService.document_create_args_validate(knowledge_config) - - try: - documents, _ = DocumentService.save_document_with_dataset_id( - dataset=dataset, - knowledge_config=knowledge_config, - account=dataset.created_by_account, - dataset_process_rule=dataset.latest_process_rule if "process_rule" not in args else None, - created_from="api", - ) - except ProviderTokenNotInitError as ex: - raise ProviderNotInitializeError(ex.description) - document = documents[0] - documents_and_batch_fields = {"document": marshal(document, document_fields), "batch": document.batch} - return documents_and_batch_fields, 200 + def post(self, tenant_id: str, dataset_id: UUID, document_id: UUID): + """Update document by file through the deprecated file-update aliases.""" + return _update_document_by_file(tenant_id=tenant_id, dataset_id=dataset_id, document_id=document_id) @service_api_ns.route("/datasets//documents") @@ -876,6 +886,22 @@ class DocumentApi(DatasetApiResource): return response + @service_api_ns.doc("update_document_by_file") + @service_api_ns.doc(description="Update an existing document by uploading a file") + @service_api_ns.doc(params={"dataset_id": "Dataset ID", "document_id": "Document ID"}) + @service_api_ns.doc( + responses={ + 200: "Document updated successfully", + 401: "Unauthorized - invalid API token", + 404: "Document not found", + } + ) + @cloud_edition_billing_resource_check("vector_space", "dataset") + @cloud_edition_billing_rate_limit_check("knowledge", "dataset") + def patch(self, tenant_id: str, dataset_id: UUID, document_id: UUID): + """Update document by file on the canonical document resource.""" + return _update_document_by_file(tenant_id=tenant_id, dataset_id=dataset_id, document_id=document_id) + @service_api_ns.doc("delete_document") @service_api_ns.doc(description="Delete a document") @service_api_ns.doc(params={"dataset_id": "Dataset ID", "document_id": "Document ID"}) diff --git a/api/controllers/web/audio.py b/api/controllers/web/audio.py index 3ad595f1f4..8ddbc3abb8 100644 --- a/api/controllers/web/audio.py +++ b/api/controllers/web/audio.py @@ -23,7 +23,7 @@ from controllers.web.wraps import WebApiResource from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError from graphon.model_runtime.errors.invoke import InvokeError from libs.helper import uuid_value -from models.model import App +from models.model import App, EndUser from services.audio_service import AudioService from services.errors.audio import ( AudioTooLargeServiceError, @@ -69,12 +69,12 @@ class AudioApi(WebApiResource): 500: "Internal Server Error", } ) - def post(self, app_model: App, end_user): + def post(self, app_model: App, end_user: EndUser): """Convert audio to text""" file = request.files["file"] try: - response = AudioService.transcript_asr(app_model=app_model, file=file, end_user=end_user) + response = AudioService.transcript_asr(app_model=app_model, file=file, end_user=end_user.external_user_id) return response except services.errors.app_model_config.AppModelConfigBrokenError: @@ -117,7 +117,7 @@ class TextApi(WebApiResource): 500: "Internal Server Error", } ) - def post(self, app_model: App, end_user): + def post(self, app_model: App, end_user: EndUser): """Convert text to audio""" try: payload = TextToAudioPayload.model_validate(web_ns.payload or {}) diff --git a/api/core/plugin/utils/http_parser.py b/api/core/plugin/utils/http_parser.py index ce943929be..af0ff10bfb 100644 --- a/api/core/plugin/utils/http_parser.py +++ b/api/core/plugin/utils/http_parser.py @@ -151,6 +151,12 @@ def deserialize_response(raw_data: bytes) -> Response: response = Response(response=body, status=status_code) + # Replace Flask's default headers (e.g. Content-Type, Content-Length) with the + # parsed ones so we faithfully reproduce the original response. Use Headers.add + # rather than dict-style assignment so that repeated headers such as Set-Cookie + # (and any other multi-valued header per RFC 9110) are preserved instead of + # being overwritten. + response.headers.clear() for line in lines[1:]: if not line: continue @@ -158,6 +164,6 @@ def deserialize_response(raw_data: bytes) -> Response: if ":" not in line_str: continue name, value = line_str.split(":", 1) - response.headers[name] = value.strip() + response.headers.add(name, value.strip()) return response diff --git a/api/core/provider_manager.py b/api/core/provider_manager.py index 8969825be4..b290ae456e 100644 --- a/api/core/provider_manager.py +++ b/api/core/provider_manager.py @@ -9,9 +9,9 @@ from typing import TYPE_CHECKING, Any from pydantic import TypeAdapter from sqlalchemy import select from sqlalchemy.exc import IntegrityError -from sqlalchemy.orm import Session from configs import dify_config +from core.db.session_factory import session_factory from core.entities.model_entities import DefaultModelEntity, DefaultModelProviderEntity from core.entities.provider_configuration import ProviderConfiguration, ProviderConfigurations, ProviderModelBundle from core.entities.provider_entities import ( @@ -445,7 +445,7 @@ class ProviderManager: @staticmethod def _get_all_providers(tenant_id: str) -> dict[str, list[Provider]]: provider_name_to_provider_records_dict = defaultdict(list) - with Session(db.engine, expire_on_commit=False) as session: + with session_factory.create_session() as session: stmt = select(Provider).where(Provider.tenant_id == tenant_id, Provider.is_valid == True) providers = session.scalars(stmt) for provider in providers: @@ -462,7 +462,7 @@ class ProviderManager: :return: """ provider_name_to_provider_model_records_dict = defaultdict(list) - with Session(db.engine, expire_on_commit=False) as session: + with session_factory.create_session() as session: stmt = select(ProviderModel).where(ProviderModel.tenant_id == tenant_id, ProviderModel.is_valid == True) provider_models = session.scalars(stmt) for provider_model in provider_models: @@ -478,7 +478,7 @@ class ProviderManager: :return: """ provider_name_to_preferred_provider_type_records_dict = {} - with Session(db.engine, expire_on_commit=False) as session: + with session_factory.create_session() as session: stmt = select(TenantPreferredModelProvider).where(TenantPreferredModelProvider.tenant_id == tenant_id) preferred_provider_types = session.scalars(stmt) provider_name_to_preferred_provider_type_records_dict = { @@ -496,7 +496,7 @@ class ProviderManager: :return: """ provider_name_to_provider_model_settings_dict = defaultdict(list) - with Session(db.engine, expire_on_commit=False) as session: + with session_factory.create_session() as session: stmt = select(ProviderModelSetting).where(ProviderModelSetting.tenant_id == tenant_id) provider_model_settings = session.scalars(stmt) for provider_model_setting in provider_model_settings: @@ -514,7 +514,7 @@ class ProviderManager: :return: """ provider_name_to_provider_model_credentials_dict = defaultdict(list) - with Session(db.engine, expire_on_commit=False) as session: + with session_factory.create_session() as session: stmt = select(ProviderModelCredential).where(ProviderModelCredential.tenant_id == tenant_id) provider_model_credentials = session.scalars(stmt) for provider_model_credential in provider_model_credentials: @@ -544,7 +544,7 @@ class ProviderManager: return {} provider_name_to_provider_load_balancing_model_configs_dict = defaultdict(list) - with Session(db.engine, expire_on_commit=False) as session: + with session_factory.create_session() as session: stmt = select(LoadBalancingModelConfig).where(LoadBalancingModelConfig.tenant_id == tenant_id) provider_load_balancing_configs = session.scalars(stmt) for provider_load_balancing_config in provider_load_balancing_configs: @@ -578,7 +578,7 @@ class ProviderManager: :param provider_name: provider name :return: """ - with Session(db.engine, expire_on_commit=False) as session: + with session_factory.create_session() as session: stmt = ( select(ProviderCredential) .where( @@ -608,7 +608,7 @@ class ProviderManager: :param model_type: model type :return: """ - with Session(db.engine, expire_on_commit=False) as session: + with session_factory.create_session() as session: stmt = ( select(ProviderModelCredential) .where( diff --git a/api/core/rag/datasource/retrieval_service.py b/api/core/rag/datasource/retrieval_service.py index c60d19045a..b985ebbe1d 100644 --- a/api/core/rag/datasource/retrieval_service.py +++ b/api/core/rag/datasource/retrieval_service.py @@ -217,10 +217,11 @@ class RetrievalService: """Deduplicate documents in O(n) while preserving first-seen order. Rules: - - For provider == "dify" and metadata["doc_id"] exists: keep the doc with the highest - metadata["score"] among duplicates; if a later duplicate has no score, ignore it. - - For non-dify documents (or dify without doc_id): deduplicate by content key - (provider, page_content), keeping the first occurrence. + - If metadata["doc_id"] exists (any provider): deduplicate by (provider, doc_id) key; + keep the doc with the highest metadata["score"] among duplicates. If a later duplicate + has no score, ignore it. + - If metadata["doc_id"] is absent: deduplicate by content key (provider, page_content), + keeping the first occurrence. """ if not documents: return documents @@ -231,11 +232,10 @@ class RetrievalService: order: list[tuple] = [] for doc in documents: - is_dify = doc.provider == "dify" - doc_id = (doc.metadata or {}).get("doc_id") if is_dify else None + doc_id = (doc.metadata or {}).get("doc_id") - if is_dify and doc_id: - key = ("dify", doc_id) + if doc_id: + key = (doc.provider or "dify", doc_id) if key not in chosen: chosen[key] = doc order.append(key) diff --git a/api/core/rag/datasource/vdb/vector_factory.py b/api/core/rag/datasource/vdb/vector_factory.py index 9575377174..1f82f7a081 100644 --- a/api/core/rag/datasource/vdb/vector_factory.py +++ b/api/core/rag/datasource/vdb/vector_factory.py @@ -144,8 +144,20 @@ class Vector: def get_vector_factory(vector_type: str) -> type[AbstractVectorFactory]: return get_vector_factory_class(vector_type) + @staticmethod + def _filter_empty_text_documents(documents: list[Document]) -> list[Document]: + filtered_documents = [document for document in documents if document.page_content.strip()] + skipped_count = len(documents) - len(filtered_documents) + if skipped_count: + logger.warning("skip %d empty documents before vector embedding", skipped_count) + return filtered_documents + def create(self, texts: list | None = None, **kwargs): if texts: + texts = self._filter_empty_text_documents(texts) + if not texts: + return + start = time.time() logger.info("start embedding %s texts %s", len(texts), start) batch_size = 1000 @@ -203,8 +215,14 @@ class Vector: logger.info("Embedding %s files took %s s", len(file_documents), time.time() - start) def add_texts(self, documents: list[Document], **kwargs): + documents = self._filter_empty_text_documents(documents) + if not documents: + return + if kwargs.get("duplicate_check", False): documents = self._filter_duplicate_texts(documents) + if not documents: + return embeddings = self._embeddings.embed_documents([document.page_content for document in documents]) self._vector_processor.create(texts=documents, embeddings=embeddings, **kwargs) diff --git a/api/core/tools/tool_manager.py b/api/core/tools/tool_manager.py index 87cf6d7085..0a7811bb53 100644 --- a/api/core/tools/tool_manager.py +++ b/api/core/tools/tool_manager.py @@ -1078,6 +1078,13 @@ class ToolManager: if parameter.form == ToolParameter.ToolParameterForm.FORM: if variable_pool: config = tool_configurations.get(parameter.name, {}) + + selector_value = cls._extract_runtime_selector_value(parameter, config) + if selector_value is not None: + # Selector parameters carry structured dictionaries, not scalar ToolInput values. + runtime_parameters[parameter.name] = selector_value + continue + if not (config and isinstance(config, dict) and config.get("value") is not None): continue tool_input = ToolNodeData.ToolInput.model_validate(tool_configurations.get(parameter.name, {})) @@ -1105,5 +1112,39 @@ class ToolManager: runtime_parameters[parameter.name] = value return runtime_parameters + @classmethod + def _extract_runtime_selector_value(cls, parameter: ToolParameter, config: Any) -> dict[str, Any] | None: + if parameter.type not in { + ToolParameter.ToolParameterType.MODEL_SELECTOR, + ToolParameter.ToolParameterType.APP_SELECTOR, + }: + return None + if not isinstance(config, dict): + return None + + input_value = config.get("value") + if isinstance(input_value, dict) and cls._is_selector_value(parameter, input_value): + return cast("dict[str, Any]", parameter.init_frontend_parameter(input_value)) + + if cls._is_selector_value(parameter, config): + selector_value = dict(config) + selector_value.pop("type", None) + selector_value.pop("value", None) + return cast("dict[str, Any]", parameter.init_frontend_parameter(selector_value)) + + return None + + @classmethod + def _is_selector_value(cls, parameter: ToolParameter, value: Mapping[str, Any]) -> bool: + if parameter.type == ToolParameter.ToolParameterType.MODEL_SELECTOR: + return ( + isinstance(value.get("provider"), str) + and isinstance(value.get("model"), str) + and isinstance(value.get("model_type"), str) + ) + if parameter.type == ToolParameter.ToolParameterType.APP_SELECTOR: + return isinstance(value.get("app_id"), str) + return False + ToolManager.load_hardcoded_providers_cache() diff --git a/api/core/workflow/human_input_adapter.py b/api/core/workflow/human_input_adapter.py index 4b765e6aea..731ae2b858 100644 --- a/api/core/workflow/human_input_adapter.py +++ b/api/core/workflow/human_input_adapter.py @@ -272,6 +272,14 @@ def _adapt_tool_node_data_for_graph(node_data: Mapping[str, Any]) -> dict[str, A normalized_tool_configurations[name] = value continue + selector_value = _extract_selector_configuration(value) + if selector_value is not None: + # Model/app selectors are dictionaries even when they come through the legacy tool configuration path. + # Move them to tool_parameters so graph validation does not flatten them as primitive constants. + found_legacy_tool_inputs = True + normalized_tool_parameters.setdefault(name, {"type": "constant", "value": selector_value}) + continue + input_type = value.get("type") input_value = value.get("value") if input_type not in {"mixed", "variable", "constant"}: @@ -310,6 +318,28 @@ def _flatten_legacy_tool_configuration_value(*, input_type: Any, input_value: An return None +def _extract_selector_configuration(value: Mapping[str, Any]) -> dict[str, Any] | None: + input_value = value.get("value") + if isinstance(input_value, Mapping) and _is_selector_configuration(input_value): + return dict(input_value) + + if _is_selector_configuration(value): + selector_value = dict(value) + selector_value.pop("type", None) + selector_value.pop("value", None) + return selector_value + + return None + + +def _is_selector_configuration(value: Mapping[str, Any]) -> bool: + return ( + isinstance(value.get("provider"), str) + and isinstance(value.get("model"), str) + and isinstance(value.get("model_type"), str) + ) or isinstance(value.get("app_id"), str) + + def _normalize_email_recipients(recipients: Mapping[str, Any]) -> dict[str, Any]: normalized = dict(recipients) diff --git a/api/core/workflow/node_factory.py b/api/core/workflow/node_factory.py index de4eae1b22..895953a3c1 100644 --- a/api/core/workflow/node_factory.py +++ b/api/core/workflow/node_factory.py @@ -365,7 +365,8 @@ class DifyNodeFactory(NodeFactory): (including pydantic ValidationError, which subclasses ValueError), if node type is unknown, or if no implementation exists for the resolved version """ - typed_node_config = NodeConfigDictAdapter.validate_python(adapt_node_config_for_graph(node_config)) + adapted_node_config = adapt_node_config_for_graph(node_config) + typed_node_config = NodeConfigDictAdapter.validate_python(adapted_node_config) node_id = typed_node_config["id"] node_data = typed_node_config["data"] node_class = self._resolve_node_class(node_type=node_data.type, node_version=str(node_data.version)) @@ -373,6 +374,11 @@ class DifyNodeFactory(NodeFactory): # Re-validate using the resolved node class so workflow-local node schemas # stay explicit and constructors receive the concrete typed payload. resolved_node_data = self._validate_resolved_node_data(node_class, node_data) + config_for_node_init: BaseNodeData | dict[str, Any] + if isinstance(resolved_node_data, BaseNodeData): + config_for_node_init = resolved_node_data.model_dump(mode="python", by_alias=True) + else: + config_for_node_init = resolved_node_data node_type = node_data.type node_init_kwargs_factories: Mapping[NodeType, Callable[[], dict[str, object]]] = { BuiltinNodeTypes.CODE: lambda: { @@ -442,7 +448,7 @@ class DifyNodeFactory(NodeFactory): node_init_kwargs = node_init_kwargs_factories.get(node_type, lambda: {})() return node_class( node_id=node_id, - config=resolved_node_data, + config=config_for_node_init, graph_init_params=self.graph_init_params, graph_runtime_state=self.graph_runtime_state, **node_init_kwargs, @@ -474,10 +480,7 @@ class DifyNodeFactory(NodeFactory): include_retriever_attachment_loader: bool, include_jinja2_template_renderer: bool, ) -> dict[str, object]: - validated_node_data = cast( - LLMCompatibleNodeData, - self._validate_resolved_node_data(node_class=node_class, node_data=node_data), - ) + validated_node_data = cast(LLMCompatibleNodeData, node_data) model_instance = self._build_model_instance_for_llm_node(validated_node_data) node_init_kwargs: dict[str, object] = { "credentials_provider": self._llm_credentials_provider, diff --git a/api/core/workflow/node_runtime.py b/api/core/workflow/node_runtime.py index b8725853c4..c1d3a856fb 100644 --- a/api/core/workflow/node_runtime.py +++ b/api/core/workflow/node_runtime.py @@ -501,11 +501,15 @@ class DifyToolNodeRuntime(ToolNodeRuntimeProtocol): @staticmethod def _build_tool_runtime_spec(node_data: ToolNodeData) -> _WorkflowToolRuntimeSpec: + tool_configurations = dict(node_data.tool_configurations) + tool_configurations.update( + {name: tool_input.model_dump(mode="python") for name, tool_input in node_data.tool_parameters.items()} + ) return _WorkflowToolRuntimeSpec( provider_type=CoreToolProviderType(node_data.provider_type.value), provider_id=node_data.provider_id, tool_name=node_data.tool_name, - tool_configurations=dict(node_data.tool_configurations), + tool_configurations=tool_configurations, credential_id=node_data.credential_id, ) diff --git a/api/events/event_handlers/delete_tool_parameters_cache_when_sync_draft_workflow.py b/api/events/event_handlers/delete_tool_parameters_cache_when_sync_draft_workflow.py index ba9758175f..f1196445ed 100644 --- a/api/events/event_handlers/delete_tool_parameters_cache_when_sync_draft_workflow.py +++ b/api/events/event_handlers/delete_tool_parameters_cache_when_sync_draft_workflow.py @@ -3,6 +3,7 @@ import logging from core.tools.entities.tool_entities import ToolProviderType from core.tools.tool_manager import ToolManager from core.tools.utils.configuration import ToolParameterConfigurationManager +from core.workflow.human_input_adapter import adapt_node_config_for_graph from events.app_event import app_draft_workflow_was_synced from graphon.nodes import BuiltinNodeTypes from graphon.nodes.tool.entities import ToolEntity @@ -19,7 +20,8 @@ def handle(sender, **kwargs): for node_data in synced_draft_workflow.graph_dict.get("nodes", []): if node_data.get("data", {}).get("type") == BuiltinNodeTypes.TOOL: try: - tool_entity = ToolEntity.model_validate(node_data["data"]) + adapted_node_data = adapt_node_config_for_graph(node_data) + tool_entity = ToolEntity.model_validate(adapted_node_data["data"]) provider_type = ToolProviderType(tool_entity.provider_type.value) tool_runtime = ToolManager.get_tool_runtime( provider_type=provider_type, diff --git a/api/extensions/ext_session_factory.py b/api/extensions/ext_session_factory.py index 0eb43d66f4..e19ccd11e5 100644 --- a/api/extensions/ext_session_factory.py +++ b/api/extensions/ext_session_factory.py @@ -1,7 +1,9 @@ +from flask import Flask + from core.db.session_factory import configure_session_factory from extensions.ext_database import db -def init_app(app): +def init_app(app: Flask): with app.app_context(): configure_session_factory(db.engine) diff --git a/api/factories/file_factory/builders.py b/api/factories/file_factory/builders.py index 1d2ad4d445..4fb976f0e7 100644 --- a/api/factories/file_factory/builders.py +++ b/api/factories/file_factory/builders.py @@ -298,7 +298,7 @@ def _build_from_datasource_file( raise ValueError(f"DatasourceFile {mapping.get('datasource_file_id')} not found") extension = "." + datasource_file.key.split(".")[-1] if "." in datasource_file.key else ".bin" - detected_file_type = standardize_file_type(extension="." + extension, mime_type=datasource_file.mime_type) + detected_file_type = standardize_file_type(extension=extension, mime_type=datasource_file.mime_type) file_type = _resolve_file_type( detected_file_type=detected_file_type, specified_type=mapping.get("type"), diff --git a/api/factories/file_factory/remote.py b/api/factories/file_factory/remote.py index e5a7186007..9b8f94b1f3 100644 --- a/api/factories/file_factory/remote.py +++ b/api/factories/file_factory/remote.py @@ -19,8 +19,13 @@ from werkzeug.http import parse_options_header from core.helper import ssrf_proxy -def extract_filename(url_path: str, content_disposition: str | None) -> str | None: - """Extract a safe filename from Content-Disposition or the request URL path.""" +def extract_filename(url_or_path: str, content_disposition: str | None) -> str | None: + """Extract a safe filename from Content-Disposition or the request URL path. + + Handles full URLs, paths with query strings, hash fragments, and percent-encoded segments. + Query strings and hash fragments are stripped from the URL before extracting the basename. + Percent-encoded characters in the path are decoded safely. + """ filename: str | None = None if content_disposition: filename_star_match = re.search(r"filename\*=([^;]+)", content_disposition) @@ -47,8 +52,13 @@ def extract_filename(url_path: str, content_disposition: str | None) -> str | No filename = urllib.parse.unquote(raw) if not filename: - candidate = os.path.basename(url_path) - filename = urllib.parse.unquote(candidate) if candidate else None + # Parse the URL to extract just the path, stripping query strings and fragments + # This handles both full URLs and bare paths + parsed = urllib.parse.urlparse(url_or_path) + path = parsed.path + candidate = os.path.basename(path) + # Decode percent-encoded characters, with safe fallback for malformed input + filename = urllib.parse.unquote(candidate, errors="replace") if candidate else None if filename: filename = os.path.basename(filename) diff --git a/api/libs/typing.py b/api/libs/typing.py deleted file mode 100644 index f84e9911e0..0000000000 --- a/api/libs/typing.py +++ /dev/null @@ -1,9 +0,0 @@ -from typing import TypeGuard - - -def is_str_dict(v: object) -> TypeGuard[dict[str, object]]: - return isinstance(v, dict) - - -def is_str(v: object) -> TypeGuard[str]: - return isinstance(v, str) diff --git a/api/models/provider.py b/api/models/provider.py index 2bb67d605b..8dc3ce4ff6 100644 --- a/api/models/provider.py +++ b/api/models/provider.py @@ -9,11 +9,11 @@ import sqlalchemy as sa from sqlalchemy import DateTime, String, func, select, text from sqlalchemy.orm import Mapped, mapped_column +from core.db.session_factory import session_factory from graphon.model_runtime.entities.model_entities import ModelType from libs.uuid_utils import uuidv7 from .base import TypeBase -from .engine import db from .enums import CredentialSourceType, PaymentStatus, ProviderQuotaType from .types import EnumText, LongText, StringUUID @@ -82,7 +82,8 @@ class Provider(TypeBase): @cached_property def credential(self): if self.credential_id: - return db.session.scalar(select(ProviderCredential).where(ProviderCredential.id == self.credential_id)) + with session_factory.create_session() as session: + return session.scalar(select(ProviderCredential).where(ProviderCredential.id == self.credential_id)) @property def credential_name(self): @@ -145,9 +146,10 @@ class ProviderModel(TypeBase): @cached_property def credential(self): if self.credential_id: - return db.session.scalar( - select(ProviderModelCredential).where(ProviderModelCredential.id == self.credential_id) - ) + with session_factory.create_session() as session: + return session.scalar( + select(ProviderModelCredential).where(ProviderModelCredential.id == self.credential_id) + ) @property def credential_name(self): diff --git a/api/models/workflow.py b/api/models/workflow.py index cb1723440b..7936c06a5a 100644 --- a/api/models/workflow.py +++ b/api/models/workflow.py @@ -1568,12 +1568,14 @@ class WorkflowDraftVariable(Base): ), ) - # Relationship to WorkflowDraftVariableFile + # WorkflowDraftVariableFile uses TypeBase while WorkflowDraftVariable uses Base, so the relationship + # must resolve the class object lazily instead of relying on string lookup across registries. variable_file: Mapped[Optional["WorkflowDraftVariableFile"]] = orm.relationship( + lambda: WorkflowDraftVariableFile, foreign_keys=[file_id], lazy="raise", uselist=False, - primaryjoin="WorkflowDraftVariableFile.id == WorkflowDraftVariable.file_id", + primaryjoin=lambda: orm.foreign(WorkflowDraftVariable.file_id) == WorkflowDraftVariableFile.id, ) # Cache for deserialized value @@ -1892,7 +1894,7 @@ class WorkflowDraftVariable(Base): return self.last_edited_at is not None -class WorkflowDraftVariableFile(Base): +class WorkflowDraftVariableFile(TypeBase): """Stores metadata about files associated with large workflow draft variables. This model acts as an intermediary between WorkflowDraftVariable and UploadFile, @@ -1906,18 +1908,7 @@ class WorkflowDraftVariableFile(Base): __tablename__ = "workflow_draft_variable_files" # Primary key - id: Mapped[str] = mapped_column( - StringUUID, - primary_key=True, - default=lambda: str(uuidv7()), - ) - - created_at: Mapped[datetime] = mapped_column( - DateTime, - nullable=False, - default=naive_utc_now, - server_default=func.current_timestamp(), - ) + id: Mapped[str] = mapped_column(StringUUID, primary_key=True, default_factory=lambda: str(uuidv7()), init=False) tenant_id: Mapped[str] = mapped_column( StringUUID, @@ -1969,15 +1960,23 @@ class WorkflowDraftVariableFile(Base): nullable=False, ) - # Relationship to UploadFile + # Rows are created with `upload_file_id`; callers should load this relationship explicitly when needed. upload_file: Mapped["UploadFile"] = orm.relationship( UploadFile, foreign_keys=[upload_file_id], lazy="raise", + init=False, uselist=False, primaryjoin=lambda: orm.foreign(WorkflowDraftVariableFile.upload_file_id) == UploadFile.id, ) + created_at: Mapped[datetime] = mapped_column( + DateTime, + nullable=False, + default_factory=naive_utc_now, + server_default=func.current_timestamp(), + ) + def is_system_variable_editable(name: str) -> bool: return name in _EDITABLE_SYSTEM_VARIABLE diff --git a/api/providers/vdb/vdb-tidb-on-qdrant/src/dify_vdb_tidb_on_qdrant/tidb_service.py b/api/providers/vdb/vdb-tidb-on-qdrant/src/dify_vdb_tidb_on_qdrant/tidb_service.py index ece061db67..6283dbb986 100644 --- a/api/providers/vdb/vdb-tidb-on-qdrant/src/dify_vdb_tidb_on_qdrant/tidb_service.py +++ b/api/providers/vdb/vdb-tidb-on-qdrant/src/dify_vdb_tidb_on_qdrant/tidb_service.py @@ -246,8 +246,18 @@ class TidbService: userPrefix = item["userPrefix"] if state == "ACTIVE" and len(userPrefix) > 0: cluster_info = tidb_serverless_list_map[item["clusterId"]] - cluster_info.status = TidbAuthBindingStatus.ACTIVE cluster_info.account = f"{userPrefix}.root" + if not cluster_info.qdrant_endpoint: + cluster_info.qdrant_endpoint = TidbService.extract_qdrant_endpoint( + item + ) or TidbService.fetch_qdrant_endpoint(api_url, public_key, private_key, item["clusterId"]) + if cluster_info.qdrant_endpoint: + cluster_info.status = TidbAuthBindingStatus.ACTIVE + else: + logger.warning( + "Cluster %s is ACTIVE but qdrant endpoint is not ready; will retry later", + item["clusterId"], + ) db.session.add(cluster_info) db.session.commit() else: diff --git a/api/providers/vdb/vdb-tidb-on-qdrant/tests/unit_tests/test_tidb_service.py b/api/providers/vdb/vdb-tidb-on-qdrant/tests/unit_tests/test_tidb_service.py index c1ffbacbbc..20a42f6cc3 100644 --- a/api/providers/vdb/vdb-tidb-on-qdrant/tests/unit_tests/test_tidb_service.py +++ b/api/providers/vdb/vdb-tidb-on-qdrant/tests/unit_tests/test_tidb_service.py @@ -1,8 +1,11 @@ +from types import SimpleNamespace from unittest.mock import MagicMock, patch import pytest from dify_vdb_tidb_on_qdrant.tidb_service import TidbService +from models.enums import TidbAuthBindingStatus + class TestExtractQdrantEndpoint: """Unit tests for TidbService.extract_qdrant_endpoint.""" @@ -216,3 +219,86 @@ class TestBatchCreateEdgeCases: private_key="priv", region="us-east-1", ) + + +class TestBatchUpdateTidbServerlessClusterStatus: + """Verify that status updates only expose clusters after qdrant endpoint is ready.""" + + @patch("dify_vdb_tidb_on_qdrant.tidb_service.db") + @patch("dify_vdb_tidb_on_qdrant.tidb_service._tidb_http_client") + def test_sets_active_when_batch_response_contains_endpoint(self, mock_http, mock_db): + binding = SimpleNamespace( + cluster_id="c-1", + status=TidbAuthBindingStatus.CREATING, + account="root", + qdrant_endpoint=None, + ) + mock_http.get.return_value = MagicMock( + status_code=200, + json=lambda: { + "clusters": [ + { + "clusterId": "c-1", + "state": "ACTIVE", + "userPrefix": "pfx", + "endpoints": {"public": {"host": "gw.tidbcloud.com"}}, + } + ] + }, + ) + + TidbService.batch_update_tidb_serverless_cluster_status([binding], "proj", "url", "iam", "pub", "priv") + + assert binding.account == "pfx.root" + assert binding.qdrant_endpoint == "https://qdrant-gw.tidbcloud.com" + assert binding.status == TidbAuthBindingStatus.ACTIVE + mock_db.session.add.assert_called_once_with(binding) + mock_db.session.commit.assert_called_once() + + @patch.object(TidbService, "fetch_qdrant_endpoint", return_value="https://qdrant-gw.tidbcloud.com") + @patch("dify_vdb_tidb_on_qdrant.tidb_service.db") + @patch("dify_vdb_tidb_on_qdrant.tidb_service._tidb_http_client") + def test_fetches_endpoint_when_batch_response_omits_it(self, mock_http, mock_db, mock_fetch_endpoint): + binding = SimpleNamespace( + cluster_id="c-1", + status=TidbAuthBindingStatus.CREATING, + account="root", + qdrant_endpoint=None, + ) + mock_http.get.return_value = MagicMock( + status_code=200, + json=lambda: {"clusters": [{"clusterId": "c-1", "state": "ACTIVE", "userPrefix": "pfx", "endpoints": {}}]}, + ) + + TidbService.batch_update_tidb_serverless_cluster_status([binding], "proj", "url", "iam", "pub", "priv") + + assert binding.account == "pfx.root" + assert binding.qdrant_endpoint == "https://qdrant-gw.tidbcloud.com" + assert binding.status == TidbAuthBindingStatus.ACTIVE + mock_fetch_endpoint.assert_called_once_with("url", "pub", "priv", "c-1") + mock_db.session.add.assert_called_once_with(binding) + mock_db.session.commit.assert_called_once() + + @patch.object(TidbService, "fetch_qdrant_endpoint", return_value=None) + @patch("dify_vdb_tidb_on_qdrant.tidb_service.db") + @patch("dify_vdb_tidb_on_qdrant.tidb_service._tidb_http_client") + def test_keeps_creating_when_endpoint_is_not_ready(self, mock_http, mock_db, mock_fetch_endpoint): + binding = SimpleNamespace( + cluster_id="c-1", + status=TidbAuthBindingStatus.CREATING, + account="root", + qdrant_endpoint=None, + ) + mock_http.get.return_value = MagicMock( + status_code=200, + json=lambda: {"clusters": [{"clusterId": "c-1", "state": "ACTIVE", "userPrefix": "pfx", "endpoints": {}}]}, + ) + + TidbService.batch_update_tidb_serverless_cluster_status([binding], "proj", "url", "iam", "pub", "priv") + + assert binding.account == "pfx.root" + assert binding.qdrant_endpoint is None + assert binding.status == TidbAuthBindingStatus.CREATING + mock_fetch_endpoint.assert_called_once_with("url", "pub", "priv", "c-1") + mock_db.session.add.assert_called_once_with(binding) + mock_db.session.commit.assert_called_once() diff --git a/api/pyproject.toml b/api/pyproject.toml index 2587d9e0bf..69add5c68d 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -1,12 +1,12 @@ [project] name = "dify-api" -version = "1.13.3" +version = "1.14.0" requires-python = "~=3.12.0" dependencies = [ # Legacy: mature and widely deployed "bleach>=6.3.0", - "boto3>=1.42.96", + "boto3>=1.43.3", "celery>=5.6.3", "croniter>=6.2.2", "flask>=3.1.3,<4.0.0", @@ -14,7 +14,7 @@ dependencies = [ "gevent>=26.4.0", "gevent-websocket>=0.10.1", "gmpy2>=2.3.0", - "google-api-python-client>=2.194.0", + "google-api-python-client>=2.195.0", "gunicorn>=25.3.0", "psycogreen>=1.0.2", "psycopg2-binary>=2.9.12", @@ -31,7 +31,7 @@ dependencies = [ "flask-migrate>=4.1.0,<5.0.0", "flask-orjson>=2.0.0,<3.0.0", "flask-restx>=1.3.2,<2.0.0", - "google-cloud-aiplatform>=1.148.1,<2.0.0", + "google-cloud-aiplatform>=1.149.0,<2.0.0", "httpx[socks]>=0.28.1,<1.0.0", "opentelemetry-distro>=0.62b1,<1.0.0", "opentelemetry-instrumentation-celery>=0.62b0,<1.0.0", @@ -127,7 +127,7 @@ dev = [ "testcontainers>=4.14.2", "types-aiofiles>=25.1.0", "types-beautifulsoup4>=4.12.0", - "types-cachetools>=6.2.0", + "types-cachetools>=7.0.0.20260503", "types-colorama>=0.4.15", "types-defusedxml>=0.7.0", "types-deprecated>=1.3.1", @@ -135,7 +135,7 @@ dev = [ "types-flask-cors>=6.0.0", "types-flask-migrate>=4.1.0", "types-gevent>=26.4.0", - "types-greenlet>=3.4.0", + "types-greenlet>=3.5.0.20260428", "types-html5lib>=1.1.11", "types-markdown>=3.10.2", "types-oauthlib>=3.3.0", @@ -143,7 +143,7 @@ dev = [ "types-olefile>=0.47.0", "types-openpyxl>=3.1.5", "types-pexpect>=4.9.0", - "types-protobuf>=7.34.1", + "types-protobuf>=7.34.1.20260503", "types-psutil>=7.2.2", "types-psycopg2>=2.9.21.20260422", "types-pygments>=2.20.0", @@ -158,11 +158,11 @@ dev = [ "types-tensorflow>=2.18.0.20260408", "types-tqdm>=4.67.3.20260408", "types-ujson>=5.10.0", - "boto3-stubs>=1.42.96", + "boto3-stubs>=1.43.2", "types-jmespath>=1.1.0.20260408", - "hypothesis>=6.152.3", + "hypothesis>=6.152.4", "types_pyOpenSSL>=24.1.0", - "types_cffi>=2.0.0.20260408", + "types_cffi>=2.0.0.20260429", "types_setuptools>=82.0.0.20260408", "pandas-stubs>=3.0.0", "scipy-stubs>=1.17.1.4", @@ -174,7 +174,7 @@ dev = [ # "locust>=2.40.4", # Temporarily removed due to compatibility issues. Uncomment when resolved. "pytest-timeout>=2.4.0", "pytest-xdist>=3.8.0", - "pyrefly>=0.62.0", + "pyrefly>=0.64.0", "xinference-client>=2.7.0", ] @@ -184,7 +184,7 @@ dev = [ ############################################################ storage = [ "azure-storage-blob>=12.28.0", - "bce-python-sdk>=0.9.70", + "bce-python-sdk>=0.9.71", "cos-python-sdk-v5>=1.9.42", "esdk-obs-python>=3.22.2", "google-cloud-storage>=3.10.1", diff --git a/api/services/entities/knowledge_entities/knowledge_entities.py b/api/services/entities/knowledge_entities/knowledge_entities.py index b1fe352861..910f54bebc 100644 --- a/api/services/entities/knowledge_entities/knowledge_entities.py +++ b/api/services/entities/knowledge_entities/knowledge_entities.py @@ -3,6 +3,7 @@ from typing import Any, Literal from pydantic import BaseModel, field_validator from core.rag.entities import Rule +from core.rag.entities.metadata_entities import MetadataFilteringCondition from core.rag.index_processor.constant.index_type import IndexStructureType from core.rag.retrieval.retrieval_methods import RetrievalMethod @@ -83,6 +84,7 @@ class RetrievalModel(BaseModel): score_threshold_enabled: bool score_threshold: float | None = None weights: WeightModel | None = None + metadata_filtering_conditions: MetadataFilteringCondition | None = None class MetaDataConfig(BaseModel): diff --git a/api/services/tag_service.py b/api/services/tag_service.py index 1882c855ea..8043a99be1 100644 --- a/api/services/tag_service.py +++ b/api/services/tag_service.py @@ -1,9 +1,11 @@ import uuid +from typing import cast import sqlalchemy as sa from flask_login import current_user from pydantic import BaseModel, Field -from sqlalchemy import func, select +from sqlalchemy import delete, func, select +from sqlalchemy.engine import CursorResult from werkzeug.exceptions import NotFound from extensions.ext_database import db @@ -29,7 +31,7 @@ class TagBindingCreatePayload(BaseModel): class TagBindingDeletePayload(BaseModel): - tag_id: str + tag_ids: list[str] = Field(min_length=1) target_id: str type: TagType @@ -178,13 +180,18 @@ class TagService: @staticmethod def delete_tag_binding(payload: TagBindingDeletePayload): TagService.check_target_exists(payload.type, payload.target_id) - tag_binding = db.session.scalar( - select(TagBinding) - .where(TagBinding.target_id == payload.target_id, TagBinding.tag_id == payload.tag_id) - .limit(1) + result = cast( + CursorResult, + db.session.execute( + delete(TagBinding).where( + TagBinding.target_id == payload.target_id, + TagBinding.tag_id.in_(payload.tag_ids), + TagBinding.tenant_id == current_user.current_tenant_id, + ) + ), ) - if tag_binding: - db.session.delete(tag_binding) + + if result.rowcount: db.session.commit() @staticmethod diff --git a/api/services/workflow_draft_variable_service.py b/api/services/workflow_draft_variable_service.py index 96f936ff9b..a55448e352 100644 --- a/api/services/workflow_draft_variable_service.py +++ b/api/services/workflow_draft_variable_service.py @@ -1083,10 +1083,9 @@ class DraftVariableSaver: mimetype=content_type, user=self._user, ) - + assert self._user.current_tenant_id # Create WorkflowDraftVariableFile record variable_file = WorkflowDraftVariableFile( - id=uuidv7(), upload_file_id=upload_file.id, size=original_size, length=original_length, @@ -1095,6 +1094,7 @@ class DraftVariableSaver: tenant_id=self._user.current_tenant_id, user_id=self._user.id, ) + variable_file.id = str(uuidv7()) engine = bind = self._session.get_bind() assert isinstance(engine, Engine) with sessionmaker(bind=engine, expire_on_commit=False).begin() as session: diff --git a/api/tests/test_containers_integration_tests/conftest.py b/api/tests/test_containers_integration_tests/conftest.py index 66a25e5daf..b4482674da 100644 --- a/api/tests/test_containers_integration_tests/conftest.py +++ b/api/tests/test_containers_integration_tests/conftest.py @@ -433,7 +433,7 @@ def flask_app_with_containers(set_up_containers_and_env) -> Flask: @pytest.fixture -def flask_req_ctx_with_containers(flask_app_with_containers) -> Generator[None, None, None]: +def flask_req_ctx_with_containers(flask_app_with_containers: Flask) -> Generator[None, None, None]: """ Request context fixture for containerized Flask application. @@ -454,7 +454,7 @@ def flask_req_ctx_with_containers(flask_app_with_containers) -> Generator[None, @pytest.fixture -def test_client_with_containers(flask_app_with_containers) -> Generator[FlaskClient, None, None]: +def test_client_with_containers(flask_app_with_containers: Flask) -> Generator[FlaskClient, None, None]: """ Test client fixture for containerized Flask application. @@ -475,7 +475,7 @@ def test_client_with_containers(flask_app_with_containers) -> Generator[FlaskCli @pytest.fixture -def db_session_with_containers(flask_app_with_containers) -> Generator[Session, None, None]: +def db_session_with_containers(flask_app_with_containers: Flask) -> Generator[Session, None, None]: """ Database session fixture for containerized testing. diff --git a/api/tests/test_containers_integration_tests/controllers/console/app/test_app_apis.py b/api/tests/test_containers_integration_tests/controllers/console/app/test_app_apis.py index 18755ef012..bb737754a1 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/app/test_app_apis.py +++ b/api/tests/test_containers_integration_tests/controllers/console/app/test_app_apis.py @@ -7,6 +7,7 @@ from types import SimpleNamespace from unittest.mock import MagicMock, patch import pytest +from flask import Flask from pydantic import ValidationError from werkzeug.exceptions import BadRequest, NotFound @@ -69,7 +70,7 @@ def _unwrap(func): class TestCompletionEndpoints: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers def test_completion_create_payload(self): @@ -86,7 +87,7 @@ class TestCompletionEndpoints: ) assert payload.query == "hi" - def test_completion_api_success(self, app, monkeypatch): + def test_completion_api_success(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = completion_module.CompletionMessageApi() method = _unwrap(api.post) @@ -116,7 +117,7 @@ class TestCompletionEndpoints: assert resp == {"result": {"text": "ok"}} - def test_completion_api_conversation_not_exists(self, app, monkeypatch): + def test_completion_api_conversation_not_exists(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = completion_module.CompletionMessageApi() method = _unwrap(api.post) @@ -142,7 +143,7 @@ class TestCompletionEndpoints: with pytest.raises(NotFound): method(app_model=MagicMock(id="app-1")) - def test_completion_api_provider_not_initialized(self, app, monkeypatch): + def test_completion_api_provider_not_initialized(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = completion_module.CompletionMessageApi() method = _unwrap(api.post) @@ -166,7 +167,7 @@ class TestCompletionEndpoints: with pytest.raises(completion_module.ProviderNotInitializeError): method(app_model=MagicMock(id="app-1")) - def test_completion_api_quota_exceeded(self, app, monkeypatch): + def test_completion_api_quota_exceeded(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = completion_module.CompletionMessageApi() method = _unwrap(api.post) @@ -193,10 +194,10 @@ class TestCompletionEndpoints: class TestAppEndpoints: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_app_put_should_preserve_icon_type_when_payload_omits_it(self, app, monkeypatch): + def test_app_put_should_preserve_icon_type_when_payload_omits_it(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = app_module.AppApi() method = _unwrap(api.put) payload = { @@ -234,7 +235,7 @@ class TestAppEndpoints: } ) - def test_app_icon_post_should_forward_icon_type(self, app, monkeypatch): + def test_app_icon_post_should_forward_icon_type(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = app_module.AppIconApi() method = _unwrap(api.post) payload = { @@ -266,7 +267,7 @@ class TestAppEndpoints: class TestOpsTraceEndpoints: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers def test_ops_trace_query_basic(self): @@ -277,7 +278,7 @@ class TestOpsTraceEndpoints: payload = TraceConfigPayload(tracing_provider="langfuse", tracing_config={"api_key": "k"}) assert payload.tracing_config["api_key"] == "k" - def test_trace_app_config_get_empty(self, app, monkeypatch): + def test_trace_app_config_get_empty(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = ops_trace_module.TraceAppConfigApi() method = _unwrap(api.get) @@ -292,7 +293,7 @@ class TestOpsTraceEndpoints: assert result == {"has_not_configured": True} - def test_trace_app_config_post_invalid(self, app, monkeypatch): + def test_trace_app_config_post_invalid(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = ops_trace_module.TraceAppConfigApi() method = _unwrap(api.post) @@ -309,7 +310,7 @@ class TestOpsTraceEndpoints: with pytest.raises(BadRequest): method(app_id="app-1") - def test_trace_app_config_delete_not_found(self, app, monkeypatch): + def test_trace_app_config_delete_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = ops_trace_module.TraceAppConfigApi() method = _unwrap(api.delete) @@ -326,7 +327,7 @@ class TestOpsTraceEndpoints: class TestSiteEndpoints: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers def test_site_response_structure(self): @@ -337,7 +338,7 @@ class TestSiteEndpoints: payload = AppSiteUpdatePayload(default_language="en-US") assert payload.default_language == "en-US" - def test_app_site_update_post(self, app, monkeypatch): + def test_app_site_update_post(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = site_module.AppSite() method = _unwrap(api.post) @@ -375,7 +376,7 @@ class TestSiteEndpoints: assert isinstance(result, dict) assert result["title"] == "My Site" - def test_app_site_access_token_reset(self, app, monkeypatch): + def test_app_site_access_token_reset(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = site_module.AppSiteAccessTokenReset() method = _unwrap(api.post) @@ -427,7 +428,7 @@ class TestWorkflowEndpoints: class TestWorkflowAppLogEndpoints: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers def test_workflow_app_log_query(self): @@ -438,7 +439,7 @@ class TestWorkflowAppLogEndpoints: query = WorkflowAppLogQuery(detail="true") assert query.detail is True - def test_workflow_app_log_api_get(self, app, monkeypatch): + def test_workflow_app_log_api_get(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = workflow_app_log_module.WorkflowAppLogApi() method = _unwrap(api.get) @@ -477,14 +478,14 @@ class TestWorkflowAppLogEndpoints: class TestWorkflowDraftVariableEndpoints: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers def test_workflow_variable_creation(self): payload = WorkflowDraftVariableUpdatePayload(name="var1", value="test") assert payload.name == "var1" - def test_workflow_variable_collection_get(self, app, monkeypatch): + def test_workflow_variable_collection_get(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = workflow_draft_variable_module.WorkflowVariableCollectionApi() method = _unwrap(api.get) @@ -529,7 +530,7 @@ class TestWorkflowDraftVariableEndpoints: class TestWorkflowStatisticEndpoints: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers def test_workflow_statistic_time_range(self): @@ -541,7 +542,7 @@ class TestWorkflowStatisticEndpoints: assert query.start is None assert query.end is None - def test_workflow_daily_runs_statistic(self, app, monkeypatch): + def test_workflow_daily_runs_statistic(self, app: Flask, monkeypatch: pytest.MonkeyPatch): monkeypatch.setattr(workflow_statistic_module, "db", SimpleNamespace(engine=MagicMock())) monkeypatch.setattr( workflow_statistic_module.DifyAPIRepositoryFactory, @@ -567,7 +568,7 @@ class TestWorkflowStatisticEndpoints: assert response.get_json() == {"data": [{"date": "2024-01-01"}]} - def test_workflow_daily_terminals_statistic(self, app, monkeypatch): + def test_workflow_daily_terminals_statistic(self, app: Flask, monkeypatch: pytest.MonkeyPatch): monkeypatch.setattr(workflow_statistic_module, "db", SimpleNamespace(engine=MagicMock())) monkeypatch.setattr( workflow_statistic_module.DifyAPIRepositoryFactory, @@ -598,7 +599,7 @@ class TestWorkflowStatisticEndpoints: class TestWorkflowTriggerEndpoints: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers def test_webhook_trigger_payload(self): @@ -608,7 +609,7 @@ class TestWorkflowTriggerEndpoints: enable_payload = ParserEnable(trigger_id="trigger-1", enable_trigger=True) assert enable_payload.enable_trigger is True - def test_webhook_trigger_api_get(self, app, monkeypatch): + def test_webhook_trigger_api_get(self, app: Flask, monkeypatch: pytest.MonkeyPatch): api = workflow_trigger_module.WebhookTriggerApi() method = _unwrap(api.get) diff --git a/api/tests/test_containers_integration_tests/controllers/console/app/test_app_import_api.py b/api/tests/test_containers_integration_tests/controllers/console/app/test_app_import_api.py index 25d19cf35a..bcb6e41ef7 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/app/test_app_import_api.py +++ b/api/tests/test_containers_integration_tests/controllers/console/app/test_app_import_api.py @@ -6,6 +6,7 @@ from types import SimpleNamespace from unittest.mock import MagicMock import pytest +from flask import Flask from controllers.console.app import app_import as app_import_module from services.app_dsl_service import ImportStatus @@ -36,10 +37,10 @@ def _install_features(monkeypatch: pytest.MonkeyPatch, enabled: bool) -> None: class TestAppImportApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_import_post_returns_failed_status(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_import_post_returns_failed_status(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: api = app_import_module.AppImportApi() method = _unwrap(api.post) @@ -57,7 +58,7 @@ class TestAppImportApi: assert status == 400 assert response["status"] == ImportStatus.FAILED - def test_import_post_returns_pending_status(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_import_post_returns_pending_status(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: api = app_import_module.AppImportApi() method = _unwrap(api.post) @@ -75,7 +76,7 @@ class TestAppImportApi: assert status == 202 assert response["status"] == ImportStatus.PENDING - def test_import_post_updates_webapp_auth_when_enabled(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_import_post_updates_webapp_auth_when_enabled(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: api = app_import_module.AppImportApi() method = _unwrap(api.post) @@ -96,7 +97,7 @@ class TestAppImportApi: assert status == 200 assert response["status"] == ImportStatus.COMPLETED - def test_import_post_commits_session_on_success(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_import_post_commits_session_on_success(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: api = app_import_module.AppImportApi() method = _unwrap(api.post) @@ -121,7 +122,7 @@ class TestAppImportApi: assert status == 200 assert response["status"] == ImportStatus.COMPLETED - def test_import_post_rolls_back_session_on_failure(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_import_post_rolls_back_session_on_failure(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: api = app_import_module.AppImportApi() method = _unwrap(api.post) @@ -149,10 +150,10 @@ class TestAppImportApi: class TestAppImportConfirmApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_import_confirm_returns_failed_status(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_import_confirm_returns_failed_status(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: api = app_import_module.AppImportConfirmApi() method = _unwrap(api.post) @@ -172,10 +173,10 @@ class TestAppImportConfirmApi: class TestAppImportCheckDependenciesApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_import_check_dependencies_returns_result(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_import_check_dependencies_returns_result(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: api = app_import_module.AppImportCheckDependenciesApi() method = _unwrap(api.get) diff --git a/api/tests/test_containers_integration_tests/controllers/console/auth/test_email_register.py b/api/tests/test_containers_integration_tests/controllers/console/auth/test_email_register.py index 320da85b60..1fcce9ca44 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/auth/test_email_register.py +++ b/api/tests/test_containers_integration_tests/controllers/console/auth/test_email_register.py @@ -6,6 +6,7 @@ from types import SimpleNamespace from unittest.mock import MagicMock, patch import pytest +from flask import Flask from controllers.console.auth.email_register import ( EmailRegisterCheckApi, @@ -16,7 +17,7 @@ from services.account_service import AccountService @pytest.fixture -def app(flask_app_with_containers): +def app(flask_app_with_containers: Flask): return flask_app_with_containers @@ -33,7 +34,7 @@ class TestEmailRegisterSendEmailApi: mock_is_freeze, mock_send_mail, mock_get_account, - app, + app: Flask, ): mock_send_mail.return_value = "token-123" mock_is_freeze.return_value = False @@ -75,7 +76,7 @@ class TestEmailRegisterCheckApi: mock_revoke, mock_generate_token, mock_reset_rate, - app, + app: Flask, ): mock_rate_limit_check.return_value = False mock_get_data.return_value = {"email": "User@Example.com", "code": "4321"} @@ -120,7 +121,7 @@ class TestEmailRegisterResetApi: mock_create_account, mock_login, mock_reset_login_rate, - app, + app: Flask, ): mock_get_data.return_value = {"phase": "register", "email": "Invitee@Example.com"} mock_create_account.return_value = MagicMock() diff --git a/api/tests/test_containers_integration_tests/controllers/console/auth/test_forgot_password.py b/api/tests/test_containers_integration_tests/controllers/console/auth/test_forgot_password.py index d2703ed5cc..014c1588fe 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/auth/test_forgot_password.py +++ b/api/tests/test_containers_integration_tests/controllers/console/auth/test_forgot_password.py @@ -6,6 +6,7 @@ from types import SimpleNamespace from unittest.mock import MagicMock, patch import pytest +from flask import Flask from controllers.console.auth.forgot_password import ( ForgotPasswordCheckApi, @@ -16,7 +17,7 @@ from services.account_service import AccountService @pytest.fixture -def app(flask_app_with_containers): +def app(flask_app_with_containers: Flask): return flask_app_with_containers @@ -31,7 +32,7 @@ class TestForgotPasswordSendEmailApi: mock_is_ip_limit, mock_send_email, mock_get_account, - app, + app: Flask, ): mock_account = MagicMock() mock_get_account.return_value = mock_account @@ -80,7 +81,7 @@ class TestForgotPasswordCheckApi: mock_revoke_token, mock_generate_token, mock_reset_rate, - app, + app: Flask, ): mock_rate_limit_check.return_value = False mock_get_data.return_value = {"email": "Admin@Example.com", "code": "4321"} @@ -123,7 +124,7 @@ class TestForgotPasswordResetApi: mock_db, mock_get_account, mock_update_account, - app, + app: Flask, ): mock_get_reset_data.return_value = {"phase": "reset", "email": "User@Example.com"} mock_account = MagicMock() diff --git a/api/tests/test_containers_integration_tests/controllers/console/auth/test_oauth.py b/api/tests/test_containers_integration_tests/controllers/console/auth/test_oauth.py index 1eabb45422..55b6a919d8 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/auth/test_oauth.py +++ b/api/tests/test_containers_integration_tests/controllers/console/auth/test_oauth.py @@ -5,6 +5,7 @@ from __future__ import annotations from unittest.mock import MagicMock, patch import pytest +from flask import Flask from controllers.console.auth.oauth import ( OAuthCallback, @@ -21,7 +22,7 @@ from services.errors.account import AccountRegisterError class TestGetOAuthProviders: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers @pytest.mark.parametrize( @@ -65,7 +66,7 @@ class TestOAuthLogin: return OAuthLogin() @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers @pytest.fixture @@ -89,7 +90,7 @@ class TestOAuthLogin: mock_redirect, mock_get_providers, resource, - app, + app: Flask, mock_oauth_provider, invite_token, expected_token, @@ -130,7 +131,7 @@ class TestOAuthCallback: return OAuthCallback() @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers @pytest.fixture @@ -164,7 +165,7 @@ class TestOAuthCallback: mock_get_providers, mock_config, resource, - app, + app: Flask, oauth_setup, ): mock_config.CONSOLE_WEB_URL = "http://localhost:3000" @@ -217,7 +218,7 @@ class TestOAuthCallback: mock_get_providers, mock_config, resource, - app, + app: Flask, oauth_setup, ): mock_config.CONSOLE_WEB_URL = "http://localhost:3000" @@ -261,7 +262,7 @@ class TestOAuthCallback: mock_tenant_service, mock_account_service, resource, - app, + app: Flask, oauth_setup, account_status, expected_redirect, @@ -300,7 +301,7 @@ class TestOAuthCallback: mock_get_providers, mock_config, resource, - app, + app: Flask, oauth_setup, ): mock_get_providers.return_value = {"github": oauth_setup["provider"]} @@ -336,7 +337,7 @@ class TestOAuthCallback: mock_get_providers, mock_config, resource, - app, + app: Flask, oauth_setup, ): """Defensive test for CLOSED account status handling in OAuth callback. @@ -394,7 +395,7 @@ class TestOAuthCallback: class TestAccountGeneration: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers @pytest.fixture @@ -465,7 +466,7 @@ class TestAccountGeneration: mock_register_service, mock_feature_service, mock_get_account, - app, + app: Flask, user_info, mock_account, allow_register, @@ -504,7 +505,7 @@ class TestAccountGeneration: mock_register_service, mock_feature_service, mock_get_account, - app, + app: Flask, ): user_info = OAuthUserInfo(id="123", name="Test User", email="Upper@Example.com") mock_feature_service.get_system_features.return_value.is_allow_register = True @@ -529,7 +530,7 @@ class TestAccountGeneration: mock_feature_service, mock_tenant_service, mock_get_account, - app, + app: Flask, user_info, mock_account, ): diff --git a/api/tests/test_containers_integration_tests/controllers/console/auth/test_password_reset.py b/api/tests/test_containers_integration_tests/controllers/console/auth/test_password_reset.py index 50249bcd74..d017e8f2bd 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/auth/test_password_reset.py +++ b/api/tests/test_containers_integration_tests/controllers/console/auth/test_password_reset.py @@ -5,6 +5,7 @@ from __future__ import annotations from unittest.mock import MagicMock, patch import pytest +from flask import Flask from controllers.console.auth.error import ( EmailCodeError, @@ -25,7 +26,7 @@ class TestForgotPasswordSendEmailApi: """Test cases for sending password reset emails.""" @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers @pytest.fixture @@ -46,7 +47,7 @@ class TestForgotPasswordSendEmailApi: mock_send_email, mock_get_account, mock_is_ip_limit, - app, + app: Flask, mock_account, ): # Arrange @@ -68,7 +69,7 @@ class TestForgotPasswordSendEmailApi: mock_send_email.assert_called_once() @patch("controllers.console.auth.forgot_password.AccountService.is_email_send_ip_limit") - def test_send_reset_email_ip_rate_limited(self, mock_is_ip_limit, app): + def test_send_reset_email_ip_rate_limited(self, mock_is_ip_limit, app: Flask): """ Test password reset email blocked by IP rate limit. @@ -104,7 +105,7 @@ class TestForgotPasswordSendEmailApi: mock_send_email, mock_get_account, mock_is_ip_limit, - app, + app: Flask, mock_account, language_input, expected_language, @@ -138,7 +139,7 @@ class TestForgotPasswordCheckApi: """Test cases for verifying password reset codes.""" @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers @patch("controllers.console.auth.forgot_password.AccountService.is_forgot_password_error_rate_limit") @@ -153,7 +154,7 @@ class TestForgotPasswordCheckApi: mock_revoke_token, mock_get_data, mock_is_rate_limit, - app, + app: Flask, ): """ Test successful verification code validation. @@ -200,7 +201,7 @@ class TestForgotPasswordCheckApi: mock_revoke_token, mock_get_data, mock_is_rate_limit, - app, + app: Flask, ): mock_is_rate_limit.return_value = False mock_get_data.return_value = {"email": "User@Example.com", "code": "999888"} @@ -221,7 +222,7 @@ class TestForgotPasswordCheckApi: mock_reset_rate_limit.assert_called_once_with("user@example.com") @patch("controllers.console.auth.forgot_password.AccountService.is_forgot_password_error_rate_limit") - def test_verify_code_rate_limited(self, mock_is_rate_limit, app): + def test_verify_code_rate_limited(self, mock_is_rate_limit, app: Flask): """ Test code verification blocked by rate limit. @@ -244,7 +245,7 @@ class TestForgotPasswordCheckApi: @patch("controllers.console.auth.forgot_password.AccountService.is_forgot_password_error_rate_limit") @patch("controllers.console.auth.forgot_password.AccountService.get_reset_password_data") - def test_verify_code_invalid_token(self, mock_get_data, mock_is_rate_limit, app): + def test_verify_code_invalid_token(self, mock_get_data, mock_is_rate_limit, app: Flask): """ Test code verification with invalid token. @@ -267,7 +268,7 @@ class TestForgotPasswordCheckApi: @patch("controllers.console.auth.forgot_password.AccountService.is_forgot_password_error_rate_limit") @patch("controllers.console.auth.forgot_password.AccountService.get_reset_password_data") - def test_verify_code_email_mismatch(self, mock_get_data, mock_is_rate_limit, app): + def test_verify_code_email_mismatch(self, mock_get_data, mock_is_rate_limit, app: Flask): """ Test code verification with mismatched email. @@ -292,7 +293,7 @@ class TestForgotPasswordCheckApi: @patch("controllers.console.auth.forgot_password.AccountService.is_forgot_password_error_rate_limit") @patch("controllers.console.auth.forgot_password.AccountService.get_reset_password_data") @patch("controllers.console.auth.forgot_password.AccountService.add_forgot_password_error_rate_limit") - def test_verify_code_wrong_code(self, mock_add_rate_limit, mock_get_data, mock_is_rate_limit, app): + def test_verify_code_wrong_code(self, mock_add_rate_limit, mock_get_data, mock_is_rate_limit, app: Flask): """ Test code verification with incorrect code. @@ -321,7 +322,7 @@ class TestForgotPasswordResetApi: """Test cases for resetting password with verified token.""" @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers @pytest.fixture @@ -344,7 +345,7 @@ class TestForgotPasswordResetApi: mock_get_account, mock_revoke_token, mock_get_data, - app, + app: Flask, mock_account, ): """ @@ -375,7 +376,7 @@ class TestForgotPasswordResetApi: mock_revoke_token.assert_called_once_with("valid_token") @patch("controllers.console.auth.forgot_password.AccountService.get_reset_password_data") - def test_reset_password_mismatch(self, mock_get_data, app): + def test_reset_password_mismatch(self, mock_get_data, app: Flask): """ Test password reset with mismatched passwords. @@ -397,7 +398,7 @@ class TestForgotPasswordResetApi: api.post() @patch("controllers.console.auth.forgot_password.AccountService.get_reset_password_data") - def test_reset_password_invalid_token(self, mock_get_data, app): + def test_reset_password_invalid_token(self, mock_get_data, app: Flask): """ Test password reset with invalid token. @@ -418,7 +419,7 @@ class TestForgotPasswordResetApi: api.post() @patch("controllers.console.auth.forgot_password.AccountService.get_reset_password_data") - def test_reset_password_wrong_phase(self, mock_get_data, app): + def test_reset_password_wrong_phase(self, mock_get_data, app: Flask): """ Test password reset with token not in reset phase. @@ -442,7 +443,7 @@ class TestForgotPasswordResetApi: @patch("controllers.console.auth.forgot_password.AccountService.get_reset_password_data") @patch("controllers.console.auth.forgot_password.AccountService.revoke_reset_password_token") @patch("controllers.console.auth.forgot_password.AccountService.get_account_by_email_with_case_fallback") - def test_reset_password_account_not_found(self, mock_get_account, mock_revoke_token, mock_get_data, app): + def test_reset_password_account_not_found(self, mock_get_account, mock_revoke_token, mock_get_data, app: Flask): """ Test password reset for non-existent account. diff --git a/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline.py b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline.py index d5ae95dfb7..7aa4aff1cc 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline.py +++ b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline.py @@ -6,6 +6,7 @@ from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest +from flask import Flask from sqlalchemy.orm import Session from controllers.console import console_ns @@ -26,10 +27,10 @@ def unwrap(func): class TestPipelineTemplateListApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = PipelineTemplateListApi() method = unwrap(api.get) @@ -50,10 +51,10 @@ class TestPipelineTemplateListApi: class TestPipelineTemplateDetailApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = PipelineTemplateDetailApi() method = unwrap(api.get) @@ -74,7 +75,7 @@ class TestPipelineTemplateDetailApi: assert status == 200 assert response == template - def test_get_returns_404_when_template_not_found(self, app): + def test_get_returns_404_when_template_not_found(self, app: Flask): api = PipelineTemplateDetailApi() method = unwrap(api.get) @@ -93,7 +94,7 @@ class TestPipelineTemplateDetailApi: assert status == 404 assert "error" in response - def test_get_returns_404_for_customized_type_not_found(self, app): + def test_get_returns_404_for_customized_type_not_found(self, app: Flask): api = PipelineTemplateDetailApi() method = unwrap(api.get) @@ -115,10 +116,10 @@ class TestPipelineTemplateDetailApi: class TestCustomizedPipelineTemplateApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_patch_success(self, app): + def test_patch_success(self, app: Flask): api = CustomizedPipelineTemplateApi() method = unwrap(api.patch) @@ -140,7 +141,7 @@ class TestCustomizedPipelineTemplateApi: update_mock.assert_called_once() assert response == 200 - def test_delete_success(self, app): + def test_delete_success(self, app: Flask): api = CustomizedPipelineTemplateApi() method = unwrap(api.delete) @@ -155,7 +156,7 @@ class TestCustomizedPipelineTemplateApi: delete_mock.assert_called_once_with("tpl-1") assert response == 200 - def test_post_success(self, app, db_session_with_containers: Session): + def test_post_success(self, app: Flask, db_session_with_containers: Session): api = CustomizedPipelineTemplateApi() method = unwrap(api.post) @@ -182,7 +183,7 @@ class TestCustomizedPipelineTemplateApi: assert status == 200 assert response == {"data": "yaml-data"} - def test_post_template_not_found(self, app): + def test_post_template_not_found(self, app: Flask): api = CustomizedPipelineTemplateApi() method = unwrap(api.post) @@ -193,10 +194,10 @@ class TestCustomizedPipelineTemplateApi: class TestPublishCustomizedPipelineTemplateApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = PublishCustomizedPipelineTemplateApi() method = unwrap(api.post) diff --git a/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_datasets.py b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_datasets.py index 64e3de2ca3..7624c1150f 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_datasets.py +++ b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_datasets.py @@ -5,6 +5,7 @@ from __future__ import annotations from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.exceptions import Forbidden import services @@ -24,13 +25,13 @@ def unwrap(func): class TestCreateRagPipelineDatasetApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers def _valid_payload(self): return {"yaml_content": "name: test"} - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = CreateRagPipelineDatasetApi() method = unwrap(api.post) @@ -58,7 +59,7 @@ class TestCreateRagPipelineDatasetApi: assert status == 201 assert response == import_info - def test_post_forbidden_non_editor(self, app): + def test_post_forbidden_non_editor(self, app: Flask): api = CreateRagPipelineDatasetApi() method = unwrap(api.post) @@ -76,7 +77,7 @@ class TestCreateRagPipelineDatasetApi: with pytest.raises(Forbidden): method(api) - def test_post_dataset_name_duplicate(self, app): + def test_post_dataset_name_duplicate(self, app: Flask): api = CreateRagPipelineDatasetApi() method = unwrap(api.post) @@ -101,7 +102,7 @@ class TestCreateRagPipelineDatasetApi: with pytest.raises(DatasetNameDuplicateError): method(api) - def test_post_invalid_payload(self, app): + def test_post_invalid_payload(self, app: Flask): api = CreateRagPipelineDatasetApi() method = unwrap(api.post) @@ -122,10 +123,10 @@ class TestCreateRagPipelineDatasetApi: class TestCreateEmptyRagPipelineDatasetApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = CreateEmptyRagPipelineDatasetApi() method = unwrap(api.post) @@ -152,7 +153,7 @@ class TestCreateEmptyRagPipelineDatasetApi: assert status == 201 assert response == {"id": "ds-1"} - def test_post_forbidden_non_editor(self, app): + def test_post_forbidden_non_editor(self, app: Flask): api = CreateEmptyRagPipelineDatasetApi() method = unwrap(api.post) diff --git a/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_import.py b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_import.py index cb67892878..44eb5c336c 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_import.py +++ b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_import.py @@ -5,6 +5,7 @@ from __future__ import annotations from unittest.mock import MagicMock, patch import pytest +from flask import Flask from controllers.console import console_ns from controllers.console.datasets.rag_pipeline.rag_pipeline_import import ( @@ -25,7 +26,7 @@ def unwrap(func): class TestRagPipelineImportApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers def _payload(self, mode="create"): @@ -35,7 +36,7 @@ class TestRagPipelineImportApi: "name": "Test", } - def test_post_success_200(self, app): + def test_post_success_200(self, app: Flask): api = RagPipelineImportApi() method = unwrap(api.post) @@ -65,7 +66,7 @@ class TestRagPipelineImportApi: assert status == 200 assert response == {"status": "success"} - def test_post_failed_400(self, app): + def test_post_failed_400(self, app: Flask): api = RagPipelineImportApi() method = unwrap(api.post) @@ -95,7 +96,7 @@ class TestRagPipelineImportApi: assert status == 400 assert response == {"status": "failed"} - def test_post_pending_202(self, app): + def test_post_pending_202(self, app: Flask): api = RagPipelineImportApi() method = unwrap(api.post) @@ -128,10 +129,10 @@ class TestRagPipelineImportApi: class TestRagPipelineImportConfirmApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_confirm_success(self, app): + def test_confirm_success(self, app: Flask): api = RagPipelineImportConfirmApi() method = unwrap(api.post) @@ -159,7 +160,7 @@ class TestRagPipelineImportConfirmApi: assert status == 200 assert response == {"ok": True} - def test_confirm_failed(self, app): + def test_confirm_failed(self, app: Flask): api = RagPipelineImportConfirmApi() method = unwrap(api.post) @@ -190,10 +191,10 @@ class TestRagPipelineImportConfirmApi: class TestRagPipelineImportCheckDependenciesApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = RagPipelineImportCheckDependenciesApi() method = unwrap(api.get) @@ -219,10 +220,10 @@ class TestRagPipelineImportCheckDependenciesApi: class TestRagPipelineExportApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_with_include_secret(self, app): + def test_get_with_include_secret(self, app: Flask): api = RagPipelineExportApi() method = unwrap(api.get) diff --git a/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_workflow.py b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_workflow.py index c1f3122c2b..c17a83cad3 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_workflow.py +++ b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_workflow.py @@ -7,6 +7,7 @@ from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest +from flask import Flask from sqlalchemy.orm import Session from werkzeug.exceptions import BadRequest, Forbidden, HTTPException, NotFound @@ -45,10 +46,10 @@ def unwrap(func): class TestDraftWorkflowApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_draft_success(self, app): + def test_get_draft_success(self, app: Flask): api = DraftRagPipelineApi() method = unwrap(api.get) @@ -68,7 +69,7 @@ class TestDraftWorkflowApi: result = method(api, pipeline) assert result == workflow - def test_get_draft_not_exist(self, app): + def test_get_draft_not_exist(self, app: Flask): api = DraftRagPipelineApi() method = unwrap(api.get) @@ -86,7 +87,7 @@ class TestDraftWorkflowApi: with pytest.raises(DraftWorkflowNotExist): method(api, pipeline) - def test_sync_hash_not_match(self, app): + def test_sync_hash_not_match(self, app: Flask): api = DraftRagPipelineApi() method = unwrap(api.post) @@ -111,7 +112,7 @@ class TestDraftWorkflowApi: with pytest.raises(DraftWorkflowNotSync): method(api, pipeline) - def test_sync_invalid_text_plain(self, app): + def test_sync_invalid_text_plain(self, app: Flask): api = DraftRagPipelineApi() method = unwrap(api.post) @@ -128,7 +129,7 @@ class TestDraftWorkflowApi: response, status = method(api, pipeline) assert status == 400 - def test_restore_published_workflow_to_draft_success(self, app): + def test_restore_published_workflow_to_draft_success(self, app: Flask): api = RagPipelineDraftWorkflowRestoreApi() method = unwrap(api.post) @@ -155,7 +156,7 @@ class TestDraftWorkflowApi: assert result["result"] == "success" assert result["hash"] == "restored-hash" - def test_restore_published_workflow_to_draft_not_found(self, app): + def test_restore_published_workflow_to_draft_not_found(self, app: Flask): api = RagPipelineDraftWorkflowRestoreApi() method = unwrap(api.post) @@ -179,7 +180,7 @@ class TestDraftWorkflowApi: with pytest.raises(NotFound): method(api, pipeline, "published-workflow") - def test_restore_published_workflow_to_draft_returns_400_for_draft_source(self, app): + def test_restore_published_workflow_to_draft_returns_400_for_draft_source(self, app: Flask): api = RagPipelineDraftWorkflowRestoreApi() method = unwrap(api.post) @@ -211,10 +212,10 @@ class TestDraftWorkflowApi: class TestDraftRunNodes: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_iteration_node_success(self, app): + def test_iteration_node_success(self, app: Flask): api = RagPipelineDraftRunIterationNodeApi() method = unwrap(api.post) @@ -240,7 +241,7 @@ class TestDraftRunNodes: result = method(api, pipeline, "node") assert result == {"ok": True} - def test_iteration_node_conversation_not_exists(self, app): + def test_iteration_node_conversation_not_exists(self, app: Flask): api = RagPipelineDraftRunIterationNodeApi() method = unwrap(api.post) @@ -262,7 +263,7 @@ class TestDraftRunNodes: with pytest.raises(NotFound): method(api, pipeline, "node") - def test_loop_node_success(self, app): + def test_loop_node_success(self, app: Flask): api = RagPipelineDraftRunLoopNodeApi() method = unwrap(api.post) @@ -290,10 +291,10 @@ class TestDraftRunNodes: class TestPipelineRunApis: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_draft_run_success(self, app): + def test_draft_run_success(self, app: Flask): api = DraftRagPipelineRunApi() method = unwrap(api.post) @@ -325,7 +326,7 @@ class TestPipelineRunApis: ): assert method(api, pipeline) == {"ok": True} - def test_draft_run_rate_limit(self, app): + def test_draft_run_rate_limit(self, app: Flask): api = DraftRagPipelineRunApi() method = unwrap(api.post) @@ -356,10 +357,10 @@ class TestPipelineRunApis: class TestDraftNodeRun: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_execution_not_found(self, app): + def test_execution_not_found(self, app: Flask): api = RagPipelineDraftNodeRunApi() method = unwrap(api.post) @@ -387,10 +388,10 @@ class TestDraftNodeRun: class TestPublishedPipelineApis: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_publish_success(self, app, db_session_with_containers: Session): + def test_publish_success(self, app: Flask, db_session_with_containers: Session): from models.dataset import Pipeline api = PublishedRagPipelineApi() @@ -436,10 +437,10 @@ class TestPublishedPipelineApis: class TestMiscApis: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_task_stop(self, app): + def test_task_stop(self, app: Flask): api = RagPipelineTaskStopApi() method = unwrap(api.post) @@ -460,7 +461,7 @@ class TestMiscApis: stop_mock.assert_called_once() assert result["result"] == "success" - def test_transform_forbidden(self, app): + def test_transform_forbidden(self, app: Flask): api = RagPipelineTransformApi() method = unwrap(api.post) @@ -476,7 +477,7 @@ class TestMiscApis: with pytest.raises(Forbidden): method(api, "ds1") - def test_recommended_plugins(self, app): + def test_recommended_plugins(self, app: Flask): api = RagPipelineRecommendedPluginApi() method = unwrap(api.get) @@ -496,10 +497,10 @@ class TestMiscApis: class TestPublishedRagPipelineRunApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_published_run_success(self, app): + def test_published_run_success(self, app: Flask): api = PublishedRagPipelineRunApi() method = unwrap(api.post) @@ -533,7 +534,7 @@ class TestPublishedRagPipelineRunApi: result = method(api, pipeline) assert result == {"ok": True} - def test_published_run_rate_limit(self, app): + def test_published_run_rate_limit(self, app: Flask): api = PublishedRagPipelineRunApi() method = unwrap(api.post) @@ -565,10 +566,10 @@ class TestPublishedRagPipelineRunApi: class TestDefaultBlockConfigApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_block_config_success(self, app): + def test_get_block_config_success(self, app: Flask): api = DefaultRagPipelineBlockConfigApi() method = unwrap(api.get) @@ -587,7 +588,7 @@ class TestDefaultBlockConfigApi: result = method(api, pipeline, "llm") assert result == {"k": "v"} - def test_get_block_config_invalid_json(self, app): + def test_get_block_config_invalid_json(self, app: Flask): api = DefaultRagPipelineBlockConfigApi() method = unwrap(api.get) @@ -600,10 +601,10 @@ class TestDefaultBlockConfigApi: class TestPublishedAllRagPipelineApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_published_workflows_success(self, app): + def test_get_published_workflows_success(self, app: Flask): api = PublishedAllRagPipelineApi() method = unwrap(api.get) @@ -629,7 +630,7 @@ class TestPublishedAllRagPipelineApi: assert result["items"] == [{"id": "w1"}] assert result["has_more"] is False - def test_get_published_workflows_forbidden(self, app): + def test_get_published_workflows_forbidden(self, app: Flask): api = PublishedAllRagPipelineApi() method = unwrap(api.get) @@ -649,10 +650,10 @@ class TestPublishedAllRagPipelineApi: class TestRagPipelineByIdApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_patch_success(self, app): + def test_patch_success(self, app: Flask): api = RagPipelineByIdApi() method = unwrap(api.patch) @@ -682,7 +683,7 @@ class TestRagPipelineByIdApi: assert result == workflow - def test_patch_no_fields(self, app): + def test_patch_no_fields(self, app: Flask): api = RagPipelineByIdApi() method = unwrap(api.patch) @@ -700,7 +701,7 @@ class TestRagPipelineByIdApi: result, status = method(api, pipeline, "w1") assert status == 400 - def test_delete_success(self, app): + def test_delete_success(self, app: Flask): api = RagPipelineByIdApi() method = unwrap(api.delete) @@ -720,7 +721,7 @@ class TestRagPipelineByIdApi: workflow_service.delete_workflow.assert_called_once() assert result == (None, 204) - def test_delete_active_workflow_rejected(self, app): + def test_delete_active_workflow_rejected(self, app: Flask): api = RagPipelineByIdApi() method = unwrap(api.delete) @@ -733,10 +734,10 @@ class TestRagPipelineByIdApi: class TestRagPipelineWorkflowLastRunApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_last_run_success(self, app): + def test_last_run_success(self, app: Flask): api = RagPipelineWorkflowLastRunApi() method = unwrap(api.get) @@ -758,7 +759,7 @@ class TestRagPipelineWorkflowLastRunApi: result = method(api, pipeline, "node1") assert result == node_exec - def test_last_run_not_found(self, app): + def test_last_run_not_found(self, app: Flask): api = RagPipelineWorkflowLastRunApi() method = unwrap(api.get) @@ -780,10 +781,10 @@ class TestRagPipelineWorkflowLastRunApi: class TestRagPipelineDatasourceVariableApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_set_datasource_variables_success(self, app): + def test_set_datasource_variables_success(self, app: Flask): api = RagPipelineDatasourceVariableApi() method = unwrap(api.post) diff --git a/api/tests/test_containers_integration_tests/controllers/console/datasets/test_data_source.py b/api/tests/test_containers_integration_tests/controllers/console/datasets/test_data_source.py index 1c4c6a899f..b59009f7c4 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/datasets/test_data_source.py +++ b/api/tests/test_containers_integration_tests/controllers/console/datasets/test_data_source.py @@ -5,6 +5,7 @@ from __future__ import annotations from unittest.mock import MagicMock, PropertyMock, patch import pytest +from flask import Flask from werkzeug.exceptions import NotFound from controllers.console.datasets import data_source @@ -51,10 +52,10 @@ def mock_engine(): class TestDataSourceApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_success(self, app, patch_tenant): + def test_get_success(self, app: Flask, patch_tenant): api = DataSourceApi() method = unwrap(api.get) @@ -78,7 +79,7 @@ class TestDataSourceApi: assert status == 200 assert response["data"][0]["is_bound"] is True - def test_get_no_bindings(self, app, patch_tenant): + def test_get_no_bindings(self, app: Flask, patch_tenant): api = DataSourceApi() method = unwrap(api.get) @@ -94,7 +95,7 @@ class TestDataSourceApi: assert status == 200 assert response["data"] == [] - def test_patch_enable_binding(self, app, patch_tenant, mock_engine): + def test_patch_enable_binding(self, app: Flask, patch_tenant, mock_engine): api = DataSourceApi() method = unwrap(api.patch) @@ -115,7 +116,7 @@ class TestDataSourceApi: assert status == 200 assert binding.disabled is False - def test_patch_disable_binding(self, app, patch_tenant, mock_engine): + def test_patch_disable_binding(self, app: Flask, patch_tenant, mock_engine): api = DataSourceApi() method = unwrap(api.patch) @@ -136,7 +137,7 @@ class TestDataSourceApi: assert status == 200 assert binding.disabled is True - def test_patch_binding_not_found(self, app, patch_tenant, mock_engine): + def test_patch_binding_not_found(self, app: Flask, patch_tenant, mock_engine): api = DataSourceApi() method = unwrap(api.patch) @@ -151,7 +152,7 @@ class TestDataSourceApi: with pytest.raises(NotFound): method(api, "b1", "enable") - def test_patch_enable_already_enabled(self, app, patch_tenant, mock_engine): + def test_patch_enable_already_enabled(self, app: Flask, patch_tenant, mock_engine): api = DataSourceApi() method = unwrap(api.patch) @@ -168,7 +169,7 @@ class TestDataSourceApi: with pytest.raises(ValueError): method(api, "b1", "enable") - def test_patch_disable_already_disabled(self, app, patch_tenant, mock_engine): + def test_patch_disable_already_disabled(self, app: Flask, patch_tenant, mock_engine): api = DataSourceApi() method = unwrap(api.patch) @@ -188,10 +189,10 @@ class TestDataSourceApi: class TestDataSourceNotionListApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_credential_not_found(self, app, patch_tenant): + def test_get_credential_not_found(self, app: Flask, patch_tenant): api = DataSourceNotionListApi() method = unwrap(api.get) @@ -205,7 +206,7 @@ class TestDataSourceNotionListApi: with pytest.raises(NotFound): method(api) - def test_get_success_no_dataset_id(self, app, patch_tenant, mock_engine): + def test_get_success_no_dataset_id(self, app: Flask, patch_tenant, mock_engine): api = DataSourceNotionListApi() method = unwrap(api.get) @@ -246,7 +247,7 @@ class TestDataSourceNotionListApi: assert status == 200 - def test_get_success_with_dataset_id(self, app, patch_tenant, mock_engine): + def test_get_success_with_dataset_id(self, app: Flask, patch_tenant, mock_engine): api = DataSourceNotionListApi() method = unwrap(api.get) @@ -299,7 +300,7 @@ class TestDataSourceNotionListApi: assert status == 200 - def test_get_invalid_dataset_type(self, app, patch_tenant, mock_engine): + def test_get_invalid_dataset_type(self, app: Flask, patch_tenant, mock_engine): api = DataSourceNotionListApi() method = unwrap(api.get) @@ -323,10 +324,10 @@ class TestDataSourceNotionListApi: class TestDataSourceNotionApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_preview_success(self, app, patch_tenant): + def test_get_preview_success(self, app: Flask, patch_tenant): api = DataSourceNotionApi() method = unwrap(api.get) @@ -347,7 +348,7 @@ class TestDataSourceNotionApi: assert status == 200 - def test_post_indexing_estimate_success(self, app, patch_tenant): + def test_post_indexing_estimate_success(self, app: Flask, patch_tenant): api = DataSourceNotionApi() method = unwrap(api.post) @@ -381,10 +382,10 @@ class TestDataSourceNotionApi: class TestDataSourceNotionDatasetSyncApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_success(self, app, patch_tenant): + def test_get_success(self, app: Flask, patch_tenant): api = DataSourceNotionDatasetSyncApi() method = unwrap(api.get) @@ -407,7 +408,7 @@ class TestDataSourceNotionDatasetSyncApi: assert status == 200 - def test_get_dataset_not_found(self, app, patch_tenant): + def test_get_dataset_not_found(self, app: Flask, patch_tenant): api = DataSourceNotionDatasetSyncApi() method = unwrap(api.get) @@ -424,10 +425,10 @@ class TestDataSourceNotionDatasetSyncApi: class TestDataSourceNotionDocumentSyncApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_success(self, app, patch_tenant): + def test_get_success(self, app: Flask, patch_tenant): api = DataSourceNotionDocumentSyncApi() method = unwrap(api.get) @@ -450,7 +451,7 @@ class TestDataSourceNotionDocumentSyncApi: assert status == 200 - def test_get_document_not_found(self, app, patch_tenant): + def test_get_document_not_found(self, app: Flask, patch_tenant): api = DataSourceNotionDocumentSyncApi() method = unwrap(api.get) diff --git a/api/tests/test_containers_integration_tests/controllers/console/explore/test_conversation.py b/api/tests/test_containers_integration_tests/controllers/console/explore/test_conversation.py index 83492048ef..917aa35fe6 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/explore/test_conversation.py +++ b/api/tests/test_containers_integration_tests/controllers/console/explore/test_conversation.py @@ -5,6 +5,7 @@ from __future__ import annotations from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.exceptions import NotFound import controllers.console.explore.conversation as conversation_module @@ -53,10 +54,10 @@ def user(): class TestConversationListApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_success(self, app, chat_app, user): + def test_get_success(self, app: Flask, chat_app, user): api = conversation_module.ConversationListApi() method = unwrap(api.get) @@ -81,7 +82,7 @@ class TestConversationListApi: assert result["has_more"] is False assert len(result["data"]) == 2 - def test_last_conversation_not_exists(self, app, chat_app, user): + def test_last_conversation_not_exists(self, app: Flask, chat_app, user): api = conversation_module.ConversationListApi() method = unwrap(api.get) @@ -97,7 +98,7 @@ class TestConversationListApi: with pytest.raises(NotFound): method(chat_app) - def test_wrong_app_mode(self, app, non_chat_app): + def test_wrong_app_mode(self, app: Flask, non_chat_app): api = conversation_module.ConversationListApi() method = unwrap(api.get) @@ -108,10 +109,10 @@ class TestConversationListApi: class TestConversationApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_delete_success(self, app, chat_app, user): + def test_delete_success(self, app: Flask, chat_app, user): api = conversation_module.ConversationApi() method = unwrap(api.delete) @@ -129,7 +130,7 @@ class TestConversationApi: assert status == 204 assert body["result"] == "success" - def test_delete_not_found(self, app, chat_app, user): + def test_delete_not_found(self, app: Flask, chat_app, user): api = conversation_module.ConversationApi() method = unwrap(api.delete) @@ -145,7 +146,7 @@ class TestConversationApi: with pytest.raises(NotFound): method(chat_app, "cid") - def test_delete_wrong_app_mode(self, app, non_chat_app): + def test_delete_wrong_app_mode(self, app: Flask, non_chat_app): api = conversation_module.ConversationApi() method = unwrap(api.delete) @@ -156,10 +157,10 @@ class TestConversationApi: class TestConversationRenameApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_rename_success(self, app, chat_app, user): + def test_rename_success(self, app: Flask, chat_app, user): api = conversation_module.ConversationRenameApi() method = unwrap(api.post) @@ -178,7 +179,7 @@ class TestConversationRenameApi: assert result["id"] == "cid" - def test_rename_not_found(self, app, chat_app, user): + def test_rename_not_found(self, app: Flask, chat_app, user): api = conversation_module.ConversationRenameApi() method = unwrap(api.post) @@ -197,10 +198,10 @@ class TestConversationRenameApi: class TestConversationPinApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_pin_success(self, app, chat_app, user): + def test_pin_success(self, app: Flask, chat_app, user): api = conversation_module.ConversationPinApi() method = unwrap(api.patch) @@ -219,10 +220,10 @@ class TestConversationPinApi: class TestConversationUnPinApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_unpin_success(self, app, chat_app, user): + def test_unpin_success(self, app: Flask, chat_app, user): api = conversation_module.ConversationUnPinApi() method = unwrap(api.patch) diff --git a/api/tests/test_containers_integration_tests/controllers/console/workspace/test_tool_provider.py b/api/tests/test_containers_integration_tests/controllers/console/workspace/test_tool_provider.py index f2e7104b18..d944613886 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/workspace/test_tool_provider.py +++ b/api/tests/test_containers_integration_tests/controllers/console/workspace/test_tool_provider.py @@ -6,6 +6,7 @@ import json from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.exceptions import Forbidden from controllers.console.workspace.tool_providers import ( @@ -60,7 +61,7 @@ def _mock_user_tenant(): @pytest.fixture -def client(flask_app_with_containers): +def client(flask_app_with_containers: Flask): return flask_app_with_containers.test_client() @@ -147,10 +148,10 @@ class TestUtils: class TestToolProviderListApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = ToolProviderListApi() method = unwrap(api.get) @@ -170,10 +171,10 @@ class TestToolProviderListApi: class TestBuiltinProviderApis: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_list_tools(self, app): + def test_list_tools(self, app: Flask): api = ToolBuiltinProviderListToolsApi() method = unwrap(api.get) @@ -190,7 +191,7 @@ class TestBuiltinProviderApis: ): assert method(api, "provider") == [{"a": 1}] - def test_info(self, app): + def test_info(self, app: Flask): api = ToolBuiltinProviderInfoApi() method = unwrap(api.get) @@ -207,7 +208,7 @@ class TestBuiltinProviderApis: ): assert method(api, "provider") == {"x": 1} - def test_delete(self, app): + def test_delete(self, app: Flask): api = ToolBuiltinProviderDeleteApi() method = unwrap(api.post) @@ -224,7 +225,7 @@ class TestBuiltinProviderApis: ): assert method(api, "provider")["result"] == "success" - def test_add_invalid_type(self, app): + def test_add_invalid_type(self, app: Flask): api = ToolBuiltinProviderAddApi() method = unwrap(api.post) @@ -238,7 +239,7 @@ class TestBuiltinProviderApis: with pytest.raises(ValueError): method(api, "provider") - def test_add_success(self, app): + def test_add_success(self, app: Flask): api = ToolBuiltinProviderAddApi() method = unwrap(api.post) @@ -257,7 +258,7 @@ class TestBuiltinProviderApis: ): assert method(api, "provider")["id"] == 1 - def test_update(self, app): + def test_update(self, app: Flask): api = ToolBuiltinProviderUpdateApi() method = unwrap(api.post) @@ -276,7 +277,7 @@ class TestBuiltinProviderApis: ): assert method(api, "provider")["ok"] - def test_get_credentials(self, app): + def test_get_credentials(self, app: Flask): api = ToolBuiltinProviderGetCredentialsApi() method = unwrap(api.get) @@ -293,7 +294,7 @@ class TestBuiltinProviderApis: ): assert method(api, "provider") == {"k": "v"} - def test_icon(self, app): + def test_icon(self, app: Flask): api = ToolBuiltinProviderIconApi() method = unwrap(api.get) @@ -307,7 +308,7 @@ class TestBuiltinProviderApis: response = method(api, "provider") assert response.mimetype == "image/png" - def test_credentials_schema(self, app): + def test_credentials_schema(self, app: Flask): api = ToolBuiltinProviderCredentialsSchemaApi() method = unwrap(api.get) @@ -324,7 +325,7 @@ class TestBuiltinProviderApis: ): assert method(api, "provider", "oauth2") == {"schema": {}} - def test_set_default_credential(self, app): + def test_set_default_credential(self, app: Flask): api = ToolBuiltinProviderSetDefaultApi() method = unwrap(api.post) @@ -341,7 +342,7 @@ class TestBuiltinProviderApis: ): assert method(api, "provider")["ok"] - def test_get_credential_info(self, app): + def test_get_credential_info(self, app: Flask): api = ToolBuiltinProviderGetCredentialInfoApi() method = unwrap(api.get) @@ -358,7 +359,7 @@ class TestBuiltinProviderApis: ): assert method(api, "provider") == {"info": "x"} - def test_get_oauth_client_schema(self, app): + def test_get_oauth_client_schema(self, app: Flask): api = ToolBuiltinProviderGetOauthClientSchemaApi() method = unwrap(api.get) @@ -378,10 +379,10 @@ class TestBuiltinProviderApis: class TestApiProviderApis: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_add(self, app): + def test_add(self, app: Flask): api = ToolApiProviderAddApi() method = unwrap(api.post) @@ -406,7 +407,7 @@ class TestApiProviderApis: ): assert method(api)["id"] == 1 - def test_remote_schema(self, app): + def test_remote_schema(self, app: Flask): api = ToolApiProviderGetRemoteSchemaApi() method = unwrap(api.get) @@ -423,7 +424,7 @@ class TestApiProviderApis: ): assert method(api)["schema"] == "x" - def test_list_tools(self, app): + def test_list_tools(self, app: Flask): api = ToolApiProviderListToolsApi() method = unwrap(api.get) @@ -440,7 +441,7 @@ class TestApiProviderApis: ): assert method(api) == [{"tool": 1}] - def test_update(self, app): + def test_update(self, app: Flask): api = ToolApiProviderUpdateApi() method = unwrap(api.post) @@ -468,7 +469,7 @@ class TestApiProviderApis: ): assert method(api)["ok"] - def test_delete(self, app): + def test_delete(self, app: Flask): api = ToolApiProviderDeleteApi() method = unwrap(api.post) @@ -485,7 +486,7 @@ class TestApiProviderApis: ): assert method(api)["result"] == "success" - def test_get(self, app): + def test_get(self, app: Flask): api = ToolApiProviderGetApi() method = unwrap(api.get) @@ -505,10 +506,10 @@ class TestApiProviderApis: class TestWorkflowApis: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_create(self, app): + def test_create(self, app: Flask): api = ToolWorkflowProviderCreateApi() method = unwrap(api.post) @@ -534,7 +535,7 @@ class TestWorkflowApis: ): assert method(api)["id"] == 1 - def test_update_invalid(self, app): + def test_update_invalid(self, app: Flask): api = ToolWorkflowProviderUpdateApi() method = unwrap(api.post) @@ -560,7 +561,7 @@ class TestWorkflowApis: result = method(api) assert result["ok"] - def test_delete(self, app): + def test_delete(self, app: Flask): api = ToolWorkflowProviderDeleteApi() method = unwrap(api.post) @@ -577,7 +578,7 @@ class TestWorkflowApis: ): assert method(api)["ok"] - def test_get_error(self, app): + def test_get_error(self, app: Flask): api = ToolWorkflowProviderGetApi() method = unwrap(api.get) @@ -594,10 +595,10 @@ class TestWorkflowApis: class TestLists: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_builtin_list(self, app): + def test_builtin_list(self, app: Flask): api = ToolBuiltinListApi() method = unwrap(api.get) @@ -617,7 +618,7 @@ class TestLists: ): assert method(api) == [{"x": 1}] - def test_api_list(self, app): + def test_api_list(self, app: Flask): api = ToolApiListApi() method = unwrap(api.get) @@ -637,7 +638,7 @@ class TestLists: ): assert method(api) == [{"x": 1}] - def test_workflow_list(self, app): + def test_workflow_list(self, app: Flask): api = ToolWorkflowListApi() method = unwrap(api.get) @@ -660,10 +661,10 @@ class TestLists: class TestLabels: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_labels(self, app): + def test_labels(self, app: Flask): api = ToolLabelsApi() method = unwrap(api.get) @@ -679,10 +680,10 @@ class TestLabels: class TestOAuth: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_oauth_no_client(self, app): + def test_oauth_no_client(self, app: Flask): api = ToolPluginOAuthApi() method = unwrap(api.get) @@ -700,7 +701,7 @@ class TestOAuth: with pytest.raises(Forbidden): method(api, "provider") - def test_oauth_callback_no_cookie(self, app): + def test_oauth_callback_no_cookie(self, app: Flask): api = ToolOAuthCallback() method = unwrap(api.get) @@ -711,10 +712,10 @@ class TestOAuth: class TestOAuthCustomClient: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_save_custom_client(self, app): + def test_save_custom_client(self, app: Flask): api = ToolOAuthCustomClient() method = unwrap(api.post) @@ -731,7 +732,7 @@ class TestOAuthCustomClient: ): assert method(api, "provider")["ok"] - def test_get_custom_client(self, app): + def test_get_custom_client(self, app: Flask): api = ToolOAuthCustomClient() method = unwrap(api.get) @@ -748,7 +749,7 @@ class TestOAuthCustomClient: ): assert method(api, "provider") == {"client_id": "x"} - def test_delete_custom_client(self, app): + def test_delete_custom_client(self, app: Flask): api = ToolOAuthCustomClient() method = unwrap(api.delete) diff --git a/api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py b/api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py index ca8195af53..e41adccf3c 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py +++ b/api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py @@ -5,6 +5,7 @@ from __future__ import annotations from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.exceptions import BadRequest, Forbidden from controllers.console.workspace.trigger_providers import ( @@ -45,10 +46,10 @@ def mock_user(): class TestTriggerProviderApis: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_icon_success(self, app): + def test_icon_success(self, app: Flask): api = TriggerProviderIconApi() method = unwrap(api.get) @@ -62,7 +63,7 @@ class TestTriggerProviderApis: ): assert method(api, "github") == "icon" - def test_list_providers(self, app): + def test_list_providers(self, app: Flask): api = TriggerProviderListApi() method = unwrap(api.get) @@ -76,7 +77,7 @@ class TestTriggerProviderApis: ): assert method(api) == [] - def test_provider_info(self, app): + def test_provider_info(self, app: Flask): api = TriggerProviderInfoApi() method = unwrap(api.get) @@ -93,10 +94,10 @@ class TestTriggerProviderApis: class TestTriggerSubscriptionListApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_list_success(self, app): + def test_list_success(self, app: Flask): api = TriggerSubscriptionListApi() method = unwrap(api.get) @@ -110,7 +111,7 @@ class TestTriggerSubscriptionListApi: ): assert method(api, "github") == [] - def test_list_invalid_provider(self, app): + def test_list_invalid_provider(self, app: Flask): api = TriggerSubscriptionListApi() method = unwrap(api.get) @@ -128,10 +129,10 @@ class TestTriggerSubscriptionListApi: class TestTriggerSubscriptionBuilderApis: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_create_builder(self, app): + def test_create_builder(self, app: Flask): api = TriggerSubscriptionBuilderCreateApi() method = unwrap(api.post) @@ -146,7 +147,7 @@ class TestTriggerSubscriptionBuilderApis: result = method(api, "github") assert "subscription_builder" in result - def test_get_builder(self, app): + def test_get_builder(self, app: Flask): api = TriggerSubscriptionBuilderGetApi() method = unwrap(api.get) @@ -159,7 +160,7 @@ class TestTriggerSubscriptionBuilderApis: ): assert method(api, "github", "b1") == {"id": "b1"} - def test_verify_builder(self, app): + def test_verify_builder(self, app: Flask): api = TriggerSubscriptionBuilderVerifyApi() method = unwrap(api.post) @@ -173,7 +174,7 @@ class TestTriggerSubscriptionBuilderApis: ): assert method(api, "github", "b1") == {"ok": True} - def test_verify_builder_error(self, app): + def test_verify_builder_error(self, app: Flask): api = TriggerSubscriptionBuilderVerifyApi() method = unwrap(api.post) @@ -188,7 +189,7 @@ class TestTriggerSubscriptionBuilderApis: with pytest.raises(ValueError): method(api, "github", "b1") - def test_update_builder(self, app): + def test_update_builder(self, app: Flask): api = TriggerSubscriptionBuilderUpdateApi() method = unwrap(api.post) @@ -202,7 +203,7 @@ class TestTriggerSubscriptionBuilderApis: ): assert method(api, "github", "b1") == {"id": "b1"} - def test_logs(self, app): + def test_logs(self, app: Flask): api = TriggerSubscriptionBuilderLogsApi() method = unwrap(api.get) @@ -219,7 +220,7 @@ class TestTriggerSubscriptionBuilderApis: ): assert "logs" in method(api, "github", "b1") - def test_build(self, app): + def test_build(self, app: Flask): api = TriggerSubscriptionBuilderBuildApi() method = unwrap(api.post) @@ -236,10 +237,10 @@ class TestTriggerSubscriptionBuilderApis: class TestTriggerSubscriptionCrud: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_update_rename_only(self, app): + def test_update_rename_only(self, app: Flask): api = TriggerSubscriptionUpdateApi() method = unwrap(api.post) @@ -258,7 +259,7 @@ class TestTriggerSubscriptionCrud: ): assert method(api, "s1") == 200 - def test_update_not_found(self, app): + def test_update_not_found(self, app: Flask): api = TriggerSubscriptionUpdateApi() method = unwrap(api.post) @@ -273,7 +274,7 @@ class TestTriggerSubscriptionCrud: with pytest.raises(NotFoundError): method(api, "x") - def test_update_rebuild(self, app): + def test_update_rebuild(self, app: Flask): api = TriggerSubscriptionUpdateApi() method = unwrap(api.post) @@ -296,7 +297,7 @@ class TestTriggerSubscriptionCrud: ): assert method(api, "s1") == 200 - def test_delete_subscription(self, app): + def test_delete_subscription(self, app: Flask): api = TriggerSubscriptionDeleteApi() method = unwrap(api.post) @@ -319,7 +320,7 @@ class TestTriggerSubscriptionCrud: assert result["result"] == "success" - def test_delete_subscription_value_error(self, app): + def test_delete_subscription_value_error(self, app: Flask): api = TriggerSubscriptionDeleteApi() method = unwrap(api.post) @@ -342,10 +343,10 @@ class TestTriggerSubscriptionCrud: class TestTriggerOAuthApis: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_oauth_authorize_success(self, app): + def test_oauth_authorize_success(self, app: Flask): api = TriggerOAuthAuthorizeApi() method = unwrap(api.get) @@ -372,7 +373,7 @@ class TestTriggerOAuthApis: resp = method(api, "github") assert resp.status_code == 200 - def test_oauth_authorize_no_client(self, app): + def test_oauth_authorize_no_client(self, app: Flask): api = TriggerOAuthAuthorizeApi() method = unwrap(api.get) @@ -387,7 +388,7 @@ class TestTriggerOAuthApis: with pytest.raises(NotFoundError): method(api, "github") - def test_oauth_callback_forbidden(self, app): + def test_oauth_callback_forbidden(self, app: Flask): api = TriggerOAuthCallbackApi() method = unwrap(api.get) @@ -395,7 +396,7 @@ class TestTriggerOAuthApis: with pytest.raises(Forbidden): method(api, "github") - def test_oauth_callback_success(self, app): + def test_oauth_callback_success(self, app: Flask): api = TriggerOAuthCallbackApi() method = unwrap(api.get) @@ -425,7 +426,7 @@ class TestTriggerOAuthApis: resp = method(api, "github") assert resp.status_code == 302 - def test_oauth_callback_no_oauth_client(self, app): + def test_oauth_callback_no_oauth_client(self, app: Flask): api = TriggerOAuthCallbackApi() method = unwrap(api.get) @@ -449,7 +450,7 @@ class TestTriggerOAuthApis: with pytest.raises(Forbidden): method(api, "github") - def test_oauth_callback_empty_credentials(self, app): + def test_oauth_callback_empty_credentials(self, app: Flask): api = TriggerOAuthCallbackApi() method = unwrap(api.get) @@ -480,10 +481,10 @@ class TestTriggerOAuthApis: class TestTriggerOAuthClientManageApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_get_client(self, app): + def test_get_client(self, app: Flask): api = TriggerOAuthClientManageApi() method = unwrap(api.get) @@ -510,7 +511,7 @@ class TestTriggerOAuthClientManageApi: result = method(api, "github") assert "configured" in result - def test_post_client(self, app): + def test_post_client(self, app: Flask): api = TriggerOAuthClientManageApi() method = unwrap(api.post) @@ -524,7 +525,7 @@ class TestTriggerOAuthClientManageApi: ): assert method(api, "github") == {"ok": True} - def test_delete_client(self, app): + def test_delete_client(self, app: Flask): api = TriggerOAuthClientManageApi() method = unwrap(api.delete) @@ -538,7 +539,7 @@ class TestTriggerOAuthClientManageApi: ): assert method(api, "github") == {"ok": True} - def test_oauth_client_post_value_error(self, app): + def test_oauth_client_post_value_error(self, app: Flask): api = TriggerOAuthClientManageApi() method = unwrap(api.post) @@ -556,10 +557,10 @@ class TestTriggerOAuthClientManageApi: class TestTriggerSubscriptionVerifyApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_verify_success(self, app): + def test_verify_success(self, app: Flask): api = TriggerSubscriptionVerifyApi() method = unwrap(api.post) diff --git a/api/tests/test_containers_integration_tests/controllers/service_api/dataset/test_dataset.py b/api/tests/test_containers_integration_tests/controllers/service_api/dataset/test_dataset.py index 9b913d6d3d..b73d28e4c4 100644 --- a/api/tests/test_containers_integration_tests/controllers/service_api/dataset/test_dataset.py +++ b/api/tests/test_containers_integration_tests/controllers/service_api/dataset/test_dataset.py @@ -18,6 +18,7 @@ from types import SimpleNamespace from unittest.mock import Mock, patch import pytest +from flask import Flask from sqlalchemy.orm import Session from werkzeug.exceptions import Forbidden, NotFound @@ -217,10 +218,20 @@ class TestTagUnbindingPayload: """Test suite for TagUnbindingPayload Pydantic model.""" def test_payload_with_valid_data(self): - payload = TagUnbindingPayload(tag_id="tag_123", target_id="dataset_456") - assert payload.tag_id == "tag_123" + payload = TagUnbindingPayload(tag_ids=["tag_123"], target_id="dataset_456") + assert payload.tag_ids == ["tag_123"] assert payload.target_id == "dataset_456" + def test_payload_normalizes_legacy_tag_id(self): + payload = TagUnbindingPayload(tag_id="tag_123", target_id="dataset_456") + assert payload.tag_ids == ["tag_123"] + assert payload.target_id == "dataset_456" + + def test_payload_rejects_empty_tag_ids(self): + with pytest.raises(ValueError) as exc_info: + TagUnbindingPayload(tag_ids=[], target_id="dataset_456") + assert "Tag IDs is required" in str(exc_info.value) + # --------------------------------------------------------------------------- # Helpers @@ -236,7 +247,7 @@ def _unwrap(method): @pytest.fixture -def app(flask_app_with_containers): +def app(flask_app_with_containers: Flask): # Uses the full containerised app so that Flask config, extensions, and # blueprint registrations match production. Most tests mock the service # layer to isolate controller logic; a few (e.g. test_list_tags_from_db) @@ -280,7 +291,7 @@ class TestDatasetListApiGet: mock_current_user, mock_provider_mgr, mock_marshal, - app, + app: Flask, mock_tenant, ): from controllers.service_api.dataset.dataset import DatasetListApi @@ -315,7 +326,7 @@ class TestDatasetListApiPost: mock_dataset_svc, mock_current_user, mock_marshal, - app, + app: Flask, mock_tenant, ): from controllers.service_api.dataset.dataset import DatasetListApi @@ -341,7 +352,7 @@ class TestDatasetListApiPost: self, mock_dataset_svc, mock_current_user, - app, + app: Flask, mock_tenant, ): from controllers.service_api.dataset.dataset import DatasetListApi @@ -379,7 +390,7 @@ class TestDatasetApiGet: mock_provider_mgr, mock_marshal, mock_perm_svc, - app, + app: Flask, mock_dataset, ): from controllers.service_api.dataset.dataset import DatasetApi @@ -429,7 +440,7 @@ class TestDatasetApiGet: self, mock_dataset_svc, mock_current_user, - app, + app: Flask, mock_dataset, ): from controllers.service_api.dataset.dataset import DatasetApi @@ -457,7 +468,7 @@ class TestDatasetApiDelete: mock_dataset_svc, mock_current_user, mock_perm_svc, - app, + app: Flask, mock_dataset, ): from controllers.service_api.dataset.dataset import DatasetApi @@ -479,7 +490,7 @@ class TestDatasetApiDelete: self, mock_dataset_svc, mock_current_user, - app, + app: Flask, mock_dataset, ): from controllers.service_api.dataset.dataset import DatasetApi @@ -500,7 +511,7 @@ class TestDatasetApiDelete: self, mock_dataset_svc, mock_current_user, - app, + app: Flask, mock_dataset, ): from controllers.service_api.dataset.dataset import DatasetApi @@ -532,7 +543,7 @@ class TestDocumentStatusApiPatch: mock_dataset_svc, mock_current_user, mock_doc_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -563,7 +574,7 @@ class TestDocumentStatusApiPatch: def test_batch_update_status_dataset_not_found( self, mock_dataset_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -592,7 +603,7 @@ class TestDocumentStatusApiPatch: mock_dataset_svc, mock_current_user, mock_doc_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -625,7 +636,7 @@ class TestDocumentStatusApiPatch: mock_dataset_svc, mock_current_user, mock_doc_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -658,7 +669,7 @@ class TestDocumentStatusApiPatch: mock_dataset_svc, mock_current_user, mock_doc_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -698,7 +709,7 @@ class TestDatasetTagsApiGet: self, mock_current_user, mock_tag_svc, - app, + app: Flask, ): from controllers.service_api.dataset.dataset import DatasetTagsApi @@ -720,7 +731,7 @@ class TestDatasetTagsApiGet: def test_list_tags_from_db( self, mock_current_user, - app, + app: Flask, db_session_with_containers: Session, ): """Integration test: creates real Tag rows and retrieves them @@ -763,7 +774,7 @@ class TestDatasetTagsApiPost: self, mock_current_user, mock_tag_svc, - app, + app: Flask, ): from controllers.service_api.dataset.dataset import DatasetTagsApi @@ -786,7 +797,7 @@ class TestDatasetTagsApiPost: mock_tag_svc.save_tags.assert_called_once() @patch("controllers.service_api.dataset.dataset.current_user") - def test_create_tag_forbidden(self, mock_current_user, app): + def test_create_tag_forbidden(self, mock_current_user, app: Flask): from controllers.service_api.dataset.dataset import DatasetTagsApi mock_current_user.__class__ = Account @@ -815,7 +826,7 @@ class TestDatasetTagsApiPatch: mock_current_user, mock_service_api_ns, mock_tag_svc, - app, + app: Flask, ): from controllers.service_api.dataset.dataset import DatasetTagsApi @@ -841,7 +852,7 @@ class TestDatasetTagsApiPatch: mock_tag_svc.update_tags.assert_called_once_with({"name": "Updated Tag", "type": "knowledge"}, "tag-1") @patch("controllers.service_api.dataset.dataset.current_user") - def test_update_tag_forbidden(self, mock_current_user, app): + def test_update_tag_forbidden(self, mock_current_user, app: Flask): from controllers.service_api.dataset.dataset import DatasetTagsApi mock_current_user.__class__ = Account @@ -869,7 +880,7 @@ class TestDatasetTagsApiDelete: mock_current_user, mock_service_api_ns, mock_tag_svc, - app, + app: Flask, ): from controllers.service_api.dataset.dataset import DatasetTagsApi @@ -894,7 +905,7 @@ class TestDatasetTagsApiDelete: mock_tag_svc.delete_tag.assert_called_once_with("tag-1") @patch("libs.login.current_user") - def test_delete_tag_forbidden(self, mock_current_user, app): + def test_delete_tag_forbidden(self, mock_current_user, app: Flask): from controllers.service_api.dataset.dataset import DatasetTagsApi user_obj = Mock(spec=Account) @@ -922,7 +933,7 @@ class TestDatasetTagsBindingStatusApi: self, mock_current_user, mock_tag_svc, - app, + app: Flask, ): from controllers.service_api.dataset.dataset import DatasetTagsBindingStatusApi @@ -952,7 +963,7 @@ class TestDatasetTagBindingApiPost: self, mock_current_user, mock_tag_svc, - app, + app: Flask, ): from controllers.service_api.dataset.dataset import DatasetTagBindingApi @@ -977,7 +988,7 @@ class TestDatasetTagBindingApiPost: ) @patch("controllers.service_api.dataset.dataset.current_user") - def test_bind_tags_forbidden(self, mock_current_user, app): + def test_bind_tags_forbidden(self, mock_current_user, app: Flask): from controllers.service_api.dataset.dataset import DatasetTagBindingApi mock_current_user.__class__ = Account @@ -1003,7 +1014,37 @@ class TestDatasetTagUnbindingApiPost: self, mock_current_user, mock_tag_svc, - app, + app: Flask, + ): + from controllers.service_api.dataset.dataset import DatasetTagUnbindingApi + + mock_current_user.__class__ = Account + mock_current_user.has_edit_permission = True + mock_current_user.is_dataset_editor = True + mock_tag_svc.delete_tag_binding.return_value = None + + with app.test_request_context( + "/datasets/tags/unbinding", + method="POST", + json={"tag_ids": ["tag-1"], "target_id": "ds-1"}, + ): + api = DatasetTagUnbindingApi() + result = api.post(_=None) + + assert result == ("", 204) + from services.tag_service import TagBindingDeletePayload + + mock_tag_svc.delete_tag_binding.assert_called_once_with( + TagBindingDeletePayload(tag_ids=["tag-1"], target_id="ds-1", type="knowledge") + ) + + @patch("controllers.service_api.dataset.dataset.TagService") + @patch("controllers.service_api.dataset.dataset.current_user") + def test_unbind_legacy_tag_id_success( + self, + mock_current_user, + mock_tag_svc, + app: Flask, ): from controllers.service_api.dataset.dataset import DatasetTagUnbindingApi @@ -1024,11 +1065,11 @@ class TestDatasetTagUnbindingApiPost: from services.tag_service import TagBindingDeletePayload mock_tag_svc.delete_tag_binding.assert_called_once_with( - TagBindingDeletePayload(tag_id="tag-1", target_id="ds-1", type="knowledge") + TagBindingDeletePayload(tag_ids=["tag-1"], target_id="ds-1", type="knowledge") ) @patch("controllers.service_api.dataset.dataset.current_user") - def test_unbind_tag_forbidden(self, mock_current_user, app): + def test_unbind_tag_forbidden(self, mock_current_user, app: Flask): from controllers.service_api.dataset.dataset import DatasetTagUnbindingApi mock_current_user.__class__ = Account @@ -1038,7 +1079,7 @@ class TestDatasetTagUnbindingApiPost: with app.test_request_context( "/datasets/tags/unbinding", method="POST", - json={"tag_id": "tag-1", "target_id": "ds-1"}, + json={"tag_ids": ["tag-1"], "target_id": "ds-1"}, ): api = DatasetTagUnbindingApi() with pytest.raises(Forbidden): diff --git a/api/tests/test_containers_integration_tests/controllers/web/test_conversation.py b/api/tests/test_containers_integration_tests/controllers/web/test_conversation.py index e1e6741014..c34da27ebe 100644 --- a/api/tests/test_containers_integration_tests/controllers/web/test_conversation.py +++ b/api/tests/test_containers_integration_tests/controllers/web/test_conversation.py @@ -7,6 +7,7 @@ from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest +from flask import Flask from werkzeug.exceptions import NotFound from controllers.web.conversation import ( @@ -34,16 +35,16 @@ def _end_user() -> SimpleNamespace: class TestConversationListApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_non_chat_mode_raises(self, app) -> None: + def test_non_chat_mode_raises(self, app: Flask) -> None: with app.test_request_context("/conversations"): with pytest.raises(NotChatAppError): ConversationListApi().get(_completion_app(), _end_user()) @patch("controllers.web.conversation.WebConversationService.pagination_by_last_id") - def test_happy_path(self, mock_paginate: MagicMock, app) -> None: + def test_happy_path(self, mock_paginate: MagicMock, app: Flask) -> None: conv_id = str(uuid4()) conv = SimpleNamespace( id=conv_id, @@ -65,16 +66,16 @@ class TestConversationListApi: class TestConversationApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_non_chat_mode_raises(self, app) -> None: + def test_non_chat_mode_raises(self, app: Flask) -> None: with app.test_request_context(f"/conversations/{uuid4()}"): with pytest.raises(NotChatAppError): ConversationApi().delete(_completion_app(), _end_user(), uuid4()) @patch("controllers.web.conversation.ConversationService.delete") - def test_delete_success(self, mock_delete: MagicMock, app) -> None: + def test_delete_success(self, mock_delete: MagicMock, app: Flask) -> None: c_id = uuid4() with app.test_request_context(f"/conversations/{c_id}"): result, status = ConversationApi().delete(_chat_app(), _end_user(), c_id) @@ -83,7 +84,7 @@ class TestConversationApi: assert result["result"] == "success" @patch("controllers.web.conversation.ConversationService.delete", side_effect=ConversationNotExistsError()) - def test_delete_not_found(self, mock_delete: MagicMock, app) -> None: + def test_delete_not_found(self, mock_delete: MagicMock, app: Flask) -> None: c_id = uuid4() with app.test_request_context(f"/conversations/{c_id}"): with pytest.raises(NotFound, match="Conversation Not Exists"): @@ -92,17 +93,17 @@ class TestConversationApi: class TestConversationRenameApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_non_chat_mode_raises(self, app) -> None: + def test_non_chat_mode_raises(self, app: Flask) -> None: with app.test_request_context(f"/conversations/{uuid4()}/name", method="POST", json={"name": "x"}): with pytest.raises(NotChatAppError): ConversationRenameApi().post(_completion_app(), _end_user(), uuid4()) @patch("controllers.web.conversation.ConversationService.rename") @patch("controllers.web.conversation.web_ns") - def test_rename_success(self, mock_ns: MagicMock, mock_rename: MagicMock, app) -> None: + def test_rename_success(self, mock_ns: MagicMock, mock_rename: MagicMock, app: Flask) -> None: c_id = uuid4() mock_ns.payload = {"name": "New Name", "auto_generate": False} conv = SimpleNamespace( @@ -126,7 +127,7 @@ class TestConversationRenameApi: side_effect=ConversationNotExistsError(), ) @patch("controllers.web.conversation.web_ns") - def test_rename_not_found(self, mock_ns: MagicMock, mock_rename: MagicMock, app) -> None: + def test_rename_not_found(self, mock_ns: MagicMock, mock_rename: MagicMock, app: Flask) -> None: c_id = uuid4() mock_ns.payload = {"name": "X", "auto_generate": False} @@ -137,16 +138,16 @@ class TestConversationRenameApi: class TestConversationPinApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_non_chat_mode_raises(self, app) -> None: + def test_non_chat_mode_raises(self, app: Flask) -> None: with app.test_request_context(f"/conversations/{uuid4()}/pin", method="PATCH"): with pytest.raises(NotChatAppError): ConversationPinApi().patch(_completion_app(), _end_user(), uuid4()) @patch("controllers.web.conversation.WebConversationService.pin") - def test_pin_success(self, mock_pin: MagicMock, app) -> None: + def test_pin_success(self, mock_pin: MagicMock, app: Flask) -> None: c_id = uuid4() with app.test_request_context(f"/conversations/{c_id}/pin", method="PATCH"): result = ConversationPinApi().patch(_chat_app(), _end_user(), c_id) @@ -154,7 +155,7 @@ class TestConversationPinApi: assert result["result"] == "success" @patch("controllers.web.conversation.WebConversationService.pin", side_effect=ConversationNotExistsError()) - def test_pin_not_found(self, mock_pin: MagicMock, app) -> None: + def test_pin_not_found(self, mock_pin: MagicMock, app: Flask) -> None: c_id = uuid4() with app.test_request_context(f"/conversations/{c_id}/pin", method="PATCH"): with pytest.raises(NotFound): @@ -163,16 +164,16 @@ class TestConversationPinApi: class TestConversationUnPinApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers - def test_non_chat_mode_raises(self, app) -> None: + def test_non_chat_mode_raises(self, app: Flask) -> None: with app.test_request_context(f"/conversations/{uuid4()}/unpin", method="PATCH"): with pytest.raises(NotChatAppError): ConversationUnPinApi().patch(_completion_app(), _end_user(), uuid4()) @patch("controllers.web.conversation.WebConversationService.unpin") - def test_unpin_success(self, mock_unpin: MagicMock, app) -> None: + def test_unpin_success(self, mock_unpin: MagicMock, app: Flask) -> None: c_id = uuid4() with app.test_request_context(f"/conversations/{c_id}/unpin", method="PATCH"): result = ConversationUnPinApi().patch(_chat_app(), _end_user(), c_id) diff --git a/api/tests/test_containers_integration_tests/controllers/web/test_web_forgot_password.py b/api/tests/test_containers_integration_tests/controllers/web/test_web_forgot_password.py index 635cfee2da..2c6a990240 100644 --- a/api/tests/test_containers_integration_tests/controllers/web/test_web_forgot_password.py +++ b/api/tests/test_containers_integration_tests/controllers/web/test_web_forgot_password.py @@ -7,6 +7,7 @@ from types import SimpleNamespace from unittest.mock import MagicMock, patch import pytest +from flask import Flask from controllers.web.forgot_password import ( ForgotPasswordCheckApi, @@ -29,7 +30,7 @@ def _patch_wraps(): class TestForgotPasswordSendEmailApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers @patch("controllers.web.forgot_password.AccountService.send_reset_password_email") @@ -42,7 +43,7 @@ class TestForgotPasswordSendEmailApi: mock_rate_limit, mock_get_account, mock_send_mail, - app, + app: Flask, ): mock_account = MagicMock() mock_get_account.return_value = mock_account @@ -64,7 +65,7 @@ class TestForgotPasswordSendEmailApi: class TestForgotPasswordCheckApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers @patch("controllers.web.forgot_password.AccountService.reset_forgot_password_error_rate_limit") @@ -81,7 +82,7 @@ class TestForgotPasswordCheckApi: mock_revoke_token, mock_generate_token, mock_reset_rate, - app, + app: Flask, ): mock_is_rate_limit.return_value = False mock_get_data.return_value = {"email": "User@Example.com", "code": "1234"} @@ -117,7 +118,7 @@ class TestForgotPasswordCheckApi: mock_revoke_token, mock_generate_token, mock_reset_rate, - app, + app: Flask, ): mock_is_rate_limit.return_value = False mock_get_data.return_value = {"email": "MixedCase@Example.com", "code": "5678"} @@ -142,7 +143,7 @@ class TestForgotPasswordCheckApi: class TestForgotPasswordResetApi: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers @patch("controllers.web.forgot_password.ForgotPasswordResetApi._update_existing_account") @@ -157,7 +158,7 @@ class TestForgotPasswordResetApi: mock_db, mock_get_account, mock_update_account, - app, + app: Flask, ): mock_get_reset_data.return_value = {"phase": "reset", "email": "User@Example.com", "code": "1234"} mock_account = MagicMock() @@ -194,7 +195,7 @@ class TestForgotPasswordResetApi: mock_db, mock_token_bytes, mock_hash_password, - app, + app: Flask, ): mock_get_reset_data.return_value = {"phase": "reset", "email": "user@example.com"} account = MagicMock() diff --git a/api/tests/test_containers_integration_tests/controllers/web/test_wraps.py b/api/tests/test_containers_integration_tests/controllers/web/test_wraps.py index 19833cc772..0a4e495f36 100644 --- a/api/tests/test_containers_integration_tests/controllers/web/test_wraps.py +++ b/api/tests/test_containers_integration_tests/controllers/web/test_wraps.py @@ -8,6 +8,7 @@ from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest +from flask import Flask from sqlalchemy.orm import Session from werkzeug.exceptions import BadRequest, NotFound, Unauthorized @@ -182,7 +183,7 @@ class TestValidateUserAccessibility: class TestDecodeJwtToken: @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers def _create_app_site_enduser(self, db_session: Session, *, enable_site: bool = True): @@ -239,7 +240,7 @@ class TestDecodeJwtToken: mock_access_mode: MagicMock, mock_validate_token: MagicMock, mock_validate_user: MagicMock, - app, + app: Flask, db_session_with_containers: Session, ) -> None: app_model, site, end_user = self._create_app_site_enduser(db_session_with_containers) @@ -299,7 +300,7 @@ class TestDecodeJwtToken: mock_extract: MagicMock, mock_passport_cls: MagicMock, mock_features: MagicMock, - app, + app: Flask, db_session_with_containers: Session, ) -> None: app_model, site, end_user = self._create_app_site_enduser(db_session_with_containers, enable_site=False) @@ -324,7 +325,7 @@ class TestDecodeJwtToken: mock_extract: MagicMock, mock_passport_cls: MagicMock, mock_features: MagicMock, - app, + app: Flask, db_session_with_containers: Session, ) -> None: app_model, site, _ = self._create_app_site_enduser(db_session_with_containers) @@ -350,7 +351,7 @@ class TestDecodeJwtToken: mock_extract: MagicMock, mock_passport_cls: MagicMock, mock_features: MagicMock, - app, + app: Flask, db_session_with_containers: Session, ) -> None: app_model, site, end_user = self._create_app_site_enduser(db_session_with_containers) diff --git a/api/tests/test_containers_integration_tests/core/app/layers/test_pause_state_persist_layer.py b/api/tests/test_containers_integration_tests/core/app/layers/test_pause_state_persist_layer.py index c342e8994b..bd13527e14 100644 --- a/api/tests/test_containers_integration_tests/core/app/layers/test_pause_state_persist_layer.py +++ b/api/tests/test_containers_integration_tests/core/app/layers/test_pause_state_persist_layer.py @@ -85,7 +85,7 @@ class TestPauseStatePersistenceLayerTestContainers: return WorkflowRunService(engine) @pytest.fixture(autouse=True) - def setup_test_data(self, db_session_with_containers, file_service, workflow_run_service): + def setup_test_data(self, db_session_with_containers: Session, file_service, workflow_run_service): """Set up test data for each test method using TestContainers.""" # Create test tenant and account from models.account import AccountStatus, Tenant, TenantAccountJoin, TenantAccountRole, TenantStatus @@ -295,7 +295,7 @@ class TestPauseStatePersistenceLayerTestContainers: generate_entity=entity, ) - def test_complete_pause_flow_with_real_dependencies(self, db_session_with_containers): + def test_complete_pause_flow_with_real_dependencies(self, db_session_with_containers: Session): """Test complete pause flow: event -> state serialization -> database save -> storage save.""" # Arrange layer = self._create_pause_state_persistence_layer() @@ -352,7 +352,7 @@ class TestPauseStatePersistenceLayerTestContainers: assert isinstance(persisted_entity, WorkflowAppGenerateEntity) assert persisted_entity.workflow_execution_id == self.test_workflow_run_id - def test_state_persistence_and_retrieval(self, db_session_with_containers): + def test_state_persistence_and_retrieval(self, db_session_with_containers: Session): """Test that pause state can be persisted and retrieved correctly.""" # Arrange layer = self._create_pause_state_persistence_layer() @@ -402,7 +402,7 @@ class TestPauseStatePersistenceLayerTestContainers: assert retrieved_state["node_run_steps"] == 10 assert resumption_context.get_generate_entity().workflow_execution_id == self.test_workflow_run_id - def test_database_transaction_handling(self, db_session_with_containers): + def test_database_transaction_handling(self, db_session_with_containers: Session): """Test that database transactions are handled correctly.""" # Arrange layer = self._create_pause_state_persistence_layer() @@ -433,7 +433,7 @@ class TestPauseStatePersistenceLayerTestContainers: assert pause_model.resumed_at is None assert pause_model.state_object_key != "" - def test_file_storage_integration(self, db_session_with_containers): + def test_file_storage_integration(self, db_session_with_containers: Session): """Test integration with file storage system.""" # Arrange layer = self._create_pause_state_persistence_layer() @@ -467,7 +467,7 @@ class TestPauseStatePersistenceLayerTestContainers: assert resumption_context.serialized_graph_runtime_state == graph_runtime_state.dumps() assert resumption_context.get_generate_entity().workflow_execution_id == self.test_workflow_run_id - def test_workflow_with_different_creators(self, db_session_with_containers): + def test_workflow_with_different_creators(self, db_session_with_containers: Session): """Test pause state with workflows created by different users.""" # Arrange - Create workflow with different creator different_user_id = str(uuid.uuid4()) @@ -532,7 +532,7 @@ class TestPauseStatePersistenceLayerTestContainers: resumption_context = WorkflowResumptionContext.loads(pause_entity.get_state().decode()) assert resumption_context.get_generate_entity().workflow_execution_id == different_workflow_run.id - def test_layer_ignores_non_pause_events(self, db_session_with_containers): + def test_layer_ignores_non_pause_events(self, db_session_with_containers: Session): """Test that layer ignores non-pause events.""" # Arrange layer = self._create_pause_state_persistence_layer() @@ -562,7 +562,7 @@ class TestPauseStatePersistenceLayerTestContainers: ).all() assert len(pause_states) == 0 - def test_layer_requires_initialization(self, db_session_with_containers): + def test_layer_requires_initialization(self, db_session_with_containers: Session): """Test that layer requires proper initialization before handling events.""" # Arrange layer = self._create_pause_state_persistence_layer() diff --git a/api/tests/test_containers_integration_tests/core/rag/pipeline/test_queue_integration.py b/api/tests/test_containers_integration_tests/core/rag/pipeline/test_queue_integration.py index a60159c66a..d1af0a56ef 100644 --- a/api/tests/test_containers_integration_tests/core/rag/pipeline/test_queue_integration.py +++ b/api/tests/test_containers_integration_tests/core/rag/pipeline/test_queue_integration.py @@ -15,11 +15,14 @@ from uuid import uuid4 import pytest from faker import Faker +from sqlalchemy.orm import Session from core.rag.pipeline.queue import TaskWrapper, TenantIsolatedTaskQueue from extensions.ext_redis import redis_client from models import Account, AccountStatus, Tenant, TenantAccountJoin, TenantAccountRole, TenantStatus +TenantAndAccount = tuple[Tenant, Account] + @dataclass class TestTask: @@ -40,7 +43,7 @@ class TestTenantIsolatedTaskQueueIntegration: return Faker() @pytest.fixture - def test_tenant_and_account(self, db_session_with_containers, fake): + def test_tenant_and_account(self, db_session_with_containers: Session, fake: Faker): """Create test tenant and account for testing.""" # Create account account = Account( @@ -73,18 +76,18 @@ class TestTenantIsolatedTaskQueueIntegration: return tenant, account @pytest.fixture - def test_queue(self, test_tenant_and_account): + def test_queue(self, test_tenant_and_account: TenantAndAccount): """Create a generic test queue for testing.""" tenant, _ = test_tenant_and_account return TenantIsolatedTaskQueue(tenant.id, "test_queue") @pytest.fixture - def secondary_queue(self, test_tenant_and_account): + def secondary_queue(self, test_tenant_and_account: TenantAndAccount): """Create a secondary test queue for testing isolation.""" tenant, _ = test_tenant_and_account return TenantIsolatedTaskQueue(tenant.id, "secondary_queue") - def test_queue_initialization(self, test_tenant_and_account): + def test_queue_initialization(self, test_tenant_and_account: TenantAndAccount): """Test queue initialization with correct key generation.""" tenant, _ = test_tenant_and_account queue = TenantIsolatedTaskQueue(tenant.id, "test-key") @@ -94,7 +97,9 @@ class TestTenantIsolatedTaskQueueIntegration: assert queue._queue == f"tenant_self_test-key_task_queue:{tenant.id}" assert queue._task_key == f"tenant_test-key_task:{tenant.id}" - def test_tenant_isolation(self, test_tenant_and_account, db_session_with_containers, fake): + def test_tenant_isolation( + self, test_tenant_and_account: TenantAndAccount, db_session_with_containers: Session, fake: Faker + ): """Test that different tenants have isolated queues.""" tenant1, _ = test_tenant_and_account @@ -114,7 +119,7 @@ class TestTenantIsolatedTaskQueueIntegration: assert queue1._queue == f"tenant_self_same-key_task_queue:{tenant1.id}" assert queue2._queue == f"tenant_self_same-key_task_queue:{tenant2.id}" - def test_key_isolation(self, test_tenant_and_account): + def test_key_isolation(self, test_tenant_and_account: TenantAndAccount): """Test that different keys have isolated queues.""" tenant, _ = test_tenant_and_account queue1 = TenantIsolatedTaskQueue(tenant.id, "key1") @@ -176,7 +181,7 @@ class TestTenantIsolatedTaskQueueIntegration: assert len(remaining_tasks) == 2 assert remaining_tasks == ["task4", "task5"] - def test_push_and_pull_complex_objects(self, test_queue, fake): + def test_push_and_pull_complex_objects(self, test_queue, fake: Faker): """Test pushing and pulling complex object tasks.""" # Create complex task objects as dictionaries (not dataclass instances) tasks = [ @@ -218,7 +223,7 @@ class TestTenantIsolatedTaskQueueIntegration: assert pulled_task["data"] == original_task["data"] assert pulled_task["metadata"] == original_task["metadata"] - def test_mixed_task_types(self, test_queue, fake): + def test_mixed_task_types(self, test_queue, fake: Faker): """Test pushing and pulling mixed string and object tasks.""" string_task = "simple_string_task" object_task = { @@ -267,7 +272,7 @@ class TestTenantIsolatedTaskQueueIntegration: # Verify task key has expired assert test_queue.get_task_key() is None - def test_large_task_batch(self, test_queue, fake): + def test_large_task_batch(self, test_queue, fake: Faker): """Test handling large batches of tasks.""" # Create large batch of tasks large_batch = [] @@ -292,7 +297,7 @@ class TestTenantIsolatedTaskQueueIntegration: assert isinstance(task, dict) assert task["index"] == i # FIFO order - def test_queue_operations_isolation(self, test_tenant_and_account, fake): + def test_queue_operations_isolation(self, test_tenant_and_account: TenantAndAccount, fake: Faker): """Test concurrent operations on different queues.""" tenant, _ = test_tenant_and_account @@ -312,7 +317,7 @@ class TestTenantIsolatedTaskQueueIntegration: assert tasks2 == ["task1_queue2", "task2_queue2"] assert tasks1 != tasks2 - def test_task_wrapper_serialization_roundtrip(self, test_queue, fake): + def test_task_wrapper_serialization_roundtrip(self, test_queue, fake: Faker): """Test TaskWrapper serialization and deserialization roundtrip.""" # Create complex nested data complex_data = { @@ -346,7 +351,7 @@ class TestTenantIsolatedTaskQueueIntegration: task = test_queue.pull_tasks(1) assert task[0] == invalid_json_task - def test_real_world_batch_processing_scenario(self, test_queue, fake): + def test_real_world_batch_processing_scenario(self, test_queue, fake: Faker): """Test realistic batch processing scenario.""" # Simulate batch processing tasks batch_tasks = [] @@ -403,7 +408,7 @@ class TestTenantIsolatedTaskQueueCompatibility: return Faker() @pytest.fixture - def test_tenant_and_account(self, db_session_with_containers, fake): + def test_tenant_and_account(self, db_session_with_containers: Session, fake: Faker): """Create test tenant and account for testing.""" # Create account account = Account( @@ -435,7 +440,7 @@ class TestTenantIsolatedTaskQueueCompatibility: return tenant, account - def test_legacy_string_queue_compatibility(self, test_tenant_and_account, fake): + def test_legacy_string_queue_compatibility(self, test_tenant_and_account: TenantAndAccount, fake: Faker): """ Test compatibility with legacy queues containing only string data. @@ -465,7 +470,7 @@ class TestTenantIsolatedTaskQueueCompatibility: expected_order = ["legacy_task_1", "legacy_task_2", "legacy_task_3", "legacy_task_4", "legacy_task_5"] assert pulled_tasks == expected_order - def test_legacy_queue_migration_scenario(self, test_tenant_and_account, fake): + def test_legacy_queue_migration_scenario(self, test_tenant_and_account: TenantAndAccount, fake: Faker): """ Test complete migration scenario from legacy to new system. @@ -546,7 +551,7 @@ class TestTenantIsolatedTaskQueueCompatibility: assert task["tenant_id"] == tenant.id assert task["processing_type"] == "new_system" - def test_legacy_queue_error_recovery(self, test_tenant_and_account, fake): + def test_legacy_queue_error_recovery(self, test_tenant_and_account: TenantAndAccount, fake: Faker): """ Test error recovery when legacy queue contains malformed data. diff --git a/api/tests/test_containers_integration_tests/core/rag/retrieval/test_dataset_retrieval_integration.py b/api/tests/test_containers_integration_tests/core/rag/retrieval/test_dataset_retrieval_integration.py index 00d7496a40..9da6b04a2c 100644 --- a/api/tests/test_containers_integration_tests/core/rag/retrieval/test_dataset_retrieval_integration.py +++ b/api/tests/test_containers_integration_tests/core/rag/retrieval/test_dataset_retrieval_integration.py @@ -3,6 +3,7 @@ from unittest.mock import patch import pytest from faker import Faker +from sqlalchemy.orm import Session from core.rag.index_processor.constant.index_type import IndexStructureType, IndexTechniqueType from core.rag.retrieval.dataset_retrieval import DatasetRetrieval @@ -15,7 +16,7 @@ from tests.test_containers_integration_tests.helpers import generate_valid_passw class TestGetAvailableDatasetsIntegration: def test_returns_datasets_with_available_documents( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): # Arrange fake = Faker() @@ -77,7 +78,7 @@ class TestGetAvailableDatasetsIntegration: assert result[0].name == dataset.name def test_filters_out_datasets_with_only_archived_documents( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): # Arrange fake = Faker() @@ -130,7 +131,7 @@ class TestGetAvailableDatasetsIntegration: assert len(result) == 0 def test_filters_out_datasets_with_only_disabled_documents( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): # Arrange fake = Faker() @@ -183,7 +184,7 @@ class TestGetAvailableDatasetsIntegration: assert len(result) == 0 def test_filters_out_datasets_with_non_completed_documents( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): # Arrange fake = Faker() @@ -236,7 +237,7 @@ class TestGetAvailableDatasetsIntegration: assert len(result) == 0 def test_includes_external_datasets_without_documents( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test that external datasets are returned even with no available documents. @@ -280,7 +281,7 @@ class TestGetAvailableDatasetsIntegration: assert result[0].id == dataset.id assert result[0].provider == "external" - def test_filters_by_tenant_id(self, db_session_with_containers, mock_external_service_dependencies): + def test_filters_by_tenant_id(self, db_session_with_containers: Session, mock_external_service_dependencies): # Arrange fake = Faker() @@ -356,7 +357,7 @@ class TestGetAvailableDatasetsIntegration: assert result[0].tenant_id == tenant1.id def test_returns_empty_list_when_no_datasets_found( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): # Arrange fake = Faker() @@ -379,7 +380,9 @@ class TestGetAvailableDatasetsIntegration: # Assert assert result == [] - def test_returns_only_requested_dataset_ids(self, db_session_with_containers, mock_external_service_dependencies): + def test_returns_only_requested_dataset_ids( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): # Arrange fake = Faker() @@ -439,7 +442,7 @@ class TestGetAvailableDatasetsIntegration: class TestKnowledgeRetrievalIntegration: def test_knowledge_retrieval_with_available_datasets( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): # Arrange fake = Faker() @@ -507,7 +510,7 @@ class TestKnowledgeRetrievalIntegration: assert isinstance(result, list) def test_knowledge_retrieval_no_available_datasets( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): # Arrange fake = Faker() @@ -555,7 +558,7 @@ class TestKnowledgeRetrievalIntegration: assert result == [] def test_knowledge_retrieval_rate_limit_exceeded( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): # Arrange fake = Faker() diff --git a/api/tests/test_containers_integration_tests/factories/test_storage_key_loader.py b/api/tests/test_containers_integration_tests/factories/test_storage_key_loader.py index 35e41035df..26b80cebbb 100644 --- a/api/tests/test_containers_integration_tests/factories/test_storage_key_loader.py +++ b/api/tests/test_containers_integration_tests/factories/test_storage_key_loader.py @@ -1,4 +1,5 @@ -import unittest +from __future__ import annotations + from datetime import UTC, datetime from unittest.mock import patch from uuid import uuid4 @@ -16,7 +17,7 @@ from models.enums import CreatorUserRole @pytest.mark.usefixtures("flask_req_ctx_with_containers") -class TestStorageKeyLoader(unittest.TestCase): +class TestStorageKeyLoader: """ Integration tests for StorageKeyLoader class. @@ -24,110 +25,82 @@ class TestStorageKeyLoader(unittest.TestCase): with different transfer methods: LOCAL_FILE, REMOTE_URL, and TOOL_FILE. """ - def setUp(self): - """Set up test data before each test method.""" - self.session = db.session() - self.tenant_id = str(uuid4()) - self.user_id = str(uuid4()) - self.conversation_id = str(uuid4()) - - # Create test data that will be cleaned up after each test - self.test_upload_files = [] - self.test_tool_files = [] - - # Create StorageKeyLoader instance - self.loader = StorageKeyLoader( - self.session, - self.tenant_id, - access_controller=DatabaseFileAccessController(), - ) - - def tearDown(self): - """Clean up test data after each test method.""" - self.session.rollback() + # ------------------------------------------------------------------ + # Per-test helpers (use db_session_with_containers as parameter) + # ------------------------------------------------------------------ + @staticmethod def _create_upload_file( - self, file_id: str | None = None, storage_key: str | None = None, tenant_id: str | None = None + session: Session, + tenant_id: str, + user_id: str, + *, + file_id: str | None = None, + storage_key: str | None = None, + override_tenant_id: str | None = None, ) -> UploadFile: - """Helper method to create an UploadFile record for testing.""" - if file_id is None: - file_id = str(uuid4()) - if storage_key is None: - storage_key = f"test_storage_key_{uuid4()}" - if tenant_id is None: - tenant_id = self.tenant_id - + """Create and flush an UploadFile record for testing.""" upload_file = UploadFile( - tenant_id=tenant_id, + tenant_id=override_tenant_id if override_tenant_id is not None else tenant_id, storage_type=StorageType.LOCAL, - key=storage_key, + key=storage_key or f"test_storage_key_{uuid4()}", name="test_file.txt", size=1024, extension=".txt", mime_type="text/plain", created_by_role=CreatorUserRole.ACCOUNT, - created_by=self.user_id, + created_by=user_id, created_at=datetime.now(UTC), used=False, ) - upload_file.id = file_id - - self.session.add(upload_file) - self.session.flush() - self.test_upload_files.append(upload_file) - + upload_file.id = file_id or str(uuid4()) + session.add(upload_file) + session.flush() return upload_file + @staticmethod def _create_tool_file( - self, file_id: str | None = None, file_key: str | None = None, tenant_id: str | None = None + session: Session, + tenant_id: str, + user_id: str, + conversation_id: str, + *, + file_id: str | None = None, + file_key: str | None = None, + override_tenant_id: str | None = None, ) -> ToolFile: - """Helper method to create a ToolFile record for testing.""" - if file_id is None: - file_id = str(uuid4()) - if file_key is None: - file_key = f"test_file_key_{uuid4()}" - if tenant_id is None: - tenant_id = self.tenant_id - + """Create and flush a ToolFile record for testing.""" tool_file = ToolFile( - user_id=self.user_id, - tenant_id=tenant_id, - conversation_id=self.conversation_id, - file_key=file_key, + user_id=user_id, + tenant_id=override_tenant_id if override_tenant_id is not None else tenant_id, + conversation_id=conversation_id, + file_key=file_key or f"test_file_key_{uuid4()}", mimetype="text/plain", original_url="http://example.com/file.txt", name="test_tool_file.txt", size=2048, ) - tool_file.id = file_id - - self.session.add(tool_file) - self.session.flush() - self.test_tool_files.append(tool_file) - + tool_file.id = file_id or str(uuid4()) + session.add(tool_file) + session.flush() return tool_file - def _create_file(self, related_id: str, transfer_method: FileTransferMethod, tenant_id: str | None = None) -> File: - """Helper method to create a File object for testing.""" - if tenant_id is None: - tenant_id = self.tenant_id - - # Set related_id for LOCAL_FILE and TOOL_FILE transfer methods - file_related_id = None - remote_url = None - - if transfer_method in (FileTransferMethod.LOCAL_FILE, FileTransferMethod.TOOL_FILE): - file_related_id = related_id - elif transfer_method == FileTransferMethod.REMOTE_URL: - remote_url = "https://example.com/test_file.txt" - file_related_id = related_id - + @staticmethod + def _create_file( + tenant_id: str, + related_id: str, + transfer_method: FileTransferMethod, + *, + override_tenant_id: str | None = None, + ) -> File: + """Build a File value-object for testing.""" + remote_url = "https://example.com/test_file.txt" if transfer_method == FileTransferMethod.REMOTE_URL else None return File( - file_id=str(uuid4()), # Generate new UUID for File.id - tenant_id=tenant_id, + file_id=str(uuid4()), + tenant_id=override_tenant_id if override_tenant_id is not None else tenant_id, file_type=FileType.DOCUMENT, transfer_method=transfer_method, - related_id=file_related_id, + related_id=related_id, remote_url=remote_url, filename="test_file.txt", extension=".txt", @@ -136,240 +109,280 @@ class TestStorageKeyLoader(unittest.TestCase): storage_key="initial_key", ) - def test_load_storage_keys_local_file(self): + # ------------------------------------------------------------------ + # Tests + # ------------------------------------------------------------------ + + def test_load_storage_keys_local_file(self, db_session_with_containers: Session): """Test loading storage keys for LOCAL_FILE transfer method.""" - # Create test data - upload_file = self._create_upload_file() - file = self._create_file(related_id=upload_file.id, transfer_method=FileTransferMethod.LOCAL_FILE) + tenant_id = str(uuid4()) + user_id = str(uuid4()) - # Load storage keys - self.loader.load_storage_keys([file]) + upload_file = self._create_upload_file(db_session_with_containers, tenant_id, user_id) + file = self._create_file(tenant_id, related_id=upload_file.id, transfer_method=FileTransferMethod.LOCAL_FILE) + + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) + loader.load_storage_keys([file]) - # Verify storage key was loaded correctly assert file._storage_key == upload_file.key - def test_load_storage_keys_remote_url(self): + def test_load_storage_keys_remote_url(self, db_session_with_containers: Session): """Test loading storage keys for REMOTE_URL transfer method.""" - # Create test data - upload_file = self._create_upload_file() - file = self._create_file(related_id=upload_file.id, transfer_method=FileTransferMethod.REMOTE_URL) + tenant_id = str(uuid4()) + user_id = str(uuid4()) - # Load storage keys - self.loader.load_storage_keys([file]) + upload_file = self._create_upload_file(db_session_with_containers, tenant_id, user_id) + file = self._create_file(tenant_id, related_id=upload_file.id, transfer_method=FileTransferMethod.REMOTE_URL) + + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) + loader.load_storage_keys([file]) - # Verify storage key was loaded correctly assert file._storage_key == upload_file.key - def test_load_storage_keys_tool_file(self): + def test_load_storage_keys_tool_file(self, db_session_with_containers: Session): """Test loading storage keys for TOOL_FILE transfer method.""" - # Create test data - tool_file = self._create_tool_file() - file = self._create_file(related_id=tool_file.id, transfer_method=FileTransferMethod.TOOL_FILE) + tenant_id = str(uuid4()) + user_id = str(uuid4()) + conversation_id = str(uuid4()) - # Load storage keys - self.loader.load_storage_keys([file]) + tool_file = self._create_tool_file(db_session_with_containers, tenant_id, user_id, conversation_id) + file = self._create_file(tenant_id, related_id=tool_file.id, transfer_method=FileTransferMethod.TOOL_FILE) + + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) + loader.load_storage_keys([file]) - # Verify storage key was loaded correctly assert file._storage_key == tool_file.file_key - def test_load_storage_keys_mixed_methods(self): + def test_load_storage_keys_mixed_methods(self, db_session_with_containers: Session): """Test batch loading with mixed transfer methods.""" - # Create test data for different transfer methods - upload_file1 = self._create_upload_file() - upload_file2 = self._create_upload_file() - tool_file = self._create_tool_file() + tenant_id = str(uuid4()) + user_id = str(uuid4()) + conversation_id = str(uuid4()) - file1 = self._create_file(related_id=upload_file1.id, transfer_method=FileTransferMethod.LOCAL_FILE) - file2 = self._create_file(related_id=upload_file2.id, transfer_method=FileTransferMethod.REMOTE_URL) - file3 = self._create_file(related_id=tool_file.id, transfer_method=FileTransferMethod.TOOL_FILE) + upload_file1 = self._create_upload_file(db_session_with_containers, tenant_id, user_id) + upload_file2 = self._create_upload_file(db_session_with_containers, tenant_id, user_id) + tool_file = self._create_tool_file(db_session_with_containers, tenant_id, user_id, conversation_id) - files = [file1, file2, file3] + file1 = self._create_file(tenant_id, related_id=upload_file1.id, transfer_method=FileTransferMethod.LOCAL_FILE) + file2 = self._create_file(tenant_id, related_id=upload_file2.id, transfer_method=FileTransferMethod.REMOTE_URL) + file3 = self._create_file(tenant_id, related_id=tool_file.id, transfer_method=FileTransferMethod.TOOL_FILE) - # Load storage keys - self.loader.load_storage_keys(files) + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) + loader.load_storage_keys([file1, file2, file3]) - # Verify all storage keys were loaded correctly assert file1._storage_key == upload_file1.key assert file2._storage_key == upload_file2.key assert file3._storage_key == tool_file.file_key - def test_load_storage_keys_empty_list(self): - """Test with empty file list.""" - # Should not raise any exceptions - self.loader.load_storage_keys([]) + def test_load_storage_keys_empty_list(self, db_session_with_containers: Session): + """Test with empty file list — should not raise.""" + tenant_id = str(uuid4()) + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) + loader.load_storage_keys([]) - def test_load_storage_keys_ignores_legacy_file_tenant_id(self): + def test_load_storage_keys_ignores_legacy_file_tenant_id(self, db_session_with_containers: Session): """Legacy file tenant_id should not override the loader tenant scope.""" - upload_file = self._create_upload_file() + tenant_id = str(uuid4()) + user_id = str(uuid4()) + + upload_file = self._create_upload_file(db_session_with_containers, tenant_id, user_id) file = self._create_file( - related_id=upload_file.id, transfer_method=FileTransferMethod.LOCAL_FILE, tenant_id=str(uuid4()) + tenant_id, + related_id=upload_file.id, + transfer_method=FileTransferMethod.LOCAL_FILE, + override_tenant_id=str(uuid4()), ) - self.loader.load_storage_keys([file]) + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) + loader.load_storage_keys([file]) assert file._storage_key == upload_file.key - def test_load_storage_keys_missing_file_id(self): - """Test with None file.related_id.""" - # Create a file with valid parameters first, then manually set related_id to None - file = self._create_file(related_id=str(uuid4()), transfer_method=FileTransferMethod.LOCAL_FILE) + def test_load_storage_keys_missing_file_id(self, db_session_with_containers: Session): + """Test with None file.related_id — should raise ValueError.""" + tenant_id = str(uuid4()) + user_id = str(uuid4()) + + upload_file = self._create_upload_file(db_session_with_containers, tenant_id, user_id) + file = self._create_file(tenant_id, related_id=upload_file.id, transfer_method=FileTransferMethod.LOCAL_FILE) file.related_id = None - # Should raise ValueError for None file related_id - with pytest.raises(ValueError) as context: - self.loader.load_storage_keys([file]) + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) + with pytest.raises(ValueError, match="file id should not be None."): + loader.load_storage_keys([file]) - assert str(context.value) == "file id should not be None." + def test_load_storage_keys_nonexistent_upload_file_records(self, db_session_with_containers: Session): + """Test with missing UploadFile database records — should raise ValueError.""" + tenant_id = str(uuid4()) + file = self._create_file(tenant_id, related_id=str(uuid4()), transfer_method=FileTransferMethod.LOCAL_FILE) - def test_load_storage_keys_nonexistent_upload_file_records(self): - """Test with missing UploadFile database records.""" - # Create file with non-existent upload file id - non_existent_id = str(uuid4()) - file = self._create_file(related_id=non_existent_id, transfer_method=FileTransferMethod.LOCAL_FILE) - - # Should raise ValueError for missing record + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) with pytest.raises(ValueError): - self.loader.load_storage_keys([file]) + loader.load_storage_keys([file]) - def test_load_storage_keys_nonexistent_tool_file_records(self): - """Test with missing ToolFile database records.""" - # Create file with non-existent tool file id - non_existent_id = str(uuid4()) - file = self._create_file(related_id=non_existent_id, transfer_method=FileTransferMethod.TOOL_FILE) + def test_load_storage_keys_nonexistent_tool_file_records(self, db_session_with_containers: Session): + """Test with missing ToolFile database records — should raise ValueError.""" + tenant_id = str(uuid4()) + file = self._create_file(tenant_id, related_id=str(uuid4()), transfer_method=FileTransferMethod.TOOL_FILE) - # Should raise ValueError for missing record + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) with pytest.raises(ValueError): - self.loader.load_storage_keys([file]) + loader.load_storage_keys([file]) - def test_load_storage_keys_invalid_uuid(self): - """Test with invalid UUID format.""" - # Create a file with valid parameters first, then manually set invalid related_id - file = self._create_file(related_id=str(uuid4()), transfer_method=FileTransferMethod.LOCAL_FILE) + def test_load_storage_keys_invalid_uuid(self, db_session_with_containers: Session): + """Test with invalid UUID format — should raise ValueError.""" + tenant_id = str(uuid4()) + user_id = str(uuid4()) + + upload_file = self._create_upload_file(db_session_with_containers, tenant_id, user_id) + file = self._create_file(tenant_id, related_id=upload_file.id, transfer_method=FileTransferMethod.LOCAL_FILE) file.related_id = "invalid-uuid-format" - # Should raise ValueError for invalid UUID + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) with pytest.raises(ValueError): - self.loader.load_storage_keys([file]) + loader.load_storage_keys([file]) - def test_load_storage_keys_batch_efficiency(self): - """Test batched operations use efficient queries.""" - # Create multiple files of different types - upload_files = [self._create_upload_file() for _ in range(3)] - tool_files = [self._create_tool_file() for _ in range(2)] + def test_load_storage_keys_batch_efficiency(self, db_session_with_containers: Session): + """Batched operations should issue exactly 2 queries for mixed file types.""" + tenant_id = str(uuid4()) + user_id = str(uuid4()) + conversation_id = str(uuid4()) - files = [] - files.extend( - [self._create_file(related_id=uf.id, transfer_method=FileTransferMethod.LOCAL_FILE) for uf in upload_files] + upload_files = [self._create_upload_file(db_session_with_containers, tenant_id, user_id) for _ in range(3)] + tool_files = [ + self._create_tool_file(db_session_with_containers, tenant_id, user_id, conversation_id) for _ in range(2) + ] + + files = [ + self._create_file(tenant_id, related_id=uf.id, transfer_method=FileTransferMethod.LOCAL_FILE) + for uf in upload_files + ] + [ + self._create_file(tenant_id, related_id=tf.id, transfer_method=FileTransferMethod.TOOL_FILE) + for tf in tool_files + ] + + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() ) - files.extend( - [self._create_file(related_id=tf.id, transfer_method=FileTransferMethod.TOOL_FILE) for tf in tool_files] - ) - - # Mock the session to count queries - with patch.object(self.session, "scalars", wraps=self.session.scalars) as mock_scalars: - self.loader.load_storage_keys(files) - - # Should make exactly 2 queries (one for upload_files, one for tool_files) + with patch.object( + db_session_with_containers, "scalars", wraps=db_session_with_containers.scalars + ) as mock_scalars: + loader.load_storage_keys(files) + # Exactly 2 DB round-trips: one for UploadFile, one for ToolFile assert mock_scalars.call_count == 2 - # Verify all storage keys were loaded correctly for i, file in enumerate(files[:3]): assert file._storage_key == upload_files[i].key for i, file in enumerate(files[3:]): assert file._storage_key == tool_files[i].file_key - def test_load_storage_keys_tenant_isolation(self): - """Test that tenant isolation works correctly.""" - # Create files for different tenants + def test_load_storage_keys_tenant_isolation(self, db_session_with_containers: Session): + """Loader should not surface records belonging to a different tenant.""" + tenant_id = str(uuid4()) other_tenant_id = str(uuid4()) + user_id = str(uuid4()) - # Create upload file for current tenant - upload_file_current = self._create_upload_file() + upload_file_current = self._create_upload_file(db_session_with_containers, tenant_id, user_id) file_current = self._create_file( - related_id=upload_file_current.id, transfer_method=FileTransferMethod.LOCAL_FILE + tenant_id, related_id=upload_file_current.id, transfer_method=FileTransferMethod.LOCAL_FILE ) - # Create upload file for other tenant (but don't add to cleanup list) - upload_file_other = UploadFile( - tenant_id=other_tenant_id, - storage_type=StorageType.LOCAL, - key="other_tenant_key", - name="other_file.txt", - size=1024, - extension=".txt", - mime_type="text/plain", - created_by_role=CreatorUserRole.ACCOUNT, - created_by=self.user_id, - created_at=datetime.now(UTC), - used=False, + upload_file_other = self._create_upload_file( + db_session_with_containers, + tenant_id, + user_id, + override_tenant_id=other_tenant_id, ) - upload_file_other.id = str(uuid4()) - self.session.add(upload_file_other) - self.session.flush() - - # Create file for other tenant but try to load with current tenant's loader file_other = self._create_file( - related_id=upload_file_other.id, transfer_method=FileTransferMethod.LOCAL_FILE, tenant_id=other_tenant_id + tenant_id, + related_id=upload_file_other.id, + transfer_method=FileTransferMethod.LOCAL_FILE, + override_tenant_id=other_tenant_id, ) - # Should raise ValueError due to tenant mismatch - with pytest.raises(ValueError) as context: - self.loader.load_storage_keys([file_other]) + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) - assert "Upload file not found for id:" in str(context.value) + with pytest.raises(ValueError, match="Upload file not found for id:"): + loader.load_storage_keys([file_other]) - # Current tenant's file should still work - self.loader.load_storage_keys([file_current]) + # Current-tenant file still resolves correctly + loader.load_storage_keys([file_current]) assert file_current._storage_key == upload_file_current.key - def test_load_storage_keys_mixed_tenant_batch(self): - """Test batch with mixed tenant files (should fail on first mismatch).""" - # Create files for current tenant - upload_file_current = self._create_upload_file() + def test_load_storage_keys_mixed_tenant_batch(self, db_session_with_containers: Session): + """A batch containing a foreign-tenant file should fail on the mismatch.""" + tenant_id = str(uuid4()) + user_id = str(uuid4()) + + upload_file_current = self._create_upload_file(db_session_with_containers, tenant_id, user_id) file_current = self._create_file( - related_id=upload_file_current.id, transfer_method=FileTransferMethod.LOCAL_FILE + tenant_id, related_id=upload_file_current.id, transfer_method=FileTransferMethod.LOCAL_FILE ) - - # Create file for different tenant - other_tenant_id = str(uuid4()) file_other = self._create_file( - related_id=str(uuid4()), transfer_method=FileTransferMethod.LOCAL_FILE, tenant_id=other_tenant_id + tenant_id, + related_id=str(uuid4()), + transfer_method=FileTransferMethod.LOCAL_FILE, + override_tenant_id=str(uuid4()), ) - # Should raise ValueError on tenant mismatch - with pytest.raises(ValueError) as context: - self.loader.load_storage_keys([file_current, file_other]) + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) + with pytest.raises(ValueError, match="Upload file not found for id:"): + loader.load_storage_keys([file_current, file_other]) - assert "Upload file not found for id:" in str(context.value) + def test_load_storage_keys_duplicate_file_ids(self, db_session_with_containers: Session): + """Duplicate file IDs in the batch should be handled gracefully.""" + tenant_id = str(uuid4()) + user_id = str(uuid4()) - def test_load_storage_keys_duplicate_file_ids(self): - """Test handling of duplicate file IDs in the batch.""" - # Create upload file - upload_file = self._create_upload_file() + upload_file = self._create_upload_file(db_session_with_containers, tenant_id, user_id) + file1 = self._create_file(tenant_id, related_id=upload_file.id, transfer_method=FileTransferMethod.LOCAL_FILE) + file2 = self._create_file(tenant_id, related_id=upload_file.id, transfer_method=FileTransferMethod.LOCAL_FILE) - # Create two File objects with same related_id - file1 = self._create_file(related_id=upload_file.id, transfer_method=FileTransferMethod.LOCAL_FILE) - file2 = self._create_file(related_id=upload_file.id, transfer_method=FileTransferMethod.LOCAL_FILE) + loader = StorageKeyLoader( + db_session_with_containers, tenant_id, access_controller=DatabaseFileAccessController() + ) + loader.load_storage_keys([file1, file2]) - # Should handle duplicates gracefully - self.loader.load_storage_keys([file1, file2]) - - # Both files should have the same storage key assert file1._storage_key == upload_file.key assert file2._storage_key == upload_file.key - def test_load_storage_keys_session_isolation(self): - """Test that the loader uses the provided session correctly.""" - # Create test data - upload_file = self._create_upload_file() - file = self._create_file(related_id=upload_file.id, transfer_method=FileTransferMethod.LOCAL_FILE) + def test_load_storage_keys_session_isolation(self, db_session_with_containers: Session): + """A loader backed by an uncommitted session should not see data from another session.""" + tenant_id = str(uuid4()) + user_id = str(uuid4()) - # Create loader with different session (same underlying connection) + upload_file = self._create_upload_file(db_session_with_containers, tenant_id, user_id) + file = self._create_file(tenant_id, related_id=upload_file.id, transfer_method=FileTransferMethod.LOCAL_FILE) + # A loader with a fresh, separate session cannot see uncommitted rows from db_session_with_containers with Session(bind=db.engine) as other_session: other_loader = StorageKeyLoader( other_session, - self.tenant_id, + tenant_id, access_controller=DatabaseFileAccessController(), ) with pytest.raises(ValueError): diff --git a/api/tests/test_containers_integration_tests/libs/broadcast_channel/redis/test_sharded_channel.py b/api/tests/test_containers_integration_tests/libs/broadcast_channel/redis/test_sharded_channel.py index 43915a204d..84c1d0ca41 100644 --- a/api/tests/test_containers_integration_tests/libs/broadcast_channel/redis/test_sharded_channel.py +++ b/api/tests/test_containers_integration_tests/libs/broadcast_channel/redis/test_sharded_channel.py @@ -8,6 +8,7 @@ Covers real Redis 7+ sharded pub/sub interactions including: - Resource cleanup accounting via PUBSUB SHARDNUMSUB """ +import socket import threading import time import uuid @@ -356,10 +357,17 @@ class TestShardedRedisBroadcastChannelClusterIntegration: def _get_test_topic_name(cls) -> str: return f"test_sharded_cluster_topic_{uuid.uuid4()}" + @staticmethod + def _resolve_announced_ip(host: str) -> str: + """Resolve the container host name to a literal IP accepted by Redis cluster config.""" + return socket.getaddrinfo(host, None, type=socket.SOCK_STREAM)[0][4][0] + @staticmethod def _ensure_single_node_cluster(host: str, port: int) -> None: + """Bootstrap a single-node cluster using a literal IP for Redis node advertisement.""" client = redis.Redis(host=host, port=port, decode_responses=False) - client.config_set("cluster-announce-ip", host) + announced_ip = TestShardedRedisBroadcastChannelClusterIntegration._resolve_announced_ip(host) + client.config_set("cluster-announce-ip", announced_ip) client.config_set("cluster-announce-port", port) slots = client.execute_command("CLUSTER", "SLOTS") if not slots: diff --git a/api/tests/test_containers_integration_tests/services/auth/test_api_key_auth_service.py b/api/tests/test_containers_integration_tests/services/auth/test_api_key_auth_service.py index 177fb95ff3..e71079829f 100644 --- a/api/tests/test_containers_integration_tests/services/auth/test_api_key_auth_service.py +++ b/api/tests/test_containers_integration_tests/services/auth/test_api_key_auth_service.py @@ -5,6 +5,7 @@ from unittest.mock import Mock, patch from uuid import uuid4 import pytest +from sqlalchemy.orm import Session from models.source import DataSourceApiKeyAuthBinding from services.auth.api_key_auth_service import ApiKeyAuthService @@ -31,7 +32,7 @@ class TestApiKeyAuthService: def mock_args(self, category, provider, mock_credentials) -> dict: return {"category": category, "provider": provider, "credentials": mock_credentials} - def _create_binding(self, db_session, *, tenant_id, category, provider, credentials=None, disabled=False): + def _create_binding(self, db_session: Session, *, tenant_id, category, provider, credentials=None, disabled=False): binding = DataSourceApiKeyAuthBinding( tenant_id=tenant_id, category=category, @@ -44,7 +45,7 @@ class TestApiKeyAuthService: return binding def test_get_provider_auth_list_success( - self, flask_app_with_containers, db_session_with_containers, tenant_id, category, provider + self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, category, provider ): self._create_binding(db_session_with_containers, tenant_id=tenant_id, category=category, provider=provider) db_session_with_containers.expire_all() @@ -56,14 +57,16 @@ class TestApiKeyAuthService: assert len(tenant_results) == 1 assert tenant_results[0].provider == provider - def test_get_provider_auth_list_empty(self, flask_app_with_containers, db_session_with_containers, tenant_id): + def test_get_provider_auth_list_empty( + self, flask_app_with_containers, db_session_with_containers: Session, tenant_id + ): result = ApiKeyAuthService.get_provider_auth_list(tenant_id) tenant_results = [r for r in result if r.tenant_id == tenant_id] assert tenant_results == [] def test_get_provider_auth_list_filters_disabled( - self, flask_app_with_containers, db_session_with_containers, tenant_id, category, provider + self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, category, provider ): self._create_binding( db_session_with_containers, tenant_id=tenant_id, category=category, provider=provider, disabled=True @@ -78,7 +81,13 @@ class TestApiKeyAuthService: @patch("services.auth.api_key_auth_service.ApiKeyAuthFactory") @patch("services.auth.api_key_auth_service.encrypter") def test_create_provider_auth_success( - self, mock_encrypter, mock_factory, flask_app_with_containers, db_session_with_containers, tenant_id, mock_args + self, + mock_encrypter, + mock_factory, + flask_app_with_containers, + db_session_with_containers: Session, + tenant_id, + mock_args, ): mock_auth_instance = Mock() mock_auth_instance.validate_credentials.return_value = True @@ -97,7 +106,7 @@ class TestApiKeyAuthService: @patch("services.auth.api_key_auth_service.ApiKeyAuthFactory") def test_create_provider_auth_validation_failed( - self, mock_factory, flask_app_with_containers, db_session_with_containers, tenant_id, mock_args + self, mock_factory, flask_app_with_containers, db_session_with_containers: Session, tenant_id, mock_args ): mock_auth_instance = Mock() mock_auth_instance.validate_credentials.return_value = False @@ -112,7 +121,13 @@ class TestApiKeyAuthService: @patch("services.auth.api_key_auth_service.ApiKeyAuthFactory") @patch("services.auth.api_key_auth_service.encrypter") def test_create_provider_auth_encrypts_api_key( - self, mock_encrypter, mock_factory, flask_app_with_containers, db_session_with_containers, tenant_id, mock_args + self, + mock_encrypter, + mock_factory, + flask_app_with_containers, + db_session_with_containers: Session, + tenant_id, + mock_args, ): mock_auth_instance = Mock() mock_auth_instance.validate_credentials.return_value = True @@ -128,7 +143,13 @@ class TestApiKeyAuthService: mock_encrypter.encrypt_token.assert_called_once_with(tenant_id, original_key) def test_get_auth_credentials_success( - self, flask_app_with_containers, db_session_with_containers, tenant_id, category, provider, mock_credentials + self, + flask_app_with_containers, + db_session_with_containers: Session, + tenant_id, + category, + provider, + mock_credentials, ): self._create_binding( db_session_with_containers, @@ -144,14 +165,14 @@ class TestApiKeyAuthService: assert result == mock_credentials def test_get_auth_credentials_not_found( - self, flask_app_with_containers, db_session_with_containers, tenant_id, category, provider + self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, category, provider ): result = ApiKeyAuthService.get_auth_credentials(tenant_id, category, provider) assert result is None def test_get_auth_credentials_json_parsing( - self, flask_app_with_containers, db_session_with_containers, tenant_id, category, provider + self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, category, provider ): special_credentials = {"auth_type": "api_key", "config": {"api_key": "key_with_中文_and_special_chars_!@#$%"}} self._create_binding( @@ -169,7 +190,7 @@ class TestApiKeyAuthService: assert result["config"]["api_key"] == "key_with_中文_and_special_chars_!@#$%" def test_delete_provider_auth_success( - self, flask_app_with_containers, db_session_with_containers, tenant_id, category, provider + self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, category, provider ): binding = self._create_binding( db_session_with_containers, tenant_id=tenant_id, category=category, provider=provider @@ -183,7 +204,9 @@ class TestApiKeyAuthService: remaining = db_session_with_containers.query(DataSourceApiKeyAuthBinding).filter_by(id=binding_id).first() assert remaining is None - def test_delete_provider_auth_not_found(self, flask_app_with_containers, db_session_with_containers, tenant_id): + def test_delete_provider_auth_not_found( + self, flask_app_with_containers, db_session_with_containers: Session, tenant_id + ): # Should not raise when binding not found ApiKeyAuthService.delete_provider_auth(tenant_id, str(uuid4())) diff --git a/api/tests/test_containers_integration_tests/services/auth/test_auth_integration.py b/api/tests/test_containers_integration_tests/services/auth/test_auth_integration.py index f48c6da690..e78fa27976 100644 --- a/api/tests/test_containers_integration_tests/services/auth/test_auth_integration.py +++ b/api/tests/test_containers_integration_tests/services/auth/test_auth_integration.py @@ -10,6 +10,7 @@ from uuid import uuid4 import httpx import pytest +from sqlalchemy.orm import Session from models.source import DataSourceApiKeyAuthBinding from services.auth.api_key_auth_factory import ApiKeyAuthFactory @@ -114,7 +115,7 @@ class TestAuthIntegration: assert result2[0].tenant_id == tenant_id_2 def test_cross_tenant_access_prevention( - self, flask_app_with_containers, db_session_with_containers, tenant_id_2, category + self, flask_app_with_containers, db_session_with_containers: Session, tenant_id_2, category ): result = ApiKeyAuthService.get_auth_credentials(tenant_id_2, category, AuthType.FIRECRAWL) diff --git a/api/tests/test_containers_integration_tests/services/document_service_status.py b/api/tests/test_containers_integration_tests/services/document_service_status.py index 42d587b7f7..327f14ddfe 100644 --- a/api/tests/test_containers_integration_tests/services/document_service_status.py +++ b/api/tests/test_containers_integration_tests/services/document_service_status.py @@ -12,6 +12,7 @@ from unittest.mock import create_autospec, patch from uuid import uuid4 import pytest +from sqlalchemy.orm import Session from core.rag.index_processor.constant.index_type import IndexStructureType from extensions.storage.storage_type import StorageType @@ -273,7 +274,9 @@ class TestDocumentServicePauseDocument: "user_id": user_id, } - def test_pause_document_waiting_state_success(self, db_session_with_containers, mock_document_service_dependencies): + def test_pause_document_waiting_state_success( + self, db_session_with_containers: Session, mock_document_service_dependencies + ): """ Test successful pause of document in waiting state. @@ -310,7 +313,7 @@ class TestDocumentServicePauseDocument: mock_document_service_dependencies["redis_client"].setnx.assert_called_once_with(expected_cache_key, "True") def test_pause_document_indexing_state_success( - self, db_session_with_containers, mock_document_service_dependencies + self, db_session_with_containers: Session, mock_document_service_dependencies ): """ Test successful pause of document in indexing state. @@ -340,7 +343,9 @@ class TestDocumentServicePauseDocument: assert document.is_paused is True assert document.paused_by == mock_document_service_dependencies["user_id"] - def test_pause_document_parsing_state_success(self, db_session_with_containers, mock_document_service_dependencies): + def test_pause_document_parsing_state_success( + self, db_session_with_containers: Session, mock_document_service_dependencies + ): """ Test successful pause of document in parsing state. @@ -367,7 +372,9 @@ class TestDocumentServicePauseDocument: db_session_with_containers.refresh(document) assert document.is_paused is True - def test_pause_document_completed_state_error(self, db_session_with_containers, mock_document_service_dependencies): + def test_pause_document_completed_state_error( + self, db_session_with_containers: Session, mock_document_service_dependencies + ): """ Test error when trying to pause completed document. @@ -396,7 +403,9 @@ class TestDocumentServicePauseDocument: db_session_with_containers.refresh(document) assert document.is_paused is False - def test_pause_document_error_state_error(self, db_session_with_containers, mock_document_service_dependencies): + def test_pause_document_error_state_error( + self, db_session_with_containers: Session, mock_document_service_dependencies + ): """ Test error when trying to pause document in error state. @@ -467,7 +476,9 @@ class TestDocumentServiceRecoverDocument: "recover_task": mock_task, } - def test_recover_document_paused_success(self, db_session_with_containers, mock_document_service_dependencies): + def test_recover_document_paused_success( + self, db_session_with_containers: Session, mock_document_service_dependencies + ): """ Test successful recovery of paused document. @@ -510,7 +521,9 @@ class TestDocumentServiceRecoverDocument: document.dataset_id, document.id ) - def test_recover_document_not_paused_error(self, db_session_with_containers, mock_document_service_dependencies): + def test_recover_document_not_paused_error( + self, db_session_with_containers: Session, mock_document_service_dependencies + ): """ Test error when trying to recover non-paused document. @@ -590,7 +603,9 @@ class TestDocumentServiceRetryDocument: "user_id": user_id, } - def test_retry_document_single_success(self, db_session_with_containers, mock_document_service_dependencies): + def test_retry_document_single_success( + self, db_session_with_containers: Session, mock_document_service_dependencies + ): """ Test successful retry of single document. @@ -629,7 +644,9 @@ class TestDocumentServiceRetryDocument: dataset.id, [document.id], mock_document_service_dependencies["user_id"] ) - def test_retry_document_multiple_success(self, db_session_with_containers, mock_document_service_dependencies): + def test_retry_document_multiple_success( + self, db_session_with_containers: Session, mock_document_service_dependencies + ): """ Test successful retry of multiple documents. @@ -675,7 +692,7 @@ class TestDocumentServiceRetryDocument: ) def test_retry_document_concurrent_retry_error( - self, db_session_with_containers, mock_document_service_dependencies + self, db_session_with_containers: Session, mock_document_service_dependencies ): """ Test error when document is already being retried. @@ -708,7 +725,7 @@ class TestDocumentServiceRetryDocument: assert document.indexing_status == IndexingStatus.ERROR def test_retry_document_missing_current_user_error( - self, db_session_with_containers, mock_document_service_dependencies + self, db_session_with_containers: Session, mock_document_service_dependencies ): """ Test error when current_user is missing. @@ -794,7 +811,7 @@ class TestDocumentServiceBatchUpdateDocumentStatus: } def test_batch_update_document_status_enable_success( - self, db_session_with_containers, mock_document_service_dependencies + self, db_session_with_containers: Session, mock_document_service_dependencies ): """ Test successful batch enabling of documents. @@ -844,7 +861,7 @@ class TestDocumentServiceBatchUpdateDocumentStatus: assert mock_document_service_dependencies["add_task"].delay.call_count == 2 def test_batch_update_document_status_disable_success( - self, db_session_with_containers, mock_document_service_dependencies + self, db_session_with_containers: Session, mock_document_service_dependencies ): """ Test successful batch disabling of documents. @@ -886,7 +903,7 @@ class TestDocumentServiceBatchUpdateDocumentStatus: mock_document_service_dependencies["remove_task"].delay.assert_called_once_with(document.id) def test_batch_update_document_status_archive_success( - self, db_session_with_containers, mock_document_service_dependencies + self, db_session_with_containers: Session, mock_document_service_dependencies ): """ Test successful batch archiving of documents. @@ -928,7 +945,7 @@ class TestDocumentServiceBatchUpdateDocumentStatus: mock_document_service_dependencies["remove_task"].delay.assert_called_once_with(document.id) def test_batch_update_document_status_unarchive_success( - self, db_session_with_containers, mock_document_service_dependencies + self, db_session_with_containers: Session, mock_document_service_dependencies ): """ Test successful batch unarchiving of documents. @@ -970,7 +987,7 @@ class TestDocumentServiceBatchUpdateDocumentStatus: mock_document_service_dependencies["add_task"].delay.assert_called_once_with(document.id) def test_batch_update_document_status_empty_list( - self, db_session_with_containers, mock_document_service_dependencies + self, db_session_with_containers: Session, mock_document_service_dependencies ): """ Test handling of empty document list. @@ -996,7 +1013,7 @@ class TestDocumentServiceBatchUpdateDocumentStatus: mock_document_service_dependencies["remove_task"].delay.assert_not_called() def test_batch_update_document_status_document_indexing_error( - self, db_session_with_containers, mock_document_service_dependencies + self, db_session_with_containers: Session, mock_document_service_dependencies ): """ Test error when document is being indexed. @@ -1073,7 +1090,7 @@ class TestDocumentServiceRenameDocument: "current_user": mock_current_user, } - def test_rename_document_success(self, db_session_with_containers, mock_document_service_dependencies): + def test_rename_document_success(self, db_session_with_containers: Session, mock_document_service_dependencies): """ Test successful document renaming. @@ -1111,7 +1128,9 @@ class TestDocumentServiceRenameDocument: assert result == document assert document.name == new_name - def test_rename_document_with_built_in_fields(self, db_session_with_containers, mock_document_service_dependencies): + def test_rename_document_with_built_in_fields( + self, db_session_with_containers: Session, mock_document_service_dependencies + ): """ Test document renaming with built-in fields enabled. @@ -1154,7 +1173,9 @@ class TestDocumentServiceRenameDocument: assert document.doc_metadata["document_name"] == new_name assert document.doc_metadata["existing_key"] == "existing_value" - def test_rename_document_with_upload_file(self, db_session_with_containers, mock_document_service_dependencies): + def test_rename_document_with_upload_file( + self, db_session_with_containers: Session, mock_document_service_dependencies + ): """ Test document renaming with associated upload file. @@ -1202,7 +1223,7 @@ class TestDocumentServiceRenameDocument: assert upload_file.name == new_name def test_rename_document_dataset_not_found_error( - self, db_session_with_containers, mock_document_service_dependencies + self, db_session_with_containers: Session, mock_document_service_dependencies ): """ Test error when dataset is not found. @@ -1224,7 +1245,9 @@ class TestDocumentServiceRenameDocument: with pytest.raises(ValueError, match="Dataset not found"): DocumentService.rename_document(dataset_id, document_id, new_name) - def test_rename_document_not_found_error(self, db_session_with_containers, mock_document_service_dependencies): + def test_rename_document_not_found_error( + self, db_session_with_containers: Session, mock_document_service_dependencies + ): """ Test error when document is not found. @@ -1251,7 +1274,9 @@ class TestDocumentServiceRenameDocument: with pytest.raises(ValueError, match="Document not found"): DocumentService.rename_document(dataset.id, document_id, new_name) - def test_rename_document_permission_error(self, db_session_with_containers, mock_document_service_dependencies): + def test_rename_document_permission_error( + self, db_session_with_containers: Session, mock_document_service_dependencies + ): """ Test error when user lacks permission. diff --git a/api/tests/test_containers_integration_tests/services/enterprise/test_account_deletion_sync.py b/api/tests/test_containers_integration_tests/services/enterprise/test_account_deletion_sync.py index 4e8255d8ed..e73c2afe7f 100644 --- a/api/tests/test_containers_integration_tests/services/enterprise/test_account_deletion_sync.py +++ b/api/tests/test_containers_integration_tests/services/enterprise/test_account_deletion_sync.py @@ -11,6 +11,7 @@ from uuid import uuid4 import pytest from redis import RedisError +from sqlalchemy.orm import Session from extensions.ext_redis import redis_client from models.account import TenantAccountJoin @@ -122,7 +123,7 @@ class TestSyncAccountDeletion: mock_queue_task.assert_not_called() def test_sync_account_deletion_multiple_workspaces( - self, flask_app_with_containers, db_session_with_containers, mock_queue_task + self, flask_app_with_containers, db_session_with_containers: Session, mock_queue_task ): account_id = str(uuid4()) tenant_ids = [str(uuid4()) for _ in range(3)] @@ -144,7 +145,7 @@ class TestSyncAccountDeletion: assert queued_workspace_ids == set(tenant_ids) def test_sync_account_deletion_no_workspaces( - self, flask_app_with_containers, db_session_with_containers, mock_queue_task + self, flask_app_with_containers, db_session_with_containers: Session, mock_queue_task ): with patch("services.enterprise.account_deletion_sync.dify_config") as mock_config: mock_config.ENTERPRISE_ENABLED = True @@ -155,7 +156,7 @@ class TestSyncAccountDeletion: mock_queue_task.assert_not_called() def test_sync_account_deletion_partial_failure( - self, flask_app_with_containers, db_session_with_containers, mock_queue_task + self, flask_app_with_containers, db_session_with_containers: Session, mock_queue_task ): account_id = str(uuid4()) tenant_ids = [str(uuid4()) for _ in range(3)] @@ -180,7 +181,7 @@ class TestSyncAccountDeletion: assert mock_queue_task.call_count == 3 def test_sync_account_deletion_all_failures( - self, flask_app_with_containers, db_session_with_containers, mock_queue_task + self, flask_app_with_containers, db_session_with_containers: Session, mock_queue_task ): account_id = str(uuid4()) tenant_id = str(uuid4()) diff --git a/api/tests/test_containers_integration_tests/services/plugin/test_plugin_permission_service.py b/api/tests/test_containers_integration_tests/services/plugin/test_plugin_permission_service.py new file mode 100644 index 0000000000..49d06986fd --- /dev/null +++ b/api/tests/test_containers_integration_tests/services/plugin/test_plugin_permission_service.py @@ -0,0 +1,94 @@ +from __future__ import annotations + +from uuid import uuid4 + +from sqlalchemy import func, select +from sqlalchemy.orm import Session + +from models.account import TenantPluginPermission +from services.plugin.plugin_permission_service import PluginPermissionService + + +def _tenant_id() -> str: + return str(uuid4()) + + +def _get_permission(session: Session, tenant_id: str) -> TenantPluginPermission | None: + session.expire_all() + stmt = select(TenantPluginPermission).where(TenantPluginPermission.tenant_id == tenant_id) + return session.scalars(stmt).one_or_none() + + +def _count_permissions(session: Session, tenant_id: str) -> int: + stmt = select(func.count()).select_from(TenantPluginPermission).where(TenantPluginPermission.tenant_id == tenant_id) + return session.scalar(stmt) or 0 + + +class TestGetPermission: + """Integration tests for PluginPermissionService.get_permission using testcontainers.""" + + def test_returns_permission_when_found(self, db_session_with_containers: Session): + tenant_id = _tenant_id() + permission = TenantPluginPermission( + tenant_id=tenant_id, + install_permission=TenantPluginPermission.InstallPermission.ADMINS, + debug_permission=TenantPluginPermission.DebugPermission.EVERYONE, + ) + db_session_with_containers.add(permission) + db_session_with_containers.commit() + + result = PluginPermissionService.get_permission(tenant_id) + + assert result is not None + assert result.id == permission.id + assert result.tenant_id == tenant_id + assert result.install_permission == TenantPluginPermission.InstallPermission.ADMINS + assert result.debug_permission == TenantPluginPermission.DebugPermission.EVERYONE + + def test_returns_none_when_not_found(self, db_session_with_containers: Session): + result = PluginPermissionService.get_permission(_tenant_id()) + + assert result is None + + +class TestChangePermission: + """Integration tests for PluginPermissionService.change_permission using testcontainers.""" + + def test_creates_new_permission_when_not_exists(self, db_session_with_containers: Session): + tenant_id = _tenant_id() + + result = PluginPermissionService.change_permission( + tenant_id, + TenantPluginPermission.InstallPermission.EVERYONE, + TenantPluginPermission.DebugPermission.EVERYONE, + ) + + permission = _get_permission(db_session_with_containers, tenant_id) + assert result is True + assert permission is not None + assert permission.install_permission == TenantPluginPermission.InstallPermission.EVERYONE + assert permission.debug_permission == TenantPluginPermission.DebugPermission.EVERYONE + + def test_updates_existing_permission(self, db_session_with_containers: Session): + tenant_id = _tenant_id() + existing = TenantPluginPermission( + tenant_id=tenant_id, + install_permission=TenantPluginPermission.InstallPermission.EVERYONE, + debug_permission=TenantPluginPermission.DebugPermission.EVERYONE, + ) + db_session_with_containers.add(existing) + db_session_with_containers.commit() + + result = PluginPermissionService.change_permission( + tenant_id, + TenantPluginPermission.InstallPermission.ADMINS, + TenantPluginPermission.DebugPermission.ADMINS, + ) + + permission = _get_permission(db_session_with_containers, tenant_id) + assert result is True + assert permission is not None + assert permission.id == existing.id + assert permission.install_permission == TenantPluginPermission.InstallPermission.ADMINS + assert permission.debug_permission == TenantPluginPermission.DebugPermission.ADMINS + assert _count_permissions(db_session_with_containers, tenant_id) == 1 diff --git a/api/tests/test_containers_integration_tests/services/recommend_app/test_database_retrieval.py b/api/tests/test_containers_integration_tests/services/recommend_app/test_database_retrieval.py index 2b842629a7..724dd19f92 100644 --- a/api/tests/test_containers_integration_tests/services/recommend_app/test_database_retrieval.py +++ b/api/tests/test_containers_integration_tests/services/recommend_app/test_database_retrieval.py @@ -3,6 +3,8 @@ from __future__ import annotations from unittest.mock import patch from uuid import uuid4 +from sqlalchemy.orm import Session + from models.model import App, RecommendedApp, Site from services.recommend_app.database.database_retrieval import DatabaseRecommendAppRetrieval from services.recommend_app.recommend_app_type import RecommendAppType @@ -91,7 +93,7 @@ class TestDatabaseRecommendAppRetrieval: class TestFetchRecommendedAppsFromDb: - def test_returns_apps_and_sorted_categories(self, flask_app_with_containers, db_session_with_containers): + def test_returns_apps_and_sorted_categories(self, flask_app_with_containers, db_session_with_containers: Session): tenant_id = str(uuid4()) app1 = _create_app(db_session_with_containers, tenant_id=tenant_id) _create_site(db_session_with_containers, app_id=app1.id) @@ -111,7 +113,9 @@ class TestFetchRecommendedAppsFromDb: assert "assistant" in result["categories"] assert "writing" in result["categories"] - def test_falls_back_to_default_language_when_empty(self, flask_app_with_containers, db_session_with_containers): + def test_falls_back_to_default_language_when_empty( + self, flask_app_with_containers, db_session_with_containers: Session + ): tenant_id = str(uuid4()) app1 = _create_app(db_session_with_containers, tenant_id=tenant_id) _create_site(db_session_with_containers, app_id=app1.id) @@ -124,7 +128,7 @@ class TestFetchRecommendedAppsFromDb: app_ids = {r["app_id"] for r in result["recommended_apps"]} assert app1.id in app_ids - def test_skips_non_public_apps(self, flask_app_with_containers, db_session_with_containers): + def test_skips_non_public_apps(self, flask_app_with_containers, db_session_with_containers: Session): tenant_id = str(uuid4()) app1 = _create_app(db_session_with_containers, tenant_id=tenant_id, is_public=False) _create_site(db_session_with_containers, app_id=app1.id) @@ -137,7 +141,7 @@ class TestFetchRecommendedAppsFromDb: app_ids = {r["app_id"] for r in result["recommended_apps"]} assert app1.id not in app_ids - def test_skips_apps_without_site(self, flask_app_with_containers, db_session_with_containers): + def test_skips_apps_without_site(self, flask_app_with_containers, db_session_with_containers: Session): tenant_id = str(uuid4()) app1 = _create_app(db_session_with_containers, tenant_id=tenant_id) _create_recommended_app(db_session_with_containers, app_id=app1.id) @@ -151,12 +155,12 @@ class TestFetchRecommendedAppsFromDb: class TestFetchRecommendedAppDetailFromDb: - def test_returns_none_when_not_listed(self, flask_app_with_containers, db_session_with_containers): + def test_returns_none_when_not_listed(self, flask_app_with_containers, db_session_with_containers: Session): result = DatabaseRecommendAppRetrieval.fetch_recommended_app_detail_from_db(str(uuid4())) assert result is None - def test_returns_none_when_app_not_public(self, flask_app_with_containers, db_session_with_containers): + def test_returns_none_when_app_not_public(self, flask_app_with_containers, db_session_with_containers: Session): tenant_id = str(uuid4()) app1 = _create_app(db_session_with_containers, tenant_id=tenant_id, is_public=False) _create_recommended_app(db_session_with_containers, app_id=app1.id) @@ -168,7 +172,7 @@ class TestFetchRecommendedAppDetailFromDb: assert result is None @patch("services.recommend_app.database.database_retrieval.AppDslService") - def test_returns_detail_on_success(self, mock_dsl, flask_app_with_containers, db_session_with_containers): + def test_returns_detail_on_success(self, mock_dsl, flask_app_with_containers, db_session_with_containers: Session): tenant_id = str(uuid4()) app1 = _create_app(db_session_with_containers, tenant_id=tenant_id) _create_site(db_session_with_containers, app_id=app1.id) diff --git a/api/tests/test_containers_integration_tests/services/test_advanced_prompt_template_service.py b/api/tests/test_containers_integration_tests/services/test_advanced_prompt_template_service.py index 3ec265d009..f78037e503 100644 --- a/api/tests/test_containers_integration_tests/services/test_advanced_prompt_template_service.py +++ b/api/tests/test_containers_integration_tests/services/test_advanced_prompt_template_service.py @@ -2,6 +2,7 @@ import copy import pytest from faker import Faker +from sqlalchemy.orm import Session from core.prompt.prompt_templates.advanced_prompt_templates import ( BAICHUAN_CHAT_APP_CHAT_PROMPT_CONFIG, @@ -29,7 +30,9 @@ class TestAdvancedPromptTemplateService: # for consistency with other test files return {} - def test_get_prompt_baichuan_model_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_prompt_baichuan_model_success( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test successful prompt generation for Baichuan model. @@ -64,7 +67,9 @@ class TestAdvancedPromptTemplateService: assert "{{#histories#}}" in prompt_text assert "{{#query#}}" in prompt_text - def test_get_prompt_common_model_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_prompt_common_model_success( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test successful prompt generation for common models. @@ -100,7 +105,7 @@ class TestAdvancedPromptTemplateService: assert "{{#query#}}" in prompt_text def test_get_prompt_case_insensitive_baichuan_detection( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test Baichuan model detection is case insensitive. @@ -131,7 +136,7 @@ class TestAdvancedPromptTemplateService: assert BAICHUAN_CONTEXT in prompt_text def test_get_common_prompt_chat_app_completion_mode( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test common prompt generation for chat app with completion mode. @@ -161,7 +166,9 @@ class TestAdvancedPromptTemplateService: assert "{{#histories#}}" in prompt_text assert "{{#query#}}" in prompt_text - def test_get_common_prompt_chat_app_chat_mode(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_common_prompt_chat_app_chat_mode( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test common prompt generation for chat app with chat mode. @@ -189,7 +196,7 @@ class TestAdvancedPromptTemplateService: assert "{{#pre_prompt#}}" in prompt_text def test_get_common_prompt_completion_app_completion_mode( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test common prompt generation for completion app with completion mode. @@ -217,7 +224,7 @@ class TestAdvancedPromptTemplateService: assert "{{#pre_prompt#}}" in prompt_text def test_get_common_prompt_completion_app_chat_mode( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test common prompt generation for completion app with chat mode. @@ -245,7 +252,9 @@ class TestAdvancedPromptTemplateService: assert CONTEXT in prompt_text assert "{{#pre_prompt#}}" in prompt_text - def test_get_common_prompt_no_context(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_common_prompt_no_context( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test common prompt generation without context. @@ -273,7 +282,7 @@ class TestAdvancedPromptTemplateService: assert "{{#query#}}" in prompt_text def test_get_common_prompt_unsupported_app_mode( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test common prompt generation with unsupported app mode. @@ -291,7 +300,7 @@ class TestAdvancedPromptTemplateService: assert result == {} def test_get_common_prompt_unsupported_model_mode( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test common prompt generation with unsupported model mode. @@ -308,7 +317,9 @@ class TestAdvancedPromptTemplateService: # Assert: Verify empty dict is returned assert result == {} - def test_get_completion_prompt_with_context(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_completion_prompt_with_context( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test completion prompt generation with context. @@ -339,7 +350,7 @@ class TestAdvancedPromptTemplateService: assert result_text == CONTEXT + original_text def test_get_completion_prompt_without_context( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test completion prompt generation without context. @@ -368,7 +379,9 @@ class TestAdvancedPromptTemplateService: assert result_text == original_text assert CONTEXT not in result_text - def test_get_chat_prompt_with_context(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_chat_prompt_with_context( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test chat prompt generation with context. @@ -399,7 +412,9 @@ class TestAdvancedPromptTemplateService: assert original_text in result_text assert result_text == CONTEXT + original_text - def test_get_chat_prompt_without_context(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_chat_prompt_without_context( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test chat prompt generation without context. @@ -429,7 +444,7 @@ class TestAdvancedPromptTemplateService: assert CONTEXT not in result_text def test_get_baichuan_prompt_chat_app_completion_mode( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test Baichuan prompt generation for chat app with completion mode. @@ -460,7 +475,7 @@ class TestAdvancedPromptTemplateService: assert "{{#query#}}" in prompt_text def test_get_baichuan_prompt_chat_app_chat_mode( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test Baichuan prompt generation for chat app with chat mode. @@ -489,7 +504,7 @@ class TestAdvancedPromptTemplateService: assert "{{#pre_prompt#}}" in prompt_text def test_get_baichuan_prompt_completion_app_completion_mode( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test Baichuan prompt generation for completion app with completion mode. @@ -517,7 +532,7 @@ class TestAdvancedPromptTemplateService: assert "{{#pre_prompt#}}" in prompt_text def test_get_baichuan_prompt_completion_app_chat_mode( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test Baichuan prompt generation for completion app with chat mode. @@ -545,7 +560,9 @@ class TestAdvancedPromptTemplateService: assert BAICHUAN_CONTEXT in prompt_text assert "{{#pre_prompt#}}" in prompt_text - def test_get_baichuan_prompt_no_context(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_baichuan_prompt_no_context( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test Baichuan prompt generation without context. @@ -573,7 +590,7 @@ class TestAdvancedPromptTemplateService: assert "{{#query#}}" in prompt_text def test_get_baichuan_prompt_unsupported_app_mode( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test Baichuan prompt generation with unsupported app mode. @@ -591,7 +608,7 @@ class TestAdvancedPromptTemplateService: assert result == {} def test_get_baichuan_prompt_unsupported_model_mode( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test Baichuan prompt generation with unsupported model mode. @@ -609,7 +626,7 @@ class TestAdvancedPromptTemplateService: assert result == {} def test_get_prompt_all_app_modes_common_model( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test prompt generation for all app modes with common model. @@ -641,7 +658,7 @@ class TestAdvancedPromptTemplateService: assert result != {} def test_get_prompt_all_app_modes_baichuan_model( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test prompt generation for all app modes with Baichuan model. @@ -672,7 +689,7 @@ class TestAdvancedPromptTemplateService: assert result is not None assert result != {} - def test_get_prompt_edge_cases(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_prompt_edge_cases(self, db_session_with_containers: Session, mock_external_service_dependencies): """ Test prompt generation with edge cases. @@ -704,7 +721,7 @@ class TestAdvancedPromptTemplateService: # Should either return a valid result or empty dict, but not crash assert result is not None - def test_template_immutability(self, db_session_with_containers, mock_external_service_dependencies): + def test_template_immutability(self, db_session_with_containers: Session, mock_external_service_dependencies): """ Test that original templates are not modified. @@ -738,7 +755,9 @@ class TestAdvancedPromptTemplateService: assert original_completion_completion == COMPLETION_APP_COMPLETION_PROMPT_CONFIG assert original_completion_chat == COMPLETION_APP_CHAT_PROMPT_CONFIG - def test_baichuan_template_immutability(self, db_session_with_containers, mock_external_service_dependencies): + def test_baichuan_template_immutability( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test that original Baichuan templates are not modified. @@ -772,7 +791,9 @@ class TestAdvancedPromptTemplateService: assert original_baichuan_completion_completion == BAICHUAN_COMPLETION_APP_COMPLETION_PROMPT_CONFIG assert original_baichuan_completion_chat == BAICHUAN_COMPLETION_APP_CHAT_PROMPT_CONFIG - def test_context_integration_consistency(self, db_session_with_containers, mock_external_service_dependencies): + def test_context_integration_consistency( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test consistency of context integration across different scenarios. @@ -828,7 +849,7 @@ class TestAdvancedPromptTemplateService: assert prompt_text.startswith(CONTEXT) def test_baichuan_context_integration_consistency( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test consistency of Baichuan context integration across different scenarios. diff --git a/api/tests/test_containers_integration_tests/services/test_app_dsl_service.py b/api/tests/test_containers_integration_tests/services/test_app_dsl_service.py index 77ce28b999..6b844615b5 100644 --- a/api/tests/test_containers_integration_tests/services/test_app_dsl_service.py +++ b/api/tests/test_containers_integration_tests/services/test_app_dsl_service.py @@ -3,12 +3,15 @@ from __future__ import annotations import base64 import json from types import SimpleNamespace +from typing import Any, cast from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest import yaml from faker import Faker +from flask import Flask +from sqlalchemy.orm import Session from core.trigger.constants import ( TRIGGER_PLUGIN_NODE_TYPE, @@ -17,7 +20,7 @@ from core.trigger.constants import ( ) from extensions.ext_redis import redis_client from graphon.enums import BuiltinNodeTypes -from models import Account, AppMode +from models import Account, App, AppMode from models.model import AppModelConfig, IconType from services import app_dsl_service from services.account_service import AccountService, TenantService @@ -67,11 +70,27 @@ def _pending_yaml_content(version: str = "99.0.0") -> bytes: return (f'version: "{version}"\nkind: app\napp:\n name: Loop Test\n mode: workflow\n').encode() +def _app_stub(**overrides: Any) -> App: + defaults = { + "id": str(uuid4()), + "tenant_id": _DEFAULT_TENANT_ID, + "mode": AppMode.WORKFLOW.value, + "name": "n", + "description": "d", + "icon_type": IconType.EMOJI, + "icon": "i", + "icon_background": "#fff", + "use_icon_as_answer_icon": False, + "app_model_config": None, + } + return cast(App, SimpleNamespace(**(defaults | overrides))) + + class TestAppDslService: """Integration tests for AppDslService using testcontainers.""" @pytest.fixture - def app(self, flask_app_with_containers): + def app(self, flask_app_with_containers: Flask): return flask_app_with_containers @pytest.fixture @@ -112,7 +131,7 @@ class TestAppDslService: "enterprise_service": mock_enterprise_service, } - def _create_test_app_and_account(self, db_session_with_containers, mock_external_service_dependencies): + def _create_test_app_and_account(self, db_session_with_containers: Session, mock_external_service_dependencies): fake = Faker() with patch("services.account_service.FeatureService") as mock_account_feature_service: mock_account_feature_service.get_system_features.return_value.is_allow_register = True @@ -189,7 +208,7 @@ class TestAppDslService: # ── Import: Validation ──────────────────────────────────────────── - def test_import_app_invalid_import_mode_raises_value_error(self, db_session_with_containers): + def test_import_app_invalid_import_mode_raises_value_error(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) with pytest.raises(ValueError, match="Invalid import_mode"): service.import_app( @@ -198,7 +217,7 @@ class TestAppDslService: yaml_content="version: '0.1.0'", ) - def test_import_app_missing_yaml_content(self, db_session_with_containers): + def test_import_app_missing_yaml_content(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) result = service.import_app( account=_account_mock(), @@ -208,7 +227,7 @@ class TestAppDslService: assert result.status == ImportStatus.FAILED assert "yaml_content is required" in result.error - def test_import_app_missing_yaml_url(self, db_session_with_containers): + def test_import_app_missing_yaml_url(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) result = service.import_app( account=_account_mock(), @@ -218,7 +237,7 @@ class TestAppDslService: assert result.status == ImportStatus.FAILED assert "yaml_url is required" in result.error - def test_import_app_yaml_not_mapping_returns_failed(self, db_session_with_containers): + def test_import_app_yaml_not_mapping_returns_failed(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) result = service.import_app( account=_account_mock(), @@ -228,7 +247,7 @@ class TestAppDslService: assert result.status == ImportStatus.FAILED assert "content must be a mapping" in result.error - def test_import_app_version_not_str_returns_failed(self, db_session_with_containers): + def test_import_app_version_not_str_returns_failed(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) yaml_content = _yaml_dump({"version": 1, "kind": "app", "app": {"name": "x", "mode": "workflow"}}) result = service.import_app( @@ -239,7 +258,7 @@ class TestAppDslService: assert result.status == ImportStatus.FAILED assert "Invalid version type" in result.error - def test_import_app_missing_app_data_returns_failed(self, db_session_with_containers): + def test_import_app_missing_app_data_returns_failed(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) result = service.import_app( account=_account_mock(), @@ -249,7 +268,7 @@ class TestAppDslService: assert result.status == ImportStatus.FAILED assert "Missing app data" in result.error - def test_import_app_yaml_error_returns_failed(self, db_session_with_containers, monkeypatch): + def test_import_app_yaml_error_returns_failed(self, db_session_with_containers: Session, monkeypatch): def bad_safe_load(_content: str): raise yaml.YAMLError("bad") @@ -264,7 +283,7 @@ class TestAppDslService: assert result.status == ImportStatus.FAILED assert result.error.startswith("Invalid YAML format:") - def test_import_app_unexpected_error_returns_failed(self, db_session_with_containers, monkeypatch): + def test_import_app_unexpected_error_returns_failed(self, db_session_with_containers: Session, monkeypatch): monkeypatch.setattr( AppDslService, "_create_or_update_app", @@ -282,7 +301,7 @@ class TestAppDslService: # ── Import: YAML URL ────────────────────────────────────────────── - def test_import_app_yaml_url_fetch_error_returns_failed(self, db_session_with_containers, monkeypatch): + def test_import_app_yaml_url_fetch_error_returns_failed(self, db_session_with_containers: Session, monkeypatch): monkeypatch.setattr( app_dsl_service.ssrf_proxy, "get", @@ -298,7 +317,7 @@ class TestAppDslService: assert result.status == ImportStatus.FAILED assert "Error fetching YAML from URL: boom" in result.error - def test_import_app_yaml_url_empty_content_returns_failed(self, db_session_with_containers, monkeypatch): + def test_import_app_yaml_url_empty_content_returns_failed(self, db_session_with_containers: Session, monkeypatch): response = MagicMock() response.content = b"" response.raise_for_status.return_value = None @@ -313,7 +332,7 @@ class TestAppDslService: assert result.status == ImportStatus.FAILED assert "Empty content" in result.error - def test_import_app_yaml_url_file_too_large_returns_failed(self, db_session_with_containers, monkeypatch): + def test_import_app_yaml_url_file_too_large_returns_failed(self, db_session_with_containers: Session, monkeypatch): response = MagicMock() response.content = b"x" * (DSL_MAX_SIZE + 1) response.raise_for_status.return_value = None @@ -328,7 +347,9 @@ class TestAppDslService: assert result.status == ImportStatus.FAILED assert "File size exceeds" in result.error - def test_import_app_yaml_url_user_attachments_keeps_original_url(self, db_session_with_containers, monkeypatch): + def test_import_app_yaml_url_user_attachments_keeps_original_url( + self, db_session_with_containers: Session, monkeypatch + ): yaml_url = "https://github.com/user-attachments/files/24290802/loop-test.yml" yaml_bytes = _pending_yaml_content() @@ -354,7 +375,7 @@ class TestAppDslService: assert result.imported_dsl_version == "99.0.0" assert requested_urls == [yaml_url] - def test_import_app_yaml_url_github_blob_rewrites_to_raw(self, db_session_with_containers, monkeypatch): + def test_import_app_yaml_url_github_blob_rewrites_to_raw(self, db_session_with_containers: Session, monkeypatch): yaml_url = "https://github.com/acme/repo/blob/main/app.yml" raw_url = "https://raw.githubusercontent.com/acme/repo/main/app.yml" yaml_bytes = _pending_yaml_content() @@ -383,7 +404,7 @@ class TestAppDslService: # ── Import: App ID checks ──────────────────────────────────────── - def test_import_app_app_id_not_found_returns_failed(self, db_session_with_containers): + def test_import_app_app_id_not_found_returns_failed(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) result = service.import_app( account=_account_mock(), @@ -395,7 +416,7 @@ class TestAppDslService: assert result.error == "App not found" def test_import_app_overwrite_only_allows_workflow_and_advanced_chat( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): app, account = self._create_test_app_and_account(db_session_with_containers, mock_external_service_dependencies) assert app.mode == "chat" @@ -412,7 +433,7 @@ class TestAppDslService: # ── Import: Flow ────────────────────────────────────────────────── - def test_import_app_pending_stores_import_info_in_redis(self, db_session_with_containers): + def test_import_app_pending_stores_import_info_in_redis(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) result = service.import_app( account=_account_mock(), @@ -432,7 +453,7 @@ class TestAppDslService: assert stored is not None def test_import_app_completed_uses_declared_dependencies( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): _, account = self._create_test_app_and_account(db_session_with_containers, mock_external_service_dependencies) @@ -466,7 +487,7 @@ class TestAppDslService: @pytest.mark.parametrize("has_workflow", [True, False]) def test_import_app_legacy_versions_extract_dependencies( - self, db_session_with_containers, monkeypatch, has_workflow: bool + self, db_session_with_containers: Session, monkeypatch, has_workflow: bool ): monkeypatch.setattr( AppDslService, @@ -523,13 +544,13 @@ class TestAppDslService: # ── Confirm Import ──────────────────────────────────────────────── - def test_confirm_import_expired_returns_failed(self, db_session_with_containers): + def test_confirm_import_expired_returns_failed(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) result = service.confirm_import(import_id=str(uuid4()), account=_account_mock()) assert result.status == ImportStatus.FAILED assert "expired" in result.error - def test_confirm_import_success_deletes_redis_key(self, db_session_with_containers, monkeypatch): + def test_confirm_import_success_deletes_redis_key(self, db_session_with_containers: Session, monkeypatch): import_id = str(uuid4()) redis_key = f"{IMPORT_INFO_REDIS_KEY_PREFIX}{import_id}" @@ -562,7 +583,7 @@ class TestAppDslService: assert result.app_id == created_app.id assert redis_client.get(redis_key) is None - def test_confirm_import_invalid_pending_data_type_returns_failed(self, db_session_with_containers): + def test_confirm_import_invalid_pending_data_type_returns_failed(self, db_session_with_containers: Session): import_id = str(uuid4()) redis_key = f"{IMPORT_INFO_REDIS_KEY_PREFIX}{import_id}" redis_client.setex(redis_key, IMPORT_INFO_REDIS_EXPIRY, "123") @@ -572,7 +593,7 @@ class TestAppDslService: assert result.status == ImportStatus.FAILED assert "validation error" in result.error - def test_confirm_import_exception_returns_failed(self, db_session_with_containers): + def test_confirm_import_exception_returns_failed(self, db_session_with_containers: Session): import_id = str(uuid4()) redis_key = f"{IMPORT_INFO_REDIS_KEY_PREFIX}{import_id}" redis_client.setex(redis_key, IMPORT_INFO_REDIS_EXPIRY, "not-valid-json") @@ -583,13 +604,13 @@ class TestAppDslService: # ── Check Dependencies ──────────────────────────────────────────── - def test_check_dependencies_returns_empty_when_no_redis_data(self, db_session_with_containers): + def test_check_dependencies_returns_empty_when_no_redis_data(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) - app_model = SimpleNamespace(id=str(uuid4()), tenant_id=_DEFAULT_TENANT_ID) + app_model = _app_stub() result = service.check_dependencies(app_model=app_model) assert result.leaked_dependencies == [] - def test_check_dependencies_calls_analysis_service(self, db_session_with_containers, monkeypatch): + def test_check_dependencies_calls_analysis_service(self, db_session_with_containers: Session, monkeypatch): app_id = str(uuid4()) pending = CheckDependenciesPendingData(dependencies=[], app_id=app_id) redis_client.setex( @@ -614,10 +635,12 @@ class TestAppDslService: ) service = AppDslService(db_session_with_containers) - result = service.check_dependencies(app_model=SimpleNamespace(id=app_id, tenant_id=_DEFAULT_TENANT_ID)) + result = service.check_dependencies(app_model=_app_stub(id=app_id)) assert len(result.leaked_dependencies) == 1 - def test_check_dependencies_with_real_app(self, db_session_with_containers, mock_external_service_dependencies): + def test_check_dependencies_with_real_app( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): app, account = self._create_test_app_and_account(db_session_with_containers, mock_external_service_dependencies) mock_dependencies_json = '{"app_id": "' + app.id + '", "dependencies": []}' @@ -633,12 +656,12 @@ class TestAppDslService: # ── Create/Update App ───────────────────────────────────────────── - def test_create_or_update_app_missing_mode_raises(self, db_session_with_containers): + def test_create_or_update_app_missing_mode_raises(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) with pytest.raises(ValueError, match="loss app mode"): service._create_or_update_app(app=None, data={"app": {}}, account=_account_mock()) - def test_create_or_update_app_existing_app_updates_fields(self, db_session_with_containers, monkeypatch): + def test_create_or_update_app_existing_app_updates_fields(self, db_session_with_containers: Session, monkeypatch): fixed_now = object() monkeypatch.setattr(app_dsl_service, "naive_utc_now", lambda: fixed_now) @@ -656,9 +679,7 @@ class TestAppDslService: lambda _m: SimpleNamespace(kind="conv"), ) - app = SimpleNamespace( - id=str(uuid4()), - tenant_id=_DEFAULT_TENANT_ID, + app = _app_stub( mode=AppMode.WORKFLOW.value, name="old", description="old-desc", @@ -667,7 +688,6 @@ class TestAppDslService: icon_background="#111111", updated_by=None, updated_at=None, - app_model_config=None, ) service = AppDslService(db_session_with_containers) updated = service._create_or_update_app( @@ -693,7 +713,7 @@ class TestAppDslService: assert app.icon_background == "#222222" assert app.updated_at is fixed_now - def test_create_or_update_app_new_app_requires_tenant(self, db_session_with_containers): + def test_create_or_update_app_new_app_requires_tenant(self, db_session_with_containers: Session): account = _account_mock() account.current_tenant_id = None service = AppDslService(db_session_with_containers) @@ -705,7 +725,7 @@ class TestAppDslService: ) def test_create_or_update_app_creates_workflow_app_and_saves_dependencies( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): _, account = self._create_test_app_and_account(db_session_with_containers, mock_external_service_dependencies) @@ -741,42 +761,26 @@ class TestAppDslService: stored = redis_client.get(f"{CHECK_DEPENDENCIES_REDIS_KEY_PREFIX}{app.id}") assert stored is not None - def test_create_or_update_app_workflow_missing_workflow_data_raises(self, db_session_with_containers): + def test_create_or_update_app_workflow_missing_workflow_data_raises(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) with pytest.raises(ValueError, match="Missing workflow data"): service._create_or_update_app( - app=SimpleNamespace( - id=str(uuid4()), - tenant_id=_DEFAULT_TENANT_ID, - mode=AppMode.WORKFLOW.value, - name="n", - description="d", - icon_background="#fff", - app_model_config=None, - ), + app=_app_stub(mode=AppMode.WORKFLOW.value), data={"app": {"mode": AppMode.WORKFLOW.value}}, account=_account_mock(), ) - def test_create_or_update_app_chat_requires_model_config(self, db_session_with_containers): + def test_create_or_update_app_chat_requires_model_config(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) with pytest.raises(ValueError, match="Missing model_config"): service._create_or_update_app( - app=SimpleNamespace( - id=str(uuid4()), - tenant_id=_DEFAULT_TENANT_ID, - mode=AppMode.CHAT.value, - name="n", - description="d", - icon_background="#fff", - app_model_config=None, - ), + app=_app_stub(mode=AppMode.CHAT.value), data={"app": {"mode": AppMode.CHAT.value}}, account=_account_mock(), ) def test_create_or_update_app_chat_creates_model_config_and_sends_event( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): app, account = self._create_test_app_and_account(db_session_with_containers, mock_external_service_dependencies) app.app_model_config_id = None @@ -795,19 +799,11 @@ class TestAppDslService: db_session_with_containers.expire_all() assert app.app_model_config_id is not None - def test_create_or_update_app_invalid_mode_raises(self, db_session_with_containers): + def test_create_or_update_app_invalid_mode_raises(self, db_session_with_containers: Session): service = AppDslService(db_session_with_containers) with pytest.raises(ValueError, match="Invalid app mode"): service._create_or_update_app( - app=SimpleNamespace( - id=str(uuid4()), - tenant_id=_DEFAULT_TENANT_ID, - mode=AppMode.RAG_PIPELINE.value, - name="n", - description="d", - icon_background="#fff", - app_model_config=None, - ), + app=_app_stub(mode=AppMode.RAG_PIPELINE.value), data={"app": {"mode": AppMode.RAG_PIPELINE.value}}, account=_account_mock(), ) @@ -828,29 +824,16 @@ class TestAppDslService: lambda *_args, **_kwargs: model_calls.append(True), ) - workflow_app = SimpleNamespace( + workflow_app = _app_stub( mode=AppMode.WORKFLOW.value, - tenant_id=_DEFAULT_TENANT_ID, - name="n", - icon="i", icon_type="emoji", - icon_background="#fff", - description="d", - use_icon_as_answer_icon=False, - app_model_config=None, ) AppDslService.export_dsl(workflow_app) assert workflow_calls == [True] - chat_app = SimpleNamespace( + chat_app = _app_stub( mode=AppMode.CHAT.value, - tenant_id=_DEFAULT_TENANT_ID, - name="n", - icon="i", icon_type="emoji", - icon_background="#fff", - description="d", - use_icon_as_answer_icon=False, app_model_config=SimpleNamespace(to_dict=lambda: {"agent_mode": {"tools": []}}), ) AppDslService.export_dsl(chat_app) @@ -863,16 +846,14 @@ class TestAppDslService: lambda **_kwargs: None, ) - emoji_app = SimpleNamespace( + emoji_app = _app_stub( mode=AppMode.WORKFLOW.value, - tenant_id=_DEFAULT_TENANT_ID, name="Emoji App", icon="🎨", icon_type=IconType.EMOJI, icon_background="#FF5733", description="App with emoji icon", use_icon_as_answer_icon=True, - app_model_config=None, ) yaml_output = AppDslService.export_dsl(emoji_app) data = yaml.safe_load(yaml_output) @@ -880,16 +861,14 @@ class TestAppDslService: assert data["app"]["icon_type"] == "emoji" assert data["app"]["icon_background"] == "#FF5733" - image_app = SimpleNamespace( + image_app = _app_stub( mode=AppMode.WORKFLOW.value, - tenant_id=_DEFAULT_TENANT_ID, name="Image App", icon="https://example.com/icon.png", icon_type=IconType.IMAGE, icon_background="#FFEAD5", description="App with image icon", use_icon_as_answer_icon=False, - app_model_config=None, ) yaml_output = AppDslService.export_dsl(image_app) data = yaml.safe_load(yaml_output) @@ -897,7 +876,7 @@ class TestAppDslService: assert data["app"]["icon_type"] == "image" assert data["app"]["icon_background"] == "#FFEAD5" - def test_export_dsl_chat_app_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_export_dsl_chat_app_success(self, db_session_with_containers: Session, mock_external_service_dependencies): app, account = self._create_test_app_and_account(db_session_with_containers, mock_external_service_dependencies) model_config = AppModelConfig( @@ -935,7 +914,9 @@ class TestAppDslService: assert "model_config" in exported_data assert "dependencies" in exported_data - def test_export_dsl_workflow_app_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_export_dsl_workflow_app_success( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): app, account = self._create_test_app_and_account(db_session_with_containers, mock_external_service_dependencies) app.mode = "workflow" db_session_with_containers.commit() @@ -968,7 +949,9 @@ class TestAppDslService: assert "workflow" in exported_data assert "dependencies" in exported_data - def test_export_dsl_with_workflow_id_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_export_dsl_with_workflow_id_success( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): app, account = self._create_test_app_and_account(db_session_with_containers, mock_external_service_dependencies) app.mode = "workflow" db_session_with_containers.commit() @@ -1008,7 +991,7 @@ class TestAppDslService: assert "workflow" in exported_data def test_export_dsl_with_invalid_workflow_id_raises_error( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): app, account = self._create_test_app_and_account(db_session_with_containers, mock_external_service_dependencies) app.mode = "workflow" @@ -1106,7 +1089,7 @@ class TestAppDslService: export_data: dict = {} AppDslService._append_workflow_export_data( export_data=export_data, - app_model=SimpleNamespace(tenant_id=_DEFAULT_TENANT_ID), + app_model=_app_stub(), include_secret=False, workflow_id=None, ) @@ -1132,7 +1115,7 @@ class TestAppDslService: with pytest.raises(ValueError, match="Missing draft workflow configuration"): AppDslService._append_workflow_export_data( export_data={}, - app_model=SimpleNamespace(tenant_id=_DEFAULT_TENANT_ID), + app_model=_app_stub(), include_secret=False, workflow_id=None, ) @@ -1160,7 +1143,7 @@ class TestAppDslService: monkeypatch.setattr(app_dsl_service, "jsonable_encoder", lambda x: x) app_model_config = SimpleNamespace(to_dict=lambda: {"agent_mode": {"tools": [{"credential_id": "secret"}]}}) - app_model = SimpleNamespace(tenant_id=_DEFAULT_TENANT_ID, app_model_config=app_model_config) + app_model = _app_stub(app_model_config=app_model_config) export_data: dict = {} AppDslService._append_model_config_export_data(export_data, app_model) @@ -1169,7 +1152,7 @@ class TestAppDslService: def test_append_model_config_export_data_requires_app_config(self): with pytest.raises(ValueError, match="Missing app configuration"): - AppDslService._append_model_config_export_data({}, SimpleNamespace(app_model_config=None)) + AppDslService._append_model_config_export_data({}, _app_stub(app_model_config=None)) # ── Dependency Extraction ───────────────────────────────────────── diff --git a/api/tests/test_containers_integration_tests/services/test_app_generate_service.py b/api/tests/test_containers_integration_tests/services/test_app_generate_service.py index 3229693fd4..e2fe6c8476 100644 --- a/api/tests/test_containers_integration_tests/services/test_app_generate_service.py +++ b/api/tests/test_containers_integration_tests/services/test_app_generate_service.py @@ -7,6 +7,7 @@ from faker import Faker from sqlalchemy.orm import Session from core.app.entities.app_invoke_entities import InvokeFrom +from models import App from models.model import EndUser from models.workflow import Workflow from services.app_generate_service import AppGenerateService @@ -184,7 +185,7 @@ class TestAppGenerateService: return app, account - def _create_test_workflow(self, db_session_with_containers: Session, app): + def _create_test_workflow(self, db_session_with_containers: Session, app: App): """ Helper method to create a test workflow for testing. diff --git a/api/tests/test_containers_integration_tests/services/test_attachment_service.py b/api/tests/test_containers_integration_tests/services/test_attachment_service.py index 768a8baee2..d0c07f0de8 100644 --- a/api/tests/test_containers_integration_tests/services/test_attachment_service.py +++ b/api/tests/test_containers_integration_tests/services/test_attachment_service.py @@ -7,7 +7,7 @@ from uuid import uuid4 import pytest from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm import Session, sessionmaker from werkzeug.exceptions import NotFound import services.attachment_service as attachment_service_module @@ -19,7 +19,7 @@ from services.attachment_service import AttachmentService class TestAttachmentService: - def _create_upload_file(self, db_session_with_containers, *, tenant_id: str | None = None) -> UploadFile: + def _create_upload_file(self, db_session_with_containers: Session, *, tenant_id: str | None = None) -> UploadFile: upload_file = UploadFile( tenant_id=tenant_id or str(uuid4()), storage_type=StorageType.OPENDAL, @@ -60,7 +60,7 @@ class TestAttachmentService: with pytest.raises(AssertionError, match="must be a sessionmaker or an Engine."): AttachmentService(session_factory=invalid_session_factory) - def test_should_return_base64_when_file_exists(self, db_session_with_containers): + def test_should_return_base64_when_file_exists(self, db_session_with_containers: Session): upload_file = self._create_upload_file(db_session_with_containers) service = AttachmentService(session_factory=sessionmaker(bind=db.engine)) @@ -70,7 +70,7 @@ class TestAttachmentService: assert result == base64.b64encode(b"binary-content").decode() mock_load.assert_called_once_with(upload_file.key) - def test_should_raise_not_found_when_file_missing(self, db_session_with_containers): + def test_should_raise_not_found_when_file_missing(self, db_session_with_containers: Session): service = AttachmentService(session_factory=sessionmaker(bind=db.engine)) with patch.object(attachment_service_module.storage, "load_once") as mock_load: diff --git a/api/tests/test_containers_integration_tests/services/test_billing_service.py b/api/tests/test_containers_integration_tests/services/test_billing_service.py index 8092c7ad75..4893126d7f 100644 --- a/api/tests/test_containers_integration_tests/services/test_billing_service.py +++ b/api/tests/test_containers_integration_tests/services/test_billing_service.py @@ -4,6 +4,7 @@ from unittest.mock import patch from uuid import uuid4 import pytest +from flask import Flask from sqlalchemy.orm import Session from extensions.ext_redis import redis_client @@ -24,7 +25,7 @@ class TestBillingServiceGetPlanBulkWithCache: """ @pytest.fixture(autouse=True) - def setup_redis_cleanup(self, flask_app_with_containers): + def setup_redis_cleanup(self, flask_app_with_containers: Flask): """Clean up Redis cache before and after each test.""" with flask_app_with_containers.app_context(): # Clean up before test @@ -56,7 +57,7 @@ class TestBillingServiceGetPlanBulkWithCache: return value return None - def test_get_plan_bulk_with_cache_all_cache_hit(self, flask_app_with_containers): + def test_get_plan_bulk_with_cache_all_cache_hit(self, flask_app_with_containers: Flask): """Test bulk plan retrieval when all tenants are in cache.""" with flask_app_with_containers.app_context(): # Arrange @@ -87,7 +88,7 @@ class TestBillingServiceGetPlanBulkWithCache: # Verify API was not called mock_get_plan_bulk.assert_not_called() - def test_get_plan_bulk_with_cache_all_cache_miss(self, flask_app_with_containers): + def test_get_plan_bulk_with_cache_all_cache_miss(self, flask_app_with_containers: Flask): """Test bulk plan retrieval when all tenants are not in cache.""" with flask_app_with_containers.app_context(): # Arrange @@ -127,7 +128,7 @@ class TestBillingServiceGetPlanBulkWithCache: assert ttl_1 > 0 assert ttl_1 <= 600 # Should be <= 600 seconds - def test_get_plan_bulk_with_cache_partial_cache_hit(self, flask_app_with_containers): + def test_get_plan_bulk_with_cache_partial_cache_hit(self, flask_app_with_containers: Flask): """Test bulk plan retrieval when some tenants are in cache, some are not.""" with flask_app_with_containers.app_context(): # Arrange @@ -158,7 +159,7 @@ class TestBillingServiceGetPlanBulkWithCache: cached_data_3 = json.loads(cached_3) assert cached_data_3 == missing_plan["tenant-3"] - def test_get_plan_bulk_with_cache_redis_mget_failure(self, flask_app_with_containers): + def test_get_plan_bulk_with_cache_redis_mget_failure(self, flask_app_with_containers: Flask): """Test fallback to API when Redis mget fails.""" with flask_app_with_containers.app_context(): # Arrange @@ -189,7 +190,7 @@ class TestBillingServiceGetPlanBulkWithCache: assert cached_1 is not None assert cached_2 is not None - def test_get_plan_bulk_with_cache_invalid_json_in_cache(self, flask_app_with_containers): + def test_get_plan_bulk_with_cache_invalid_json_in_cache(self, flask_app_with_containers: Flask): """Test fallback to API when cache contains invalid JSON.""" with flask_app_with_containers.app_context(): # Arrange @@ -241,7 +242,7 @@ class TestBillingServiceGetPlanBulkWithCache: cached_data_3 = json.loads(cached_3) assert cached_data_3 == expected_plans["tenant-3"] - def test_get_plan_bulk_with_cache_invalid_plan_data_in_cache(self, flask_app_with_containers): + def test_get_plan_bulk_with_cache_invalid_plan_data_in_cache(self, flask_app_with_containers: Flask): """Test fallback to API when cache data doesn't match SubscriptionPlan schema.""" with flask_app_with_containers.app_context(): # Arrange @@ -274,7 +275,7 @@ class TestBillingServiceGetPlanBulkWithCache: # Verify API was called for tenant-2 and tenant-3 mock_get_plan_bulk.assert_called_once_with(["tenant-2", "tenant-3"]) - def test_get_plan_bulk_with_cache_redis_pipeline_failure(self, flask_app_with_containers): + def test_get_plan_bulk_with_cache_redis_pipeline_failure(self, flask_app_with_containers: Flask): """Test that pipeline failure doesn't affect return value.""" with flask_app_with_containers.app_context(): # Arrange @@ -303,7 +304,7 @@ class TestBillingServiceGetPlanBulkWithCache: # Verify pipeline was attempted mock_pipeline.assert_called_once() - def test_get_plan_bulk_with_cache_empty_tenant_ids(self, flask_app_with_containers): + def test_get_plan_bulk_with_cache_empty_tenant_ids(self, flask_app_with_containers: Flask): """Test with empty tenant_ids list.""" with flask_app_with_containers.app_context(): # Act @@ -321,7 +322,7 @@ class TestBillingServiceGetPlanBulkWithCache: # But we should check that mget was not called at all # Since we can't easily verify this without more mocking, we just verify the result - def test_get_plan_bulk_with_cache_ttl_expired(self, flask_app_with_containers): + def test_get_plan_bulk_with_cache_ttl_expired(self, flask_app_with_containers: Flask): """Test that expired cache keys are treated as cache misses.""" with flask_app_with_containers.app_context(): # Arrange diff --git a/api/tests/test_containers_integration_tests/services/test_conversation_service.py b/api/tests/test_containers_integration_tests/services/test_conversation_service.py index 98c38f2b5f..8aa10129c1 100644 --- a/api/tests/test_containers_integration_tests/services/test_conversation_service.py +++ b/api/tests/test_containers_integration_tests/services/test_conversation_service.py @@ -7,6 +7,7 @@ from uuid import uuid4 import pytest from sqlalchemy import select +from sqlalchemy.orm import Session from core.app.entities.app_invoke_entities import InvokeFrom from models.account import Account, Tenant, TenantAccountJoin @@ -170,7 +171,7 @@ class ConversationServiceIntegrationTestDataFactory: class TestConversationServicePagination: """Test conversation pagination operations.""" - def test_pagination_with_non_empty_include_ids(self, db_session_with_containers): + def test_pagination_with_non_empty_include_ids(self, db_session_with_containers: Session): """ Test that non-empty include_ids filters properly. @@ -204,7 +205,7 @@ class TestConversationServicePagination: returned_ids = {conversation.id for conversation in result.data} assert returned_ids == {conversations[0].id, conversations[1].id} - def test_pagination_with_empty_exclude_ids(self, db_session_with_containers): + def test_pagination_with_empty_exclude_ids(self, db_session_with_containers: Session): """ Test that empty exclude_ids doesn't filter. @@ -237,7 +238,7 @@ class TestConversationServicePagination: # Assert assert len(result.data) == len(conversations) - def test_pagination_with_non_empty_exclude_ids(self, db_session_with_containers): + def test_pagination_with_non_empty_exclude_ids(self, db_session_with_containers: Session): """ Test that non-empty exclude_ids filters properly. @@ -271,7 +272,7 @@ class TestConversationServicePagination: returned_ids = {conversation.id for conversation in result.data} assert returned_ids == {conversations[2].id} - def test_pagination_with_sorting_descending(self, db_session_with_containers): + def test_pagination_with_sorting_descending(self, db_session_with_containers: Session): """ Test pagination with descending sort order. @@ -316,7 +317,7 @@ class TestConversationServiceMessageCreation: within conversations. """ - def test_pagination_by_first_id_without_first_id(self, db_session_with_containers): + def test_pagination_by_first_id_without_first_id(self, db_session_with_containers: Session): """ Test message pagination without specifying first_id. @@ -354,7 +355,7 @@ class TestConversationServiceMessageCreation: assert len(result.data) == 3 # All 3 messages returned assert result.has_more is False # No more messages available (3 < limit of 10) - def test_pagination_by_first_id_with_first_id(self, db_session_with_containers): + def test_pagination_by_first_id_with_first_id(self, db_session_with_containers: Session): """ Test message pagination with first_id specified. @@ -399,7 +400,9 @@ class TestConversationServiceMessageCreation: assert len(result.data) == 2 # Only 2 messages returned after first_id assert result.has_more is False # No more messages available (2 < limit of 10) - def test_pagination_by_first_id_raises_error_when_first_message_not_found(self, db_session_with_containers): + def test_pagination_by_first_id_raises_error_when_first_message_not_found( + self, db_session_with_containers: Session + ): """ Test that FirstMessageNotExistsError is raised when first_id doesn't exist. @@ -424,7 +427,7 @@ class TestConversationServiceMessageCreation: limit=10, ) - def test_pagination_with_has_more_flag(self, db_session_with_containers): + def test_pagination_with_has_more_flag(self, db_session_with_containers: Session): """ Test that has_more flag is correctly set when there are more messages. @@ -463,7 +466,7 @@ class TestConversationServiceMessageCreation: assert len(result.data) == limit # Extra message should be removed assert result.has_more is True # Flag should be set - def test_pagination_with_ascending_order(self, db_session_with_containers): + def test_pagination_with_ascending_order(self, db_session_with_containers: Session): """ Test message pagination with ascending order. @@ -512,7 +515,7 @@ class TestConversationServiceSummarization: """ @patch("services.conversation_service.LLMGenerator.generate_conversation_name") - def test_auto_generate_name_success(self, mock_llm_generator, db_session_with_containers): + def test_auto_generate_name_success(self, mock_llm_generator, db_session_with_containers: Session): """ Test successful auto-generation of conversation name. @@ -552,7 +555,7 @@ class TestConversationServiceSummarization: app_model.tenant_id, first_message.query, conversation.id, app_model.id ) - def test_auto_generate_name_raises_error_when_no_message(self, db_session_with_containers): + def test_auto_generate_name_raises_error_when_no_message(self, db_session_with_containers: Session): """ Test that MessageNotExistsError is raised when conversation has no messages. @@ -571,7 +574,9 @@ class TestConversationServiceSummarization: ConversationService.auto_generate_name(app_model, conversation) @patch("services.conversation_service.LLMGenerator.generate_conversation_name") - def test_auto_generate_name_handles_llm_failure_gracefully(self, mock_llm_generator, db_session_with_containers): + def test_auto_generate_name_handles_llm_failure_gracefully( + self, mock_llm_generator, db_session_with_containers: Session + ): """ Test that LLM generation failures are suppressed and don't crash. @@ -604,7 +609,7 @@ class TestConversationServiceSummarization: assert conversation.name == original_name # Name remains unchanged @patch("services.conversation_service.naive_utc_now") - def test_rename_with_manual_name(self, mock_naive_utc_now, db_session_with_containers): + def test_rename_with_manual_name(self, mock_naive_utc_now, db_session_with_containers: Session): """ Test renaming conversation with manual name. @@ -638,7 +643,7 @@ class TestConversationServiceSummarization: assert conversation.updated_at == mock_time @patch("services.conversation_service.LLMGenerator.generate_conversation_name") - def test_rename_with_auto_generate(self, mock_llm_generator, db_session_with_containers): + def test_rename_with_auto_generate(self, mock_llm_generator, db_session_with_containers: Session): """ Test rename delegates to auto_generate_name when auto_generate is True. @@ -682,7 +687,9 @@ class TestConversationServiceMessageAnnotation: @patch("services.annotation_service.add_annotation_to_index_task") @patch("services.annotation_service.current_account_with_tenant") - def test_create_annotation_from_message(self, mock_current_account, mock_add_task, db_session_with_containers): + def test_create_annotation_from_message( + self, mock_current_account, mock_add_task, db_session_with_containers: Session + ): """ Test creating annotation from existing message. @@ -721,7 +728,9 @@ class TestConversationServiceMessageAnnotation: @patch("services.annotation_service.add_annotation_to_index_task") @patch("services.annotation_service.current_account_with_tenant") - def test_create_annotation_without_message(self, mock_current_account, mock_add_task, db_session_with_containers): + def test_create_annotation_without_message( + self, mock_current_account, mock_add_task, db_session_with_containers: Session + ): """ Test creating standalone annotation without message. @@ -753,7 +762,7 @@ class TestConversationServiceMessageAnnotation: @patch("services.annotation_service.add_annotation_to_index_task") @patch("services.annotation_service.current_account_with_tenant") - def test_update_existing_annotation(self, mock_current_account, mock_add_task, db_session_with_containers): + def test_update_existing_annotation(self, mock_current_account, mock_add_task, db_session_with_containers: Session): """ Test updating an existing annotation. @@ -800,7 +809,7 @@ class TestConversationServiceMessageAnnotation: mock_add_task.delay.assert_not_called() @patch("services.annotation_service.current_account_with_tenant") - def test_get_annotation_list(self, mock_current_account, db_session_with_containers): + def test_get_annotation_list(self, mock_current_account, db_session_with_containers: Session): """ Test retrieving paginated annotation list. @@ -836,7 +845,7 @@ class TestConversationServiceMessageAnnotation: assert result_total == 5 @patch("services.annotation_service.current_account_with_tenant") - def test_get_annotation_list_with_keyword_search(self, mock_current_account, db_session_with_containers): + def test_get_annotation_list_with_keyword_search(self, mock_current_account, db_session_with_containers: Session): """ Test retrieving annotations with keyword filtering. @@ -885,7 +894,7 @@ class TestConversationServiceMessageAnnotation: @patch("services.annotation_service.add_annotation_to_index_task") @patch("services.annotation_service.current_account_with_tenant") - def test_insert_annotation_directly(self, mock_current_account, mock_add_task, db_session_with_containers): + def test_insert_annotation_directly(self, mock_current_account, mock_add_task, db_session_with_containers: Session): """ Test direct annotation insertion without message reference. @@ -919,7 +928,7 @@ class TestConversationServiceExport: Tests retrieving conversation data for export purposes. """ - def test_get_conversation_success(self, db_session_with_containers): + def test_get_conversation_success(self, db_session_with_containers: Session): """Test successful retrieval of conversation.""" # Arrange app_model, user = ConversationServiceIntegrationTestDataFactory.create_app_and_account( @@ -937,7 +946,7 @@ class TestConversationServiceExport: # Assert assert result == conversation - def test_get_conversation_not_found(self, db_session_with_containers): + def test_get_conversation_not_found(self, db_session_with_containers: Session): """Test ConversationNotExistsError when conversation doesn't exist.""" # Arrange app_model, user = ConversationServiceIntegrationTestDataFactory.create_app_and_account( @@ -949,7 +958,7 @@ class TestConversationServiceExport: ConversationService.get_conversation(app_model=app_model, conversation_id=str(uuid4()), user=user) @patch("services.annotation_service.current_account_with_tenant") - def test_export_annotation_list(self, mock_current_account, db_session_with_containers): + def test_export_annotation_list(self, mock_current_account, db_session_with_containers: Session): """Test exporting all annotations for an app.""" # Arrange app_model, account = ConversationServiceIntegrationTestDataFactory.create_app_and_account( @@ -977,7 +986,7 @@ class TestConversationServiceExport: # Assert assert len(result) == 10 - def test_get_message_success(self, db_session_with_containers): + def test_get_message_success(self, db_session_with_containers: Session): """Test successful retrieval of a message.""" # Arrange app_model, user = ConversationServiceIntegrationTestDataFactory.create_app_and_account( @@ -1001,7 +1010,7 @@ class TestConversationServiceExport: # Assert assert result == message - def test_get_message_not_found(self, db_session_with_containers): + def test_get_message_not_found(self, db_session_with_containers: Session): """Test MessageNotExistsError when message doesn't exist.""" # Arrange app_model, user = ConversationServiceIntegrationTestDataFactory.create_app_and_account( @@ -1012,7 +1021,7 @@ class TestConversationServiceExport: with pytest.raises(MessageNotExistsError): MessageService.get_message(app_model=app_model, user=user, message_id=str(uuid4())) - def test_get_conversation_for_end_user(self, db_session_with_containers): + def test_get_conversation_for_end_user(self, db_session_with_containers: Session): """ Test retrieving conversation created by end user via API. @@ -1038,7 +1047,7 @@ class TestConversationServiceExport: assert result == conversation @patch("services.conversation_service.delete_conversation_related_data") - def test_delete_conversation(self, mock_delete_task, db_session_with_containers): + def test_delete_conversation(self, mock_delete_task, db_session_with_containers: Session): """ Test conversation deletion with async cleanup. @@ -1071,7 +1080,7 @@ class TestConversationServiceExport: mock_delete_task.delay.assert_called_once_with(conversation_id) @patch("services.conversation_service.delete_conversation_related_data") - def test_delete_conversation_not_owned_by_account(self, mock_delete_task, db_session_with_containers): + def test_delete_conversation_not_owned_by_account(self, mock_delete_task, db_session_with_containers: Session): """ Test deletion is denied when conversation belongs to a different account. """ @@ -1102,7 +1111,7 @@ class TestConversationServiceExport: mock_delete_task.delay.assert_not_called() @patch("services.conversation_service.delete_conversation_related_data") - def test_delete_handles_exception_and_rollback(self, mock_delete_task, db_session_with_containers): + def test_delete_handles_exception_and_rollback(self, mock_delete_task, db_session_with_containers: Session): """ Test that delete propagates exceptions and does not trigger the cleanup task. diff --git a/api/tests/test_containers_integration_tests/services/test_conversation_service_variables.py b/api/tests/test_containers_integration_tests/services/test_conversation_service_variables.py index 0b7bd9ca64..6c292dbc4b 100644 --- a/api/tests/test_containers_integration_tests/services/test_conversation_service_variables.py +++ b/api/tests/test_containers_integration_tests/services/test_conversation_service_variables.py @@ -5,7 +5,8 @@ from unittest.mock import patch from uuid import uuid4 import pytest -from sqlalchemy.orm import sessionmaker +from flask import Flask +from sqlalchemy.orm import Session, sessionmaker from core.app.entities.app_invoke_entities import InvokeFrom from extensions.ext_database import db @@ -149,7 +150,7 @@ class ConversationServiceVariableIntegrationFactory: @pytest.fixture -def real_conversation_service_session_factory(flask_app_with_containers): +def real_conversation_service_session_factory(flask_app_with_containers: Flask): del flask_app_with_containers real_session_maker = sessionmaker(bind=db.engine, expire_on_commit=False) @@ -162,7 +163,7 @@ def real_conversation_service_session_factory(flask_app_with_containers): class TestConversationServiceVariables: def test_get_conversational_variable_success( - self, db_session_with_containers, real_conversation_service_session_factory + self, db_session_with_containers: Session, real_conversation_service_session_factory ): del real_conversation_service_session_factory factory = ConversationServiceVariableIntegrationFactory @@ -200,7 +201,7 @@ class TestConversationServiceVariables: assert result.has_more is False def test_get_conversational_variable_with_last_id( - self, db_session_with_containers, real_conversation_service_session_factory + self, db_session_with_containers: Session, real_conversation_service_session_factory ): del real_conversation_service_session_factory factory = ConversationServiceVariableIntegrationFactory @@ -242,7 +243,7 @@ class TestConversationServiceVariables: assert result.has_more is False def test_get_conversational_variable_last_id_not_found_raises_error( - self, db_session_with_containers, real_conversation_service_session_factory + self, db_session_with_containers: Session, real_conversation_service_session_factory ): del real_conversation_service_session_factory factory = ConversationServiceVariableIntegrationFactory @@ -259,7 +260,7 @@ class TestConversationServiceVariables: ) def test_get_conversational_variable_sets_has_more( - self, db_session_with_containers, real_conversation_service_session_factory + self, db_session_with_containers: Session, real_conversation_service_session_factory ): del real_conversation_service_session_factory factory = ConversationServiceVariableIntegrationFactory @@ -287,7 +288,7 @@ class TestConversationServiceVariables: assert result.has_more is True def test_update_conversation_variable_success( - self, db_session_with_containers, real_conversation_service_session_factory + self, db_session_with_containers: Session, real_conversation_service_session_factory ): del real_conversation_service_session_factory factory = ConversationServiceVariableIntegrationFactory @@ -320,7 +321,7 @@ class TestConversationServiceVariables: assert result["updated_at"] == updated_at def test_update_conversation_variable_not_found_raises_error( - self, db_session_with_containers, real_conversation_service_session_factory + self, db_session_with_containers: Session, real_conversation_service_session_factory ): del real_conversation_service_session_factory factory = ConversationServiceVariableIntegrationFactory @@ -337,7 +338,7 @@ class TestConversationServiceVariables: ) def test_update_conversation_variable_type_mismatch_raises_error( - self, db_session_with_containers, real_conversation_service_session_factory + self, db_session_with_containers: Session, real_conversation_service_session_factory ): del real_conversation_service_session_factory factory = ConversationServiceVariableIntegrationFactory @@ -360,7 +361,7 @@ class TestConversationServiceVariables: ) def test_update_conversation_variable_integer_number_compatibility( - self, db_session_with_containers, real_conversation_service_session_factory + self, db_session_with_containers: Session, real_conversation_service_session_factory ): del real_conversation_service_session_factory factory = ConversationServiceVariableIntegrationFactory @@ -390,7 +391,7 @@ class TestConversationServiceVariables: class TestConversationServicePaginationWithContainers: - def test_pagination_by_last_id_raises_error_when_last_id_missing(self, db_session_with_containers): + def test_pagination_by_last_id_raises_error_when_last_id_missing(self, db_session_with_containers: Session): factory = ConversationServiceVariableIntegrationFactory app, account = factory.create_app_and_account(db_session_with_containers) @@ -404,7 +405,7 @@ class TestConversationServicePaginationWithContainers: invoke_from=InvokeFrom.WEB_APP, ) - def test_pagination_by_last_id_with_default_desc_updated_at(self, db_session_with_containers): + def test_pagination_by_last_id_with_default_desc_updated_at(self, db_session_with_containers: Session): factory = ConversationServiceVariableIntegrationFactory app, account = factory.create_app_and_account(db_session_with_containers) base_time = datetime(2024, 1, 1, 8, 0, 0) @@ -442,7 +443,7 @@ class TestConversationServicePaginationWithContainers: assert newest.id != middle.id assert [conversation.id for conversation in result.data] == [oldest.id] - def test_pagination_by_last_id_with_name_sort(self, db_session_with_containers): + def test_pagination_by_last_id_with_name_sort(self, db_session_with_containers: Session): factory = ConversationServiceVariableIntegrationFactory app, account = factory.create_app_and_account(db_session_with_containers) alpha = factory.create_conversation(db_session_with_containers, app, account, name="Alpha") @@ -462,7 +463,7 @@ class TestConversationServicePaginationWithContainers: assert alpha.id != beta.id assert [conversation.id for conversation in result.data] == [gamma.id] - def test_pagination_filters_to_end_user_api_source(self, db_session_with_containers): + def test_pagination_filters_to_end_user_api_source(self, db_session_with_containers: Session): factory = ConversationServiceVariableIntegrationFactory app, account = factory.create_app_and_account(db_session_with_containers) end_user = factory.create_end_user(db_session_with_containers, app) @@ -493,7 +494,7 @@ class TestConversationServicePaginationWithContainers: assert account_conversation.id != end_user_conversation.id assert [conversation.id for conversation in result.data] == [end_user_conversation.id] - def test_pagination_filters_to_account_console_source(self, db_session_with_containers): + def test_pagination_filters_to_account_console_source(self, db_session_with_containers: Session): factory = ConversationServiceVariableIntegrationFactory app, account = factory.create_app_and_account(db_session_with_containers) end_user = factory.create_end_user(db_session_with_containers, app) diff --git a/api/tests/test_containers_integration_tests/services/test_conversation_variable_updater.py b/api/tests/test_containers_integration_tests/services/test_conversation_variable_updater.py index 02ab3f8314..638a962f18 100644 --- a/api/tests/test_containers_integration_tests/services/test_conversation_variable_updater.py +++ b/api/tests/test_containers_integration_tests/services/test_conversation_variable_updater.py @@ -3,7 +3,7 @@ from uuid import uuid4 import pytest -from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm import Session, sessionmaker from extensions.ext_database import db from graphon.variables import StringVariable @@ -13,7 +13,12 @@ from services.conversation_variable_updater import ConversationVariableNotFoundE class TestConversationVariableUpdater: def _create_conversation_variable( - self, db_session_with_containers, *, conversation_id: str, variable: StringVariable, app_id: str | None = None + self, + db_session_with_containers: Session, + *, + conversation_id: str, + variable: StringVariable, + app_id: str | None = None, ) -> ConversationVariable: row = ConversationVariable( id=variable.id, @@ -25,7 +30,7 @@ class TestConversationVariableUpdater: db_session_with_containers.commit() return row - def test_should_update_conversation_variable_data_and_commit(self, db_session_with_containers): + def test_should_update_conversation_variable_data_and_commit(self, db_session_with_containers: Session): conversation_id = str(uuid4()) variable = StringVariable(id=str(uuid4()), name="topic", value="old value") self._create_conversation_variable( @@ -42,7 +47,7 @@ class TestConversationVariableUpdater: assert row is not None assert row.data == updated_variable.model_dump_json() - def test_should_raise_not_found_when_variable_missing(self, db_session_with_containers): + def test_should_raise_not_found_when_variable_missing(self, db_session_with_containers: Session): conversation_id = str(uuid4()) variable = StringVariable(id=str(uuid4()), name="topic", value="value") updater = ConversationVariableUpdater(sessionmaker(bind=db.engine)) @@ -50,7 +55,7 @@ class TestConversationVariableUpdater: with pytest.raises(ConversationVariableNotFoundError, match="conversation variable not found in the database"): updater.update(conversation_id=conversation_id, variable=variable) - def test_should_do_nothing_when_flush_is_called(self, db_session_with_containers): + def test_should_do_nothing_when_flush_is_called(self, db_session_with_containers: Session): updater = ConversationVariableUpdater(sessionmaker(bind=db.engine)) result = updater.flush() diff --git a/api/tests/test_containers_integration_tests/services/test_credit_pool_service.py b/api/tests/test_containers_integration_tests/services/test_credit_pool_service.py index 0f63d98642..09ba041244 100644 --- a/api/tests/test_containers_integration_tests/services/test_credit_pool_service.py +++ b/api/tests/test_containers_integration_tests/services/test_credit_pool_service.py @@ -3,6 +3,7 @@ from uuid import uuid4 import pytest +from sqlalchemy.orm import Session from core.errors.error import QuotaExceededError from models import TenantCreditPool @@ -14,7 +15,7 @@ class TestCreditPoolService: def _create_tenant_id(self) -> str: return str(uuid4()) - def test_create_default_pool(self, db_session_with_containers): + def test_create_default_pool(self, db_session_with_containers: Session): tenant_id = self._create_tenant_id() pool = CreditPoolService.create_default_pool(tenant_id) @@ -25,7 +26,7 @@ class TestCreditPoolService: assert pool.quota_used == 0 assert pool.quota_limit > 0 - def test_get_pool_returns_pool_when_exists(self, db_session_with_containers): + def test_get_pool_returns_pool_when_exists(self, db_session_with_containers: Session): tenant_id = self._create_tenant_id() CreditPoolService.create_default_pool(tenant_id) @@ -35,17 +36,17 @@ class TestCreditPoolService: assert result.tenant_id == tenant_id assert result.pool_type == ProviderQuotaType.TRIAL - def test_get_pool_returns_none_when_not_exists(self, db_session_with_containers): + def test_get_pool_returns_none_when_not_exists(self, db_session_with_containers: Session): result = CreditPoolService.get_pool(tenant_id=self._create_tenant_id(), pool_type=ProviderQuotaType.TRIAL) assert result is None - def test_check_credits_available_returns_false_when_no_pool(self, db_session_with_containers): + def test_check_credits_available_returns_false_when_no_pool(self, db_session_with_containers: Session): result = CreditPoolService.check_credits_available(tenant_id=self._create_tenant_id(), credits_required=10) assert result is False - def test_check_credits_available_returns_true_when_sufficient(self, db_session_with_containers): + def test_check_credits_available_returns_true_when_sufficient(self, db_session_with_containers: Session): tenant_id = self._create_tenant_id() CreditPoolService.create_default_pool(tenant_id) @@ -53,7 +54,7 @@ class TestCreditPoolService: assert result is True - def test_check_credits_available_returns_false_when_insufficient(self, db_session_with_containers): + def test_check_credits_available_returns_false_when_insufficient(self, db_session_with_containers: Session): tenant_id = self._create_tenant_id() pool = CreditPoolService.create_default_pool(tenant_id) # Exhaust credits @@ -64,11 +65,11 @@ class TestCreditPoolService: assert result is False - def test_check_and_deduct_credits_raises_when_no_pool(self, db_session_with_containers): + def test_check_and_deduct_credits_raises_when_no_pool(self, db_session_with_containers: Session): with pytest.raises(QuotaExceededError, match="Credit pool not found"): CreditPoolService.check_and_deduct_credits(tenant_id=self._create_tenant_id(), credits_required=10) - def test_check_and_deduct_credits_raises_when_no_remaining(self, db_session_with_containers): + def test_check_and_deduct_credits_raises_when_no_remaining(self, db_session_with_containers: Session): tenant_id = self._create_tenant_id() pool = CreditPoolService.create_default_pool(tenant_id) pool.quota_used = pool.quota_limit @@ -77,7 +78,7 @@ class TestCreditPoolService: with pytest.raises(QuotaExceededError, match="No credits remaining"): CreditPoolService.check_and_deduct_credits(tenant_id=tenant_id, credits_required=10) - def test_check_and_deduct_credits_deducts_required_amount(self, db_session_with_containers): + def test_check_and_deduct_credits_deducts_required_amount(self, db_session_with_containers: Session): tenant_id = self._create_tenant_id() CreditPoolService.create_default_pool(tenant_id) credits_required = 10 @@ -89,7 +90,7 @@ class TestCreditPoolService: pool = CreditPoolService.get_pool(tenant_id=tenant_id) assert pool.quota_used == credits_required - def test_check_and_deduct_credits_caps_at_remaining(self, db_session_with_containers): + def test_check_and_deduct_credits_caps_at_remaining(self, db_session_with_containers: Session): tenant_id = self._create_tenant_id() pool = CreditPoolService.create_default_pool(tenant_id) remaining = 5 diff --git a/api/tests/test_containers_integration_tests/services/test_dataset_permission_service.py b/api/tests/test_containers_integration_tests/services/test_dataset_permission_service.py index 71c8874f79..f9898e2cfa 100644 --- a/api/tests/test_containers_integration_tests/services/test_dataset_permission_service.py +++ b/api/tests/test_containers_integration_tests/services/test_dataset_permission_service.py @@ -8,6 +8,7 @@ checks with testcontainers-backed infrastructure instead of database-chain mocks from uuid import uuid4 import pytest +from sqlalchemy.orm import Session from core.rag.index_processor.constant.index_type import IndexTechniqueType from extensions.ext_database import db @@ -107,7 +108,7 @@ class DatasetPermissionTestDataFactory: class TestDatasetPermissionServiceGetPartialMemberList: """Verify partial-member list reads against persisted DatasetPermission rows.""" - def test_get_dataset_partial_member_list_with_members(self, db_session_with_containers): + def test_get_dataset_partial_member_list_with_members(self, db_session_with_containers: Session): """ Test retrieving partial member list with multiple members. """ @@ -138,7 +139,7 @@ class TestDatasetPermissionServiceGetPartialMemberList: assert set(result) == set(expected_account_ids) assert len(result) == 3 - def test_get_dataset_partial_member_list_with_single_member(self, db_session_with_containers): + def test_get_dataset_partial_member_list_with_single_member(self, db_session_with_containers: Session): """ Test retrieving partial member list with single member. """ @@ -160,7 +161,7 @@ class TestDatasetPermissionServiceGetPartialMemberList: assert set(result) == set(expected_account_ids) assert len(result) == 1 - def test_get_dataset_partial_member_list_empty(self, db_session_with_containers): + def test_get_dataset_partial_member_list_empty(self, db_session_with_containers: Session): """ Test retrieving partial member list when no members exist. """ @@ -179,7 +180,7 @@ class TestDatasetPermissionServiceGetPartialMemberList: class TestDatasetPermissionServiceUpdatePartialMemberList: """Verify partial-member list updates against persisted DatasetPermission rows.""" - def test_update_partial_member_list_add_new_members(self, db_session_with_containers): + def test_update_partial_member_list_add_new_members(self, db_session_with_containers: Session): """ Test adding new partial members to a dataset. """ @@ -203,7 +204,7 @@ class TestDatasetPermissionServiceUpdatePartialMemberList: result = DatasetPermissionService.get_dataset_partial_member_list(dataset.id) assert set(result) == {member_1.id, member_2.id} - def test_update_partial_member_list_replace_existing(self, db_session_with_containers): + def test_update_partial_member_list_replace_existing(self, db_session_with_containers: Session): """ Test replacing existing partial members with new ones. """ @@ -239,7 +240,7 @@ class TestDatasetPermissionServiceUpdatePartialMemberList: result = DatasetPermissionService.get_dataset_partial_member_list(dataset.id) assert set(result) == {new_member_1.id, new_member_2.id} - def test_update_partial_member_list_empty_list(self, db_session_with_containers): + def test_update_partial_member_list_empty_list(self, db_session_with_containers: Session): """ Test updating with empty member list (clearing all members). """ @@ -264,7 +265,7 @@ class TestDatasetPermissionServiceUpdatePartialMemberList: result = DatasetPermissionService.get_dataset_partial_member_list(dataset.id) assert result == [] - def test_update_partial_member_list_database_error_rollback(self, db_session_with_containers): + def test_update_partial_member_list_database_error_rollback(self, db_session_with_containers: Session): """ Test error handling and rollback on database error. """ @@ -313,7 +314,7 @@ class TestDatasetPermissionServiceUpdatePartialMemberList: class TestDatasetPermissionServiceClearPartialMemberList: """Verify partial-member clearing against persisted DatasetPermission rows.""" - def test_clear_partial_member_list_success(self, db_session_with_containers): + def test_clear_partial_member_list_success(self, db_session_with_containers: Session): """ Test successful clearing of partial member list. """ @@ -338,7 +339,7 @@ class TestDatasetPermissionServiceClearPartialMemberList: result = DatasetPermissionService.get_dataset_partial_member_list(dataset.id) assert result == [] - def test_clear_partial_member_list_empty_list(self, db_session_with_containers): + def test_clear_partial_member_list_empty_list(self, db_session_with_containers: Session): """ Test clearing partial member list when no members exist. """ @@ -353,7 +354,7 @@ class TestDatasetPermissionServiceClearPartialMemberList: result = DatasetPermissionService.get_dataset_partial_member_list(dataset.id) assert result == [] - def test_clear_partial_member_list_database_error_rollback(self, db_session_with_containers): + def test_clear_partial_member_list_database_error_rollback(self, db_session_with_containers: Session): """ Test error handling and rollback on database error. """ @@ -398,7 +399,7 @@ class TestDatasetPermissionServiceClearPartialMemberList: class TestDatasetServiceCheckDatasetPermission: """Verify dataset access checks against persisted partial-member permissions.""" - def test_check_dataset_permission_different_tenant_should_fail(self, db_session_with_containers): + def test_check_dataset_permission_different_tenant_should_fail(self, db_session_with_containers: Session): """Test that users from different tenants cannot access dataset.""" owner, tenant = DatasetPermissionTestDataFactory.create_account_with_tenant(role=TenantAccountRole.OWNER) other_user, _ = DatasetPermissionTestDataFactory.create_account_with_tenant(role=TenantAccountRole.EDITOR) @@ -410,7 +411,7 @@ class TestDatasetServiceCheckDatasetPermission: with pytest.raises(NoPermissionError): DatasetService.check_dataset_permission(dataset, other_user) - def test_check_dataset_permission_owner_can_access_any_dataset(self, db_session_with_containers): + def test_check_dataset_permission_owner_can_access_any_dataset(self, db_session_with_containers: Session): """Test that tenant owners can access any dataset regardless of permission level.""" owner, tenant = DatasetPermissionTestDataFactory.create_account_with_tenant(role=TenantAccountRole.OWNER) creator, _ = DatasetPermissionTestDataFactory.create_account_with_tenant( @@ -423,7 +424,7 @@ class TestDatasetServiceCheckDatasetPermission: DatasetService.check_dataset_permission(dataset, owner) - def test_check_dataset_permission_only_me_creator_can_access(self, db_session_with_containers): + def test_check_dataset_permission_only_me_creator_can_access(self, db_session_with_containers: Session): """Test ONLY_ME permission allows only the dataset creator to access.""" creator, tenant = DatasetPermissionTestDataFactory.create_account_with_tenant(role=TenantAccountRole.EDITOR) @@ -433,7 +434,7 @@ class TestDatasetServiceCheckDatasetPermission: DatasetService.check_dataset_permission(dataset, creator) - def test_check_dataset_permission_only_me_others_cannot_access(self, db_session_with_containers): + def test_check_dataset_permission_only_me_others_cannot_access(self, db_session_with_containers: Session): """Test ONLY_ME permission denies access to non-creators.""" creator, tenant = DatasetPermissionTestDataFactory.create_account_with_tenant(role=TenantAccountRole.NORMAL) other, _ = DatasetPermissionTestDataFactory.create_account_with_tenant( @@ -447,7 +448,7 @@ class TestDatasetServiceCheckDatasetPermission: with pytest.raises(NoPermissionError): DatasetService.check_dataset_permission(dataset, other) - def test_check_dataset_permission_all_team_allows_access(self, db_session_with_containers): + def test_check_dataset_permission_all_team_allows_access(self, db_session_with_containers: Session): """Test ALL_TEAM permission allows any team member to access the dataset.""" creator, tenant = DatasetPermissionTestDataFactory.create_account_with_tenant(role=TenantAccountRole.NORMAL) member, _ = DatasetPermissionTestDataFactory.create_account_with_tenant( @@ -460,7 +461,9 @@ class TestDatasetServiceCheckDatasetPermission: DatasetService.check_dataset_permission(dataset, member) - def test_check_dataset_permission_partial_members_with_permission_success(self, db_session_with_containers): + def test_check_dataset_permission_partial_members_with_permission_success( + self, db_session_with_containers: Session + ): """ Test that user with explicit permission can access partial_members dataset. """ @@ -485,7 +488,9 @@ class TestDatasetServiceCheckDatasetPermission: permissions = DatasetPermissionService.get_dataset_partial_member_list(dataset.id) assert user.id in permissions - def test_check_dataset_permission_partial_members_without_permission_error(self, db_session_with_containers): + def test_check_dataset_permission_partial_members_without_permission_error( + self, db_session_with_containers: Session + ): """ Test error when user without permission tries to access partial_members dataset. """ @@ -506,7 +511,7 @@ class TestDatasetServiceCheckDatasetPermission: with pytest.raises(NoPermissionError, match="You do not have permission to access this dataset"): DatasetService.check_dataset_permission(dataset, user) - def test_check_dataset_permission_partial_team_creator_can_access(self, db_session_with_containers): + def test_check_dataset_permission_partial_team_creator_can_access(self, db_session_with_containers: Session): """Test PARTIAL_TEAM permission allows creator to access without explicit permission.""" creator, tenant = DatasetPermissionTestDataFactory.create_account_with_tenant(role=TenantAccountRole.EDITOR) diff --git a/api/tests/test_containers_integration_tests/services/test_dataset_service.py b/api/tests/test_containers_integration_tests/services/test_dataset_service.py index 0de3c64c4f..e6ee896a52 100644 --- a/api/tests/test_containers_integration_tests/services/test_dataset_service.py +++ b/api/tests/test_containers_integration_tests/services/test_dataset_service.py @@ -712,7 +712,7 @@ class TestDatasetServiceRetrievalConfiguration: class TestDocumentServicePauseRecoverRetry: """Tests for pause/recover/retry orchestration using real DB and Redis.""" - def _create_indexing_document(self, db_session_with_containers, indexing_status="indexing"): + def _create_indexing_document(self, db_session_with_containers: Session, indexing_status="indexing"): factory = DatasetServiceIntegrationDataFactory account, tenant = factory.create_account_with_tenant(db_session_with_containers) dataset = factory.create_dataset(db_session_with_containers, tenant.id, account.id) @@ -721,7 +721,7 @@ class TestDocumentServicePauseRecoverRetry: db_session_with_containers.commit() return doc, account - def test_pause_document_success(self, db_session_with_containers): + def test_pause_document_success(self, db_session_with_containers: Session): from extensions.ext_redis import redis_client from services.dataset_service import DocumentService @@ -740,7 +740,7 @@ class TestDocumentServicePauseRecoverRetry: assert redis_client.get(cache_key) is not None redis_client.delete(cache_key) - def test_pause_document_invalid_status_error(self, db_session_with_containers): + def test_pause_document_invalid_status_error(self, db_session_with_containers: Session): from services.dataset_service import DocumentService from services.errors.document import DocumentIndexingError @@ -751,7 +751,7 @@ class TestDocumentServicePauseRecoverRetry: with pytest.raises(DocumentIndexingError): DocumentService.pause_document(doc) - def test_recover_document_success(self, db_session_with_containers): + def test_recover_document_success(self, db_session_with_containers: Session): from extensions.ext_redis import redis_client from services.dataset_service import DocumentService @@ -775,7 +775,7 @@ class TestDocumentServicePauseRecoverRetry: assert redis_client.get(cache_key) is None recover_task.delay.assert_called_once_with(doc.dataset_id, doc.id) - def test_retry_document_indexing_success(self, db_session_with_containers): + def test_retry_document_indexing_success(self, db_session_with_containers: Session): from extensions.ext_redis import redis_client from services.dataset_service import DocumentService diff --git a/api/tests/test_containers_integration_tests/services/test_dataset_service_create_dataset.py b/api/tests/test_containers_integration_tests/services/test_dataset_service_create_dataset.py index c486ff5613..08de79f4b7 100644 --- a/api/tests/test_containers_integration_tests/services/test_dataset_service_create_dataset.py +++ b/api/tests/test_containers_integration_tests/services/test_dataset_service_create_dataset.py @@ -6,6 +6,7 @@ from unittest.mock import Mock, patch from uuid import uuid4 import pytest +from sqlalchemy.orm import Session from models.account import Account, Tenant, TenantAccountJoin from services.dataset_service import DatasetService @@ -48,7 +49,7 @@ class TestDatasetServiceCreateRagPipelineDataset: permission="only_me", ) - def test_create_rag_pipeline_dataset_raises_when_current_user_id_is_none(self, db_session_with_containers): + def test_create_rag_pipeline_dataset_raises_when_current_user_id_is_none(self, db_session_with_containers: Session): tenant, _ = self._create_tenant_and_account(db_session_with_containers) mock_user = Mock(id=None) diff --git a/api/tests/test_containers_integration_tests/services/test_dataset_service_delete_dataset.py b/api/tests/test_containers_integration_tests/services/test_dataset_service_delete_dataset.py index 3cac964d89..c43a5d5978 100644 --- a/api/tests/test_containers_integration_tests/services/test_dataset_service_delete_dataset.py +++ b/api/tests/test_containers_integration_tests/services/test_dataset_service_delete_dataset.py @@ -3,6 +3,8 @@ from unittest.mock import patch from uuid import uuid4 +from sqlalchemy.orm import Session + from core.rag.index_processor.constant.index_type import IndexStructureType, IndexTechniqueType from models.account import Account, Tenant, TenantAccountJoin, TenantAccountRole from models.dataset import Dataset, Document @@ -101,7 +103,7 @@ class DatasetDeleteIntegrationDataFactory: class TestDatasetServiceDeleteDataset: """Integration coverage for DatasetService.delete_dataset using testcontainers.""" - def test_delete_dataset_with_documents_success(self, db_session_with_containers): + def test_delete_dataset_with_documents_success(self, db_session_with_containers: Session): """Delete a dataset with documents and dispatch cleanup through the real signal handler.""" # Arrange owner, tenant = DatasetDeleteIntegrationDataFactory.create_account_with_tenant(db_session_with_containers) @@ -144,7 +146,7 @@ class TestDatasetServiceDeleteDataset: dataset.pipeline_id, ) - def test_delete_empty_dataset_success(self, db_session_with_containers): + def test_delete_empty_dataset_success(self, db_session_with_containers: Session): """Delete an empty dataset without scheduling cleanup when both gating fields are absent.""" # Arrange owner, tenant = DatasetDeleteIntegrationDataFactory.create_account_with_tenant(db_session_with_containers) @@ -172,7 +174,7 @@ class TestDatasetServiceDeleteDataset: assert db_session_with_containers.get(Dataset, dataset.id) is None clean_dataset_delay.assert_not_called() - def test_delete_dataset_with_partial_none_values(self, db_session_with_containers): + def test_delete_dataset_with_partial_none_values(self, db_session_with_containers: Session): """Delete a dataset without cleanup when indexing_technique is missing but doc_form resolves.""" # Arrange owner, tenant = DatasetDeleteIntegrationDataFactory.create_account_with_tenant(db_session_with_containers) @@ -200,7 +202,7 @@ class TestDatasetServiceDeleteDataset: assert db_session_with_containers.get(Dataset, dataset.id) is None clean_dataset_delay.assert_not_called() - def test_delete_dataset_with_doc_form_none_indexing_technique_exists(self, db_session_with_containers): + def test_delete_dataset_with_doc_form_none_indexing_technique_exists(self, db_session_with_containers: Session): """Delete a dataset without cleanup when indexing exists but doc_form resolves to None.""" # Arrange owner, tenant = DatasetDeleteIntegrationDataFactory.create_account_with_tenant(db_session_with_containers) @@ -228,7 +230,7 @@ class TestDatasetServiceDeleteDataset: assert db_session_with_containers.get(Dataset, dataset.id) is None clean_dataset_delay.assert_not_called() - def test_delete_dataset_not_found(self, db_session_with_containers): + def test_delete_dataset_not_found(self, db_session_with_containers: Session): """Return False without scheduling cleanup when the target dataset does not exist.""" # Arrange owner, _ = DatasetDeleteIntegrationDataFactory.create_account_with_tenant(db_session_with_containers) diff --git a/api/tests/test_containers_integration_tests/services/test_dataset_service_permissions.py b/api/tests/test_containers_integration_tests/services/test_dataset_service_permissions.py index 1b4179c9c7..0603a1e27f 100644 --- a/api/tests/test_containers_integration_tests/services/test_dataset_service_permissions.py +++ b/api/tests/test_containers_integration_tests/services/test_dataset_service_permissions.py @@ -6,6 +6,7 @@ from unittest.mock import patch from uuid import uuid4 import pytest +from flask import Flask from sqlalchemy.orm import Session from werkzeug.exceptions import NotFound @@ -363,7 +364,7 @@ class TestDatasetServicePermissionsAndLifecycle: DatasetService.check_dataset_operator_permission(user=operator, dataset=dataset) - def test_update_dataset_api_status_raises_not_found_for_missing_dataset(self, flask_app_with_containers): + def test_update_dataset_api_status_raises_not_found_for_missing_dataset(self, flask_app_with_containers: Flask): with flask_app_with_containers.app_context(): with pytest.raises(NotFound, match="Dataset not found"): DatasetService.update_dataset_api_status(str(uuid4()), True) @@ -473,7 +474,7 @@ class TestDatasetCollectionBindingServiceIntegration: assert persisted.type == "dataset" assert persisted.collection_name - def test_get_dataset_collection_binding_by_id_and_type_raises_when_missing(self, flask_app_with_containers): + def test_get_dataset_collection_binding_by_id_and_type_raises_when_missing(self, flask_app_with_containers: Flask): with flask_app_with_containers.app_context(): with pytest.raises(ValueError, match="Dataset collection binding not found"): DatasetCollectionBindingService.get_dataset_collection_binding_by_id_and_type(str(uuid4())) diff --git a/api/tests/test_containers_integration_tests/services/test_delete_archived_workflow_run.py b/api/tests/test_containers_integration_tests/services/test_delete_archived_workflow_run.py index fe426ae516..69c39b8bfb 100644 --- a/api/tests/test_containers_integration_tests/services/test_delete_archived_workflow_run.py +++ b/api/tests/test_containers_integration_tests/services/test_delete_archived_workflow_run.py @@ -6,6 +6,7 @@ from datetime import UTC, datetime, timedelta from uuid import uuid4 from sqlalchemy import select +from sqlalchemy.orm import Session from graphon.enums import WorkflowExecutionStatus from models.enums import CreatorUserRole, WorkflowRunTriggeredFrom @@ -46,7 +47,7 @@ class TestArchivedWorkflowRunDeletion: db_session_with_containers.commit() return run - def _create_archive_log(self, db_session_with_containers, *, run: WorkflowRun) -> None: + def _create_archive_log(self, db_session_with_containers: Session, *, run: WorkflowRun) -> None: archive_log = WorkflowArchiveLog( tenant_id=run.tenant_id, app_id=run.app_id, @@ -72,7 +73,7 @@ class TestArchivedWorkflowRunDeletion: db_session_with_containers.add(archive_log) db_session_with_containers.commit() - def test_delete_by_run_id_returns_error_when_run_missing(self, db_session_with_containers): + def test_delete_by_run_id_returns_error_when_run_missing(self, db_session_with_containers: Session): deleter = ArchivedWorkflowRunDeletion() missing_run_id = str(uuid4()) @@ -81,7 +82,7 @@ class TestArchivedWorkflowRunDeletion: assert result.success is False assert result.error == f"Workflow run {missing_run_id} not found" - def test_delete_by_run_id_returns_error_when_not_archived(self, db_session_with_containers): + def test_delete_by_run_id_returns_error_when_not_archived(self, db_session_with_containers: Session): tenant_id = str(uuid4()) run = self._create_workflow_run( db_session_with_containers, @@ -95,7 +96,7 @@ class TestArchivedWorkflowRunDeletion: assert result.success is False assert result.error == f"Workflow run {run.id} is not archived" - def test_delete_batch_uses_repo(self, db_session_with_containers): + def test_delete_batch_uses_repo(self, db_session_with_containers: Session): tenant_id = str(uuid4()) base_time = datetime.now(UTC) run1 = self._create_workflow_run(db_session_with_containers, tenant_id=tenant_id, created_at=base_time) @@ -124,7 +125,7 @@ class TestArchivedWorkflowRunDeletion: ).all() assert remaining_runs == [] - def test_delete_run_calls_repo(self, db_session_with_containers): + def test_delete_run_calls_repo(self, db_session_with_containers: Session): tenant_id = str(uuid4()) run = self._create_workflow_run( db_session_with_containers, @@ -142,7 +143,7 @@ class TestArchivedWorkflowRunDeletion: deleted_run = db_session_with_containers.get(WorkflowRun, run_id) assert deleted_run is None - def test_delete_run_dry_run(self, db_session_with_containers): + def test_delete_run_dry_run(self, db_session_with_containers: Session): """Dry run should return success without actually deleting.""" tenant_id = str(uuid4()) run = self._create_workflow_run( @@ -161,7 +162,7 @@ class TestArchivedWorkflowRunDeletion: db_session_with_containers.expire_all() assert db_session_with_containers.get(WorkflowRun, run_id) is not None - def test_delete_run_exception_returns_error(self, db_session_with_containers): + def test_delete_run_exception_returns_error(self, db_session_with_containers: Session): """Exception during deletion should return failure result.""" from unittest.mock import MagicMock, patch @@ -183,7 +184,7 @@ class TestArchivedWorkflowRunDeletion: assert result.success is False assert result.error == "Database error" - def test_delete_by_run_id_success(self, db_session_with_containers): + def test_delete_by_run_id_success(self, db_session_with_containers: Session): """Successfully delete an archived workflow run by ID.""" tenant_id = str(uuid4()) base_time = datetime.now(UTC) @@ -202,7 +203,7 @@ class TestArchivedWorkflowRunDeletion: db_session_with_containers.expunge_all() assert db_session_with_containers.get(WorkflowRun, run_id) is None - def test_get_workflow_run_repo_caches_instance(self, db_session_with_containers): + def test_get_workflow_run_repo_caches_instance(self, db_session_with_containers: Session): """_get_workflow_run_repo should return a cached repo on subsequent calls.""" deleter = ArchivedWorkflowRunDeletion() diff --git a/api/tests/test_containers_integration_tests/services/test_end_user_service.py b/api/tests/test_containers_integration_tests/services/test_end_user_service.py index cafabc939b..074d448aab 100644 --- a/api/tests/test_containers_integration_tests/services/test_end_user_service.py +++ b/api/tests/test_containers_integration_tests/services/test_end_user_service.py @@ -4,6 +4,7 @@ from unittest.mock import patch from uuid import uuid4 import pytest +from sqlalchemy.orm import Session from core.app.entities.app_invoke_entities import InvokeFrom from models.account import Account, Tenant, TenantAccountJoin @@ -102,7 +103,7 @@ class TestEndUserServiceGetOrCreateEndUser: """Provide test data factory.""" return TestEndUserServiceFactory() - def test_get_or_create_end_user_with_custom_user_id(self, db_session_with_containers, factory): + def test_get_or_create_end_user_with_custom_user_id(self, db_session_with_containers: Session, factory): """Test getting or creating end user with custom user_id.""" # Arrange app = factory.create_app_and_account(db_session_with_containers) @@ -118,7 +119,7 @@ class TestEndUserServiceGetOrCreateEndUser: assert result.type == InvokeFrom.SERVICE_API assert result.is_anonymous is False - def test_get_or_create_end_user_without_user_id(self, db_session_with_containers, factory): + def test_get_or_create_end_user_without_user_id(self, db_session_with_containers: Session, factory): """Test getting or creating end user without user_id uses default session.""" # Arrange app = factory.create_app_and_account(db_session_with_containers) @@ -131,7 +132,7 @@ class TestEndUserServiceGetOrCreateEndUser: # Verify _is_anonymous is set correctly (property always returns False) assert result._is_anonymous is True - def test_get_existing_end_user(self, db_session_with_containers, factory): + def test_get_existing_end_user(self, db_session_with_containers: Session, factory): """Test retrieving an existing end user.""" # Arrange app = factory.create_app_and_account(db_session_with_containers) @@ -167,7 +168,7 @@ class TestEndUserServiceGetOrCreateEndUserByType: """Provide test data factory.""" return TestEndUserServiceFactory() - def test_create_end_user_service_api_type(self, db_session_with_containers, factory): + def test_create_end_user_service_api_type(self, db_session_with_containers: Session, factory): """Test creating new end user with SERVICE_API type.""" # Arrange app = factory.create_app_and_account(db_session_with_containers) @@ -189,7 +190,7 @@ class TestEndUserServiceGetOrCreateEndUserByType: assert result.app_id == app_id assert result.session_id == user_id - def test_create_end_user_web_app_type(self, db_session_with_containers, factory): + def test_create_end_user_web_app_type(self, db_session_with_containers: Session, factory): """Test creating new end user with WEB_APP type.""" # Arrange app = factory.create_app_and_account(db_session_with_containers) @@ -209,7 +210,7 @@ class TestEndUserServiceGetOrCreateEndUserByType: assert result.type == InvokeFrom.WEB_APP @patch("services.end_user_service.logger") - def test_upgrade_legacy_end_user_type(self, mock_logger, db_session_with_containers, factory): + def test_upgrade_legacy_end_user_type(self, mock_logger, db_session_with_containers: Session, factory): """Test upgrading legacy end user with different type.""" # Arrange app = factory.create_app_and_account(db_session_with_containers) @@ -243,7 +244,7 @@ class TestEndUserServiceGetOrCreateEndUserByType: assert "Upgrading legacy EndUser" in log_call @patch("services.end_user_service.logger") - def test_get_existing_end_user_matching_type(self, mock_logger, db_session_with_containers, factory): + def test_get_existing_end_user_matching_type(self, mock_logger, db_session_with_containers: Session, factory): """Test retrieving existing end user with matching type.""" # Arrange app = factory.create_app_and_account(db_session_with_containers) @@ -272,7 +273,7 @@ class TestEndUserServiceGetOrCreateEndUserByType: assert result.type == InvokeFrom.SERVICE_API mock_logger.info.assert_not_called() - def test_create_anonymous_user_with_default_session(self, db_session_with_containers, factory): + def test_create_anonymous_user_with_default_session(self, db_session_with_containers: Session, factory): """Test creating anonymous user when user_id is None.""" # Arrange app = factory.create_app_and_account(db_session_with_containers) @@ -293,7 +294,7 @@ class TestEndUserServiceGetOrCreateEndUserByType: assert result._is_anonymous is True assert result.external_user_id == DefaultEndUserSessionID.DEFAULT_SESSION_ID - def test_query_ordering_prioritizes_matching_type(self, db_session_with_containers, factory): + def test_query_ordering_prioritizes_matching_type(self, db_session_with_containers: Session, factory): """Test that query ordering prioritizes records with matching type.""" # Arrange app = factory.create_app_and_account(db_session_with_containers) @@ -328,7 +329,7 @@ class TestEndUserServiceGetOrCreateEndUserByType: assert result.id == matching.id assert result.id != non_matching.id - def test_external_user_id_matches_session_id(self, db_session_with_containers, factory): + def test_external_user_id_matches_session_id(self, db_session_with_containers: Session, factory): """Test that external_user_id is set to match session_id.""" # Arrange app = factory.create_app_and_account(db_session_with_containers) @@ -357,7 +358,9 @@ class TestEndUserServiceGetOrCreateEndUserByType: InvokeFrom.DEBUGGER, ], ) - def test_create_end_user_with_different_invoke_types(self, db_session_with_containers, invoke_type, factory): + def test_create_end_user_with_different_invoke_types( + self, db_session_with_containers: Session, invoke_type, factory + ): """Test creating end users with different InvokeFrom types.""" # Arrange app = factory.create_app_and_account(db_session_with_containers) @@ -385,7 +388,7 @@ class TestEndUserServiceGetEndUserById: """Provide test data factory.""" return TestEndUserServiceFactory() - def test_get_end_user_by_id_returns_end_user(self, db_session_with_containers, factory): + def test_get_end_user_by_id_returns_end_user(self, db_session_with_containers: Session, factory): app = factory.create_app_and_account(db_session_with_containers) existing_user = factory.create_end_user( db_session_with_containers, @@ -404,7 +407,7 @@ class TestEndUserServiceGetEndUserById: assert result is not None assert result.id == existing_user.id - def test_get_end_user_by_id_returns_none(self, db_session_with_containers, factory): + def test_get_end_user_by_id_returns_none(self, db_session_with_containers: Session, factory): app = factory.create_app_and_account(db_session_with_containers) result = EndUserService.get_end_user_by_id( @@ -423,7 +426,7 @@ class TestEndUserServiceCreateBatch: def factory(self): return TestEndUserServiceFactory() - def _create_multiple_apps(self, db_session_with_containers, factory, count: int = 3): + def _create_multiple_apps(self, db_session_with_containers: Session, factory, count: int = 3): """Create multiple apps under the same tenant.""" first_app = factory.create_app_and_account(db_session_with_containers) tenant_id = first_app.tenant_id @@ -452,13 +455,13 @@ class TestEndUserServiceCreateBatch: all_apps = db_session_with_containers.query(App).filter(App.tenant_id == tenant_id).all() return tenant_id, all_apps - def test_create_batch_empty_app_ids(self, db_session_with_containers): + def test_create_batch_empty_app_ids(self, db_session_with_containers: Session): result = EndUserService.create_end_user_batch( type=InvokeFrom.SERVICE_API, tenant_id=str(uuid4()), app_ids=[], user_id="user-1" ) assert result == {} - def test_create_batch_creates_users_for_all_apps(self, db_session_with_containers, factory): + def test_create_batch_creates_users_for_all_apps(self, db_session_with_containers: Session, factory): tenant_id, apps = self._create_multiple_apps(db_session_with_containers, factory, count=3) app_ids = [a.id for a in apps] user_id = f"user-{uuid4()}" @@ -473,7 +476,7 @@ class TestEndUserServiceCreateBatch: assert result[app_id].session_id == user_id assert result[app_id].type == InvokeFrom.SERVICE_API - def test_create_batch_default_session_id(self, db_session_with_containers, factory): + def test_create_batch_default_session_id(self, db_session_with_containers: Session, factory): tenant_id, apps = self._create_multiple_apps(db_session_with_containers, factory, count=2) app_ids = [a.id for a in apps] @@ -486,7 +489,7 @@ class TestEndUserServiceCreateBatch: assert end_user.session_id == DefaultEndUserSessionID.DEFAULT_SESSION_ID assert end_user._is_anonymous is True - def test_create_batch_deduplicate_app_ids(self, db_session_with_containers, factory): + def test_create_batch_deduplicate_app_ids(self, db_session_with_containers: Session, factory): tenant_id, apps = self._create_multiple_apps(db_session_with_containers, factory, count=2) app_ids = [apps[0].id, apps[1].id, apps[0].id, apps[1].id] user_id = f"user-{uuid4()}" @@ -497,7 +500,7 @@ class TestEndUserServiceCreateBatch: assert len(result) == 2 - def test_create_batch_returns_existing_users(self, db_session_with_containers, factory): + def test_create_batch_returns_existing_users(self, db_session_with_containers: Session, factory): tenant_id, apps = self._create_multiple_apps(db_session_with_containers, factory, count=2) app_ids = [a.id for a in apps] user_id = f"user-{uuid4()}" @@ -516,7 +519,7 @@ class TestEndUserServiceCreateBatch: for app_id in app_ids: assert first_result[app_id].id == second_result[app_id].id - def test_create_batch_partial_existing_users(self, db_session_with_containers, factory): + def test_create_batch_partial_existing_users(self, db_session_with_containers: Session, factory): tenant_id, apps = self._create_multiple_apps(db_session_with_containers, factory, count=3) user_id = f"user-{uuid4()}" @@ -545,7 +548,7 @@ class TestEndUserServiceCreateBatch: "invoke_type", [InvokeFrom.SERVICE_API, InvokeFrom.WEB_APP, InvokeFrom.EXPLORE, InvokeFrom.DEBUGGER], ) - def test_create_batch_all_invoke_types(self, db_session_with_containers, invoke_type, factory): + def test_create_batch_all_invoke_types(self, db_session_with_containers: Session, invoke_type, factory): tenant_id, apps = self._create_multiple_apps(db_session_with_containers, factory, count=1) user_id = f"user-{uuid4()}" diff --git a/api/tests/test_containers_integration_tests/services/test_feature_service.py b/api/tests/test_containers_integration_tests/services/test_feature_service.py index 315936d721..f78aeaf984 100644 --- a/api/tests/test_containers_integration_tests/services/test_feature_service.py +++ b/api/tests/test_containers_integration_tests/services/test_feature_service.py @@ -2,6 +2,7 @@ from unittest.mock import patch import pytest from faker import Faker +from sqlalchemy.orm import Session from enums.cloud_plan import CloudPlan from services.feature_service import ( @@ -81,7 +82,7 @@ class TestFeatureService: fake = Faker() return fake.uuid4() - def test_get_features_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_features_success(self, db_session_with_containers: Session, mock_external_service_dependencies): """ Test successful feature retrieval with billing and enterprise enabled. @@ -156,7 +157,7 @@ class TestFeatureService: tenant_id ) - def test_get_features_sandbox_plan(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_features_sandbox_plan(self, db_session_with_containers: Session, mock_external_service_dependencies): """ Test feature retrieval for sandbox plan with specific limitations. @@ -222,7 +223,9 @@ class TestFeatureService: # Verify mock interactions mock_external_service_dependencies["billing_service"].get_info.assert_called_once_with(tenant_id) - def test_get_knowledge_rate_limit_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_knowledge_rate_limit_success( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test successful knowledge rate limit retrieval with billing enabled. @@ -255,7 +258,7 @@ class TestFeatureService: tenant_id ) - def test_get_system_features_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_system_features_success(self, db_session_with_containers: Session, mock_external_service_dependencies): """ Test successful system features retrieval with enterprise and marketplace enabled. @@ -332,7 +335,9 @@ class TestFeatureService: # Verify mock interactions mock_external_service_dependencies["enterprise_service"].get_info.assert_called_once() - def test_get_system_features_unauthenticated(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_system_features_unauthenticated( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test system features retrieval for an unauthenticated user. @@ -386,7 +391,9 @@ class TestFeatureService: # Marketplace should be visible assert result.enable_marketplace is True - def test_get_system_features_basic_config(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_system_features_basic_config( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test system features retrieval with basic configuration (no enterprise). @@ -436,7 +443,9 @@ class TestFeatureService: # Verify plugin package size (uses default value from dify_config) assert result.max_plugin_package_size == 15728640 - def test_get_features_billing_disabled(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_features_billing_disabled( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test feature retrieval when billing is disabled. @@ -492,7 +501,7 @@ class TestFeatureService: assert result.webapp_copyright_enabled is False def test_get_knowledge_rate_limit_billing_disabled( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test knowledge rate limit retrieval when billing is disabled. @@ -523,7 +532,9 @@ class TestFeatureService: # Verify no billing service calls mock_external_service_dependencies["billing_service"].get_knowledge_rate_limit.assert_not_called() - def test_get_features_enterprise_only(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_features_enterprise_only( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test feature retrieval with enterprise enabled but billing disabled. @@ -583,7 +594,7 @@ class TestFeatureService: mock_external_service_dependencies["billing_service"].get_info.assert_not_called() def test_get_system_features_enterprise_disabled( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test system features retrieval when enterprise is disabled. @@ -640,7 +651,7 @@ class TestFeatureService: # Verify no enterprise service calls mock_external_service_dependencies["enterprise_service"].get_info.assert_not_called() - def test_get_features_no_tenant_id(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_features_no_tenant_id(self, db_session_with_containers: Session, mock_external_service_dependencies): """ Test feature retrieval without tenant ID (billing disabled). @@ -686,7 +697,9 @@ class TestFeatureService: # Verify no billing service calls mock_external_service_dependencies["billing_service"].get_info.assert_not_called() - def test_get_features_partial_billing_info(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_features_partial_billing_info( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test feature retrieval with partial billing information. @@ -746,7 +759,9 @@ class TestFeatureService: # Verify mock interactions mock_external_service_dependencies["billing_service"].get_info.assert_called_once_with(tenant_id) - def test_get_features_edge_case_vector_space(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_features_edge_case_vector_space( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test feature retrieval with edge case vector space configuration. @@ -807,7 +822,7 @@ class TestFeatureService: mock_external_service_dependencies["billing_service"].get_info.assert_called_once_with(tenant_id) def test_get_system_features_edge_case_webapp_auth( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test system features retrieval with edge case webapp auth configuration. @@ -863,7 +878,9 @@ class TestFeatureService: # Verify mock interactions mock_external_service_dependencies["enterprise_service"].get_info.assert_called_once() - def test_get_features_edge_case_members_quota(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_features_edge_case_members_quota( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test feature retrieval with edge case members quota configuration. @@ -924,7 +941,7 @@ class TestFeatureService: mock_external_service_dependencies["billing_service"].get_info.assert_called_once_with(tenant_id) def test_plugin_installation_permission_scopes( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test system features retrieval with different plugin installation permission scopes. @@ -1023,7 +1040,7 @@ class TestFeatureService: assert result.plugin_installation_permission.restrict_to_marketplace_only is True def test_get_features_workspace_members_missing( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test feature retrieval when workspace members info is missing from enterprise. @@ -1064,7 +1081,9 @@ class TestFeatureService: tenant_id ) - def test_get_system_features_license_inactive(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_system_features_license_inactive( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test system features retrieval with inactive license. @@ -1117,7 +1136,7 @@ class TestFeatureService: mock_external_service_dependencies["enterprise_service"].get_info.assert_called_once() def test_get_system_features_partial_enterprise_info( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test system features retrieval with partial enterprise information. @@ -1186,7 +1205,9 @@ class TestFeatureService: # Verify mock interactions mock_external_service_dependencies["enterprise_service"].get_info.assert_called_once() - def test_get_features_edge_case_limits(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_features_edge_case_limits( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test feature retrieval with edge case limit values. @@ -1244,7 +1265,7 @@ class TestFeatureService: mock_external_service_dependencies["billing_service"].get_info.assert_called_once_with(tenant_id) def test_get_system_features_edge_case_protocols( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test system features retrieval with edge case protocol values. @@ -1297,7 +1318,9 @@ class TestFeatureService: # Verify mock interactions mock_external_service_dependencies["enterprise_service"].get_info.assert_called_once() - def test_get_features_edge_case_education(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_features_edge_case_education( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test feature retrieval with edge case education configuration. @@ -1353,7 +1376,7 @@ class TestFeatureService: mock_external_service_dependencies["billing_service"].get_info.assert_called_once_with(tenant_id) def test_license_limitation_model_is_available( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test LicenseLimitationModel.is_available method with various scenarios. @@ -1394,7 +1417,7 @@ class TestFeatureService: assert exact_limit.is_available(3) is True def test_get_features_workspace_members_disabled( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test feature retrieval when workspace members are disabled in enterprise. @@ -1433,7 +1456,9 @@ class TestFeatureService: # Verify mock interactions mock_external_service_dependencies["enterprise_service"].get_workspace_info.assert_called_once_with(tenant_id) - def test_get_system_features_license_expired(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_system_features_license_expired( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test system features retrieval with expired license. @@ -1486,7 +1511,7 @@ class TestFeatureService: mock_external_service_dependencies["enterprise_service"].get_info.assert_called_once() def test_get_features_edge_case_docs_processing( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test feature retrieval with edge case document processing configuration. @@ -1544,7 +1569,7 @@ class TestFeatureService: mock_external_service_dependencies["billing_service"].get_info.assert_called_once_with(tenant_id) def test_get_system_features_edge_case_branding( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test system features retrieval with edge case branding configuration. @@ -1606,7 +1631,7 @@ class TestFeatureService: mock_external_service_dependencies["enterprise_service"].get_info.assert_called_once() def test_get_features_edge_case_annotation_quota( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test feature retrieval with edge case annotation quota configuration. @@ -1668,7 +1693,7 @@ class TestFeatureService: mock_external_service_dependencies["billing_service"].get_info.assert_called_once_with(tenant_id) def test_get_features_edge_case_documents_upload( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test feature retrieval with edge case documents upload settings. @@ -1733,7 +1758,7 @@ class TestFeatureService: mock_external_service_dependencies["billing_service"].get_info.assert_called_once_with(tenant_id) def test_get_system_features_edge_case_license_lost( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test system features with lost license status. @@ -1784,7 +1809,7 @@ class TestFeatureService: mock_external_service_dependencies["enterprise_service"].get_info.assert_called_once() def test_get_features_edge_case_education_disabled( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test feature retrieval with education feature disabled. diff --git a/api/tests/test_containers_integration_tests/services/test_human_input_delivery_test_service.py b/api/tests/test_containers_integration_tests/services/test_human_input_delivery_test_service.py index ed75363f3b..ce63e7a71a 100644 --- a/api/tests/test_containers_integration_tests/services/test_human_input_delivery_test_service.py +++ b/api/tests/test_containers_integration_tests/services/test_human_input_delivery_test_service.py @@ -6,6 +6,7 @@ from uuid import uuid4 import pytest from sqlalchemy.engine import Engine +from sqlalchemy.orm import Session from configs import dify_config from core.workflow.human_input_adapter import ( @@ -88,7 +89,7 @@ class TestDeliveryTestRegistry: with pytest.raises(DeliveryTestUnsupportedError, match="Delivery method does not support test send."): registry.dispatch(context=context, method=method) - def test_default(self, flask_app_with_containers, db_session_with_containers): + def test_default(self, flask_app_with_containers, db_session_with_containers: Session): registry = DeliveryTestRegistry.default() assert len(registry._handlers) == 1 assert isinstance(registry._handlers[0], EmailDeliveryTestHandler) @@ -260,7 +261,7 @@ class TestEmailDeliveryTestHandler: ) assert handler._resolve_recipients(tenant_id="t1", method=method) == ["ext@example.com"] - def test_resolve_recipients_member(self, flask_app_with_containers, db_session_with_containers): + def test_resolve_recipients_member(self, flask_app_with_containers, db_session_with_containers: Session): tenant_id = str(uuid4()) account = Account(name="Test User", email="member@example.com") db_session_with_containers.add(account) @@ -282,7 +283,7 @@ class TestEmailDeliveryTestHandler: ) assert handler._resolve_recipients(tenant_id=tenant_id, method=method) == ["member@example.com"] - def test_resolve_recipients_whole_workspace(self, flask_app_with_containers, db_session_with_containers): + def test_resolve_recipients_whole_workspace(self, flask_app_with_containers, db_session_with_containers: Session): tenant_id = str(uuid4()) account1 = Account(name="User 1", email=f"u1-{uuid4()}@example.com") account2 = Account(name="User 2", email=f"u2-{uuid4()}@example.com") diff --git a/api/tests/test_containers_integration_tests/services/test_messages_clean_service.py b/api/tests/test_containers_integration_tests/services/test_messages_clean_service.py index cd63d3ad6c..1a1efe0337 100644 --- a/api/tests/test_containers_integration_tests/services/test_messages_clean_service.py +++ b/api/tests/test_containers_integration_tests/services/test_messages_clean_service.py @@ -165,7 +165,7 @@ class TestMessagesCleanServiceIntegration: return app - def _create_conversation(self, db_session_with_containers: Session, app): + def _create_conversation(self, db_session_with_containers: Session, app: App): """Helper to create a conversation.""" conversation = Conversation( app_id=app.id, diff --git a/api/tests/test_containers_integration_tests/services/test_metadata_partial_update.py b/api/tests/test_containers_integration_tests/services/test_metadata_partial_update.py index b55a19eaa9..fffa82bf5c 100644 --- a/api/tests/test_containers_integration_tests/services/test_metadata_partial_update.py +++ b/api/tests/test_containers_integration_tests/services/test_metadata_partial_update.py @@ -5,6 +5,7 @@ from uuid import uuid4 import pytest from sqlalchemy import select +from sqlalchemy.orm import Session from models.dataset import Dataset, DatasetMetadataBinding, Document from models.enums import DataSourceType, DocumentCreatedFrom @@ -65,7 +66,7 @@ class TestMetadataPartialUpdate: yield account def test_partial_update_merges_metadata( - self, flask_app_with_containers, db_session_with_containers, tenant_id, mock_current_account + self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, mock_current_account ): dataset = _create_dataset(db_session_with_containers, tenant_id=tenant_id) document = _create_document( @@ -92,7 +93,7 @@ class TestMetadataPartialUpdate: assert updated_doc.doc_metadata["new_key"] == "new_value" def test_full_update_replaces_metadata( - self, flask_app_with_containers, db_session_with_containers, tenant_id, mock_current_account + self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, mock_current_account ): dataset = _create_dataset(db_session_with_containers, tenant_id=tenant_id) document = _create_document( @@ -119,7 +120,7 @@ class TestMetadataPartialUpdate: assert "existing_key" not in updated_doc.doc_metadata def test_partial_update_skips_existing_binding( - self, flask_app_with_containers, db_session_with_containers, tenant_id, user_id, mock_current_account + self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, user_id, mock_current_account ): dataset = _create_dataset(db_session_with_containers, tenant_id=tenant_id) document = _create_document( @@ -159,7 +160,7 @@ class TestMetadataPartialUpdate: assert len(bindings) == 1 def test_rollback_called_on_commit_failure( - self, flask_app_with_containers, db_session_with_containers, tenant_id, mock_current_account + self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, mock_current_account ): dataset = _create_dataset(db_session_with_containers, tenant_id=tenant_id) document = _create_document( diff --git a/api/tests/test_containers_integration_tests/services/test_oauth_server_service.py b/api/tests/test_containers_integration_tests/services/test_oauth_server_service.py index c146a5924b..5fa5de6d80 100644 --- a/api/tests/test_containers_integration_tests/services/test_oauth_server_service.py +++ b/api/tests/test_containers_integration_tests/services/test_oauth_server_service.py @@ -8,6 +8,7 @@ from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest +from sqlalchemy.orm import Session from werkzeug.exceptions import BadRequest from models.model import OAuthProviderApp @@ -25,7 +26,7 @@ from services.oauth_server import ( class TestOAuthServerServiceGetProviderApp: """DB-backed tests for get_oauth_provider_app.""" - def _create_oauth_provider_app(self, db_session_with_containers, *, client_id: str) -> OAuthProviderApp: + def _create_oauth_provider_app(self, db_session_with_containers: Session, *, client_id: str) -> OAuthProviderApp: app = OAuthProviderApp( app_icon="icon.png", client_id=client_id, @@ -38,7 +39,7 @@ class TestOAuthServerServiceGetProviderApp: db_session_with_containers.commit() return app - def test_get_oauth_provider_app_returns_app_when_exists(self, db_session_with_containers): + def test_get_oauth_provider_app_returns_app_when_exists(self, db_session_with_containers: Session): client_id = f"client-{uuid4()}" created = self._create_oauth_provider_app(db_session_with_containers, client_id=client_id) @@ -48,7 +49,7 @@ class TestOAuthServerServiceGetProviderApp: assert result.client_id == client_id assert result.id == created.id - def test_get_oauth_provider_app_returns_none_when_not_exists(self, db_session_with_containers): + def test_get_oauth_provider_app_returns_none_when_not_exists(self, db_session_with_containers: Session): result = OAuthServerService.get_oauth_provider_app(f"nonexistent-{uuid4()}") assert result is None diff --git a/api/tests/test_containers_integration_tests/services/test_restore_archived_workflow_run.py b/api/tests/test_containers_integration_tests/services/test_restore_archived_workflow_run.py index 7036524918..2f20949611 100644 --- a/api/tests/test_containers_integration_tests/services/test_restore_archived_workflow_run.py +++ b/api/tests/test_containers_integration_tests/services/test_restore_archived_workflow_run.py @@ -8,6 +8,7 @@ from datetime import datetime from uuid import uuid4 from sqlalchemy import select +from sqlalchemy.orm import Session from models.workflow import WorkflowPause, WorkflowRun from services.retention.workflow_run.restore_archived_workflow_run import WorkflowRunRestore @@ -39,7 +40,7 @@ class TestWorkflowRunRestore: assert result["created_at"].month == 1 assert result["name"] == "test" - def test_restore_table_records_returns_rowcount(self, db_session_with_containers): + def test_restore_table_records_returns_rowcount(self, db_session_with_containers: Session): """Restore should return inserted rowcount.""" restore = WorkflowRunRestore() record_id = str(uuid4()) @@ -65,7 +66,7 @@ class TestWorkflowRunRestore: restored_pause = db_session_with_containers.scalar(select(WorkflowPause).where(WorkflowPause.id == record_id)) assert restored_pause is not None - def test_restore_table_records_unknown_table(self, db_session_with_containers): + def test_restore_table_records_unknown_table(self, db_session_with_containers: Session): """Unknown table names should be ignored gracefully.""" restore = WorkflowRunRestore() diff --git a/api/tests/test_containers_integration_tests/services/test_saved_message_service.py b/api/tests/test_containers_integration_tests/services/test_saved_message_service.py index 70aa813142..7b9e9924cd 100644 --- a/api/tests/test_containers_integration_tests/services/test_saved_message_service.py +++ b/api/tests/test_containers_integration_tests/services/test_saved_message_service.py @@ -4,6 +4,7 @@ import pytest from faker import Faker from sqlalchemy.orm import Session +from models import App, CreatorUserRole from models.enums import ConversationFromSource from models.model import EndUser, Message from models.web import SavedMessage @@ -88,7 +89,7 @@ class TestSavedMessageService: return app, account - def _create_test_end_user(self, db_session_with_containers: Session, app): + def _create_test_end_user(self, db_session_with_containers: Session, app: App): """ Helper method to create a test end user for testing. @@ -116,7 +117,7 @@ class TestSavedMessageService: return end_user - def _create_test_message(self, db_session_with_containers: Session, app, user): + def _create_test_message(self, db_session_with_containers: Session, app: App, user): """ Helper method to create a test message for testing. @@ -199,13 +200,13 @@ class TestSavedMessageService: saved_message1 = SavedMessage( app_id=app.id, message_id=message1.id, - created_by_role="account", + created_by_role=CreatorUserRole.ACCOUNT, created_by=account.id, ) saved_message2 = SavedMessage( app_id=app.id, message_id=message2.id, - created_by_role="account", + created_by_role=CreatorUserRole.ACCOUNT, created_by=account.id, ) @@ -272,13 +273,13 @@ class TestSavedMessageService: saved_message1 = SavedMessage( app_id=app.id, message_id=message1.id, - created_by_role="end_user", + created_by_role=CreatorUserRole.END_USER, created_by=end_user.id, ) saved_message2 = SavedMessage( app_id=app.id, message_id=message2.id, - created_by_role="end_user", + created_by_role=CreatorUserRole.END_USER, created_by=end_user.id, ) @@ -449,7 +450,7 @@ class TestSavedMessageService: saved_message = SavedMessage( app_id=app.id, message_id=message.id, - created_by_role="account", + created_by_role=CreatorUserRole.ACCOUNT, created_by=account.id, ) @@ -540,7 +541,9 @@ class TestSavedMessageService: message = self._create_test_message(db_session_with_containers, app, account) # Pre-create a saved message - saved = SavedMessage(app_id=app.id, message_id=message.id, created_by_role="account", created_by=account.id) + saved = SavedMessage( + app_id=app.id, message_id=message.id, created_by_role=CreatorUserRole.ACCOUNT, created_by=account.id + ) db_session_with_containers.add(saved) db_session_with_containers.commit() @@ -571,7 +574,9 @@ class TestSavedMessageService: end_user = self._create_test_end_user(db_session_with_containers, app) message = self._create_test_message(db_session_with_containers, app, end_user) - saved = SavedMessage(app_id=app.id, message_id=message.id, created_by_role="end_user", created_by=end_user.id) + saved = SavedMessage( + app_id=app.id, message_id=message.id, created_by_role=CreatorUserRole.END_USER, created_by=end_user.id + ) db_session_with_containers.add(saved) db_session_with_containers.commit() @@ -596,10 +601,10 @@ class TestSavedMessageService: # Both users save the same message saved_account = SavedMessage( - app_id=app.id, message_id=message.id, created_by_role="account", created_by=account1.id + app_id=app.id, message_id=message.id, created_by_role=CreatorUserRole.ACCOUNT, created_by=account1.id ) saved_end_user = SavedMessage( - app_id=app.id, message_id=message.id, created_by_role="end_user", created_by=end_user.id + app_id=app.id, message_id=message.id, created_by_role=CreatorUserRole.END_USER, created_by=end_user.id ) db_session_with_containers.add_all([saved_account, saved_end_user]) db_session_with_containers.commit() diff --git a/api/tests/test_containers_integration_tests/services/test_tag_service.py b/api/tests/test_containers_integration_tests/services/test_tag_service.py index 5a6bf0466e..583b6128e6 100644 --- a/api/tests/test_containers_integration_tests/services/test_tag_service.py +++ b/api/tests/test_containers_integration_tests/services/test_tag_service.py @@ -1099,38 +1099,39 @@ class TestTagService: db_session_with_containers, mock_external_service_dependencies ) - # Create tag - tag = self._create_test_tags( - db_session_with_containers, mock_external_service_dependencies, tenant.id, "knowledge", 1 - )[0] + # Create tags + tags = self._create_test_tags( + db_session_with_containers, mock_external_service_dependencies, tenant.id, "knowledge", 2 + ) - # Create dataset and bind tag + # Create dataset and bind tags dataset = self._create_test_dataset(db_session_with_containers, mock_external_service_dependencies, tenant.id) self._create_test_tag_bindings( - db_session_with_containers, mock_external_service_dependencies, [tag], dataset.id, tenant.id + db_session_with_containers, mock_external_service_dependencies, tags, dataset.id, tenant.id ) - # Verify binding exists before deletion - - binding_before = ( + # Verify bindings exist before deletion + bindings_before = ( db_session_with_containers.query(TagBinding) - .where(TagBinding.tag_id == tag.id, TagBinding.target_id == dataset.id) - .first() + .where(TagBinding.tag_id.in_([tag.id for tag in tags]), TagBinding.target_id == dataset.id) + .all() ) - assert binding_before is not None + assert len(bindings_before) == 2 # Act: Execute the method under test - delete_payload = TagBindingDeletePayload(type="knowledge", target_id=dataset.id, tag_id=tag.id) + delete_payload = TagBindingDeletePayload( + type="knowledge", target_id=dataset.id, tag_ids=[tag.id for tag in tags] + ) TagService.delete_tag_binding(delete_payload) # Assert: Verify the expected outcomes - # Verify tag binding was deleted - binding_after = ( + # Verify tag bindings were deleted + bindings_after = ( db_session_with_containers.query(TagBinding) - .where(TagBinding.tag_id == tag.id, TagBinding.target_id == dataset.id) - .first() + .where(TagBinding.tag_id.in_([tag.id for tag in tags]), TagBinding.target_id == dataset.id) + .all() ) - assert binding_after is None + assert len(bindings_after) == 0 def test_delete_tag_binding_non_existent_binding( self, db_session_with_containers: Session, mock_external_service_dependencies @@ -1156,7 +1157,7 @@ class TestTagService: app = self._create_test_app(db_session_with_containers, mock_external_service_dependencies, tenant.id) # Act: Try to delete non-existent binding - delete_payload = TagBindingDeletePayload(type="app", target_id=app.id, tag_id=tag.id) + delete_payload = TagBindingDeletePayload(type="app", target_id=app.id, tag_ids=[tag.id]) TagService.delete_tag_binding(delete_payload) # Assert: Verify the expected outcomes diff --git a/api/tests/test_containers_integration_tests/services/test_web_conversation_service.py b/api/tests/test_containers_integration_tests/services/test_web_conversation_service.py index f2307fbd7d..797731d04b 100644 --- a/api/tests/test_containers_integration_tests/services/test_web_conversation_service.py +++ b/api/tests/test_containers_integration_tests/services/test_web_conversation_service.py @@ -6,7 +6,7 @@ from sqlalchemy import select from sqlalchemy.orm import Session from core.app.entities.app_invoke_entities import InvokeFrom -from models import Account +from models import Account, App from models.enums import ConversationFromSource from models.model import Conversation, EndUser from models.web import PinnedConversation @@ -93,7 +93,7 @@ class TestWebConversationService: return app, account - def _create_test_end_user(self, db_session_with_containers: Session, app): + def _create_test_end_user(self, db_session_with_containers: Session, app: App): """ Helper method to create a test end user for testing. diff --git a/api/tests/test_containers_integration_tests/services/test_webhook_service.py b/api/tests/test_containers_integration_tests/services/test_webhook_service.py index 970da98c55..6d5c7380b7 100644 --- a/api/tests/test_containers_integration_tests/services/test_webhook_service.py +++ b/api/tests/test_containers_integration_tests/services/test_webhook_service.py @@ -5,6 +5,7 @@ from unittest.mock import MagicMock, patch import pytest from faker import Faker from flask import Flask +from sqlalchemy.orm import Session from werkzeug.datastructures import FileStorage from models.enums import AppTriggerStatus, AppTriggerType @@ -52,7 +53,7 @@ class TestWebhookService: } @pytest.fixture - def test_data(self, db_session_with_containers, mock_external_dependencies): + def test_data(self, db_session_with_containers: Session, mock_external_dependencies): """Create test data for webhook service tests.""" fake = Faker() @@ -160,7 +161,7 @@ class TestWebhookService: "app_trigger": app_trigger, } - def test_get_webhook_trigger_and_workflow_success(self, test_data, flask_app_with_containers): + def test_get_webhook_trigger_and_workflow_success(self, test_data, flask_app_with_containers: Flask): """Test successful retrieval of webhook trigger and workflow.""" webhook_id = test_data["webhook_id"] @@ -175,7 +176,7 @@ class TestWebhookService: assert node_config["id"] == "webhook_node" assert node_config["data"].title == "Test Webhook" - def test_get_webhook_trigger_and_workflow_not_found(self, flask_app_with_containers): + def test_get_webhook_trigger_and_workflow_not_found(self, flask_app_with_containers: Flask): """Test webhook trigger not found scenario.""" with flask_app_with_containers.app_context(): with pytest.raises(ValueError, match="Webhook not found"): @@ -421,7 +422,9 @@ class TestWebhookService: assert result["files"] == {} - def test_trigger_workflow_execution_success(self, test_data, mock_external_dependencies, flask_app_with_containers): + def test_trigger_workflow_execution_success( + self, test_data, mock_external_dependencies, flask_app_with_containers: Flask + ): """Test successful workflow execution trigger.""" webhook_data = { "method": "POST", @@ -452,7 +455,7 @@ class TestWebhookService: mock_external_dependencies["async_service"].trigger_workflow_async.assert_called_once() def test_trigger_workflow_execution_end_user_service_failure( - self, test_data, mock_external_dependencies, flask_app_with_containers + self, test_data, mock_external_dependencies, flask_app_with_containers: Flask ): """Test workflow execution trigger when EndUserService fails.""" webhook_data = {"method": "POST", "headers": {}, "query_params": {}, "body": {}, "files": {}} diff --git a/api/tests/test_containers_integration_tests/services/test_webhook_service_relationships.py b/api/tests/test_containers_integration_tests/services/test_webhook_service_relationships.py index 85ce3a6ba6..69cde847f8 100644 --- a/api/tests/test_containers_integration_tests/services/test_webhook_service_relationships.py +++ b/api/tests/test_containers_integration_tests/services/test_webhook_service_relationships.py @@ -6,6 +6,7 @@ from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest +from flask import Flask from sqlalchemy import select from sqlalchemy.orm import Session @@ -165,7 +166,7 @@ class WebhookServiceRelationshipFactory: class TestWebhookServiceLookupWithContainers: def test_get_webhook_trigger_and_workflow_raises_when_app_trigger_missing( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory @@ -182,7 +183,7 @@ class TestWebhookServiceLookupWithContainers: WebhookService.get_webhook_trigger_and_workflow(webhook_trigger.webhook_id) def test_get_webhook_trigger_and_workflow_raises_when_app_trigger_rate_limited( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory @@ -202,7 +203,7 @@ class TestWebhookServiceLookupWithContainers: WebhookService.get_webhook_trigger_and_workflow(webhook_trigger.webhook_id) def test_get_webhook_trigger_and_workflow_raises_when_app_trigger_disabled( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory @@ -222,7 +223,7 @@ class TestWebhookServiceLookupWithContainers: WebhookService.get_webhook_trigger_and_workflow(webhook_trigger.webhook_id) def test_get_webhook_trigger_and_workflow_raises_when_workflow_missing( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory @@ -239,7 +240,7 @@ class TestWebhookServiceLookupWithContainers: WebhookService.get_webhook_trigger_and_workflow(webhook_trigger.webhook_id) def test_get_webhook_trigger_and_workflow_returns_debug_draft_workflow( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory @@ -275,7 +276,7 @@ class TestWebhookServiceLookupWithContainers: class TestWebhookServiceTriggerExecutionWithContainers: def test_trigger_workflow_execution_triggers_async_workflow_successfully( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory @@ -318,7 +319,7 @@ class TestWebhookServiceTriggerExecutionWithContainers: assert trigger_args[2].root_node_id == webhook_trigger.node_id def test_trigger_workflow_execution_marks_tenant_rate_limited_when_quota_exceeded( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory @@ -354,7 +355,7 @@ class TestWebhookServiceTriggerExecutionWithContainers: mock_mark_rate_limited.assert_called_once_with(tenant.id) def test_trigger_workflow_execution_logs_and_reraises_unexpected_errors( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory @@ -386,7 +387,7 @@ class TestWebhookServiceTriggerExecutionWithContainers: class TestWebhookServiceRelationshipSyncWithContainers: def test_sync_webhook_relationships_raises_when_workflow_exceeds_node_limit( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory @@ -401,7 +402,7 @@ class TestWebhookServiceRelationshipSyncWithContainers: WebhookService.sync_webhook_relationships(app, workflow) def test_sync_webhook_relationships_raises_when_lock_not_acquired( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory @@ -418,7 +419,7 @@ class TestWebhookServiceRelationshipSyncWithContainers: WebhookService.sync_webhook_relationships(app, workflow) def test_sync_webhook_relationships_creates_missing_records_and_deletes_stale_records( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory @@ -455,7 +456,7 @@ class TestWebhookServiceRelationshipSyncWithContainers: assert db_session_with_containers.get(WorkflowWebhookTrigger, stale_trigger_id) is None def test_sync_webhook_relationships_sets_redis_cache_for_new_record( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory @@ -481,7 +482,7 @@ class TestWebhookServiceRelationshipSyncWithContainers: assert cached_payload["webhook_id"] == "cache-webhook-id-00001" def test_sync_webhook_relationships_logs_when_lock_release_fails( - self, db_session_with_containers: Session, flask_app_with_containers + self, db_session_with_containers: Session, flask_app_with_containers: Flask ): del flask_app_with_containers factory = WebhookServiceRelationshipFactory diff --git a/api/tests/test_containers_integration_tests/services/test_workflow_app_service.py b/api/tests/test_containers_integration_tests/services/test_workflow_app_service.py index 1e57b5603d..a2cdddad61 100644 --- a/api/tests/test_containers_integration_tests/services/test_workflow_app_service.py +++ b/api/tests/test_containers_integration_tests/services/test_workflow_app_service.py @@ -1530,7 +1530,7 @@ class TestWorkflowAppService: assert result_cross_tenant["total"] == 0 def test_get_paginate_workflow_app_logs_raises_when_account_filter_email_not_found( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): app, account = self._create_test_app_and_account(db_session_with_containers, mock_external_service_dependencies) service = WorkflowAppService() @@ -1543,7 +1543,7 @@ class TestWorkflowAppService: ) def test_get_paginate_workflow_app_logs_filters_by_account( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): app, account = self._create_test_app_and_account(db_session_with_containers, mock_external_service_dependencies) service = WorkflowAppService() @@ -1558,7 +1558,9 @@ class TestWorkflowAppService: assert result["total"] >= 0 assert isinstance(result["data"], list) - def test_get_paginate_workflow_archive_logs(self, db_session_with_containers, mock_external_service_dependencies): + def test_get_paginate_workflow_archive_logs( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): app, account = self._create_test_app_and_account(db_session_with_containers, mock_external_service_dependencies) service = WorkflowAppService() diff --git a/api/tests/test_containers_integration_tests/services/test_workflow_draft_variable_service.py b/api/tests/test_containers_integration_tests/services/test_workflow_draft_variable_service.py index 86cf2327c7..82fe391b08 100644 --- a/api/tests/test_containers_integration_tests/services/test_workflow_draft_variable_service.py +++ b/api/tests/test_containers_integration_tests/services/test_workflow_draft_variable_service.py @@ -45,7 +45,9 @@ class TestWorkflowDraftVariableService: # WorkflowDraftVariableService doesn't have external dependencies that need mocking return {} - def _create_test_app(self, db_session_with_containers: Session, mock_external_service_dependencies, fake=None): + def _create_test_app( + self, db_session_with_containers: Session, mock_external_service_dependencies, fake: Faker | None = None + ): """ Helper method to create a test app with realistic data for testing. @@ -80,7 +82,7 @@ class TestWorkflowDraftVariableService: db_session_with_containers.commit() return app - def _create_test_workflow(self, db_session_with_containers: Session, app, fake=None): + def _create_test_workflow(self, db_session_with_containers: Session, app, fake: Faker | None = None): """ Helper method to create a test workflow associated with an app. diff --git a/api/tests/test_containers_integration_tests/services/test_workflow_service.py b/api/tests/test_containers_integration_tests/services/test_workflow_service.py index b5ce8a53de..9ba1fda08b 100644 --- a/api/tests/test_containers_integration_tests/services/test_workflow_service.py +++ b/api/tests/test_containers_integration_tests/services/test_workflow_service.py @@ -12,7 +12,7 @@ import pytest from faker import Faker from sqlalchemy.orm import Session -from models import Account, App, Workflow +from models import Account, AccountStatus, App, TenantStatus, Workflow from models.model import AppMode from models.workflow import WorkflowType from services.workflow_service import WorkflowService @@ -33,7 +33,7 @@ class TestWorkflowService: and realistic testing environment with actual database interactions. """ - def _create_test_account(self, db_session_with_containers: Session, fake=None): + def _create_test_account(self, db_session_with_containers: Session, fake: Faker | None = None): """ Helper method to create a test account with realistic data. @@ -49,7 +49,7 @@ class TestWorkflowService: email=fake.email(), name=fake.name(), avatar=fake.url(), - status="active", + status=AccountStatus.ACTIVE, interface_language="en-US", # Set interface language for Site creation ) account.created_at = fake.date_time_this_year() @@ -62,7 +62,7 @@ class TestWorkflowService: tenant = Tenant( name=f"Test Tenant {fake.company()}", plan="basic", - status="normal", + status=TenantStatus.NORMAL, ) tenant.id = account.current_tenant_id tenant.created_at = fake.date_time_this_year() @@ -77,7 +77,7 @@ class TestWorkflowService: return account - def _create_test_app(self, db_session_with_containers: Session, fake=None): + def _create_test_app(self, db_session_with_containers: Session, fake: Faker | None = None): """ Helper method to create a test app with realistic data. @@ -109,7 +109,7 @@ class TestWorkflowService: db_session_with_containers.commit() return app - def _create_test_workflow(self, db_session_with_containers: Session, app, account, fake=None): + def _create_test_workflow(self, db_session_with_containers: Session, app, account, fake: Faker | None = None): """ Helper method to create a test workflow associated with an app. diff --git a/api/tests/test_containers_integration_tests/services/workflow/test_workflow_deletion.py b/api/tests/test_containers_integration_tests/services/workflow/test_workflow_deletion.py index 29e1e240b4..afc4908c15 100644 --- a/api/tests/test_containers_integration_tests/services/workflow/test_workflow_deletion.py +++ b/api/tests/test_containers_integration_tests/services/workflow/test_workflow_deletion.py @@ -100,7 +100,7 @@ class TestWorkflowDeletion: session.flush() return provider - def test_delete_workflow_success(self, db_session_with_containers): + def test_delete_workflow_success(self, db_session_with_containers: Session): tenant, account = self._create_tenant_and_account(db_session_with_containers) app = self._create_app(db_session_with_containers, tenant=tenant, account=account) workflow = self._create_workflow( @@ -118,7 +118,7 @@ class TestWorkflowDeletion: db_session_with_containers.expire_all() assert db_session_with_containers.get(Workflow, workflow_id) is None - def test_delete_draft_workflow_raises_error(self, db_session_with_containers): + def test_delete_draft_workflow_raises_error(self, db_session_with_containers: Session): tenant, account = self._create_tenant_and_account(db_session_with_containers) app = self._create_app(db_session_with_containers, tenant=tenant, account=account) workflow = self._create_workflow( @@ -130,7 +130,7 @@ class TestWorkflowDeletion: with pytest.raises(DraftWorkflowDeletionError): service.delete_workflow(session=db_session_with_containers, workflow_id=workflow.id, tenant_id=tenant.id) - def test_delete_workflow_in_use_by_app_raises_error(self, db_session_with_containers): + def test_delete_workflow_in_use_by_app_raises_error(self, db_session_with_containers: Session): tenant, account = self._create_tenant_and_account(db_session_with_containers) app = self._create_app(db_session_with_containers, tenant=tenant, account=account) workflow = self._create_workflow( @@ -144,7 +144,7 @@ class TestWorkflowDeletion: with pytest.raises(WorkflowInUseError, match="currently in use by app"): service.delete_workflow(session=db_session_with_containers, workflow_id=workflow.id, tenant_id=tenant.id) - def test_delete_workflow_published_as_tool_raises_error(self, db_session_with_containers): + def test_delete_workflow_published_as_tool_raises_error(self, db_session_with_containers: Session): tenant, account = self._create_tenant_and_account(db_session_with_containers) app = self._create_app(db_session_with_containers, tenant=tenant, account=account) workflow = self._create_workflow( diff --git a/api/tests/test_containers_integration_tests/services/workflow/test_workflow_node_execution_service_repository.py b/api/tests/test_containers_integration_tests/services/workflow/test_workflow_node_execution_service_repository.py index 4dab895135..32b76c3469 100644 --- a/api/tests/test_containers_integration_tests/services/workflow/test_workflow_node_execution_service_repository.py +++ b/api/tests/test_containers_integration_tests/services/workflow/test_workflow_node_execution_service_repository.py @@ -64,7 +64,7 @@ class TestSQLAlchemyWorkflowNodeExecutionServiceRepository: db_session_with_containers.commit() return execution - def test_get_node_last_execution_found(self, db_session_with_containers): + def test_get_node_last_execution_found(self, db_session_with_containers: Session): """Test getting the last execution for a node when it exists.""" # Arrange tenant_id = str(uuid4()) @@ -110,7 +110,7 @@ class TestSQLAlchemyWorkflowNodeExecutionServiceRepository: assert result.id == expected.id assert result.status == WorkflowNodeExecutionStatus.SUCCEEDED - def test_get_node_last_execution_not_found(self, db_session_with_containers): + def test_get_node_last_execution_not_found(self, db_session_with_containers: Session): """Test getting the last execution for a node when it doesn't exist.""" # Arrange tenant_id = str(uuid4()) @@ -129,7 +129,7 @@ class TestSQLAlchemyWorkflowNodeExecutionServiceRepository: # Assert assert result is None - def test_get_executions_by_workflow_run_empty(self, db_session_with_containers): + def test_get_executions_by_workflow_run_empty(self, db_session_with_containers: Session): """Test getting executions for a workflow run when none exist.""" # Arrange tenant_id = str(uuid4()) @@ -147,7 +147,7 @@ class TestSQLAlchemyWorkflowNodeExecutionServiceRepository: # Assert assert result == [] - def test_get_execution_by_id_found(self, db_session_with_containers): + def test_get_execution_by_id_found(self, db_session_with_containers: Session): """Test getting execution by ID when it exists.""" # Arrange execution = self._create_execution( @@ -170,7 +170,7 @@ class TestSQLAlchemyWorkflowNodeExecutionServiceRepository: assert result is not None assert result.id == execution.id - def test_get_execution_by_id_not_found(self, db_session_with_containers): + def test_get_execution_by_id_not_found(self, db_session_with_containers: Session): """Test getting execution by ID when it doesn't exist.""" # Arrange repository = self._create_repository(db_session_with_containers) @@ -182,7 +182,7 @@ class TestSQLAlchemyWorkflowNodeExecutionServiceRepository: # Assert assert result is None - def test_delete_expired_executions(self, db_session_with_containers): + def test_delete_expired_executions(self, db_session_with_containers: Session): """Test deleting expired executions.""" # Arrange tenant_id = str(uuid4()) @@ -248,7 +248,7 @@ class TestSQLAlchemyWorkflowNodeExecutionServiceRepository: assert old_execution_2_id not in remaining_ids assert kept_execution_id in remaining_ids - def test_delete_executions_by_app(self, db_session_with_containers): + def test_delete_executions_by_app(self, db_session_with_containers: Session): """Test deleting executions by app.""" # Arrange tenant_id = str(uuid4()) @@ -313,7 +313,7 @@ class TestSQLAlchemyWorkflowNodeExecutionServiceRepository: assert deleted_2_id not in remaining_ids assert kept_id in remaining_ids - def test_get_expired_executions_batch(self, db_session_with_containers): + def test_get_expired_executions_batch(self, db_session_with_containers: Session): """Test getting expired executions batch for backup.""" # Arrange tenant_id = str(uuid4()) @@ -370,7 +370,7 @@ class TestSQLAlchemyWorkflowNodeExecutionServiceRepository: assert old_execution_1.id in result_ids assert old_execution_2.id in result_ids - def test_delete_executions_by_ids(self, db_session_with_containers): + def test_delete_executions_by_ids(self, db_session_with_containers: Session): """Test deleting executions by IDs.""" # Arrange tenant_id = str(uuid4()) @@ -424,7 +424,7 @@ class TestSQLAlchemyWorkflowNodeExecutionServiceRepository: ).all() assert remaining == [] - def test_delete_executions_by_ids_empty_list(self, db_session_with_containers): + def test_delete_executions_by_ids_empty_list(self, db_session_with_containers: Session): """Test deleting executions with empty ID list.""" # Arrange repository = self._create_repository(db_session_with_containers) diff --git a/api/tests/test_containers_integration_tests/tasks/test_clean_notion_document_task.py b/api/tests/test_containers_integration_tests/tasks/test_clean_notion_document_task.py index 7e5c374b5d..1c8d5969e0 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_clean_notion_document_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_clean_notion_document_task.py @@ -71,7 +71,7 @@ class TestCleanNotionDocumentTask: yield mock_factory def test_clean_notion_document_task_success( - self, db_session_with_containers, mock_index_processor_factory, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_index_processor_factory, mock_external_service_dependencies ): """ Test successful cleanup of Notion documents with proper database operations. @@ -176,7 +176,7 @@ class TestCleanNotionDocumentTask: # 5. The task completes without errors def test_clean_notion_document_task_dataset_not_found( - self, db_session_with_containers, mock_index_processor_factory, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_index_processor_factory, mock_external_service_dependencies ): """ Test cleanup task behavior when dataset is not found. @@ -196,7 +196,7 @@ class TestCleanNotionDocumentTask: mock_index_processor_factory.return_value.init_index_processor.assert_not_called() def test_clean_notion_document_task_empty_document_list( - self, db_session_with_containers, mock_index_processor_factory, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_index_processor_factory, mock_external_service_dependencies ): """ Test cleanup task behavior with empty document list. @@ -240,7 +240,7 @@ class TestCleanNotionDocumentTask: assert args[1] == [] def test_clean_notion_document_task_with_different_index_types( - self, db_session_with_containers, mock_index_processor_factory, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_index_processor_factory, mock_external_service_dependencies ): """ Test cleanup task with different dataset index types. @@ -328,7 +328,7 @@ class TestCleanNotionDocumentTask: mock_index_processor_factory.reset_mock() def test_clean_notion_document_task_with_segments_no_index_node_ids( - self, db_session_with_containers, mock_index_processor_factory, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_index_processor_factory, mock_external_service_dependencies ): """ Test cleanup task with segments that have no index_node_ids. @@ -411,7 +411,7 @@ class TestCleanNotionDocumentTask: # are properly deleted from the database. def test_clean_notion_document_task_partial_document_cleanup( - self, db_session_with_containers, mock_index_processor_factory, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_index_processor_factory, mock_external_service_dependencies ): """ Test cleanup task with partial document cleanup scenario. @@ -513,7 +513,7 @@ class TestCleanNotionDocumentTask: # The database operations work correctly, isolating only the specified documents. def test_clean_notion_document_task_with_mixed_segment_statuses( - self, db_session_with_containers, mock_index_processor_factory, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_index_processor_factory, mock_external_service_dependencies ): """ Test cleanup task with segments in different statuses. @@ -603,7 +603,7 @@ class TestCleanNotionDocumentTask: # IndexProcessor verification would require more sophisticated mocking. def test_clean_notion_document_task_continues_when_index_processor_fails( - self, db_session_with_containers, mock_index_processor_factory, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_index_processor_factory, mock_external_service_dependencies ): """ Index processor failure (e.g. transient billing API error propagated via @@ -707,7 +707,7 @@ class TestCleanNotionDocumentTask: assert _count_segments(db_session_with_containers, DocumentSegment.document_id == document.id) == 0 def test_clean_notion_document_task_with_large_number_of_documents( - self, db_session_with_containers, mock_index_processor_factory, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_index_processor_factory, mock_external_service_dependencies ): """ Test cleanup task with a large number of documents and segments. @@ -806,7 +806,7 @@ class TestCleanNotionDocumentTask: # The database efficiently handles large-scale deletions. def test_clean_notion_document_task_with_documents_from_different_tenants( - self, db_session_with_containers, mock_index_processor_factory, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_index_processor_factory, mock_external_service_dependencies ): """ Test cleanup task with documents from different tenants. @@ -918,7 +918,7 @@ class TestCleanNotionDocumentTask: # Only documents from the target dataset are affected, maintaining tenant separation. def test_clean_notion_document_task_with_documents_in_different_states( - self, db_session_with_containers, mock_index_processor_factory, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_index_processor_factory, mock_external_service_dependencies ): """ Test cleanup task with documents in different indexing states. @@ -1024,7 +1024,7 @@ class TestCleanNotionDocumentTask: # All documents are deleted regardless of their indexing status. def test_clean_notion_document_task_with_documents_having_metadata( - self, db_session_with_containers, mock_index_processor_factory, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_index_processor_factory, mock_external_service_dependencies ): """ Test cleanup task with documents that have rich metadata. diff --git a/api/tests/test_containers_integration_tests/tasks/test_create_segment_to_index_task.py b/api/tests/test_containers_integration_tests/tasks/test_create_segment_to_index_task.py index 9084667c31..80289c448a 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_create_segment_to_index_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_create_segment_to_index_task.py @@ -12,6 +12,7 @@ from uuid import uuid4 import pytest from faker import Faker from sqlalchemy import delete +from sqlalchemy.orm import Session from core.rag.index_processor.constant.index_type import IndexStructureType, IndexTechniqueType from extensions.ext_redis import redis_client @@ -25,7 +26,7 @@ class TestCreateSegmentToIndexTask: """Integration tests for create_segment_to_index_task using testcontainers.""" @pytest.fixture(autouse=True) - def cleanup_database(self, db_session_with_containers): + def cleanup_database(self, db_session_with_containers: Session): """Clean up database and Redis before each test to ensure isolation.""" # Clear all test data using fixture session @@ -55,7 +56,7 @@ class TestCreateSegmentToIndexTask: "index_processor": mock_processor, } - def _create_test_account_and_tenant(self, db_session_with_containers): + def _create_test_account_and_tenant(self, db_session_with_containers: Session): """ Helper method to create a test account and tenant for testing. @@ -102,7 +103,7 @@ class TestCreateSegmentToIndexTask: return account, tenant - def _create_test_dataset_and_document(self, db_session_with_containers, tenant_id, account_id): + def _create_test_dataset_and_document(self, db_session_with_containers: Session, tenant_id, account_id): """ Helper method to create a test dataset and document for testing. @@ -151,7 +152,13 @@ class TestCreateSegmentToIndexTask: return dataset, document def _create_test_segment( - self, db_session_with_containers, dataset_id, document_id, tenant_id, account_id, status=SegmentStatus.WAITING + self, + db_session_with_containers: Session, + dataset_id, + document_id, + tenant_id, + account_id, + status=SegmentStatus.WAITING, ): """ Helper method to create a test document segment for testing. @@ -189,7 +196,9 @@ class TestCreateSegmentToIndexTask: return segment - def test_create_segment_to_index_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_create_segment_to_index_success( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test successful creation of segment to index. @@ -225,7 +234,7 @@ class TestCreateSegmentToIndexTask: assert redis_client.exists(cache_key) == 0 def test_create_segment_to_index_segment_not_found( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling of non-existent segment ID. @@ -246,7 +255,7 @@ class TestCreateSegmentToIndexTask: mock_external_service_dependencies["index_processor_factory"].assert_not_called() def test_create_segment_to_index_invalid_status( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling of segment with invalid status. @@ -277,7 +286,9 @@ class TestCreateSegmentToIndexTask: # Verify no index processor calls were made mock_external_service_dependencies["index_processor_factory"].assert_not_called() - def test_create_segment_to_index_no_dataset(self, db_session_with_containers, mock_external_service_dependencies): + def test_create_segment_to_index_no_dataset( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test handling of segment without associated dataset. @@ -330,7 +341,9 @@ class TestCreateSegmentToIndexTask: # Verify no index processor calls were made mock_external_service_dependencies["index_processor_factory"].assert_not_called() - def test_create_segment_to_index_no_document(self, db_session_with_containers, mock_external_service_dependencies): + def test_create_segment_to_index_no_document( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test handling of segment without associated document. @@ -367,7 +380,7 @@ class TestCreateSegmentToIndexTask: mock_external_service_dependencies["index_processor_factory"].assert_not_called() def test_create_segment_to_index_document_disabled( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling of segment with disabled document. @@ -403,7 +416,7 @@ class TestCreateSegmentToIndexTask: mock_external_service_dependencies["index_processor_factory"].assert_not_called() def test_create_segment_to_index_document_archived( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling of segment with archived document. @@ -439,7 +452,7 @@ class TestCreateSegmentToIndexTask: mock_external_service_dependencies["index_processor_factory"].assert_not_called() def test_create_segment_to_index_document_indexing_incomplete( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling of segment with document that has incomplete indexing. @@ -475,7 +488,7 @@ class TestCreateSegmentToIndexTask: mock_external_service_dependencies["index_processor_factory"].assert_not_called() def test_create_segment_to_index_processor_exception( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling of index processor exceptions. @@ -511,7 +524,7 @@ class TestCreateSegmentToIndexTask: assert redis_client.exists(cache_key) == 0 def test_create_segment_to_index_with_keywords( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test segment indexing with custom keywords. @@ -543,7 +556,7 @@ class TestCreateSegmentToIndexTask: mock_external_service_dependencies["index_processor"].load.assert_called_once() def test_create_segment_to_index_different_doc_forms( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test segment indexing with different document forms. @@ -586,7 +599,7 @@ class TestCreateSegmentToIndexTask: mock_external_service_dependencies["index_processor_factory"].assert_called_with(doc_form) def test_create_segment_to_index_performance_timing( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test segment indexing performance and timing. @@ -617,7 +630,7 @@ class TestCreateSegmentToIndexTask: assert segment.status == SegmentStatus.COMPLETED def test_create_segment_to_index_concurrent_execution( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test concurrent execution of segment indexing tasks. @@ -654,7 +667,7 @@ class TestCreateSegmentToIndexTask: assert mock_external_service_dependencies["index_processor_factory"].call_count == 3 def test_create_segment_to_index_large_content( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test segment indexing with large content. @@ -703,7 +716,7 @@ class TestCreateSegmentToIndexTask: assert segment.completed_at is not None def test_create_segment_to_index_redis_failure( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test segment indexing when Redis operations fail. @@ -743,7 +756,7 @@ class TestCreateSegmentToIndexTask: assert redis_client.exists(cache_key) == 1 def test_create_segment_to_index_database_transaction_rollback( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test segment indexing with database transaction handling. @@ -775,7 +788,7 @@ class TestCreateSegmentToIndexTask: assert segment.error is not None def test_create_segment_to_index_metadata_validation( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test segment indexing with metadata validation. @@ -817,7 +830,7 @@ class TestCreateSegmentToIndexTask: assert doc is not None def test_create_segment_to_index_status_transition_flow( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test complete status transition flow during indexing. @@ -852,7 +865,7 @@ class TestCreateSegmentToIndexTask: assert segment.indexing_at <= segment.completed_at def test_create_segment_to_index_with_empty_content( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test segment indexing with empty or minimal content. @@ -894,7 +907,7 @@ class TestCreateSegmentToIndexTask: assert segment.completed_at is not None def test_create_segment_to_index_with_special_characters( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test segment indexing with special characters and unicode content. @@ -940,7 +953,7 @@ class TestCreateSegmentToIndexTask: assert segment.completed_at is not None def test_create_segment_to_index_with_long_keywords( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test segment indexing with long keyword lists. @@ -974,7 +987,7 @@ class TestCreateSegmentToIndexTask: mock_external_service_dependencies["index_processor"].load.assert_called_once() def test_create_segment_to_index_tenant_isolation( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test segment indexing with proper tenant isolation. @@ -1017,7 +1030,7 @@ class TestCreateSegmentToIndexTask: assert segment1.tenant_id != segment2.tenant_id def test_create_segment_to_index_with_none_keywords( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test segment indexing with None keywords parameter. @@ -1048,7 +1061,7 @@ class TestCreateSegmentToIndexTask: mock_external_service_dependencies["index_processor"].load.assert_called_once() def test_create_segment_to_index_comprehensive_integration( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Comprehensive integration test covering multiple scenarios. diff --git a/api/tests/test_containers_integration_tests/tasks/test_dataset_indexing_task.py b/api/tests/test_containers_integration_tests/tasks/test_dataset_indexing_task.py index 684097851b..a5a3cd10b5 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_dataset_indexing_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_dataset_indexing_task.py @@ -7,6 +7,7 @@ from unittest.mock import MagicMock, patch import pytest from faker import Faker from sqlalchemy import select +from sqlalchemy.orm import Session from core.indexing_runner import DocumentIsPausedError from core.rag.index_processor.constant.index_type import IndexTechniqueType @@ -174,11 +175,11 @@ class TestDatasetIndexingTaskIntegration: return dataset, documents - def _query_document(self, db_session_with_containers, document_id: str) -> Document | None: + def _query_document(self, db_session_with_containers: Session, document_id: str) -> Document | None: """Return the latest persisted document state.""" return db_session_with_containers.scalar(select(Document).where(Document.id == document_id).limit(1)) - def _assert_documents_parsing(self, db_session_with_containers, document_ids: Sequence[str]) -> None: + def _assert_documents_parsing(self, db_session_with_containers: Session, document_ids: Sequence[str]) -> None: """Assert all target documents are persisted in parsing status.""" db_session_with_containers.expire_all() for document_id in document_ids: @@ -212,7 +213,9 @@ class TestDatasetIndexingTaskIntegration: assert len(opened) >= 2 assert opened_ids <= closed_ids - def test_legacy_document_indexing_task_still_works(self, db_session_with_containers, patched_external_dependencies): + def test_legacy_document_indexing_task_still_works( + self, db_session_with_containers: Session, patched_external_dependencies + ): """Ensure the legacy task entrypoint still updates parsing status.""" # Arrange dataset, documents = self._create_test_dataset_and_documents(db_session_with_containers, document_count=2) @@ -225,7 +228,9 @@ class TestDatasetIndexingTaskIntegration: patched_external_dependencies["indexing_runner_instance"].run.assert_called_once() self._assert_documents_parsing(db_session_with_containers, document_ids) - def test_batch_processing_multiple_documents(self, db_session_with_containers, patched_external_dependencies): + def test_batch_processing_multiple_documents( + self, db_session_with_containers: Session, patched_external_dependencies + ): """Process multiple documents in one batch.""" # Arrange dataset, documents = self._create_test_dataset_and_documents(db_session_with_containers, document_count=3) @@ -240,7 +245,9 @@ class TestDatasetIndexingTaskIntegration: assert len(run_args) == len(document_ids) self._assert_documents_parsing(db_session_with_containers, document_ids) - def test_batch_processing_with_limit_check(self, db_session_with_containers, patched_external_dependencies): + def test_batch_processing_with_limit_check( + self, db_session_with_containers: Session, patched_external_dependencies + ): """Reject batches larger than configured upload limit. This test patches config only to force a deterministic limit branch while keeping SQL writes real. @@ -263,7 +270,7 @@ class TestDatasetIndexingTaskIntegration: self._assert_documents_error_contains(db_session_with_containers, document_ids, "batch upload limit") def test_batch_processing_sandbox_plan_single_document_only( - self, db_session_with_containers, patched_external_dependencies + self, db_session_with_containers: Session, patched_external_dependencies ): """Reject multi-document upload under sandbox plan.""" # Arrange @@ -280,7 +287,9 @@ class TestDatasetIndexingTaskIntegration: patched_external_dependencies["indexing_runner_instance"].run.assert_not_called() self._assert_documents_error_contains(db_session_with_containers, document_ids, "does not support batch upload") - def test_batch_processing_empty_document_list(self, db_session_with_containers, patched_external_dependencies): + def test_batch_processing_empty_document_list( + self, db_session_with_containers: Session, patched_external_dependencies + ): """Handle empty list input without failing.""" # Arrange dataset, _ = self._create_test_dataset_and_documents(db_session_with_containers, document_count=0) @@ -292,7 +301,7 @@ class TestDatasetIndexingTaskIntegration: patched_external_dependencies["indexing_runner_instance"].run.assert_called_once_with([]) def test_tenant_queue_dispatches_next_task_after_completion( - self, db_session_with_containers, patched_external_dependencies + self, db_session_with_containers: Session, patched_external_dependencies ): """Dispatch the next queued task after current tenant task completes. @@ -337,7 +346,7 @@ class TestDatasetIndexingTaskIntegration: delete_key_spy.assert_not_called() def test_tenant_queue_deletes_running_key_when_no_follow_up_tasks( - self, db_session_with_containers, patched_external_dependencies + self, db_session_with_containers: Session, patched_external_dependencies ): """Delete tenant running flag when queue has no pending tasks. @@ -362,7 +371,7 @@ class TestDatasetIndexingTaskIntegration: delete_key_spy.assert_called_once() def test_validation_failure_sets_error_status_when_vector_space_at_limit( - self, db_session_with_containers, patched_external_dependencies + self, db_session_with_containers: Session, patched_external_dependencies ): """Set error status when vector space validation fails before runner phase.""" # Arrange @@ -382,7 +391,7 @@ class TestDatasetIndexingTaskIntegration: self._assert_documents_error_contains(db_session_with_containers, document_ids, "over the limit") def test_runner_exception_does_not_crash_indexing_task( - self, db_session_with_containers, patched_external_dependencies + self, db_session_with_containers: Session, patched_external_dependencies ): """Catch generic runner exceptions without crashing the task.""" # Arrange @@ -397,7 +406,7 @@ class TestDatasetIndexingTaskIntegration: patched_external_dependencies["indexing_runner_instance"].run.assert_called_once() self._assert_documents_parsing(db_session_with_containers, document_ids) - def test_document_paused_error_handling(self, db_session_with_containers, patched_external_dependencies): + def test_document_paused_error_handling(self, db_session_with_containers: Session, patched_external_dependencies): """Handle DocumentIsPausedError and keep persisted state consistent.""" # Arrange dataset, documents = self._create_test_dataset_and_documents(db_session_with_containers, document_count=2) @@ -424,7 +433,7 @@ class TestDatasetIndexingTaskIntegration: patched_external_dependencies["indexing_runner_instance"].run.assert_not_called() def test_tenant_queue_error_handling_still_processes_next_task( - self, db_session_with_containers, patched_external_dependencies + self, db_session_with_containers: Session, patched_external_dependencies ): """Even on current task failure, enqueue the next waiting tenant task. @@ -491,7 +500,7 @@ class TestDatasetIndexingTaskIntegration: self._assert_all_opened_sessions_closed(session_close_tracker) def test_multiple_documents_with_mixed_success_and_failure( - self, db_session_with_containers, patched_external_dependencies + self, db_session_with_containers: Session, patched_external_dependencies ): """Process only existing documents when request includes missing ids.""" # Arrange @@ -508,7 +517,7 @@ class TestDatasetIndexingTaskIntegration: self._assert_documents_parsing(db_session_with_containers, existing_ids) def test_tenant_queue_dispatches_up_to_concurrency_limit( - self, db_session_with_containers, patched_external_dependencies + self, db_session_with_containers: Session, patched_external_dependencies ): """Dispatch only up to configured concurrency under queued backlog burst. @@ -543,7 +552,7 @@ class TestDatasetIndexingTaskIntegration: assert task_dispatch_spy.apply_async.call_count == concurrency_limit assert set_waiting_spy.call_count == concurrency_limit - def test_task_queue_fifo_ordering(self, db_session_with_containers, patched_external_dependencies): + def test_task_queue_fifo_ordering(self, db_session_with_containers: Session, patched_external_dependencies): """Keep FIFO ordering when dispatching next queued tasks. Queue APIs are patched to isolate dispatch side effects while preserving DB assertions. @@ -576,7 +585,9 @@ class TestDatasetIndexingTaskIntegration: call_kwargs = task_dispatch_spy.apply_async.call_args_list[index].kwargs.get("kwargs", {}) assert call_kwargs.get("document_ids") == expected_task["document_ids"] - def test_billing_disabled_skips_limit_checks(self, db_session_with_containers, patched_external_dependencies): + def test_billing_disabled_skips_limit_checks( + self, db_session_with_containers: Session, patched_external_dependencies + ): """Skip limit checks when billing feature is disabled.""" # Arrange large_document_ids = [str(uuid.uuid4()) for _ in range(100)] @@ -595,7 +606,7 @@ class TestDatasetIndexingTaskIntegration: assert len(run_args) == 100 self._assert_documents_parsing(db_session_with_containers, large_document_ids) - def test_complete_workflow_normal_task(self, db_session_with_containers, patched_external_dependencies): + def test_complete_workflow_normal_task(self, db_session_with_containers: Session, patched_external_dependencies): """Run end-to-end normal queue workflow with tenant queue cleanup. Queue APIs are patched to isolate dispatch side effects while preserving DB assertions. @@ -618,7 +629,7 @@ class TestDatasetIndexingTaskIntegration: self._assert_documents_parsing(db_session_with_containers, document_ids) delete_key_spy.assert_called_once() - def test_complete_workflow_priority_task(self, db_session_with_containers, patched_external_dependencies): + def test_complete_workflow_priority_task(self, db_session_with_containers: Session, patched_external_dependencies): """Run end-to-end priority queue workflow with tenant queue cleanup. Queue APIs are patched to isolate dispatch side effects while preserving DB assertions. @@ -641,7 +652,7 @@ class TestDatasetIndexingTaskIntegration: self._assert_documents_parsing(db_session_with_containers, document_ids) delete_key_spy.assert_called_once() - def test_single_document_processing(self, db_session_with_containers, patched_external_dependencies): + def test_single_document_processing(self, db_session_with_containers: Session, patched_external_dependencies): """Process the minimum batch size (single document).""" # Arrange dataset, documents = self._create_test_dataset_and_documents(db_session_with_containers, document_count=1) @@ -655,7 +666,9 @@ class TestDatasetIndexingTaskIntegration: assert len(run_args) == 1 self._assert_documents_parsing(db_session_with_containers, [document_id]) - def test_document_with_special_characters_in_id(self, db_session_with_containers, patched_external_dependencies): + def test_document_with_special_characters_in_id( + self, db_session_with_containers: Session, patched_external_dependencies + ): """Handle standard UUID ids with hyphen characters safely.""" # Arrange special_document_id = str(uuid.uuid4()) @@ -670,7 +683,9 @@ class TestDatasetIndexingTaskIntegration: # Assert self._assert_documents_parsing(db_session_with_containers, [special_document_id]) - def test_zero_vector_space_limit_allows_unlimited(self, db_session_with_containers, patched_external_dependencies): + def test_zero_vector_space_limit_allows_unlimited( + self, db_session_with_containers: Session, patched_external_dependencies + ): """Treat vector limit 0 as unlimited and continue indexing.""" # Arrange dataset, documents = self._create_test_dataset_and_documents(db_session_with_containers, document_count=3) @@ -689,7 +704,7 @@ class TestDatasetIndexingTaskIntegration: self._assert_documents_parsing(db_session_with_containers, document_ids) def test_negative_vector_space_values_handled_gracefully( - self, db_session_with_containers, patched_external_dependencies + self, db_session_with_containers: Session, patched_external_dependencies ): """Treat negative vector limits as non-blocking and continue indexing.""" # Arrange @@ -708,7 +723,7 @@ class TestDatasetIndexingTaskIntegration: patched_external_dependencies["indexing_runner_instance"].run.assert_called_once() self._assert_documents_parsing(db_session_with_containers, document_ids) - def test_large_document_batch_processing(self, db_session_with_containers, patched_external_dependencies): + def test_large_document_batch_processing(self, db_session_with_containers: Session, patched_external_dependencies): """Process a batch exactly at configured upload limit. This test patches config only to force a deterministic limit branch while keeping SQL writes real. diff --git a/api/tests/test_containers_integration_tests/tasks/test_deal_dataset_vector_index_task.py b/api/tests/test_containers_integration_tests/tasks/test_deal_dataset_vector_index_task.py index 48fec441c5..e4cbb9e589 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_deal_dataset_vector_index_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_deal_dataset_vector_index_task.py @@ -12,6 +12,7 @@ from unittest.mock import ANY, Mock, patch import pytest from faker import Faker from sqlalchemy import select +from sqlalchemy.orm import Session from core.rag.index_processor.constant.index_type import IndexStructureType from models.dataset import Dataset, Document, DocumentSegment @@ -55,7 +56,7 @@ class TestDealDatasetVectorIndexTask: yield mock_factory @pytest.fixture - def account_and_tenant(self, db_session_with_containers, mock_external_service_dependencies): + def account_and_tenant(self, db_session_with_containers: Session, mock_external_service_dependencies): """Create an account with an owner tenant for testing. Returns a tuple of (account, tenant) where tenant is guaranteed to be non-None. @@ -73,7 +74,7 @@ class TestDealDatasetVectorIndexTask: return account, tenant def test_deal_dataset_vector_index_task_remove_action_success( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test successful removal of dataset vector index. @@ -131,7 +132,7 @@ class TestDealDatasetVectorIndexTask: assert mock_processor.clean.call_count >= 0 # For now, just check it doesn't fail def test_deal_dataset_vector_index_task_add_action_success( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test successful addition of dataset vector index. @@ -233,7 +234,7 @@ class TestDealDatasetVectorIndexTask: mock_processor.load.assert_called_once() def test_deal_dataset_vector_index_task_update_action_success( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test successful update of dataset vector index. @@ -337,7 +338,7 @@ class TestDealDatasetVectorIndexTask: mock_processor.load.assert_called_once() def test_deal_dataset_vector_index_task_dataset_not_found_error( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test task behavior when dataset is not found. @@ -357,7 +358,7 @@ class TestDealDatasetVectorIndexTask: mock_processor.load.assert_not_called() def test_deal_dataset_vector_index_task_add_action_no_documents( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test add action when no documents exist for the dataset. @@ -389,7 +390,7 @@ class TestDealDatasetVectorIndexTask: mock_processor.load.assert_not_called() def test_deal_dataset_vector_index_task_add_action_no_segments( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test add action when documents exist but have no segments. @@ -447,7 +448,7 @@ class TestDealDatasetVectorIndexTask: mock_processor.load.assert_not_called() def test_deal_dataset_vector_index_task_update_action_no_documents( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test update action when no documents exist for the dataset. @@ -480,7 +481,7 @@ class TestDealDatasetVectorIndexTask: mock_processor.load.assert_not_called() def test_deal_dataset_vector_index_task_add_action_with_exception_handling( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test add action with exception handling during processing. @@ -578,7 +579,7 @@ class TestDealDatasetVectorIndexTask: assert "Test exception during indexing" in updated_document.error def test_deal_dataset_vector_index_task_with_custom_index_type( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test task behavior with custom index type (QA_INDEX). @@ -656,7 +657,7 @@ class TestDealDatasetVectorIndexTask: mock_processor.load.assert_called_once() def test_deal_dataset_vector_index_task_with_default_index_type( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test task behavior with default index type (PARAGRAPH_INDEX). @@ -734,7 +735,7 @@ class TestDealDatasetVectorIndexTask: mock_processor.load.assert_called_once() def test_deal_dataset_vector_index_task_multiple_documents_processing( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test task processing with multiple documents and segments. @@ -839,7 +840,7 @@ class TestDealDatasetVectorIndexTask: assert mock_processor.load.call_count == 3 def test_deal_dataset_vector_index_task_document_status_transitions( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test document status transitions during task execution. @@ -938,7 +939,7 @@ class TestDealDatasetVectorIndexTask: assert updated_document.indexing_status == IndexingStatus.COMPLETED def test_deal_dataset_vector_index_task_with_disabled_documents( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test task behavior with disabled documents. @@ -1061,7 +1062,7 @@ class TestDealDatasetVectorIndexTask: mock_processor.load.assert_called_once() def test_deal_dataset_vector_index_task_with_archived_documents( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test task behavior with archived documents. @@ -1184,7 +1185,7 @@ class TestDealDatasetVectorIndexTask: mock_processor.load.assert_called_once() def test_deal_dataset_vector_index_task_with_incomplete_documents( - self, db_session_with_containers, mock_index_processor_factory, account_and_tenant + self, db_session_with_containers: Session, mock_index_processor_factory, account_and_tenant ): """ Test task behavior with documents that have incomplete indexing status. diff --git a/api/tests/test_containers_integration_tests/tasks/test_delete_segment_from_index_task.py b/api/tests/test_containers_integration_tests/tasks/test_delete_segment_from_index_task.py index 8a69707b38..f4a71040c1 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_delete_segment_from_index_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_delete_segment_from_index_task.py @@ -11,9 +11,19 @@ import logging from unittest.mock import MagicMock, patch from faker import Faker +from sqlalchemy.orm import Session from core.rag.index_processor.constant.index_type import IndexStructureType, IndexTechniqueType -from models import Account, Dataset, Document, DocumentSegment, Tenant +from models import ( + Account, + AccountStatus, + Dataset, + DatasetPermissionEnum, + Document, + DocumentSegment, + Tenant, + TenantStatus, +) from models.enums import DataSourceType, DocumentCreatedFrom, DocumentDocType, IndexingStatus, SegmentStatus from tasks.delete_segment_from_index_task import delete_segment_from_index_task @@ -37,7 +47,7 @@ class TestDeleteSegmentFromIndexTask: and realistic testing environment with actual database interactions. """ - def _create_test_tenant(self, db_session_with_containers, fake=None): + def _create_test_tenant(self, db_session_with_containers: Session, fake: Faker | None = None): """ Helper method to create a test tenant with realistic data. @@ -49,7 +59,7 @@ class TestDeleteSegmentFromIndexTask: Tenant: Created test tenant instance """ fake = fake or Faker() - tenant = Tenant(name=f"Test Tenant {fake.company()}", plan="basic", status="normal") + tenant = Tenant(name=f"Test Tenant {fake.company()}", plan="basic", status=TenantStatus.NORMAL) tenant.id = fake.uuid4() tenant.created_at = fake.date_time_this_year() tenant.updated_at = tenant.created_at @@ -58,7 +68,7 @@ class TestDeleteSegmentFromIndexTask: db_session_with_containers.commit() return tenant - def _create_test_account(self, db_session_with_containers, tenant, fake=None): + def _create_test_account(self, db_session_with_containers: Session, tenant, fake: Faker | None = None): """ Helper method to create a test account with realistic data. @@ -75,7 +85,7 @@ class TestDeleteSegmentFromIndexTask: name=fake.name(), email=fake.email(), avatar=fake.url(), - status="active", + status=AccountStatus.ACTIVE, interface_language="en-US", ) account.id = fake.uuid4() @@ -86,7 +96,9 @@ class TestDeleteSegmentFromIndexTask: db_session_with_containers.commit() return account - def _create_test_dataset(self, db_session_with_containers, tenant, account, fake=None): + def _create_test_dataset( + self, db_session_with_containers: Session, tenant: Tenant, account: Account, fake: Faker | None = None + ): """ Helper method to create a test dataset with realistic data. @@ -106,7 +118,7 @@ class TestDeleteSegmentFromIndexTask: dataset.name = f"Test Dataset {fake.word()}" dataset.description = fake.text(max_nb_chars=200) dataset.provider = "vendor" - dataset.permission = "only_me" + dataset.permission = DatasetPermissionEnum.ONLY_ME dataset.data_source_type = DataSourceType.UPLOAD_FILE dataset.indexing_technique = IndexTechniqueType.HIGH_QUALITY dataset.index_struct = '{"type": "paragraph"}' @@ -122,7 +134,7 @@ class TestDeleteSegmentFromIndexTask: db_session_with_containers.commit() return dataset - def _create_test_document(self, db_session_with_containers, dataset, account, fake=None, **kwargs): + def _create_test_document(self, db_session_with_containers: Session, dataset, account, fake=None, **kwargs): """ Helper method to create a test document with realistic data. @@ -172,7 +184,14 @@ class TestDeleteSegmentFromIndexTask: db_session_with_containers.commit() return document - def _create_test_document_segments(self, db_session_with_containers, document, account, count=3, fake=None): + def _create_test_document_segments( + self, + db_session_with_containers: Session, + document: Document, + account: Account, + count: int = 3, + fake: Faker | None = None, + ): """ Helper method to create test document segments with realistic data. @@ -218,7 +237,9 @@ class TestDeleteSegmentFromIndexTask: return segments @patch("tasks.delete_segment_from_index_task.IndexProcessorFactory", autospec=True) - def test_delete_segment_from_index_task_success(self, mock_index_processor_factory, db_session_with_containers): + def test_delete_segment_from_index_task_success( + self, mock_index_processor_factory, db_session_with_containers: Session + ): """ Test successful segment deletion from index with comprehensive verification. @@ -267,7 +288,7 @@ class TestDeleteSegmentFromIndexTask: assert call_args[1]["with_keywords"] is True assert call_args[1]["delete_child_chunks"] is True - def test_delete_segment_from_index_task_dataset_not_found(self, db_session_with_containers): + def test_delete_segment_from_index_task_dataset_not_found(self, db_session_with_containers: Session): """ Test task behavior when dataset is not found. @@ -288,7 +309,7 @@ class TestDeleteSegmentFromIndexTask: # Verify the task completed without exceptions assert result is None # Task should return None when dataset not found - def test_delete_segment_from_index_task_document_not_found(self, db_session_with_containers): + def test_delete_segment_from_index_task_document_not_found(self, db_session_with_containers: Session): """ Test task behavior when document is not found. @@ -314,7 +335,7 @@ class TestDeleteSegmentFromIndexTask: # Verify the task completed without exceptions assert result is None # Task should return None when document not found - def test_delete_segment_from_index_task_document_disabled(self, db_session_with_containers): + def test_delete_segment_from_index_task_document_disabled(self, db_session_with_containers: Session): """ Test task behavior when document is disabled. @@ -342,7 +363,7 @@ class TestDeleteSegmentFromIndexTask: # Verify the task completed without exceptions assert result is None # Task should return None when document is disabled - def test_delete_segment_from_index_task_document_archived(self, db_session_with_containers): + def test_delete_segment_from_index_task_document_archived(self, db_session_with_containers: Session): """ Test task behavior when document is archived. @@ -370,7 +391,7 @@ class TestDeleteSegmentFromIndexTask: # Verify the task completed without exceptions assert result is None # Task should return None when document is archived - def test_delete_segment_from_index_task_document_not_completed(self, db_session_with_containers): + def test_delete_segment_from_index_task_document_not_completed(self, db_session_with_containers: Session): """ Test task behavior when document indexing is not completed. diff --git a/api/tests/test_containers_integration_tests/tasks/test_disable_segments_from_index_task.py b/api/tests/test_containers_integration_tests/tasks/test_disable_segments_from_index_task.py index 6e03bd9351..6bfb1e1f1e 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_disable_segments_from_index_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_disable_segments_from_index_task.py @@ -13,7 +13,7 @@ from sqlalchemy import select from sqlalchemy.orm import Session from core.rag.index_processor.constant.index_type import IndexStructureType, IndexTechniqueType -from models import Account, Dataset, DocumentSegment +from models import Account, AccountStatus, Dataset, DocumentSegment, TenantAccountRole, TenantStatus from models import Document as DatasetDocument from models.dataset import DatasetProcessRule from models.enums import DataSourceType, DocumentCreatedFrom, ProcessRuleMode, SegmentStatus @@ -35,7 +35,7 @@ class TestDisableSegmentsFromIndexTask: and realistic testing environment with actual database interactions. """ - def _create_test_account(self, db_session_with_containers: Session, fake=None): + def _create_test_account(self, db_session_with_containers: Session, fake: Faker | None = None): """ Helper method to create a test account with realistic data. @@ -51,24 +51,23 @@ class TestDisableSegmentsFromIndexTask: email=fake.email(), name=fake.name(), avatar=fake.url(), - status="active", + status=AccountStatus.ACTIVE, interface_language="en-US", ) - account.id = fake.uuid4() # monkey-patch attributes for test setup + account.updated_at = fake.date_time_this_year() + account.created_at = fake.date_time_this_year() + account.role = TenantAccountRole.OWNER + account.id = fake.uuid4() account.tenant_id = fake.uuid4() account.type = "normal" - account.role = "owner" - account.created_at = fake.date_time_this_year() - account.updated_at = account.created_at - # Create a tenant for the account from models.account import Tenant tenant = Tenant( name=f"Test Tenant {fake.company()}", plan="basic", - status="normal", + status=TenantStatus.NORMAL, ) tenant.id = account.tenant_id tenant.created_at = fake.date_time_this_year() @@ -83,7 +82,7 @@ class TestDisableSegmentsFromIndexTask: return account - def _create_test_dataset(self, db_session_with_containers: Session, account, fake=None): + def _create_test_dataset(self, db_session_with_containers: Session, account, fake: Faker | None = None): """ Helper method to create a test dataset with realistic data. @@ -117,7 +116,9 @@ class TestDisableSegmentsFromIndexTask: return dataset - def _create_test_document(self, db_session_with_containers: Session, dataset, account, fake=None): + def _create_test_document( + self, db_session_with_containers: Session, dataset, account: Account, fake: Faker | None = None + ): """ Helper method to create a test document with realistic data. @@ -216,7 +217,7 @@ class TestDisableSegmentsFromIndexTask: return segments - def _create_dataset_process_rule(self, db_session_with_containers: Session, dataset, fake=None): + def _create_dataset_process_rule(self, db_session_with_containers: Session, dataset, fake: Faker | None = None): """ Helper method to create a dataset process rule. diff --git a/api/tests/test_containers_integration_tests/tasks/test_document_indexing_sync_task.py b/api/tests/test_containers_integration_tests/tasks/test_document_indexing_sync_task.py index b6e7e6e5c9..77cd259833 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_document_indexing_sync_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_document_indexing_sync_task.py @@ -13,6 +13,7 @@ from uuid import uuid4 import pytest from sqlalchemy import delete, func, select, update +from sqlalchemy.orm import Session from core.indexing_runner import DocumentIsPausedError, IndexingRunner from core.rag.index_processor.constant.index_type import IndexStructureType, IndexTechniqueType @@ -162,7 +163,7 @@ class TestDocumentIndexingSyncTask: "indexing_runner": indexing_runner, } - def _create_notion_sync_context(self, db_session_with_containers, *, data_source_info: dict | None = None): + def _create_notion_sync_context(self, db_session_with_containers: Session, *, data_source_info: dict | None = None): account, tenant = DocumentIndexingSyncTaskTestDataFactory.create_account_with_tenant(db_session_with_containers) dataset = DocumentIndexingSyncTaskTestDataFactory.create_dataset( db_session_with_containers, @@ -206,7 +207,7 @@ class TestDocumentIndexingSyncTask: "notion_info": notion_info, } - def test_document_not_found(self, db_session_with_containers, mock_external_dependencies): + def test_document_not_found(self, db_session_with_containers: Session, mock_external_dependencies): """Test that task handles missing document gracefully.""" # Arrange dataset_id = str(uuid4()) @@ -219,7 +220,7 @@ class TestDocumentIndexingSyncTask: mock_external_dependencies["datasource_service"].get_datasource_credentials.assert_not_called() mock_external_dependencies["indexing_runner"].run.assert_not_called() - def test_missing_notion_workspace_id(self, db_session_with_containers, mock_external_dependencies): + def test_missing_notion_workspace_id(self, db_session_with_containers: Session, mock_external_dependencies): """Test that task raises error when notion_workspace_id is missing.""" # Arrange context = self._create_notion_sync_context( @@ -235,7 +236,7 @@ class TestDocumentIndexingSyncTask: with pytest.raises(ValueError, match="no notion page found"): document_indexing_sync_task(context["dataset"].id, context["document"].id) - def test_missing_notion_page_id(self, db_session_with_containers, mock_external_dependencies): + def test_missing_notion_page_id(self, db_session_with_containers: Session, mock_external_dependencies): """Test that task raises error when notion_page_id is missing.""" # Arrange context = self._create_notion_sync_context( @@ -251,7 +252,7 @@ class TestDocumentIndexingSyncTask: with pytest.raises(ValueError, match="no notion page found"): document_indexing_sync_task(context["dataset"].id, context["document"].id) - def test_empty_data_source_info(self, db_session_with_containers, mock_external_dependencies): + def test_empty_data_source_info(self, db_session_with_containers: Session, mock_external_dependencies): """Test that task raises error when data_source_info is empty.""" # Arrange context = self._create_notion_sync_context(db_session_with_containers, data_source_info=None) @@ -264,7 +265,7 @@ class TestDocumentIndexingSyncTask: with pytest.raises(ValueError, match="no notion page found"): document_indexing_sync_task(context["dataset"].id, context["document"].id) - def test_credential_not_found(self, db_session_with_containers, mock_external_dependencies): + def test_credential_not_found(self, db_session_with_containers: Session, mock_external_dependencies): """Test that task sets document error state when credential is missing.""" # Arrange context = self._create_notion_sync_context(db_session_with_containers) @@ -284,7 +285,7 @@ class TestDocumentIndexingSyncTask: assert updated_document.stopped_at is not None mock_external_dependencies["indexing_runner"].run.assert_not_called() - def test_page_not_updated(self, db_session_with_containers, mock_external_dependencies): + def test_page_not_updated(self, db_session_with_containers: Session, mock_external_dependencies): """Test that task exits early when notion page is unchanged.""" # Arrange context = self._create_notion_sync_context(db_session_with_containers) @@ -310,7 +311,7 @@ class TestDocumentIndexingSyncTask: mock_external_dependencies["index_processor"].clean.assert_not_called() mock_external_dependencies["indexing_runner"].run.assert_not_called() - def test_successful_sync_when_page_updated(self, db_session_with_containers, mock_external_dependencies): + def test_successful_sync_when_page_updated(self, db_session_with_containers: Session, mock_external_dependencies): """Test full successful sync flow with SQL state updates and side effects.""" # Arrange context = self._create_notion_sync_context(db_session_with_containers) @@ -349,7 +350,7 @@ class TestDocumentIndexingSyncTask: assert len(run_documents) == 1 assert getattr(run_documents[0], "id", None) == context["document"].id - def test_dataset_not_found_during_cleaning(self, db_session_with_containers, mock_external_dependencies): + def test_dataset_not_found_during_cleaning(self, db_session_with_containers: Session, mock_external_dependencies): """Test that task still updates document and reindexes if dataset vanishes before clean.""" # Arrange context = self._create_notion_sync_context(db_session_with_containers) @@ -376,7 +377,9 @@ class TestDocumentIndexingSyncTask: mock_external_dependencies["index_processor"].clean.assert_not_called() mock_external_dependencies["indexing_runner"].run.assert_called_once() - def test_cleaning_error_continues_to_indexing(self, db_session_with_containers, mock_external_dependencies): + def test_cleaning_error_continues_to_indexing( + self, db_session_with_containers: Session, mock_external_dependencies + ): """Test that indexing continues when index cleanup fails.""" # Arrange context = self._create_notion_sync_context(db_session_with_containers) @@ -400,7 +403,9 @@ class TestDocumentIndexingSyncTask: assert remaining_segments == 0 mock_external_dependencies["indexing_runner"].run.assert_called_once() - def test_indexing_runner_document_paused_error(self, db_session_with_containers, mock_external_dependencies): + def test_indexing_runner_document_paused_error( + self, db_session_with_containers: Session, mock_external_dependencies + ): """Test that DocumentIsPausedError does not flip document into error state.""" # Arrange context = self._create_notion_sync_context(db_session_with_containers) @@ -418,7 +423,7 @@ class TestDocumentIndexingSyncTask: assert updated_document.indexing_status == IndexingStatus.PARSING assert updated_document.error is None - def test_indexing_runner_general_error(self, db_session_with_containers, mock_external_dependencies): + def test_indexing_runner_general_error(self, db_session_with_containers: Session, mock_external_dependencies): """Test that indexing errors are persisted to document state.""" # Arrange context = self._create_notion_sync_context(db_session_with_containers) diff --git a/api/tests/test_containers_integration_tests/tasks/test_document_indexing_task.py b/api/tests/test_containers_integration_tests/tasks/test_document_indexing_task.py index cf1a8666f3..6c1454b6d8 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_document_indexing_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_document_indexing_task.py @@ -3,11 +3,12 @@ from unittest.mock import MagicMock, patch import pytest from faker import Faker +from sqlalchemy.orm import Session from core.entities.document_task import DocumentTask from core.rag.index_processor.constant.index_type import IndexTechniqueType from enums.cloud_plan import CloudPlan -from models import Account, Tenant, TenantAccountJoin, TenantAccountRole +from models import Account, AccountStatus, Tenant, TenantAccountJoin, TenantAccountRole, TenantStatus from models.dataset import Dataset, Document from models.enums import DataSourceType, DocumentCreatedFrom, IndexingStatus from tasks.document_indexing_task import ( @@ -51,7 +52,7 @@ class TestDocumentIndexingTasks: } def _create_test_dataset_and_documents( - self, db_session_with_containers, mock_external_service_dependencies, document_count=3 + self, db_session_with_containers: Session, mock_external_service_dependencies, document_count=3 ): """ Helper method to create a test dataset and documents for testing. @@ -71,14 +72,14 @@ class TestDocumentIndexingTasks: email=fake.email(), name=fake.name(), interface_language="en-US", - status="active", + status=AccountStatus.ACTIVE, ) db_session_with_containers.add(account) db_session_with_containers.commit() tenant = Tenant( name=fake.company(), - status="normal", + status=TenantStatus.NORMAL, ) db_session_with_containers.add(tenant) db_session_with_containers.commit() @@ -133,7 +134,7 @@ class TestDocumentIndexingTasks: return dataset, documents def _create_test_dataset_with_billing_features( - self, db_session_with_containers, mock_external_service_dependencies, billing_enabled=True + self, db_session_with_containers: Session, mock_external_service_dependencies, billing_enabled=True ): """ Helper method to create a test dataset with billing features configured. @@ -153,14 +154,14 @@ class TestDocumentIndexingTasks: email=fake.email(), name=fake.name(), interface_language="en-US", - status="active", + status=AccountStatus.ACTIVE, ) db_session_with_containers.add(account) db_session_with_containers.commit() tenant = Tenant( name=fake.company(), - status="normal", + status=TenantStatus.NORMAL, ) db_session_with_containers.add(tenant) db_session_with_containers.commit() @@ -221,7 +222,9 @@ class TestDocumentIndexingTasks: return dataset, documents - def test_document_indexing_task_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_document_indexing_task_success( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test successful document indexing with multiple documents. @@ -262,7 +265,7 @@ class TestDocumentIndexingTasks: assert len(processed_documents) == 3 def test_document_indexing_task_dataset_not_found( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling of non-existent dataset. @@ -286,7 +289,7 @@ class TestDocumentIndexingTasks: mock_external_service_dependencies["indexing_runner_instance"].run.assert_not_called() def test_document_indexing_task_document_not_found_in_dataset( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling when some documents don't exist in the dataset. @@ -332,7 +335,7 @@ class TestDocumentIndexingTasks: assert len(processed_documents) == 2 # Only existing documents def test_document_indexing_task_indexing_runner_exception( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling of IndexingRunner exceptions. @@ -373,7 +376,7 @@ class TestDocumentIndexingTasks: assert updated_document.processing_started_at is not None def test_document_indexing_task_mixed_document_states( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test processing documents with mixed initial states. @@ -456,7 +459,7 @@ class TestDocumentIndexingTasks: assert len(processed_documents) == 4 def test_document_indexing_task_billing_sandbox_plan_batch_limit( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test billing validation for sandbox plan batch upload limit. @@ -518,7 +521,7 @@ class TestDocumentIndexingTasks: mock_external_service_dependencies["indexing_runner"].assert_not_called() def test_document_indexing_task_billing_disabled_success( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test successful processing when billing is disabled. @@ -554,7 +557,7 @@ class TestDocumentIndexingTasks: assert updated_document.processing_started_at is not None def test_document_indexing_task_document_is_paused_error( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling of DocumentIsPausedError from IndexingRunner. @@ -597,7 +600,9 @@ class TestDocumentIndexingTasks: assert updated_document.processing_started_at is not None # ==================== NEW TESTS FOR REFACTORED FUNCTIONS ==================== - def test_old_document_indexing_task_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_old_document_indexing_task_success( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test document_indexing_task basic functionality. @@ -619,7 +624,7 @@ class TestDocumentIndexingTasks: mock_external_service_dependencies["indexing_runner_instance"].run.assert_called_once() def test_normal_document_indexing_task_success( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test normal_document_indexing_task basic functionality. @@ -643,7 +648,7 @@ class TestDocumentIndexingTasks: mock_external_service_dependencies["indexing_runner_instance"].run.assert_called_once() def test_priority_document_indexing_task_success( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test priority_document_indexing_task basic functionality. @@ -667,7 +672,7 @@ class TestDocumentIndexingTasks: mock_external_service_dependencies["indexing_runner_instance"].run.assert_called_once() def test_document_indexing_with_tenant_queue_success( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test _document_indexing_with_tenant_queue function with no waiting tasks. @@ -717,7 +722,7 @@ class TestDocumentIndexingTasks: mock_task_func.delay.assert_not_called() def test_document_indexing_with_tenant_queue_with_waiting_tasks( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test _document_indexing_with_tenant_queue function with waiting tasks in queue using real Redis. @@ -776,7 +781,7 @@ class TestDocumentIndexingTasks: assert len(remaining_tasks) == 1 def test_document_indexing_with_tenant_queue_error_handling( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test error handling in _document_indexing_with_tenant_queue using real Redis. @@ -848,7 +853,7 @@ class TestDocumentIndexingTasks: assert len(remaining_tasks) == 0 def test_document_indexing_with_tenant_queue_tenant_isolation( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test tenant isolation in _document_indexing_with_tenant_queue using real Redis. diff --git a/api/tests/test_containers_integration_tests/tasks/test_document_indexing_update_task.py b/api/tests/test_containers_integration_tests/tasks/test_document_indexing_update_task.py index a9a8c0f30c..208fc1aa1d 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_document_indexing_update_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_document_indexing_update_task.py @@ -3,9 +3,10 @@ from unittest.mock import MagicMock, patch import pytest from faker import Faker from sqlalchemy import func, select +from sqlalchemy.orm import Session from core.rag.index_processor.constant.index_type import IndexStructureType, IndexTechniqueType -from models import Account, Tenant, TenantAccountJoin, TenantAccountRole +from models import Account, AccountStatus, Tenant, TenantAccountJoin, TenantAccountRole, TenantStatus from models.dataset import Dataset, Document, DocumentSegment from models.enums import DataSourceType, DocumentCreatedFrom, IndexingStatus, SegmentStatus from tasks.document_indexing_update_task import document_indexing_update_task @@ -33,7 +34,7 @@ class TestDocumentIndexingUpdateTask: "runner_instance": runner_instance, } - def _create_dataset_document_with_segments(self, db_session_with_containers, *, segment_count: int = 2): + def _create_dataset_document_with_segments(self, db_session_with_containers: Session, *, segment_count: int = 2): fake = Faker() # Account and tenant @@ -41,12 +42,12 @@ class TestDocumentIndexingUpdateTask: email=fake.email(), name=fake.name(), interface_language="en-US", - status="active", + status=AccountStatus.ACTIVE, ) db_session_with_containers.add(account) db_session_with_containers.commit() - tenant = Tenant(name=fake.company(), status="normal") + tenant = Tenant(name=fake.company(), status=TenantStatus.NORMAL) db_session_with_containers.add(tenant) db_session_with_containers.commit() @@ -114,7 +115,7 @@ class TestDocumentIndexingUpdateTask: return dataset, document, node_ids - def test_cleans_segments_and_reindexes(self, db_session_with_containers, mock_external_dependencies): + def test_cleans_segments_and_reindexes(self, db_session_with_containers: Session, mock_external_dependencies): dataset, document, node_ids = self._create_dataset_document_with_segments(db_session_with_containers) # Act @@ -153,7 +154,9 @@ class TestDocumentIndexingUpdateTask: first = run_docs[0] assert getattr(first, "id", None) == document.id - def test_clean_error_is_logged_and_indexing_continues(self, db_session_with_containers, mock_external_dependencies): + def test_clean_error_is_logged_and_indexing_continues( + self, db_session_with_containers: Session, mock_external_dependencies + ): dataset, document, node_ids = self._create_dataset_document_with_segments(db_session_with_containers) # Force clean to raise; task should continue to indexing @@ -173,7 +176,7 @@ class TestDocumentIndexingUpdateTask: ) assert remaining > 0 - def test_document_not_found_noop(self, db_session_with_containers, mock_external_dependencies): + def test_document_not_found_noop(self, db_session_with_containers: Session, mock_external_dependencies): fake = Faker() # Act with non-existent document id document_indexing_update_task(dataset_id=fake.uuid4(), document_id=fake.uuid4()) diff --git a/api/tests/test_containers_integration_tests/tasks/test_duplicate_document_indexing_task.py b/api/tests/test_containers_integration_tests/tasks/test_duplicate_document_indexing_task.py index 39c58987fd..12440f3e6b 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_duplicate_document_indexing_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_duplicate_document_indexing_task.py @@ -3,6 +3,7 @@ from unittest.mock import MagicMock, patch import pytest from faker import Faker from sqlalchemy import select +from sqlalchemy.orm import Session from core.indexing_runner import DocumentIsPausedError from core.rag.index_processor.constant.index_type import IndexStructureType, IndexTechniqueType @@ -62,7 +63,7 @@ class TestDuplicateDocumentIndexingTasks: } def _create_test_dataset_and_documents( - self, db_session_with_containers, mock_external_service_dependencies, document_count=3 + self, db_session_with_containers: Session, mock_external_service_dependencies, document_count=3 ): """ Helper method to create a test dataset and documents for testing. @@ -145,7 +146,11 @@ class TestDuplicateDocumentIndexingTasks: return dataset, documents def _create_test_dataset_with_segments( - self, db_session_with_containers, mock_external_service_dependencies, document_count=3, segments_per_doc=2 + self, + db_session_with_containers: Session, + mock_external_service_dependencies, + document_count=3, + segments_per_doc=2, ): """ Helper method to create a test dataset with documents and segments. @@ -197,7 +202,7 @@ class TestDuplicateDocumentIndexingTasks: return dataset, documents, segments def _create_test_dataset_with_billing_features( - self, db_session_with_containers, mock_external_service_dependencies, billing_enabled=True + self, db_session_with_containers: Session, mock_external_service_dependencies, billing_enabled=True ): """ Helper method to create a test dataset with billing features configured. @@ -287,7 +292,7 @@ class TestDuplicateDocumentIndexingTasks: return dataset, documents def _test_duplicate_document_indexing_task_success( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test successful duplicate document indexing with multiple documents. @@ -329,7 +334,7 @@ class TestDuplicateDocumentIndexingTasks: assert len(processed_documents) == 3 def _test_duplicate_document_indexing_task_with_segment_cleanup( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test duplicate document indexing with existing segments that need cleanup. @@ -379,7 +384,7 @@ class TestDuplicateDocumentIndexingTasks: mock_external_service_dependencies["indexing_runner_instance"].run.assert_called_once() def _test_duplicate_document_indexing_task_dataset_not_found( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling of non-existent dataset. @@ -404,7 +409,7 @@ class TestDuplicateDocumentIndexingTasks: mock_external_service_dependencies["index_processor"].clean.assert_not_called() def test_duplicate_document_indexing_task_document_not_found_in_dataset( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling when some documents don't exist in the dataset. @@ -450,7 +455,7 @@ class TestDuplicateDocumentIndexingTasks: assert len(processed_documents) == 2 # Only existing documents def _test_duplicate_document_indexing_task_indexing_runner_exception( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling of IndexingRunner exceptions. @@ -491,7 +496,7 @@ class TestDuplicateDocumentIndexingTasks: assert updated_document.processing_started_at is not None def _test_duplicate_document_indexing_task_billing_sandbox_plan_batch_limit( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test billing validation for sandbox plan batch upload limit. @@ -554,7 +559,7 @@ class TestDuplicateDocumentIndexingTasks: mock_external_service_dependencies["indexing_runner_instance"].run.assert_not_called() def _test_duplicate_document_indexing_task_billing_vector_space_limit_exceeded( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test billing validation for vector space limit. @@ -596,7 +601,7 @@ class TestDuplicateDocumentIndexingTasks: mock_external_service_dependencies["indexing_runner_instance"].run.assert_not_called() def test_duplicate_document_indexing_task_with_empty_document_list( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test handling of empty document list. @@ -622,7 +627,7 @@ class TestDuplicateDocumentIndexingTasks: mock_external_service_dependencies["indexing_runner_instance"].run.assert_called_once_with([]) def test_deprecated_duplicate_document_indexing_task_delegates_to_core( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test that deprecated duplicate_document_indexing_task delegates to core function. @@ -655,7 +660,7 @@ class TestDuplicateDocumentIndexingTasks: @patch("tasks.duplicate_document_indexing_task.TenantIsolatedTaskQueue", autospec=True) def test_normal_duplicate_document_indexing_task_with_tenant_queue( - self, mock_queue_class, db_session_with_containers, mock_external_service_dependencies + self, mock_queue_class, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test normal_duplicate_document_indexing_task with tenant isolation queue. @@ -698,7 +703,7 @@ class TestDuplicateDocumentIndexingTasks: @patch("tasks.duplicate_document_indexing_task.TenantIsolatedTaskQueue", autospec=True) def test_priority_duplicate_document_indexing_task_with_tenant_queue( - self, mock_queue_class, db_session_with_containers, mock_external_service_dependencies + self, mock_queue_class, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test priority_duplicate_document_indexing_task with tenant isolation queue. @@ -742,7 +747,7 @@ class TestDuplicateDocumentIndexingTasks: @patch("tasks.duplicate_document_indexing_task.TenantIsolatedTaskQueue", autospec=True) def test_tenant_queue_wrapper_processes_next_tasks( - self, mock_queue_class, db_session_with_containers, mock_external_service_dependencies + self, mock_queue_class, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test tenant queue wrapper processes next queued tasks. @@ -789,7 +794,7 @@ class TestDuplicateDocumentIndexingTasks: mock_queue.delete_task_key.assert_not_called() def test_successful_duplicate_document_indexing( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """Test successful duplicate document indexing flow.""" self._test_duplicate_document_indexing_task_success( @@ -797,7 +802,7 @@ class TestDuplicateDocumentIndexingTasks: ) def test_duplicate_document_indexing_dataset_not_found( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """Test duplicate document indexing when dataset is not found.""" self._test_duplicate_document_indexing_task_dataset_not_found( @@ -805,7 +810,7 @@ class TestDuplicateDocumentIndexingTasks: ) def test_duplicate_document_indexing_with_billing_enabled_sandbox_plan( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """Test duplicate document indexing with billing enabled and sandbox plan.""" self._test_duplicate_document_indexing_task_billing_sandbox_plan_batch_limit( @@ -813,7 +818,7 @@ class TestDuplicateDocumentIndexingTasks: ) def test_duplicate_document_indexing_with_billing_limit_exceeded( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """Test duplicate document indexing when billing limit is exceeded.""" self._test_duplicate_document_indexing_task_billing_vector_space_limit_exceeded( @@ -821,7 +826,7 @@ class TestDuplicateDocumentIndexingTasks: ) def test_duplicate_document_indexing_runner_error( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """Test duplicate document indexing when IndexingRunner raises an error.""" self._test_duplicate_document_indexing_task_indexing_runner_exception( @@ -829,7 +834,7 @@ class TestDuplicateDocumentIndexingTasks: ) def _test_duplicate_document_indexing_task_document_is_paused( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """Test duplicate document indexing when document is paused.""" # Arrange @@ -860,7 +865,7 @@ class TestDuplicateDocumentIndexingTasks: mock_external_service_dependencies["indexing_runner_instance"].run.assert_called_once() def test_duplicate_document_indexing_document_is_paused( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """Test duplicate document indexing when document is paused.""" self._test_duplicate_document_indexing_task_document_is_paused( @@ -868,7 +873,7 @@ class TestDuplicateDocumentIndexingTasks: ) def test_duplicate_document_indexing_cleans_old_segments( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """Test that duplicate document indexing cleans old segments.""" self._test_duplicate_document_indexing_task_with_segment_cleanup( diff --git a/api/tests/test_containers_integration_tests/tasks/test_mail_change_mail_task.py b/api/tests/test_containers_integration_tests/tasks/test_mail_change_mail_task.py index 177af266fb..a697878bb6 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_mail_change_mail_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_mail_change_mail_task.py @@ -2,6 +2,7 @@ from unittest.mock import patch import pytest from faker import Faker +from sqlalchemy.orm import Session from libs.email_i18n import EmailType from models.account import Account, Tenant, TenantAccountJoin, TenantAccountRole @@ -29,7 +30,7 @@ class TestMailChangeMailTask: "get_email_i18n_service": mock_get_email_i18n_service, } - def _create_test_account(self, db_session_with_containers): + def _create_test_account(self, db_session_with_containers: Session): """ Helper method to create a test account for testing. @@ -72,7 +73,7 @@ class TestMailChangeMailTask: return account def test_send_change_mail_task_success_old_email_phase( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test successful change email task execution for old_email phase. @@ -103,7 +104,7 @@ class TestMailChangeMailTask: ) def test_send_change_mail_task_success_new_email_phase( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test successful change email task execution for new_email phase. @@ -134,7 +135,7 @@ class TestMailChangeMailTask: ) def test_send_change_mail_task_mail_not_initialized( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test change email task when mail service is not initialized. @@ -159,7 +160,7 @@ class TestMailChangeMailTask: mock_external_service_dependencies["email_i18n_service"].send_change_email.assert_not_called() def test_send_change_mail_task_email_service_exception( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test change email task when email service raises an exception. @@ -191,7 +192,7 @@ class TestMailChangeMailTask: ) def test_send_change_mail_completed_notification_task_success( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test successful change email completed notification task execution. @@ -224,7 +225,7 @@ class TestMailChangeMailTask: ) def test_send_change_mail_completed_notification_task_mail_not_initialized( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test change email completed notification task when mail service is not initialized. @@ -247,7 +248,7 @@ class TestMailChangeMailTask: mock_external_service_dependencies["email_i18n_service"].send_email.assert_not_called() def test_send_change_mail_completed_notification_task_email_service_exception( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test change email completed notification task when email service raises an exception. diff --git a/api/tests/test_containers_integration_tests/tasks/test_mail_email_code_login_task.py b/api/tests/test_containers_integration_tests/tasks/test_mail_email_code_login_task.py index 8343711998..8e9da6aaaa 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_mail_email_code_login_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_mail_email_code_login_task.py @@ -15,6 +15,7 @@ from unittest.mock import MagicMock, patch import pytest from faker import Faker from sqlalchemy import delete +from sqlalchemy.orm import Session from libs.email_i18n import EmailType from models.account import Account, Tenant, TenantAccountJoin, TenantAccountRole @@ -37,7 +38,7 @@ class TestSendEmailCodeLoginMailTask: """ @pytest.fixture(autouse=True) - def cleanup_database(self, db_session_with_containers): + def cleanup_database(self, db_session_with_containers: Session): """Clean up database before each test to ensure isolation.""" from extensions.ext_redis import redis_client @@ -71,7 +72,7 @@ class TestSendEmailCodeLoginMailTask: "email_service_instance": mock_email_service_instance, } - def _create_test_account(self, db_session_with_containers, fake=None): + def _create_test_account(self, db_session_with_containers: Session, fake: Faker | None = None): """ Helper method to create a test account for testing. @@ -98,7 +99,7 @@ class TestSendEmailCodeLoginMailTask: return account - def _create_test_tenant_and_account(self, db_session_with_containers, fake=None): + def _create_test_tenant_and_account(self, db_session_with_containers: Session, fake: Faker | None = None): """ Helper method to create a test tenant and account for testing. @@ -138,7 +139,7 @@ class TestSendEmailCodeLoginMailTask: return account, tenant def test_send_email_code_login_mail_task_success_english( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test successful email code login mail sending in English. @@ -182,7 +183,7 @@ class TestSendEmailCodeLoginMailTask: ) def test_send_email_code_login_mail_task_success_chinese( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test successful email code login mail sending in Chinese. @@ -221,7 +222,7 @@ class TestSendEmailCodeLoginMailTask: ) def test_send_email_code_login_mail_task_success_multiple_languages( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test successful email code login mail sending with multiple languages. @@ -261,7 +262,7 @@ class TestSendEmailCodeLoginMailTask: assert call_args[1]["template_context"]["code"] == test_codes[i] def test_send_email_code_login_mail_task_mail_not_initialized( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test email code login mail task when mail service is not initialized. @@ -299,7 +300,7 @@ class TestSendEmailCodeLoginMailTask: mock_email_service_instance.send_email.assert_not_called() def test_send_email_code_login_mail_task_email_service_exception( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test email code login mail task when email service raises an exception. @@ -346,7 +347,7 @@ class TestSendEmailCodeLoginMailTask: ) def test_send_email_code_login_mail_task_invalid_parameters( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test email code login mail task with invalid parameters. @@ -388,7 +389,7 @@ class TestSendEmailCodeLoginMailTask: mock_email_service_instance.send_email.assert_called_once() def test_send_email_code_login_mail_task_edge_cases( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test email code login mail task with edge cases and boundary conditions. @@ -451,7 +452,7 @@ class TestSendEmailCodeLoginMailTask: ) def test_send_email_code_login_mail_task_database_integration( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test email code login mail task with database integration. @@ -497,7 +498,7 @@ class TestSendEmailCodeLoginMailTask: assert account.status == "active" def test_send_email_code_login_mail_task_redis_integration( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test email code login mail task with Redis integration. @@ -541,7 +542,7 @@ class TestSendEmailCodeLoginMailTask: redis_client.delete(cache_key) def test_send_email_code_login_mail_task_error_handling_comprehensive( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test comprehensive error handling for email code login mail task. diff --git a/api/tests/test_containers_integration_tests/tasks/test_mail_human_input_delivery_task.py b/api/tests/test_containers_integration_tests/tasks/test_mail_human_input_delivery_task.py index 95a867dbb5..f505361727 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_mail_human_input_delivery_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_mail_human_input_delivery_task.py @@ -4,6 +4,7 @@ from unittest.mock import patch import pytest from sqlalchemy import delete +from sqlalchemy.orm import Session from configs import dify_config from core.app.app_config.entities import WorkflowUIBasedAppConfig @@ -172,7 +173,9 @@ def _create_workflow_pause_state( db_session_with_containers.commit() -def test_dispatch_human_input_email_task_integration(monkeypatch: pytest.MonkeyPatch, db_session_with_containers): +def test_dispatch_human_input_email_task_integration( + monkeypatch: pytest.MonkeyPatch, db_session_with_containers: Session +): tenant, account = _create_workspace_member(db_session_with_containers) workflow_run_id = str(uuid.uuid4()) workflow_id = str(uuid.uuid4()) diff --git a/api/tests/test_containers_integration_tests/tasks/test_mail_inner_task.py b/api/tests/test_containers_integration_tests/tasks/test_mail_inner_task.py index 1a20b6deec..f8e54ea9e6 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_mail_inner_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_mail_inner_task.py @@ -2,6 +2,7 @@ from unittest.mock import patch import pytest from faker import Faker +from sqlalchemy.orm import Session from tasks.mail_inner_task import send_inner_email_task @@ -51,7 +52,7 @@ class TestMailInnerTask: }, } - def test_send_inner_email_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_send_inner_email_success(self, db_session_with_containers: Session, mock_external_service_dependencies): """ Test successful email sending with valid data. @@ -90,7 +91,9 @@ class TestMailInnerTask: html_content="Test email content", ) - def test_send_inner_email_single_recipient(self, db_session_with_containers, mock_external_service_dependencies): + def test_send_inner_email_single_recipient( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test email sending with single recipient. @@ -126,7 +129,9 @@ class TestMailInnerTask: html_content="Test email content", ) - def test_send_inner_email_empty_substitutions(self, db_session_with_containers, mock_external_service_dependencies): + def test_send_inner_email_empty_substitutions( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test email sending with empty substitutions. @@ -163,7 +168,7 @@ class TestMailInnerTask: ) def test_send_inner_email_mail_not_initialized( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test email sending when mail service is not initialized. @@ -193,7 +198,7 @@ class TestMailInnerTask: mock_external_service_dependencies["email_service"].send_raw_email.assert_not_called() def test_send_inner_email_template_rendering_error( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test email sending when template rendering fails. @@ -222,7 +227,9 @@ class TestMailInnerTask: # Verify no email service calls due to exception mock_external_service_dependencies["email_service"].send_raw_email.assert_not_called() - def test_send_inner_email_service_error(self, db_session_with_containers, mock_external_service_dependencies): + def test_send_inner_email_service_error( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test email sending when email service fails. diff --git a/api/tests/test_containers_integration_tests/tasks/test_mail_invite_member_task.py b/api/tests/test_containers_integration_tests/tasks/test_mail_invite_member_task.py index d34828c4b1..c8c7a4d961 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_mail_invite_member_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_mail_invite_member_task.py @@ -18,6 +18,7 @@ from unittest.mock import MagicMock, patch import pytest from faker import Faker from sqlalchemy import delete, select +from sqlalchemy.orm import Session from extensions.ext_redis import redis_client from libs.email_i18n import EmailType @@ -42,7 +43,7 @@ class TestMailInviteMemberTask: """ @pytest.fixture(autouse=True) - def cleanup_database(self, db_session_with_containers): + def cleanup_database(self, db_session_with_containers: Session): """Clean up database before each test to ensure isolation.""" # Clear all test data db_session_with_containers.execute(delete(TenantAccountJoin)) @@ -78,7 +79,7 @@ class TestMailInviteMemberTask: "config": mock_config, } - def _create_test_account_and_tenant(self, db_session_with_containers): + def _create_test_account_and_tenant(self, db_session_with_containers: Session): """ Helper method to create a test account and tenant for testing. @@ -147,7 +148,7 @@ class TestMailInviteMemberTask: redis_client.setex(cache_key, 24 * 60 * 60, json.dumps(invitation_data)) # 24 hours return token - def _create_pending_account_for_invitation(self, db_session_with_containers, email, tenant): + def _create_pending_account_for_invitation(self, db_session_with_containers: Session, email, tenant): """ Helper method to create a pending account for invitation testing. @@ -185,7 +186,9 @@ class TestMailInviteMemberTask: return account - def test_send_invite_member_mail_success(self, db_session_with_containers, mock_external_service_dependencies): + def test_send_invite_member_mail_success( + self, db_session_with_containers: Session, mock_external_service_dependencies + ): """ Test successful invitation email sending with all parameters. @@ -231,7 +234,7 @@ class TestMailInviteMemberTask: assert template_context["url"] == f"https://console.dify.ai/activate?token={token}" def test_send_invite_member_mail_different_languages( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test invitation email sending with different language codes. @@ -263,7 +266,7 @@ class TestMailInviteMemberTask: assert call_args[1]["language_code"] == language def test_send_invite_member_mail_mail_not_initialized( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test behavior when mail service is not initialized. @@ -292,7 +295,7 @@ class TestMailInviteMemberTask: mock_email_service.send_email.assert_not_called() def test_send_invite_member_mail_email_service_exception( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test error handling when email service raises an exception. @@ -322,7 +325,7 @@ class TestMailInviteMemberTask: assert "Send invite member mail to %s failed" in error_call def test_send_invite_member_mail_template_context_validation( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test template context contains all required fields for email rendering. @@ -368,7 +371,7 @@ class TestMailInviteMemberTask: assert template_context["url"] == f"https://console.dify.ai/activate?token={token}" def test_send_invite_member_mail_integration_with_redis_token( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test integration with Redis token validation. @@ -407,7 +410,7 @@ class TestMailInviteMemberTask: assert invitation_data["workspace_id"] == tenant.id def test_send_invite_member_mail_with_special_characters( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test email sending with special characters in names and workspace names. @@ -449,7 +452,7 @@ class TestMailInviteMemberTask: assert template_context["workspace_name"] == workspace_name def test_send_invite_member_mail_real_database_integration( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test real database integration with actual invitation flow. @@ -501,7 +504,7 @@ class TestMailInviteMemberTask: assert tenant_join.role == TenantAccountRole.NORMAL def test_send_invite_member_mail_token_lifecycle_management( - self, db_session_with_containers, mock_external_service_dependencies + self, db_session_with_containers: Session, mock_external_service_dependencies ): """ Test token lifecycle management and validation. diff --git a/api/tests/test_containers_integration_tests/tasks/test_mail_owner_transfer_task.py b/api/tests/test_containers_integration_tests/tasks/test_mail_owner_transfer_task.py index e08b099480..176645a4ab 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_mail_owner_transfer_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_mail_owner_transfer_task.py @@ -11,6 +11,7 @@ from unittest.mock import patch import pytest from faker import Faker +from sqlalchemy.orm import Session from libs.email_i18n import EmailType from models.account import Account, Tenant, TenantAccountJoin, TenantAccountRole @@ -44,7 +45,7 @@ class TestMailOwnerTransferTask: "get_email_service": mock_get_email_service, } - def _create_test_account_and_tenant(self, db_session_with_containers): + def _create_test_account_and_tenant(self, db_session_with_containers: Session): """ Helper method to create test account and tenant for testing. @@ -86,7 +87,9 @@ class TestMailOwnerTransferTask: return account, tenant - def test_send_owner_transfer_confirm_task_success(self, db_session_with_containers, mock_mail_dependencies): + def test_send_owner_transfer_confirm_task_success( + self, db_session_with_containers: Session, mock_mail_dependencies + ): """ Test successful owner transfer confirmation email sending. @@ -127,7 +130,7 @@ class TestMailOwnerTransferTask: assert call_args[1]["template_context"]["WorkspaceName"] == test_workspace def test_send_owner_transfer_confirm_task_mail_not_initialized( - self, db_session_with_containers, mock_mail_dependencies + self, db_session_with_containers: Session, mock_mail_dependencies ): """ Test owner transfer confirmation email when mail service is not initialized. @@ -158,7 +161,7 @@ class TestMailOwnerTransferTask: mock_mail_dependencies["email_service"].send_email.assert_not_called() def test_send_owner_transfer_confirm_task_exception_handling( - self, db_session_with_containers, mock_mail_dependencies + self, db_session_with_containers: Session, mock_mail_dependencies ): """ Test exception handling in owner transfer confirmation email. @@ -192,7 +195,7 @@ class TestMailOwnerTransferTask: mock_mail_dependencies["email_service"].send_email.assert_called_once() def test_send_old_owner_transfer_notify_email_task_success( - self, db_session_with_containers, mock_mail_dependencies + self, db_session_with_containers: Session, mock_mail_dependencies ): """ Test successful old owner transfer notification email sending. @@ -234,7 +237,7 @@ class TestMailOwnerTransferTask: assert call_args[1]["template_context"]["NewOwnerEmail"] == test_new_owner_email def test_send_old_owner_transfer_notify_email_task_mail_not_initialized( - self, db_session_with_containers, mock_mail_dependencies + self, db_session_with_containers: Session, mock_mail_dependencies ): """ Test old owner transfer notification email when mail service is not initialized. @@ -265,7 +268,7 @@ class TestMailOwnerTransferTask: mock_mail_dependencies["email_service"].send_email.assert_not_called() def test_send_old_owner_transfer_notify_email_task_exception_handling( - self, db_session_with_containers, mock_mail_dependencies + self, db_session_with_containers: Session, mock_mail_dependencies ): """ Test exception handling in old owner transfer notification email. @@ -299,7 +302,7 @@ class TestMailOwnerTransferTask: mock_mail_dependencies["email_service"].send_email.assert_called_once() def test_send_new_owner_transfer_notify_email_task_success( - self, db_session_with_containers, mock_mail_dependencies + self, db_session_with_containers: Session, mock_mail_dependencies ): """ Test successful new owner transfer notification email sending. @@ -338,7 +341,7 @@ class TestMailOwnerTransferTask: assert call_args[1]["template_context"]["WorkspaceName"] == test_workspace def test_send_new_owner_transfer_notify_email_task_mail_not_initialized( - self, db_session_with_containers, mock_mail_dependencies + self, db_session_with_containers: Session, mock_mail_dependencies ): """ Test new owner transfer notification email when mail service is not initialized. @@ -367,7 +370,7 @@ class TestMailOwnerTransferTask: mock_mail_dependencies["email_service"].send_email.assert_not_called() def test_send_new_owner_transfer_notify_email_task_exception_handling( - self, db_session_with_containers, mock_mail_dependencies + self, db_session_with_containers: Session, mock_mail_dependencies ): """ Test exception handling in new owner transfer notification email. diff --git a/api/tests/test_containers_integration_tests/tasks/test_mail_register_task.py b/api/tests/test_containers_integration_tests/tasks/test_mail_register_task.py index cced6f7780..071971f324 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_mail_register_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_mail_register_task.py @@ -9,6 +9,7 @@ from unittest.mock import patch import pytest from faker import Faker +from sqlalchemy.orm import Session from libs.email_i18n import EmailType from tasks.mail_register_task import send_email_register_mail_task, send_email_register_mail_task_when_account_exist @@ -35,7 +36,7 @@ class TestMailRegisterTask: "get_email_service": mock_get_email_service, } - def test_send_email_register_mail_task_success(self, db_session_with_containers, mock_mail_dependencies): + def test_send_email_register_mail_task_success(self, db_session_with_containers: Session, mock_mail_dependencies): """Test successful email registration mail sending.""" fake = Faker() language = "en-US" @@ -56,7 +57,7 @@ class TestMailRegisterTask: ) def test_send_email_register_mail_task_mail_not_initialized( - self, db_session_with_containers, mock_mail_dependencies + self, db_session_with_containers: Session, mock_mail_dependencies ): """Test email registration task when mail service is not initialized.""" mock_mail_dependencies["mail"].is_inited.return_value = False @@ -66,7 +67,9 @@ class TestMailRegisterTask: mock_mail_dependencies["get_email_service"].assert_not_called() mock_mail_dependencies["email_service"].send_email.assert_not_called() - def test_send_email_register_mail_task_exception_handling(self, db_session_with_containers, mock_mail_dependencies): + def test_send_email_register_mail_task_exception_handling( + self, db_session_with_containers: Session, mock_mail_dependencies + ): """Test email registration task exception handling.""" mock_mail_dependencies["email_service"].send_email.side_effect = Exception("Email service error") @@ -79,7 +82,7 @@ class TestMailRegisterTask: mock_logger.exception.assert_called_once_with("Send email register mail to %s failed", to_email) def test_send_email_register_mail_task_when_account_exist_success( - self, db_session_with_containers, mock_mail_dependencies + self, db_session_with_containers: Session, mock_mail_dependencies ): """Test successful email registration mail sending when account exists.""" fake = Faker() @@ -105,7 +108,7 @@ class TestMailRegisterTask: ) def test_send_email_register_mail_task_when_account_exist_mail_not_initialized( - self, db_session_with_containers, mock_mail_dependencies + self, db_session_with_containers: Session, mock_mail_dependencies ): """Test account exist email task when mail service is not initialized.""" mock_mail_dependencies["mail"].is_inited.return_value = False @@ -118,7 +121,7 @@ class TestMailRegisterTask: mock_mail_dependencies["email_service"].send_email.assert_not_called() def test_send_email_register_mail_task_when_account_exist_exception_handling( - self, db_session_with_containers, mock_mail_dependencies + self, db_session_with_containers: Session, mock_mail_dependencies ): """Test account exist email task exception handling.""" mock_mail_dependencies["email_service"].send_email.side_effect = Exception("Email service error") diff --git a/api/tests/test_containers_integration_tests/tasks/test_rag_pipeline_run_tasks.py b/api/tests/test_containers_integration_tests/tasks/test_rag_pipeline_run_tasks.py index f01fcc1742..5eea985fdc 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_rag_pipeline_run_tasks.py +++ b/api/tests/test_containers_integration_tests/tasks/test_rag_pipeline_run_tasks.py @@ -4,12 +4,13 @@ from unittest.mock import MagicMock, patch import pytest from faker import Faker +from flask import Flask from sqlalchemy.orm import Session from core.app.entities.app_invoke_entities import InvokeFrom, RagPipelineGenerateEntity from core.app.entities.rag_pipeline_invoke_entities import RagPipelineInvokeEntity from core.rag.pipeline.queue import TenantIsolatedTaskQueue -from models import Account, Tenant, TenantAccountJoin, TenantAccountRole +from models import Account, AccountStatus, Tenant, TenantAccountJoin, TenantAccountRole, TenantStatus from models.dataset import Pipeline from models.workflow import Workflow from tasks.rag_pipeline.priority_rag_pipeline_run_task import ( @@ -69,14 +70,14 @@ class TestRagPipelineRunTasks: email=fake.email(), name=fake.name(), interface_language="en-US", - status="active", + status=AccountStatus.ACTIVE, ) db_session_with_containers.add(account) db_session_with_containers.commit() tenant = Tenant( name=fake.company(), - status="normal", + status=TenantStatus.NORMAL, ) db_session_with_containers.add(tenant) db_session_with_containers.commit() @@ -725,7 +726,7 @@ class TestRagPipelineRunTasks: assert queue1._task_key != queue2._task_key def test_run_single_rag_pipeline_task_success( - self, db_session_with_containers: Session, mock_pipeline_generator, flask_app_with_containers + self, db_session_with_containers: Session, mock_pipeline_generator, flask_app_with_containers: Flask ): """ Test successful run_single_rag_pipeline_task execution. @@ -760,7 +761,7 @@ class TestRagPipelineRunTasks: assert isinstance(call_kwargs["application_generate_entity"], RagPipelineGenerateEntity) def test_run_single_rag_pipeline_task_entity_validation_error( - self, db_session_with_containers: Session, mock_pipeline_generator, flask_app_with_containers + self, db_session_with_containers: Session, mock_pipeline_generator, flask_app_with_containers: Flask ): """ Test run_single_rag_pipeline_task with invalid entity data. @@ -805,7 +806,7 @@ class TestRagPipelineRunTasks: mock_pipeline_generator.assert_not_called() def test_run_single_rag_pipeline_task_database_entity_not_found( - self, db_session_with_containers: Session, mock_pipeline_generator, flask_app_with_containers + self, db_session_with_containers: Session, mock_pipeline_generator, flask_app_with_containers: Flask ): """ Test run_single_rag_pipeline_task with non-existent database entities. diff --git a/api/tests/test_containers_integration_tests/tasks/test_remove_app_and_related_data_task.py b/api/tests/test_containers_integration_tests/tasks/test_remove_app_and_related_data_task.py index b43b622870..03c02ea341 100644 --- a/api/tests/test_containers_integration_tests/tasks/test_remove_app_and_related_data_task.py +++ b/api/tests/test_containers_integration_tests/tasks/test_remove_app_and_related_data_task.py @@ -3,6 +3,7 @@ from unittest.mock import ANY, call, patch import pytest from sqlalchemy import delete, func, select +from sqlalchemy.orm import Session from core.db.session_factory import session_factory from extensions.storage.storage_type import StorageType @@ -117,7 +118,7 @@ def _create_offload_data(db_session_with_containers, *, tenant_id: str, app_id: class TestDeleteDraftVariablesBatch: - def test_delete_draft_variables_batch_success(self, db_session_with_containers): + def test_delete_draft_variables_batch_success(self, db_session_with_containers: Session): """Test successful deletion of draft variables in batches.""" _, app1 = _create_tenant_and_app(db_session_with_containers) _, app2 = _create_tenant_and_app(db_session_with_containers) @@ -137,7 +138,7 @@ class TestDeleteDraftVariablesBatch: assert app1_remaining_count == 0 assert app2_remaining_count == 100 - def test_delete_draft_variables_batch_empty_result(self, db_session_with_containers): + def test_delete_draft_variables_batch_empty_result(self, db_session_with_containers: Session): """Test deletion when no draft variables exist for the app.""" result = delete_draft_variables_batch(str(uuid.uuid4()), 1000) @@ -176,7 +177,7 @@ class TestDeleteDraftVariableOffloadData: """Test the Offload data cleanup functionality.""" @patch("extensions.ext_storage.storage") - def test_delete_draft_variable_offload_data_success(self, mock_storage, db_session_with_containers): + def test_delete_draft_variable_offload_data_success(self, mock_storage, db_session_with_containers: Session): """Test successful deletion of offload data.""" tenant, app = _create_tenant_and_app(db_session_with_containers) offload_data = _create_offload_data(db_session_with_containers, tenant_id=tenant.id, app_id=app.id, count=3) diff --git a/api/tests/test_containers_integration_tests/test_opendal_fs_default_root.py b/api/tests/test_containers_integration_tests/test_opendal_fs_default_root.py index 34a1941c39..6365207661 100644 --- a/api/tests/test_containers_integration_tests/test_opendal_fs_default_root.py +++ b/api/tests/test_containers_integration_tests/test_opendal_fs_default_root.py @@ -1,12 +1,14 @@ from pathlib import Path +import pytest + from extensions.storage.opendal_storage import OpenDALStorage class TestOpenDALFsDefaultRoot: """Test that OpenDALStorage with scheme='fs' works correctly when no root is provided.""" - def test_fs_without_root_uses_default(self, tmp_path, monkeypatch): + def test_fs_without_root_uses_default(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch): """When no root is specified, the default 'storage' should be used and passed to the Operator.""" # Change to tmp_path so the default "storage" dir is created there monkeypatch.chdir(tmp_path) @@ -25,7 +27,7 @@ class TestOpenDALFsDefaultRoot: # Cleanup storage.delete("test_default_root.txt") - def test_fs_with_explicit_root(self, tmp_path): + def test_fs_with_explicit_root(self, tmp_path: Path): """When root is explicitly provided, it should be used.""" custom_root = str(tmp_path / "custom_storage") storage = OpenDALStorage(scheme="fs", root=custom_root) @@ -38,7 +40,7 @@ class TestOpenDALFsDefaultRoot: # Cleanup storage.delete("test_explicit_root.txt") - def test_fs_with_env_var_root(self, tmp_path, monkeypatch): + def test_fs_with_env_var_root(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch): """When OPENDAL_FS_ROOT env var is set, it should be picked up via _get_opendal_kwargs.""" env_root = str(tmp_path / "env_storage") monkeypatch.setenv("OPENDAL_FS_ROOT", env_root) diff --git a/api/tests/test_containers_integration_tests/test_workflow_pause_integration.py b/api/tests/test_containers_integration_tests/test_workflow_pause_integration.py index b00d827e37..6402e7da2b 100644 --- a/api/tests/test_containers_integration_tests/test_workflow_pause_integration.py +++ b/api/tests/test_containers_integration_tests/test_workflow_pause_integration.py @@ -175,7 +175,7 @@ class TestWorkflowPauseIntegration: """Comprehensive integration tests for workflow pause functionality.""" @pytest.fixture(autouse=True) - def setup_test_data(self, db_session_with_containers): + def setup_test_data(self, db_session_with_containers: Session): """Set up test data for each test method using TestContainers.""" # Create test tenant and account diff --git a/api/tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_javascript.py b/api/tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_javascript.py index 19a41b6186..a5086b4c5d 100644 --- a/api/tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_javascript.py +++ b/api/tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_javascript.py @@ -1,12 +1,14 @@ from textwrap import dedent +from flask import Flask + from .test_utils import CodeExecutorTestMixin class TestJavaScriptCodeExecutor(CodeExecutorTestMixin): """Test class for JavaScript code executor functionality.""" - def test_javascript_plain(self, flask_app_with_containers): + def test_javascript_plain(self, flask_app_with_containers: Flask): """Test basic JavaScript code execution with console.log output""" CodeExecutor, CodeLanguage = self.code_executor_imports @@ -14,7 +16,7 @@ class TestJavaScriptCodeExecutor(CodeExecutorTestMixin): result_message = CodeExecutor.execute_code(language=CodeLanguage.JAVASCRIPT, preload="", code=code) assert result_message == "Hello World\n" - def test_javascript_json(self, flask_app_with_containers): + def test_javascript_json(self, flask_app_with_containers: Flask): """Test JavaScript code execution with JSON output""" CodeExecutor, CodeLanguage = self.code_executor_imports @@ -25,7 +27,7 @@ class TestJavaScriptCodeExecutor(CodeExecutorTestMixin): result = CodeExecutor.execute_code(language=CodeLanguage.JAVASCRIPT, preload="", code=code) assert result == '{"Hello":"World"}\n' - def test_javascript_with_code_template(self, flask_app_with_containers): + def test_javascript_with_code_template(self, flask_app_with_containers: Flask): """Test JavaScript workflow code template execution with inputs""" CodeExecutor, CodeLanguage = self.code_executor_imports JavascriptCodeProvider, _ = self.javascript_imports @@ -37,7 +39,7 @@ class TestJavaScriptCodeExecutor(CodeExecutorTestMixin): ) assert result == {"result": "HelloWorld"} - def test_javascript_get_runner_script(self, flask_app_with_containers): + def test_javascript_get_runner_script(self, flask_app_with_containers: Flask): """Test JavaScript template transformer runner script generation""" _, NodeJsTemplateTransformer = self.javascript_imports diff --git a/api/tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_jinja2.py b/api/tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_jinja2.py index ddb079f00c..8b4c3c3d4a 100644 --- a/api/tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_jinja2.py +++ b/api/tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_jinja2.py @@ -1,12 +1,14 @@ import base64 +from flask import Flask + from .test_utils import CodeExecutorTestMixin class TestJinja2CodeExecutor(CodeExecutorTestMixin): """Test class for Jinja2 code executor functionality.""" - def test_jinja2(self, flask_app_with_containers): + def test_jinja2(self, flask_app_with_containers: Flask): """Test basic Jinja2 template execution with variable substitution""" CodeExecutor, CodeLanguage = self.code_executor_imports _, Jinja2TemplateTransformer = self.jinja2_imports @@ -25,7 +27,7 @@ class TestJinja2CodeExecutor(CodeExecutorTestMixin): ) assert result == "<>Hello World<>\n" - def test_jinja2_with_code_template(self, flask_app_with_containers): + def test_jinja2_with_code_template(self, flask_app_with_containers: Flask): """Test Jinja2 workflow code template execution with inputs""" CodeExecutor, CodeLanguage = self.code_executor_imports @@ -34,7 +36,7 @@ class TestJinja2CodeExecutor(CodeExecutorTestMixin): ) assert result == {"result": "Hello World"} - def test_jinja2_get_runner_script(self, flask_app_with_containers): + def test_jinja2_get_runner_script(self, flask_app_with_containers: Flask): """Test Jinja2 template transformer runner script generation""" _, Jinja2TemplateTransformer = self.jinja2_imports @@ -43,7 +45,7 @@ class TestJinja2CodeExecutor(CodeExecutorTestMixin): assert runner_script.count(Jinja2TemplateTransformer._inputs_placeholder) == 1 assert runner_script.count(Jinja2TemplateTransformer._result_tag) == 2 - def test_jinja2_template_with_special_characters(self, flask_app_with_containers): + def test_jinja2_template_with_special_characters(self, flask_app_with_containers: Flask): """ Test that templates with special characters (quotes, newlines) render correctly. This is a regression test for issue #26818 where textarea pre-fill values diff --git a/api/tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_python3.py b/api/tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_python3.py index 6d93df2472..0de41e1312 100644 --- a/api/tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_python3.py +++ b/api/tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_python3.py @@ -1,12 +1,14 @@ from textwrap import dedent +from flask import Flask + from .test_utils import CodeExecutorTestMixin class TestPython3CodeExecutor(CodeExecutorTestMixin): """Test class for Python3 code executor functionality.""" - def test_python3_plain(self, flask_app_with_containers): + def test_python3_plain(self, flask_app_with_containers: Flask): """Test basic Python3 code execution with print output""" CodeExecutor, CodeLanguage = self.code_executor_imports @@ -14,7 +16,7 @@ class TestPython3CodeExecutor(CodeExecutorTestMixin): result = CodeExecutor.execute_code(language=CodeLanguage.PYTHON3, preload="", code=code) assert result == "Hello World\n" - def test_python3_json(self, flask_app_with_containers): + def test_python3_json(self, flask_app_with_containers: Flask): """Test Python3 code execution with JSON output""" CodeExecutor, CodeLanguage = self.code_executor_imports @@ -25,7 +27,7 @@ class TestPython3CodeExecutor(CodeExecutorTestMixin): result = CodeExecutor.execute_code(language=CodeLanguage.PYTHON3, preload="", code=code) assert result == '{"Hello": "World"}\n' - def test_python3_with_code_template(self, flask_app_with_containers): + def test_python3_with_code_template(self, flask_app_with_containers: Flask): """Test Python3 workflow code template execution with inputs""" CodeExecutor, CodeLanguage = self.code_executor_imports Python3CodeProvider, _ = self.python3_imports @@ -37,7 +39,7 @@ class TestPython3CodeExecutor(CodeExecutorTestMixin): ) assert result == {"result": "HelloWorld"} - def test_python3_get_runner_script(self, flask_app_with_containers): + def test_python3_get_runner_script(self, flask_app_with_containers: Flask): """Test Python3 template transformer runner script generation""" _, Python3TemplateTransformer = self.python3_imports diff --git a/api/tests/unit_tests/controllers/console/app/test_app_response_models.py b/api/tests/unit_tests/controllers/console/app/test_app_response_models.py index 35d07a987d..80e7c41a9e 100644 --- a/api/tests/unit_tests/controllers/console/app/test_app_response_models.py +++ b/api/tests/unit_tests/controllers/console/app/test_app_response_models.py @@ -10,6 +10,8 @@ from typing import Any import pytest from flask.views import MethodView +from pydantic import ValidationError +from werkzeug.datastructures import MultiDict # kombu references MethodView as a global when importing celery/kombu pools. if not hasattr(builtins, "MethodView"): @@ -174,6 +176,101 @@ def _dummy_workflow(): ) +def test_app_list_query_normalizes_orpc_bracket_tag_ids(app_module): + first_tag_id = "8c4ef3d1-58a1-4d94-8a1c-1c171d889e08" + second_tag_id = "3c39395b-6d1f-4030-8b17-eaa7cc85221c" + query_args = MultiDict( + [ + ("page", "1"), + ("limit", "30"), + ("tag_ids[1]", second_tag_id), + ("tag_ids[0]", first_tag_id), + ] + ) + + normalized = app_module._normalize_app_list_query_args(query_args) + query = app_module.AppListQuery.model_validate(normalized) + + assert query.tag_ids == [first_tag_id, second_tag_id] + + +def test_app_list_query_preserves_regular_query_params(app_module): + query_args = MultiDict( + [ + ("page", "2"), + ("limit", "50"), + ("mode", "chat"), + ("name", "Sales Copilot"), + ("is_created_by_me", "true"), + ] + ) + + normalized = app_module._normalize_app_list_query_args(query_args) + query = app_module.AppListQuery.model_validate(normalized) + + assert normalized == { + "page": "2", + "limit": "50", + "mode": "chat", + "name": "Sales Copilot", + "is_created_by_me": "true", + } + assert query.page == 2 + assert query.limit == 50 + assert query.mode == "chat" + assert query.name == "Sales Copilot" + assert query.is_created_by_me is True + assert query.tag_ids is None + + +def test_app_list_query_normalizes_empty_bracket_tag_ids_to_none(app_module): + query_args = MultiDict( + [ + ("tag_ids[0]", ""), + ("tag_ids[1]", " "), + ] + ) + + normalized = app_module._normalize_app_list_query_args(query_args) + query = app_module.AppListQuery.model_validate(normalized) + + assert normalized == {"tag_ids": ["", " "]} + assert query.tag_ids is None + + +def test_app_list_query_rejects_invalid_bracket_tag_id(app_module): + normalized = app_module._normalize_app_list_query_args(MultiDict([("tag_ids[0]", "not-a-uuid")])) + + with pytest.raises(ValidationError): + app_module.AppListQuery.model_validate(normalized) + + +def test_app_list_query_sorts_bracket_tag_ids_by_index(app_module): + first_tag_id = "8c4ef3d1-58a1-4d94-8a1c-1c171d889e08" + second_tag_id = "3c39395b-6d1f-4030-8b17-eaa7cc85221c" + third_tag_id = "9d5ec0f7-4f2b-4e7f-9c13-1e7a034d0eb1" + query_args = MultiDict( + [ + ("tag_ids[2]", third_tag_id), + ("tag_ids[1]", second_tag_id), + ("tag_ids[0]", first_tag_id), + ] + ) + + normalized = app_module._normalize_app_list_query_args(query_args) + query = app_module.AppListQuery.model_validate(normalized) + + assert query.tag_ids == [first_tag_id, second_tag_id, third_tag_id] + + +def test_app_list_query_rejects_flat_tag_ids(app_module): + tag_id = "8c4ef3d1-58a1-4d94-8a1c-1c171d889e08" + normalized = app_module._normalize_app_list_query_args(MultiDict([("tag_ids", tag_id)])) + + with pytest.raises(ValidationError): + app_module.AppListQuery.model_validate(normalized) + + def test_app_partial_serialization_uses_aliases(app_models): AppPartial = app_models.AppPartial created_at = _ts() diff --git a/api/tests/unit_tests/controllers/console/app/test_workflow.py b/api/tests/unit_tests/controllers/console/app/test_workflow.py index e91c0a0597..7c470eb9a8 100644 --- a/api/tests/unit_tests/controllers/console/app/test_workflow.py +++ b/api/tests/unit_tests/controllers/console/app/test_workflow.py @@ -363,7 +363,8 @@ def test_workflow_online_users_filters_inaccessible_workflow(app, monkeypatch: p ) monkeypatch.setattr(workflow_module.file_helpers, "get_signed_file_url", sign_avatar) - workflow_module.redis_client.hgetall.side_effect = lambda key: ( + redis_pipeline = Mock() + redis_pipeline.execute.return_value = [ { b"sid-1": json.dumps( { @@ -374,16 +375,16 @@ def test_workflow_online_users_filters_inaccessible_workflow(app, monkeypatch: p } ) } - if key == f"{workflow_module.WORKFLOW_ONLINE_USERS_PREFIX}{app_id_1}" - else {} - ) + ] + workflow_module.redis_client.pipeline.return_value = redis_pipeline api = workflow_module.WorkflowOnlineUsersApi() - handler = _unwrap(api.get) + handler = _unwrap(api.post) with app.test_request_context( - f"/apps/workflows/online-users?app_ids={app_id_1},{app_id_2}", - method="GET", + "/apps/workflows/online-users", + method="POST", + json={"app_ids": [app_id_1, app_id_2]}, ): response = handler(api) @@ -402,12 +403,43 @@ def test_workflow_online_users_filters_inaccessible_workflow(app, monkeypatch: p } ] } - workflow_module.redis_client.hgetall.assert_called_once_with( - f"{workflow_module.WORKFLOW_ONLINE_USERS_PREFIX}{app_id_1}" - ) + workflow_module.redis_client.pipeline.assert_called_once_with(transaction=False) + redis_pipeline.hgetall.assert_called_once_with(f"{workflow_module.WORKFLOW_ONLINE_USERS_PREFIX}{app_id_1}") + redis_pipeline.execute.assert_called_once_with() sign_avatar.assert_called_once_with("avatar-file-id") +def test_workflow_online_users_batches_redis_reads(app, monkeypatch: pytest.MonkeyPatch) -> None: + app_ids = [f"wf-{index}" for index in range(workflow_module.WORKFLOW_ONLINE_USERS_REDIS_BATCH_SIZE + 1)] + monkeypatch.setattr(workflow_module, "current_account_with_tenant", lambda: (SimpleNamespace(), "tenant-1")) + monkeypatch.setattr( + workflow_module, + "WorkflowService", + lambda: SimpleNamespace(get_accessible_app_ids=lambda app_ids, tenant_id: set(app_ids)), + ) + + first_pipeline = Mock() + first_pipeline.execute.return_value = [{} for _ in range(workflow_module.WORKFLOW_ONLINE_USERS_REDIS_BATCH_SIZE)] + second_pipeline = Mock() + second_pipeline.execute.return_value = [{}] + workflow_module.redis_client.pipeline.side_effect = [first_pipeline, second_pipeline] + + api = workflow_module.WorkflowOnlineUsersApi() + handler = _unwrap(api.post) + + with app.test_request_context( + "/apps/workflows/online-users", + method="POST", + json={"app_ids": app_ids}, + ): + response = handler(api) + + assert len(response["data"]) == len(app_ids) + assert workflow_module.redis_client.pipeline.call_count == 2 + assert first_pipeline.hgetall.call_count == workflow_module.WORKFLOW_ONLINE_USERS_REDIS_BATCH_SIZE + assert second_pipeline.hgetall.call_count == 1 + + def test_workflow_online_users_rejects_excessive_workflow_ids(app, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(workflow_module, "current_account_with_tenant", lambda: (SimpleNamespace(), "tenant-1")) accessible_app_ids = Mock(return_value=set()) @@ -417,14 +449,15 @@ def test_workflow_online_users_rejects_excessive_workflow_ids(app, monkeypatch: lambda: SimpleNamespace(get_accessible_app_ids=accessible_app_ids), ) - excessive_ids = ",".join(f"wf-{index}" for index in range(workflow_module.MAX_WORKFLOW_ONLINE_USERS_QUERY_IDS + 1)) + excessive_ids = [f"wf-{index}" for index in range(workflow_module.MAX_WORKFLOW_ONLINE_USERS_REQUEST_IDS + 1)] api = workflow_module.WorkflowOnlineUsersApi() - handler = _unwrap(api.get) + handler = _unwrap(api.post) with app.test_request_context( - f"/apps/workflows/online-users?app_ids={excessive_ids}", - method="GET", + "/apps/workflows/online-users", + method="POST", + json={"app_ids": excessive_ids}, ): with pytest.raises(HTTPException) as exc: handler(api) diff --git a/api/tests/unit_tests/controllers/console/app/workflow_draft_variables_test.py b/api/tests/unit_tests/controllers/console/app/workflow_draft_variables_test.py index 22b80b748e..62fa82e339 100644 --- a/api/tests/unit_tests/controllers/console/app/workflow_draft_variables_test.py +++ b/api/tests/unit_tests/controllers/console/app/workflow_draft_variables_test.py @@ -1,7 +1,7 @@ import uuid from collections import OrderedDict from typing import Any, NamedTuple -from unittest.mock import MagicMock, patch +from unittest.mock import patch import pytest from flask_restx import marshal @@ -29,15 +29,18 @@ class TestWorkflowDraftVariableFields: def test_serialize_full_content(self): """Test that _serialize_full_content uses pre-loaded relationships.""" # Create mock objects with relationships pre-loaded - mock_variable_file = MagicMock(spec=WorkflowDraftVariableFile) - mock_variable_file.size = 100000 - mock_variable_file.length = 50 - mock_variable_file.value_type = SegmentType.OBJECT - mock_variable_file.upload_file_id = "test-upload-file-id" - - mock_variable = MagicMock(spec=WorkflowDraftVariable) - mock_variable.file_id = "test-file-id" - mock_variable.variable_file = mock_variable_file + mock_variable = WorkflowDraftVariable( + file_id="test-file-id", + variable_file=WorkflowDraftVariableFile( + size=100000, + length=50, + value_type=SegmentType.OBJECT, + upload_file_id="test-upload-file-id", + tenant_id=str(uuid.uuid4()), + app_id=str(uuid.uuid4()), + user_id=str(uuid.uuid4()), + ), + ) # Mock the file helpers with patch("controllers.console.app.workflow_draft_variable.file_helpers", autospec=True) as mock_file_helpers: @@ -84,7 +87,7 @@ class TestWorkflowDraftVariableFields: expected_without_value: OrderedDict[str, Any] = OrderedDict( { - "id": str(conv_var.id), + "id": conv_var.id, "type": conv_var.get_variable_type().value, "name": "conv_var", "description": "", @@ -117,7 +120,7 @@ class TestWorkflowDraftVariableFields: expected_without_value = OrderedDict( { - "id": str(sys_var.id), + "id": sys_var.id, "type": sys_var.get_variable_type().value, "name": "sys_var", "description": "", @@ -149,7 +152,7 @@ class TestWorkflowDraftVariableFields: expected_without_value: OrderedDict[str, Any] = OrderedDict( { - "id": str(node_var.id), + "id": node_var.id, "type": node_var.get_variable_type().value, "name": "node_var", "description": "", @@ -180,19 +183,22 @@ class TestWorkflowDraftVariableFields: node_var.id = str(uuid.uuid4()) node_var.last_edited_at = naive_utc_now() variable_file = WorkflowDraftVariableFile( - id=str(uuidv7()), upload_file_id=str(uuid.uuid4()), size=1024, length=10, value_type=SegmentType.ARRAY_STRING, + tenant_id=str(uuidv7()), + app_id=str(uuidv7()), + user_id=str(uuidv7()), ) + variable_file.id = str(uuidv7()) node_var.variable_file = variable_file node_var.file_id = variable_file.id expected_without_value: OrderedDict[str, Any] = OrderedDict( { - "id": str(node_var.id), - "type": node_var.get_variable_type().value, + "id": node_var.id, + "type": node_var.get_variable_type(), "name": "node_var", "description": "", "selector": ["test_node", "node_var"], @@ -235,7 +241,7 @@ class TestWorkflowDraftVariableList: node_var.id = str(uuid.uuid4()) node_var_dict = OrderedDict( { - "id": str(node_var.id), + "id": node_var.id, "type": node_var.get_variable_type().value, "name": "test_var", "description": "", diff --git a/api/tests/unit_tests/controllers/console/auth/test_account_activation.py b/api/tests/unit_tests/controllers/console/auth/test_account_activation.py index d3e864a75a..0fb0ebc330 100644 --- a/api/tests/unit_tests/controllers/console/auth/test_account_activation.py +++ b/api/tests/unit_tests/controllers/console/auth/test_account_activation.py @@ -67,7 +67,7 @@ class TestActivateCheckApi: assert response["data"]["email"] == "invitee@example.com" @patch("controllers.console.auth.activate.RegisterService.get_invitation_with_case_fallback") - def test_check_invalid_invitation_token(self, mock_get_invitation, app): + def test_check_invalid_invitation_token(self, mock_get_invitation, app: Flask): """ Test checking invalid invitation token. @@ -185,7 +185,7 @@ class TestActivateApi: mock_db, mock_revoke_token, mock_get_invitation, - app, + app: Flask, mock_invitation, mock_account, ): @@ -227,7 +227,7 @@ class TestActivateApi: mock_db.session.commit.assert_called_once() @patch("controllers.console.auth.activate.RegisterService.get_invitation_with_case_fallback") - def test_activation_with_invalid_token(self, mock_get_invitation, app): + def test_activation_with_invalid_token(self, mock_get_invitation, app: Flask): """ Test account activation with invalid token. @@ -263,7 +263,7 @@ class TestActivateApi: mock_db, mock_revoke_token, mock_get_invitation, - app, + app: Flask, mock_invitation, mock_account, ): @@ -312,7 +312,7 @@ class TestActivateApi: mock_db, mock_revoke_token, mock_get_invitation, - app, + app: Flask, mock_invitation, mock_account, language, @@ -358,7 +358,7 @@ class TestActivateApi: mock_db, mock_revoke_token, mock_get_invitation, - app, + app: Flask, mock_invitation, ): """ @@ -398,7 +398,7 @@ class TestActivateApi: mock_db, mock_revoke_token, mock_get_invitation, - app, + app: Flask, mock_invitation, ): """ @@ -438,7 +438,7 @@ class TestActivateApi: mock_db, mock_revoke_token, mock_get_invitation, - app, + app: Flask, mock_invitation, mock_account, ): diff --git a/api/tests/unit_tests/controllers/console/auth/test_email_verification.py b/api/tests/unit_tests/controllers/console/auth/test_email_verification.py index b7bc73da5f..102af9b250 100644 --- a/api/tests/unit_tests/controllers/console/auth/test_email_verification.py +++ b/api/tests/unit_tests/controllers/console/auth/test_email_verification.py @@ -140,7 +140,7 @@ class TestEmailCodeLoginSendEmailApi: @patch("controllers.console.wraps.db") @patch("controllers.console.auth.login.AccountService.is_email_send_ip_limit") - def test_send_email_code_ip_rate_limited(self, mock_is_ip_limit, mock_db, app): + def test_send_email_code_ip_rate_limited(self, mock_is_ip_limit, mock_db, app: Flask): """ Test email code sending blocked by IP rate limit. @@ -160,7 +160,7 @@ class TestEmailCodeLoginSendEmailApi: @patch("controllers.console.wraps.db") @patch("controllers.console.auth.login.AccountService.is_email_send_ip_limit") @patch("controllers.console.auth.login.AccountService.get_user_through_email") - def test_send_email_code_frozen_account(self, mock_get_user, mock_is_ip_limit, mock_db, app): + def test_send_email_code_frozen_account(self, mock_get_user, mock_is_ip_limit, mock_db, app: Flask): """ Test email code sending to frozen account. @@ -195,7 +195,7 @@ class TestEmailCodeLoginSendEmailApi: mock_get_user, mock_is_ip_limit, mock_db, - app, + app: Flask, mock_account, language_input, expected_language, @@ -267,7 +267,7 @@ class TestEmailCodeLoginApi: mock_revoke_token, mock_get_data, mock_db, - app, + app: Flask, mock_account, mock_token_pair, ): @@ -315,7 +315,7 @@ class TestEmailCodeLoginApi: mock_revoke_token, mock_get_data, mock_db, - app, + app: Flask, mock_account, mock_token_pair, ): @@ -353,7 +353,7 @@ class TestEmailCodeLoginApi: @patch("controllers.console.wraps.db") @patch("controllers.console.auth.login.AccountService.get_email_code_login_data") - def test_email_code_login_invalid_token(self, mock_get_data, mock_db, app): + def test_email_code_login_invalid_token(self, mock_get_data, mock_db, app: Flask): """ Test email code login with invalid token. @@ -375,7 +375,7 @@ class TestEmailCodeLoginApi: @patch("controllers.console.wraps.db") @patch("controllers.console.auth.login.AccountService.get_email_code_login_data") - def test_email_code_login_email_mismatch(self, mock_get_data, mock_db, app): + def test_email_code_login_email_mismatch(self, mock_get_data, mock_db, app: Flask): """ Test email code login with mismatched email. @@ -397,7 +397,7 @@ class TestEmailCodeLoginApi: @patch("controllers.console.wraps.db") @patch("controllers.console.auth.login.AccountService.get_email_code_login_data") - def test_email_code_login_wrong_code(self, mock_get_data, mock_db, app): + def test_email_code_login_wrong_code(self, mock_get_data, mock_db, app: Flask): """ Test email code login with incorrect code. @@ -431,7 +431,7 @@ class TestEmailCodeLoginApi: mock_revoke_token, mock_get_data, mock_db, - app, + app: Flask, mock_account, ): """ @@ -474,7 +474,7 @@ class TestEmailCodeLoginApi: mock_revoke_token, mock_get_data, mock_db, - app, + app: Flask, mock_account, ): """ @@ -515,7 +515,7 @@ class TestEmailCodeLoginApi: mock_revoke_token, mock_get_data, mock_db, - app, + app: Flask, mock_account, ): """ diff --git a/api/tests/unit_tests/controllers/console/auth/test_login_logout.py b/api/tests/unit_tests/controllers/console/auth/test_login_logout.py index d089be8905..ace2ce5706 100644 --- a/api/tests/unit_tests/controllers/console/auth/test_login_logout.py +++ b/api/tests/unit_tests/controllers/console/auth/test_login_logout.py @@ -9,7 +9,7 @@ This module tests the core authentication endpoints including: """ import base64 -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock, Mock, patch import pytest from flask import Flask @@ -52,12 +52,12 @@ class TestLoginApi: return app @pytest.fixture - def api(self, app): + def api(self, app: Flask): """Create Flask-RESTX API instance.""" return Api(app) @pytest.fixture - def client(self, app, api): + def client(self, app: Flask, api: Api): """Create test client.""" api.add_resource(LoginApi, "/login") return app.test_client() @@ -97,7 +97,7 @@ class TestLoginApi: mock_get_invitation, mock_is_rate_limit, mock_db, - app, + app: Flask, mock_account, mock_token_pair, ): @@ -141,14 +141,14 @@ class TestLoginApi: @patch("controllers.console.auth.login.AccountService.reset_login_error_rate_limit") def test_successful_login_with_valid_invitation( self, - mock_reset_rate_limit, + mock_reset_rate_limit: Mock, mock_login, mock_get_tenants, mock_authenticate, mock_get_invitation, mock_is_rate_limit, mock_db, - app, + app: Flask, mock_account, mock_token_pair, ): @@ -188,7 +188,7 @@ class TestLoginApi: @patch("controllers.console.auth.login.dify_config.BILLING_ENABLED", False) @patch("controllers.console.auth.login.AccountService.is_login_error_rate_limit") @patch("controllers.console.auth.login.RegisterService.get_invitation_with_case_fallback") - def test_login_fails_when_rate_limited(self, mock_get_invitation, mock_is_rate_limit, mock_db, app): + def test_login_fails_when_rate_limited(self, mock_get_invitation, mock_is_rate_limit, mock_db, app: Flask): """ Test login rejection when rate limit is exceeded. @@ -216,7 +216,7 @@ class TestLoginApi: @patch("controllers.console.wraps.db") @patch("controllers.console.auth.login.dify_config.BILLING_ENABLED", True) @patch("controllers.console.auth.login.BillingService.is_email_in_freeze") - def test_login_fails_when_account_frozen(self, mock_is_frozen, mock_db, app): + def test_login_fails_when_account_frozen(self, mock_is_frozen, mock_db, app: Flask): """ Test login rejection for frozen accounts. @@ -253,7 +253,7 @@ class TestLoginApi: mock_get_invitation, mock_is_rate_limit, mock_db, - app, + app: Flask, ): """ Test login failure with invalid credentials. @@ -290,7 +290,7 @@ class TestLoginApi: @patch("controllers.console.auth.login.RegisterService.get_invitation_with_case_fallback") @patch("controllers.console.auth.login.AccountService.authenticate") def test_login_fails_for_banned_account( - self, mock_authenticate, mock_get_invitation, mock_is_rate_limit, mock_db, app + self, mock_authenticate, mock_get_invitation, mock_is_rate_limit, mock_db, app: Flask ): """ Test login rejection for banned accounts. @@ -328,14 +328,14 @@ class TestLoginApi: @patch("controllers.console.auth.login.FeatureService.get_system_features") def test_login_fails_when_no_workspace_and_limit_exceeded( self, - mock_get_features, - mock_get_tenants, - mock_authenticate, - mock_get_invitation, - mock_is_rate_limit, - mock_db, - app, - mock_account, + mock_get_features: MagicMock, + mock_get_tenants: MagicMock, + mock_authenticate: MagicMock, + mock_get_invitation: MagicMock, + mock_is_rate_limit: MagicMock, + mock_db: MagicMock, + app: Flask, + mock_account: MagicMock, ): """ Test login failure when user has no workspace and workspace limit exceeded. @@ -367,7 +367,7 @@ class TestLoginApi: @patch("controllers.console.auth.login.dify_config.BILLING_ENABLED", False) @patch("controllers.console.auth.login.AccountService.is_login_error_rate_limit") @patch("controllers.console.auth.login.RegisterService.get_invitation_with_case_fallback") - def test_login_invitation_email_mismatch(self, mock_get_invitation, mock_is_rate_limit, mock_db, app): + def test_login_invitation_email_mismatch(self, mock_get_invitation, mock_is_rate_limit, mock_db, app: Flask): """ Test login failure when invitation email doesn't match login email. @@ -412,7 +412,7 @@ class TestLoginApi: mock_get_invitation, mock_is_rate_limit, mock_db, - app, + app: Flask, mock_account, mock_token_pair, ): @@ -448,7 +448,7 @@ class TestLoginApi: mock_revoke_token, mock_get_token_data, mock_db, - app, + app: Flask, ): mock_get_token_data.return_value = {"email": "User@Example.com", "code": "123456"} mock_get_account.side_effect = Unauthorized("Account is banned.") @@ -491,7 +491,7 @@ class TestLogoutApi: @patch("controllers.console.auth.login.AccountService.logout") @patch("controllers.console.auth.login.flask_login.logout_user") def test_successful_logout( - self, mock_logout_user, mock_service_logout, mock_current_account, mock_db, app, mock_account + self, mock_logout_user, mock_service_logout, mock_current_account, mock_db, app: Flask, mock_account ): """ Test successful logout flow. @@ -518,7 +518,7 @@ class TestLogoutApi: @patch("controllers.console.wraps.db") @patch("controllers.console.auth.login.current_account_with_tenant") @patch("controllers.console.auth.login.flask_login") - def test_logout_anonymous_user(self, mock_flask_login, mock_current_account, mock_db, app): + def test_logout_anonymous_user(self, mock_flask_login, mock_current_account, mock_db, app: Flask): """ Test logout for anonymous (not logged in) user. diff --git a/api/tests/unit_tests/controllers/console/auth/test_token_refresh.py b/api/tests/unit_tests/controllers/console/auth/test_token_refresh.py index d010f60866..22974ca416 100644 --- a/api/tests/unit_tests/controllers/console/auth/test_token_refresh.py +++ b/api/tests/unit_tests/controllers/console/auth/test_token_refresh.py @@ -28,12 +28,12 @@ class TestRefreshTokenApi: return app @pytest.fixture - def api(self, app): + def api(self, app: Flask): """Create Flask-RESTX API instance.""" return Api(app) @pytest.fixture - def client(self, app, api): + def client(self, app: Flask, api: Api): """Create test client.""" api.add_resource(RefreshTokenApi, "/refresh-token") return app.test_client() @@ -74,7 +74,7 @@ class TestRefreshTokenApi: assert response.json["result"] == "success" @patch("controllers.console.auth.login.extract_refresh_token", autospec=True) - def test_refresh_fails_without_token(self, mock_extract_token, app): + def test_refresh_fails_without_token(self, mock_extract_token, app: Flask): """ Test token refresh failure when no refresh token provided. @@ -98,7 +98,7 @@ class TestRefreshTokenApi: @patch("controllers.console.auth.login.extract_refresh_token", autospec=True) @patch("controllers.console.auth.login.AccountService.refresh_token", autospec=True) - def test_refresh_fails_with_invalid_token(self, mock_refresh_token, mock_extract_token, app): + def test_refresh_fails_with_invalid_token(self, mock_refresh_token, mock_extract_token, app: Flask): """ Test token refresh failure with invalid refresh token. @@ -123,7 +123,7 @@ class TestRefreshTokenApi: @patch("controllers.console.auth.login.extract_refresh_token", autospec=True) @patch("controllers.console.auth.login.AccountService.refresh_token", autospec=True) - def test_refresh_fails_with_expired_token(self, mock_refresh_token, mock_extract_token, app): + def test_refresh_fails_with_expired_token(self, mock_refresh_token, mock_extract_token, app: Flask): """ Test token refresh failure with expired refresh token. @@ -148,7 +148,7 @@ class TestRefreshTokenApi: @patch("controllers.console.auth.login.extract_refresh_token", autospec=True) @patch("controllers.console.auth.login.AccountService.refresh_token", autospec=True) - def test_refresh_with_empty_token(self, mock_refresh_token, mock_extract_token, app): + def test_refresh_with_empty_token(self, mock_refresh_token, mock_extract_token, app: Flask): """ Test token refresh with empty string token. diff --git a/api/tests/unit_tests/controllers/console/billing/test_billing.py b/api/tests/unit_tests/controllers/console/billing/test_billing.py index 810f1b94fc..defa9064fd 100644 --- a/api/tests/unit_tests/controllers/console/billing/test_billing.py +++ b/api/tests/unit_tests/controllers/console/billing/test_billing.py @@ -49,7 +49,7 @@ class TestPartnerTenants: mock_csrf.return_value = None yield {"db": mock_db, "csrf": mock_csrf} - def test_put_success(self, app, mock_account, mock_billing_service, mock_decorators): + def test_put_success(self, app: Flask, mock_account, mock_billing_service, mock_decorators): """Test successful partner tenants bindings sync.""" # Arrange partner_key_encoded = base64.b64encode(b"partner-key-123").decode("utf-8") @@ -79,7 +79,7 @@ class TestPartnerTenants: mock_account.id, "partner-key-123", click_id ) - def test_put_invalid_partner_key_base64(self, app, mock_account, mock_billing_service, mock_decorators): + def test_put_invalid_partner_key_base64(self, app: Flask, mock_account, mock_billing_service, mock_decorators): """Test that invalid base64 partner_key raises BadRequest.""" # Arrange invalid_partner_key = "invalid-base64-!@#$" @@ -104,7 +104,7 @@ class TestPartnerTenants: resource.put(invalid_partner_key) assert "Invalid partner_key" in str(exc_info.value) - def test_put_missing_click_id(self, app, mock_account, mock_billing_service, mock_decorators): + def test_put_missing_click_id(self, app: Flask, mock_account, mock_billing_service, mock_decorators): """Test that missing click_id raises BadRequest.""" # Arrange partner_key_encoded = base64.b64encode(b"partner-key-123").decode("utf-8") @@ -128,7 +128,9 @@ class TestPartnerTenants: with pytest.raises(BadRequest): resource.put(partner_key_encoded) - def test_put_billing_service_json_decode_error(self, app, mock_account, mock_billing_service, mock_decorators): + def test_put_billing_service_json_decode_error( + self, app: Flask, mock_account, mock_billing_service, mock_decorators + ): """Test handling of billing service JSON decode error. When billing service returns non-200 status code with invalid JSON response, @@ -174,7 +176,7 @@ class TestPartnerTenants: assert isinstance(exc_info.value, json.JSONDecodeError) assert "Expecting value" in str(exc_info.value) - def test_put_empty_click_id(self, app, mock_account, mock_billing_service, mock_decorators): + def test_put_empty_click_id(self, app: Flask, mock_account, mock_billing_service, mock_decorators): """Test that empty click_id raises BadRequest.""" # Arrange partner_key_encoded = base64.b64encode(b"partner-key-123").decode("utf-8") @@ -199,7 +201,7 @@ class TestPartnerTenants: resource.put(partner_key_encoded) assert "Invalid partner information" in str(exc_info.value) - def test_put_empty_partner_key_after_decode(self, app, mock_account, mock_billing_service, mock_decorators): + def test_put_empty_partner_key_after_decode(self, app: Flask, mock_account, mock_billing_service, mock_decorators): """Test that empty partner_key after decode raises BadRequest.""" # Arrange # Base64 encode an empty string @@ -225,7 +227,7 @@ class TestPartnerTenants: resource.put(empty_partner_key_encoded) assert "Invalid partner information" in str(exc_info.value) - def test_put_empty_user_id(self, app, mock_account, mock_billing_service, mock_decorators): + def test_put_empty_user_id(self, app: Flask, mock_account, mock_billing_service, mock_decorators): """Test that empty user id raises BadRequest.""" # Arrange partner_key_encoded = base64.b64encode(b"partner-key-123").decode("utf-8") diff --git a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_datasource_auth.py b/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_datasource_auth.py index 5136922e88..9c5b5ec256 100644 --- a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_datasource_auth.py +++ b/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_datasource_auth.py @@ -1,6 +1,7 @@ from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.exceptions import Forbidden, NotFound from controllers.console import console_ns @@ -29,7 +30,7 @@ def unwrap(func): class TestDatasourcePluginOAuthAuthorizationUrl: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = DatasourcePluginOAuthAuthorizationUrl() method = unwrap(api.get) @@ -61,7 +62,7 @@ class TestDatasourcePluginOAuthAuthorizationUrl: assert response.status_code == 200 - def test_get_no_oauth_config(self, app): + def test_get_no_oauth_config(self, app: Flask): api = DatasourcePluginOAuthAuthorizationUrl() method = unwrap(api.get) @@ -80,7 +81,7 @@ class TestDatasourcePluginOAuthAuthorizationUrl: with pytest.raises(ValueError): method(api, "notion") - def test_get_without_credential_id_sets_cookie(self, app): + def test_get_without_credential_id_sets_cookie(self, app: Flask): api = DatasourcePluginOAuthAuthorizationUrl() method = unwrap(api.get) @@ -115,7 +116,7 @@ class TestDatasourcePluginOAuthAuthorizationUrl: class TestDatasourceOAuthCallback: - def test_callback_success_new_credential(self, app): + def test_callback_success_new_credential(self, app: Flask): api = DatasourceOAuthCallback() method = unwrap(api.get) @@ -157,7 +158,7 @@ class TestDatasourceOAuthCallback: assert response.status_code == 302 - def test_callback_missing_context(self, app): + def test_callback_missing_context(self, app: Flask): api = DatasourceOAuthCallback() method = unwrap(api.get) @@ -165,7 +166,7 @@ class TestDatasourceOAuthCallback: with pytest.raises(Forbidden): method(api, "notion") - def test_callback_invalid_context(self, app): + def test_callback_invalid_context(self, app: Flask): api = DatasourceOAuthCallback() method = unwrap(api.get) @@ -180,7 +181,7 @@ class TestDatasourceOAuthCallback: with pytest.raises(Forbidden): method(api, "notion") - def test_callback_oauth_config_not_found(self, app): + def test_callback_oauth_config_not_found(self, app: Flask): api = DatasourceOAuthCallback() method = unwrap(api.get) @@ -202,7 +203,7 @@ class TestDatasourceOAuthCallback: with pytest.raises(NotFound): method(api, "notion") - def test_callback_reauthorize_existing_credential(self, app): + def test_callback_reauthorize_existing_credential(self, app: Flask): api = DatasourceOAuthCallback() method = unwrap(api.get) @@ -245,7 +246,7 @@ class TestDatasourceOAuthCallback: assert response.status_code == 302 assert "/oauth-callback" in response.location - def test_callback_context_id_from_cookie(self, app): + def test_callback_context_id_from_cookie(self, app: Flask): api = DatasourceOAuthCallback() method = unwrap(api.get) @@ -289,7 +290,7 @@ class TestDatasourceOAuthCallback: class TestDatasourceAuth: - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = DatasourceAuth() method = unwrap(api.post) @@ -312,7 +313,7 @@ class TestDatasourceAuth: assert status == 200 - def test_post_invalid_credentials(self, app): + def test_post_invalid_credentials(self, app: Flask): api = DatasourceAuth() method = unwrap(api.post) @@ -334,7 +335,7 @@ class TestDatasourceAuth: with pytest.raises(ValueError): method(api, "notion") - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = DatasourceAuth() method = unwrap(api.get) @@ -355,7 +356,7 @@ class TestDatasourceAuth: assert status == 200 assert response["result"] - def test_post_missing_credentials(self, app): + def test_post_missing_credentials(self, app: Flask): api = DatasourceAuth() method = unwrap(api.post) @@ -372,7 +373,7 @@ class TestDatasourceAuth: with pytest.raises(ValueError): method(api, "notion") - def test_get_empty_list(self, app): + def test_get_empty_list(self, app: Flask): api = DatasourceAuth() method = unwrap(api.get) @@ -395,7 +396,7 @@ class TestDatasourceAuth: class TestDatasourceAuthDeleteApi: - def test_delete_success(self, app): + def test_delete_success(self, app: Flask): api = DatasourceAuthDeleteApi() method = unwrap(api.post) @@ -418,7 +419,7 @@ class TestDatasourceAuthDeleteApi: assert status == 200 - def test_delete_missing_credential_id(self, app): + def test_delete_missing_credential_id(self, app: Flask): api = DatasourceAuthDeleteApi() method = unwrap(api.post) @@ -437,7 +438,7 @@ class TestDatasourceAuthDeleteApi: class TestDatasourceAuthUpdateApi: - def test_update_success(self, app): + def test_update_success(self, app: Flask): api = DatasourceAuthUpdateApi() method = unwrap(api.post) @@ -460,7 +461,7 @@ class TestDatasourceAuthUpdateApi: assert status == 201 - def test_update_with_credentials_none(self, app): + def test_update_with_credentials_none(self, app: Flask): api = DatasourceAuthUpdateApi() method = unwrap(api.post) @@ -484,7 +485,7 @@ class TestDatasourceAuthUpdateApi: update_mock.assert_called_once() assert status == 201 - def test_update_name_only(self, app): + def test_update_name_only(self, app: Flask): api = DatasourceAuthUpdateApi() method = unwrap(api.post) @@ -507,7 +508,7 @@ class TestDatasourceAuthUpdateApi: assert status == 201 - def test_update_with_empty_credentials_dict(self, app): + def test_update_with_empty_credentials_dict(self, app: Flask): api = DatasourceAuthUpdateApi() method = unwrap(api.post) @@ -533,7 +534,7 @@ class TestDatasourceAuthUpdateApi: class TestDatasourceAuthListApi: - def test_list_success(self, app): + def test_list_success(self, app: Flask): api = DatasourceAuthListApi() method = unwrap(api.get) @@ -553,7 +554,7 @@ class TestDatasourceAuthListApi: assert status == 200 - def test_auth_list_empty(self, app): + def test_auth_list_empty(self, app: Flask): api = DatasourceAuthListApi() method = unwrap(api.get) @@ -574,7 +575,7 @@ class TestDatasourceAuthListApi: assert status == 200 assert response["result"] == [] - def test_hardcode_list_empty(self, app): + def test_hardcode_list_empty(self, app: Flask): api = DatasourceHardCodeAuthListApi() method = unwrap(api.get) @@ -597,7 +598,7 @@ class TestDatasourceAuthListApi: class TestDatasourceHardCodeAuthListApi: - def test_list_success(self, app): + def test_list_success(self, app: Flask): api = DatasourceHardCodeAuthListApi() method = unwrap(api.get) @@ -619,7 +620,7 @@ class TestDatasourceHardCodeAuthListApi: class TestDatasourceAuthOauthCustomClient: - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = DatasourceAuthOauthCustomClient() method = unwrap(api.post) @@ -642,7 +643,7 @@ class TestDatasourceAuthOauthCustomClient: assert status == 200 - def test_delete_success(self, app): + def test_delete_success(self, app: Flask): api = DatasourceAuthOauthCustomClient() method = unwrap(api.delete) @@ -662,7 +663,7 @@ class TestDatasourceAuthOauthCustomClient: assert status == 200 - def test_post_empty_payload(self, app): + def test_post_empty_payload(self, app: Flask): api = DatasourceAuthOauthCustomClient() method = unwrap(api.post) @@ -685,7 +686,7 @@ class TestDatasourceAuthOauthCustomClient: assert status == 200 - def test_post_disabled_flag(self, app): + def test_post_disabled_flag(self, app: Flask): api = DatasourceAuthOauthCustomClient() method = unwrap(api.post) @@ -714,7 +715,7 @@ class TestDatasourceAuthOauthCustomClient: class TestDatasourceAuthDefaultApi: - def test_set_default_success(self, app): + def test_set_default_success(self, app: Flask): api = DatasourceAuthDefaultApi() method = unwrap(api.post) @@ -737,7 +738,7 @@ class TestDatasourceAuthDefaultApi: assert status == 200 - def test_default_missing_id(self, app): + def test_default_missing_id(self, app: Flask): api = DatasourceAuthDefaultApi() method = unwrap(api.post) @@ -756,7 +757,7 @@ class TestDatasourceAuthDefaultApi: class TestDatasourceUpdateProviderNameApi: - def test_update_name_success(self, app): + def test_update_name_success(self, app: Flask): api = DatasourceUpdateProviderNameApi() method = unwrap(api.post) @@ -779,7 +780,7 @@ class TestDatasourceUpdateProviderNameApi: assert status == 200 - def test_update_name_too_long(self, app): + def test_update_name_too_long(self, app: Flask): api = DatasourceUpdateProviderNameApi() method = unwrap(api.post) @@ -799,7 +800,7 @@ class TestDatasourceUpdateProviderNameApi: with pytest.raises(ValueError): method(api, "notion") - def test_update_name_missing_credential_id(self, app): + def test_update_name_missing_credential_id(self, app: Flask): api = DatasourceUpdateProviderNameApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_datasource_content_preview.py b/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_datasource_content_preview.py index 7a8ccde55a..d4c6a775ec 100644 --- a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_datasource_content_preview.py +++ b/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_datasource_content_preview.py @@ -1,6 +1,7 @@ from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.exceptions import Forbidden from controllers.console import console_ns @@ -25,7 +26,7 @@ class TestDataSourceContentPreviewApi: "credential_id": "cred-1", } - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = DataSourceContentPreviewApi() method = unwrap(api.post) @@ -66,7 +67,7 @@ class TestDataSourceContentPreviewApi: assert status == 200 assert response == preview_result - def test_post_forbidden_non_account_user(self, app): + def test_post_forbidden_non_account_user(self, app: Flask): api = DataSourceContentPreviewApi() method = unwrap(api.post) @@ -85,7 +86,7 @@ class TestDataSourceContentPreviewApi: with pytest.raises(Forbidden): method(api, pipeline, "node-1") - def test_post_invalid_payload(self, app): + def test_post_invalid_payload(self, app: Flask): api = DataSourceContentPreviewApi() method = unwrap(api.post) @@ -108,7 +109,7 @@ class TestDataSourceContentPreviewApi: with pytest.raises(ValueError): method(api, pipeline, "node-1") - def test_post_without_credential_id(self, app): + def test_post_without_credential_id(self, app: Flask): api = DataSourceContentPreviewApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/datasets/test_datasets.py b/api/tests/unit_tests/controllers/console/datasets/test_datasets.py index 9465936f28..e28d68ee5a 100644 --- a/api/tests/unit_tests/controllers/console/datasets/test_datasets.py +++ b/api/tests/unit_tests/controllers/console/datasets/test_datasets.py @@ -2,6 +2,7 @@ import datetime from unittest.mock import MagicMock, PropertyMock, patch import pytest +from flask import Flask from werkzeug.exceptions import BadRequest, Forbidden, NotFound import services @@ -58,7 +59,7 @@ class TestDatasetList: user.is_dataset_editor = True return user - def test_get_success_basic(self, app): + def test_get_success_basic(self, app: Flask): api = DatasetListApi() method = unwrap(api.get) @@ -93,7 +94,7 @@ class TestDatasetList: assert resp["total"] == 1 assert resp["data"][0]["embedding_available"] is True - def test_get_with_ids_filter(self, app): + def test_get_with_ids_filter(self, app: Flask): api = DatasetListApi() method = unwrap(api.get) @@ -128,7 +129,7 @@ class TestDatasetList: assert status == 200 assert resp["total"] == 2 - def test_get_with_tag_ids(self, app): + def test_get_with_tag_ids(self, app: Flask): api = DatasetListApi() method = unwrap(api.get) @@ -161,7 +162,7 @@ class TestDatasetList: assert status == 200 - def test_embedding_available_false(self, app): + def test_embedding_available_false(self, app: Flask): api = DatasetListApi() method = unwrap(api.get) @@ -203,7 +204,7 @@ class TestDatasetList: assert resp["data"][0]["embedding_available"] is False - def test_partial_members_permission(self, app): + def test_partial_members_permission(self, app: Flask): api = DatasetListApi() method = unwrap(api.get) @@ -242,7 +243,7 @@ class TestDatasetList: class TestDatasetListApiPost: - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = DatasetListApi() method = unwrap(api.post) @@ -290,7 +291,7 @@ class TestDatasetListApiPost: assert status == 201 - def test_post_forbidden(self, app): + def test_post_forbidden(self, app: Flask): api = DatasetListApi() method = unwrap(api.post) @@ -310,7 +311,7 @@ class TestDatasetListApiPost: with pytest.raises(Forbidden): method(api) - def test_post_duplicate_name(self, app): + def test_post_duplicate_name(self, app: Flask): api = DatasetListApi() method = unwrap(api.post) @@ -335,7 +336,7 @@ class TestDatasetListApiPost: with pytest.raises(DatasetNameDuplicateError): method(api) - def test_post_invalid_payload_missing_name(self, app): + def test_post_invalid_payload_missing_name(self, app: Flask): api = DatasetListApi() method = unwrap(api.post) @@ -343,7 +344,7 @@ class TestDatasetListApiPost: with pytest.raises(ValueError): method(api) - def test_post_invalid_indexing_technique(self, app): + def test_post_invalid_indexing_technique(self, app: Flask): api = DatasetListApi() method = unwrap(api.post) @@ -356,7 +357,7 @@ class TestDatasetListApiPost: with pytest.raises(ValueError, match="Invalid indexing technique"): method(api) - def test_post_invalid_provider(self, app): + def test_post_invalid_provider(self, app: Flask): api = DatasetListApi() method = unwrap(api.post) @@ -371,7 +372,7 @@ class TestDatasetListApiPost: class TestDatasetApiGet: - def test_get_success_basic(self, app): + def test_get_success_basic(self, app: Flask): api = DatasetApi() method = unwrap(api.get) @@ -427,7 +428,7 @@ class TestDatasetApiGet: assert status == 200 assert data["embedding_available"] is True - def test_get_dataset_not_found(self, app): + def test_get_dataset_not_found(self, app: Flask): api = DatasetApi() method = unwrap(api.get) @@ -448,7 +449,7 @@ class TestDatasetApiGet: with pytest.raises(NotFound, match="Dataset not found"): method(api, dataset_id) - def test_get_permission_denied(self, app): + def test_get_permission_denied(self, app: Flask): api = DatasetApi() method = unwrap(api.get) @@ -475,7 +476,7 @@ class TestDatasetApiGet: with pytest.raises(Forbidden, match="no access"): method(api, dataset_id) - def test_get_high_quality_embedding_unavailable(self, app): + def test_get_high_quality_embedding_unavailable(self, app: Flask): api = DatasetApi() method = unwrap(api.get) @@ -530,7 +531,7 @@ class TestDatasetApiGet: assert data["embedding_available"] is False - def test_get_partial_members_permission(self, app): + def test_get_partial_members_permission(self, app: Flask): api = DatasetApi() method = unwrap(api.get) @@ -590,7 +591,7 @@ class TestDatasetApiGet: class TestDatasetApiPatch: - def test_patch_success_basic(self, app): + def test_patch_success_basic(self, app: Flask): api = DatasetApi() method = unwrap(api.patch) @@ -659,7 +660,7 @@ class TestDatasetApiPatch: assert status == 200 assert result["partial_member_list"] == [] - def test_patch_dataset_not_found(self, app): + def test_patch_dataset_not_found(self, app: Flask): api = DatasetApi() method = unwrap(api.patch) @@ -674,7 +675,7 @@ class TestDatasetApiPatch: with pytest.raises(NotFound, match="Dataset not found"): method(api, "missing") - def test_patch_permission_denied(self, app): + def test_patch_permission_denied(self, app: Flask): api = DatasetApi() method = unwrap(api.patch) @@ -704,7 +705,7 @@ class TestDatasetApiPatch: with pytest.raises(Forbidden): method(api, dataset_id) - def test_patch_partial_members_update(self, app): + def test_patch_partial_members_update(self, app: Flask): api = DatasetApi() method = unwrap(api.patch) @@ -773,7 +774,7 @@ class TestDatasetApiPatch: assert result["partial_member_list"] == payload["partial_member_list"] - def test_patch_clear_partial_members(self, app): + def test_patch_clear_partial_members(self, app: Flask): api = DatasetApi() method = unwrap(api.patch) @@ -843,7 +844,7 @@ class TestDatasetApiPatch: class TestDatasetApiDelete: - def test_delete_success(self, app): + def test_delete_success(self, app: Flask): api = DatasetApi() method = unwrap(api.delete) @@ -874,7 +875,7 @@ class TestDatasetApiDelete: assert status == 204 assert result == {"result": "success"} - def test_delete_forbidden_no_permission(self, app): + def test_delete_forbidden_no_permission(self, app: Flask): api = DatasetApi() method = unwrap(api.delete) @@ -893,7 +894,7 @@ class TestDatasetApiDelete: with pytest.raises(Forbidden): method(api, dataset_id) - def test_delete_dataset_not_found(self, app): + def test_delete_dataset_not_found(self, app: Flask): api = DatasetApi() method = unwrap(api.delete) @@ -917,7 +918,7 @@ class TestDatasetApiDelete: with pytest.raises(NotFound, match="Dataset not found"): method(api, dataset_id) - def test_delete_dataset_in_use(self, app): + def test_delete_dataset_in_use(self, app: Flask): api = DatasetApi() method = unwrap(api.delete) @@ -943,7 +944,7 @@ class TestDatasetApiDelete: class TestDatasetUseCheckApi: - def test_get_use_check_true(self, app): + def test_get_use_check_true(self, app: Flask): api = DatasetUseCheckApi() method = unwrap(api.get) @@ -962,7 +963,7 @@ class TestDatasetUseCheckApi: assert status == 200 assert result == {"is_using": True} - def test_get_use_check_false(self, app): + def test_get_use_check_false(self, app: Flask): api = DatasetUseCheckApi() method = unwrap(api.get) @@ -983,7 +984,7 @@ class TestDatasetUseCheckApi: class TestDatasetQueryApi: - def test_get_queries_success(self, app): + def test_get_queries_success(self, app: Flask): api = DatasetQueryApi() method = unwrap(api.get) @@ -1027,7 +1028,7 @@ class TestDatasetQueryApi: assert response["has_more"] is False assert len(response["data"]) == 2 - def test_get_queries_dataset_not_found(self, app): + def test_get_queries_dataset_not_found(self, app: Flask): api = DatasetQueryApi() method = unwrap(api.get) @@ -1049,7 +1050,7 @@ class TestDatasetQueryApi: with pytest.raises(NotFound, match="Dataset not found"): method(api, dataset_id) - def test_get_queries_permission_denied(self, app): + def test_get_queries_permission_denied(self, app: Flask): api = DatasetQueryApi() method = unwrap(api.get) @@ -1078,7 +1079,7 @@ class TestDatasetQueryApi: with pytest.raises(Forbidden): method(api, dataset_id) - def test_get_queries_pagination_has_more(self, app): + def test_get_queries_pagination_has_more(self, app: Flask): api = DatasetQueryApi() method = unwrap(api.get) @@ -1152,7 +1153,7 @@ class TestDatasetIndexingEstimateApi: "dataset_id": None, } - def test_post_success_upload_file(self, app): + def test_post_success_upload_file(self, app: Flask): api = DatasetIndexingEstimateApi() method = unwrap(api.post) @@ -1193,7 +1194,7 @@ class TestDatasetIndexingEstimateApi: assert status == 200 assert response == {"tokens": 100} - def test_post_file_not_found(self, app): + def test_post_file_not_found(self, app: Flask): api = DatasetIndexingEstimateApi() method = unwrap(api.post) @@ -1223,7 +1224,7 @@ class TestDatasetIndexingEstimateApi: with pytest.raises(NotFound): method(api) - def test_post_llm_bad_request_error(self, app): + def test_post_llm_bad_request_error(self, app: Flask): api = DatasetIndexingEstimateApi() method = unwrap(api.post) mock_file = self._upload_file() @@ -1258,7 +1259,7 @@ class TestDatasetIndexingEstimateApi: with pytest.raises(ProviderNotInitializeError): method(api) - def test_post_provider_token_not_init(self, app): + def test_post_provider_token_not_init(self, app: Flask): api = DatasetIndexingEstimateApi() method = unwrap(api.post) mock_file = self._upload_file() @@ -1293,7 +1294,7 @@ class TestDatasetIndexingEstimateApi: with pytest.raises(ProviderNotInitializeError): method(api) - def test_post_generic_exception(self, app): + def test_post_generic_exception(self, app: Flask): api = DatasetIndexingEstimateApi() method = unwrap(api.post) mock_file = self._upload_file() @@ -1330,7 +1331,7 @@ class TestDatasetIndexingEstimateApi: class TestDatasetRelatedAppListApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = DatasetRelatedAppListApi() method = unwrap(api.get) @@ -1368,7 +1369,7 @@ class TestDatasetRelatedAppListApi: assert response["total"] == 2 assert response["data"] == [app1, app2] - def test_get_dataset_not_found(self, app): + def test_get_dataset_not_found(self, app: Flask): api = DatasetRelatedAppListApi() method = unwrap(api.get) @@ -1386,7 +1387,7 @@ class TestDatasetRelatedAppListApi: with pytest.raises(NotFound): method(api, "dataset-1") - def test_get_permission_denied(self, app): + def test_get_permission_denied(self, app: Flask): api = DatasetRelatedAppListApi() method = unwrap(api.get) @@ -1410,7 +1411,7 @@ class TestDatasetRelatedAppListApi: with pytest.raises(Forbidden): method(api, "dataset-1") - def test_get_filters_none_apps(self, app): + def test_get_filters_none_apps(self, app: Flask): api = DatasetRelatedAppListApi() method = unwrap(api.get) @@ -1449,7 +1450,7 @@ class TestDatasetRelatedAppListApi: class TestDatasetIndexingStatusApi: - def test_get_success_with_documents(self, app): + def test_get_success_with_documents(self, app: Flask): api = DatasetIndexingStatusApi() method = unwrap(api.get) @@ -1490,7 +1491,7 @@ class TestDatasetIndexingStatusApi: assert item["completed_segments"] == 3 assert item["total_segments"] == 3 - def test_get_success_no_documents(self, app): + def test_get_success_no_documents(self, app: Flask): api = DatasetIndexingStatusApi() method = unwrap(api.get) @@ -1510,7 +1511,7 @@ class TestDatasetIndexingStatusApi: assert status == 200 assert response == {"data": []} - def test_segment_counts_different_values(self, app): + def test_segment_counts_different_values(self, app: Flask): api = DatasetIndexingStatusApi() method = unwrap(api.get) @@ -1550,7 +1551,7 @@ class TestDatasetIndexingStatusApi: class TestDatasetApiKeyApi: - def test_get_api_keys_success(self, app): + def test_get_api_keys_success(self, app: Flask): api = DatasetApiKeyApi() method = unwrap(api.get) @@ -1587,7 +1588,7 @@ class TestDatasetApiKeyApi: assert response["data"][1]["id"] == "key-2" assert response["data"][1]["token"] == "ds-def" - def test_post_create_api_key_success(self, app): + def test_post_create_api_key_success(self, app: Flask): api = DatasetApiKeyApi() method = unwrap(api.post) @@ -1632,7 +1633,7 @@ class TestDatasetApiKeyApi: assert response["type"] == "dataset" assert response["created_at"] is not None - def test_post_exceed_max_keys(self, app): + def test_post_exceed_max_keys(self, app: Flask): api = DatasetApiKeyApi() method = unwrap(api.post) @@ -1658,7 +1659,7 @@ class TestDatasetApiKeyApi: class TestDatasetApiDeleteApi: - def test_delete_success(self, app): + def test_delete_success(self, app: Flask): api = DatasetApiDeleteApi() method = unwrap(api.delete) @@ -1688,7 +1689,7 @@ class TestDatasetApiDeleteApi: assert status == 204 assert response["result"] == "success" - def test_delete_key_not_found(self, app): + def test_delete_key_not_found(self, app: Flask): api = DatasetApiDeleteApi() method = unwrap(api.delete) @@ -1708,7 +1709,7 @@ class TestDatasetApiDeleteApi: class TestDatasetEnableApiApi: - def test_enable_api(self, app): + def test_enable_api(self, app: Flask): api = DatasetEnableApiApi() method = unwrap(api.post) @@ -1724,7 +1725,7 @@ class TestDatasetEnableApiApi: assert status == 200 assert response["result"] == "success" - def test_disable_api(self, app): + def test_disable_api(self, app: Flask): api = DatasetEnableApiApi() method = unwrap(api.post) @@ -1742,7 +1743,7 @@ class TestDatasetEnableApiApi: class TestDatasetApiBaseUrlApi: - def test_get_api_base_url_from_config(self, app): + def test_get_api_base_url_from_config(self, app: Flask): api = DatasetApiBaseUrlApi() method = unwrap(api.get) @@ -1757,7 +1758,7 @@ class TestDatasetApiBaseUrlApi: assert response["api_base_url"] == "https://example.com/v1" - def test_get_api_base_url_from_request(self, app): + def test_get_api_base_url_from_request(self, app: Flask): api = DatasetApiBaseUrlApi() method = unwrap(api.get) @@ -1772,7 +1773,7 @@ class TestDatasetApiBaseUrlApi: assert response["api_base_url"] == "http://localhost:5000/v1" - def test_get_api_base_url_no_double_v1(self, app): + def test_get_api_base_url_no_double_v1(self, app: Flask): api = DatasetApiBaseUrlApi() method = unwrap(api.get) @@ -1789,7 +1790,7 @@ class TestDatasetApiBaseUrlApi: class TestDatasetRetrievalSettingApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = DatasetRetrievalSettingApi() method = unwrap(api.get) @@ -1810,7 +1811,7 @@ class TestDatasetRetrievalSettingApi: class TestDatasetRetrievalSettingMockApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = DatasetRetrievalSettingMockApi() method = unwrap(api.get) @@ -1827,7 +1828,7 @@ class TestDatasetRetrievalSettingMockApi: class TestDatasetErrorDocs: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = DatasetErrorDocs() method = unwrap(api.get) @@ -1850,7 +1851,7 @@ class TestDatasetErrorDocs: assert status == 200 assert response["total"] == 1 - def test_get_dataset_not_found(self, app): + def test_get_dataset_not_found(self, app: Flask): api = DatasetErrorDocs() method = unwrap(api.get) @@ -1866,7 +1867,7 @@ class TestDatasetErrorDocs: class TestDatasetPermissionUserListApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = DatasetPermissionUserListApi() method = unwrap(api.get) @@ -1897,7 +1898,7 @@ class TestDatasetPermissionUserListApi: assert status == 200 assert response["data"] == users - def test_get_permission_denied(self, app): + def test_get_permission_denied(self, app: Flask): api = DatasetPermissionUserListApi() method = unwrap(api.get) @@ -1923,7 +1924,7 @@ class TestDatasetPermissionUserListApi: class TestDatasetAutoDisableLogApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = DatasetAutoDisableLogApi() method = unwrap(api.get) @@ -1946,7 +1947,7 @@ class TestDatasetAutoDisableLogApi: assert status == 200 assert response == logs - def test_get_dataset_not_found(self, app): + def test_get_dataset_not_found(self, app: Flask): api = DatasetAutoDisableLogApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/datasets/test_datasets_document.py b/api/tests/unit_tests/controllers/console/datasets/test_datasets_document.py index d9b02ac453..ff9e1736d2 100644 --- a/api/tests/unit_tests/controllers/console/datasets/test_datasets_document.py +++ b/api/tests/unit_tests/controllers/console/datasets/test_datasets_document.py @@ -2,6 +2,7 @@ from types import SimpleNamespace from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.exceptions import Forbidden, NotFound import services @@ -239,7 +240,7 @@ class TestDatasetDocumentListApi: assert "documents" in response - def test_post_forbidden(self, app): + def test_post_forbidden(self, app: Flask): api = DatasetDocumentListApi() method = unwrap(api.post) @@ -395,7 +396,7 @@ class TestDocumentDownloadApi: class TestDocumentProcessingApi: - def test_processing_forbidden_when_not_editor(self, app): + def test_processing_forbidden_when_not_editor(self, app: Flask): api = DocumentProcessingApi() method = unwrap(api.patch) @@ -1185,7 +1186,7 @@ class TestDocumentPermissionCases: "preview": [], } - def test_document_tenant_mismatch(self, app): + def test_document_tenant_mismatch(self, app: Flask): api = DocumentApi() method = unwrap(api.get) @@ -1253,7 +1254,7 @@ class TestDocumentPermissionCases: assert status == 200 assert response["mode"] == "custom" - def test_process_rule_permission_denied(self, app): + def test_process_rule_permission_denied(self, app: Flask): api = GetProcessRuleApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/datasets/test_datasets_segments.py b/api/tests/unit_tests/controllers/console/datasets/test_datasets_segments.py index 693b06e95b..412edb9dfe 100644 --- a/api/tests/unit_tests/controllers/console/datasets/test_datasets_segments.py +++ b/api/tests/unit_tests/controllers/console/datasets/test_datasets_segments.py @@ -2,6 +2,7 @@ from types import SimpleNamespace from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.exceptions import Forbidden, NotFound import services @@ -82,7 +83,7 @@ def test_get_segment_with_summary(monkeypatch): class TestDatasetDocumentSegmentListApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = DatasetDocumentSegmentListApi() method = unwrap(api.get) @@ -132,7 +133,7 @@ class TestDatasetDocumentSegmentListApi: assert status == 200 - def test_get_dataset_not_found(self, app): + def test_get_dataset_not_found(self, app: Flask): api = DatasetDocumentSegmentListApi() method = unwrap(api.get) @@ -150,7 +151,7 @@ class TestDatasetDocumentSegmentListApi: with pytest.raises(NotFound): method(api, "ds-1", "doc-1") - def test_get_permission_denied(self, app): + def test_get_permission_denied(self, app: Flask): api = DatasetDocumentSegmentListApi() method = unwrap(api.get) @@ -176,7 +177,7 @@ class TestDatasetDocumentSegmentListApi: class TestDatasetDocumentSegmentApi: - def test_patch_success(self, app): + def test_patch_success(self, app: Flask): api = DatasetDocumentSegmentApi() method = unwrap(api.patch) @@ -221,7 +222,7 @@ class TestDatasetDocumentSegmentApi: assert status == 200 assert response["result"] == "success" - def test_patch_document_indexing_in_progress(self, app): + def test_patch_document_indexing_in_progress(self, app: Flask): api = DatasetDocumentSegmentApi() method = unwrap(api.patch) @@ -264,7 +265,7 @@ class TestDatasetDocumentSegmentApi: with pytest.raises(InvalidActionError): method(api, "ds-1", "doc-1", "disable") - def test_patch_llm_bad_request(self, app): + def test_patch_llm_bad_request(self, app: Flask): api = DatasetDocumentSegmentApi() method = unwrap(api.patch) @@ -308,7 +309,7 @@ class TestDatasetDocumentSegmentApi: with pytest.raises(ProviderNotInitializeError): method(api, "ds-1", "doc-1", "enable") - def test_patch_provider_token_not_init(self, app): + def test_patch_provider_token_not_init(self, app: Flask): api = DatasetDocumentSegmentApi() method = unwrap(api.patch) @@ -354,7 +355,7 @@ class TestDatasetDocumentSegmentApi: class TestDatasetDocumentSegmentAddApi: - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = DatasetDocumentSegmentAddApi() method = unwrap(api.post) @@ -413,7 +414,7 @@ class TestDatasetDocumentSegmentAddApi: assert status == 200 assert response["data"]["id"] == "seg-1" - def test_post_llm_bad_request(self, app): + def test_post_llm_bad_request(self, app: Flask): api = DatasetDocumentSegmentAddApi() method = unwrap(api.post) @@ -452,7 +453,7 @@ class TestDatasetDocumentSegmentAddApi: with pytest.raises(ProviderNotInitializeError): method(api, "ds-1", "doc-1") - def test_post_provider_token_not_init(self, app): + def test_post_provider_token_not_init(self, app: Flask): api = DatasetDocumentSegmentAddApi() method = unwrap(api.post) @@ -493,7 +494,7 @@ class TestDatasetDocumentSegmentAddApi: class TestDatasetDocumentSegmentUpdateApi: - def test_patch_success(self, app): + def test_patch_success(self, app: Flask): api = DatasetDocumentSegmentUpdateApi() method = unwrap(api.patch) @@ -551,7 +552,7 @@ class TestDatasetDocumentSegmentUpdateApi: assert status == 200 assert "data" in response - def test_patch_llm_bad_request(self, app): + def test_patch_llm_bad_request(self, app: Flask): api = DatasetDocumentSegmentUpdateApi() method = unwrap(api.patch) @@ -596,7 +597,7 @@ class TestDatasetDocumentSegmentUpdateApi: class TestDatasetDocumentSegmentBatchImportApi: - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = DatasetDocumentSegmentBatchImportApi() method = unwrap(api.post) @@ -638,7 +639,7 @@ class TestDatasetDocumentSegmentBatchImportApi: assert status == 200 assert response["job_status"] == "waiting" - def test_post_dataset_not_found(self, app): + def test_post_dataset_not_found(self, app: Flask): api = DatasetDocumentSegmentBatchImportApi() method = unwrap(api.post) @@ -659,7 +660,7 @@ class TestDatasetDocumentSegmentBatchImportApi: with pytest.raises(NotFound): method(api, "ds-1", "doc-1") - def test_post_document_not_found(self, app): + def test_post_document_not_found(self, app: Flask): api = DatasetDocumentSegmentBatchImportApi() method = unwrap(api.post) @@ -684,7 +685,7 @@ class TestDatasetDocumentSegmentBatchImportApi: with pytest.raises(NotFound): method(api, "ds-1", "doc-1") - def test_post_upload_file_not_found(self, app): + def test_post_upload_file_not_found(self, app: Flask): api = DatasetDocumentSegmentBatchImportApi() method = unwrap(api.post) @@ -713,7 +714,7 @@ class TestDatasetDocumentSegmentBatchImportApi: with pytest.raises(NotFound): method(api, "ds-1", "doc-1") - def test_post_invalid_file_type(self, app): + def test_post_invalid_file_type(self, app: Flask): api = DatasetDocumentSegmentBatchImportApi() method = unwrap(api.post) @@ -745,7 +746,7 @@ class TestDatasetDocumentSegmentBatchImportApi: with pytest.raises(ValueError): method(api, "ds-1", "doc-1") - def test_post_async_task_failure(self, app): + def test_post_async_task_failure(self, app: Flask): api = DatasetDocumentSegmentBatchImportApi() method = unwrap(api.post) @@ -783,7 +784,7 @@ class TestDatasetDocumentSegmentBatchImportApi: assert status == 500 assert "error" in response - def test_get_job_not_found_in_redis(self, app): + def test_get_job_not_found_in_redis(self, app: Flask): api = DatasetDocumentSegmentBatchImportApi() method = unwrap(api.get) @@ -799,7 +800,7 @@ class TestDatasetDocumentSegmentBatchImportApi: class TestChildChunkAddApi: - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = ChildChunkAddApi() method = unwrap(api.post) @@ -852,7 +853,7 @@ class TestChildChunkAddApi: assert status == 200 assert response["data"]["id"] == "cc-1" - def test_post_child_chunk_indexing_error(self, app): + def test_post_child_chunk_indexing_error(self, app: Flask): api = ChildChunkAddApi() method = unwrap(api.post) @@ -897,7 +898,7 @@ class TestChildChunkAddApi: class TestChildChunkUpdateApi: - def test_delete_success(self, app): + def test_delete_success(self, app: Flask): api = ChildChunkUpdateApi() method = unwrap(api.delete) @@ -941,7 +942,7 @@ class TestChildChunkUpdateApi: assert status == 204 assert response["result"] == "success" - def test_delete_child_chunk_index_error(self, app): + def test_delete_child_chunk_index_error(self, app: Flask): api = ChildChunkUpdateApi() method = unwrap(api.delete) @@ -984,7 +985,7 @@ class TestChildChunkUpdateApi: class TestSegmentListAdvancedCases: - def test_segment_list_with_keyword_filter(self, app): + def test_segment_list_with_keyword_filter(self, app: Flask): api = DatasetDocumentSegmentListApi() method = unwrap(api.get) @@ -1035,7 +1036,7 @@ class TestSegmentListAdvancedCases: assert status == 200 assert response["total"] == 1 - def test_segment_list_permission_denied(self, app): + def test_segment_list_permission_denied(self, app: Flask): """Test segment list with permission denied""" api = DatasetDocumentSegmentListApi() method = unwrap(api.get) @@ -1058,7 +1059,7 @@ class TestSegmentListAdvancedCases: with pytest.raises(Forbidden): method(api, "ds-1", "doc-1") - def test_segment_list_dataset_not_found(self, app): + def test_segment_list_dataset_not_found(self, app: Flask): """Test segment list with dataset not found""" api = DatasetDocumentSegmentListApi() method = unwrap(api.get) @@ -1079,7 +1080,7 @@ class TestSegmentListAdvancedCases: class TestSegmentOperationCases: - def test_segment_add_with_provider_token_error(self, app): + def test_segment_add_with_provider_token_error(self, app: Flask): """Test segment add with provider token not initialized""" api = DatasetDocumentSegmentAddApi() method = unwrap(api.post) @@ -1117,7 +1118,7 @@ class TestSegmentOperationCases: with pytest.raises(ProviderTokenNotInitError): method(api, "ds-1", "doc-1") - def test_batch_import_with_document_not_found(self, app): + def test_batch_import_with_document_not_found(self, app: Flask): """Test batch import with document not found""" api = DatasetDocumentSegmentBatchImportApi() method = unwrap(api.post) @@ -1146,7 +1147,7 @@ class TestSegmentOperationCases: with pytest.raises(NotFound): method(api, "ds-1", "doc-1") - def test_batch_import_with_invalid_file(self, app): + def test_batch_import_with_invalid_file(self, app: Flask): """Test batch import with invalid file type""" api = DatasetDocumentSegmentBatchImportApi() method = unwrap(api.post) @@ -1181,7 +1182,7 @@ class TestSegmentOperationCases: with pytest.raises(NotFound): method(api, "ds-1", "doc-1") - def test_batch_import_with_async_task_failure(self, app): + def test_batch_import_with_async_task_failure(self, app: Flask): api = DatasetDocumentSegmentBatchImportApi() method = unwrap(api.post) @@ -1226,7 +1227,7 @@ class TestSegmentOperationCases: assert status == 500 assert "error" in response - def test_batch_import_get_job_not_found(self, app): + def test_batch_import_get_job_not_found(self, app: Flask): api = DatasetDocumentSegmentBatchImportApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/datasets/test_external.py b/api/tests/unit_tests/controllers/console/datasets/test_external.py index 514bbbe040..7254bf7670 100644 --- a/api/tests/unit_tests/controllers/console/datasets/test_external.py +++ b/api/tests/unit_tests/controllers/console/datasets/test_external.py @@ -57,7 +57,7 @@ def mock_auth(monkeypatch, current_user): class TestExternalApiTemplateListApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = ExternalApiTemplateListApi() method = unwrap(api.get) @@ -78,7 +78,7 @@ class TestExternalApiTemplateListApi: assert resp["total"] == 1 assert resp["data"][0]["id"] == "1" - def test_post_forbidden(self, app, current_user): + def test_post_forbidden(self, app: Flask, current_user): current_user.is_dataset_editor = False api = ExternalApiTemplateListApi() method = unwrap(api.post) @@ -93,7 +93,7 @@ class TestExternalApiTemplateListApi: with pytest.raises(Forbidden): method(api) - def test_post_duplicate_name(self, app): + def test_post_duplicate_name(self, app: Flask): api = ExternalApiTemplateListApi() method = unwrap(api.post) @@ -114,7 +114,7 @@ class TestExternalApiTemplateListApi: class TestExternalApiTemplateApi: - def test_get_not_found(self, app): + def test_get_not_found(self, app: Flask): api = ExternalApiTemplateApi() method = unwrap(api.get) @@ -129,7 +129,7 @@ class TestExternalApiTemplateApi: with pytest.raises(NotFound): method(api, "api-id") - def test_delete_forbidden(self, app, current_user): + def test_delete_forbidden(self, app: Flask, current_user): current_user.has_edit_permission = False current_user.is_dataset_operator = False @@ -142,7 +142,7 @@ class TestExternalApiTemplateApi: class TestExternalApiUseCheckApi: - def test_get_scopes_usage_check_to_current_tenant(self, app): + def test_get_scopes_usage_check_to_current_tenant(self, app: Flask): api = ExternalApiUseCheckApi() method = unwrap(api.get) @@ -162,7 +162,7 @@ class TestExternalApiUseCheckApi: class TestExternalDatasetCreateApi: - def test_create_success(self, app): + def test_create_success(self, app: Flask): api = ExternalDatasetCreateApi() method = unwrap(api.post) @@ -206,7 +206,7 @@ class TestExternalDatasetCreateApi: assert status == 201 - def test_create_forbidden(self, app, current_user): + def test_create_forbidden(self, app: Flask, current_user): current_user.is_dataset_editor = False api = ExternalDatasetCreateApi() method = unwrap(api.post) @@ -226,7 +226,7 @@ class TestExternalDatasetCreateApi: class TestExternalKnowledgeHitTestingApi: - def test_hit_testing_dataset_not_found(self, app): + def test_hit_testing_dataset_not_found(self, app: Flask): api = ExternalKnowledgeHitTestingApi() method = unwrap(api.post) @@ -241,7 +241,7 @@ class TestExternalKnowledgeHitTestingApi: with pytest.raises(NotFound): method(api, "dataset-id") - def test_hit_testing_success(self, app): + def test_hit_testing_success(self, app: Flask): api = ExternalKnowledgeHitTestingApi() method = unwrap(api.post) @@ -266,7 +266,7 @@ class TestExternalKnowledgeHitTestingApi: class TestBedrockRetrievalApi: - def test_bedrock_retrieval(self, app): + def test_bedrock_retrieval(self, app: Flask): api = BedrockRetrievalApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/datasets/test_metadata.py b/api/tests/unit_tests/controllers/console/datasets/test_metadata.py index de834c2d4d..0105aacd65 100644 --- a/api/tests/unit_tests/controllers/console/datasets/test_metadata.py +++ b/api/tests/unit_tests/controllers/console/datasets/test_metadata.py @@ -269,7 +269,7 @@ class TestDatasetMetadataApi: class TestDatasetMetadataBuiltInFieldApi: - def test_get_built_in_fields(self, app): + def test_get_built_in_fields(self, app: Flask): api = DatasetMetadataBuiltInFieldApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/explore/test_banner.py b/api/tests/unit_tests/controllers/console/explore/test_banner.py index c8f674f515..d1cb6b6a03 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_banner.py +++ b/api/tests/unit_tests/controllers/console/explore/test_banner.py @@ -1,6 +1,8 @@ from datetime import datetime from unittest.mock import MagicMock, patch +from flask import Flask + import controllers.console.explore.banner as banner_module from models.enums import BannerStatus @@ -12,7 +14,7 @@ def unwrap(func): class TestBannerApi: - def test_get_banners_with_requested_language(self, app): + def test_get_banners_with_requested_language(self, app: Flask): api = banner_module.BannerApi() method = unwrap(api.get) @@ -41,7 +43,7 @@ class TestBannerApi: } ] - def test_get_banners_fallback_to_en_us(self, app): + def test_get_banners_fallback_to_en_us(self, app: Flask): api = banner_module.BannerApi() method = unwrap(api.get) @@ -76,7 +78,7 @@ class TestBannerApi: } ] - def test_get_banners_default_language_en_us(self, app): + def test_get_banners_default_language_en_us(self, app: Flask): api = banner_module.BannerApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/explore/test_message.py b/api/tests/unit_tests/controllers/console/explore/test_message.py index 145cc9cdd7..3d41489435 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_message.py +++ b/api/tests/unit_tests/controllers/console/explore/test_message.py @@ -1,6 +1,7 @@ from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.exceptions import InternalServerError, NotFound import controllers.console.explore.message as module @@ -54,7 +55,7 @@ def make_message(): class TestMessageListApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = module.MessageListApi() method = unwrap(api.get) @@ -96,7 +97,7 @@ class TestMessageListApi: with pytest.raises(NotChatAppError): method(installed_app) - def test_conversation_not_exists(self, app): + def test_conversation_not_exists(self, app: Flask): api = module.MessageListApi() method = unwrap(api.get) @@ -118,7 +119,7 @@ class TestMessageListApi: with pytest.raises(NotFound): method(installed_app) - def test_first_message_not_exists(self, app): + def test_first_message_not_exists(self, app: Flask): api = module.MessageListApi() method = unwrap(api.get) @@ -142,7 +143,7 @@ class TestMessageListApi: class TestMessageFeedbackApi: - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = module.MessageFeedbackApi() method = unwrap(api.post) @@ -161,7 +162,7 @@ class TestMessageFeedbackApi: assert result["result"] == "success" - def test_message_not_exists(self, app): + def test_message_not_exists(self, app: Flask): api = module.MessageFeedbackApi() method = unwrap(api.post) @@ -182,7 +183,7 @@ class TestMessageFeedbackApi: class TestMessageMoreLikeThisApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = module.MessageMoreLikeThisApi() method = unwrap(api.get) @@ -221,7 +222,7 @@ class TestMessageMoreLikeThisApi: with pytest.raises(NotCompletionAppError): method(installed_app, "mid") - def test_more_like_this_disabled(self, app): + def test_more_like_this_disabled(self, app: Flask): api = module.MessageMoreLikeThisApi() method = unwrap(api.get) @@ -243,7 +244,7 @@ class TestMessageMoreLikeThisApi: with pytest.raises(AppMoreLikeThisDisabledError): method(installed_app, "mid") - def test_message_not_exists_more_like_this(self, app): + def test_message_not_exists_more_like_this(self, app: Flask): api = module.MessageMoreLikeThisApi() method = unwrap(api.get) @@ -265,7 +266,7 @@ class TestMessageMoreLikeThisApi: with pytest.raises(NotFound): method(installed_app, "mid") - def test_provider_not_init_more_like_this(self, app): + def test_provider_not_init_more_like_this(self, app: Flask): api = module.MessageMoreLikeThisApi() method = unwrap(api.get) @@ -287,7 +288,7 @@ class TestMessageMoreLikeThisApi: with pytest.raises(ProviderNotInitializeError): method(installed_app, "mid") - def test_quota_exceeded_more_like_this(self, app): + def test_quota_exceeded_more_like_this(self, app: Flask): api = module.MessageMoreLikeThisApi() method = unwrap(api.get) @@ -309,7 +310,7 @@ class TestMessageMoreLikeThisApi: with pytest.raises(ProviderQuotaExceededError): method(installed_app, "mid") - def test_model_not_support_more_like_this(self, app): + def test_model_not_support_more_like_this(self, app: Flask): api = module.MessageMoreLikeThisApi() method = unwrap(api.get) @@ -331,7 +332,7 @@ class TestMessageMoreLikeThisApi: with pytest.raises(ProviderModelCurrentlyNotSupportError): method(installed_app, "mid") - def test_invoke_error_more_like_this(self, app): + def test_invoke_error_more_like_this(self, app: Flask): api = module.MessageMoreLikeThisApi() method = unwrap(api.get) @@ -353,7 +354,7 @@ class TestMessageMoreLikeThisApi: with pytest.raises(CompletionRequestError): method(installed_app, "mid") - def test_unexpected_error_more_like_this(self, app): + def test_unexpected_error_more_like_this(self, app: Flask): api = module.MessageMoreLikeThisApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/explore/test_recommended_app.py b/api/tests/unit_tests/controllers/console/explore/test_recommended_app.py index 76c863577a..557fded37e 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_recommended_app.py +++ b/api/tests/unit_tests/controllers/console/explore/test_recommended_app.py @@ -1,5 +1,7 @@ from unittest.mock import MagicMock, patch +from flask import Flask + import controllers.console.explore.recommended_app as module from models.model import AppMode, IconType @@ -11,7 +13,7 @@ def unwrap(func): class TestRecommendedAppListApi: - def test_get_with_language_param(self, app): + def test_get_with_language_param(self, app: Flask): api = module.RecommendedAppListApi() method = unwrap(api.get) @@ -31,7 +33,7 @@ class TestRecommendedAppListApi: service_mock.assert_called_once_with("en-US") assert result == result_data - def test_get_fallback_to_user_language(self, app): + def test_get_fallback_to_user_language(self, app: Flask): api = module.RecommendedAppListApi() method = unwrap(api.get) @@ -51,7 +53,7 @@ class TestRecommendedAppListApi: service_mock.assert_called_once_with("fr-FR") assert result == result_data - def test_get_fallback_to_default_language(self, app): + def test_get_fallback_to_default_language(self, app: Flask): api = module.RecommendedAppListApi() method = unwrap(api.get) @@ -73,7 +75,7 @@ class TestRecommendedAppListApi: class TestRecommendedAppApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = module.RecommendedAppApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/explore/test_saved_message.py b/api/tests/unit_tests/controllers/console/explore/test_saved_message.py index bb7cdd55c4..71241890e9 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_saved_message.py +++ b/api/tests/unit_tests/controllers/console/explore/test_saved_message.py @@ -2,6 +2,7 @@ from unittest.mock import MagicMock, PropertyMock, patch from uuid import uuid4 import pytest +from flask import Flask from werkzeug.exceptions import NotFound import controllers.console.explore.saved_message as module @@ -42,7 +43,7 @@ def payload_patch(): class TestSavedMessageListApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = module.SavedMessageListApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/explore/test_trial.py b/api/tests/unit_tests/controllers/console/explore/test_trial.py index 3625056af9..14f00e6295 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_trial.py +++ b/api/tests/unit_tests/controllers/console/explore/test_trial.py @@ -3,6 +3,7 @@ from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest +from flask import Flask from werkzeug.exceptions import Forbidden, InternalServerError, NotFound import controllers.console.explore.trial as module @@ -88,7 +89,7 @@ def valid_parameters(): class TestTrialAppWorkflowRunApi: - def test_not_workflow_app(self, app): + def test_not_workflow_app(self, app: Flask): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -224,7 +225,7 @@ class TestTrialAppWorkflowRunApi: class TestTrialChatApi: - def test_not_chat_app(self, app): + def test_not_chat_app(self, app: Flask): api = module.TrialChatApi() method = unwrap(api.post) @@ -408,7 +409,7 @@ class TestTrialChatApi: class TestTrialCompletionApi: - def test_not_completion_app(self, app): + def test_not_completion_app(self, app: Flask): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -560,7 +561,7 @@ class TestTrialCompletionApi: class TestTrialMessageSuggestedQuestionApi: - def test_not_chat_app(self, app): + def test_not_chat_app(self, app: Flask): api = module.TrialMessageSuggestedQuestionApi() method = unwrap(api.get) @@ -952,7 +953,7 @@ class TestTrialAppWorkflowTaskStopApi: class TestTrialSitApi: - def test_no_site(self, app): + def test_no_site(self, app: Flask): api = module.TrialSitApi() method = unwrap(api.get) app_model = MagicMock() @@ -963,7 +964,7 @@ class TestTrialSitApi: with pytest.raises(Forbidden): method(api, app_model) - def test_archived_tenant(self, app): + def test_archived_tenant(self, app: Flask): api = module.TrialSitApi() method = unwrap(api.get) @@ -978,7 +979,7 @@ class TestTrialSitApi: with pytest.raises(Forbidden): method(api, app_model) - def test_success(self, app): + def test_success(self, app: Flask): api = module.TrialSitApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/tag/test_tags.py b/api/tests/unit_tests/controllers/console/tag/test_tags.py index 6405558bb4..8b47da25fb 100644 --- a/api/tests/unit_tests/controllers/console/tag/test_tags.py +++ b/api/tests/unit_tests/controllers/console/tag/test_tags.py @@ -8,10 +8,8 @@ from werkzeug.exceptions import Forbidden import controllers.console.tag.tags as module from controllers.console import console_ns from controllers.console.tag.tags import ( - DeprecatedTagBindingCreateApi, - DeprecatedTagBindingRemoveApi, TagBindingCollectionApi, - TagBindingItemApi, + TagBindingRemoveApi, TagListApi, TagUpdateDeleteApi, ) @@ -75,7 +73,7 @@ def payload_patch(): class TestTagListApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = TagListApi() method = unwrap(api.get) @@ -126,7 +124,7 @@ class TestTagListApi: assert result["name"] == "test-tag" assert result["binding_count"] == "0" - def test_post_forbidden(self, app, readonly_user, payload_patch): + def test_post_forbidden(self, app: Flask, readonly_user, payload_patch): api = TagListApi() method = unwrap(api.post) @@ -172,7 +170,7 @@ class TestTagUpdateDeleteApi: assert status == 200 assert result["binding_count"] == "3" - def test_patch_forbidden(self, app, readonly_user, payload_patch): + def test_patch_forbidden(self, app: Flask, readonly_user, payload_patch): api = TagUpdateDeleteApi() method = unwrap(api.patch) @@ -233,7 +231,7 @@ class TestTagBindingCollectionApi: assert status == 200 assert result["result"] == "success" - def test_create_forbidden(self, app, readonly_user, payload_patch): + def test_create_forbidden(self, app: Flask, readonly_user, payload_patch): api = TagBindingCollectionApi() method = unwrap(api.post) @@ -249,39 +247,13 @@ class TestTagBindingCollectionApi: method(api) -class TestDeprecatedTagBindingCreateApi: - def test_create_success(self, app, admin_user, payload_patch): - api = DeprecatedTagBindingCreateApi() +class TestTagBindingRemoveApi: + def test_remove_success(self, app, admin_user, payload_patch): + api = TagBindingRemoveApi() method = unwrap(api.post) payload = { - "tag_ids": ["tag-1"], - "target_id": "target-1", - "type": "knowledge", - } - - with app.test_request_context("/", json=payload): - with ( - patch( - "controllers.console.tag.tags.current_account_with_tenant", - return_value=(admin_user, None), - ), - payload_patch(payload), - patch("controllers.console.tag.tags.TagService.save_tag_binding") as save_mock, - ): - result, status = method(api) - - save_mock.assert_called_once() - assert status == 200 - assert result["result"] == "success" - - -class TestTagBindingItemApi: - def test_delete_success(self, app, admin_user, payload_patch): - api = TagBindingItemApi() - method = unwrap(api.delete) - - payload = { + "tag_ids": ["tag-1", "tag-2"], "target_id": "target-1", "type": "knowledge", } @@ -295,57 +267,16 @@ class TestTagBindingItemApi: payload_patch(payload), patch("controllers.console.tag.tags.TagService.delete_tag_binding") as delete_mock, ): - result, status = method(api, "tag-1") + result, status = method(api) delete_mock.assert_called_once() delete_payload = delete_mock.call_args.args[0] - assert delete_payload.tag_id == "tag-1" - assert delete_payload.target_id == "target-1" - assert delete_payload.type == TagType.KNOWLEDGE + assert delete_payload.tag_ids == ["tag-1", "tag-2"] assert status == 200 assert result["result"] == "success" - def test_delete_forbidden(self, app, readonly_user): - api = TagBindingItemApi() - method = unwrap(api.delete) - - with app.test_request_context("/"): - with patch( - "controllers.console.tag.tags.current_account_with_tenant", - return_value=(readonly_user, None), - ): - with pytest.raises(Forbidden): - method(api, "tag-1") - - -class TestDeprecatedTagBindingRemoveApi: - def test_remove_success(self, app, admin_user, payload_patch): - api = DeprecatedTagBindingRemoveApi() - method = unwrap(api.post) - - payload = { - "tag_id": "tag-1", - "target_id": "target-1", - "type": "knowledge", - } - - with app.test_request_context("/", json=payload): - with ( - patch( - "controllers.console.tag.tags.current_account_with_tenant", - return_value=(admin_user, None), - ), - payload_patch(payload), - patch("controllers.console.tag.tags.TagService.delete_tag_binding") as delete_mock, - ): - result, status = method(api) - - delete_mock.assert_called_once() - assert status == 200 - assert result["result"] == "success" - - def test_remove_forbidden(self, app, readonly_user, payload_patch): - api = DeprecatedTagBindingRemoveApi() + def test_remove_forbidden(self, app: Flask, readonly_user, payload_patch): + api = TagBindingRemoveApi() method = unwrap(api.post) with app.test_request_context("/", json={}): @@ -371,32 +302,30 @@ class TestTagResponseModel: class TestTagBindingRouteMetadata: - def test_legacy_write_routes_are_marked_deprecated(self): - assert DeprecatedTagBindingCreateApi.post.__apidoc__["deprecated"] is True - assert DeprecatedTagBindingRemoveApi.post.__apidoc__["deprecated"] is True + def test_write_routes_are_not_deprecated(self): assert TagBindingCollectionApi.post.__apidoc__.get("deprecated") is not True - assert TagBindingItemApi.delete.__apidoc__.get("deprecated") is not True + assert TagBindingRemoveApi.post.__apidoc__.get("deprecated") is not True def test_write_routes_have_stable_operation_ids(self): assert TagBindingCollectionApi.post.__apidoc__["id"] == "create_tag_binding" - assert TagBindingItemApi.delete.__apidoc__["id"] == "delete_tag_binding" - assert DeprecatedTagBindingCreateApi.post.__apidoc__["id"] == "create_tag_binding_deprecated" - assert DeprecatedTagBindingRemoveApi.post.__apidoc__["id"] == "delete_tag_binding_deprecated" + assert TagBindingRemoveApi.post.__apidoc__["id"] == "remove_tag_bindings" - def test_canonical_and_legacy_write_routes_are_registered(self): + def test_write_routes_are_registered(self): route_map = { resource.__name__: urls for resource, urls, _route_doc, _kwargs in console_ns.resources if resource.__name__ in { "TagBindingCollectionApi", - "TagBindingItemApi", - "DeprecatedTagBindingCreateApi", - "DeprecatedTagBindingRemoveApi", + "TagBindingRemoveApi", } } assert route_map["TagBindingCollectionApi"] == ("/tag-bindings",) - assert route_map["TagBindingItemApi"] == ("/tag-bindings/",) - assert route_map["DeprecatedTagBindingCreateApi"] == ("/tag-bindings/create",) - assert route_map["DeprecatedTagBindingRemoveApi"] == ("/tag-bindings/remove",) + assert route_map["TagBindingRemoveApi"] == ("/tag-bindings/remove",) + + def test_legacy_write_routes_are_not_registered(self): + urls = {url for _resource, resource_urls, _route_doc, _kwargs in console_ns.resources for url in resource_urls} + + assert "/tag-bindings/create" not in urls + assert "/tag-bindings/" not in urls diff --git a/api/tests/unit_tests/controllers/console/test_files.py b/api/tests/unit_tests/controllers/console/test_files.py index 5df9daa7f8..eebc6f9d60 100644 --- a/api/tests/unit_tests/controllers/console/test_files.py +++ b/api/tests/unit_tests/controllers/console/test_files.py @@ -82,7 +82,7 @@ def mock_file_service(mock_db): class TestFileApiGet: - def test_get_upload_config(self, app): + def test_get_upload_config(self, app: Flask): api = FileApi() get_method = unwrap(api.get) @@ -290,7 +290,7 @@ class TestFilePreviewApi: class TestFileSupportTypeApi: - def test_get_supported_types(self, app): + def test_get_supported_types(self, app: Flask): api = FileSupportTypeApi() get_method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/test_workspace_account.py b/api/tests/unit_tests/controllers/console/test_workspace_account.py index 0b1a32581a..4b4f968c8f 100644 --- a/api/tests/unit_tests/controllers/console/test_workspace_account.py +++ b/api/tests/unit_tests/controllers/console/test_workspace_account.py @@ -58,7 +58,7 @@ class TestChangeEmailSend: mock_get_change_data, mock_current_account, mock_db, - app, + app: Flask, ): mock_features.return_value = SimpleNamespace(enable_change_email=True) mock_account = _build_account("current@example.com", "acc1") @@ -107,7 +107,7 @@ class TestChangeEmailSend: mock_get_change_data, mock_current_account, mock_db, - app, + app: Flask, ): """GHSA-4q3w-q5mc-45rq: a phase-1 token must not unlock the new-email send step.""" from controllers.console.auth.error import InvalidTokenError @@ -155,7 +155,7 @@ class TestChangeEmailValidity: mock_reset_rate, mock_current_account, mock_db, - app, + app: Flask, ): mock_features.return_value = SimpleNamespace(enable_change_email=True) mock_account = _build_account("user@example.com", "acc2") @@ -214,7 +214,7 @@ class TestChangeEmailValidity: mock_reset_rate, mock_current_account, mock_db, - app, + app: Flask, ): mock_features.return_value = SimpleNamespace(enable_change_email=True) mock_current_account.return_value = (_build_account("old@example.com", "acc"), None) @@ -267,7 +267,7 @@ class TestChangeEmailValidity: mock_reset_rate, mock_current_account, mock_db, - app, + app: Flask, ): """A token whose phase marker is a string but not a known transition must be rejected.""" from controllers.console.auth.error import InvalidTokenError @@ -316,7 +316,7 @@ class TestChangeEmailValidity: mock_reset_rate, mock_current_account, mock_db, - app, + app: Flask, ): """A token minted without a phase marker (e.g. a hand-crafted token) must not validate.""" from controllers.console.auth.error import InvalidTokenError @@ -366,7 +366,7 @@ class TestChangeEmailReset: mock_send_notify, mock_current_account, mock_db, - app, + app: Flask, ): mock_features.return_value = SimpleNamespace(enable_change_email=True) current_user = _build_account("old@example.com", "acc3") @@ -418,7 +418,7 @@ class TestChangeEmailReset: mock_send_notify, mock_current_account, mock_db, - app, + app: Flask, ): """GHSA-4q3w-q5mc-45rq PoC: phase-1 token must not be usable against /reset.""" from controllers.console.auth.error import InvalidTokenError @@ -471,7 +471,7 @@ class TestChangeEmailReset: mock_send_notify, mock_current_account, mock_db, - app, + app: Flask, ): """A verified token for address A must not be replayed to change to address B.""" from controllers.console.auth.error import InvalidTokenError @@ -547,7 +547,7 @@ class TestAccountServiceSendChangeEmailEmail: class TestAccountDeletionFeedback: @patch("controllers.console.wraps.db") @patch("controllers.console.workspace.account.BillingService.update_account_deletion_feedback") - def test_should_normalize_feedback_email(self, mock_update, mock_db, app): + def test_should_normalize_feedback_email(self, mock_update, mock_db, app: Flask): with app.test_request_context( "/account/delete/feedback", method="POST", @@ -563,7 +563,7 @@ class TestCheckEmailUnique: @patch("controllers.console.wraps.db") @patch("controllers.console.workspace.account.AccountService.check_email_unique") @patch("controllers.console.workspace.account.AccountService.is_account_in_freeze") - def test_should_normalize_email(self, mock_is_freeze, mock_check_unique, mock_db, app): + def test_should_normalize_email(self, mock_is_freeze, mock_check_unique, mock_db, app: Flask): mock_is_freeze.return_value = False mock_check_unique.return_value = True diff --git a/api/tests/unit_tests/controllers/console/test_workspace_members.py b/api/tests/unit_tests/controllers/console/test_workspace_members.py index 811bf5b1e7..412d6a6c52 100644 --- a/api/tests/unit_tests/controllers/console/test_workspace_members.py +++ b/api/tests/unit_tests/controllers/console/test_workspace_members.py @@ -43,7 +43,7 @@ class TestMemberInviteEmailApi: mock_current_account, mock_invite_member, mock_get_features, - app, + app: Flask, ): mock_get_features.return_value = _build_feature_flags() mock_invite_member.return_value = "token-abc" diff --git a/api/tests/unit_tests/controllers/console/workspace/test_accounts.py b/api/tests/unit_tests/controllers/console/workspace/test_accounts.py index 42be02cdaf..064726da05 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_accounts.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_accounts.py @@ -1,6 +1,8 @@ from unittest.mock import MagicMock, PropertyMock, patch import pytest +from flask import Flask +from werkzeug.exceptions import NotFound from controllers.console import console_ns from controllers.console.auth.error import ( @@ -29,6 +31,7 @@ from controllers.console.workspace.error import ( CurrentPasswordIncorrectError, InvalidAccountDeletionCodeError, ) +from models.enums import CreatorUserRole from services.errors.account import CurrentPasswordIncorrectError as ServicePwdError @@ -39,7 +42,7 @@ def unwrap(func): class TestAccountInitApi: - def test_init_success(self, app): + def test_init_success(self, app: Flask): api = AccountInitApi() method = unwrap(api.post) @@ -62,7 +65,7 @@ class TestAccountInitApi: assert resp["result"] == "success" - def test_init_already_initialized(self, app): + def test_init_already_initialized(self, app: Flask): api = AccountInitApi() method = unwrap(api.post) @@ -77,7 +80,7 @@ class TestAccountInitApi: class TestAccountProfileApi: - def test_get_profile_success(self, app): + def test_get_profile_success(self, app: Flask): api = AccountProfileApi() method = unwrap(api.get) @@ -135,8 +138,133 @@ class TestAccountUpdateApis: assert result["id"] == "u1" +class TestAccountAvatarApiGet: + """GET /account/avatar must not sign arbitrary upload_file IDs (IDOR).""" + + def test_get_avatar_signed_url_when_upload_owned_by_current_account(self, app: Flask): + api = AccountAvatarApi() + method = unwrap(api.get) + + user = MagicMock() + user.id = "acc-owner" + tenant_id = "tenant-1" + file_id = "550e8400-e29b-41d4-a716-446655440000" + + upload_file = MagicMock() + upload_file.id = file_id + upload_file.tenant_id = tenant_id + upload_file.created_by = user.id + upload_file.created_by_role = CreatorUserRole.ACCOUNT + + with ( + app.test_request_context(f"/account/avatar?avatar={file_id}"), + patch( + "controllers.console.workspace.account.current_account_with_tenant", + return_value=(user, tenant_id), + ), + patch("controllers.console.workspace.account.db.session.scalar", return_value=upload_file), + patch( + "controllers.console.workspace.account.file_helpers.get_signed_file_url", + return_value="https://signed/example", + ) as sign_mock, + ): + result = method(api) + + assert result == {"avatar_url": "https://signed/example"} + sign_mock.assert_called_once_with(upload_file_id=file_id) + + def test_get_avatar_not_found_when_upload_created_by_other_account_same_tenant(self, app: Flask): + api = AccountAvatarApi() + method = unwrap(api.get) + + user = MagicMock() + user.id = "acc-a" + tenant_id = "tenant-1" + file_id = "550e8400-e29b-41d4-a716-446655440001" + + upload_file = MagicMock() + upload_file.id = file_id + upload_file.tenant_id = tenant_id + upload_file.created_by = "acc-b" + upload_file.created_by_role = CreatorUserRole.ACCOUNT + + with ( + app.test_request_context(f"/account/avatar?avatar={file_id}"), + patch( + "controllers.console.workspace.account.current_account_with_tenant", + return_value=(user, tenant_id), + ), + patch("controllers.console.workspace.account.db.session.scalar", return_value=upload_file), + patch( + "controllers.console.workspace.account.file_helpers.get_signed_file_url", + return_value="https://signed/leak", + ) as sign_mock, + ): + with pytest.raises(NotFound): + method(api) + + sign_mock.assert_not_called() + + def test_get_avatar_not_found_when_upload_belongs_to_other_tenant(self, app: Flask): + api = AccountAvatarApi() + method = unwrap(api.get) + + user = MagicMock() + user.id = "acc-owner" + tenant_id = "tenant-1" + file_id = "550e8400-e29b-41d4-a716-446655440002" + + upload_file = MagicMock() + upload_file.id = file_id + upload_file.tenant_id = "tenant-other" + upload_file.created_by = user.id + upload_file.created_by_role = CreatorUserRole.ACCOUNT + + with ( + app.test_request_context(f"/account/avatar?avatar={file_id}"), + patch( + "controllers.console.workspace.account.current_account_with_tenant", + return_value=(user, tenant_id), + ), + patch("controllers.console.workspace.account.db.session.scalar", return_value=upload_file), + patch( + "controllers.console.workspace.account.file_helpers.get_signed_file_url", + return_value="https://signed/leak", + ) as sign_mock, + ): + with pytest.raises(NotFound): + method(api) + + sign_mock.assert_not_called() + + def test_get_avatar_https_pass_through_without_signing(self, app: Flask): + api = AccountAvatarApi() + method = unwrap(api.get) + + user = MagicMock() + user.id = "acc-owner" + tenant_id = "tenant-1" + external = "https://cdn.example/avatar.png" + + with ( + app.test_request_context(f"/account/avatar?avatar={external}"), + patch( + "controllers.console.workspace.account.current_account_with_tenant", + return_value=(user, tenant_id), + ), + patch( + "controllers.console.workspace.account.file_helpers.get_signed_file_url", + return_value="https://signed/should-not-use", + ) as sign_mock, + ): + result = method(api) + + assert result == {"avatar_url": external} + sign_mock.assert_not_called() + + class TestAccountPasswordApi: - def test_password_success(self, app): + def test_password_success(self, app: Flask): api = AccountPasswordApi() method = unwrap(api.post) @@ -165,7 +293,7 @@ class TestAccountPasswordApi: assert result["id"] == "u1" - def test_password_wrong_current(self, app): + def test_password_wrong_current(self, app: Flask): api = AccountPasswordApi() method = unwrap(api.post) @@ -190,7 +318,7 @@ class TestAccountPasswordApi: class TestAccountIntegrateApi: - def test_get_integrates(self, app): + def test_get_integrates(self, app: Flask): api = AccountIntegrateApi() method = unwrap(api.get) @@ -209,7 +337,7 @@ class TestAccountIntegrateApi: class TestAccountDeleteApi: - def test_delete_verify_success(self, app): + def test_delete_verify_success(self, app: Flask): api = AccountDeleteVerifyApi() method = unwrap(api.get) @@ -231,7 +359,7 @@ class TestAccountDeleteApi: assert result["result"] == "success" - def test_delete_invalid_code(self, app): + def test_delete_invalid_code(self, app: Flask): api = AccountDeleteApi() method = unwrap(api.post) @@ -252,7 +380,7 @@ class TestAccountDeleteApi: class TestChangeEmailApis: - def test_check_email_code_invalid(self, app): + def test_check_email_code_invalid(self, app: Flask): api = ChangeEmailCheckApi() method = unwrap(api.post) @@ -278,7 +406,7 @@ class TestChangeEmailApis: with pytest.raises(EmailCodeError): method(api) - def test_reset_email_already_used(self, app): + def test_reset_email_already_used(self, app: Flask): api = ChangeEmailResetApi() method = unwrap(api.post) @@ -300,7 +428,7 @@ class TestChangeEmailApis: class TestCheckEmailUniqueApi: - def test_email_unique_success(self, app): + def test_email_unique_success(self, app: Flask): api = CheckEmailUnique() method = unwrap(api.post) @@ -321,7 +449,7 @@ class TestCheckEmailUniqueApi: assert result["result"] == "success" - def test_email_in_freeze(self, app): + def test_email_in_freeze(self, app: Flask): api = CheckEmailUnique() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/workspace/test_agent_providers.py b/api/tests/unit_tests/controllers/console/workspace/test_agent_providers.py index b4e03f681d..eb0ca15d2e 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_agent_providers.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_agent_providers.py @@ -1,6 +1,7 @@ from unittest.mock import MagicMock, patch import pytest +from flask import Flask from controllers.console.error import AccountNotFound from controllers.console.workspace.agent_providers import ( @@ -16,7 +17,7 @@ def unwrap(func): class TestAgentProviderListApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = AgentProviderListApi() method = unwrap(api.get) @@ -39,7 +40,7 @@ class TestAgentProviderListApi: assert result == providers - def test_get_empty_list(self, app): + def test_get_empty_list(self, app: Flask): api = AgentProviderListApi() method = unwrap(api.get) @@ -61,7 +62,7 @@ class TestAgentProviderListApi: assert result == [] - def test_get_account_not_found(self, app): + def test_get_account_not_found(self, app: Flask): api = AgentProviderListApi() method = unwrap(api.get) @@ -77,7 +78,7 @@ class TestAgentProviderListApi: class TestAgentProviderApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = AgentProviderApi() method = unwrap(api.get) @@ -101,7 +102,7 @@ class TestAgentProviderApi: assert result == provider_data - def test_get_provider_not_found(self, app): + def test_get_provider_not_found(self, app: Flask): api = AgentProviderApi() method = unwrap(api.get) @@ -124,7 +125,7 @@ class TestAgentProviderApi: assert result is None - def test_get_account_not_found(self, app): + def test_get_account_not_found(self, app: Flask): api = AgentProviderApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/workspace/test_endpoint.py b/api/tests/unit_tests/controllers/console/workspace/test_endpoint.py index 0b3d7ef6d7..ed7b2d606f 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_endpoint.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_endpoint.py @@ -1,6 +1,7 @@ from unittest.mock import MagicMock, patch import pytest +from flask import Flask from controllers.console import console_ns from controllers.console.workspace.endpoint import ( @@ -39,7 +40,7 @@ def patch_current_account(user_and_tenant): @pytest.mark.usefixtures("patch_current_account") class TestEndpointCollectionApi: - def test_create_success(self, app): + def test_create_success(self, app: Flask): api = EndpointCollectionApi() method = unwrap(api.post) @@ -57,7 +58,7 @@ class TestEndpointCollectionApi: assert result["success"] is True - def test_create_permission_denied(self, app): + def test_create_permission_denied(self, app: Flask): api = EndpointCollectionApi() method = unwrap(api.post) @@ -77,7 +78,7 @@ class TestEndpointCollectionApi: with pytest.raises(ValueError): method(api) - def test_create_validation_error(self, app): + def test_create_validation_error(self, app: Flask): api = EndpointCollectionApi() method = unwrap(api.post) @@ -96,7 +97,7 @@ class TestEndpointCollectionApi: @pytest.mark.usefixtures("patch_current_account") class TestDeprecatedEndpointCreateApi: - def test_create_success(self, app): + def test_create_success(self, app: Flask): api = DeprecatedEndpointCreateApi() method = unwrap(api.post) @@ -117,7 +118,7 @@ class TestDeprecatedEndpointCreateApi: @pytest.mark.usefixtures("patch_current_account") class TestEndpointListApi: - def test_list_success(self, app): + def test_list_success(self, app: Flask): api = EndpointListApi() method = unwrap(api.get) @@ -130,7 +131,7 @@ class TestEndpointListApi: assert "endpoints" in result assert len(result["endpoints"]) == 1 - def test_list_invalid_query(self, app): + def test_list_invalid_query(self, app: Flask): api = EndpointListApi() method = unwrap(api.get) @@ -143,7 +144,7 @@ class TestEndpointListApi: @pytest.mark.usefixtures("patch_current_account") class TestEndpointListForSinglePluginApi: - def test_list_for_plugin_success(self, app): + def test_list_for_plugin_success(self, app: Flask): api = EndpointListForSinglePluginApi() method = unwrap(api.get) @@ -158,7 +159,7 @@ class TestEndpointListForSinglePluginApi: assert "endpoints" in result - def test_list_for_plugin_missing_param(self, app): + def test_list_for_plugin_missing_param(self, app: Flask): api = EndpointListForSinglePluginApi() method = unwrap(api.get) @@ -171,7 +172,7 @@ class TestEndpointListForSinglePluginApi: @pytest.mark.usefixtures("patch_current_account") class TestEndpointItemApi: - def test_delete_success(self, app): + def test_delete_success(self, app: Flask): api = EndpointItemApi() method = unwrap(api.delete) @@ -187,7 +188,7 @@ class TestEndpointItemApi: assert result["success"] is True mock_delete.assert_called_once_with(tenant_id="t1", user_id="u1", endpoint_id="e1") - def test_delete_service_failure(self, app): + def test_delete_service_failure(self, app: Flask): api = EndpointItemApi() method = unwrap(api.delete) @@ -199,7 +200,7 @@ class TestEndpointItemApi: assert result["success"] is False - def test_update_success(self, app): + def test_update_success(self, app: Flask): api = EndpointItemApi() method = unwrap(api.patch) @@ -226,7 +227,7 @@ class TestEndpointItemApi: settings={"x": 1}, ) - def test_update_validation_error(self, app): + def test_update_validation_error(self, app: Flask): api = EndpointItemApi() method = unwrap(api.patch) @@ -238,7 +239,7 @@ class TestEndpointItemApi: with pytest.raises(ValueError): method(api, "e1") - def test_update_service_failure(self, app): + def test_update_service_failure(self, app: Flask): api = EndpointItemApi() method = unwrap(api.patch) @@ -258,7 +259,7 @@ class TestEndpointItemApi: @pytest.mark.usefixtures("patch_current_account") class TestDeprecatedEndpointDeleteApi: - def test_delete_success(self, app): + def test_delete_success(self, app: Flask): api = DeprecatedEndpointDeleteApi() method = unwrap(api.post) @@ -272,7 +273,7 @@ class TestDeprecatedEndpointDeleteApi: assert result["success"] is True - def test_delete_invalid_payload(self, app): + def test_delete_invalid_payload(self, app: Flask): api = DeprecatedEndpointDeleteApi() method = unwrap(api.post) @@ -282,7 +283,7 @@ class TestDeprecatedEndpointDeleteApi: with pytest.raises(ValueError): method(api) - def test_delete_service_failure(self, app): + def test_delete_service_failure(self, app: Flask): api = DeprecatedEndpointDeleteApi() method = unwrap(api.post) @@ -299,7 +300,7 @@ class TestDeprecatedEndpointDeleteApi: @pytest.mark.usefixtures("patch_current_account") class TestDeprecatedEndpointUpdateApi: - def test_update_success(self, app): + def test_update_success(self, app: Flask): api = DeprecatedEndpointUpdateApi() method = unwrap(api.post) @@ -317,7 +318,7 @@ class TestDeprecatedEndpointUpdateApi: assert result["success"] is True - def test_update_validation_error(self, app): + def test_update_validation_error(self, app: Flask): api = DeprecatedEndpointUpdateApi() method = unwrap(api.post) @@ -329,7 +330,7 @@ class TestDeprecatedEndpointUpdateApi: with pytest.raises(ValueError): method(api) - def test_update_service_failure(self, app): + def test_update_service_failure(self, app: Flask): api = DeprecatedEndpointUpdateApi() method = unwrap(api.post) @@ -380,7 +381,7 @@ class TestEndpointRouteMetadata: @pytest.mark.usefixtures("patch_current_account") class TestEndpointEnableApi: - def test_enable_success(self, app): + def test_enable_success(self, app: Flask): api = EndpointEnableApi() method = unwrap(api.post) @@ -394,7 +395,7 @@ class TestEndpointEnableApi: assert result["success"] is True - def test_enable_invalid_payload(self, app): + def test_enable_invalid_payload(self, app: Flask): api = EndpointEnableApi() method = unwrap(api.post) @@ -404,7 +405,7 @@ class TestEndpointEnableApi: with pytest.raises(ValueError): method(api) - def test_enable_service_failure(self, app): + def test_enable_service_failure(self, app: Flask): api = EndpointEnableApi() method = unwrap(api.post) @@ -421,7 +422,7 @@ class TestEndpointEnableApi: @pytest.mark.usefixtures("patch_current_account") class TestEndpointDisableApi: - def test_disable_success(self, app): + def test_disable_success(self, app: Flask): api = EndpointDisableApi() method = unwrap(api.post) @@ -435,7 +436,7 @@ class TestEndpointDisableApi: assert result["success"] is True - def test_disable_invalid_payload(self, app): + def test_disable_invalid_payload(self, app: Flask): api = EndpointDisableApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/workspace/test_members.py b/api/tests/unit_tests/controllers/console/workspace/test_members.py index 718b57ba6b..0788ff603c 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_members.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_members.py @@ -1,6 +1,7 @@ from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.exceptions import HTTPException import services @@ -34,7 +35,7 @@ def unwrap(func): class TestMemberListApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = MemberListApi() method = unwrap(api.get) @@ -59,7 +60,7 @@ class TestMemberListApi: assert status == 200 assert len(result["accounts"]) == 1 - def test_get_no_tenant(self, app): + def test_get_no_tenant(self, app: Flask): api = MemberListApi() method = unwrap(api.get) @@ -74,7 +75,7 @@ class TestMemberListApi: class TestMemberInviteEmailApi: - def test_invite_success(self, app): + def test_invite_success(self, app: Flask): api = MemberInviteEmailApi() method = unwrap(api.post) @@ -101,7 +102,7 @@ class TestMemberInviteEmailApi: assert status == 201 assert result["result"] == "success" - def test_invite_limit_exceeded(self, app): + def test_invite_limit_exceeded(self, app: Flask): api = MemberInviteEmailApi() method = unwrap(api.post) @@ -123,7 +124,7 @@ class TestMemberInviteEmailApi: with pytest.raises(WorkspaceMembersLimitExceeded): method(api) - def test_invite_already_member(self, app): + def test_invite_already_member(self, app: Flask): api = MemberInviteEmailApi() method = unwrap(api.post) @@ -151,7 +152,7 @@ class TestMemberInviteEmailApi: assert result["invitation_results"][0]["status"] == "success" - def test_invite_invalid_role(self, app): + def test_invite_invalid_role(self, app: Flask): api = MemberInviteEmailApi() method = unwrap(api.post) @@ -166,7 +167,7 @@ class TestMemberInviteEmailApi: assert status == 400 assert result["code"] == "invalid-role" - def test_invite_generic_exception(self, app): + def test_invite_generic_exception(self, app: Flask): api = MemberInviteEmailApi() method = unwrap(api.post) @@ -196,7 +197,7 @@ class TestMemberInviteEmailApi: class TestMemberCancelInviteApi: - def test_cancel_success(self, app): + def test_cancel_success(self, app: Flask): api = MemberCancelInviteApi() method = unwrap(api.delete) @@ -216,7 +217,7 @@ class TestMemberCancelInviteApi: assert status == 200 assert result["result"] == "success" - def test_cancel_not_found(self, app): + def test_cancel_not_found(self, app: Flask): api = MemberCancelInviteApi() method = unwrap(api.delete) @@ -233,7 +234,7 @@ class TestMemberCancelInviteApi: with pytest.raises(HTTPException): method(api, "x") - def test_cancel_cannot_operate_self(self, app): + def test_cancel_cannot_operate_self(self, app: Flask): api = MemberCancelInviteApi() method = unwrap(api.delete) @@ -255,7 +256,7 @@ class TestMemberCancelInviteApi: assert status == 400 - def test_cancel_no_permission(self, app): + def test_cancel_no_permission(self, app: Flask): api = MemberCancelInviteApi() method = unwrap(api.delete) @@ -277,7 +278,7 @@ class TestMemberCancelInviteApi: assert status == 403 - def test_cancel_member_not_in_tenant(self, app): + def test_cancel_member_not_in_tenant(self, app: Flask): api = MemberCancelInviteApi() method = unwrap(api.delete) @@ -301,7 +302,7 @@ class TestMemberCancelInviteApi: class TestMemberUpdateRoleApi: - def test_update_success(self, app): + def test_update_success(self, app: Flask): api = MemberUpdateRoleApi() method = unwrap(api.put) @@ -324,7 +325,7 @@ class TestMemberUpdateRoleApi: assert result["result"] == "success" - def test_update_invalid_role(self, app): + def test_update_invalid_role(self, app: Flask): api = MemberUpdateRoleApi() method = unwrap(api.put) @@ -335,7 +336,7 @@ class TestMemberUpdateRoleApi: assert status == 400 - def test_update_member_not_found(self, app): + def test_update_member_not_found(self, app: Flask): api = MemberUpdateRoleApi() method = unwrap(api.put) @@ -354,7 +355,7 @@ class TestMemberUpdateRoleApi: class TestDatasetOperatorMemberListApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = DatasetOperatorMemberListApi() method = unwrap(api.get) @@ -381,7 +382,7 @@ class TestDatasetOperatorMemberListApi: assert status == 200 assert len(result["accounts"]) == 1 - def test_get_no_tenant(self, app): + def test_get_no_tenant(self, app: Flask): api = DatasetOperatorMemberListApi() method = unwrap(api.get) @@ -396,7 +397,7 @@ class TestDatasetOperatorMemberListApi: class TestSendOwnerTransferEmailApi: - def test_send_success(self, app): + def test_send_success(self, app: Flask): api = SendOwnerTransferEmailApi() method = unwrap(api.post) @@ -419,7 +420,7 @@ class TestSendOwnerTransferEmailApi: assert result["result"] == "success" - def test_send_ip_limit(self, app): + def test_send_ip_limit(self, app: Flask): api = SendOwnerTransferEmailApi() method = unwrap(api.post) @@ -433,7 +434,7 @@ class TestSendOwnerTransferEmailApi: with pytest.raises(EmailSendIpLimitError): method(api) - def test_send_not_owner(self, app): + def test_send_not_owner(self, app: Flask): api = SendOwnerTransferEmailApi() method = unwrap(api.post) @@ -452,7 +453,7 @@ class TestSendOwnerTransferEmailApi: class TestOwnerTransferCheckApi: - def test_check_invalid_code(self, app): + def test_check_invalid_code(self, app: Flask): api = OwnerTransferCheckApi() method = unwrap(api.post) @@ -477,7 +478,7 @@ class TestOwnerTransferCheckApi: with pytest.raises(EmailCodeError): method(api) - def test_rate_limited(self, app): + def test_rate_limited(self, app: Flask): api = OwnerTransferCheckApi() method = unwrap(api.post) @@ -498,7 +499,7 @@ class TestOwnerTransferCheckApi: with pytest.raises(OwnerTransferLimitError): method(api) - def test_invalid_token(self, app): + def test_invalid_token(self, app: Flask): api = OwnerTransferCheckApi() method = unwrap(api.post) @@ -520,7 +521,7 @@ class TestOwnerTransferCheckApi: with pytest.raises(InvalidTokenError): method(api) - def test_invalid_email(self, app): + def test_invalid_email(self, app: Flask): api = OwnerTransferCheckApi() method = unwrap(api.post) @@ -547,7 +548,7 @@ class TestOwnerTransferCheckApi: class TestOwnerTransferApi: - def test_transfer_self(self, app): + def test_transfer_self(self, app: Flask): api = OwnerTransfer() method = unwrap(api.post) @@ -564,7 +565,7 @@ class TestOwnerTransferApi: with pytest.raises(CannotTransferOwnerToSelfError): method(api, "1") - def test_invalid_token(self, app): + def test_invalid_token(self, app: Flask): api = OwnerTransfer() method = unwrap(api.post) @@ -582,7 +583,7 @@ class TestOwnerTransferApi: with pytest.raises(InvalidTokenError): method(api, "2") - def test_member_not_in_tenant(self, app): + def test_member_not_in_tenant(self, app: Flask): api = OwnerTransfer() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/workspace/test_model_providers.py b/api/tests/unit_tests/controllers/console/workspace/test_model_providers.py index 168479af1e..e836a3cc55 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_model_providers.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_model_providers.py @@ -1,6 +1,7 @@ from unittest.mock import MagicMock, patch import pytest +from flask import Flask from pydantic_core import ValidationError from werkzeug.exceptions import Forbidden @@ -26,7 +27,7 @@ def unwrap(func): class TestModelProviderListApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = ModelProviderListApi() method = unwrap(api.get) @@ -47,7 +48,7 @@ class TestModelProviderListApi: class TestModelProviderCredentialApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = ModelProviderCredentialApi() method = unwrap(api.get) @@ -66,7 +67,7 @@ class TestModelProviderCredentialApi: assert "credentials" in result - def test_get_invalid_uuid(self, app): + def test_get_invalid_uuid(self, app: Flask): api = ModelProviderCredentialApi() method = unwrap(api.get) @@ -80,7 +81,7 @@ class TestModelProviderCredentialApi: with pytest.raises(ValidationError): method(api, provider="openai") - def test_post_create_success(self, app): + def test_post_create_success(self, app: Flask): api = ModelProviderCredentialApi() method = unwrap(api.post) @@ -102,7 +103,7 @@ class TestModelProviderCredentialApi: assert result["result"] == "success" assert status == 201 - def test_post_create_validation_error(self, app): + def test_post_create_validation_error(self, app: Flask): api = ModelProviderCredentialApi() method = unwrap(api.post) @@ -122,7 +123,7 @@ class TestModelProviderCredentialApi: with pytest.raises(ValueError): method(api, provider="openai") - def test_put_update_success(self, app): + def test_put_update_success(self, app: Flask): api = ModelProviderCredentialApi() method = unwrap(api.put) @@ -143,7 +144,7 @@ class TestModelProviderCredentialApi: assert result["result"] == "success" - def test_put_invalid_uuid(self, app): + def test_put_invalid_uuid(self, app: Flask): api = ModelProviderCredentialApi() method = unwrap(api.put) @@ -159,7 +160,7 @@ class TestModelProviderCredentialApi: with pytest.raises(ValidationError): method(api, provider="openai") - def test_delete_success(self, app): + def test_delete_success(self, app: Flask): api = ModelProviderCredentialApi() method = unwrap(api.delete) @@ -183,7 +184,7 @@ class TestModelProviderCredentialApi: class TestModelProviderCredentialSwitchApi: - def test_switch_success(self, app): + def test_switch_success(self, app: Flask): api = ModelProviderCredentialSwitchApi() method = unwrap(api.post) @@ -204,7 +205,7 @@ class TestModelProviderCredentialSwitchApi: assert result["result"] == "success" - def test_switch_invalid_uuid(self, app): + def test_switch_invalid_uuid(self, app: Flask): api = ModelProviderCredentialSwitchApi() method = unwrap(api.post) @@ -222,7 +223,7 @@ class TestModelProviderCredentialSwitchApi: class TestModelProviderValidateApi: - def test_validate_success(self, app): + def test_validate_success(self, app: Flask): api = ModelProviderValidateApi() method = unwrap(api.post) @@ -243,7 +244,7 @@ class TestModelProviderValidateApi: assert result["result"] == "success" - def test_validate_failure(self, app): + def test_validate_failure(self, app: Flask): api = ModelProviderValidateApi() method = unwrap(api.post) @@ -266,7 +267,7 @@ class TestModelProviderValidateApi: class TestModelProviderIconApi: - def test_icon_success(self, app): + def test_icon_success(self, app: Flask): api = ModelProviderIconApi() with ( @@ -280,7 +281,7 @@ class TestModelProviderIconApi: assert response.mimetype == "image/png" - def test_icon_not_found(self, app): + def test_icon_not_found(self, app: Flask): api = ModelProviderIconApi() with ( @@ -295,7 +296,7 @@ class TestModelProviderIconApi: class TestPreferredProviderTypeUpdateApi: - def test_update_success(self, app): + def test_update_success(self, app: Flask): api = PreferredProviderTypeUpdateApi() method = unwrap(api.post) @@ -316,7 +317,7 @@ class TestPreferredProviderTypeUpdateApi: assert result["result"] == "success" - def test_invalid_enum(self, app): + def test_invalid_enum(self, app: Flask): api = PreferredProviderTypeUpdateApi() method = unwrap(api.post) @@ -334,7 +335,7 @@ class TestPreferredProviderTypeUpdateApi: class TestModelProviderPaymentCheckoutUrlApi: - def test_checkout_success(self, app): + def test_checkout_success(self, app: Flask): api = ModelProviderPaymentCheckoutUrlApi() method = unwrap(api.get) @@ -359,7 +360,7 @@ class TestModelProviderPaymentCheckoutUrlApi: assert "url" in result - def test_invalid_provider(self, app): + def test_invalid_provider(self, app: Flask): api = ModelProviderPaymentCheckoutUrlApi() method = unwrap(api.get) @@ -367,7 +368,7 @@ class TestModelProviderPaymentCheckoutUrlApi: with pytest.raises(ValueError): method(api, provider="openai") - def test_permission_denied(self, app): + def test_permission_denied(self, app: Flask): api = ModelProviderPaymentCheckoutUrlApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/workspace/test_models.py b/api/tests/unit_tests/controllers/console/workspace/test_models.py index f0d32f81fb..4246e3c04c 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_models.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_models.py @@ -72,7 +72,7 @@ class TestDefaultModelApi: assert result["result"] == "success" - def test_get_returns_empty_when_no_default(self, app): + def test_get_returns_empty_when_no_default(self, app: Flask): api = DefaultModelApi() method = unwrap(api.get) @@ -154,7 +154,7 @@ class TestModelProviderModelApi: assert status == 204 - def test_get_models_returns_empty(self, app): + def test_get_models_returns_empty(self, app: Flask): api = ModelProviderModelApi() method = unwrap(api.get) @@ -224,7 +224,7 @@ class TestModelProviderModelCredentialApi: assert status == 201 - def test_get_empty_credentials(self, app): + def test_get_empty_credentials(self, app: Flask): api = ModelProviderModelCredentialApi() method = unwrap(api.get) @@ -242,7 +242,7 @@ class TestModelProviderModelCredentialApi: assert result["credentials"] == {} - def test_delete_success(self, app): + def test_delete_success(self, app: Flask): api = ModelProviderModelCredentialApi() method = unwrap(api.delete) @@ -416,7 +416,7 @@ class TestParameterAndAvailableModels: assert "data" in result - def test_empty_rules(self, app): + def test_empty_rules(self, app: Flask): api = ModelProviderModelParameterRuleApi() method = unwrap(api.get) @@ -431,7 +431,7 @@ class TestParameterAndAvailableModels: assert result["data"] == [] - def test_no_models(self, app): + def test_no_models(self, app: Flask): api = ModelProviderAvailableModelApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/workspace/test_plugin.py b/api/tests/unit_tests/controllers/console/workspace/test_plugin.py index ce5fd1c466..d01bf7d668 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_plugin.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_plugin.py @@ -2,6 +2,7 @@ import io from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.datastructures import FileStorage from werkzeug.exceptions import Forbidden @@ -61,7 +62,7 @@ def tenant(): class TestPluginListLatestVersionsApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginListLatestVersionsApi() method = unwrap(api.post) @@ -77,7 +78,7 @@ class TestPluginListLatestVersionsApi: assert "versions" in result - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginListLatestVersionsApi() method = unwrap(api.post) @@ -95,7 +96,7 @@ class TestPluginListLatestVersionsApi: class TestPluginDebuggingKeyApi: - def test_debugging_key_success(self, app): + def test_debugging_key_success(self, app: Flask): api = PluginDebuggingKeyApi() method = unwrap(api.get) @@ -108,7 +109,7 @@ class TestPluginDebuggingKeyApi: assert result["key"] == "k" - def test_debugging_key_error(self, app): + def test_debugging_key_error(self, app: Flask): api = PluginDebuggingKeyApi() method = unwrap(api.get) @@ -125,7 +126,7 @@ class TestPluginDebuggingKeyApi: class TestPluginListApi: - def test_plugin_list(self, app): + def test_plugin_list(self, app: Flask): api = PluginListApi() method = unwrap(api.get) @@ -142,7 +143,7 @@ class TestPluginListApi: class TestPluginIconApi: - def test_plugin_icon(self, app): + def test_plugin_icon(self, app: Flask): api = PluginIconApi() method = unwrap(api.get) @@ -156,7 +157,7 @@ class TestPluginIconApi: class TestPluginAssetApi: - def test_plugin_asset(self, app): + def test_plugin_asset(self, app: Flask): api = PluginAssetApi() method = unwrap(api.get) @@ -171,7 +172,7 @@ class TestPluginAssetApi: class TestPluginUploadFromPkgApi: - def test_upload_pkg_success(self, app): + def test_upload_pkg_success(self, app: Flask): api = PluginUploadFromPkgApi() method = unwrap(api.post) @@ -188,7 +189,7 @@ class TestPluginUploadFromPkgApi: assert result["ok"] is True - def test_upload_pkg_too_large(self, app): + def test_upload_pkg_too_large(self, app: Flask): api = PluginUploadFromPkgApi() method = unwrap(api.post) @@ -210,7 +211,7 @@ class TestPluginUploadFromPkgApi: class TestPluginInstallFromPkgApi: - def test_install_from_pkg(self, app): + def test_install_from_pkg(self, app: Flask): api = PluginInstallFromPkgApi() method = unwrap(api.post) @@ -229,7 +230,7 @@ class TestPluginInstallFromPkgApi: class TestPluginUninstallApi: - def test_uninstall(self, app): + def test_uninstall(self, app: Flask): api = PluginUninstallApi() method = unwrap(api.post) @@ -246,7 +247,7 @@ class TestPluginUninstallApi: class TestPluginChangePermissionApi: - def test_change_permission_forbidden(self, app): + def test_change_permission_forbidden(self, app: Flask): api = PluginChangePermissionApi() method = unwrap(api.post) @@ -264,7 +265,7 @@ class TestPluginChangePermissionApi: with pytest.raises(Forbidden): method(api) - def test_change_permission_success(self, app): + def test_change_permission_success(self, app: Flask): api = PluginChangePermissionApi() method = unwrap(api.post) @@ -286,7 +287,7 @@ class TestPluginChangePermissionApi: class TestPluginFetchPermissionApi: - def test_fetch_permission_default(self, app): + def test_fetch_permission_default(self, app: Flask): api = PluginFetchPermissionApi() method = unwrap(api.get) @@ -319,7 +320,7 @@ class TestPluginFetchDynamicSelectOptionsApi: class TestPluginReadmeApi: - def test_fetch_readme(self, app): + def test_fetch_readme(self, app: Flask): api = PluginReadmeApi() method = unwrap(api.get) @@ -334,7 +335,7 @@ class TestPluginReadmeApi: class TestPluginListInstallationsFromIdsApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginListInstallationsFromIdsApi() method = unwrap(api.post) @@ -352,7 +353,7 @@ class TestPluginListInstallationsFromIdsApi: assert "plugins" in result - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginListInstallationsFromIdsApi() method = unwrap(api.post) @@ -371,7 +372,7 @@ class TestPluginListInstallationsFromIdsApi: class TestPluginUploadFromGithubApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginUploadFromGithubApi() method = unwrap(api.post) @@ -388,7 +389,7 @@ class TestPluginUploadFromGithubApi: assert result["ok"] is True - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginUploadFromGithubApi() method = unwrap(api.post) @@ -407,7 +408,7 @@ class TestPluginUploadFromGithubApi: class TestPluginUploadFromBundleApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginUploadFromBundleApi() method = unwrap(api.post) @@ -430,7 +431,7 @@ class TestPluginUploadFromBundleApi: assert result["ok"] is True - def test_too_large(self, app): + def test_too_large(self, app: Flask): api = PluginUploadFromBundleApi() method = unwrap(api.post) @@ -458,7 +459,7 @@ class TestPluginUploadFromBundleApi: class TestPluginInstallFromGithubApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginInstallFromGithubApi() method = unwrap(api.post) @@ -478,7 +479,7 @@ class TestPluginInstallFromGithubApi: assert result["ok"] is True - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginInstallFromGithubApi() method = unwrap(api.post) @@ -502,7 +503,7 @@ class TestPluginInstallFromGithubApi: class TestPluginInstallFromMarketplaceApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginInstallFromMarketplaceApi() method = unwrap(api.post) @@ -520,7 +521,7 @@ class TestPluginInstallFromMarketplaceApi: assert result["ok"] is True - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginInstallFromMarketplaceApi() method = unwrap(api.post) @@ -539,7 +540,7 @@ class TestPluginInstallFromMarketplaceApi: class TestPluginFetchMarketplacePkgApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginFetchMarketplacePkgApi() method = unwrap(api.get) @@ -552,7 +553,7 @@ class TestPluginFetchMarketplacePkgApi: assert "manifest" in result - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginFetchMarketplacePkgApi() method = unwrap(api.get) @@ -569,7 +570,7 @@ class TestPluginFetchMarketplacePkgApi: class TestPluginFetchManifestApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginFetchManifestApi() method = unwrap(api.get) @@ -585,7 +586,7 @@ class TestPluginFetchManifestApi: assert "manifest" in result - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginFetchManifestApi() method = unwrap(api.get) @@ -602,7 +603,7 @@ class TestPluginFetchManifestApi: class TestPluginFetchInstallTasksApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginFetchInstallTasksApi() method = unwrap(api.get) @@ -615,7 +616,7 @@ class TestPluginFetchInstallTasksApi: assert "tasks" in result - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginFetchInstallTasksApi() method = unwrap(api.get) @@ -632,7 +633,7 @@ class TestPluginFetchInstallTasksApi: class TestPluginFetchInstallTaskApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginFetchInstallTaskApi() method = unwrap(api.get) @@ -645,7 +646,7 @@ class TestPluginFetchInstallTaskApi: assert "task" in result - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginFetchInstallTaskApi() method = unwrap(api.get) @@ -662,7 +663,7 @@ class TestPluginFetchInstallTaskApi: class TestPluginDeleteInstallTaskApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginDeleteInstallTaskApi() method = unwrap(api.post) @@ -675,7 +676,7 @@ class TestPluginDeleteInstallTaskApi: assert result["success"] is True - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginDeleteInstallTaskApi() method = unwrap(api.post) @@ -692,7 +693,7 @@ class TestPluginDeleteInstallTaskApi: class TestPluginDeleteAllInstallTaskItemsApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginDeleteAllInstallTaskItemsApi() method = unwrap(api.post) @@ -707,7 +708,7 @@ class TestPluginDeleteAllInstallTaskItemsApi: assert result["success"] is True - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginDeleteAllInstallTaskItemsApi() method = unwrap(api.post) @@ -724,7 +725,7 @@ class TestPluginDeleteAllInstallTaskItemsApi: class TestPluginDeleteInstallTaskItemApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginDeleteInstallTaskItemApi() method = unwrap(api.post) @@ -737,7 +738,7 @@ class TestPluginDeleteInstallTaskItemApi: assert result["success"] is True - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginDeleteInstallTaskItemApi() method = unwrap(api.post) @@ -754,7 +755,7 @@ class TestPluginDeleteInstallTaskItemApi: class TestPluginUpgradeFromMarketplaceApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginUpgradeFromMarketplaceApi() method = unwrap(api.post) @@ -775,7 +776,7 @@ class TestPluginUpgradeFromMarketplaceApi: assert result["ok"] is True - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginUpgradeFromMarketplaceApi() method = unwrap(api.post) @@ -797,7 +798,7 @@ class TestPluginUpgradeFromMarketplaceApi: class TestPluginUpgradeFromGithubApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginUpgradeFromGithubApi() method = unwrap(api.post) @@ -821,7 +822,7 @@ class TestPluginUpgradeFromGithubApi: assert result["ok"] is True - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginUpgradeFromGithubApi() method = unwrap(api.post) @@ -846,7 +847,7 @@ class TestPluginUpgradeFromGithubApi: class TestPluginFetchDynamicSelectOptionsWithCredentialsApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginFetchDynamicSelectOptionsWithCredentialsApi() method = unwrap(api.post) @@ -873,7 +874,7 @@ class TestPluginFetchDynamicSelectOptionsWithCredentialsApi: assert result["options"] == [1] - def test_daemon_error(self, app): + def test_daemon_error(self, app: Flask): api = PluginFetchDynamicSelectOptionsWithCredentialsApi() method = unwrap(api.post) @@ -901,7 +902,7 @@ class TestPluginFetchDynamicSelectOptionsWithCredentialsApi: class TestPluginChangePreferencesApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginChangePreferencesApi() method = unwrap(api.post) @@ -931,7 +932,7 @@ class TestPluginChangePreferencesApi: assert result["success"] is True - def test_permission_fail(self, app): + def test_permission_fail(self, app: Flask): api = PluginChangePreferencesApi() method = unwrap(api.post) @@ -962,7 +963,7 @@ class TestPluginChangePreferencesApi: class TestPluginFetchPreferencesApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginFetchPreferencesApi() method = unwrap(api.get) @@ -996,7 +997,7 @@ class TestPluginFetchPreferencesApi: class TestPluginAutoUpgradeExcludePluginApi: - def test_success(self, app): + def test_success(self, app: Flask): api = PluginAutoUpgradeExcludePluginApi() method = unwrap(api.post) @@ -1011,7 +1012,7 @@ class TestPluginAutoUpgradeExcludePluginApi: assert result["success"] is True - def test_fail(self, app): + def test_fail(self, app: Flask): api = PluginAutoUpgradeExcludePluginApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/workspace/test_workspace.py b/api/tests/unit_tests/controllers/console/workspace/test_workspace.py index e82a29f045..a52518c2d2 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_workspace.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_workspace.py @@ -2,6 +2,7 @@ from io import BytesIO from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.datastructures import FileStorage from werkzeug.exceptions import Unauthorized @@ -37,7 +38,7 @@ def unwrap(func): class TestTenantListApi: - def test_get_success_saas_path(self, app): + def test_get_success_saas_path(self, app: Flask): api = TenantListApi() method = unwrap(api.get) @@ -85,7 +86,7 @@ class TestTenantListApi: get_plan_bulk_mock.assert_called_once_with(["t1", "t2"]) get_features_mock.assert_not_called() - def test_get_saas_path_partial_fallback_does_not_gate_plan_on_billing_enabled(self, app): + def test_get_saas_path_partial_fallback_does_not_gate_plan_on_billing_enabled(self, app: Flask): """Bulk omits a tenant: resolve plan via subscription.plan only; billing.enabled is not used. billing.enabled is mocked False to prove the endpoint does not gate on it for this path @@ -140,7 +141,7 @@ class TestTenantListApi: get_plan_bulk_mock.assert_called_once_with(["t1", "t2"]) get_features_mock.assert_called_once_with("t2") - def test_get_saas_path_falls_back_to_legacy_feature_path_on_bulk_error(self, app): + def test_get_saas_path_falls_back_to_legacy_feature_path_on_bulk_error(self, app: Flask): """Test fallback to FeatureService when bulk billing returns empty result. BillingService.get_plan_bulk catches exceptions internally and returns empty dict, @@ -197,7 +198,7 @@ class TestTenantListApi: assert get_features_mock.call_count == 2 logger_warning_mock.assert_called_once() - def test_get_billing_disabled_community_path(self, app): + def test_get_billing_disabled_community_path(self, app: Flask): api = TenantListApi() method = unwrap(api.get) @@ -236,7 +237,7 @@ class TestTenantListApi: assert result["workspaces"][0]["plan"] == CloudPlan.SANDBOX get_features_mock.assert_called_once_with("t1") - def test_get_enterprise_only_skips_feature_service(self, app): + def test_get_enterprise_only_skips_feature_service(self, app: Flask): api = TenantListApi() method = unwrap(api.get) @@ -276,7 +277,7 @@ class TestTenantListApi: assert result["workspaces"][1]["current"] is True get_features_mock.assert_not_called() - def test_get_enterprise_only_with_empty_tenants(self, app): + def test_get_enterprise_only_with_empty_tenants(self, app: Flask): api = TenantListApi() method = unwrap(api.get) @@ -302,7 +303,7 @@ class TestTenantListApi: class TestWorkspaceListApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = WorkspaceListApi() method = unwrap(api.get) @@ -324,7 +325,7 @@ class TestWorkspaceListApi: assert result["total"] == 1 assert result["has_more"] is False - def test_get_has_next_true(self, app): + def test_get_has_next_true(self, app: Flask): api = WorkspaceListApi() method = unwrap(api.get) @@ -355,7 +356,7 @@ class TestWorkspaceListApi: class TestTenantApi: - def test_post_active_tenant(self, app): + def test_post_active_tenant(self, app: Flask): api = TenantApi() method = unwrap(api.post) @@ -375,7 +376,7 @@ class TestTenantApi: assert status == 200 assert result["id"] == "t1" - def test_post_archived_with_switch(self, app): + def test_post_archived_with_switch(self, app: Flask): api = TenantApi() method = unwrap(api.post) @@ -397,7 +398,7 @@ class TestTenantApi: assert result["id"] == "new" - def test_post_archived_no_tenant(self, app): + def test_post_archived_no_tenant(self, app: Flask): api = TenantApi() method = unwrap(api.post) @@ -411,7 +412,7 @@ class TestTenantApi: with pytest.raises(Unauthorized): method(api) - def test_post_info_path(self, app): + def test_post_info_path(self, app: Flask): api = TenantApi() method = unwrap(api.post) @@ -454,7 +455,7 @@ class TestTenantInfoResponse: class TestSwitchWorkspaceApi: - def test_switch_success(self, app): + def test_switch_success(self, app: Flask): api = SwitchWorkspaceApi() method = unwrap(api.post) @@ -477,7 +478,7 @@ class TestSwitchWorkspaceApi: assert result["result"] == "success" - def test_switch_not_linked(self, app): + def test_switch_not_linked(self, app: Flask): api = SwitchWorkspaceApi() method = unwrap(api.post) @@ -493,7 +494,7 @@ class TestSwitchWorkspaceApi: with pytest.raises(AccountNotLinkTenantError): method(api) - def test_switch_tenant_not_found(self, app): + def test_switch_tenant_not_found(self, app: Flask): api = SwitchWorkspaceApi() method = unwrap(api.post) @@ -515,7 +516,7 @@ class TestSwitchWorkspaceApi: class TestCustomConfigWorkspaceApi: - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = CustomConfigWorkspaceApi() method = unwrap(api.post) @@ -538,7 +539,7 @@ class TestCustomConfigWorkspaceApi: assert result["result"] == "success" - def test_logo_fallback(self, app): + def test_logo_fallback(self, app: Flask): api = CustomConfigWorkspaceApi() method = unwrap(api.post) @@ -569,7 +570,7 @@ class TestCustomConfigWorkspaceApi: class TestWebappLogoWorkspaceApi: - def test_no_file(self, app): + def test_no_file(self, app: Flask): api = WebappLogoWorkspaceApi() method = unwrap(api.post) @@ -582,7 +583,7 @@ class TestWebappLogoWorkspaceApi: with pytest.raises(NoFileUploadedError): method(api) - def test_too_many_files(self, app): + def test_too_many_files(self, app: Flask): api = WebappLogoWorkspaceApi() method = unwrap(api.post) @@ -601,7 +602,7 @@ class TestWebappLogoWorkspaceApi: with pytest.raises(TooManyFilesError): method(api) - def test_invalid_extension(self, app): + def test_invalid_extension(self, app: Flask): api = WebappLogoWorkspaceApi() method = unwrap(api.post) @@ -616,7 +617,7 @@ class TestWebappLogoWorkspaceApi: with pytest.raises(UnsupportedFileTypeError): method(api) - def test_upload_success(self, app): + def test_upload_success(self, app: Flask): api = WebappLogoWorkspaceApi() method = unwrap(api.post) @@ -648,7 +649,7 @@ class TestWebappLogoWorkspaceApi: assert status == 201 assert result["id"] == "file1" - def test_filename_missing(self, app): + def test_filename_missing(self, app: Flask): api = WebappLogoWorkspaceApi() method = unwrap(api.post) @@ -672,7 +673,7 @@ class TestWebappLogoWorkspaceApi: with pytest.raises(FilenameNotExistsError): method(api) - def test_file_too_large(self, app): + def test_file_too_large(self, app: Flask): api = WebappLogoWorkspaceApi() method = unwrap(api.post) @@ -701,7 +702,7 @@ class TestWebappLogoWorkspaceApi: with pytest.raises(FileTooLargeError): method(api) - def test_service_unsupported_file(self, app): + def test_service_unsupported_file(self, app: Flask): api = WebappLogoWorkspaceApi() method = unwrap(api.post) @@ -732,7 +733,7 @@ class TestWebappLogoWorkspaceApi: class TestWorkspaceInfoApi: - def test_post_success(self, app): + def test_post_success(self, app: Flask): api = WorkspaceInfoApi() method = unwrap(api.post) @@ -756,7 +757,7 @@ class TestWorkspaceInfoApi: assert result["result"] == "success" - def test_no_current_tenant(self, app): + def test_no_current_tenant(self, app: Flask): api = WorkspaceInfoApi() method = unwrap(api.post) @@ -774,7 +775,7 @@ class TestWorkspaceInfoApi: class TestWorkspacePermissionApi: - def test_get_success(self, app): + def test_get_success(self, app: Flask): api = WorkspacePermissionApi() method = unwrap(api.get) @@ -799,7 +800,7 @@ class TestWorkspacePermissionApi: assert status == 200 assert result["workspace_id"] == "t1" - def test_no_current_tenant(self, app): + def test_no_current_tenant(self, app: Flask): api = WorkspacePermissionApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/service_api/app/test_app.py b/api/tests/unit_tests/controllers/service_api/app/test_app.py index f5d93b5ac3..ae0edcf382 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_app.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_app.py @@ -41,7 +41,7 @@ class TestAppParameterApi: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.db") def test_get_parameters_for_chat_app( - self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app, mock_app_model + self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app: Flask, mock_app_model ): """Test retrieving parameters for a chat app.""" # Arrange @@ -91,7 +91,7 @@ class TestAppParameterApi: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.db") def test_get_parameters_for_workflow_app( - self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app, mock_app_model + self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app: Flask, mock_app_model ): """Test retrieving parameters for a workflow app.""" # Arrange @@ -136,7 +136,7 @@ class TestAppParameterApi: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.db") def test_get_parameters_raises_error_when_chat_config_missing( - self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app, mock_app_model + self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app: Flask, mock_app_model ): """Test that AppUnavailableError is raised when chat app has no config.""" # Arrange @@ -174,7 +174,7 @@ class TestAppParameterApi: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.db") def test_get_parameters_raises_error_when_workflow_missing( - self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app, mock_app_model + self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app: Flask, mock_app_model ): """Test that AppUnavailableError is raised when workflow app has no workflow.""" # Arrange @@ -234,7 +234,14 @@ class TestAppMetaApi: @patch("controllers.service_api.wraps.db") @patch("controllers.service_api.app.app.AppService") def test_get_app_meta( - self, mock_app_service, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app, mock_app_model + self, + mock_app_service, + mock_db, + mock_validate_token, + mock_current_app, + mock_user_logged_in, + app: Flask, + mock_app_model, ): """Test retrieving app metadata via AppService.""" # Arrange @@ -310,7 +317,7 @@ class TestAppInfoApi: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.db") def test_get_app_info( - self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app, mock_app_model + self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app: Flask, mock_app_model ): """Test retrieving basic app information.""" mock_current_app.login_manager = Mock() @@ -402,7 +409,9 @@ class TestAppInfoApi: @patch("controllers.service_api.wraps.current_app") @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.db") - def test_get_app_info_with_no_tags(self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app): + def test_get_app_info_with_no_tags( + self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app: Flask + ): """Test retrieving app info when app has no tags.""" # Arrange mock_current_app.login_manager = Mock() @@ -453,7 +462,7 @@ class TestAppInfoApi: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.db") def test_get_app_info_returns_correct_mode( - self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app, app_mode + self, mock_db, mock_validate_token, mock_current_app, mock_user_logged_in, app: Flask, app_mode ): """Test that all app modes are correctly returned.""" # Arrange diff --git a/api/tests/unit_tests/controllers/service_api/app/test_audio.py b/api/tests/unit_tests/controllers/service_api/app/test_audio.py index c16ebad739..4741481ef6 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_audio.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_audio.py @@ -13,6 +13,7 @@ from types import SimpleNamespace from unittest.mock import Mock, patch import pytest +from flask import Flask from werkzeug.datastructures import FileStorage from werkzeug.exceptions import InternalServerError @@ -190,7 +191,7 @@ class TestAudioServiceMockedBehavior: class TestAudioApi: - def test_success(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_success(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(AudioService, "transcript_asr", lambda **_kwargs: {"text": "ok"}) api = AudioApi() handler = _unwrap(api.post) @@ -216,7 +217,7 @@ class TestAudioApi: (InvokeError("invoke"), CompletionRequestError), ], ) - def test_error_mapping(self, app, monkeypatch: pytest.MonkeyPatch, exc, expected) -> None: + def test_error_mapping(self, app: Flask, monkeypatch: pytest.MonkeyPatch, exc, expected) -> None: monkeypatch.setattr(AudioService, "transcript_asr", lambda **_kwargs: (_ for _ in ()).throw(exc)) api = AudioApi() handler = _unwrap(api.post) @@ -227,7 +228,7 @@ class TestAudioApi: with pytest.raises(expected): handler(api, app_model=app_model, end_user=end_user) - def test_unhandled_error(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_unhandled_error(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( AudioService, "transcript_asr", lambda **_kwargs: (_ for _ in ()).throw(RuntimeError("boom")) ) @@ -242,7 +243,7 @@ class TestAudioApi: class TestTextApi: - def test_success(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_success(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(AudioService, "transcript_tts", lambda **_kwargs: {"audio": "ok"}) api = TextApi() @@ -259,7 +260,7 @@ class TestTextApi: assert response == {"audio": "ok"} - def test_error_mapping(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_error_mapping(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( AudioService, "transcript_tts", lambda **_kwargs: (_ for _ in ()).throw(QuotaExceededError()) ) diff --git a/api/tests/unit_tests/controllers/service_api/app/test_completion.py b/api/tests/unit_tests/controllers/service_api/app/test_completion.py index 3364c07e62..259741937f 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_completion.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_completion.py @@ -16,6 +16,7 @@ from types import SimpleNamespace from unittest.mock import Mock, patch import pytest +from flask import Flask from pydantic import ValidationError from werkzeug.exceptions import BadRequest, NotFound @@ -295,7 +296,7 @@ class TestCompletionControllerLogic: @patch("controllers.service_api.app.completion.service_api_ns") @patch("controllers.service_api.app.completion.AppGenerateService") - def test_completion_api_post_success(self, mock_generate_service, mock_service_api_ns, app): + def test_completion_api_post_success(self, mock_generate_service, mock_service_api_ns, app: Flask): """Test CompletionApi.post success path.""" from controllers.service_api.app.completion import CompletionApi @@ -320,7 +321,7 @@ class TestCompletionControllerLogic: mock_generate_service.generate.assert_called_once() @patch("controllers.service_api.app.completion.service_api_ns") - def test_completion_api_post_wrong_app_mode(self, mock_service_api_ns, app): + def test_completion_api_post_wrong_app_mode(self, mock_service_api_ns, app: Flask): """Test CompletionApi.post with wrong app mode.""" from controllers.service_api.app.completion import CompletionApi @@ -334,7 +335,7 @@ class TestCompletionControllerLogic: @patch("controllers.service_api.app.completion.service_api_ns") @patch("controllers.service_api.app.completion.AppGenerateService") - def test_chat_api_post_success(self, mock_generate_service, mock_service_api_ns, app): + def test_chat_api_post_success(self, mock_generate_service, mock_service_api_ns, app: Flask): """Test ChatApi.post success path.""" from controllers.service_api.app.completion import ChatApi @@ -355,7 +356,7 @@ class TestCompletionControllerLogic: assert response == {"text": "compacted"} @patch("controllers.service_api.app.completion.service_api_ns") - def test_chat_api_post_wrong_app_mode(self, mock_service_api_ns, app): + def test_chat_api_post_wrong_app_mode(self, mock_service_api_ns, app: Flask): """Test ChatApi.post with wrong app mode.""" from controllers.service_api.app.completion import ChatApi @@ -368,7 +369,7 @@ class TestCompletionControllerLogic: ChatApi().post.__wrapped__(ChatApi(), mock_app_model, mock_end_user) @patch("controllers.service_api.app.completion.AppTaskService") - def test_completion_stop_api_success(self, mock_task_service, app): + def test_completion_stop_api_success(self, mock_task_service, app: Flask): """Test CompletionStopApi.post success.""" from controllers.service_api.app.completion import CompletionStopApi @@ -385,7 +386,7 @@ class TestCompletionControllerLogic: mock_task_service.stop_task.assert_called_once() @patch("controllers.service_api.app.completion.AppTaskService") - def test_chat_stop_api_success(self, mock_task_service, app): + def test_chat_stop_api_success(self, mock_task_service, app: Flask): """Test ChatStopApi.post success.""" from controllers.service_api.app.completion import ChatStopApi diff --git a/api/tests/unit_tests/controllers/service_api/app/test_conversation.py b/api/tests/unit_tests/controllers/service_api/app/test_conversation.py index 4fb8ecf784..6dc8f54d42 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_conversation.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_conversation.py @@ -20,6 +20,7 @@ from types import SimpleNamespace from unittest.mock import Mock, patch import pytest +from flask import Flask from werkzeug.exceptions import BadRequest, NotFound import services @@ -504,7 +505,7 @@ class TestConversationApiController: with pytest.raises(NotChatAppError): handler(api, app_model=app_model, end_user=end_user) - def test_list_last_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_list_last_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: class _BeginStub: def __enter__(self): return SimpleNamespace() @@ -552,7 +553,7 @@ class TestConversationDetailApiController: with pytest.raises(NotChatAppError): handler(api, app_model=app_model, end_user=end_user, c_id="00000000-0000-0000-0000-000000000001") - def test_delete_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_delete_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( ConversationService, "delete", @@ -570,7 +571,7 @@ class TestConversationDetailApiController: class TestConversationRenameApiController: - def test_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( ConversationService, "rename", @@ -602,7 +603,7 @@ class TestConversationVariablesApiController: with pytest.raises(NotChatAppError): handler(api, app_model=app_model, end_user=end_user, c_id="00000000-0000-0000-0000-000000000001") - def test_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( ConversationService, "get_conversational_variable", @@ -621,7 +622,7 @@ class TestConversationVariablesApiController: with pytest.raises(NotFound): handler(api, app_model=app_model, end_user=end_user, c_id="00000000-0000-0000-0000-000000000001") - def test_success_serializes_response(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_success_serializes_response(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: created_at = datetime(2026, 1, 2, 3, 4, 5, tzinfo=UTC) monkeypatch.setattr( ConversationService, @@ -661,7 +662,7 @@ class TestConversationVariablesApiController: class TestConversationVariableDetailApiController: - def test_update_type_mismatch(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_update_type_mismatch(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( ConversationService, "update_conversation_variable", @@ -687,7 +688,7 @@ class TestConversationVariableDetailApiController: variable_id="00000000-0000-0000-0000-000000000002", ) - def test_update_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_update_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( ConversationService, "update_conversation_variable", @@ -713,7 +714,7 @@ class TestConversationVariableDetailApiController: variable_id="00000000-0000-0000-0000-000000000002", ) - def test_update_success_serializes_response(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_update_success_serializes_response(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: created_at = datetime(2026, 1, 2, 3, 4, 5, tzinfo=UTC) monkeypatch.setattr( ConversationService, diff --git a/api/tests/unit_tests/controllers/service_api/app/test_file.py b/api/tests/unit_tests/controllers/service_api/app/test_file.py index 7060bd79df..2615c3edac 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_file.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_file.py @@ -16,6 +16,7 @@ import uuid from unittest.mock import Mock, patch import pytest +from flask import Flask from controllers.common.errors import ( FilenameNotExistsError, @@ -282,7 +283,7 @@ class TestFileApiPost: assert status == 201 mock_file_svc_cls.return_value.upload_file.assert_called_once() - def test_upload_no_file(self, app, mock_app_model, mock_end_user): + def test_upload_no_file(self, app: Flask, mock_app_model, mock_end_user): """Test NoFileUploadedError when no file in request.""" from controllers.service_api.app.file import FileApi @@ -296,7 +297,7 @@ class TestFileApiPost: with pytest.raises(NoFileUploadedError): _unwrap(api.post)(api, app_model=mock_app_model, end_user=mock_end_user) - def test_upload_too_many_files(self, app, mock_app_model, mock_end_user): + def test_upload_too_many_files(self, app: Flask, mock_app_model, mock_end_user): """Test TooManyFilesError when multiple files uploaded.""" from io import BytesIO @@ -317,7 +318,7 @@ class TestFileApiPost: with pytest.raises(TooManyFilesError): _unwrap(api.post)(api, app_model=mock_app_model, end_user=mock_end_user) - def test_upload_no_mimetype(self, app, mock_app_model, mock_end_user): + def test_upload_no_mimetype(self, app: Flask, mock_app_model, mock_end_user): """Test UnsupportedFileTypeError when file has no mimetype.""" from io import BytesIO diff --git a/api/tests/unit_tests/controllers/service_api/app/test_hitl_service_api.py b/api/tests/unit_tests/controllers/service_api/app/test_hitl_service_api.py index 846d5368f3..510d4a9470 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_hitl_service_api.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_hitl_service_api.py @@ -11,6 +11,7 @@ from types import SimpleNamespace from unittest.mock import ANY, MagicMock, Mock import pytest +from flask import Flask import services.app_generate_service as ags_module from controllers.service_api.app.workflow_events import WorkflowEventsApi @@ -281,7 +282,7 @@ class TestHitlServiceApi: workflow_generator.convert_to_event_stream.assert_called_once_with(["raw-event"]) def test_workflow_events_snapshot_continue_on_pause_keeps_pause_open( - self, app, monkeypatch: pytest.MonkeyPatch + self, app: Flask, monkeypatch: pytest.MonkeyPatch ) -> None: workflow_run = SimpleNamespace( id="run-1", diff --git a/api/tests/unit_tests/controllers/service_api/app/test_message.py b/api/tests/unit_tests/controllers/service_api/app/test_message.py index c2b8aed1ae..2bc9771862 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_message.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_message.py @@ -19,6 +19,7 @@ from types import SimpleNamespace from unittest.mock import Mock, patch import pytest +from flask import Flask from werkzeug.exceptions import BadRequest, InternalServerError, NotFound from controllers.service_api.app.error import NotChatAppError @@ -390,7 +391,7 @@ class TestMessageListApi: with pytest.raises(NotChatAppError): handler(api, app_model=app_model, end_user=end_user) - def test_conversation_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_conversation_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( MessageService, "pagination_by_first_id", @@ -409,7 +410,7 @@ class TestMessageListApi: with pytest.raises(NotFound): handler(api, app_model=app_model, end_user=end_user) - def test_first_message_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_first_message_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( MessageService, "pagination_by_first_id", @@ -430,7 +431,7 @@ class TestMessageListApi: class TestMessageFeedbackApi: - def test_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( MessageService, "create_feedback", @@ -452,7 +453,7 @@ class TestMessageFeedbackApi: class TestAppGetFeedbacksApi: - def test_success(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_success(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(MessageService, "get_all_messages_feedbacks", lambda *_args, **_kwargs: ["f1"]) api = AppGetFeedbacksApi() @@ -476,7 +477,7 @@ class TestMessageSuggestedApi: with pytest.raises(NotChatAppError): handler(api, app_model=app_model, end_user=end_user, message_id="m1") - def test_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( MessageService, "get_suggested_questions_after_answer", @@ -492,7 +493,7 @@ class TestMessageSuggestedApi: with pytest.raises(NotFound): handler(api, app_model=app_model, end_user=end_user, message_id="m1") - def test_disabled(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_disabled(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( MessageService, "get_suggested_questions_after_answer", @@ -508,7 +509,7 @@ class TestMessageSuggestedApi: with pytest.raises(BadRequest): handler(api, app_model=app_model, end_user=end_user, message_id="m1") - def test_internal_error(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_internal_error(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( MessageService, "get_suggested_questions_after_answer", @@ -524,7 +525,7 @@ class TestMessageSuggestedApi: with pytest.raises(InternalServerError): handler(api, app_model=app_model, end_user=end_user, message_id="m1") - def test_success(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_success(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( MessageService, "get_suggested_questions_after_answer", diff --git a/api/tests/unit_tests/controllers/service_api/app/test_workflow.py b/api/tests/unit_tests/controllers/service_api/app/test_workflow.py index da09ec13ce..7115ea1e12 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_workflow.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_workflow.py @@ -20,6 +20,7 @@ from types import SimpleNamespace from unittest.mock import Mock, patch import pytest +from flask import Flask from werkzeug.exceptions import BadRequest, NotFound from controllers.service_api.app.error import NotWorkflowAppError @@ -366,7 +367,7 @@ class TestWorkflowRunRepository: class TestWorkflowRunDetailApi: - def test_not_workflow_app(self, app) -> None: + def test_not_workflow_app(self, app: Flask) -> None: api = WorkflowRunDetailApi() handler = _unwrap(api.get) app_model = SimpleNamespace(mode=AppMode.CHAT.value) @@ -397,7 +398,7 @@ class TestWorkflowRunDetailApi: class TestWorkflowRunApi: - def test_not_workflow_app(self, app) -> None: + def test_not_workflow_app(self, app: Flask) -> None: api = WorkflowRunApi() handler = _unwrap(api.post) app_model = SimpleNamespace(mode=AppMode.CHAT.value) @@ -407,7 +408,7 @@ class TestWorkflowRunApi: with pytest.raises(NotWorkflowAppError): handler(api, app_model=app_model, end_user=end_user) - def test_rate_limit(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_rate_limit(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( AppGenerateService, "generate", @@ -425,7 +426,7 @@ class TestWorkflowRunApi: class TestWorkflowRunByIdApi: - def test_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( AppGenerateService, "generate", @@ -441,7 +442,7 @@ class TestWorkflowRunByIdApi: with pytest.raises(NotFound): handler(api, app_model=app_model, end_user=end_user, workflow_id="w1") - def test_draft_workflow(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_draft_workflow(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( AppGenerateService, "generate", @@ -459,7 +460,7 @@ class TestWorkflowRunByIdApi: class TestWorkflowTaskStopApi: - def test_wrong_mode(self, app) -> None: + def test_wrong_mode(self, app: Flask) -> None: api = WorkflowTaskStopApi() handler = _unwrap(api.post) app_model = SimpleNamespace(mode=AppMode.CHAT.value) @@ -469,7 +470,7 @@ class TestWorkflowTaskStopApi: with pytest.raises(NotWorkflowAppError): handler(api, app_model=app_model, end_user=end_user, task_id="t1") - def test_success(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_success(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: stop_mock = Mock() send_mock = Mock() monkeypatch.setattr(AppQueueManager, "set_stop_flag_no_user_check", stop_mock) @@ -489,7 +490,7 @@ class TestWorkflowTaskStopApi: class TestWorkflowAppLogApi: - def test_success(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_success(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: class _BeginStub: def __enter__(self): return SimpleNamespace() @@ -557,7 +558,7 @@ class TestWorkflowRunDetailApiGet: self, mock_db, mock_repo_factory, - app, + app: Flask, mock_workflow_app, ): """Test successful workflow run detail retrieval.""" @@ -579,7 +580,7 @@ class TestWorkflowRunDetailApiGet: assert result["status"] == "succeeded" @patch("controllers.service_api.app.workflow.db") - def test_get_workflow_run_wrong_app_mode(self, mock_db, app): + def test_get_workflow_run_wrong_app_mode(self, mock_db, app: Flask): """Test NotWorkflowAppError when app mode is not workflow or advanced_chat.""" from controllers.service_api.app.workflow import WorkflowRunDetailApi @@ -604,7 +605,7 @@ class TestWorkflowTaskStopApiPost: self, mock_queue_mgr, mock_graph_mgr, - app, + app: Flask, mock_workflow_app, ): """Test successful workflow task stop.""" @@ -624,7 +625,7 @@ class TestWorkflowTaskStopApiPost: mock_graph_mgr.assert_called_once() mock_graph_mgr.return_value.send_stop_command.assert_called_once_with("task-1") - def test_stop_workflow_task_wrong_app_mode(self, app): + def test_stop_workflow_task_wrong_app_mode(self, app: Flask): """Test NotWorkflowAppError when app mode is not workflow.""" from controllers.service_api.app.workflow import WorkflowTaskStopApi @@ -649,7 +650,7 @@ class TestWorkflowAppLogApiGet: self, mock_db, mock_wf_svc_cls, - app, + app: Flask, mock_workflow_app, ): """Test successful workflow log retrieval.""" diff --git a/api/tests/unit_tests/controllers/service_api/app/test_workflow_events.py b/api/tests/unit_tests/controllers/service_api/app/test_workflow_events.py index f45a7f9632..b3edc2ecd8 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_workflow_events.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_workflow_events.py @@ -9,6 +9,7 @@ from types import SimpleNamespace from unittest.mock import Mock import pytest +from flask import Flask from werkzeug.exceptions import NotFound from controllers.service_api.app.error import NotWorkflowAppError @@ -41,7 +42,7 @@ class TestWorkflowEventsApi: with pytest.raises(NotWorkflowAppError): handler(api, app_model=app_model, end_user=end_user, task_id="run-1") - def test_workflow_run_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_workflow_run_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: _mock_repo_for_run(monkeypatch, workflow_run=None) api = WorkflowEventsApi() handler = _unwrap(api.get) @@ -52,7 +53,7 @@ class TestWorkflowEventsApi: with pytest.raises(NotFound): handler(api, app_model=app_model, end_user=end_user, task_id="run-1") - def test_workflow_run_permission_denied(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_workflow_run_permission_denied(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: workflow_run = SimpleNamespace( id="run-1", app_id="app-1", @@ -70,7 +71,7 @@ class TestWorkflowEventsApi: with pytest.raises(NotFound): handler(api, app_model=app_model, end_user=end_user, task_id="run-1") - def test_finished_run_returns_sse(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_finished_run_returns_sse(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: workflow_run = SimpleNamespace( id="run-1", app_id="app-1", @@ -103,7 +104,7 @@ class TestWorkflowEventsApi: assert payload["task_id"] == "run-1" assert payload["event"] == "workflow_finished" - def test_running_run_streams_events(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_running_run_streams_events(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: workflow_run = SimpleNamespace( id="run-1", app_id="app-1", @@ -135,7 +136,7 @@ class TestWorkflowEventsApi: ) workflow_generator.convert_to_event_stream.assert_called_once_with(["raw-event"]) - def test_running_run_with_snapshot(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_running_run_with_snapshot(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: workflow_run = SimpleNamespace( id="run-1", app_id="app-1", diff --git a/api/tests/unit_tests/controllers/service_api/dataset/rag_pipeline/test_rag_pipeline_workflow.py b/api/tests/unit_tests/controllers/service_api/dataset/rag_pipeline/test_rag_pipeline_workflow.py index f33c482d04..362af883ed 100644 --- a/api/tests/unit_tests/controllers/service_api/dataset/rag_pipeline/test_rag_pipeline_workflow.py +++ b/api/tests/unit_tests/controllers/service_api/dataset/rag_pipeline/test_rag_pipeline_workflow.py @@ -23,6 +23,7 @@ from datetime import UTC, datetime from unittest.mock import Mock, patch import pytest +from flask import Flask from werkzeug.datastructures import FileStorage from werkzeug.exceptions import Forbidden, NotFound @@ -373,7 +374,7 @@ class TestDatasourcePluginsApiGet: @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.db") @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.RagPipelineService") - def test_get_plugins_success(self, mock_svc_cls, mock_db, app): + def test_get_plugins_success(self, mock_svc_cls, mock_db, app: Flask): """Test successful retrieval of datasource plugins.""" tenant_id = str(uuid.uuid4()) dataset_id = str(uuid.uuid4()) @@ -396,7 +397,7 @@ class TestDatasourcePluginsApiGet: ) @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.db") - def test_get_plugins_not_found(self, mock_db, app): + def test_get_plugins_not_found(self, mock_db, app: Flask): """Test NotFound when dataset check fails.""" mock_db.session.scalar.return_value = None @@ -407,7 +408,7 @@ class TestDatasourcePluginsApiGet: @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.db") @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.RagPipelineService") - def test_get_plugins_empty_list(self, mock_svc_cls, mock_db, app): + def test_get_plugins_empty_list(self, mock_svc_cls, mock_db, app: Flask): """Test empty plugin list.""" mock_db.session.scalar.return_value = Mock() mock_svc_instance = Mock() @@ -439,7 +440,7 @@ class TestDatasourceNodeRunApiPost: @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.RagPipelineService") @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.db") @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.service_api_ns") - def test_post_success(self, mock_ns, mock_db, mock_svc_cls, mock_current_user, mock_gen, mock_helper, app): + def test_post_success(self, mock_ns, mock_db, mock_svc_cls, mock_current_user, mock_gen, mock_helper, app: Flask): """Test successful datasource node run.""" tenant_id = str(uuid.uuid4()) dataset_id = str(uuid.uuid4()) @@ -473,7 +474,7 @@ class TestDatasourceNodeRunApiPost: mock_svc_instance.run_datasource_workflow_node.assert_called_once() @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.db") - def test_post_not_found(self, mock_db, app): + def test_post_not_found(self, mock_db, app: Flask): """Test NotFound when dataset check fails.""" mock_db.session.scalar.return_value = None @@ -488,7 +489,7 @@ class TestDatasourceNodeRunApiPost: ) @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.db") @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.service_api_ns") - def test_post_fails_when_current_user_not_account(self, mock_ns, mock_db, app): + def test_post_fails_when_current_user_not_account(self, mock_ns, mock_db, app: Flask): """Test AssertionError when current_user is not an Account instance.""" mock_db.session.scalar.return_value = Mock() mock_ns.payload = { @@ -549,7 +550,7 @@ class TestPipelineRunApiPost: mock_gen_svc.generate.assert_called_once() @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.db") - def test_post_not_found(self, mock_db, app): + def test_post_not_found(self, mock_db, app: Flask): """Test NotFound when dataset check fails.""" mock_db.session.scalar.return_value = None @@ -561,7 +562,7 @@ class TestPipelineRunApiPost: @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.current_user", new="not_account") @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.db") @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.service_api_ns") - def test_post_forbidden_non_account_user(self, mock_ns, mock_db, app): + def test_post_forbidden_non_account_user(self, mock_ns, mock_db, app: Flask): """Test Forbidden when current_user is not an Account.""" mock_db.session.scalar.return_value = Mock() mock_ns.payload = { @@ -585,7 +586,7 @@ class TestFileUploadApiPost: @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.FileService") @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.current_user") @patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.db") - def test_upload_success(self, mock_db, mock_current_user, mock_file_svc_cls, app): + def test_upload_success(self, mock_db, mock_current_user, mock_file_svc_cls, app: Flask): """Test successful file upload.""" mock_current_user.__bool__ = Mock(return_value=True) @@ -621,7 +622,7 @@ class TestFileUploadApiPost: assert response["name"] == "doc.pdf" assert response["extension"] == "pdf" - def test_upload_no_file(self, app): + def test_upload_no_file(self, app: Flask): """Test error when no file is uploaded.""" with app.test_request_context( "/datasets/pipeline/file-upload", diff --git a/api/tests/unit_tests/controllers/service_api/dataset/test_dataset_segment.py b/api/tests/unit_tests/controllers/service_api/dataset/test_dataset_segment.py index e9c3e6d376..fe8fc02548 100644 --- a/api/tests/unit_tests/controllers/service_api/dataset/test_dataset_segment.py +++ b/api/tests/unit_tests/controllers/service_api/dataset/test_dataset_segment.py @@ -18,6 +18,7 @@ import uuid from unittest.mock import Mock, patch import pytest +from flask import Flask from werkzeug.exceptions import NotFound from controllers.service_api.dataset.segment import ( @@ -782,7 +783,7 @@ class TestSegmentApiGet: mock_seg_svc, mock_marshal, mock_summary_svc, - app, + app: Flask, mock_tenant, mock_dataset, mock_segment, @@ -893,7 +894,7 @@ class TestSegmentApiPost: mock_seg_svc, mock_marshal, mock_summary_svc, - app, + app: Flask, mock_tenant, mock_dataset, mock_segment, @@ -946,7 +947,7 @@ class TestSegmentApiPost: mock_db, mock_account_fn, mock_doc_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -989,7 +990,7 @@ class TestSegmentApiPost: mock_db, mock_account_fn, mock_doc_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1041,7 +1042,7 @@ class TestDatasetSegmentApiDelete: mock_doc_svc, mock_dataset_svc, mock_seg_svc, - app, + app: Flask, mock_tenant, mock_dataset, mock_segment, @@ -1086,7 +1087,7 @@ class TestDatasetSegmentApiDelete: mock_account_fn, mock_doc_svc, mock_seg_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1128,7 +1129,7 @@ class TestDatasetSegmentApiDelete: mock_account_fn, mock_doc_svc, mock_dataset_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1162,7 +1163,7 @@ class TestDatasetSegmentApiDelete: mock_account_fn, mock_dataset_svc, mock_doc_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1232,7 +1233,7 @@ class TestDatasetSegmentApiUpdate: mock_seg_svc, mock_marshal, mock_summary_svc, - app, + app: Flask, mock_tenant, mock_dataset, mock_segment, @@ -1282,7 +1283,7 @@ class TestDatasetSegmentApiUpdate: mock_account_fn, mock_dataset_svc, mock_doc_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1322,7 +1323,7 @@ class TestDatasetSegmentApiUpdate: mock_dataset_svc, mock_doc_svc, mock_seg_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1374,7 +1375,7 @@ class TestDatasetSegmentApiGetSingle: mock_seg_svc, mock_marshal, mock_summary_svc, - app, + app: Flask, mock_tenant, mock_dataset, mock_segment, @@ -1421,7 +1422,7 @@ class TestDatasetSegmentApiGetSingle: mock_seg_svc, mock_marshal, mock_summary_svc, - app, + app: Flask, mock_tenant, mock_dataset, mock_segment, @@ -1460,7 +1461,7 @@ class TestDatasetSegmentApiGetSingle: self, mock_db, mock_account_fn, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1491,7 +1492,7 @@ class TestDatasetSegmentApiGetSingle: mock_account_fn, mock_dataset_svc, mock_doc_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1526,7 +1527,7 @@ class TestDatasetSegmentApiGetSingle: mock_dataset_svc, mock_doc_svc, mock_seg_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1570,7 +1571,7 @@ class TestChildChunkApiGet: mock_doc_svc, mock_seg_svc, mock_marshal, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1609,7 +1610,7 @@ class TestChildChunkApiGet: self, mock_db, mock_account_fn, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1638,7 +1639,7 @@ class TestChildChunkApiGet: mock_db, mock_account_fn, mock_doc_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1670,7 +1671,7 @@ class TestChildChunkApiGet: mock_account_fn, mock_doc_svc, mock_seg_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1729,7 +1730,7 @@ class TestChildChunkApiPost: mock_doc_svc, mock_seg_svc, mock_marshal, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1771,7 +1772,7 @@ class TestChildChunkApiPost: mock_feature_svc, mock_db, mock_account_fn, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1809,7 +1810,7 @@ class TestChildChunkApiPost: mock_account_fn, mock_doc_svc, mock_seg_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1863,7 +1864,7 @@ class TestDatasetChildChunkApiDelete: mock_account_fn, mock_doc_svc, mock_seg_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1913,7 +1914,7 @@ class TestDatasetChildChunkApiDelete: mock_account_fn, mock_doc_svc, mock_seg_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1954,7 +1955,7 @@ class TestDatasetChildChunkApiDelete: mock_account_fn, mock_doc_svc, mock_seg_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1994,7 +1995,7 @@ class TestDatasetChildChunkApiDelete: mock_account_fn, mock_doc_svc, mock_seg_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): diff --git a/api/tests/unit_tests/controllers/service_api/dataset/test_document.py b/api/tests/unit_tests/controllers/service_api/dataset/test_document.py index 1b391e67ec..230c51161f 100644 --- a/api/tests/unit_tests/controllers/service_api/dataset/test_document.py +++ b/api/tests/unit_tests/controllers/service_api/dataset/test_document.py @@ -23,6 +23,7 @@ from werkzeug.exceptions import Forbidden, NotFound from controllers.service_api.dataset.document import ( DeprecatedDocumentAddByTextApi, + DeprecatedDocumentUpdateByFileApi, DeprecatedDocumentUpdateByTextApi, DocumentAddByFileApi, DocumentAddByTextApi, @@ -32,7 +33,6 @@ from controllers.service_api.dataset.document import ( DocumentListQuery, DocumentTextCreatePayload, DocumentTextUpdate, - DocumentUpdateByFileApi, DocumentUpdateByTextApi, InvalidMetadataError, ) @@ -1095,8 +1095,8 @@ class TestArchivedDocumentImmutableError: assert error.code == 403 -class TestDocumentTextRouteDeprecation: - """Test that legacy underscore text routes stay marked deprecated.""" +class TestDocumentRouteDeprecation: + """Test that legacy document routes stay marked deprecated.""" def test_create_by_text_legacy_alias_is_deprecated(self): """Ensure only the legacy create-by-text alias is marked deprecated.""" @@ -1108,10 +1108,15 @@ class TestDocumentTextRouteDeprecation: assert DeprecatedDocumentUpdateByTextApi.post.__apidoc__["deprecated"] is True assert DocumentUpdateByTextApi.post.__apidoc__.get("deprecated") is not True + def test_update_by_file_legacy_aliases_are_deprecated(self): + """Ensure only the legacy file-update aliases are marked deprecated.""" + assert DeprecatedDocumentUpdateByFileApi.post.__apidoc__["deprecated"] is True + assert DocumentApi.patch.__apidoc__.get("deprecated") is not True + # ============================================================================= # Endpoint tests for DocumentUpdateByTextApi, DocumentAddByFileApi, -# DocumentUpdateByFileApi. +# and the canonical/deprecated document file update routes. # # These controllers use ``@cloud_edition_billing_resource_check`` (does NOT # preserve ``__wrapped__``) and ``@cloud_edition_billing_rate_limit_check`` @@ -1359,13 +1364,52 @@ class TestDocumentAddByFileApiPost: api.post(tenant_id=mock_tenant.id, dataset_id=mock_dataset.id) -class TestDocumentUpdateByFileApiPost: - """Test suite for DocumentUpdateByFileApi.post() endpoint. +class TestDocumentUpdateByFileApiPatch: + """Test suite for the canonical document file update endpoint. - ``post`` is wrapped by ``@cloud_edition_billing_resource_check`` and + ``patch`` is wrapped by ``@cloud_edition_billing_resource_check`` and ``@cloud_edition_billing_rate_limit_check``. """ + @pytest.mark.parametrize("route_name", ["update_by_file", "update-by-file"]) + @patch("controllers.service_api.dataset.document._update_document_by_file") + @patch("controllers.service_api.wraps.FeatureService") + @patch("controllers.service_api.wraps.validate_and_get_api_token") + def test_update_by_file_deprecated_aliases_delegate_to_shared_handler( + self, + mock_validate_token, + mock_feature_svc, + mock_update_document_by_file, + route_name, + app, + mock_tenant, + mock_dataset, + ): + """Test legacy POST aliases still dispatch while marked deprecated.""" + _setup_billing_mocks(mock_validate_token, mock_feature_svc, mock_tenant.id) + mock_update_document_by_file.return_value = ({"document": {"id": "doc-1"}, "batch": "batch-1"}, 200) + + doc_id = str(uuid.uuid4()) + with app.test_request_context( + f"/datasets/{mock_dataset.id}/documents/{doc_id}/{route_name}", + method="POST", + headers={"Authorization": "Bearer test_token"}, + ): + api = DeprecatedDocumentUpdateByFileApi() + response, status = api.post( + tenant_id=mock_tenant.id, + dataset_id=mock_dataset.id, + document_id=doc_id, + ) + + assert status == 200 + assert response["batch"] == "batch-1" + mock_update_document_by_file.assert_called_once_with( + tenant_id=mock_tenant.id, + dataset_id=mock_dataset.id, + document_id=doc_id, + ) + @patch("controllers.service_api.dataset.document.db") @patch("controllers.service_api.wraps.FeatureService") @patch("controllers.service_api.wraps.validate_and_get_api_token") @@ -1387,15 +1431,15 @@ class TestDocumentUpdateByFileApiPost: doc_id = str(uuid.uuid4()) data = {"file": (BytesIO(b"content"), "test.pdf", "application/pdf")} with app.test_request_context( - f"/datasets/{mock_dataset.id}/documents/{doc_id}/update_by_file", - method="POST", + f"/datasets/{mock_dataset.id}/documents/{doc_id}", + method="PATCH", content_type="multipart/form-data", data=data, headers={"Authorization": "Bearer test_token"}, ): - api = DocumentUpdateByFileApi() + api = DocumentApi() with pytest.raises(ValueError, match="Dataset does not exist"): - api.post( + api.patch( tenant_id=mock_tenant.id, dataset_id=mock_dataset.id, document_id=doc_id, @@ -1423,15 +1467,15 @@ class TestDocumentUpdateByFileApiPost: doc_id = str(uuid.uuid4()) data = {"file": (BytesIO(b"content"), "test.pdf", "application/pdf")} with app.test_request_context( - f"/datasets/{mock_dataset.id}/documents/{doc_id}/update_by_file", - method="POST", + f"/datasets/{mock_dataset.id}/documents/{doc_id}", + method="PATCH", content_type="multipart/form-data", data=data, headers={"Authorization": "Bearer test_token"}, ): - api = DocumentUpdateByFileApi() + api = DocumentApi() with pytest.raises(ValueError, match="External datasets"): - api.post( + api.patch( tenant_id=mock_tenant.id, dataset_id=mock_dataset.id, document_id=doc_id, @@ -1482,14 +1526,14 @@ class TestDocumentUpdateByFileApiPost: doc_id = str(uuid.uuid4()) data = {"file": (BytesIO(b"file content"), "test.pdf", "application/pdf")} with app.test_request_context( - f"/datasets/{mock_dataset.id}/documents/{doc_id}/update_by_file", - method="POST", + f"/datasets/{mock_dataset.id}/documents/{doc_id}", + method="PATCH", content_type="multipart/form-data", data=data, headers={"Authorization": "Bearer test_token"}, ): - api = DocumentUpdateByFileApi() - response, status = api.post( + api = DocumentApi() + response, status = api.patch( tenant_id=mock_tenant.id, dataset_id=mock_dataset.id, document_id=doc_id, diff --git a/api/tests/unit_tests/controllers/service_api/dataset/test_hit_testing.py b/api/tests/unit_tests/controllers/service_api/dataset/test_hit_testing.py index 9be8e56f56..a26cdf6563 100644 --- a/api/tests/unit_tests/controllers/service_api/dataset/test_hit_testing.py +++ b/api/tests/unit_tests/controllers/service_api/dataset/test_hit_testing.py @@ -171,6 +171,62 @@ class TestHitTestingApiPost: assert passed_retrieval_model["search_method"] == "semantic_search" assert passed_retrieval_model["top_k"] == 10 + @patch("controllers.service_api.dataset.hit_testing.service_api_ns") + @patch("controllers.console.datasets.hit_testing_base.marshal") + @patch("controllers.console.datasets.hit_testing_base.HitTestingService") + @patch("controllers.console.datasets.hit_testing_base.DatasetService") + @patch("controllers.console.datasets.hit_testing_base.current_user", new_callable=lambda: Mock(spec=Account)) + def test_post_preserves_retrieval_model_metadata_filtering_conditions( + self, + mock_current_user, + mock_dataset_svc, + mock_hit_svc, + mock_marshal, + mock_ns, + app, + ): + """Service API retrieval payload should not drop metadata filters.""" + dataset_id = str(uuid.uuid4()) + tenant_id = str(uuid.uuid4()) + + mock_dataset = Mock() + mock_dataset.id = dataset_id + + mock_dataset_svc.get_dataset.return_value = mock_dataset + mock_dataset_svc.check_dataset_permission.return_value = None + mock_hit_svc.retrieve.return_value = {"query": "filtered query", "records": []} + mock_hit_svc.hit_testing_args_check.return_value = None + mock_marshal.return_value = [] + + metadata_filtering_conditions = { + "logical_operator": "and", + "conditions": [ + { + "name": "category", + "comparison_operator": "is", + "value": "finance", + } + ], + } + mock_ns.payload = { + "query": "filtered query", + "retrieval_model": { + "search_method": "semantic_search", + "reranking_enable": False, + "score_threshold_enabled": False, + "top_k": 4, + "metadata_filtering_conditions": metadata_filtering_conditions, + }, + } + + with app.test_request_context(): + api = HitTestingApi() + HitTestingApi.post.__wrapped__(api, tenant_id, dataset_id) + + passed_retrieval_model = mock_hit_svc.retrieve.call_args.kwargs.get("retrieval_model") + assert passed_retrieval_model is not None + assert passed_retrieval_model["metadata_filtering_conditions"] == metadata_filtering_conditions + @patch("controllers.service_api.dataset.hit_testing.service_api_ns") @patch("controllers.console.datasets.hit_testing_base.marshal") @patch("controllers.console.datasets.hit_testing_base.HitTestingService") diff --git a/api/tests/unit_tests/controllers/service_api/dataset/test_metadata.py b/api/tests/unit_tests/controllers/service_api/dataset/test_metadata.py index b93a1cf14b..b7e24f9201 100644 --- a/api/tests/unit_tests/controllers/service_api/dataset/test_metadata.py +++ b/api/tests/unit_tests/controllers/service_api/dataset/test_metadata.py @@ -19,6 +19,7 @@ import uuid from unittest.mock import Mock, patch import pytest +from flask import Flask from werkzeug.exceptions import NotFound from controllers.service_api.dataset.metadata import ( @@ -76,7 +77,7 @@ class TestDatasetMetadataCreatePost: mock_dataset_svc, mock_meta_svc, mock_marshal, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -106,7 +107,7 @@ class TestDatasetMetadataCreatePost: def test_create_metadata_dataset_not_found( self, mock_dataset_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -136,7 +137,7 @@ class TestDatasetMetadataCreateGet: self, mock_dataset_svc, mock_meta_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -160,7 +161,7 @@ class TestDatasetMetadataCreateGet: def test_get_metadata_dataset_not_found( self, mock_dataset_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -201,7 +202,7 @@ class TestDatasetMetadataServiceApiPatch: mock_dataset_svc, mock_meta_svc, mock_marshal, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -232,7 +233,7 @@ class TestDatasetMetadataServiceApiPatch: def test_update_metadata_dataset_not_found( self, mock_dataset_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -273,7 +274,7 @@ class TestDatasetMetadataServiceApiDelete: mock_current_user, mock_dataset_svc, mock_meta_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -302,7 +303,7 @@ class TestDatasetMetadataServiceApiDelete: def test_delete_metadata_dataset_not_found( self, mock_dataset_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -336,7 +337,7 @@ class TestDatasetMetadataBuiltInFieldGet: def test_get_built_in_fields_success( self, mock_meta_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -382,7 +383,7 @@ class TestDatasetMetadataBuiltInFieldAction: mock_current_user, mock_dataset_svc, mock_meta_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -414,7 +415,7 @@ class TestDatasetMetadataBuiltInFieldAction: mock_current_user, mock_dataset_svc, mock_meta_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -441,7 +442,7 @@ class TestDatasetMetadataBuiltInFieldAction: def test_action_dataset_not_found( self, mock_dataset_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -485,7 +486,7 @@ class TestDocumentMetadataEditPost: mock_current_user, mock_dataset_svc, mock_meta_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -513,7 +514,7 @@ class TestDocumentMetadataEditPost: def test_update_documents_metadata_dataset_not_found( self, mock_dataset_svc, - app, + app: Flask, mock_tenant, mock_dataset, ): diff --git a/api/tests/unit_tests/controllers/service_api/test_index.py b/api/tests/unit_tests/controllers/service_api/test_index.py index c560a3c698..8441118181 100644 --- a/api/tests/unit_tests/controllers/service_api/test_index.py +++ b/api/tests/unit_tests/controllers/service_api/test_index.py @@ -5,6 +5,7 @@ Unit tests for Service API Index endpoint from unittest.mock import MagicMock, patch import pytest +from flask import Flask from controllers.service_api.index import IndexApi @@ -13,7 +14,7 @@ class TestIndexApi: """Test suite for IndexApi resource.""" @patch("controllers.service_api.index.dify_config", autospec=True) - def test_get_returns_api_info(self, mock_config, app): + def test_get_returns_api_info(self, mock_config, app: Flask): """Test that GET returns API metadata with correct structure.""" # Arrange mock_config.project.version = "1.0.0-test" @@ -32,7 +33,7 @@ class TestIndexApi: assert response["api_version"] == "v1" assert response["server_version"] == "1.0.0-test" - def test_get_response_has_required_fields(self, app): + def test_get_response_has_required_fields(self, app: Flask): """Test that response contains all required fields.""" # Arrange mock_config = MagicMock() diff --git a/api/tests/unit_tests/controllers/service_api/test_wraps.py b/api/tests/unit_tests/controllers/service_api/test_wraps.py index 6dfbdcf98e..30d7b92913 100644 --- a/api/tests/unit_tests/controllers/service_api/test_wraps.py +++ b/api/tests/unit_tests/controllers/service_api/test_wraps.py @@ -39,7 +39,7 @@ class TestValidateAndGetApiToken: app.config["TESTING"] = True return app - def test_missing_authorization_header(self, app): + def test_missing_authorization_header(self, app: Flask): """Test that Unauthorized is raised when Authorization header is missing.""" # Arrange with app.test_request_context("/", method="GET"): @@ -50,7 +50,7 @@ class TestValidateAndGetApiToken: validate_and_get_api_token("app") assert "Authorization header must be provided" in str(exc_info.value) - def test_invalid_auth_scheme(self, app): + def test_invalid_auth_scheme(self, app: Flask): """Test that Unauthorized is raised when auth scheme is not Bearer.""" # Arrange with app.test_request_context("/", method="GET", headers={"Authorization": "Basic token123"}): @@ -62,7 +62,7 @@ class TestValidateAndGetApiToken: @patch("controllers.service_api.wraps.record_token_usage") @patch("controllers.service_api.wraps.ApiTokenCache") @patch("controllers.service_api.wraps.fetch_token_with_single_flight") - def test_valid_token_returns_api_token(self, mock_fetch_token, mock_cache_cls, mock_record_usage, app): + def test_valid_token_returns_api_token(self, mock_fetch_token, mock_cache_cls, mock_record_usage, app: Flask): """Test that valid token returns the ApiToken object.""" # Arrange mock_api_token = Mock(spec=ApiToken) @@ -84,7 +84,7 @@ class TestValidateAndGetApiToken: @patch("controllers.service_api.wraps.record_token_usage") @patch("controllers.service_api.wraps.ApiTokenCache") @patch("controllers.service_api.wraps.fetch_token_with_single_flight") - def test_invalid_token_raises_unauthorized(self, mock_fetch_token, mock_cache_cls, mock_record_usage, app): + def test_invalid_token_raises_unauthorized(self, mock_fetch_token, mock_cache_cls, mock_record_usage, app: Flask): """Test that invalid token raises Unauthorized.""" # Arrange from werkzeug.exceptions import Unauthorized @@ -161,7 +161,7 @@ class TestValidateAppToken: @patch("controllers.service_api.wraps.db") @patch("controllers.service_api.wraps.validate_and_get_api_token") - def test_app_not_found_raises_forbidden(self, mock_validate_token, mock_db, app): + def test_app_not_found_raises_forbidden(self, mock_validate_token, mock_db, app: Flask): """Test that Forbidden is raised when app no longer exists.""" # Arrange mock_api_token = Mock() @@ -182,7 +182,7 @@ class TestValidateAppToken: @patch("controllers.service_api.wraps.db") @patch("controllers.service_api.wraps.validate_and_get_api_token") - def test_app_status_abnormal_raises_forbidden(self, mock_validate_token, mock_db, app): + def test_app_status_abnormal_raises_forbidden(self, mock_validate_token, mock_db, app: Flask): """Test that Forbidden is raised when app status is abnormal.""" # Arrange mock_api_token = Mock() @@ -205,7 +205,7 @@ class TestValidateAppToken: @patch("controllers.service_api.wraps.db") @patch("controllers.service_api.wraps.validate_and_get_api_token") - def test_app_api_disabled_raises_forbidden(self, mock_validate_token, mock_db, app): + def test_app_api_disabled_raises_forbidden(self, mock_validate_token, mock_db, app: Flask): """Test that Forbidden is raised when app API is disabled.""" # Arrange mock_api_token = Mock() @@ -240,7 +240,7 @@ class TestCloudEditionBillingResourceCheck: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.FeatureService.get_features") - def test_allows_when_under_limit(self, mock_get_features, mock_validate_token, app): + def test_allows_when_under_limit(self, mock_get_features, mock_validate_token, app: Flask): """Test that request is allowed when under resource limit.""" # Arrange mock_validate_token.return_value = Mock(tenant_id="tenant123") @@ -264,7 +264,7 @@ class TestCloudEditionBillingResourceCheck: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.FeatureService.get_features") - def test_rejects_when_at_limit(self, mock_get_features, mock_validate_token, app): + def test_rejects_when_at_limit(self, mock_get_features, mock_validate_token, app: Flask): """Test that Forbidden is raised when at resource limit.""" # Arrange mock_validate_token.return_value = Mock(tenant_id="tenant123") @@ -287,7 +287,7 @@ class TestCloudEditionBillingResourceCheck: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.FeatureService.get_features") - def test_allows_when_billing_disabled(self, mock_get_features, mock_validate_token, app): + def test_allows_when_billing_disabled(self, mock_get_features, mock_validate_token, app: Flask): """Test that request is allowed when billing is disabled.""" # Arrange mock_validate_token.return_value = Mock(tenant_id="tenant123") @@ -320,7 +320,7 @@ class TestCloudEditionBillingKnowledgeLimitCheck: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.FeatureService.get_features") - def test_rejects_add_segment_in_sandbox(self, mock_get_features, mock_validate_token, app): + def test_rejects_add_segment_in_sandbox(self, mock_get_features, mock_validate_token, app: Flask): """Test that add_segment is rejected in SANDBOX plan.""" # Arrange mock_validate_token.return_value = Mock(tenant_id="tenant123") @@ -342,7 +342,7 @@ class TestCloudEditionBillingKnowledgeLimitCheck: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.FeatureService.get_features") - def test_allows_other_operations_in_sandbox(self, mock_get_features, mock_validate_token, app): + def test_allows_other_operations_in_sandbox(self, mock_get_features, mock_validate_token, app: Flask): """Test that non-add_segment operations are allowed in SANDBOX.""" # Arrange mock_validate_token.return_value = Mock(tenant_id="tenant123") @@ -376,7 +376,7 @@ class TestCloudEditionBillingRateLimitCheck: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.FeatureService.get_knowledge_rate_limit") - def test_allows_within_rate_limit(self, mock_get_rate_limit, mock_validate_token, app): + def test_allows_within_rate_limit(self, mock_get_rate_limit, mock_validate_token, app: Flask): """Test that request is allowed when within rate limit.""" # Arrange mock_validate_token.return_value = Mock(tenant_id="tenant123") @@ -406,7 +406,7 @@ class TestCloudEditionBillingRateLimitCheck: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.FeatureService.get_knowledge_rate_limit") @patch("controllers.service_api.wraps.db") - def test_rejects_over_rate_limit(self, mock_db, mock_get_rate_limit, mock_validate_token, app): + def test_rejects_over_rate_limit(self, mock_db, mock_get_rate_limit, mock_validate_token, app: Flask): """Test that Forbidden is raised when over rate limit.""" # Arrange mock_validate_token.return_value = Mock(tenant_id="tenant123") @@ -445,7 +445,7 @@ class TestValidateDatasetToken: @patch("controllers.service_api.wraps.db") @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.wraps.current_app") - def test_valid_dataset_token(self, mock_current_app, mock_validate_token, mock_db, mock_user_logged_in, app): + def test_valid_dataset_token(self, mock_current_app, mock_validate_token, mock_db, mock_user_logged_in, app: Flask): """Test that valid dataset token allows access.""" # Arrange # Use standard Mock for login_manager @@ -487,7 +487,7 @@ class TestValidateDatasetToken: @patch("controllers.service_api.wraps.db") @patch("controllers.service_api.wraps.validate_and_get_api_token") - def test_dataset_not_found_raises_not_found(self, mock_validate_token, mock_db, app): + def test_dataset_not_found_raises_not_found(self, mock_validate_token, mock_db, app: Flask): """Test that NotFound is raised when dataset doesn't exist.""" # Arrange mock_api_token = Mock() diff --git a/api/tests/unit_tests/core/external_data_tool/test_external_data_fetch.py b/api/tests/unit_tests/core/external_data_tool/test_external_data_fetch.py index 86b461cf04..c1c1291281 100644 --- a/api/tests/unit_tests/core/external_data_tool/test_external_data_fetch.py +++ b/api/tests/unit_tests/core/external_data_tool/test_external_data_fetch.py @@ -13,7 +13,7 @@ class TestExternalDataFetch: app = Flask(__name__) return app - def test_fetch_success(self, app): + def test_fetch_success(self, app: Flask): with app.app_context(): fetcher = ExternalDataFetch() @@ -79,7 +79,7 @@ class TestExternalDataFetch: assert result_inputs == inputs assert result_inputs is not inputs # Should be a copy - def test_fetch_with_none_variable(self, app): + def test_fetch_with_none_variable(self, app: Flask): with app.app_context(): fetcher = ExternalDataFetch() tool = ExternalDataVariableEntity(variable="var1", type="type1", config={}) @@ -95,7 +95,7 @@ class TestExternalDataFetch: assert "var1" not in result_inputs assert result_inputs == {"in": "val"} - def test_query_external_data_tool(self, app): + def test_query_external_data_tool(self, app: Flask): fetcher = ExternalDataFetch() tool = ExternalDataVariableEntity(variable="var1", type="type1", config={"k": "v"}) diff --git a/api/tests/unit_tests/core/plugin/utils/test_http_parser.py b/api/tests/unit_tests/core/plugin/utils/test_http_parser.py index 71144695bc..e0419d3266 100644 --- a/api/tests/unit_tests/core/plugin/utils/test_http_parser.py +++ b/api/tests/unit_tests/core/plugin/utils/test_http_parser.py @@ -323,6 +323,50 @@ class TestDeserializeResponse: with pytest.raises(ValueError, match="Invalid status line"): deserialize_response(raw_data) + def test_deserialize_response_preserves_duplicate_set_cookie_headers(self): + # Regression test for https://github.com/langgenius/dify/issues/35722 + # Multiple Set-Cookie headers must be preserved per RFC 9110, not collapsed + # into a single value by dict-style assignment. + raw_data = ( + b"HTTP/1.1 200 OK\r\n" + b"Content-Type: text/plain\r\n" + b"Set-Cookie: session=abc; Path=/; HttpOnly\r\n" + b"Set-Cookie: tracking=xyz; Path=/; Secure\r\n" + b"\r\n" + b"ok" + ) + + response = deserialize_response(raw_data) + + cookies = response.headers.getlist("Set-Cookie") + assert cookies == [ + "session=abc; Path=/; HttpOnly", + "tracking=xyz; Path=/; Secure", + ] + # Single-valued headers should still be readable normally. + assert response.headers.get("Content-Type") == "text/plain" + + def test_deserialize_response_preserves_duplicate_generic_headers(self): + # Any header name (not just Set-Cookie) may legitimately repeat; verify the + # parser preserves all values rather than overwriting earlier ones. + raw_data = b"HTTP/1.1 200 OK\r\nX-Custom: first\r\nX-Custom: second\r\n\r\n" + + response = deserialize_response(raw_data) + + assert response.headers.getlist("X-Custom") == ["first", "second"] + + def test_deserialize_response_does_not_inject_default_content_type(self): + # Flask's Response constructor adds a default Content-Type header. When the + # raw response has no Content-Type, the parsed response should not silently + # gain one from the framework default. + raw_data = b"HTTP/1.1 204 No Content\r\nX-Trace-Id: abc\r\n\r\n" + + response = deserialize_response(raw_data) + + header_names = [name for name, _ in response.headers.items()] + assert "Content-Type" not in header_names + assert response.headers.get("X-Trace-Id") == "abc" + def test_roundtrip_response(self): # Test that serialize -> deserialize produces equivalent response original_response = Response( diff --git a/api/tests/unit_tests/core/rag/datasource/vdb/test_vector_factory.py b/api/tests/unit_tests/core/rag/datasource/vdb/test_vector_factory.py index f84ce2771f..7b6ee97f1c 100644 --- a/api/tests/unit_tests/core/rag/datasource/vdb/test_vector_factory.py +++ b/api/tests/unit_tests/core/rag/datasource/vdb/test_vector_factory.py @@ -316,6 +316,33 @@ def test_create_batches_texts_and_skips_empty_input(vector_factory_module): vector._vector_processor.create.assert_not_called() +def test_create_skips_empty_text_documents_before_embedding(vector_factory_module): + vector = vector_factory_module.Vector.__new__(vector_factory_module.Vector) + vector._embeddings = MagicMock() + vector._embeddings.embed_documents.return_value = [[0.1], [0.2]] + vector._vector_processor = MagicMock() + + docs = [ + Document(page_content="foo", metadata={"doc_id": "id-1"}), + Document(page_content="", metadata={"doc_id": "id-empty"}), + Document(page_content=" \n", metadata={"doc_id": "id-blank"}), + Document(page_content="bar", metadata={"doc_id": "id-2"}), + ] + + vector.create(texts=docs, request_id="r-1") + + vector._embeddings.embed_documents.assert_called_once_with(["foo", "bar"]) + vector._vector_processor.create.assert_called_once_with( + texts=[docs[0], docs[3]], embeddings=[[0.1], [0.2]], request_id="r-1" + ) + + vector._embeddings.embed_documents.reset_mock() + vector._vector_processor.create.reset_mock() + vector.create(texts=[docs[1], docs[2]]) + vector._embeddings.embed_documents.assert_not_called() + vector._vector_processor.create.assert_not_called() + + def test_create_multimodal_filters_missing_uploads(vector_factory_module, monkeypatch): class _Field: def in_(self, value): @@ -396,6 +423,48 @@ def test_add_texts_with_optional_duplicate_check(vector_factory_module): vector._vector_processor.create.assert_called_once() +def test_add_texts_skips_empty_text_documents(vector_factory_module): + vector = vector_factory_module.Vector.__new__(vector_factory_module.Vector) + vector._embeddings = MagicMock() + vector._embeddings.embed_documents.return_value = [[0.1]] + vector._vector_processor = MagicMock() + + docs = [ + Document(page_content="keep", metadata={"doc_id": "id-1"}), + Document(page_content="", metadata={"doc_id": "id-empty"}), + ] + + vector.add_texts(docs, source="api") + + vector._embeddings.embed_documents.assert_called_once_with(["keep"]) + vector._vector_processor.create.assert_called_once_with(texts=[docs[0]], embeddings=[[0.1]], source="api") + + vector._embeddings.embed_documents.reset_mock() + vector._vector_processor.create.reset_mock() + vector.add_texts([docs[1]]) + vector._embeddings.embed_documents.assert_not_called() + vector._vector_processor.create.assert_not_called() + + +def test_add_texts_filters_empty_documents_before_duplicate_check(vector_factory_module): + vector = vector_factory_module.Vector.__new__(vector_factory_module.Vector) + vector._embeddings = MagicMock() + vector._embeddings.embed_documents.return_value = [[0.1]] + vector._vector_processor = MagicMock() + vector._filter_duplicate_texts = MagicMock(return_value=[]) + + docs = [ + Document(page_content="keep", metadata={"doc_id": "id-1"}), + Document(page_content=" ", metadata={"doc_id": "id-empty"}), + ] + + vector.add_texts(docs, duplicate_check=True) + + vector._filter_duplicate_texts.assert_called_once_with([docs[0]]) + vector._embeddings.embed_documents.assert_not_called() + vector._vector_processor.create.assert_not_called() + + def test_vector_delegation_methods(vector_factory_module): vector = vector_factory_module.Vector.__new__(vector_factory_module.Vector) vector._embeddings = MagicMock() diff --git a/api/tests/unit_tests/core/rag/extractor/test_word_extractor.py b/api/tests/unit_tests/core/rag/extractor/test_word_extractor.py index 0220fb6d4a..b9f2449cfb 100644 --- a/api/tests/unit_tests/core/rag/extractor/test_word_extractor.py +++ b/api/tests/unit_tests/core/rag/extractor/test_word_extractor.py @@ -1,14 +1,12 @@ """Primarily used for testing merged cell scenarios""" -import gc import io import os import tempfile -import warnings from collections import UserDict from pathlib import Path from types import SimpleNamespace -from unittest.mock import AsyncMock, MagicMock +from unittest.mock import MagicMock import pytest from docx import Document @@ -377,23 +375,21 @@ def test_close_is_idempotent(): extractor.temp_file.close.assert_called_once() -def test_close_handles_async_close_mock(): +async def _async_close() -> None: + return None + + +def test_close_closes_awaitable_close_result(): extractor = object.__new__(WordExtractor) extractor._closed = False extractor.temp_file = MagicMock() - extractor.temp_file.close = AsyncMock() + close_result = _async_close() + extractor.temp_file.close = MagicMock(return_value=close_result) - with warnings.catch_warnings(record=True) as caught: - warnings.simplefilter("always") - extractor.close() - gc.collect() + extractor.close() + assert close_result.cr_frame is None extractor.temp_file.close.assert_called_once() - assert not [ - warning - for warning in caught - if issubclass(warning.category, RuntimeWarning) and "AsyncMockMixin._execute_mock_call" in str(warning.message) - ] def test_extract_images_handles_invalid_external_cases(monkeypatch): diff --git a/api/tests/unit_tests/core/rag/retrieval/test_dataset_retrieval.py b/api/tests/unit_tests/core/rag/retrieval/test_dataset_retrieval.py index fd607210f1..b556ddf528 100644 --- a/api/tests/unit_tests/core/rag/retrieval/test_dataset_retrieval.py +++ b/api/tests/unit_tests/core/rag/retrieval/test_dataset_retrieval.py @@ -1106,11 +1106,11 @@ class TestRetrievalService: def test_deduplicate_documents_non_dify_provider(self): """ - Test deduplication with non-dify provider documents. + Test deduplication with non-dify provider documents that have no doc_id. Verifies: - - External provider documents use content-based deduplication - - Different providers are handled correctly + - External provider documents without doc_id use content-based deduplication + - Identical content from the same provider is collapsed to one result """ # Arrange doc1 = Document( @@ -1131,7 +1131,96 @@ class TestRetrievalService: # Assert # External documents without doc_id should use content-based dedup - assert len(result) >= 1 + assert len(result) == 1 + + def test_deduplicate_documents_non_dify_provider_with_doc_id_different_sources(self): + """ + Regression test for issue #35707. + + Two chunks from different source documents share identical text content but carry + different doc_ids. Before the fix, non-dify providers were forced into content-based + deduplication and the second chunk was silently dropped. After the fix, doc_id is used + as the dedup key for any provider that exposes it, so both chunks must be retained. + + Verifies: + - Non-dify provider documents with different doc_ids are NOT deduplicated even when + their page_content is identical. + """ + # Arrange — same content, different doc_ids, non-dify provider (e.g. Weaviate / Qdrant) + doc_a = Document( + page_content="Shared identical content", + metadata={"doc_id": "doc-from-file-a", "score": 0.85}, + provider="weaviate", + ) + doc_b = Document( + page_content="Shared identical content", + metadata={"doc_id": "doc-from-file-b", "score": 0.82}, + provider="weaviate", + ) + + # Act + result = RetrievalService._deduplicate_documents([doc_a, doc_b]) + + # Assert — both documents must be kept; losing either silently drops a source citation + assert len(result) == 2 + doc_ids = {doc.metadata["doc_id"] for doc in result} + assert doc_ids == {"doc-from-file-a", "doc-from-file-b"} + + def test_deduplicate_documents_non_dify_provider_with_same_doc_id(self): + """ + Test that non-dify provider documents sharing the same doc_id are deduplicated by + doc_id key (not by content), and the higher-scored duplicate is retained. + + Verifies: + - doc_id-based deduplication now applies to any provider, not only "dify" + - The document with the highest score wins when doc_ids collide + """ + # Arrange + doc_low = Document( + page_content="Content A", + metadata={"doc_id": "chunk-1", "score": 0.5}, + provider="qdrant", + ) + doc_high = Document( + page_content="Content A", + metadata={"doc_id": "chunk-1", "score": 0.9}, + provider="qdrant", + ) + + # Act + result = RetrievalService._deduplicate_documents([doc_low, doc_high]) + + # Assert + assert len(result) == 1 + assert result[0].metadata["score"] == 0.9 + + def test_deduplicate_documents_dify_provider_without_doc_id_falls_back_to_content(self): + """ + Test that a dify provider document without doc_id still falls back to content-based + deduplication (no regression from original behaviour). + + Verifies: + - Absence of doc_id triggers content-based dedup regardless of provider + - First occurrence is kept when content is identical + """ + # Arrange — dify docs with no doc_id, same content + doc1 = Document( + page_content="Same content", + metadata={"score": 0.8}, + provider="dify", + ) + doc2 = Document( + page_content="Same content", + metadata={"score": 0.9}, + provider="dify", + ) + + # Act + result = RetrievalService._deduplicate_documents([doc1, doc2]) + + # Assert — collapsed to one; first-seen wins (no score comparison in content branch) + assert len(result) == 1 + assert result[0].metadata["score"] == 0.8 # ==================== Metadata Filtering Tests ==================== diff --git a/api/tests/unit_tests/core/test_provider_manager.py b/api/tests/unit_tests/core/test_provider_manager.py index a5a542c94f..02f12fb3b4 100644 --- a/api/tests/unit_tests/core/test_provider_manager.py +++ b/api/tests/unit_tests/core/test_provider_manager.py @@ -570,8 +570,7 @@ def test_get_all_providers_normalizes_provider_names_with_model_provider_id() -> session.scalars.return_value = [openai_provider, gemini_provider] with ( - patch("core.provider_manager.db", SimpleNamespace(engine=object())), - patch("core.provider_manager.Session", return_value=_build_session_context(session)), + patch("core.provider_manager.session_factory.create_session", return_value=_build_session_context(session)), ): result = ProviderManager._get_all_providers("tenant-id") @@ -595,8 +594,7 @@ def test_provider_grouping_helpers_group_records_by_provider_name(method_name: s session.scalars.return_value = [openai_primary, openai_secondary, anthropic_record] with ( - patch("core.provider_manager.db", SimpleNamespace(engine=object())), - patch("core.provider_manager.Session", return_value=_build_session_context(session)), + patch("core.provider_manager.session_factory.create_session", return_value=_build_session_context(session)), ): result = getattr(ProviderManager, method_name)("tenant-id") @@ -611,8 +609,7 @@ def test_get_all_preferred_model_providers_returns_mapping_by_provider_name() -> session.scalars.return_value = [openai_preference, anthropic_preference] with ( - patch("core.provider_manager.db", SimpleNamespace(engine=object())), - patch("core.provider_manager.Session", return_value=_build_session_context(session)), + patch("core.provider_manager.session_factory.create_session", return_value=_build_session_context(session)), ): result = ProviderManager._get_all_preferred_model_providers("tenant-id") @@ -626,13 +623,13 @@ def test_get_all_provider_load_balancing_configs_returns_empty_when_cached_flag_ with ( patch("core.provider_manager.redis_client.get", return_value=b"False"), patch("core.provider_manager.FeatureService.get_features") as mock_get_features, - patch("core.provider_manager.Session") as mock_session_cls, + patch("core.provider_manager.session_factory.create_session") as mock_create_session, ): result = ProviderManager._get_all_provider_load_balancing_configs("tenant-id") assert result == {} mock_get_features.assert_not_called() - mock_session_cls.assert_not_called() + mock_create_session.assert_not_called() def test_get_all_provider_load_balancing_configs_populates_cache_and_groups_configs() -> None: @@ -642,14 +639,13 @@ def test_get_all_provider_load_balancing_configs_populates_cache_and_groups_conf session.scalars.return_value = [openai_config, anthropic_config] with ( - patch("core.provider_manager.db", SimpleNamespace(engine=object())), patch("core.provider_manager.redis_client.get", return_value=None), patch("core.provider_manager.redis_client.setex") as mock_setex, patch( "core.provider_manager.FeatureService.get_features", return_value=SimpleNamespace(model_load_balancing_enabled=True), ), - patch("core.provider_manager.Session", return_value=_build_session_context(session)), + patch("core.provider_manager.session_factory.create_session", return_value=_build_session_context(session)), ): result = ProviderManager._get_all_provider_load_balancing_configs("tenant-id") diff --git a/api/tests/unit_tests/core/tools/test_tool_manager.py b/api/tests/unit_tests/core/tools/test_tool_manager.py index 9ebaa0417b..c9b3dfb186 100644 --- a/api/tests/unit_tests/core/tools/test_tool_manager.py +++ b/api/tests/unit_tests/core/tools/test_tool_manager.py @@ -925,3 +925,78 @@ def test_convert_tool_parameters_type_constant_branch(): ) assert constant == {"text": "fixed"} + + +def test_convert_tool_parameters_type_model_selector_from_legacy_top_level_config(): + model_param = ToolParameter.get_simple_instance( + name="vision_llm_model", + llm_description="vision model", + typ=ToolParameter.ToolParameterType.MODEL_SELECTOR, + required=True, + ) + model_param.form = ToolParameter.ToolParameterForm.FORM + variable_pool = Mock() + + runtime_parameters = ToolManager._convert_tool_parameters_type( + parameters=[model_param], + variable_pool=variable_pool, + tool_configurations={ + "vision_llm_model": { + "type": "constant", + "value": "", + "provider": "langgenius/tongyi/tongyi", + "model": "qwen3-vl-plus", + "model_type": "llm", + "mode": "chat", + } + }, + typ="workflow", + ) + + assert runtime_parameters == { + "vision_llm_model": { + "provider": "langgenius/tongyi/tongyi", + "model": "qwen3-vl-plus", + "model_type": "llm", + "mode": "chat", + } + } + + +def test_convert_tool_parameters_type_model_selector_from_constant_value_config(): + model_param = ToolParameter.get_simple_instance( + name="tts_model", + llm_description="tts model", + typ=ToolParameter.ToolParameterType.MODEL_SELECTOR, + required=True, + ) + model_param.form = ToolParameter.ToolParameterForm.FORM + variable_pool = Mock() + + runtime_parameters = ToolManager._convert_tool_parameters_type( + parameters=[model_param], + variable_pool=variable_pool, + tool_configurations={ + "tts_model": { + "type": "constant", + "value": { + "provider": "langgenius/tongyi/tongyi", + "model": "qwen3-tts-flash", + "model_type": "tts", + "language": "Chinese", + "voice": "Cherry", + }, + } + }, + typ="workflow", + ) + + assert runtime_parameters == { + "tts_model": { + "provider": "langgenius/tongyi/tongyi", + "model": "qwen3-tts-flash", + "model_type": "tts", + "language": "Chinese", + "voice": "Cherry", + } + } diff --git a/api/tests/unit_tests/core/tools/utils/test_parser.py b/api/tests/unit_tests/core/tools/utils/test_parser.py index 032b1377a4..99a90f3b67 100644 --- a/api/tests/unit_tests/core/tools/utils/test_parser.py +++ b/api/tests/unit_tests/core/tools/utils/test_parser.py @@ -17,7 +17,7 @@ def app(): return app -def test_parse_openapi_to_tool_bundle_operation_id(app): +def test_parse_openapi_to_tool_bundle_operation_id(app: Flask): openapi = { "openapi": "3.0.0", "info": {"title": "Simple API", "version": "1.0.0"}, @@ -63,7 +63,7 @@ def test_parse_openapi_to_tool_bundle_operation_id(app): assert tool_bundles[2].operation_id == "createResource" -def test_parse_openapi_to_tool_bundle_properties_all_of(app): +def test_parse_openapi_to_tool_bundle_properties_all_of(app: Flask): openapi = { "openapi": "3.0.0", "info": {"title": "Simple API", "version": "1.0.0"}, @@ -118,7 +118,7 @@ def test_parse_openapi_to_tool_bundle_properties_all_of(app): # assert set(tool_bundles[0].parameters[0].options) == {"option1", "option2", "option3"} -def test_parse_openapi_to_tool_bundle_default_value_type_casting(app): +def test_parse_openapi_to_tool_bundle_default_value_type_casting(app: Flask): """ Test that default values are properly cast to match parameter types. This addresses the issue where array default values like [] cause validation errors diff --git a/api/tests/unit_tests/core/workflow/graph_engine/test_tool_in_chatflow.py b/api/tests/unit_tests/core/workflow/graph_engine/test_tool_in_chatflow.py index 12aec6edf2..ba1e74f3e0 100644 --- a/api/tests/unit_tests/core/workflow/graph_engine/test_tool_in_chatflow.py +++ b/api/tests/unit_tests/core/workflow/graph_engine/test_tool_in_chatflow.py @@ -5,6 +5,7 @@ from graphon.graph_events import ( NodeRunStreamChunkEvent, ) +from .test_mock_config import MockConfigBuilder from .test_table_runner import TableTestRunner @@ -44,3 +45,51 @@ def test_tool_in_chatflow(): assert stream_chunk_events[0].chunk == "hello, dify!", ( f"Expected chunk to be 'hello, dify!', but got {stream_chunk_events[0].chunk}" ) + + +def test_answer_can_render_llm_structured_output_in_chatflow(): + runner = TableTestRunner() + + fixture_data = runner.workflow_runner.load_fixture("basic_chatflow") + nodes = fixture_data["workflow"]["graph"]["nodes"] + answer_node = next(node for node in nodes if node["id"] == "answer") + answer_node["data"]["answer"] = "{{#llm.structured_output#}}" + + mock_config = ( + MockConfigBuilder() + .with_node_output( + "llm", + { + "text": "plain text", + "structured_output": {"type": "greeting"}, + "usage": { + "prompt_tokens": 10, + "completion_tokens": 5, + "total_tokens": 15, + }, + "finish_reason": "stop", + }, + ) + .build() + ) + + graph, graph_runtime_state = runner.workflow_runner.create_graph_from_fixture( + fixture_data=fixture_data, + query="hello", + use_mock_factory=True, + mock_config=mock_config, + ) + + engine = GraphEngine( + workflow_id="test_workflow", + graph=graph, + graph_runtime_state=graph_runtime_state, + command_channel=InMemoryChannel(), + config=GraphEngineConfig(), + ) + + events = list(engine.run()) + success_events = [e for e in events if isinstance(e, GraphRunSucceededEvent)] + + assert success_events, "Workflow should complete successfully" + assert success_events[-1].outputs["answer"] == '{\n "type": "greeting"\n}' diff --git a/api/tests/unit_tests/core/workflow/nodes/answer/test_answer.py b/api/tests/unit_tests/core/workflow/nodes/answer/test_answer.py index 76b4cd1ef4..ae9dae0646 100644 --- a/api/tests/unit_tests/core/workflow/nodes/answer/test_answer.py +++ b/api/tests/unit_tests/core/workflow/nodes/answer/test_answer.py @@ -86,3 +86,80 @@ def test_execute_answer(): assert result.status == WorkflowNodeExecutionStatus.SUCCEEDED assert result.outputs["answer"] == "Today's weather is sunny\nYou are a helpful AI.\n{{img}}\nFin." + + +def test_execute_answer_renders_structured_output_object_as_json() -> None: + init_params = build_test_graph_init_params( + workflow_id="1", + graph_config={"nodes": [], "edges": []}, + tenant_id="1", + app_id="1", + user_id="1", + user_from=UserFrom.ACCOUNT, + invoke_from=InvokeFrom.DEBUGGER, + call_depth=0, + ) + + variable_pool = VariablePool( + system_variables=build_system_variables(user_id="aaa", files=[]), + user_inputs={}, + environment_variables=[], + conversation_variables=[], + ) + variable_pool.add(["1777539038857", "structured_output"], {"type": "greeting"}) + + graph_runtime_state = GraphRuntimeState(variable_pool=variable_pool, start_at=time.perf_counter()) + + node = AnswerNode( + node_id=str(uuid.uuid4()), + graph_init_params=init_params, + graph_runtime_state=graph_runtime_state, + config=AnswerNodeData( + title="123", + type="answer", + answer="{{#1777539038857.structured_output#}}", + ), + ) + + result = node._run() + + assert result.status == WorkflowNodeExecutionStatus.SUCCEEDED + assert result.outputs["answer"] == '{\n "type": "greeting"\n}' + + +def test_execute_answer_falls_back_to_plain_selector_text_when_structured_output_missing() -> None: + init_params = build_test_graph_init_params( + workflow_id="1", + graph_config={"nodes": [], "edges": []}, + tenant_id="1", + app_id="1", + user_id="1", + user_from=UserFrom.ACCOUNT, + invoke_from=InvokeFrom.DEBUGGER, + call_depth=0, + ) + + variable_pool = VariablePool( + system_variables=build_system_variables(user_id="aaa", files=[]), + user_inputs={}, + environment_variables=[], + conversation_variables=[], + ) + + graph_runtime_state = GraphRuntimeState(variable_pool=variable_pool, start_at=time.perf_counter()) + + node = AnswerNode( + node_id=str(uuid.uuid4()), + graph_init_params=init_params, + graph_runtime_state=graph_runtime_state, + config=AnswerNodeData( + title="123", + type="answer", + answer="{{#1777539038857.structured_output#}}", + ), + ) + + result = node._run() + + assert result.status == WorkflowNodeExecutionStatus.SUCCEEDED + assert result.outputs["answer"] == "1777539038857.structured_output" diff --git a/api/tests/unit_tests/core/workflow/test_human_input_adapter.py b/api/tests/unit_tests/core/workflow/test_human_input_adapter.py index 8b5fceeb37..51049f8792 100644 --- a/api/tests/unit_tests/core/workflow/test_human_input_adapter.py +++ b/api/tests/unit_tests/core/workflow/test_human_input_adapter.py @@ -166,6 +166,71 @@ def test_adapt_node_data_for_graph_migrates_legacy_tool_configurations() -> None } +def test_adapt_node_data_for_graph_preserves_model_selector_top_level_configurations() -> None: + normalized = adapt_node_data_for_graph( + { + "type": BuiltinNodeTypes.TOOL, + "tool_configurations": { + "vision_llm_model": { + "type": "constant", + "value": "", + "provider": "langgenius/tongyi/tongyi", + "model": "qwen3-vl-plus", + "model_type": "llm", + "mode": "chat", + }, + }, + } + ) + + assert normalized["tool_configurations"] == {} + assert normalized["tool_parameters"] == { + "vision_llm_model": { + "type": "constant", + "value": { + "provider": "langgenius/tongyi/tongyi", + "model": "qwen3-vl-plus", + "model_type": "llm", + "mode": "chat", + }, + } + } + + +def test_adapt_node_data_for_graph_flattens_constant_model_selector_value() -> None: + normalized = adapt_node_data_for_graph( + { + "type": BuiltinNodeTypes.TOOL, + "tool_configurations": { + "tts_model": { + "type": "constant", + "value": { + "provider": "langgenius/tongyi/tongyi", + "model": "qwen3-tts-flash", + "model_type": "tts", + "language": "Chinese", + "voice": "Cherry", + }, + }, + }, + } + ) + + assert normalized["tool_configurations"] == {} + assert normalized["tool_parameters"] == { + "tts_model": { + "type": "constant", + "value": { + "provider": "langgenius/tongyi/tongyi", + "model": "qwen3-tts-flash", + "model_type": "tts", + "language": "Chinese", + "voice": "Cherry", + }, + } + } + + def test_adapt_node_config_for_graph_rewrites_nested_node_data() -> None: normalized = adapt_node_config_for_graph( { diff --git a/api/tests/unit_tests/core/workflow/test_node_factory.py b/api/tests/unit_tests/core/workflow/test_node_factory.py index 1418cdd87c..1821f72e0c 100644 --- a/api/tests/unit_tests/core/workflow/test_node_factory.py +++ b/api/tests/unit_tests/core/workflow/test_node_factory.py @@ -10,14 +10,20 @@ from core.workflow.nodes.knowledge_index import KNOWLEDGE_INDEX_NODE_TYPE from graphon.entities.base_node_data import BaseNodeData from graphon.enums import BuiltinNodeTypes, NodeType from graphon.nodes.code.entities import CodeLanguage +from graphon.nodes.llm.entities import LLMNodeData from graphon.variables.segments import StringSegment def _assert_typed_node_config(config, *, node_id: str, node_type: NodeType, version: str = "1") -> None: _ = node_id - assert isinstance(config, BaseNodeData) - assert config.type == node_type - assert config.version == version + if isinstance(config, BaseNodeData): + assert config.type == node_type + assert config.version == version + return + + assert isinstance(config, dict) + assert config["type"] == node_type + assert config["version"] == version def _node_constructor(*, return_value): @@ -546,6 +552,84 @@ class TestDifyNodeFactoryCreateNode: assert kwargs["unstructured_api_config"] is sentinel.unstructured_api_config assert kwargs["http_client"] is sentinel.http_client + def test_build_llm_compatible_node_init_kwargs_preserves_structured_output_switch(self, factory): + node_data = LLMNodeData.model_validate( + { + "type": BuiltinNodeTypes.LLM, + "title": "LLM", + "model": {"provider": "provider", "name": "model", "mode": "chat", "completion_params": {}}, + "prompt_template": [{"role": "system", "text": "x"}], + "context": {"enabled": False, "variable_selector": []}, + "vision": {"enabled": False}, + "structured_output_enabled": True, + "structured_output": { + "schema": { + "type": "object", + "properties": {"type": {"type": "string"}}, + "required": ["type"], + } + }, + } + ) + wrapped_model_instance = sentinel.wrapped_model_instance + memory = sentinel.memory + factory._build_model_instance_for_llm_node = MagicMock(return_value=sentinel.model_instance) + factory._build_memory_for_llm_node = MagicMock(return_value=memory) + with patch.object(node_factory, "DifyPreparedLLM", return_value=wrapped_model_instance) as prepared_llm: + kwargs = factory._build_llm_compatible_node_init_kwargs( + node_class=sentinel.node_class, + node_data=node_data, + wrap_model_instance=True, + include_http_client=True, + include_llm_file_saver=True, + include_prompt_message_serializer=True, + include_retriever_attachment_loader=True, + include_jinja2_template_renderer=True, + ) + + assert node_data.structured_output_switch_on is True + assert node_data.structured_output_enabled is True + factory._build_model_instance_for_llm_node.assert_called_once_with(node_data) + factory._build_memory_for_llm_node.assert_called_once_with( + node_data=node_data, + model_instance=sentinel.model_instance, + ) + prepared_llm.assert_called_once_with(sentinel.model_instance) + assert kwargs["model_instance"] is wrapped_model_instance + + def test_create_node_passes_alias_preserving_llm_config_to_constructor(self, monkeypatch, factory): + created_node = object() + constructor = _node_constructor(return_value=created_node) + monkeypatch.setattr(factory, "_resolve_node_class", MagicMock(return_value=constructor)) + monkeypatch.setattr(factory, "_build_llm_compatible_node_init_kwargs", MagicMock(return_value={})) + + node_config = { + "id": "llm-node-id", + "data": { + "type": BuiltinNodeTypes.LLM, + "title": "LLM", + "model": {"provider": "provider", "name": "model", "mode": "chat", "completion_params": {}}, + "prompt_template": [{"role": "system", "text": "x"}], + "context": {"enabled": False, "variable_selector": []}, + "vision": {"enabled": False}, + "structured_output_enabled": True, + "structured_output": { + "schema": { + "type": "object", + "properties": {"type": {"type": "string"}}, + "required": ["type"], + } + }, + }, + } + + factory.create_node(node_config) + + config = constructor.call_args.kwargs["config"] + assert isinstance(config, dict) + assert config["structured_output_enabled"] is True + assert "structured_output_switch_on" not in config + @pytest.mark.parametrize( ("node_type", "constructor_name", "expected_extra_kwargs"), [ diff --git a/api/tests/unit_tests/core/workflow/test_node_runtime.py b/api/tests/unit_tests/core/workflow/test_node_runtime.py index 5a43369a1a..0d13151f42 100644 --- a/api/tests/unit_tests/core/workflow/test_node_runtime.py +++ b/api/tests/unit_tests/core/workflow/test_node_runtime.py @@ -22,6 +22,7 @@ from core.workflow.node_runtime import ( DifyPromptMessageSerializer, DifyRetrieverAttachmentLoader, DifyToolFileManager, + DifyToolNodeRuntime, apply_dify_debug_email_recipient, build_dify_llm_file_saver, resolve_dify_run_context, @@ -30,6 +31,7 @@ from graphon.file import FileTransferMethod, FileType from graphon.model_runtime.entities.common_entities import I18nObject from graphon.model_runtime.entities.model_entities import AIModelEntity, FetchFrom, ModelType from graphon.nodes.human_input.entities import HumanInputNodeData +from graphon.nodes.tool.entities import ToolNodeData, ToolProviderType from tests.workflow_test_utils import build_test_run_context @@ -334,6 +336,41 @@ def test_dify_human_input_runtime_builds_debug_repository(monkeypatch: pytest.Mo ) +def test_dify_tool_runtime_spec_prefers_tool_parameters_for_runtime_form_values() -> None: + node_data = ToolNodeData( + provider_id="video-mixcut-agent", + provider_type=ToolProviderType.PLUGIN, + provider_name="sawyer-shi/video-mixcut-agent", + tool_name="mixcut", + tool_label="MixCut", + tool_configurations={"count": 2}, + tool_parameters={ + "vision_llm_model": { + "type": "constant", + "value": { + "provider": "langgenius/tongyi/tongyi", + "model": "qwen3-vl-plus", + "model_type": "llm", + }, + } + }, + ) + + spec = DifyToolNodeRuntime._build_tool_runtime_spec(node_data) + + assert spec.tool_configurations == { + "count": 2, + "vision_llm_model": { + "type": "constant", + "value": { + "provider": "langgenius/tongyi/tongyi", + "model": "qwen3-vl-plus", + "model_type": "llm", + }, + }, + } + + def test_dify_human_input_runtime_create_form_filters_debugger_delivery_methods() -> None: repository = MagicMock() repository.create_form.return_value = sentinel.form diff --git a/api/tests/unit_tests/factories/test_file_factory.py b/api/tests/unit_tests/factories/test_file_factory.py index 5b105d6084..293be925ae 100644 --- a/api/tests/unit_tests/factories/test_file_factory.py +++ b/api/tests/unit_tests/factories/test_file_factory.py @@ -1,8 +1,11 @@ import re +from unittest.mock import MagicMock import pytest +from factories.file_factory import builders from factories.file_factory.remote import extract_filename, get_remote_file_info +from graphon.file import FileTransferMethod class _FakeResponse: @@ -230,3 +233,153 @@ class TestExtractFilename: "http://example.com/", 'attachment; filename="file%20with%20quotes%20%26%20encoding.txt"' ) assert result == "file with quotes & encoding.txt" + + def test_url_with_query_string(self): + """Test that query strings are stripped from URL basename.""" + result = extract_filename("http://example.com/path/file.txt?signature=abc123&expires=12345", None) + assert result == "file.txt" + + def test_url_with_hash_fragment(self): + """Test that hash fragments are stripped from URL basename.""" + result = extract_filename("http://example.com/path/file.txt#section", None) + assert result == "file.txt" + + def test_url_with_query_and_fragment(self): + """Test that both query strings and hash fragments are stripped.""" + result = extract_filename("http://example.com/path/file.txt?token=xyz#section", None) + assert result == "file.txt" + + def test_signed_url_preserves_filename(self): + """Test that signed URL parameters don't affect filename extraction.""" + result = extract_filename( + "http://storage.example.com/bucket/documents/report.pdf?AWSAccessKeyId=xxx&Signature=yyy&Expires=12345", + None, + ) + assert result == "report.pdf" + + def test_percent_encoded_filename_with_query_string(self): + """Test percent-encoded filename with query string is decoded correctly.""" + result = extract_filename("http://example.com/path/my%20file.txt?download=true", None) + assert result == "my file.txt" + + def test_percent_encoded_filename_with_fragment(self): + """Test percent-encoded filename with fragment is decoded correctly.""" + result = extract_filename("http://example.com/path/my%20file.txt#page=1", None) + assert result == "my file.txt" + + def test_complex_percent_encoding_with_query(self): + """Test complex percent-encoded filename with query parameters.""" + result = extract_filename("http://example.com/docs/%E4%B8%AD%E6%96%87%E6%96%87%E4%BB%B6.pdf?v=1", None) + assert result == "中文文件.pdf" + + def test_url_with_special_chars_in_query(self): + """Test that special characters in query string don't affect filename.""" + result = extract_filename("http://example.com/file.bin?name=test&path=/some/path", None) + assert result == "file.bin" + + def test_malformed_percent_encoding_safe_fallback(self): + """Test that malformed percent-encoding is handled safely.""" + result = extract_filename("http://example.com/path/file%20name%GG.txt?x=1", None) + # %GG is invalid, should be replaced with replacement character + + assert "file" in result + assert ".txt" in result + + def test_empty_path_with_query_returns_none(self): + """Test that empty path with query string returns None.""" + result = extract_filename("http://example.com/?query=value", None) + assert result is None + + def test_path_only_with_query_string(self): + """Test bare path (not full URL) with query string.""" + result = extract_filename("/path/to/file.txt?extra=params", None) + assert result == "file.txt" + + +class TestBuildFromDatasourceFile: + """Tests for _build_from_datasource_file extension handling.""" + + @staticmethod + def _patch_session(monkeypatch: pytest.MonkeyPatch, datasource_file): + """Stub session_factory.create_session() so it returns the given UploadFile-shaped record.""" + session = MagicMock() + session.scalar.return_value = datasource_file + ctx = MagicMock() + ctx.__enter__ = MagicMock(return_value=session) + ctx.__exit__ = MagicMock(return_value=False) + monkeypatch.setattr(builders.session_factory, "create_session", lambda: ctx) + + def _make_datasource_file(self, *, key: str, mime_type: str = "text/csv"): + f = MagicMock() + f.id = "file-id" + f.key = key + f.name = key.split("/")[-1] + f.mime_type = mime_type + f.size = 123 + f.source_url = f"https://example.com/{key}" + return f + + def test_extension_passed_without_doubled_dot(self, monkeypatch: pytest.MonkeyPatch): + """Regression: standardize_file_type must receive the extension exactly once-prefixed. + + Previously the call was ``standardize_file_type(extension="." + extension, ...)`` while + ``extension`` already had a leading dot, producing ``"..csv"``. The mitigating + ``lstrip(".")`` inside ``standardize_file_type`` masked the bug from end users, but the + argument shape itself was wrong and showed up in any caller that didn't strip dots. + """ + captured: dict = {} + + def fake_standardize(*, extension: str = "", mime_type: str = ""): + from graphon.file import FileType + + captured["extension"] = extension + captured["mime_type"] = mime_type + return FileType.DOCUMENT + + monkeypatch.setattr(builders, "standardize_file_type", fake_standardize) + + datasource_file = self._make_datasource_file(key="folder/data.csv", mime_type="text/csv") + self._patch_session(monkeypatch, datasource_file) + + access_controller = MagicMock() + access_controller.apply_upload_file_filters = lambda stmt: stmt + + file = builders._build_from_datasource_file( + mapping={"datasource_file_id": "file-id", "transfer_method": "datasource_file"}, + tenant_id="tenant-id", + transfer_method=FileTransferMethod.DATASOURCE_FILE, + access_controller=access_controller, + ) + + assert captured["extension"] == ".csv", ( + f"standardize_file_type received {captured['extension']!r}; expected single-dot '.csv'" + ) + assert captured["mime_type"] == "text/csv" + assert file.extension == ".csv" + + def test_extension_falls_back_to_bin_when_key_has_no_dot(self, monkeypatch: pytest.MonkeyPatch): + captured: dict = {} + + def fake_standardize(*, extension: str = "", mime_type: str = ""): + from graphon.file import FileType + + captured["extension"] = extension + return FileType.CUSTOM + + monkeypatch.setattr(builders, "standardize_file_type", fake_standardize) + + datasource_file = self._make_datasource_file(key="dotless-key", mime_type="application/octet-stream") + self._patch_session(monkeypatch, datasource_file) + + access_controller = MagicMock() + access_controller.apply_upload_file_filters = lambda stmt: stmt + + file = builders._build_from_datasource_file( + mapping={"datasource_file_id": "file-id", "transfer_method": "datasource_file"}, + tenant_id="tenant-id", + transfer_method=FileTransferMethod.DATASOURCE_FILE, + access_controller=access_controller, + ) + + assert captured["extension"] == ".bin" + assert file.extension == ".bin" diff --git a/api/tests/unit_tests/services/controller_api.py b/api/tests/unit_tests/services/controller_api.py index 762d7b9090..e7f7cabecd 100644 --- a/api/tests/unit_tests/services/controller_api.py +++ b/api/tests/unit_tests/services/controller_api.py @@ -146,7 +146,7 @@ class ControllerApiTestDataFactory: return app @staticmethod - def create_api_instance(app): + def create_api_instance(app: Flask): """ Create a Flask-RESTX API instance. @@ -160,7 +160,12 @@ class ControllerApiTestDataFactory: return api @staticmethod - def create_test_client(app, api, resource_class, route): + def create_test_client( + app: Flask, + api: Api, + resource_class: type, + route: str, + ): """ Create a Flask test client with a resource registered. @@ -302,7 +307,7 @@ class TestDatasetListApi: return ControllerApiTestDataFactory.create_flask_app() @pytest.fixture - def api(self, app): + def api(self, app: Flask): """ Create Flask-RESTX API instance. @@ -311,7 +316,7 @@ class TestDatasetListApi: return ControllerApiTestDataFactory.create_api_instance(app) @pytest.fixture - def client(self, app, api): + def client(self, app: Flask, api: Api): """ Create test client with DatasetListApi registered. @@ -472,12 +477,12 @@ class TestDatasetApiGet: return ControllerApiTestDataFactory.create_flask_app() @pytest.fixture - def api(self, app): + def api(self, app: Flask): """Create Flask-RESTX API instance.""" return ControllerApiTestDataFactory.create_api_instance(app) @pytest.fixture - def client(self, app, api): + def client(self, app: Flask, api: Api): """Create test client with DatasetApi registered.""" return ControllerApiTestDataFactory.create_test_client(app, api, DatasetApi, "/datasets/") @@ -588,12 +593,12 @@ class TestDatasetApiCreate: return ControllerApiTestDataFactory.create_flask_app() @pytest.fixture - def api(self, app): + def api(self, app: Flask): """Create Flask-RESTX API instance.""" return ControllerApiTestDataFactory.create_api_instance(app) @pytest.fixture - def client(self, app, api): + def client(self, app: Flask, api: Api): """Create test client with DatasetApi registered.""" return ControllerApiTestDataFactory.create_test_client(app, api, DatasetApi, "/datasets") @@ -681,12 +686,12 @@ class TestHitTestingApi: return ControllerApiTestDataFactory.create_flask_app() @pytest.fixture - def api(self, app): + def api(self, app: Flask): """Create Flask-RESTX API instance.""" return ControllerApiTestDataFactory.create_api_instance(app) @pytest.fixture - def client(self, app, api): + def client(self, app: Flask, api: Api): """Create test client with HitTestingApi registered.""" return ControllerApiTestDataFactory.create_test_client( app, api, HitTestingApi, "/datasets//hit-testing" @@ -799,12 +804,12 @@ class TestExternalDatasetApi: return ControllerApiTestDataFactory.create_flask_app() @pytest.fixture - def api(self, app): + def api(self, app: Flask): """Create Flask-RESTX API instance.""" return ControllerApiTestDataFactory.create_api_instance(app) @pytest.fixture - def client_list(self, app, api): + def client_list(self, app: Flask, api: Api): """Create test client for external knowledge API list endpoint.""" return ControllerApiTestDataFactory.create_test_client( app, api, ExternalApiTemplateListApi, "/datasets/external-knowledge-api" diff --git a/api/tests/unit_tests/services/plugin/test_plugin_permission_service.py b/api/tests/unit_tests/services/plugin/test_plugin_permission_service.py deleted file mode 100644 index 53a9e6210c..0000000000 --- a/api/tests/unit_tests/services/plugin/test_plugin_permission_service.py +++ /dev/null @@ -1,79 +0,0 @@ -from unittest.mock import MagicMock, patch - -from models.account import TenantPluginPermission - -MODULE = "services.plugin.plugin_permission_service" - - -def _patched_session(): - """Patch session_factory.create_session() to return a mock session as context manager.""" - session = MagicMock() - session.__enter__ = MagicMock(return_value=session) - session.__exit__ = MagicMock(return_value=False) - session.begin.return_value.__enter__ = MagicMock(return_value=session) - session.begin.return_value.__exit__ = MagicMock(return_value=False) - mock_factory = MagicMock() - mock_factory.create_session.return_value = session - patcher = patch(f"{MODULE}.session_factory", mock_factory) - return patcher, session - - -class TestGetPermission: - def test_returns_permission_when_found(self): - p1, session = _patched_session() - permission = MagicMock() - session.scalar.return_value = permission - - with p1: - from services.plugin.plugin_permission_service import PluginPermissionService - - result = PluginPermissionService.get_permission("t1") - - assert result is permission - - def test_returns_none_when_not_found(self): - p1, session = _patched_session() - session.scalar.return_value = None - - with p1: - from services.plugin.plugin_permission_service import PluginPermissionService - - result = PluginPermissionService.get_permission("t1") - - assert result is None - - -class TestChangePermission: - def test_creates_new_permission_when_not_exists(self): - p1, session = _patched_session() - session.scalar.return_value = None - - with p1, patch(f"{MODULE}.select"), patch(f"{MODULE}.TenantPluginPermission") as perm_cls: - perm_cls.return_value = MagicMock() - from services.plugin.plugin_permission_service import PluginPermissionService - - result = PluginPermissionService.change_permission( - "t1", TenantPluginPermission.InstallPermission.EVERYONE, TenantPluginPermission.DebugPermission.EVERYONE - ) - - assert result is True - session.begin.assert_called_once() - session.add.assert_called_once() - - def test_updates_existing_permission(self): - p1, session = _patched_session() - existing = MagicMock() - session.scalar.return_value = existing - - with p1: - from services.plugin.plugin_permission_service import PluginPermissionService - - result = PluginPermissionService.change_permission( - "t1", TenantPluginPermission.InstallPermission.ADMINS, TenantPluginPermission.DebugPermission.ADMINS - ) - - assert result is True - session.begin.assert_called_once() - assert existing.install_permission == TenantPluginPermission.InstallPermission.ADMINS - assert existing.debug_permission == TenantPluginPermission.DebugPermission.ADMINS - session.add.assert_not_called() diff --git a/api/tests/unit_tests/services/workflow/test_draft_var_loader_simple.py b/api/tests/unit_tests/services/workflow/test_draft_var_loader_simple.py index 497c26a9b3..fb5cf7bc6e 100644 --- a/api/tests/unit_tests/services/workflow/test_draft_var_loader_simple.py +++ b/api/tests/unit_tests/services/workflow/test_draft_var_loader_simple.py @@ -33,42 +33,6 @@ class TestDraftVarLoaderSimple: fallback_variables=[], ) - def test_load_offloaded_variable_string_type_unit(self, draft_var_loader): - """Test _load_offloaded_variable with string type - isolated unit test.""" - # Create mock objects - upload_file = Mock(spec=UploadFile) - upload_file.key = "storage/key/test.txt" - - variable_file = Mock(spec=WorkflowDraftVariableFile) - variable_file.value_type = SegmentType.STRING - variable_file.upload_file = upload_file - - draft_var = Mock(spec=WorkflowDraftVariable) - draft_var.id = "draft-var-id" - draft_var.node_id = "test-node-id" - draft_var.name = "test_variable" - draft_var.description = "test description" - draft_var.get_selector.return_value = ["test-node-id", "test_variable"] - draft_var.variable_file = variable_file - - test_content = "This is the full string content" - - with patch("services.workflow_draft_variable_service.storage") as mock_storage: - mock_storage.load.return_value = test_content.encode() - - # Execute the method - selector_tuple, variable = draft_var_loader._load_offloaded_variable(draft_var) - - # Verify results - assert selector_tuple == ("test-node-id", "test_variable") - assert variable.id == "draft-var-id" - assert variable.name == "test_variable" - assert variable.description == "test description" - assert variable.value == test_content - - # Verify storage was called correctly - mock_storage.load.assert_called_once_with("storage/key/test.txt") - def test_load_offloaded_variable_object_type_unit(self, draft_var_loader): """Test _load_offloaded_variable with object type - isolated unit test.""" # Create mock objects @@ -139,47 +103,6 @@ class TestDraftVarLoaderSimple: result = draft_var_loader._selector_to_tuple(selector) assert result == ("node_id", "var_name") - def test_load_offloaded_variable_number_type_unit(self, draft_var_loader): - """Test _load_offloaded_variable with number type - isolated unit test.""" - # Create mock objects - upload_file = Mock(spec=UploadFile) - upload_file.key = "storage/key/test_number.json" - - variable_file = Mock(spec=WorkflowDraftVariableFile) - variable_file.value_type = SegmentType.NUMBER - variable_file.upload_file = upload_file - - draft_var = Mock(spec=WorkflowDraftVariable) - draft_var.id = "draft-var-id" - draft_var.node_id = "test-node-id" - draft_var.name = "test_number" - draft_var.description = "test number description" - draft_var.get_selector.return_value = ["test-node-id", "test_number"] - draft_var.variable_file = variable_file - - test_number = 123.45 - test_json_content = json.dumps(test_number) - - with patch("services.workflow_draft_variable_service.storage") as mock_storage: - mock_storage.load.return_value = test_json_content.encode() - from graphon.variables.segments import FloatSegment - - mock_segment = FloatSegment(value=test_number) - draft_var.build_segment_from_serialized_value.return_value = mock_segment - - # Execute the method - selector_tuple, variable = draft_var_loader._load_offloaded_variable(draft_var) - - # Verify results - assert selector_tuple == ("test-node-id", "test_number") - assert variable.id == "draft-var-id" - assert variable.name == "test_number" - assert variable.description == "test number description" - - # Verify method calls - mock_storage.load.assert_called_once_with("storage/key/test_number.json") - draft_var.build_segment_from_serialized_value.assert_called_once_with(SegmentType.NUMBER, test_number) - def test_load_offloaded_variable_array_type_unit(self, draft_var_loader): """Test _load_offloaded_variable with array type - isolated unit test.""" # Create mock objects @@ -229,12 +152,13 @@ class TestDraftVarLoaderSimple: variable_file.value_type = SegmentType.FILE variable_file.upload_file = upload_file - draft_var = WorkflowDraftVariable() - draft_var.id = "draft-var-id" - draft_var.app_id = "app-1" - draft_var.node_id = "test-node-id" - draft_var.name = "test_file" - draft_var.description = "test file description" + draft_var = WorkflowDraftVariable( + id="draft-var-id", + app_id="app-1", + node_id="test-node-id", + name="test_file", + description="test file description", + ) draft_var._set_selector(["test-node-id", "test_file"]) draft_var.variable_file = variable_file diff --git a/api/tests/unit_tests/services/workflow/test_workflow_draft_variable_service.py b/api/tests/unit_tests/services/workflow/test_workflow_draft_variable_service.py index b14d767568..663eec6a06 100644 --- a/api/tests/unit_tests/services/workflow/test_workflow_draft_variable_service.py +++ b/api/tests/unit_tests/services/workflow/test_workflow_draft_variable_service.py @@ -200,7 +200,7 @@ class TestDraftVariableSaver: user=mock_user, ) - def test_draft_saver_with_small_variables(self, draft_saver, mock_session): + def test_draft_saver_with_small_variables(self, draft_saver: DraftVariableSaver, mock_session): with patch( "services.workflow_draft_variable_service.DraftVariableSaver._try_offload_large_variable", autospec=True ) as _mock_try_offload: @@ -212,18 +212,21 @@ class TestDraftVariableSaver: assert draft_var.file_id is None _mock_try_offload.return_value = None - def test_draft_saver_with_large_variables(self, draft_saver, mock_session): + def test_draft_saver_with_large_variables(self, draft_saver: DraftVariableSaver, mock_session): with patch( "services.workflow_draft_variable_service.DraftVariableSaver._try_offload_large_variable", autospec=True ) as _mock_try_offload: mock_segment = StringSegment(value="small value") mock_draft_var_file = WorkflowDraftVariableFile( - id=str(uuidv7()), + tenant_id=str(uuidv7()), + app_id=str(uuidv7()), + user_id=str(uuidv7()), size=1024, length=10, value_type=SegmentType.ARRAY_STRING, - upload_file_id=str(uuid.uuid4()), + upload_file_id=str(uuidv7()), ) + mock_draft_var_file.id = str(uuidv7()) _mock_try_offload.return_value = mock_segment, mock_draft_var_file draft_var = draft_saver._create_draft_variable(name="small_var", value=mock_segment, visible=True) diff --git a/api/uv.lock b/api/uv.lock index 1b52f8b53f..6f75c9f6fe 100644 --- a/api/uv.lock +++ b/api/uv.lock @@ -481,7 +481,7 @@ wheels = [ [[package]] name = "bce-python-sdk" -version = "0.9.70" +version = "0.9.71" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "crc32c" }, @@ -489,9 +489,9 @@ dependencies = [ { name = "pycryptodome" }, { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f7/a9/7c21a9073eb9ad7e8cacf6f8a0e47c0d01ad7bf8fd8e0dc42164b117d60b/bce_python_sdk-0.9.70.tar.gz", hash = "sha256:3b37fd7448278dd33f745a6a23198a2cc2490fded9cb8d59b72500784853df4e", size = 299967, upload-time = "2026-04-14T12:02:42.034Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/74/72058f098b9e7184376f2b3d4c1d233ca7fdc52d0f527078f3ce4d9828b9/bce_python_sdk-0.9.71.tar.gz", hash = "sha256:7a917edaee39082694776e25a9e6556ec8072400a3be649f28eb13f9c7a0b5b5", size = 301508, upload-time = "2026-04-28T06:23:21.061Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/2d/70fc866ff98d1f6bd75b0a4235694129b3c519b014254d7bcfc02ffe1bee/bce_python_sdk-0.9.70-py3-none-any.whl", hash = "sha256:fd1f31113e4a8dca314f040662b7caf07ec11cf896c5da232627a9a2c9d2e3a1", size = 415660, upload-time = "2026-04-14T12:02:40.034Z" }, + { url = "https://files.pythonhosted.org/packages/2d/2d/821ae8878dc36b77e56bb7e5dbf9a8e73209c11d38c0ba6b38b5778668ae/bce_python_sdk-0.9.71-py3-none-any.whl", hash = "sha256:9f64a99267616456bac487983d92cc778720bf4f102c8931e8e38aea3cb63268", size = 417000, upload-time = "2026-04-28T06:23:19.078Z" }, ] [[package]] @@ -604,29 +604,29 @@ wheels = [ [[package]] name = "boto3" -version = "1.42.96" +version = "1.43.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a6/2d/69fb3acd50bab83fb295c167d33c4b653faeb5fb0f42bfca4d9b69d6fb68/boto3-1.42.96.tar.gz", hash = "sha256:b38a9e4a3fbbee9017252576f1379780d0a5814768676c08df2f539d31fcdd68", size = 113203, upload-time = "2026-04-24T19:47:18.677Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/50/ea184e159c4ac64fef816a72094fb8656eb071361a39ed22c0e3b15a35b4/boto3-1.43.3.tar.gz", hash = "sha256:7c7777862ffc898f05efa566032bbabfe226dbb810e35ec11125817f128bc5c5", size = 113111, upload-time = "2026-05-04T19:34:09.731Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/9d/b3f617d011c42eb804d993103b8fa9acdce153e181a3042f58bfe33d7cb4/boto3-1.42.96-py3-none-any.whl", hash = "sha256:2f4566da2c209a98bdbfc874d813ef231c84ad24e4f815e9bc91de5f63351a24", size = 140557, upload-time = "2026-04-24T19:47:15.824Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ad/8a6946a329f0127322108e537dc1c0d9f8eea4f1d1231702c073d2e85f46/boto3-1.43.3-py3-none-any.whl", hash = "sha256:fb9fe51849ef2a78198d582756fc06f14f7de27f73e0fa90275d6aa4171eb4d0", size = 140501, upload-time = "2026-05-04T19:34:07.991Z" }, ] [[package]] name = "boto3-stubs" -version = "1.42.96" +version = "1.43.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore-stubs" }, { name = "types-s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/86/65f45f84621cccc2471871088bab8fe515b4346ba9e48d9001484ec440d6/boto3_stubs-1.42.96.tar.gz", hash = "sha256:1e7819c34d1eae8e5e3cfaf9d144fdcad65aad184b380488871de1d0b2851879", size = 102691, upload-time = "2026-04-24T20:25:13.984Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8a/7f/399bcdeaa60a89aafe5292c8364c313177d22b886dffc1bd7b56fe817900/boto3_stubs-1.43.2.tar.gz", hash = "sha256:0d46636f3e761a92070114b39a76b154c5da6c5794c890e1440a7f191bf1ff2e", size = 102658, upload-time = "2026-05-01T20:31:36.963Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/51/bdac1ff9fd4321091183776c5adffce5fc7b4d0fec7e38af9064e24a2497/boto3_stubs-1.42.96-py3-none-any.whl", hash = "sha256:2c112e257f40006147a53f6f62075804689154271973b2807f5656feaa804216", size = 70668, upload-time = "2026-04-24T20:25:09.736Z" }, + { url = "https://files.pythonhosted.org/packages/da/df/17647562444b2047ca325eaaf2fea738571822b7b4efdaa6bacf0fd4fff9/boto3_stubs-1.43.2-py3-none-any.whl", hash = "sha256:941f2907236223a1209704eaf708d3cdf1ecc8695618c558f9fb9e23e90c513b", size = 70653, upload-time = "2026-05-01T20:31:30.057Z" }, ] [package.optional-dependencies] @@ -636,16 +636,16 @@ bedrock-runtime = [ [[package]] name = "botocore" -version = "1.42.96" +version = "1.43.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/61/77/2c333622a1d47cf5bf73cdcab0cb6c92addafbef2ec05f81b9f75687d9e5/botocore-1.42.96.tar.gz", hash = "sha256:75b3b841ffacaa944f645196655a21ca777591dd8911e732bfb6614545af0250", size = 15263344, upload-time = "2026-04-24T19:47:05.283Z" } +sdist = { url = "https://files.pythonhosted.org/packages/74/ac/cd55f886e17b6b952dbc95b792d3645a73d58586a1400ababe54406073bd/botocore-1.43.3.tar.gz", hash = "sha256:eac6da0fffccf87888ebf4d89f0b2378218a707efa748cd955b838995e944695", size = 15308705, upload-time = "2026-05-04T19:33:56.28Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/56/152c3a859ca1b9d77ed16deac3cf81682013677c68cf5715698781fc81bd/botocore-1.42.96-py3-none-any.whl", hash = "sha256:db2c3e2006628be6fde81a24124a6563c363d6982fb92728837cf174bad9d98a", size = 14945920, upload-time = "2026-04-24T19:47:00.323Z" }, + { url = "https://files.pythonhosted.org/packages/be/99/1d9e296edf244f47e0508032f20999f8fd40704dd3c5b601fed099424eb6/botocore-1.43.3-py3-none-any.whl", hash = "sha256:ec0769eb0f7c5034856bb406a92698dbc02a3d4be0f78a384747106b161d8ea3", size = 14989027, upload-time = "2026-05-04T19:33:50.81Z" }, ] [[package]] @@ -1289,7 +1289,7 @@ wheels = [ [[package]] name = "dify-api" -version = "1.13.3" +version = "1.14.0" source = { virtual = "." } dependencies = [ { name = "aliyun-log-python-sdk" }, @@ -1578,7 +1578,7 @@ requires-dist = [ { name = "aliyun-log-python-sdk", specifier = ">=0.9.44,<1.0.0" }, { name = "azure-identity", specifier = ">=1.25.3,<2.0.0" }, { name = "bleach", specifier = ">=6.3.0" }, - { name = "boto3", specifier = ">=1.42.96" }, + { name = "boto3", specifier = ">=1.43.3" }, { name = "celery", specifier = ">=5.6.3" }, { name = "croniter", specifier = ">=6.2.2" }, { name = "fastopenapi", extras = ["flask"], specifier = "~=0.7.0" }, @@ -1592,8 +1592,8 @@ requires-dist = [ { name = "gevent", specifier = ">=26.4.0" }, { name = "gevent-websocket", specifier = ">=0.10.1" }, { name = "gmpy2", specifier = ">=2.3.0" }, - { name = "google-api-python-client", specifier = ">=2.194.0" }, - { name = "google-cloud-aiplatform", specifier = ">=1.148.1,<2.0.0" }, + { name = "google-api-python-client", specifier = ">=2.195.0" }, + { name = "google-cloud-aiplatform", specifier = ">=1.149.0,<2.0.0" }, { name = "graphon", specifier = "~=0.2.2" }, { name = "gunicorn", specifier = ">=25.3.0" }, { name = "httpx", extras = ["socks"], specifier = ">=0.28.1,<1.0.0" }, @@ -1619,17 +1619,17 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "basedpyright", specifier = ">=1.39.3" }, - { name = "boto3-stubs", specifier = ">=1.42.96" }, + { name = "boto3-stubs", specifier = ">=1.43.2" }, { name = "celery-types", specifier = ">=0.23.0" }, { name = "coverage", specifier = ">=7.13.4" }, { name = "dotenv-linter", specifier = ">=0.7.0" }, { name = "faker", specifier = ">=40.15.0" }, - { name = "hypothesis", specifier = ">=6.152.3" }, + { name = "hypothesis", specifier = ">=6.152.4" }, { name = "import-linter", specifier = ">=2.3" }, { name = "lxml-stubs", specifier = ">=0.5.1" }, { name = "mypy", specifier = ">=1.20.2" }, { name = "pandas-stubs", specifier = ">=3.0.0" }, - { name = "pyrefly", specifier = ">=0.62.0" }, + { name = "pyrefly", specifier = ">=0.64.0" }, { name = "pytest", specifier = ">=9.0.3" }, { name = "pytest-benchmark", specifier = ">=5.2.3" }, { name = "pytest-cov", specifier = ">=7.1.0" }, @@ -1642,8 +1642,8 @@ dev = [ { name = "testcontainers", specifier = ">=4.14.2" }, { name = "types-aiofiles", specifier = ">=25.1.0" }, { name = "types-beautifulsoup4", specifier = ">=4.12.0" }, - { name = "types-cachetools", specifier = ">=6.2.0" }, - { name = "types-cffi", specifier = ">=2.0.0.20260408" }, + { name = "types-cachetools", specifier = ">=7.0.0.20260503" }, + { name = "types-cffi", specifier = ">=2.0.0.20260429" }, { name = "types-colorama", specifier = ">=0.4.15" }, { name = "types-defusedxml", specifier = ">=0.7.0" }, { name = "types-deprecated", specifier = ">=1.3.1" }, @@ -1651,7 +1651,7 @@ dev = [ { name = "types-flask-cors", specifier = ">=6.0.0" }, { name = "types-flask-migrate", specifier = ">=4.1.0" }, { name = "types-gevent", specifier = ">=26.4.0" }, - { name = "types-greenlet", specifier = ">=3.4.0" }, + { name = "types-greenlet", specifier = ">=3.5.0.20260428" }, { name = "types-html5lib", specifier = ">=1.1.11" }, { name = "types-jmespath", specifier = ">=1.1.0.20260408" }, { name = "types-markdown", specifier = ">=3.10.2" }, @@ -1660,7 +1660,7 @@ dev = [ { name = "types-olefile", specifier = ">=0.47.0" }, { name = "types-openpyxl", specifier = ">=3.1.5" }, { name = "types-pexpect", specifier = ">=4.9.0" }, - { name = "types-protobuf", specifier = ">=7.34.1" }, + { name = "types-protobuf", specifier = ">=7.34.1.20260503" }, { name = "types-psutil", specifier = ">=7.2.2" }, { name = "types-psycopg2", specifier = ">=2.9.21.20260422" }, { name = "types-pygments", specifier = ">=2.20.0" }, @@ -1683,7 +1683,7 @@ dev = [ ] storage = [ { name = "azure-storage-blob", specifier = ">=12.28.0" }, - { name = "bce-python-sdk", specifier = ">=0.9.70" }, + { name = "bce-python-sdk", specifier = ">=0.9.71" }, { name = "cos-python-sdk-v5", specifier = ">=1.9.42" }, { name = "esdk-obs-python", specifier = ">=3.22.2" }, { name = "google-cloud-storage", specifier = ">=3.10.1" }, @@ -2657,14 +2657,14 @@ wheels = [ [[package]] name = "gitpython" -version = "3.1.47" +version = "3.1.49" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gitdb" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c1/bd/50db468e9b1310529a19fce651b3b0e753b5c07954d486cba31bbee9a5d5/gitpython-3.1.47.tar.gz", hash = "sha256:dba27f922bd2b42cb54c87a8ab3cb6beb6bf07f3d564e21ac848913a05a8a3cd", size = 216978, upload-time = "2026-04-22T02:44:44.059Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/63/210aaa302d6a0a78daa67c5c15bbac2cad361722841278b0209b6da20855/gitpython-3.1.49.tar.gz", hash = "sha256:42f9399c9eb33fc581014bedd76049dfbaf6375aa2a5754575966387280315e1", size = 219367, upload-time = "2026-04-29T00:31:20.478Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/c5/a1bc0996af85757903cf2bf444a7824e68e0035ce63fb41d6f76f9def68b/gitpython-3.1.47-py3-none-any.whl", hash = "sha256:489f590edfd6d20571b2c0e72c6a6ac6915ee8b8cd04572330e3842207a78905", size = 209547, upload-time = "2026-04-22T02:44:41.271Z" }, + { url = "https://files.pythonhosted.org/packages/fd/6f/b842bfa6f21d6f87c57f9abf7194225e55279d96d869775e19e9f7236fc5/gitpython-3.1.49-py3-none-any.whl", hash = "sha256:024b0422d7f84d15cd794844e029ffebd4c5d42a7eb9b936b458697ef550a02c", size = 212190, upload-time = "2026-04-29T00:31:18.412Z" }, ] [[package]] @@ -2719,7 +2719,7 @@ grpc = [ [[package]] name = "google-api-python-client" -version = "2.194.0" +version = "2.195.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-api-core" }, @@ -2728,9 +2728,9 @@ dependencies = [ { name = "httplib2" }, { name = "uritemplate" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/60/ab/e83af0eb043e4ccc49571ca7a6a49984e9d00f4e9e6e6f1238d60bc84dce/google_api_python_client-2.194.0.tar.gz", hash = "sha256:db92647bd1a90f40b79c9618461553c2b20b6a43ce7395fa6de07132dc14f023", size = 14443469, upload-time = "2026-04-08T23:07:35.757Z" } +sdist = { url = "https://files.pythonhosted.org/packages/69/07/08d759b9cb10f48af14b25262dd0d6685ca8cda6c1f9e8a8109f57457205/google_api_python_client-2.195.0.tar.gz", hash = "sha256:c72cf2661c3addf01c880ce60541e83e1df354644b874f7f9d8d5ed2070446ae", size = 14584819, upload-time = "2026-04-30T21:51:50.638Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/34/5a624e49f179aa5b0cb87b2ce8093960299030ff40423bfbde09360eb908/google_api_python_client-2.194.0-py3-none-any.whl", hash = "sha256:61eaaac3b8fc8fdf11c08af87abc3d1342d1b37319cc1b57405f86ef7697e717", size = 15016514, upload-time = "2026-04-08T23:07:33.093Z" }, + { url = "https://files.pythonhosted.org/packages/21/b9/2c71095e31fff57668fec7c07ac897df065f15521d070e63229e13689590/google_api_python_client-2.195.0-py3-none-any.whl", hash = "sha256:753e62057f23049a89534bea0162b60fe391b85fb86d80bcdf884d05ec91c5bf", size = 15162418, upload-time = "2026-04-30T21:51:47.444Z" }, ] [[package]] @@ -2766,7 +2766,7 @@ wheels = [ [[package]] name = "google-cloud-aiplatform" -version = "1.148.1" +version = "1.149.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "docstring-parser" }, @@ -2782,9 +2782,9 @@ dependencies = [ { name = "pydantic" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/f3/b2a9417014c93858a2e3266134f931eefd972c2d410b25d7b8782fc6f143/google_cloud_aiplatform-1.148.1.tar.gz", hash = "sha256:75d605fba34e68714bd08e1e482755d0a6e3ae972805f809d088e686c30879e7", size = 10278758, upload-time = "2026-04-17T23:45:26.738Z" } +sdist = { url = "https://files.pythonhosted.org/packages/42/2c/fba4adc56f74c0ee0fbd91a39d414ca2c3588dd8b71f9be8a507015ca886/google_cloud_aiplatform-1.149.0.tar.gz", hash = "sha256:a4d73485bf1d727a9e1bbbd13d08d7031490686bbf7d125eb905c1a6c1559a35", size = 10451466, upload-time = "2026-04-27T23:11:54.513Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/5b/e3515d7bbba602c2b0f6a0da5431785e897252443682e4735d0e6873dc8f/google_cloud_aiplatform-1.148.1-py2.py3-none-any.whl", hash = "sha256:035101e2d8e65c6a706cc3930b2452de7ddcbde50dd130320fcea0d8b03b0c5a", size = 8434481, upload-time = "2026-04-17T23:45:22.919Z" }, + { url = "https://files.pythonhosted.org/packages/bf/a0/27719ba23967ef62e52a1d54e013e0fc174bdab8dd84fb300bab9bf0d4a3/google_cloud_aiplatform-1.149.0-py2.py3-none-any.whl", hash = "sha256:e6b5299fa5d303e971cb29a19f03fdbb7b1e3b9d2faa3a788ca933341fba2f2e", size = 8570410, upload-time = "2026-04-27T23:11:50.495Z" }, ] [[package]] @@ -3319,14 +3319,14 @@ wheels = [ [[package]] name = "hypothesis" -version = "6.152.3" +version = "6.152.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sortedcontainers" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/70/90/fc0b263b6f2622e5f8d2aa93f2e95ba79718a5faa7d2a74bfab10d6b0905/hypothesis-6.152.3.tar.gz", hash = "sha256:c4e5300d3755b6c8a270a28fe5abff40153e927328e89d2bb0229c1384618998", size = 466478, upload-time = "2026-04-26T17:31:07.657Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fa/c7/3147bd903d6b18324a016d43a259cf5b4bb4545e1ead6773dc8a0374e70a/hypothesis-6.152.4.tar.gz", hash = "sha256:31c8f9ce619716f543e2710b489b1633c833586641d9e6c94cee03f109a5afc4", size = 466444, upload-time = "2026-04-27T20:18:37.594Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/38/15475b91a4c12721d2be3349e9d6cf8649c76ed9bc1287e2de7c8d06c261/hypothesis-6.152.3-py3-none-any.whl", hash = "sha256:4b47f00916c858ed49cf870a2f08b04e5fff5afae0bb78f3b4a6d9c74fd6c7bc", size = 532154, upload-time = "2026-04-26T17:31:04.42Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/0f50dd0d92e8a7dffc24f69ab910ff81db89b2f082ba42682bd57695e4d2/hypothesis-6.152.4-py3-none-any.whl", hash = "sha256:e730fd93c7578182efadc7f90b3c5437ee4d55edf738930eb5043c81ac1d97e8", size = 532145, upload-time = "2026-04-27T20:18:35.043Z" }, ] [[package]] @@ -3740,14 +3740,14 @@ wheels = [ [[package]] name = "mako" -version = "1.3.11" +version = "1.3.12" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/59/8a/805404d0c0b9f3d7a326475ca008db57aea9c5c9f2e1e39ed0faa335571c/mako-1.3.11.tar.gz", hash = "sha256:071eb4ab4c5010443152255d77db7faa6ce5916f35226eb02dc34479b6858069", size = 399811, upload-time = "2026-04-14T20:19:51.493Z" } +sdist = { url = "https://files.pythonhosted.org/packages/00/62/791b31e69ae182791ec67f04850f2f062716bbd205483d63a215f3e062d3/mako-1.3.12.tar.gz", hash = "sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a", size = 400219, upload-time = "2026-04-28T19:01:08.512Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/a5/19d7aaa7e433713ffe881df33705925a196afb9532efc8475d26593921a6/mako-1.3.11-py3-none-any.whl", hash = "sha256:e372c6e333cf004aa736a15f425087ec977e1fcbd2966aae7f17c8dc1da27a77", size = 78503, upload-time = "2026-04-14T20:19:53.233Z" }, + { url = "https://files.pythonhosted.org/packages/bc/b1/a0ec7a5a9db730a08daef1fdfb8090435b82465abbf758a596f0ea88727e/mako-1.3.12-py3-none-any.whl", hash = "sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9", size = 78521, upload-time = "2026-04-28T19:01:10.393Z" }, ] [[package]] @@ -3969,11 +3969,11 @@ wheels = [ [[package]] name = "mypy-boto3-bedrock-runtime" -version = "1.42.42" +version = "1.43.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/46/bb/65dc1b2c5796a6ab5f60bdb57343bd6c3ecb82251c580eca415c8548333e/mypy_boto3_bedrock_runtime-1.42.42.tar.gz", hash = "sha256:3a4088218478b6fbbc26055c03c95bee4fc04624a801090b3cce3037e8275c8d", size = 29840, upload-time = "2026-02-04T20:53:05.999Z" } +sdist = { url = "https://files.pythonhosted.org/packages/21/f2/61519c0162307b1e4d47f63ed8b25390874640934f3d2d25c5d6c5078dd8/mypy_boto3_bedrock_runtime-1.43.0.tar.gz", hash = "sha256:19fc3167de6e66dd7a0ab293adc55c93e2fd67be35e8ab4fc3a7523a380752ce", size = 29903, upload-time = "2026-04-29T22:57:57.561Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/43/7ea062f2228f47b5779dcfa14dab48d6e29f979b35d1a5102b0ba80b9c1b/mypy_boto3_bedrock_runtime-1.42.42-py3-none-any.whl", hash = "sha256:b2d16eae22607d0685f90796b3a0afc78c0b09d45872e00eafd634a31dd9358f", size = 36077, upload-time = "2026-02-04T20:53:01.768Z" }, + { url = "https://files.pythonhosted.org/packages/40/4d/7e4c4d55af23b2b1304d6814db8c406beab7977056963200230417c1a2db/mypy_boto3_bedrock_runtime-1.43.0-py3-none-any.whl", hash = "sha256:a125296f992093d58bdcd95176002680fa81ca8a8b8bdf02afad7e5f2d8966aa", size = 36172, upload-time = "2026-04-29T22:57:54.777Z" }, ] [[package]] @@ -5359,19 +5359,19 @@ wheels = [ [[package]] name = "pyrefly" -version = "0.62.0" +version = "0.64.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/ad/8874ed25781e7dd561c6d75fb4a7becf10a18d75b074f25b845cc334f781/pyrefly-0.62.0.tar.gz", hash = "sha256:da1fbe1075dc1e6c8e3134e9370b0a0e7a296061d782cca5bf83dbb8e4c10d7c", size = 5537672, upload-time = "2026-04-20T17:12:15.718Z" } +sdist = { url = "https://files.pythonhosted.org/packages/85/99/923622d7b52ef84e83f357b19bd08dff063ccc5f4472b003105e1f308d93/pyrefly-0.64.0.tar.gz", hash = "sha256:fbfcdb0031adadc340b6c64cb41c6094c95349ee952fe3d4c143866add829172", size = 5678516, upload-time = "2026-05-06T17:28:44.056Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1b/ea/09bd9da7d5df294db800312fb415be2fefbaa5594178e9e49f44fa071aea/pyrefly-0.62.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9d78ec4f126dee1fa76215b193b964490ce10e62a32d2787a72c51623658b803", size = 13020414, upload-time = "2026-04-20T17:11:43.617Z" }, - { url = "https://files.pythonhosted.org/packages/4b/f0/f84afac4f220c4c8c801b779ee2ff28ad3f7731f4283c2e1b6ee9012e8c2/pyrefly-0.62.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2a41a34902d20756264486f9e309f22633d100261bd960feea6e858a098d985d", size = 12515659, upload-time = "2026-04-20T17:11:46.59Z" }, - { url = "https://files.pythonhosted.org/packages/40/0b/620c39cefa9ae1b25ee7a2da9d8d3c278b095649cb8435c5e01ea64f7c17/pyrefly-0.62.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4666c6b65aea662e5f77b64dc91c091b7ea5cede6aa66c0f4cbae26480403583", size = 36228332, upload-time = "2026-04-20T17:11:50.523Z" }, - { url = "https://files.pythonhosted.org/packages/2d/fb/47b8b76438c12761e509a3666cd5a99d4af7f21976ba8385feb475cbfe30/pyrefly-0.62.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1aefab798f47d37c13ded791192fee9b39a6d2b12e31f38ae06a1f80c4b26e22", size = 38995741, upload-time = "2026-04-20T17:11:54.702Z" }, - { url = "https://files.pythonhosted.org/packages/55/d2/03bd17673f61147cd5609cd7d6a1455eeccc17a07a7e141ed9931b0c42c0/pyrefly-0.62.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8fa986b50d56740da1d7ae7c660a505143cb9d286fa98cc7e5f4a759cc6eaa5d", size = 37205321, upload-time = "2026-04-20T17:11:58.9Z" }, - { url = "https://files.pythonhosted.org/packages/75/14/20ba7b7f2d182f9b7c1e24a3041dac9b5730ae28cfe1614a2c98706650f2/pyrefly-0.62.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32e9b175805c82ffb967e4708f4910bace7e1a12736907380cc9afdbaabb0efb", size = 41786834, upload-time = "2026-04-20T17:12:03.221Z" }, - { url = "https://files.pythonhosted.org/packages/fa/c8/5a7ba88c4fa1b5090d877f70fa1b742b921b9e7d8d3f4b6b9b1ba1820850/pyrefly-0.62.0-py3-none-win32.whl", hash = "sha256:1cd98edc20cab5bac8016c9220ee66080e39bd22e7f0e9bb3e2c4e2be1555eed", size = 12010170, upload-time = "2026-04-20T17:12:06.791Z" }, - { url = "https://files.pythonhosted.org/packages/2e/78/d8f810de010ff2ed594c630c724fd817ef430963249e9eb396ce8f785e9d/pyrefly-0.62.0-py3-none-win_amd64.whl", hash = "sha256:6994f8ee7d6720325ee52207fbdaca98a799a1efe462bb5ba90c47160f7f3e6e", size = 12861816, upload-time = "2026-04-20T17:12:09.689Z" }, - { url = "https://files.pythonhosted.org/packages/c7/a9/ac824ef6a3f50b7c0ec5974471f8f2cb205cd1edd53a5abbcf7ba37feb5d/pyrefly-0.62.0-py3-none-win_arm64.whl", hash = "sha256:362a5d47a5ac5aaa5258091e878a1759ff8b687d8cf462af1c516144f7b0108a", size = 12352977, upload-time = "2026-04-20T17:12:12.736Z" }, + { url = "https://files.pythonhosted.org/packages/b8/1c/b001b7e84a811dbb3c85e31bd4bfc3edfa3c94438140cd1d6e8c06b7c1df/pyrefly-0.64.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:683b317d8d0e815fb2ad75b7e0fa6c15eed5be4bcbc407dc13312984da3a9c47", size = 13287462, upload-time = "2026-05-06T17:28:19.169Z" }, + { url = "https://files.pythonhosted.org/packages/89/02/1e6fcd311bd7c24aaccc0afb998d584e1fa6c370e1428b4b091103760efe/pyrefly-0.64.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:96913cc4f066a7bd008b9dba8e3951234e92bb8a3a2cb1aea0e274fd2a444c55", size = 12777104, upload-time = "2026-05-06T17:28:22.047Z" }, + { url = "https://files.pythonhosted.org/packages/d6/2b/3f347b8d97c9065d6ace14a22591c8d91e64610e74e0d4f214b3025ebcf7/pyrefly-0.64.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2ae557e1b6a6a5bda844806cae10b212cf84ea786ece10d55083a0321ee1705", size = 37064924, upload-time = "2026-05-06T17:28:24.743Z" }, + { url = "https://files.pythonhosted.org/packages/73/dd/0b40175e930a96139a8e9f62a8e1db7f9a5e9df8e6cef08bf280affcb05e/pyrefly-0.64.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d062ac1744346efacd7df23c6bbff662ad29ed495923cb59ede656a306355655", size = 39719832, upload-time = "2026-05-06T17:28:28.042Z" }, + { url = "https://files.pythonhosted.org/packages/9a/4b/0afb4ad02eb67ddb299ff3f7108ceb307e520578b00e900d07f2371423ca/pyrefly-0.64.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6850b305d45121911fbe25ad56497d2e887b387ea50644ba15a8ad2a8cf855f4", size = 37861666, upload-time = "2026-05-06T17:28:31.234Z" }, + { url = "https://files.pythonhosted.org/packages/e5/1b/f5390f8678433708288afab13f043ddd021a55dba3f665360d2c9396ee04/pyrefly-0.64.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a259925620a84fe87cd30a82643ec524eeef631f0c4ec5af81a21e006c2f5b1", size = 42634235, upload-time = "2026-05-06T17:28:34.405Z" }, + { url = "https://files.pythonhosted.org/packages/47/f7/4b66934e375dde3e4d75373b1a94eb7e7c0c0c788e94267641a223930180/pyrefly-0.64.0-py3-none-win32.whl", hash = "sha256:20317f6dd97e22bc508b8dbc537e59b0ab58e384113ee61920c87ed1a6a12f62", size = 12213388, upload-time = "2026-05-06T17:28:37.146Z" }, + { url = "https://files.pythonhosted.org/packages/0a/15/653523d99795041a1be6dadf7a73225317cb2aae4b21e6df57edbce807f0/pyrefly-0.64.0-py3-none-win_amd64.whl", hash = "sha256:e88fc6a83add9b7c2224be0f74df1b0db10b3af856ae30e4e0a90ba3644c712f", size = 13136719, upload-time = "2026-05-06T17:28:39.767Z" }, + { url = "https://files.pythonhosted.org/packages/50/bb/9ea1c26b511b38a3e1eefc1bd3de7d3f65b2bbfdb59295f3244f61564a81/pyrefly-0.64.0-py3-none-win_arm64.whl", hash = "sha256:73744bd95e836abda0d08e9cdcf008142090ae0124c8f8ff477c944b60c0343c", size = 12526050, upload-time = "2026-05-06T17:28:42.077Z" }, ] [[package]] @@ -5914,14 +5914,14 @@ wheels = [ [[package]] name = "s3transfer" -version = "0.16.0" +version = "0.17.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/05/04/74127fc843314818edfa81b5540e26dd537353b123a4edc563109d8f17dd/s3transfer-0.16.0.tar.gz", hash = "sha256:8e990f13268025792229cd52fa10cb7163744bf56e719e0b9cb925ab79abf920", size = 153827, upload-time = "2025-12-01T02:30:59.114Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9b/ec/7c692cde9125b77e84b307354d4fb705f98b8ccad59a036d5957ca75bfc3/s3transfer-0.17.0.tar.gz", hash = "sha256:9edeb6d1c3c2f89d6050348548834ad8289610d886e5bf7b7207728bd43ce33a", size = 155337, upload-time = "2026-04-29T22:07:36.33Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl", hash = "sha256:18e25d66fed509e3868dc1572b3f427ff947dd2c56f844a5bf09481ad3f3b2fe", size = 86830, upload-time = "2025-12-01T02:30:57.729Z" }, + { url = "https://files.pythonhosted.org/packages/87/72/c6c32d2b657fa3dad1de340254e14390b1e334ce38268b7ad51abda3c8c2/s3transfer-0.17.0-py3-none-any.whl", hash = "sha256:ce3801712acf4ad3e89fb9990df97b4972e93f4b3b0004d214be5bce12814c20", size = 86811, upload-time = "2026-04-29T22:07:34.966Z" }, ] [[package]] @@ -6585,23 +6585,23 @@ wheels = [ [[package]] name = "types-cachetools" -version = "6.2.0.20260408" +version = "7.0.0.20260503" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ec/61/475b0e8f4a92e5e33affcc6f4e6344c6dee540824021d22f695ea170da63/types_cachetools-6.2.0.20260408.tar.gz", hash = "sha256:0d8ae2dd5ba0b4cfe6a55c34396dd0415f1be07d0033d84781cdc4ed9c2ebc6b", size = 9854, upload-time = "2026-04-08T04:31:49.665Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/57/5d3b8b3e66b002911ec1274e87f904eeee1d843c8713d95476c25c29cf31/types_cachetools-7.0.0.20260503.tar.gz", hash = "sha256:dfa4dcdf453f397dfc6d69fc0a57423ac1f248393f70aa56b5d05fac2df7a96c", size = 10033, upload-time = "2026-05-03T05:19:54.128Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/7d/579f50f4f004ee93c7d1baa95339591cac1fe02f4e3fb8fc0f900ee4a80f/types_cachetools-6.2.0.20260408-py3-none-any.whl", hash = "sha256:470e0b274737feae74beed3d764885bf4664002ecc393fba3778846b13ce92cb", size = 9350, upload-time = "2026-04-08T04:31:48.826Z" }, + { url = "https://files.pythonhosted.org/packages/3d/a8/84562723d9a3572e0851d82bdea6bed5a7dc033c6bd648f492c76b8c4ac8/types_cachetools-7.0.0.20260503-py3-none-any.whl", hash = "sha256:011b4fe0e85ef05c4a2471a4fda40254a78746b501cc1727359233872bb3a4e9", size = 9493, upload-time = "2026-05-03T05:19:53.124Z" }, ] [[package]] name = "types-cffi" -version = "2.0.0.20260408" +version = "2.0.0.20260429" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "types-setuptools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/64/67/eb4ef3408fdc0b4e5af38b30c0e6ad4663b41bdae9fb85a9f09a8db61a99/types_cffi-2.0.0.20260408.tar.gz", hash = "sha256:aa8b9c456ab715c079fc655929811f21f331bfb940f4a821987c581bf4e36230", size = 17541, upload-time = "2026-04-08T04:36:03.918Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0c/7d/56b9be8b0f9dfbffb7c73e248aacf178693ff3c6cf765b77c43a1e886e04/types_cffi-2.0.0.20260429.tar.gz", hash = "sha256:afe7d9777a2921139623af0b94647637a5bd0b938b77ec125e5e5e068a1727bd", size = 17562, upload-time = "2026-04-29T05:16:43.29Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/a3/7fbd93ededcc7c77e9e5948b9794161733ebdbf618a27965b1bea0e728a4/types_cffi-2.0.0.20260408-py3-none-any.whl", hash = "sha256:68bd296742b4ff7c0afe3547f50bd0acc55416ecf322ffefd2b7344ef6388a42", size = 20101, upload-time = "2026-04-08T04:36:02.995Z" }, + { url = "https://files.pythonhosted.org/packages/b8/2c/79fa47a70d534f63a54b6d22e28cc842f8c6d9ebec93048355b0020bc7a9/types_cffi-2.0.0.20260429-py3-none-any.whl", hash = "sha256:6a4237bfdbd50e4d0726929070d8b9983bde541726a5a6fe0e8e24e78c1b3826", size = 20103, upload-time = "2026-04-29T05:16:42.155Z" }, ] [[package]] @@ -6680,11 +6680,11 @@ wheels = [ [[package]] name = "types-greenlet" -version = "3.4.0.20260409" +version = "3.5.0.20260428" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/27/a6/668751bc864efe820e1eb12c2a77f9e62537f433cc002e483ad01badb04b/types_greenlet-3.4.0.20260409.tar.gz", hash = "sha256:81d2cf628934a16856bb9e54136def8de5356e934f0ad5d5474f219a0c5cb205", size = 8976, upload-time = "2026-04-09T04:22:31.693Z" } +sdist = { url = "https://files.pythonhosted.org/packages/79/50/d255c0e068679d7b9441d9408424ddf9e1f35620548e121003b3660af526/types_greenlet-3.5.0.20260428.tar.gz", hash = "sha256:6c188f5e9c5775d50bd00780a3eb1fb3cde17c396cf9703e3d417936e9e7a082", size = 9003, upload-time = "2026-04-28T05:19:43.062Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4f/3f/c8a4d8782f78fccb4b5fe91c5eae2efce6648072754bc7096b1e3b5407ad/types_greenlet-3.4.0.20260409-py3-none-any.whl", hash = "sha256:cbceadb4594eccd95b57b3f7fa8a9b851488f5e6c05026f4a3db9aac02ec8333", size = 8812, upload-time = "2026-04-09T04:22:30.734Z" }, + { url = "https://files.pythonhosted.org/packages/30/e5/5ff280f02392ced53cb5e866b660b492b4245b1395a61e57d2a6dc02977b/types_greenlet-3.5.0.20260428-py3-none-any.whl", hash = "sha256:7b0f23ce84ee93474d4aa8058920f0578181e11431be92ce9a4ad4123de2c41b", size = 8809, upload-time = "2026-04-28T05:19:41.976Z" }, ] [[package]] @@ -6764,11 +6764,11 @@ wheels = [ [[package]] name = "types-protobuf" -version = "7.34.1.20260408" +version = "7.34.1.20260503" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5b/b1/4521e68c2cc17703d80eb42796751345376dd4c706f84007ef5e7c707774/types_protobuf-7.34.1.20260408.tar.gz", hash = "sha256:e2c0a0430e08c75b52671a6f0035abfdcc791aad12af16274282de1b721758ab", size = 68835, upload-time = "2026-04-08T04:26:43.613Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a0/31/87969cb3e62287bde7598b78b3c098d2873d54f5fb5a7cfbcaa73b8c965e/types_protobuf-7.34.1.20260503.tar.gz", hash = "sha256:effbc819aa17e02448dde99f089c6794662d66f4b2797e922f185ffe0b24e766", size = 68830, upload-time = "2026-05-03T05:19:50.739Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/b5/0bc9874d89c58fb0ce851e150055ce732d254dbb10b06becbc7635d0d635/types_protobuf-7.34.1.20260408-py3-none-any.whl", hash = "sha256:ebbcd4e27b145aef6a59bc0cb6c013b3528151c1ba5e7f7337aeee355d276a5e", size = 86012, upload-time = "2026-04-08T04:26:42.566Z" }, + { url = "https://files.pythonhosted.org/packages/f9/67/a33fb18090a927794a5ee4b1a30730b528ace0dad6b18932540d21258184/types_protobuf-7.34.1.20260503-py3-none-any.whl", hash = "sha256:75fd66121d56785c91828b8bf7b511f39ba847f11e682573e41847f01e9cd1de", size = 86019, upload-time = "2026-05-03T05:19:49.486Z" }, ] [[package]] diff --git a/docker/.env.default b/docker/.env.default new file mode 100644 index 0000000000..6f6683b9f5 --- /dev/null +++ b/docker/.env.default @@ -0,0 +1,51 @@ +# ------------------------------------------------------------------ +# Minimal defaults for Docker Compose deployments. +# +# Keep local changes in .env. Use .env.example as the full reference +# for advanced and service-specific settings. +# ------------------------------------------------------------------ + +# Public URLs used when Dify generates links. Change these together when +# exposing Dify under another hostname, IP address, or port. +CONSOLE_WEB_URL=http://localhost +SERVICE_API_URL=http://localhost +APP_WEB_URL=http://localhost +FILES_URL=http://localhost +INTERNAL_FILES_URL=http://api:5001 +TRIGGER_URL=http://localhost +ENDPOINT_URL_TEMPLATE=http://localhost/e/{hook_id} +NEXT_PUBLIC_SOCKET_URL=ws://localhost +EXPOSE_PLUGIN_DEBUGGING_HOST=localhost +EXPOSE_PLUGIN_DEBUGGING_PORT=5003 + +# Built-in metadata database defaults. +DB_TYPE=postgresql +DB_USERNAME=postgres +DB_PASSWORD=difyai123456 +DB_HOST=db_postgres +DB_PORT=5432 +DB_DATABASE=dify + +# Built-in Redis defaults. +REDIS_HOST=redis +REDIS_PORT=6379 +REDIS_PASSWORD=difyai123456 + +# Default file storage. +STORAGE_TYPE=opendal +OPENDAL_SCHEME=fs +OPENDAL_FS_ROOT=storage + +# Default vector database. +VECTOR_STORE=weaviate + +# Internal service authentication. Paired values must match. +PLUGIN_DAEMON_KEY=lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi +PLUGIN_DIFY_INNER_API_KEY=QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1 + +# Host ports. +EXPOSE_NGINX_PORT=80 +EXPOSE_NGINX_SSL_PORT=443 + +# Docker Compose profiles for bundled services. +COMPOSE_PROFILES=${VECTOR_STORE:-weaviate},${DB_TYPE:-postgresql} diff --git a/docker/.env.example b/docker/.env.example index 29741474fa..122228cdd1 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -1003,7 +1003,7 @@ NOTION_INTERNAL_SECRET= # ------------------------------ # Mail type, support: resend, smtp, sendgrid -MAIL_TYPE=resend +MAIL_TYPE= # Default send from email address, if not specified # If using SendGrid, use the 'from' field for authentication if necessary. @@ -1011,7 +1011,7 @@ MAIL_DEFAULT_SEND_FROM= # API-Key for the Resend email provider, used when MAIL_TYPE is `resend`. RESEND_API_URL=https://api.resend.com -RESEND_API_KEY=your-resend-api-key +RESEND_API_KEY= # SMTP server configuration, used when MAIL_TYPE is `smtp` @@ -1359,10 +1359,10 @@ NGINX_ENABLE_CERTBOT_CHALLENGE=false # ------------------------------ # Email address (required to get certificates from Let's Encrypt) -CERTBOT_EMAIL=your_email@example.com +CERTBOT_EMAIL= # Domain name -CERTBOT_DOMAIN=your_domain.com +CERTBOT_DOMAIN= # certbot command options # i.e: --force-renewal --dry-run --test-cert --debug diff --git a/docker/README.md b/docker/README.md index 3130fa9886..3a7f4c2ad5 100644 --- a/docker/README.md +++ b/docker/README.md @@ -7,28 +7,28 @@ Welcome to the new `docker` directory for deploying Dify using Docker Compose. T - **Certbot Container**: `docker-compose.yaml` now contains `certbot` for managing SSL certificates. This container automatically renews certificates and ensures secure HTTPS connections.\ For more information, refer `docker/certbot/README.md`. -- **Persistent Environment Variables**: Environment variables are now managed through a `.env` file, ensuring that your configurations persist across deployments. +- **Persistent Environment Variables**: Default environment variables are managed through `.env.default`, while local overrides are stored in `.env`, ensuring that your configurations persist across deployments. > What is `.env`?

- > The `.env` file is a crucial component in Docker and Docker Compose environments, serving as a centralized configuration file where you can define environment variables that are accessible to the containers at runtime. This file simplifies the management of environment settings across different stages of development, testing, and production, providing consistency and ease of configuration to deployments. + > The `.env` file is a local override file. Keep it small by adding only the values that differ from `.env.default`. Use `.env.example` as the full reference when you need advanced configuration. - **Unified Vector Database Services**: All vector database services are now managed from a single Docker Compose file `docker-compose.yaml`. You can switch between different vector databases by setting the `VECTOR_STORE` environment variable in your `.env` file. -- **Mandatory .env File**: A `.env` file is now required to run `docker compose up`. This file is crucial for configuring your deployment and for any custom settings to persist through upgrades. +- **Local .env Overrides**: The `dify-compose` and `dify-compose.ps1` wrappers create `.env` if it is missing and generate a persistent `SECRET_KEY` for this deployment. ### How to Deploy Dify with `docker-compose.yaml` 1. **Prerequisites**: Ensure Docker and Docker Compose are installed on your system. 1. **Environment Setup**: - Navigate to the `docker` directory. - - Copy the `.env.example` file to a new file named `.env` by running `cp .env.example .env`. - - Customize the `.env` file as needed. Refer to the `.env.example` file for detailed configuration options. - - **Optional (Recommended for upgrades)**: - You may use the environment synchronization tool to help keep your `.env` file aligned with the latest `.env.example` updates, while preserving your custom settings. - This is especially useful when upgrading Dify or managing a large, customized `.env` file. + - No copy step is required. The `dify-compose` wrappers create `.env` if it is missing and write a generated `SECRET_KEY` to it. + - When prompted on first run, press Enter to use the default deployment, or answer `y` to stop and edit `.env` first. + - Customize `.env` only when you need to override defaults from `.env.default`. Refer to `.env.example` for the full list of available variables. + - **Optional (for advanced deployments)**: + If you maintain a full `.env` file copied from `.env.example`, you may use the environment synchronization tool to keep it aligned with the latest `.env.example` updates while preserving your custom settings. See the [Environment Variables Synchronization](#environment-variables-synchronization) section below. 1. **Running the Services**: - - Execute `docker compose up` from the `docker` directory to start the services. + - Execute `./dify-compose up -d` from the `docker` directory to start the services. On Windows PowerShell, run `.\dify-compose.ps1 up -d`. - To specify a vector database, set the `VECTOR_STORE` variable in your `.env` file to your desired vector database service, such as `milvus`, `weaviate`, or `opensearch`. 1. **SSL Certificate Setup**: - Refer `docker/certbot/README.md` to set up SSL certificates using Certbot. @@ -58,7 +58,13 @@ For users migrating from the `docker-legacy` setup: 1. **Data Migration**: - Ensure that data from services like databases and caches is backed up and migrated appropriately to the new structure if necessary. -### Overview of `.env` +### Overview of `.env.default`, `.env`, and `.env.example` + +- `.env.default` contains the minimal default configuration for Docker Compose deployments. +- `.env` contains the generated `SECRET_KEY` plus any local overrides. +- `.env.example` is the full reference for advanced configuration. + +The `dify-compose` wrappers merge `.env.default` and `.env` into a temporary environment file, append paired internal service keys when needed, and remove the temporary file after Docker Compose starts. #### Key Modules and Customization @@ -118,9 +124,11 @@ The `.env.example` file provided in the Docker setup is extensive and covers a w ### Environment Variables Synchronization -When upgrading Dify or pulling the latest changes, new environment variables may be introduced in `.env.example`. +When upgrading Dify or pulling the latest changes, new environment variables may be introduced in `.env.default` or `.env.example`. -To help keep your existing `.env` file up to date **without losing your custom values**, an optional environment variables synchronization tool is provided. +If you use the default override-only workflow, review `.env.default` and add only the values you need to override to `.env`. + +If you maintain a full `.env` file copied from `.env.example`, an optional environment variables synchronization tool is provided. > This tool performs a **one-way synchronization** from `.env.example` to `.env`. > Existing values in `.env` are never overwritten automatically. @@ -143,9 +151,9 @@ Before synchronization, the current `.env` file is saved to the `env-backup/` di **When to use** -- After upgrading Dify to a newer version +- After upgrading Dify to a newer version with a full `.env` file - When `.env.example` has been updated with new environment variables -- When managing a large or heavily customized `.env` file +- When managing a large or heavily customized `.env` file copied from `.env.example` **Usage** diff --git a/docker/dify-compose b/docker/dify-compose new file mode 100755 index 0000000000..16bbd6b538 --- /dev/null +++ b/docker/dify-compose @@ -0,0 +1,334 @@ +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +DEFAULT_ENV_FILE=".env.default" +USER_ENV_FILE=".env" + +log() { + printf '%s\n' "$*" >&2 +} + +die() { + printf 'Error: %s\n' "$*" >&2 + exit 1 +} + +detect_compose() { + if docker compose version >/dev/null 2>&1; then + COMPOSE_CMD=(docker compose) + return + fi + + if command -v docker-compose >/dev/null 2>&1; then + COMPOSE_CMD=(docker-compose) + return + fi + + die "Docker Compose is not available. Install Docker Compose, then run this command again." +} + +generate_secret_key() { + if command -v openssl >/dev/null 2>&1; then + openssl rand -base64 42 + return + fi + + if command -v dd >/dev/null 2>&1 && command -v base64 >/dev/null 2>&1; then + dd if=/dev/urandom bs=42 count=1 2>/dev/null | base64 | tr -d '\n' + printf '\n' + return + fi + + return 1 +} + +ensure_env_files() { + [[ -f "$DEFAULT_ENV_FILE" ]] || die "$DEFAULT_ENV_FILE is missing." + + if [[ -f "$USER_ENV_FILE" ]]; then + return + fi + + : >"$USER_ENV_FILE" + + if [[ ! -t 0 ]]; then + log "Created $USER_ENV_FILE for local overrides." + return + fi + + printf 'Created %s for local overrides.\n' "$USER_ENV_FILE" + printf 'Do you need a custom deployment now? (Most users can press Enter to skip.) [y/N] ' + read -r answer + + case "${answer:-}" in + y | Y | yes | YES | Yes) + cat <<'EOF' +Edit .env with the settings you want to override, using .env.example as the full reference. +Run ./dify-compose up -d again when you are ready. +EOF + exit 0 + ;; + esac +} + +user_env_value() { + local key="$1" + awk -F= -v target="$key" ' + /^[[:space:]]*#/ || !/=/{ next } + { + key = $1 + gsub(/^[[:space:]]+|[[:space:]]+$/, "", key) + if (key == target) { + value = substr($0, index($0, "=") + 1) + gsub(/^[[:space:]]+|[[:space:]]+$/, "", value) + if ((value ~ /^".*"$/) || (value ~ /^'\''.*'\''$/)) { + value = substr(value, 2, length(value) - 2) + } + result = value + } + } + END { print result } + ' "$USER_ENV_FILE" +} + +set_user_env_value() { + local key="$1" + local value="$2" + local temp_file + + temp_file="$(mktemp "${TMPDIR:-/tmp}/dify-env.XXXXXX")" + awk -F= -v target="$key" -v replacement="$key=$value" ' + BEGIN { replaced = 0 } + /^[[:space:]]*#/ || !/=/{ print; next } + { + key = $1 + gsub(/^[[:space:]]+|[[:space:]]+$/, "", key) + if (key == target) { + if (!replaced) { + print replacement + replaced = 1 + } + next + } + print + } + END { + if (!replaced) { + print replacement + } + } + ' "$USER_ENV_FILE" >"$temp_file" + mv "$temp_file" "$USER_ENV_FILE" +} + +ensure_secret_key() { + local current_secret_key + local secret_key + + current_secret_key="$(user_env_value SECRET_KEY)" + if [[ -n "$current_secret_key" ]]; then + return + fi + + secret_key="$(generate_secret_key)" || die "Unable to generate SECRET_KEY. Install openssl or configure SECRET_KEY in .env." + set_user_env_value SECRET_KEY "$secret_key" + log "Generated SECRET_KEY in $USER_ENV_FILE." +} + +env_value() { + local key="$1" + awk -F= -v target="$key" ' + /^[[:space:]]*#/ || !/=/{ next } + { + key = $1 + gsub(/^[[:space:]]+|[[:space:]]+$/, "", key) + if (key == target) { + value = substr($0, index($0, "=") + 1) + gsub(/^[[:space:]]+|[[:space:]]+$/, "", value) + if ((value ~ /^".*"$/) || (value ~ /^'\''.*'\''$/)) { + value = substr(value, 2, length(value) - 2) + } + result = value + } + } + END { print result } + ' "$DEFAULT_ENV_FILE" "$USER_ENV_FILE" +} + +user_overrides() { + local key="$1" + grep -Eq "^[[:space:]]*${key}[[:space:]]*=" "$USER_ENV_FILE" +} + +write_merged_env() { + awk ' + function trim(s) { + sub(/^[[:space:]]+/, "", s) + sub(/[[:space:]]+$/, "", s) + return s + } + + /^[[:space:]]*#/ || !/=/{ next } + + { + key = $0 + sub(/=.*/, "", key) + key = trim(key) + if (key == "") { + next + } + + value = substr($0, index($0, "=") + 1) + value = trim(value) + + if (!(key in seen)) { + order[++count] = key + seen[key] = 1 + } + + values[key] = value + } + + END { + for (i = 1; i <= count; i++) { + key = order[i] + print key "=" values[key] + } + } + ' "$DEFAULT_ENV_FILE" "$USER_ENV_FILE" >"$MERGED_ENV_FILE" +} + +set_merged_env_value() { + local key="$1" + local value="$2" + local temp_file + + temp_file="$(mktemp "${TMPDIR:-/tmp}/dify-compose-env.XXXXXX")" + awk -F= -v target="$key" -v replacement="$key=$value" ' + BEGIN { replaced = 0 } + /^[[:space:]]*#/ || !/=/{ print; next } + { + key = $1 + gsub(/^[[:space:]]+|[[:space:]]+$/, "", key) + if (key == target) { + if (!replaced) { + print replacement + replaced = 1 + } + next + } + print + } + END { + if (!replaced) { + print replacement + } + } + ' "$MERGED_ENV_FILE" >"$temp_file" + mv "$temp_file" "$MERGED_ENV_FILE" +} + +set_if_not_overridden() { + local key="$1" + local value="$2" + + if user_overrides "$key"; then + return + fi + + set_merged_env_value "$key" "$value" +} + +metadata_db_host() { + case "$1" in + mysql) printf 'db_mysql' ;; + postgresql | '') printf 'db_postgres' ;; + *) printf '%s' "$(env_value DB_HOST)" ;; + esac +} + +metadata_db_port() { + case "$1" in + mysql) printf '3306' ;; + postgresql | '') printf '5432' ;; + *) printf '%s' "$(env_value DB_PORT)" ;; + esac +} + +metadata_db_user() { + case "$1" in + mysql) printf 'root' ;; + postgresql | '') printf 'postgres' ;; + *) printf '%s' "$(env_value DB_USERNAME)" ;; + esac +} + +build_merged_env() { + MERGED_ENV_FILE="$(mktemp "${TMPDIR:-/tmp}/dify-compose.XXXXXX")" + trap 'rm -f "$MERGED_ENV_FILE"' EXIT + + write_merged_env + + local db_type + local redis_host + local redis_port + local redis_username + local redis_password + local redis_auth + local code_execution_api_key + local weaviate_api_key + + db_type="$(env_value DB_TYPE)" + + set_if_not_overridden DB_HOST "$(metadata_db_host "$db_type")" + set_if_not_overridden DB_PORT "$(metadata_db_port "$db_type")" + set_if_not_overridden DB_USERNAME "$(metadata_db_user "$db_type")" + + if ! user_overrides CELERY_BROKER_URL; then + redis_host="$(env_value REDIS_HOST)" + redis_port="$(env_value REDIS_PORT)" + redis_username="$(env_value REDIS_USERNAME)" + redis_password="$(env_value REDIS_PASSWORD)" + redis_auth="" + + if [[ -n "$redis_username" && -n "$redis_password" ]]; then + redis_auth="${redis_username}:${redis_password}@" + elif [[ -n "$redis_password" ]]; then + redis_auth=":${redis_password}@" + elif [[ -n "$redis_username" ]]; then + redis_auth="${redis_username}@" + fi + + set_merged_env_value CELERY_BROKER_URL "redis://${redis_auth}${redis_host:-redis}:${redis_port:-6379}/1" + fi + + if ! user_overrides SANDBOX_API_KEY; then + code_execution_api_key="$(env_value CODE_EXECUTION_API_KEY)" + set_if_not_overridden SANDBOX_API_KEY "${code_execution_api_key:-dify-sandbox}" + fi + + if ! user_overrides WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS; then + weaviate_api_key="$(env_value WEAVIATE_API_KEY)" + set_if_not_overridden WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS \ + "${weaviate_api_key:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih}" + fi +} + +main() { + detect_compose + ensure_env_files + ensure_secret_key + build_merged_env + + if [[ "$#" -eq 0 ]]; then + set -- up -d + fi + + "${COMPOSE_CMD[@]}" --env-file "$MERGED_ENV_FILE" "$@" +} + +main "$@" diff --git a/docker/dify-compose.ps1 b/docker/dify-compose.ps1 new file mode 100644 index 0000000000..851f8b76fe --- /dev/null +++ b/docker/dify-compose.ps1 @@ -0,0 +1,317 @@ +$ErrorActionPreference = "Stop" +Set-StrictMode -Version Latest + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +Set-Location $ScriptDir + +$DefaultEnvFile = ".env.default" +$UserEnvFile = ".env" +$MergedEnvFile = $null +$Utf8NoBom = New-Object System.Text.UTF8Encoding -ArgumentList $false + +function Write-Info { + param([string]$Message) + [Console]::Error.WriteLine($Message) +} + +function Fail { + param([string]$Message) + [Console]::Error.WriteLine("Error: $Message") + exit 1 +} + +function Test-CommandSuccess { + param([string[]]$Command) + + try { + $Executable = $Command[0] + $CommandArgs = @() + if ($Command.Length -gt 1) { + $CommandArgs = @($Command[1..($Command.Length - 1)]) + } + + & $Executable @CommandArgs *> $null + return $LASTEXITCODE -eq 0 + } + catch { + return $false + } +} + +function Get-ComposeCommand { + if (Test-CommandSuccess @("docker", "compose", "version")) { + return @("docker", "compose") + } + + if ((Get-Command "docker-compose" -ErrorAction SilentlyContinue) -and (Test-CommandSuccess @("docker-compose", "version"))) { + return @("docker-compose") + } + + Fail "Docker Compose is not available. Install Docker Compose, then run this command again." +} + +function New-SecretKey { + $Bytes = New-Object byte[] 42 + $Generator = [System.Security.Cryptography.RandomNumberGenerator]::Create() + + try { + $Generator.GetBytes($Bytes) + } + finally { + $Generator.Dispose() + } + + return [Convert]::ToBase64String($Bytes) +} + +function Ensure-EnvFiles { + if (-not (Test-Path $DefaultEnvFile -PathType Leaf)) { + Fail "$DefaultEnvFile is missing." + } + + if (Test-Path $UserEnvFile -PathType Leaf) { + return + } + + New-Item -ItemType File -Path $UserEnvFile | Out-Null + + if ([Console]::IsInputRedirected) { + Write-Info "Created $UserEnvFile for local overrides." + return + } + + Write-Info "Created $UserEnvFile for local overrides." + $Answer = Read-Host "Do you need a custom deployment now? (Most users can press Enter to skip.) [y/N]" + + if ($Answer -match "^(y|yes)$") { + Write-Output "Edit .env with the settings you want to override, using .env.example as the full reference." + Write-Output "Run .\dify-compose.ps1 up -d again when you are ready." + exit 0 + } +} + +function Read-EnvFile { + param([string]$Path) + + $Values = [ordered]@{} + + if (-not (Test-Path $Path -PathType Leaf)) { + return $Values + } + + foreach ($Line in Get-Content -Path $Path) { + if ($Line -match "^\s*#" -or $Line -notmatch "=") { + continue + } + + $SeparatorIndex = $Line.IndexOf("=") + $Key = $Line.Substring(0, $SeparatorIndex).Trim() + $Value = $Line.Substring($SeparatorIndex + 1).Trim() + + if (($Value.StartsWith('"') -and $Value.EndsWith('"')) -or ($Value.StartsWith("'") -and $Value.EndsWith("'"))) { + $Value = $Value.Substring(1, $Value.Length - 2) + } + + if ($Key.Length -gt 0) { + $Values[$Key] = $Value + } + } + + return $Values +} + +function Set-UserEnvValue { + param( + [string]$Key, + [string]$Value + ) + + $Path = [string](Resolve-Path $UserEnvFile) + $Lines = [System.IO.File]::ReadAllLines($Path, [System.Text.Encoding]::UTF8) + $Output = New-Object System.Collections.Generic.List[string] + $Replaced = $false + + foreach ($Line in $Lines) { + if ($Line -match "^\s*#" -or $Line -notmatch "=") { + $Output.Add($Line) + continue + } + + $SeparatorIndex = $Line.IndexOf("=") + $CurrentKey = $Line.Substring(0, $SeparatorIndex).Trim() + + if ($CurrentKey -eq $Key) { + if (-not $Replaced) { + $Output.Add("$Key=$Value") + $Replaced = $true + } + continue + } + + $Output.Add($Line) + } + + if (-not $Replaced) { + $Output.Add("$Key=$Value") + } + + [System.IO.File]::WriteAllLines($Path, $Output, $Utf8NoBom) +} + +function Ensure-SecretKey { + $Values = Read-EnvFile $UserEnvFile + + if ($Values.Contains("SECRET_KEY") -and $Values["SECRET_KEY"]) { + return + } + + Set-UserEnvValue "SECRET_KEY" (New-SecretKey) + Write-Info "Generated SECRET_KEY in $UserEnvFile." +} + +function Merge-EnvValues { + $Values = [ordered]@{} + + foreach ($Entry in (Read-EnvFile $DefaultEnvFile).GetEnumerator()) { + $Values[$Entry.Key] = $Entry.Value + } + + foreach ($Entry in (Read-EnvFile $UserEnvFile).GetEnumerator()) { + $Values[$Entry.Key] = $Entry.Value + } + + return $Values +} + +function User-Overrides { + param([string]$Key) + + if (-not (Test-Path $UserEnvFile -PathType Leaf)) { + return $false + } + + return [bool](Select-String -Path $UserEnvFile -Pattern "^\s*$([regex]::Escape($Key))\s*=" -Quiet) +} + +function Metadata-DbHost { + param([string]$DbType, $Values) + + switch ($DbType) { + "mysql" { return "db_mysql" } + "postgresql" { return "db_postgres" } + "" { return "db_postgres" } + default { return $Values["DB_HOST"] } + } +} + +function Metadata-DbPort { + param([string]$DbType, $Values) + + switch ($DbType) { + "mysql" { return "3306" } + "postgresql" { return "5432" } + "" { return "5432" } + default { return $Values["DB_PORT"] } + } +} + +function Metadata-DbUser { + param([string]$DbType, $Values) + + switch ($DbType) { + "mysql" { return "root" } + "postgresql" { return "postgres" } + "" { return "postgres" } + default { return $Values["DB_USERNAME"] } + } +} + +function Write-MergedEnv { + param($Values) + + $Output = New-Object System.Collections.Generic.List[string] + + foreach ($Entry in $Values.GetEnumerator()) { + $Output.Add("$($Entry.Key)=$($Entry.Value)") + } + + [System.IO.File]::WriteAllLines($MergedEnvFile, $Output, $Utf8NoBom) +} + +function Build-MergedEnv { + $Values = Merge-EnvValues + $script:MergedEnvFile = [System.IO.Path]::GetTempFileName() + + $DbType = if ($Values.Contains("DB_TYPE")) { $Values["DB_TYPE"] } else { "postgresql" } + + if (-not (User-Overrides "DB_HOST")) { + $Values["DB_HOST"] = Metadata-DbHost $DbType $Values + } + + if (-not (User-Overrides "DB_PORT")) { + $Values["DB_PORT"] = Metadata-DbPort $DbType $Values + } + + if (-not (User-Overrides "DB_USERNAME")) { + $Values["DB_USERNAME"] = Metadata-DbUser $DbType $Values + } + + if (-not (User-Overrides "CELERY_BROKER_URL")) { + $RedisHost = if ($Values.Contains("REDIS_HOST") -and $Values["REDIS_HOST"]) { $Values["REDIS_HOST"] } else { "redis" } + $RedisPort = if ($Values.Contains("REDIS_PORT") -and $Values["REDIS_PORT"]) { $Values["REDIS_PORT"] } else { "6379" } + $RedisUsername = if ($Values.Contains("REDIS_USERNAME")) { $Values["REDIS_USERNAME"] } else { "" } + $RedisPassword = if ($Values.Contains("REDIS_PASSWORD")) { $Values["REDIS_PASSWORD"] } else { "" } + $RedisAuth = "" + + if ($RedisUsername -and $RedisPassword) { + $RedisAuth = "${RedisUsername}:${RedisPassword}@" + } + elseif ($RedisPassword) { + $RedisAuth = ":${RedisPassword}@" + } + elseif ($RedisUsername) { + $RedisAuth = "${RedisUsername}@" + } + + $Values["CELERY_BROKER_URL"] = "redis://$RedisAuth${RedisHost}:${RedisPort}/1" + } + + if (-not (User-Overrides "SANDBOX_API_KEY")) { + $CodeExecutionApiKey = if ($Values.Contains("CODE_EXECUTION_API_KEY") -and $Values["CODE_EXECUTION_API_KEY"]) { $Values["CODE_EXECUTION_API_KEY"] } else { "dify-sandbox" } + $Values["SANDBOX_API_KEY"] = $CodeExecutionApiKey + } + + if (-not (User-Overrides "WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS")) { + $WeaviateApiKey = if ($Values.Contains("WEAVIATE_API_KEY") -and $Values["WEAVIATE_API_KEY"]) { $Values["WEAVIATE_API_KEY"] } else { "WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih" } + $Values["WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS"] = $WeaviateApiKey + } + + Write-MergedEnv $Values +} + +$ComposeCommand = Get-ComposeCommand + +try { + Ensure-EnvFiles + Ensure-SecretKey + Build-MergedEnv + + $ComposeArgs = @($args) + if ($ComposeArgs.Count -eq 0) { + $ComposeArgs = @("up", "-d") + } + + $ComposeCommandArgs = @() + if ($ComposeCommand.Length -gt 1) { + $ComposeCommandArgs = @($ComposeCommand[1..($ComposeCommand.Length - 1)]) + } + + $ComposeExecutable = $ComposeCommand[0] + & $ComposeExecutable @ComposeCommandArgs --env-file $MergedEnvFile @ComposeArgs + exit $LASTEXITCODE +} +finally { + if ($MergedEnvFile -and (Test-Path $MergedEnvFile -PathType Leaf)) { + Remove-Item -Force $MergedEnvFile + } +} diff --git a/docker/docker-compose-template.yaml b/docker/docker-compose-template.yaml index 888f96332c..b2df61ebb2 100644 --- a/docker/docker-compose-template.yaml +++ b/docker/docker-compose-template.yaml @@ -21,7 +21,7 @@ services: # API service api: - image: langgenius/dify-api:1.13.3 + image: langgenius/dify-api:1.14.0 restart: always environment: # Use the shared environment variables. @@ -69,7 +69,7 @@ services: # worker service # The Celery worker for processing all queues (dataset, workflow, mail, etc.) worker: - image: langgenius/dify-api:1.13.3 + image: langgenius/dify-api:1.14.0 restart: always environment: # Use the shared environment variables. @@ -115,7 +115,7 @@ services: # worker_beat service # Celery beat for scheduling periodic tasks. worker_beat: - image: langgenius/dify-api:1.13.3 + image: langgenius/dify-api:1.14.0 restart: always environment: # Use the shared environment variables. @@ -152,7 +152,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:1.13.3 + image: langgenius/dify-web:1.14.0 restart: always environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} @@ -170,8 +170,8 @@ services: ALLOW_UNSAFE_DATA_SCHEME: ${ALLOW_UNSAFE_DATA_SCHEME:-false} MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai} MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai} - TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-} - INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-} + TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-10} + INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-4000} LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100} MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10} MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10} @@ -268,7 +268,7 @@ services: # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.14 + image: langgenius/dify-sandbox:0.2.15 restart: always environment: # The DifySandbox configurations @@ -292,7 +292,7 @@ services: # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.5.3-local + image: langgenius/dify-plugin-daemon:0.6.0-local restart: always environment: # Use the shared environment variables. @@ -402,8 +402,8 @@ services: - ./certbot/update-cert.template.txt:/update-cert.template.txt - ./certbot/docker-entrypoint.sh:/docker-entrypoint.sh environment: - - CERTBOT_EMAIL=${CERTBOT_EMAIL} - - CERTBOT_DOMAIN=${CERTBOT_DOMAIN} + - CERTBOT_EMAIL=${CERTBOT_EMAIL:-} + - CERTBOT_DOMAIN=${CERTBOT_DOMAIN:-} - CERTBOT_OPTIONS=${CERTBOT_OPTIONS:-} entrypoint: ["/docker-entrypoint.sh"] command: ["tail", "-f", "/dev/null"] diff --git a/docker/docker-compose.middleware.yaml b/docker/docker-compose.middleware.yaml index af3d54dfb3..23c26c6695 100644 --- a/docker/docker-compose.middleware.yaml +++ b/docker/docker-compose.middleware.yaml @@ -103,7 +103,7 @@ services: # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.14 + image: langgenius/dify-sandbox:0.2.15 restart: always env_file: - ./middleware.env @@ -129,7 +129,7 @@ services: # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.5.3-local + image: langgenius/dify-plugin-daemon:0.6.0-local restart: always env_file: - ./middleware.env diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 60ba510f44..6dcab4a9fc 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -441,10 +441,10 @@ x-shared-env: &shared-api-worker-env NOTION_CLIENT_SECRET: ${NOTION_CLIENT_SECRET:-} NOTION_CLIENT_ID: ${NOTION_CLIENT_ID:-} NOTION_INTERNAL_SECRET: ${NOTION_INTERNAL_SECRET:-} - MAIL_TYPE: ${MAIL_TYPE:-resend} + MAIL_TYPE: ${MAIL_TYPE:-} MAIL_DEFAULT_SEND_FROM: ${MAIL_DEFAULT_SEND_FROM:-} RESEND_API_URL: ${RESEND_API_URL:-https://api.resend.com} - RESEND_API_KEY: ${RESEND_API_KEY:-your-resend-api-key} + RESEND_API_KEY: ${RESEND_API_KEY:-} SMTP_SERVER: ${SMTP_SERVER:-} SMTP_PORT: ${SMTP_PORT:-465} SMTP_USERNAME: ${SMTP_USERNAME:-} @@ -586,8 +586,8 @@ x-shared-env: &shared-api-worker-env NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s} NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s} NGINX_ENABLE_CERTBOT_CHALLENGE: ${NGINX_ENABLE_CERTBOT_CHALLENGE:-false} - CERTBOT_EMAIL: ${CERTBOT_EMAIL:-your_email@example.com} - CERTBOT_DOMAIN: ${CERTBOT_DOMAIN:-your_domain.com} + CERTBOT_EMAIL: ${CERTBOT_EMAIL:-} + CERTBOT_DOMAIN: ${CERTBOT_DOMAIN:-} CERTBOT_OPTIONS: ${CERTBOT_OPTIONS:-} SSRF_HTTP_PORT: ${SSRF_HTTP_PORT:-3128} SSRF_COREDUMP_DIR: ${SSRF_COREDUMP_DIR:-/var/spool/squid} @@ -745,7 +745,7 @@ services: # API service api: - image: langgenius/dify-api:1.13.3 + image: langgenius/dify-api:1.14.0 restart: always environment: # Use the shared environment variables. @@ -793,7 +793,7 @@ services: # worker service # The Celery worker for processing all queues (dataset, workflow, mail, etc.) worker: - image: langgenius/dify-api:1.13.3 + image: langgenius/dify-api:1.14.0 restart: always environment: # Use the shared environment variables. @@ -839,7 +839,7 @@ services: # worker_beat service # Celery beat for scheduling periodic tasks. worker_beat: - image: langgenius/dify-api:1.13.3 + image: langgenius/dify-api:1.14.0 restart: always environment: # Use the shared environment variables. @@ -876,7 +876,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:1.13.3 + image: langgenius/dify-web:1.14.0 restart: always environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} @@ -894,8 +894,8 @@ services: ALLOW_UNSAFE_DATA_SCHEME: ${ALLOW_UNSAFE_DATA_SCHEME:-false} MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai} MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai} - TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-} - INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-} + TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-10} + INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-4000} LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100} MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10} MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10} @@ -992,7 +992,7 @@ services: # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.14 + image: langgenius/dify-sandbox:0.2.15 restart: always environment: # The DifySandbox configurations @@ -1016,7 +1016,7 @@ services: # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.5.3-local + image: langgenius/dify-plugin-daemon:0.6.0-local restart: always environment: # Use the shared environment variables. @@ -1126,8 +1126,8 @@ services: - ./certbot/update-cert.template.txt:/update-cert.template.txt - ./certbot/docker-entrypoint.sh:/docker-entrypoint.sh environment: - - CERTBOT_EMAIL=${CERTBOT_EMAIL} - - CERTBOT_DOMAIN=${CERTBOT_DOMAIN} + - CERTBOT_EMAIL=${CERTBOT_EMAIL:-} + - CERTBOT_DOMAIN=${CERTBOT_DOMAIN:-} - CERTBOT_OPTIONS=${CERTBOT_OPTIONS:-} entrypoint: ["/docker-entrypoint.sh"] command: ["tail", "-f", "/dev/null"] diff --git a/eslint-suppressions.json b/eslint-suppressions.json index e1c8bda126..b5e67df509 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -119,11 +119,6 @@ "count": 3 } }, - "web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config-popup.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-panel.tsx": { "ts/no-explicit-any": { "count": 1 @@ -160,18 +155,10 @@ } }, "web/app/account/(commonLayout)/account-page/email-change-modal.tsx": { - "erasable-syntax-only/enums": { - "count": 1 - }, "ts/no-explicit-any": { "count": 5 } }, - "web/app/account/(commonLayout)/account-page/index.tsx": { - "ts/no-explicit-any": { - "count": 1 - } - }, "web/app/account/(commonLayout)/delete-account/components/feed-back.tsx": { "no-restricted-imports": { "count": 1 @@ -202,26 +189,11 @@ "count": 4 } }, - "web/app/components/app-sidebar/basic.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/app-sidebar/dataset-info/dropdown.tsx": { - "ts/no-explicit-any": { - "count": 1 - } - }, "web/app/components/app-sidebar/index.tsx": { "ts/no-explicit-any": { "count": 1 } }, - "web/app/components/app-sidebar/toggle-button.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/annotation/add-annotation-modal/edit-item/index.tsx": { "erasable-syntax-only/enums": { "count": 1 @@ -343,34 +315,16 @@ "count": 4 } }, - "web/app/components/app/configuration/config-var/config-modal/type-select.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/configuration/config-var/index.tsx": { "no-restricted-imports": { "count": 1 } }, "web/app/components/app/configuration/config-var/select-var-type.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } }, - "web/app/components/app/configuration/config-vision/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/app/configuration/config-vision/param-config-content.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/configuration/config/agent/agent-setting/index.tsx": { "react/set-state-in-effect": { "count": 1 @@ -385,9 +339,6 @@ } }, "web/app/components/app/configuration/config/agent/agent-tools/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 9 } @@ -404,9 +355,6 @@ } }, "web/app/components/app/configuration/config/assistant-type-picker/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -442,11 +390,6 @@ "count": 1 } }, - "web/app/components/app/configuration/config/automatic/version-selector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx": { "no-restricted-imports": { "count": 1 @@ -458,21 +401,6 @@ "count": 2 } }, - "web/app/components/app/configuration/config/config-audio.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/app/configuration/config/config-document.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/app/configuration/dataset-config/context-var/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/configuration/dataset-config/index.tsx": { "ts/no-explicit-any": { "count": 1 @@ -483,11 +411,6 @@ "count": 1 } }, - "web/app/components/app/configuration/dataset-config/params-config/config-content.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/configuration/dataset-config/params-config/index.tsx": { "no-restricted-imports": { "count": 1 @@ -496,11 +419,6 @@ "count": 1 } }, - "web/app/components/app/configuration/dataset-config/select-dataset/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/configuration/dataset-config/settings-modal/index.tsx": { "react/set-state-in-effect": { "count": 2 @@ -529,11 +447,6 @@ "count": 2 } }, - "web/app/components/app/configuration/debug/debug-with-multiple-model/model-parameter-trigger.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/configuration/debug/debug-with-multiple-model/text-generation-item.tsx": { "ts/no-explicit-any": { "count": 8 @@ -562,11 +475,6 @@ "count": 1 } }, - "web/app/components/app/configuration/prompt-value-panel/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/configuration/prompt-value-panel/utils.ts": { "ts/no-explicit-any": { "count": 1 @@ -623,9 +531,6 @@ } }, "web/app/components/app/log/list.tsx": { - "no-restricted-imports": { - "count": 1 - }, "react/set-state-in-effect": { "count": 6 }, @@ -641,35 +546,6 @@ "count": 2 } }, - "web/app/components/app/overview/app-card.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/app/overview/customize/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/app/overview/embedded/index.tsx": { - "no-restricted-imports": { - "count": 2 - }, - "react/set-state-in-effect": { - "count": 1 - } - }, - "web/app/components/app/overview/settings/index.tsx": { - "no-restricted-imports": { - "count": 2 - }, - "react/set-state-in-effect": { - "count": 3 - }, - "regexp/no-unused-capturing-group": { - "count": 1 - } - }, "web/app/components/app/overview/trigger-card.tsx": { "ts/no-explicit-any": { "count": 1 @@ -713,25 +589,6 @@ "count": 1 } }, - "web/app/components/apps/app-card.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react/set-state-in-effect": { - "count": 1 - }, - "ts/no-explicit-any": { - "count": 2 - } - }, - "web/app/components/apps/list.tsx": { - "react-hooks/exhaustive-deps": { - "count": 1 - }, - "react/unsupported-syntax": { - "count": 2 - } - }, "web/app/components/apps/new-app-card.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 1 @@ -799,11 +656,6 @@ "count": 3 } }, - "web/app/components/base/audio-btn/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/audio-gallery/AudioPlayer.tsx": { "ts/no-explicit-any": { "count": 2 @@ -879,9 +731,6 @@ } }, "web/app/components/base/chat/chat-with-history/header/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 2 } @@ -909,11 +758,6 @@ "count": 1 } }, - "web/app/components/base/chat/chat-with-history/sidebar/rename-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/chat/chat/answer/agent-content.tsx": { "style/multiline-ternary": { "count": 2 @@ -935,11 +779,6 @@ "count": 1 } }, - "web/app/components/base/chat/chat/answer/operation.tsx": { - "no-restricted-imports": { - "count": 2 - } - }, "web/app/components/base/chat/chat/answer/workflow-process.tsx": { "react/set-state-in-effect": { "count": 1 @@ -999,11 +838,6 @@ "count": 7 } }, - "web/app/components/base/chat/embedded-chatbot/header/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/chat/embedded-chatbot/hooks.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 3 @@ -1045,11 +879,6 @@ "count": 1 } }, - "web/app/components/base/copy-feedback/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/date-and-time-picker/hooks.ts": { "react/no-unnecessary-use-prefix": { "count": 2 @@ -1101,11 +930,6 @@ "count": 1 } }, - "web/app/components/base/features/new-feature-panel/annotation-reply/annotation-ctrl-button.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.tsx": { "no-restricted-imports": { "count": 1 @@ -1131,15 +955,7 @@ "count": 2 } }, - "web/app/components/base/features/new-feature-panel/feature-bar.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/features/new-feature-panel/feature-card.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 5 } @@ -1176,9 +992,6 @@ } }, "web/app/components/base/file-uploader/file-list-in-log.tsx": { - "no-restricted-imports": { - "count": 1 - }, "react/no-missing-key": { "count": 1 } @@ -1201,11 +1014,6 @@ "count": 2 } }, - "web/app/components/base/file-uploader/pdf-preview.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/file-uploader/store.tsx": { "react-refresh/only-export-components": { "count": 4 @@ -1221,14 +1029,6 @@ "count": 3 } }, - "web/app/components/base/form/components/base/base-field.tsx": { - "no-restricted-imports": { - "count": 2 - }, - "ts/no-explicit-any": { - "count": 3 - } - }, "web/app/components/base/form/components/base/base-form.tsx": { "ts/no-explicit-any": { "count": 6 @@ -1601,15 +1401,7 @@ "count": 1 } }, - "web/app/components/base/image-uploader/image-list.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/image-uploader/image-preview.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -1763,18 +1555,7 @@ "count": 1 } }, - "web/app/components/base/modal/modal.stories.tsx": { - "no-console": { - "count": 4 - }, - "react/set-state-in-effect": { - "count": 1 - } - }, "web/app/components/base/new-audio-button/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -1807,11 +1588,6 @@ "count": 1 } }, - "web/app/components/base/param-item/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/prompt-editor/index.stories.tsx": { "no-console": { "count": 1 @@ -1825,11 +1601,6 @@ "count": 4 } }, - "web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx": { - "ts/no-explicit-any": { - "count": 1 - } - }, "web/app/components/base/prompt-editor/plugins/component-picker-block/menu.tsx": { "erasable-syntax-only/parameter-properties": { "count": 1 @@ -1957,11 +1728,6 @@ "count": 1 } }, - "web/app/components/base/qrcode/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/radio-card/index.stories.tsx": { "ts/no-explicit-any": { "count": 1 @@ -1990,25 +1756,6 @@ "count": 1 } }, - "web/app/components/base/select/index.stories.tsx": { - "no-console": { - "count": 4 - }, - "ts/no-explicit-any": { - "count": 1 - } - }, - "web/app/components/base/select/index.tsx": { - "react/set-state-in-effect": { - "count": 2 - }, - "style/multiline-ternary": { - "count": 2 - }, - "ts/no-explicit-any": { - "count": 1 - } - }, "web/app/components/base/sort/index.tsx": { "ts/no-explicit-any": { "count": 2 @@ -2032,26 +1779,6 @@ "count": 1 } }, - "web/app/components/base/tag-management/__tests__/panel.spec.tsx": { - "ts/no-explicit-any": { - "count": 2 - } - }, - "web/app/components/base/tag-management/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/base/tag-management/tag-item-editor.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/base/tag-management/tag-remove-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/text-generation/hooks.ts": { "ts/no-explicit-any": { "count": 1 @@ -2124,21 +1851,11 @@ "count": 4 } }, - "web/app/components/billing/plan-upgrade-modal/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/billing/plan/assets/index.tsx": { "no-barrel-files/no-barrel-files": { "count": 4 } }, - "web/app/components/billing/plan/index.tsx": { - "ts/no-explicit-any": { - "count": 2 - } - }, "web/app/components/billing/pricing/assets/index.tsx": { "no-barrel-files/no-barrel-files": { "count": 12 @@ -2157,11 +1874,6 @@ "count": 1 } }, - "web/app/components/billing/priority-label/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/billing/type.ts": { "erasable-syntax-only/enums": { "count": 4 @@ -2187,11 +1899,6 @@ "count": 3 } }, - "web/app/components/datasets/common/image-uploader/image-uploader-in-retrieval-testing/image-input.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/common/image-uploader/store.tsx": { "react-refresh/only-export-components": { "count": 3 @@ -2202,11 +1909,6 @@ "count": 1 } }, - "web/app/components/datasets/common/retrieval-param-config/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/dsl-confirm-modal.tsx": { "no-restricted-imports": { "count": 1 @@ -2225,11 +1927,6 @@ "count": 1 } }, - "web/app/components/datasets/create-from-pipeline/list/template-card/details/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/create-from-pipeline/list/template-card/details/types.ts": { "erasable-syntax-only/enums": { "count": 1 @@ -2240,11 +1937,6 @@ "count": 1 } }, - "web/app/components/datasets/create/embedding-process/indexing-progress-item.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/create/empty-dataset-creation-modal/index.tsx": { "no-restricted-imports": { "count": 1 @@ -2270,26 +1962,11 @@ "count": 1 } }, - "web/app/components/datasets/create/step-two/components/general-chunking-options.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/create/step-two/components/index.ts": { "no-barrel-files/no-barrel-files": { "count": 5 } }, - "web/app/components/datasets/create/step-two/components/indexing-mode-section.tsx": { - "no-restricted-imports": { - "count": 2 - } - }, - "web/app/components/datasets/create/step-two/components/inputs.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/create/step-two/hooks/index.ts": { "no-barrel-files/no-barrel-files": { "count": 6 @@ -2324,16 +2001,6 @@ "count": 1 } }, - "web/app/components/datasets/create/website/base/checkbox-with-label.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/datasets/create/website/base/field.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/create/website/firecrawl/index.tsx": { "no-console": { "count": 1 @@ -2382,11 +2049,6 @@ "count": 1 } }, - "web/app/components/datasets/documents/components/document-list/components/document-table-row.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/documents/components/document-list/components/index.ts": { "no-barrel-files/no-barrel-files": { "count": 2 @@ -2412,11 +2074,6 @@ "count": 1 } }, - "web/app/components/datasets/documents/create-from-pipeline/data-source/base/credential-selector/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/documents/create-from-pipeline/data-source/online-documents/index.tsx": { "ts/no-explicit-any": { "count": 1 @@ -2447,11 +2104,6 @@ "count": 4 } }, - "web/app/components/datasets/documents/create-from-pipeline/data-source/website-crawl/base/checkbox-with-label.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/documents/create-from-pipeline/data-source/website-crawl/base/options/index.tsx": { "ts/no-explicit-any": { "count": 1 @@ -2561,11 +2213,6 @@ "count": 1 } }, - "web/app/components/datasets/documents/detail/metadata/components/doc-type-selector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/documents/detail/metadata/components/metadata-field-list.tsx": { "ts/no-non-null-asserted-optional-chain": { "count": 1 @@ -2602,19 +2249,6 @@ "count": 3 } }, - "web/app/components/datasets/documents/status-item/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/datasets/external-api/external-api-modal/index.tsx": { - "no-restricted-imports": { - "count": 2 - }, - "react/set-state-in-effect": { - "count": 1 - } - }, "web/app/components/datasets/external-knowledge-base/create/ExternalApiSelect.tsx": { "react/set-state-in-effect": { "count": 1 @@ -2625,11 +2259,6 @@ "count": 1 } }, - "web/app/components/datasets/extra-info/statistics.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/formatted-text/flavours/type.ts": { "ts/no-empty-object-type": { "count": 1 @@ -2640,11 +2269,6 @@ "count": 1 } }, - "web/app/components/datasets/hit-testing/components/query-input/textarea.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/hit-testing/components/result-item-external.tsx": { "no-restricted-imports": { "count": 1 @@ -2660,21 +2284,6 @@ "count": 1 } }, - "web/app/components/datasets/list/dataset-card/components/dataset-card-footer.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/datasets/list/dataset-card/hooks/use-dataset-card-state.ts": { - "react/set-state-in-effect": { - "count": 1 - } - }, - "web/app/components/datasets/metadata/edit-metadata-batch/edited-beacon.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/metadata/edit-metadata-batch/input-combined.tsx": { "ts/no-explicit-any": { "count": 2 @@ -2718,11 +2327,6 @@ "count": 1 } }, - "web/app/components/datasets/metadata/metadata-document/info-group.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/metadata/types.ts": { "erasable-syntax-only/enums": { "count": 2 @@ -2738,21 +2342,6 @@ "count": 1 } }, - "web/app/components/datasets/settings/index-method/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/datasets/settings/index-method/keyword-number.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/datasets/settings/summary-index-setting.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/develop/code.tsx": { "ts/no-empty-object-type": { "count": 1 @@ -2795,27 +2384,11 @@ "count": 2 } }, - "web/app/components/explore/create-app-modal/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "ts/no-explicit-any": { - "count": 1 - }, - "unicorn/prefer-number-properties": { - "count": 1 - } - }, "web/app/components/explore/item-operation/index.tsx": { "react/set-state-in-effect": { "count": 1 } }, - "web/app/components/explore/try-app/app/chat.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/explore/try-app/index.tsx": { "no-restricted-imports": { "count": 1 @@ -2941,9 +2514,6 @@ } }, "web/app/components/header/account-setting/key-validator/declarations.ts": { - "erasable-syntax-only/enums": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -2957,11 +2527,8 @@ "erasable-syntax-only/enums": { "count": 1 }, - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { - "count": 3 + "count": 2 } }, "web/app/components/header/account-setting/model-provider-page/declarations.ts": { @@ -2990,11 +2557,6 @@ "count": 1 } }, - "web/app/components/header/account-setting/model-provider-page/model-auth/credential-selector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/header/account-setting/model-provider-page/model-auth/hooks/index.ts": { "no-barrel-files/no-barrel-files": { "count": 6 @@ -3028,14 +2590,6 @@ "count": 3 } }, - "web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "ts/no-explicit-any": { - "count": 6 - } - }, "web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx": { "unicorn/prefer-number-properties": { "count": 2 @@ -3064,15 +2618,7 @@ "count": 2 } }, - "web/app/components/header/account-setting/model-provider-page/model-selector/feature-icon.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/header/account-setting/model-provider-page/provider-added-card/cooldown-timer.tsx": { - "no-restricted-imports": { - "count": 1 - }, "react/set-state-in-effect": { "count": 2 } @@ -3088,9 +2634,6 @@ } }, "web/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-configs.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 5 } @@ -3106,11 +2649,6 @@ "count": 3 } }, - "web/app/components/header/account-setting/model-provider-page/provider-added-card/priority-use-tip.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/header/account-setting/model-provider-page/utils.ts": { "no-barrel-files/no-barrel-files": { "count": 2 @@ -3121,14 +2659,6 @@ "count": 4 } }, - "web/app/components/header/app-nav/index.tsx": { - "react/set-state-in-effect": { - "count": 2 - }, - "ts/no-explicit-any": { - "count": 1 - } - }, "web/app/components/header/header-wrapper.tsx": { "ts/no-explicit-any": { "count": 1 @@ -3203,33 +2733,12 @@ "count": 1 } }, - "web/app/components/plugins/plugin-auth/authorize/add-oauth-button.tsx": { - "ts/no-explicit-any": { - "count": 2 - } - }, - "web/app/components/plugins/plugin-auth/authorize/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/plugins/plugin-auth/authorize/oauth-client-settings.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "ts/no-explicit-any": { - "count": 2 - } - }, "web/app/components/plugins/plugin-auth/authorized-in-node.tsx": { "ts/no-explicit-any": { "count": 1 } }, "web/app/components/plugins/plugin-auth/authorized/item.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -3299,9 +2808,6 @@ } }, "web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 2 } @@ -3327,9 +2833,6 @@ } }, "web/app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -3344,67 +2847,21 @@ "count": 2 } }, - "web/app/components/plugins/plugin-detail-panel/subscription-list/create/common-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/use-common-modal-state.ts": { "erasable-syntax-only/enums": { "count": 1 } }, - "web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/use-oauth-client-state.ts": { - "erasable-syntax-only/enums": { - "count": 2 - } - }, - "web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx": { - "no-barrel-files/no-barrel-files": { - "count": 3 - }, - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/plugins/plugin-detail-panel/subscription-list/create/oauth-client.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/plugins/plugin-detail-panel/subscription-list/create/types.ts": { "erasable-syntax-only/enums": { "count": 1 } }, - "web/app/components/plugins/plugin-detail-panel/subscription-list/edit/apikey-edit-modal.tsx": { - "erasable-syntax-only/enums": { - "count": 1 - }, - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/plugins/plugin-detail-panel/subscription-list/edit/manual-edit-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/plugins/plugin-detail-panel/subscription-list/edit/oauth-edit-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/plugins/plugin-detail-panel/subscription-list/index.tsx": { "no-barrel-files/no-barrel-files": { "count": 2 } }, - "web/app/components/plugins/plugin-detail-panel/subscription-list/list-view.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/plugins/plugin-detail-panel/subscription-list/log-viewer.tsx": { "erasable-syntax-only/enums": { "count": 1 @@ -3413,11 +2870,6 @@ "count": 2 } }, - "web/app/components/plugins/plugin-detail-panel/subscription-list/selector-view.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/plugins/plugin-detail-panel/subscription-list/subscription-card.tsx": { "no-restricted-imports": { "count": 1 @@ -3433,14 +2885,9 @@ "count": 7 } }, - "web/app/components/plugins/plugin-detail-panel/tool-selector/components/schema-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/plugins/plugin-detail-panel/tool-selector/components/tool-item.tsx": { "no-restricted-imports": { - "count": 2 + "count": 1 } }, "web/app/components/plugins/plugin-detail-panel/tool-selector/hooks/index.ts": { @@ -3453,11 +2900,6 @@ "count": 5 } }, - "web/app/components/plugins/plugin-item/action.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/plugins/plugin-item/index.tsx": { "no-restricted-imports": { "count": 1 @@ -3481,11 +2923,6 @@ "count": 2 } }, - "web/app/components/plugins/plugin-page/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx": { "react/set-state-in-effect": { "count": 2 @@ -3573,11 +3010,6 @@ "count": 1 } }, - "web/app/components/rag-pipeline/components/panel/input-field/label-right-content/global-inputs.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/rag-pipeline/components/panel/test-run/preparation/document-processing/index.tsx": { "ts/no-explicit-any": { "count": 1 @@ -3764,11 +3196,6 @@ "count": 1 } }, - "web/app/components/tools/mcp/detail/tool-item.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/tools/mcp/mcp-server-modal.tsx": { "no-restricted-imports": { "count": 1 @@ -3782,11 +3209,6 @@ "count": 1 } }, - "web/app/components/tools/mcp/mcp-service-card.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/tools/mcp/modal.tsx": { "no-restricted-imports": { "count": 1 @@ -3820,21 +3242,6 @@ "count": 4 } }, - "web/app/components/tools/workflow-tool/confirm-modal/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/tools/workflow-tool/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/tools/workflow-tool/method-selector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow-app/components/workflow-children.tsx": { "ts/no-explicit-any": { "count": 3 @@ -3997,11 +3404,6 @@ "count": 1 } }, - "web/app/components/workflow/dsl-export-confirm-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/header/run-mode.tsx": { "no-console": { "count": 1 @@ -4018,11 +3420,6 @@ "count": 1 } }, - "web/app/components/workflow/header/version-history-button.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/hooks-store/index.ts": { "no-barrel-files/no-barrel-files": { "count": 2 @@ -4045,7 +3442,7 @@ }, "web/app/components/workflow/hooks/index.ts": { "no-barrel-files/no-barrel-files": { - "count": 27 + "count": 25 } }, "web/app/components/workflow/hooks/use-checklist.ts": { @@ -4152,11 +3549,6 @@ "count": 1 } }, - "web/app/components/workflow/nodes/_base/components/config-vision.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/_base/components/editor/code-editor/editor-support-vars.tsx": { "react/set-state-in-effect": { "count": 1 @@ -4186,11 +3578,6 @@ "count": 1 } }, - "web/app/components/workflow/nodes/_base/components/error-handle/error-handle-type-selector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/_base/components/error-handle/types.ts": { "erasable-syntax-only/enums": { "count": 1 @@ -4199,15 +3586,7 @@ "count": 1 } }, - "web/app/components/workflow/nodes/_base/components/field.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/_base/components/input-support-select-var.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -4250,15 +3629,7 @@ "count": 1 } }, - "web/app/components/workflow/nodes/_base/components/option-card.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/_base/components/prompt/editor.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 4 } @@ -4274,9 +3645,6 @@ } }, "web/app/components/workflow/nodes/_base/components/setting-item.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -4291,11 +3659,6 @@ "count": 8 } }, - "web/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/picker/field.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/_base/components/variable/output-var-list.tsx": { "ts/no-non-null-asserted-optional-chain": { "count": 1 @@ -4311,11 +3674,6 @@ "count": 1 } }, - "web/app/components/workflow/nodes/_base/components/variable/var-type-picker.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/_base/components/variable/variable-label/hooks.ts": { "react/no-unnecessary-use-prefix": { "count": 2 @@ -4327,9 +3685,6 @@ } }, "web/app/components/workflow/nodes/_base/components/workflow-panel/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, "react/set-state-in-effect": { "count": 3 }, @@ -4604,42 +3959,6 @@ "count": 5 } }, - "web/app/components/workflow/nodes/human-input/components/delivery-method/email-configure-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/workflow/nodes/human-input/components/delivery-method/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/workflow/nodes/human-input/components/delivery-method/method-item.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/workflow/nodes/human-input/components/delivery-method/method-selector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/workflow/nodes/human-input/components/delivery-method/test-email-sender.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "ts/no-explicit-any": { - "count": 2 - }, - "ts/no-non-null-asserted-optional-chain": { - "count": 1 - } - }, - "web/app/components/workflow/nodes/human-input/components/delivery-method/upgrade-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/human-input/components/form-content-preview.tsx": { "react/unsupported-syntax": { "count": 1 @@ -4664,11 +3983,6 @@ "count": 2 } }, - "web/app/components/workflow/nodes/human-input/panel.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/human-input/types.ts": { "erasable-syntax-only/enums": { "count": 2 @@ -4679,16 +3993,6 @@ "count": 1 } }, - "web/app/components/workflow/nodes/if-else/components/condition-list/condition-operator.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/workflow/nodes/if-else/components/condition-number-input.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/if-else/default.ts": { "ts/no-explicit-any": { "count": 1 @@ -4724,16 +4028,6 @@ "count": 6 } }, - "web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/selector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/workflow/nodes/knowledge-base/components/index-method.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/hooks.tsx": { "ts/no-explicit-any": { "count": 4 @@ -4772,26 +4066,11 @@ "count": 1 } }, - "web/app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-operator.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-value-method.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-filter/index.tsx": { "no-restricted-imports": { "count": 1 } }, - "web/app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-filter/metadata-filter-selector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/knowledge-retrieval/default.ts": { "ts/no-explicit-any": { "count": 1 @@ -4830,14 +4109,6 @@ "count": 1 } }, - "web/app/components/workflow/nodes/llm/components/config-prompt-item.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "ts/no-explicit-any": { - "count": 3 - } - }, "web/app/components/workflow/nodes/llm/components/config-prompt.tsx": { "react/unsupported-syntax": { "count": 1 @@ -4871,11 +4142,6 @@ "count": 2 } }, - "web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/prompt-editor.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/context.tsx": { "react-refresh/only-export-components": { "count": 2 @@ -4886,11 +4152,6 @@ "count": 1 } }, - "web/app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/type-selector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/hooks.ts": { "ts/no-explicit-any": { "count": 1 @@ -4942,16 +4203,6 @@ "count": 1 } }, - "web/app/components/workflow/nodes/loop/components/condition-list/condition-operator.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/workflow/nodes/loop/components/condition-number-input.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/loop/components/loop-variables/form-item.tsx": { "ts/no-explicit-any": { "count": 3 @@ -5123,9 +4374,6 @@ } }, "web/app/components/workflow/nodes/tool/components/tool-form/item.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -5209,11 +4457,6 @@ "count": 7 } }, - "web/app/components/workflow/nodes/trigger-schedule/components/monthly-days-selector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/trigger-schedule/default.ts": { "regexp/no-unused-capturing-group": { "count": 2 @@ -5282,11 +4525,6 @@ "count": 1 } }, - "web/app/components/workflow/operator/tip-popup.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/operator/zoom-in-out.tsx": { "erasable-syntax-only/enums": { "count": 1 @@ -5351,11 +4589,6 @@ "count": 12 } }, - "web/app/components/workflow/panel/debug-and-preview/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/panel/env-panel/variable-modal.tsx": { "no-restricted-imports": { "count": 1 @@ -5580,9 +4813,6 @@ } }, "web/app/components/workflow/variable-inspect/group.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 2 } @@ -5606,17 +4836,11 @@ } }, "web/app/components/workflow/variable-inspect/right.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 3 } }, "web/app/components/workflow/variable-inspect/trigger.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -5640,11 +4864,6 @@ "count": 5 } }, - "web/app/components/workflow/workflow-history-store.tsx": { - "react-refresh/only-export-components": { - "count": 2 - } - }, "web/app/components/workflow/workflow-preview/components/nodes/base.tsx": { "no-restricted-imports": { "count": 1 @@ -5680,11 +4899,6 @@ "count": 5 } }, - "web/app/education-apply/verify-state-modal.tsx": { - "react/set-state-in-effect": { - "count": 1 - } - }, "web/app/forgot-password/ForgotPasswordForm.spec.tsx": { "ts/no-explicit-any": { "count": 5 @@ -5710,11 +4924,6 @@ "count": 1 } }, - "web/app/signin/_header.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/signin/components/mail-and-password-auth.tsx": { "ts/no-explicit-any": { "count": 1 @@ -5726,9 +4935,6 @@ } }, "web/app/signin/one-more-step.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -5753,21 +4959,6 @@ "count": 3 } }, - "web/context/modal-context-provider.tsx": { - "ts/no-explicit-any": { - "count": 3 - } - }, - "web/context/modal-context.test.tsx": { - "ts/no-explicit-any": { - "count": 5 - } - }, - "web/context/modal-context.ts": { - "ts/no-explicit-any": { - "count": 2 - } - }, "web/context/provider-context-provider.tsx": { "ts/no-explicit-any": { "count": 1 @@ -5929,11 +5120,6 @@ "count": 1 } }, - "web/plugins/dev-proxy/server.spec.ts": { - "ts/no-explicit-any": { - "count": 1 - } - }, "web/scripts/component-analyzer.js": { "regexp/no-unused-capturing-group": { "count": 6 @@ -5987,11 +5173,6 @@ "count": 2 } }, - "web/service/knowledge/use-dataset.ts": { - "@tanstack/query/exhaustive-deps": { - "count": 1 - } - }, "web/service/share.ts": { "erasable-syntax-only/enums": { "count": 1 @@ -6005,11 +5186,6 @@ "count": 2 } }, - "web/service/use-apps.ts": { - "ts/no-explicit-any": { - "count": 1 - } - }, "web/service/use-common.ts": { "ts/no-empty-object-type": { "count": 1 diff --git a/eslint.config.mjs b/eslint.config.mjs index ae9fdaff01..1380ed67d2 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -4,6 +4,17 @@ import antfu, { GLOB_MARKDOWN } from '@antfu/eslint-config' import md from 'eslint-markdown' import markdownPreferences from 'eslint-plugin-markdown-preferences' +const GENERATED_IGNORES = [ + '**/storybook-static/', + '**/.next/', + 'web/next/', + 'web/next-env.d.ts', + '**/dist/', + '**/coverage/', + 'e2e/.auth/', + 'e2e/cucumber-report/', +] + export default antfu( { ignores: original => [ @@ -15,6 +26,7 @@ export default antfu( '!package.json', '!pnpm-workspace.yaml', '!vite.config.ts', + ...GENERATED_IGNORES, ...original, ], typescript: { diff --git a/package.json b/package.json index 42d6961f5f..9ef6b4ef4e 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,12 @@ "name": "dify", "type": "module", "private": true, - "packageManager": "pnpm@10.33.2", + "packageManager": "pnpm@11.0.8", "engines": { "node": "^22.22.1" }, "scripts": { + "dev": "concurrently -k -n vinext,proxy \"vp run dify-web#dev:vinext\" \"vp run dify-web#dev:proxy\"", "prepare": "vp config", "type-check": "vp run -r type-check", "lint": "eslint --cache --concurrency=auto", @@ -16,6 +17,7 @@ }, "devDependencies": { "@antfu/eslint-config": "catalog:", + "concurrently": "catalog:", "eslint": "catalog:", "eslint-markdown": "catalog:", "eslint-plugin-markdown-preferences": "catalog:", diff --git a/packages/contracts/generated/api/console/account/orpc.gen.ts b/packages/contracts/generated/api/console/account/orpc.gen.ts new file mode 100644 index 0000000000..a926103667 --- /dev/null +++ b/packages/contracts/generated/api/console/account/orpc.gen.ts @@ -0,0 +1,378 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetAccountAvatarQuery, + zGetAccountAvatarResponse, + zGetAccountDeleteVerifyResponse, + zGetAccountEducationAutocompleteQuery, + zGetAccountEducationAutocompleteResponse, + zGetAccountEducationResponse, + zGetAccountEducationVerifyResponse, + zGetAccountIntegratesResponse, + zGetAccountProfileResponse, + zPostAccountAvatarBody, + zPostAccountAvatarResponse, + zPostAccountChangeEmailBody, + zPostAccountChangeEmailCheckEmailUniqueBody, + zPostAccountChangeEmailCheckEmailUniqueResponse, + zPostAccountChangeEmailResetBody, + zPostAccountChangeEmailResetResponse, + zPostAccountChangeEmailResponse, + zPostAccountChangeEmailValidityBody, + zPostAccountChangeEmailValidityResponse, + zPostAccountDeleteBody, + zPostAccountDeleteFeedbackBody, + zPostAccountDeleteFeedbackResponse, + zPostAccountDeleteResponse, + zPostAccountEducationBody, + zPostAccountEducationResponse, + zPostAccountInitBody, + zPostAccountInitResponse, + zPostAccountInterfaceLanguageBody, + zPostAccountInterfaceLanguageResponse, + zPostAccountInterfaceThemeBody, + zPostAccountInterfaceThemeResponse, + zPostAccountNameBody, + zPostAccountNameResponse, + zPostAccountPasswordBody, + zPostAccountPasswordResponse, + zPostAccountTimezoneBody, + zPostAccountTimezoneResponse, +} from './zod.gen' + +/** + * Get account avatar url + */ +export const get = oc + .route({ + description: 'Get account avatar url', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAccountAvatar', + path: '/account/avatar', + tags: ['console'], + }) + .input(z.object({ query: zGetAccountAvatarQuery })) + .output(zGetAccountAvatarResponse) + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountAvatar', + path: '/account/avatar', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountAvatarBody })) + .output(zPostAccountAvatarResponse) + +export const avatar = { + get, + post, +} + +export const post2 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountChangeEmailCheckEmailUnique', + path: '/account/change-email/check-email-unique', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountChangeEmailCheckEmailUniqueBody })) + .output(zPostAccountChangeEmailCheckEmailUniqueResponse) + +export const checkEmailUnique = { + post: post2, +} + +export const post3 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountChangeEmailReset', + path: '/account/change-email/reset', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountChangeEmailResetBody })) + .output(zPostAccountChangeEmailResetResponse) + +export const reset = { + post: post3, +} + +export const post4 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountChangeEmailValidity', + path: '/account/change-email/validity', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountChangeEmailValidityBody })) + .output(zPostAccountChangeEmailValidityResponse) + +export const validity = { + post: post4, +} + +export const post5 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountChangeEmail', + path: '/account/change-email', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountChangeEmailBody })) + .output(zPostAccountChangeEmailResponse) + +export const changeEmail = { + post: post5, + checkEmailUnique, + reset, + validity, +} + +export const post6 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountDeleteFeedback', + path: '/account/delete/feedback', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountDeleteFeedbackBody })) + .output(zPostAccountDeleteFeedbackResponse) + +export const feedback = { + post: post6, +} + +export const get2 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAccountDeleteVerify', + path: '/account/delete/verify', + tags: ['console'], + }) + .output(zGetAccountDeleteVerifyResponse) + +export const verify = { + get: get2, +} + +export const post7 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountDelete', + path: '/account/delete', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountDeleteBody })) + .output(zPostAccountDeleteResponse) + +export const delete_ = { + post: post7, + feedback, + verify, +} + +export const get3 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAccountEducationAutocomplete', + path: '/account/education/autocomplete', + tags: ['console'], + }) + .input(z.object({ query: zGetAccountEducationAutocompleteQuery })) + .output(zGetAccountEducationAutocompleteResponse) + +export const autocomplete = { + get: get3, +} + +export const get4 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAccountEducationVerify', + path: '/account/education/verify', + tags: ['console'], + }) + .output(zGetAccountEducationVerifyResponse) + +export const verify2 = { + get: get4, +} + +export const get5 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAccountEducation', + path: '/account/education', + tags: ['console'], + }) + .output(zGetAccountEducationResponse) + +export const post8 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountEducation', + path: '/account/education', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountEducationBody })) + .output(zPostAccountEducationResponse) + +export const education = { + get: get5, + post: post8, + autocomplete, + verify: verify2, +} + +export const post9 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountInit', + path: '/account/init', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountInitBody })) + .output(zPostAccountInitResponse) + +export const init = { + post: post9, +} + +export const get6 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAccountIntegrates', + path: '/account/integrates', + tags: ['console'], + }) + .output(zGetAccountIntegratesResponse) + +export const integrates = { + get: get6, +} + +export const post10 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountInterfaceLanguage', + path: '/account/interface-language', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountInterfaceLanguageBody })) + .output(zPostAccountInterfaceLanguageResponse) + +export const interfaceLanguage = { + post: post10, +} + +export const post11 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountInterfaceTheme', + path: '/account/interface-theme', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountInterfaceThemeBody })) + .output(zPostAccountInterfaceThemeResponse) + +export const interfaceTheme = { + post: post11, +} + +export const post12 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountName', + path: '/account/name', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountNameBody })) + .output(zPostAccountNameResponse) + +export const name = { + post: post12, +} + +export const post13 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountPassword', + path: '/account/password', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountPasswordBody })) + .output(zPostAccountPasswordResponse) + +export const password = { + post: post13, +} + +export const get7 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAccountProfile', + path: '/account/profile', + tags: ['console'], + }) + .output(zGetAccountProfileResponse) + +export const profile = { + get: get7, +} + +export const post14 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAccountTimezone', + path: '/account/timezone', + tags: ['console'], + }) + .input(z.object({ body: zPostAccountTimezoneBody })) + .output(zPostAccountTimezoneResponse) + +export const timezone = { + post: post14, +} + +export const account = { + avatar, + changeEmail, + delete: delete_, + education, + init, + integrates, + interfaceLanguage, + interfaceTheme, + name, + password, + profile, + timezone, +} + +export const contract = { + account, +} diff --git a/packages/contracts/generated/api/console/account/types.gen.ts b/packages/contracts/generated/api/console/account/types.gen.ts new file mode 100644 index 0000000000..9021d4c8fb --- /dev/null +++ b/packages/contracts/generated/api/console/account/types.gen.ts @@ -0,0 +1,429 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type AccountAvatarPayload = { + avatar: string +} + +export type Account = { + avatar?: string | null + created_at?: number | null + email: string + id: string + interface_language?: string | null + interface_theme?: string | null + is_password_set: boolean + last_login_at?: number | null + last_login_ip?: string | null + name: string + timezone?: string | null +} + +export type ChangeEmailSendPayload = { + email: string + language?: string | null + phase?: string | null + token?: string | null +} + +export type CheckEmailUniquePayload = { + email: string +} + +export type ChangeEmailResetPayload = { + new_email: string + token: string +} + +export type ChangeEmailValidityPayload = { + code: string + email: string + token: string +} + +export type AccountDeletePayload = { + code: string + token: string +} + +export type AccountDeletionFeedbackPayload = { + email: string + feedback: string +} + +export type EducationStatusResponse = { + allow_refresh?: boolean | null + expire_at?: number | null + is_student?: boolean | null + result?: boolean | null +} + +export type EducationActivatePayload = { + institution: string + role: string + token: string +} + +export type EducationAutocompleteResponse = { + curr_page?: number | null + data?: Array + has_next?: boolean | null +} + +export type EducationVerifyResponse = { + token?: string | null +} + +export type AccountInitPayload = { + interface_language: string + invitation_code?: string | null + timezone: string +} + +export type AccountIntegrateListResponse = { + data: Array +} + +export type AccountInterfaceLanguagePayload = { + interface_language: string +} + +export type AccountInterfaceThemePayload = { + interface_theme: 'light' | 'dark' +} + +export type AccountNamePayload = { + name: string +} + +export type AccountPasswordPayload = { + new_password: string + password?: string | null + repeat_new_password: string +} + +export type AccountTimezonePayload = { + timezone: string +} + +export type AccountIntegrateResponse = { + created_at?: number | null + is_bound: boolean + link?: string | null + provider: string +} + +export type GetAccountAvatarData = { + body?: never + path?: never + query: { + avatar: string + } + url: '/account/avatar' +} + +export type GetAccountAvatarResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAccountAvatarResponse = GetAccountAvatarResponses[keyof GetAccountAvatarResponses] + +export type PostAccountAvatarData = { + body: AccountAvatarPayload + path?: never + query?: never + url: '/account/avatar' +} + +export type PostAccountAvatarResponses = { + 200: Account +} + +export type PostAccountAvatarResponse = PostAccountAvatarResponses[keyof PostAccountAvatarResponses] + +export type PostAccountChangeEmailData = { + body: ChangeEmailSendPayload + path?: never + query?: never + url: '/account/change-email' +} + +export type PostAccountChangeEmailResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAccountChangeEmailResponse + = PostAccountChangeEmailResponses[keyof PostAccountChangeEmailResponses] + +export type PostAccountChangeEmailCheckEmailUniqueData = { + body: CheckEmailUniquePayload + path?: never + query?: never + url: '/account/change-email/check-email-unique' +} + +export type PostAccountChangeEmailCheckEmailUniqueResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAccountChangeEmailCheckEmailUniqueResponse + = PostAccountChangeEmailCheckEmailUniqueResponses[keyof PostAccountChangeEmailCheckEmailUniqueResponses] + +export type PostAccountChangeEmailResetData = { + body: ChangeEmailResetPayload + path?: never + query?: never + url: '/account/change-email/reset' +} + +export type PostAccountChangeEmailResetResponses = { + 200: Account +} + +export type PostAccountChangeEmailResetResponse + = PostAccountChangeEmailResetResponses[keyof PostAccountChangeEmailResetResponses] + +export type PostAccountChangeEmailValidityData = { + body: ChangeEmailValidityPayload + path?: never + query?: never + url: '/account/change-email/validity' +} + +export type PostAccountChangeEmailValidityResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAccountChangeEmailValidityResponse + = PostAccountChangeEmailValidityResponses[keyof PostAccountChangeEmailValidityResponses] + +export type PostAccountDeleteData = { + body: AccountDeletePayload + path?: never + query?: never + url: '/account/delete' +} + +export type PostAccountDeleteResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAccountDeleteResponse = PostAccountDeleteResponses[keyof PostAccountDeleteResponses] + +export type PostAccountDeleteFeedbackData = { + body: AccountDeletionFeedbackPayload + path?: never + query?: never + url: '/account/delete/feedback' +} + +export type PostAccountDeleteFeedbackResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAccountDeleteFeedbackResponse + = PostAccountDeleteFeedbackResponses[keyof PostAccountDeleteFeedbackResponses] + +export type GetAccountDeleteVerifyData = { + body?: never + path?: never + query?: never + url: '/account/delete/verify' +} + +export type GetAccountDeleteVerifyResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAccountDeleteVerifyResponse + = GetAccountDeleteVerifyResponses[keyof GetAccountDeleteVerifyResponses] + +export type GetAccountEducationData = { + body?: never + path?: never + query?: never + url: '/account/education' +} + +export type GetAccountEducationResponses = { + 200: EducationStatusResponse +} + +export type GetAccountEducationResponse + = GetAccountEducationResponses[keyof GetAccountEducationResponses] + +export type PostAccountEducationData = { + body: EducationActivatePayload + path?: never + query?: never + url: '/account/education' +} + +export type PostAccountEducationResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAccountEducationResponse + = PostAccountEducationResponses[keyof PostAccountEducationResponses] + +export type GetAccountEducationAutocompleteData = { + body?: never + path?: never + query: { + keywords: string + limit?: number + page?: number + } + url: '/account/education/autocomplete' +} + +export type GetAccountEducationAutocompleteResponses = { + 200: EducationAutocompleteResponse +} + +export type GetAccountEducationAutocompleteResponse + = GetAccountEducationAutocompleteResponses[keyof GetAccountEducationAutocompleteResponses] + +export type GetAccountEducationVerifyData = { + body?: never + path?: never + query?: never + url: '/account/education/verify' +} + +export type GetAccountEducationVerifyResponses = { + 200: EducationVerifyResponse +} + +export type GetAccountEducationVerifyResponse + = GetAccountEducationVerifyResponses[keyof GetAccountEducationVerifyResponses] + +export type PostAccountInitData = { + body: AccountInitPayload + path?: never + query?: never + url: '/account/init' +} + +export type PostAccountInitResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAccountInitResponse = PostAccountInitResponses[keyof PostAccountInitResponses] + +export type GetAccountIntegratesData = { + body?: never + path?: never + query?: never + url: '/account/integrates' +} + +export type GetAccountIntegratesResponses = { + 200: AccountIntegrateListResponse +} + +export type GetAccountIntegratesResponse + = GetAccountIntegratesResponses[keyof GetAccountIntegratesResponses] + +export type PostAccountInterfaceLanguageData = { + body: AccountInterfaceLanguagePayload + path?: never + query?: never + url: '/account/interface-language' +} + +export type PostAccountInterfaceLanguageResponses = { + 200: Account +} + +export type PostAccountInterfaceLanguageResponse + = PostAccountInterfaceLanguageResponses[keyof PostAccountInterfaceLanguageResponses] + +export type PostAccountInterfaceThemeData = { + body: AccountInterfaceThemePayload + path?: never + query?: never + url: '/account/interface-theme' +} + +export type PostAccountInterfaceThemeResponses = { + 200: Account +} + +export type PostAccountInterfaceThemeResponse + = PostAccountInterfaceThemeResponses[keyof PostAccountInterfaceThemeResponses] + +export type PostAccountNameData = { + body: AccountNamePayload + path?: never + query?: never + url: '/account/name' +} + +export type PostAccountNameResponses = { + 200: Account +} + +export type PostAccountNameResponse = PostAccountNameResponses[keyof PostAccountNameResponses] + +export type PostAccountPasswordData = { + body: AccountPasswordPayload + path?: never + query?: never + url: '/account/password' +} + +export type PostAccountPasswordResponses = { + 200: Account +} + +export type PostAccountPasswordResponse + = PostAccountPasswordResponses[keyof PostAccountPasswordResponses] + +export type GetAccountProfileData = { + body?: never + path?: never + query?: never + url: '/account/profile' +} + +export type GetAccountProfileResponses = { + 200: Account +} + +export type GetAccountProfileResponse = GetAccountProfileResponses[keyof GetAccountProfileResponses] + +export type PostAccountTimezoneData = { + body: AccountTimezonePayload + path?: never + query?: never + url: '/account/timezone' +} + +export type PostAccountTimezoneResponses = { + 200: Account +} + +export type PostAccountTimezoneResponse + = PostAccountTimezoneResponses[keyof PostAccountTimezoneResponses] diff --git a/packages/contracts/generated/api/console/account/zod.gen.ts b/packages/contracts/generated/api/console/account/zod.gen.ts new file mode 100644 index 0000000000..befa7c27c6 --- /dev/null +++ b/packages/contracts/generated/api/console/account/zod.gen.ts @@ -0,0 +1,318 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * AccountAvatarPayload + */ +export const zAccountAvatarPayload = z.object({ + avatar: z.string(), +}) + +/** + * Account + */ +export const zAccount = z.object({ + avatar: z.string().nullish(), + created_at: z.int().nullish(), + email: z.string(), + id: z.string(), + interface_language: z.string().nullish(), + interface_theme: z.string().nullish(), + is_password_set: z.boolean(), + last_login_at: z.int().nullish(), + last_login_ip: z.string().nullish(), + name: z.string(), + timezone: z.string().nullish(), +}) + +/** + * ChangeEmailSendPayload + */ +export const zChangeEmailSendPayload = z.object({ + email: z.string(), + language: z.string().nullish(), + phase: z.string().nullish(), + token: z.string().nullish(), +}) + +/** + * CheckEmailUniquePayload + */ +export const zCheckEmailUniquePayload = z.object({ + email: z.string(), +}) + +/** + * ChangeEmailResetPayload + */ +export const zChangeEmailResetPayload = z.object({ + new_email: z.string(), + token: z.string(), +}) + +/** + * ChangeEmailValidityPayload + */ +export const zChangeEmailValidityPayload = z.object({ + code: z.string(), + email: z.string(), + token: z.string(), +}) + +/** + * AccountDeletePayload + */ +export const zAccountDeletePayload = z.object({ + code: z.string(), + token: z.string(), +}) + +/** + * AccountDeletionFeedbackPayload + */ +export const zAccountDeletionFeedbackPayload = z.object({ + email: z.string(), + feedback: z.string(), +}) + +/** + * EducationStatusResponse + */ +export const zEducationStatusResponse = z.object({ + allow_refresh: z.boolean().nullish(), + expire_at: z.int().nullish(), + is_student: z.boolean().nullish(), + result: z.boolean().nullish(), +}) + +/** + * EducationActivatePayload + */ +export const zEducationActivatePayload = z.object({ + institution: z.string(), + role: z.string(), + token: z.string(), +}) + +/** + * EducationAutocompleteResponse + */ +export const zEducationAutocompleteResponse = z.object({ + curr_page: z.int().nullish(), + data: z.array(z.string()).optional(), + has_next: z.boolean().nullish(), +}) + +/** + * EducationVerifyResponse + */ +export const zEducationVerifyResponse = z.object({ + token: z.string().nullish(), +}) + +/** + * AccountInitPayload + */ +export const zAccountInitPayload = z.object({ + interface_language: z.string(), + invitation_code: z.string().nullish(), + timezone: z.string(), +}) + +/** + * AccountInterfaceLanguagePayload + */ +export const zAccountInterfaceLanguagePayload = z.object({ + interface_language: z.string(), +}) + +/** + * AccountInterfaceThemePayload + */ +export const zAccountInterfaceThemePayload = z.object({ + interface_theme: z.enum(['light', 'dark']), +}) + +/** + * AccountNamePayload + */ +export const zAccountNamePayload = z.object({ + name: z.string().min(3).max(30), +}) + +/** + * AccountPasswordPayload + */ +export const zAccountPasswordPayload = z.object({ + new_password: z.string(), + password: z.string().nullish(), + repeat_new_password: z.string(), +}) + +/** + * AccountTimezonePayload + */ +export const zAccountTimezonePayload = z.object({ + timezone: z.string(), +}) + +/** + * AccountIntegrateResponse + */ +export const zAccountIntegrateResponse = z.object({ + created_at: z.int().nullish(), + is_bound: z.boolean(), + link: z.string().nullish(), + provider: z.string(), +}) + +/** + * AccountIntegrateListResponse + */ +export const zAccountIntegrateListResponse = z.object({ + data: z.array(zAccountIntegrateResponse), +}) + +export const zGetAccountAvatarQuery = z.object({ + avatar: z.string(), +}) + +/** + * Success + */ +export const zGetAccountAvatarResponse = z.record(z.string(), z.unknown()) + +export const zPostAccountAvatarBody = zAccountAvatarPayload + +/** + * Success + */ +export const zPostAccountAvatarResponse = zAccount + +export const zPostAccountChangeEmailBody = zChangeEmailSendPayload + +/** + * Success + */ +export const zPostAccountChangeEmailResponse = z.record(z.string(), z.unknown()) + +export const zPostAccountChangeEmailCheckEmailUniqueBody = zCheckEmailUniquePayload + +/** + * Success + */ +export const zPostAccountChangeEmailCheckEmailUniqueResponse = z.record(z.string(), z.unknown()) + +export const zPostAccountChangeEmailResetBody = zChangeEmailResetPayload + +/** + * Success + */ +export const zPostAccountChangeEmailResetResponse = zAccount + +export const zPostAccountChangeEmailValidityBody = zChangeEmailValidityPayload + +/** + * Success + */ +export const zPostAccountChangeEmailValidityResponse = z.record(z.string(), z.unknown()) + +export const zPostAccountDeleteBody = zAccountDeletePayload + +/** + * Success + */ +export const zPostAccountDeleteResponse = z.record(z.string(), z.unknown()) + +export const zPostAccountDeleteFeedbackBody = zAccountDeletionFeedbackPayload + +/** + * Success + */ +export const zPostAccountDeleteFeedbackResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetAccountDeleteVerifyResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetAccountEducationResponse = zEducationStatusResponse + +export const zPostAccountEducationBody = zEducationActivatePayload + +/** + * Success + */ +export const zPostAccountEducationResponse = z.record(z.string(), z.unknown()) + +export const zGetAccountEducationAutocompleteQuery = z.object({ + keywords: z.string(), + limit: z.int().optional().default(20), + page: z.int().optional().default(0), +}) + +/** + * Success + */ +export const zGetAccountEducationAutocompleteResponse = zEducationAutocompleteResponse + +/** + * Success + */ +export const zGetAccountEducationVerifyResponse = zEducationVerifyResponse + +export const zPostAccountInitBody = zAccountInitPayload + +/** + * Success + */ +export const zPostAccountInitResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetAccountIntegratesResponse = zAccountIntegrateListResponse + +export const zPostAccountInterfaceLanguageBody = zAccountInterfaceLanguagePayload + +/** + * Success + */ +export const zPostAccountInterfaceLanguageResponse = zAccount + +export const zPostAccountInterfaceThemeBody = zAccountInterfaceThemePayload + +/** + * Success + */ +export const zPostAccountInterfaceThemeResponse = zAccount + +export const zPostAccountNameBody = zAccountNamePayload + +/** + * Success + */ +export const zPostAccountNameResponse = zAccount + +export const zPostAccountPasswordBody = zAccountPasswordPayload + +/** + * Success + */ +export const zPostAccountPasswordResponse = zAccount + +/** + * Success + */ +export const zGetAccountProfileResponse = zAccount + +export const zPostAccountTimezoneBody = zAccountTimezonePayload + +/** + * Success + */ +export const zPostAccountTimezoneResponse = zAccount diff --git a/packages/contracts/generated/api/console/activate/orpc.gen.ts b/packages/contracts/generated/api/console/activate/orpc.gen.ts new file mode 100644 index 0000000000..870f45bd2e --- /dev/null +++ b/packages/contracts/generated/api/console/activate/orpc.gen.ts @@ -0,0 +1,54 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetActivateCheckQuery, + zGetActivateCheckResponse, + zPostActivateBody, + zPostActivateResponse, +} from './zod.gen' + +/** + * Check if activation token is valid + */ +export const get = oc + .route({ + description: 'Check if activation token is valid', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getActivateCheck', + path: '/activate/check', + tags: ['console'], + }) + .input(z.object({ query: zGetActivateCheckQuery })) + .output(zGetActivateCheckResponse) + +export const check = { + get, +} + +/** + * Activate account with invitation token + */ +export const post = oc + .route({ + description: 'Activate account with invitation token', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postActivate', + path: '/activate', + tags: ['console'], + }) + .input(z.object({ body: zPostActivateBody })) + .output(zPostActivateResponse) + +export const activate = { + post, + check, +} + +export const contract = { + activate, +} diff --git a/packages/contracts/generated/api/console/activate/types.gen.ts b/packages/contracts/generated/api/console/activate/types.gen.ts new file mode 100644 index 0000000000..97a16c6861 --- /dev/null +++ b/packages/contracts/generated/api/console/activate/types.gen.ts @@ -0,0 +1,63 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type ActivatePayload = { + email?: string | null + interface_language: string + name: string + timezone: string + token: string + workspace_id?: string | null +} + +export type ActivationResponse = { + result: string +} + +export type ActivationCheckResponse = { + data?: { + [key: string]: unknown + } | null + is_valid: boolean +} + +export type PostActivateData = { + body: ActivatePayload + path?: never + query?: never + url: '/activate' +} + +export type PostActivateErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostActivateError = PostActivateErrors[keyof PostActivateErrors] + +export type PostActivateResponses = { + 200: ActivationResponse +} + +export type PostActivateResponse = PostActivateResponses[keyof PostActivateResponses] + +export type GetActivateCheckData = { + body?: never + path?: never + query: { + email?: string | null + token: string + workspace_id?: string | null + } + url: '/activate/check' +} + +export type GetActivateCheckResponses = { + 200: ActivationCheckResponse +} + +export type GetActivateCheckResponse = GetActivateCheckResponses[keyof GetActivateCheckResponses] diff --git a/packages/contracts/generated/api/console/activate/zod.gen.ts b/packages/contracts/generated/api/console/activate/zod.gen.ts new file mode 100644 index 0000000000..30897b6666 --- /dev/null +++ b/packages/contracts/generated/api/console/activate/zod.gen.ts @@ -0,0 +1,48 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * ActivatePayload + */ +export const zActivatePayload = z.object({ + email: z.string().nullish(), + interface_language: z.string(), + name: z.string().max(30), + timezone: z.string(), + token: z.string(), + workspace_id: z.string().nullish(), +}) + +/** + * ActivationResponse + */ +export const zActivationResponse = z.object({ + result: z.string(), +}) + +/** + * ActivationCheckResponse + */ +export const zActivationCheckResponse = z.object({ + data: z.record(z.string(), z.unknown()).nullish(), + is_valid: z.boolean(), +}) + +export const zPostActivateBody = zActivatePayload + +/** + * Account activated successfully + */ +export const zPostActivateResponse = zActivationResponse + +export const zGetActivateCheckQuery = z.object({ + email: z.string().nullish(), + token: z.string(), + workspace_id: z.string().nullish(), +}) + +/** + * Success + */ +export const zGetActivateCheckResponse = zActivationCheckResponse diff --git a/packages/contracts/generated/api/console/admin/orpc.gen.ts b/packages/contracts/generated/api/console/admin/orpc.gen.ts new file mode 100644 index 0000000000..93f012405a --- /dev/null +++ b/packages/contracts/generated/api/console/admin/orpc.gen.ts @@ -0,0 +1,153 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteAdminDeleteExploreBannerByBannerIdPath, + zDeleteAdminDeleteExploreBannerByBannerIdResponse, + zDeleteAdminInsertExploreAppsByAppIdPath, + zDeleteAdminInsertExploreAppsByAppIdResponse, + zPostAdminBatchAddNotificationAccountsResponse, + zPostAdminInsertExploreAppsBody, + zPostAdminInsertExploreAppsResponse, + zPostAdminInsertExploreBannerBody, + zPostAdminInsertExploreBannerResponse, + zPostAdminUpsertNotificationBody, + zPostAdminUpsertNotificationResponse, +} from './zod.gen' + +/** + * Register target accounts for a notification by email address. JSON body: {"notification_id": "...", "user_email": ["a@example.com", ...]}. File upload: multipart/form-data with a 'file' field (CSV or TXT, one email per line) plus a 'notification_id' field. Emails that do not match any account are silently skipped. + */ +export const post = oc + .route({ + description: + 'Register target accounts for a notification by email address. JSON body: {"notification_id": "...", "user_email": ["a@example.com", ...]}. File upload: multipart/form-data with a \'file\' field (CSV or TXT, one email per line) plus a \'notification_id\' field. Emails that do not match any account are silently skipped.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAdminBatchAddNotificationAccounts', + path: '/admin/batch_add_notification_accounts', + tags: ['console'], + }) + .output(zPostAdminBatchAddNotificationAccountsResponse) + +export const batchAddNotificationAccounts = { + post, +} + +/** + * Delete an explore banner + */ +export const delete_ = oc + .route({ + description: 'Delete an explore banner', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAdminDeleteExploreBannerByBannerId', + path: '/admin/delete-explore-banner/{banner_id}', + successStatus: 204, + tags: ['console'], + }) + .input(z.object({ params: zDeleteAdminDeleteExploreBannerByBannerIdPath })) + .output(zDeleteAdminDeleteExploreBannerByBannerIdResponse) + +export const byBannerId = { + delete: delete_, +} + +export const deleteExploreBanner = { + byBannerId, +} + +/** + * Remove an app from the explore list + */ +export const delete2 = oc + .route({ + description: 'Remove an app from the explore list', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAdminInsertExploreAppsByAppId', + path: '/admin/insert-explore-apps/{app_id}', + successStatus: 204, + tags: ['console'], + }) + .input(z.object({ params: zDeleteAdminInsertExploreAppsByAppIdPath })) + .output(zDeleteAdminInsertExploreAppsByAppIdResponse) + +export const byAppId = { + delete: delete2, +} + +/** + * Insert or update an app in the explore list + */ +export const post2 = oc + .route({ + description: 'Insert or update an app in the explore list', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAdminInsertExploreApps', + path: '/admin/insert-explore-apps', + tags: ['console'], + }) + .input(z.object({ body: zPostAdminInsertExploreAppsBody })) + .output(zPostAdminInsertExploreAppsResponse) + +export const insertExploreApps = { + post: post2, + byAppId, +} + +/** + * Insert an explore banner + */ +export const post3 = oc + .route({ + description: 'Insert an explore banner', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAdminInsertExploreBanner', + path: '/admin/insert-explore-banner', + successStatus: 201, + tags: ['console'], + }) + .input(z.object({ body: zPostAdminInsertExploreBannerBody })) + .output(zPostAdminInsertExploreBannerResponse) + +export const insertExploreBanner = { + post: post3, +} + +/** + * Create or update an in-product notification. Supply notification_id to update an existing one; omit it to create a new one. Pass at least one language variant in contents (zh / en / jp). + */ +export const post4 = oc + .route({ + description: + 'Create or update an in-product notification. Supply notification_id to update an existing one; omit it to create a new one. Pass at least one language variant in contents (zh / en / jp).', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAdminUpsertNotification', + path: '/admin/upsert_notification', + tags: ['console'], + }) + .input(z.object({ body: zPostAdminUpsertNotificationBody })) + .output(zPostAdminUpsertNotificationResponse) + +export const upsertNotification = { + post: post4, +} + +export const admin = { + batchAddNotificationAccounts, + deleteExploreBanner, + insertExploreApps, + insertExploreBanner, + upsertNotification, +} + +export const contract = { + admin, +} diff --git a/packages/contracts/generated/api/console/admin/types.gen.ts b/packages/contracts/generated/api/console/admin/types.gen.ts new file mode 100644 index 0000000000..d3fef01791 --- /dev/null +++ b/packages/contracts/generated/api/console/admin/types.gen.ts @@ -0,0 +1,157 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type InsertExploreAppPayload = { + app_id: string + can_trial?: boolean + category: string + copyright?: string | null + custom_disclaimer?: string | null + desc?: string | null + language: string + position: number + privacy_policy?: string | null + trial_limit?: number +} + +export type InsertExploreBannerPayload = { + 'category': string + 'description': string + 'img-src': string + 'language'?: string + 'link': string + 'sort': number + 'title': string +} + +export type UpsertNotificationPayload = { + contents: Array + end_time?: string | null + frequency?: string + notification_id?: string | null + start_time?: string | null + status?: string +} + +export type LangContentPayload = { + body: string + lang: string + subtitle?: string | null + title: string + title_pic_url?: string | null +} + +export type PostAdminBatchAddNotificationAccountsData = { + body?: never + path?: never + query?: never + url: '/admin/batch_add_notification_accounts' +} + +export type PostAdminBatchAddNotificationAccountsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAdminBatchAddNotificationAccountsResponse + = PostAdminBatchAddNotificationAccountsResponses[keyof PostAdminBatchAddNotificationAccountsResponses] + +export type DeleteAdminDeleteExploreBannerByBannerIdData = { + body?: never + path: { + banner_id: string + } + query?: never + url: '/admin/delete-explore-banner/{banner_id}' +} + +export type DeleteAdminDeleteExploreBannerByBannerIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAdminDeleteExploreBannerByBannerIdResponse + = DeleteAdminDeleteExploreBannerByBannerIdResponses[keyof DeleteAdminDeleteExploreBannerByBannerIdResponses] + +export type PostAdminInsertExploreAppsData = { + body: InsertExploreAppPayload + path?: never + query?: never + url: '/admin/insert-explore-apps' +} + +export type PostAdminInsertExploreAppsErrors = { + 404: { + [key: string]: unknown + } +} + +export type PostAdminInsertExploreAppsError + = PostAdminInsertExploreAppsErrors[keyof PostAdminInsertExploreAppsErrors] + +export type PostAdminInsertExploreAppsResponses = { + 200: { + [key: string]: unknown + } + 201: { + [key: string]: unknown + } +} + +export type PostAdminInsertExploreAppsResponse + = PostAdminInsertExploreAppsResponses[keyof PostAdminInsertExploreAppsResponses] + +export type DeleteAdminInsertExploreAppsByAppIdData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/admin/insert-explore-apps/{app_id}' +} + +export type DeleteAdminInsertExploreAppsByAppIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAdminInsertExploreAppsByAppIdResponse + = DeleteAdminInsertExploreAppsByAppIdResponses[keyof DeleteAdminInsertExploreAppsByAppIdResponses] + +export type PostAdminInsertExploreBannerData = { + body: InsertExploreBannerPayload + path?: never + query?: never + url: '/admin/insert-explore-banner' +} + +export type PostAdminInsertExploreBannerResponses = { + 201: { + [key: string]: unknown + } +} + +export type PostAdminInsertExploreBannerResponse + = PostAdminInsertExploreBannerResponses[keyof PostAdminInsertExploreBannerResponses] + +export type PostAdminUpsertNotificationData = { + body: UpsertNotificationPayload + path?: never + query?: never + url: '/admin/upsert_notification' +} + +export type PostAdminUpsertNotificationResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAdminUpsertNotificationResponse + = PostAdminUpsertNotificationResponses[keyof PostAdminUpsertNotificationResponses] diff --git a/packages/contracts/generated/api/console/admin/zod.gen.ts b/packages/contracts/generated/api/console/admin/zod.gen.ts new file mode 100644 index 0000000000..9ebed93e1e --- /dev/null +++ b/packages/contracts/generated/api/console/admin/zod.gen.ts @@ -0,0 +1,99 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * InsertExploreAppPayload + */ +export const zInsertExploreAppPayload = z.object({ + app_id: z.string(), + can_trial: z.boolean().optional().default(false), + category: z.string(), + copyright: z.string().nullish(), + custom_disclaimer: z.string().nullish(), + desc: z.string().nullish(), + language: z.string(), + position: z.int(), + privacy_policy: z.string().nullish(), + trial_limit: z.int().optional().default(0), +}) + +/** + * InsertExploreBannerPayload + */ +export const zInsertExploreBannerPayload = z.object({ + 'category': z.string(), + 'description': z.string(), + 'img-src': z.string(), + 'language': z.string().optional().default('en-US'), + 'link': z.string(), + 'sort': z.int(), + 'title': z.string(), +}) + +/** + * LangContentPayload + */ +export const zLangContentPayload = z.object({ + body: z.string(), + lang: z.string(), + subtitle: z.string().nullish(), + title: z.string(), + title_pic_url: z.string().nullish(), +}) + +/** + * UpsertNotificationPayload + */ +export const zUpsertNotificationPayload = z.object({ + contents: z.array(zLangContentPayload).min(1), + end_time: z.string().nullish(), + frequency: z.string().optional().default('once'), + notification_id: z.string().nullish(), + start_time: z.string().nullish(), + status: z.string().optional().default('active'), +}) + +/** + * Accounts added successfully + */ +export const zPostAdminBatchAddNotificationAccountsResponse = z.record(z.string(), z.unknown()) + +export const zDeleteAdminDeleteExploreBannerByBannerIdPath = z.object({ + banner_id: z.string(), +}) + +/** + * Banner deleted successfully + */ +export const zDeleteAdminDeleteExploreBannerByBannerIdResponse = z.record(z.string(), z.unknown()) + +export const zPostAdminInsertExploreAppsBody = zInsertExploreAppPayload + +export const zPostAdminInsertExploreAppsResponse = z.union([ + z.record(z.string(), z.unknown()), + z.record(z.string(), z.unknown()), +]) + +export const zDeleteAdminInsertExploreAppsByAppIdPath = z.object({ + app_id: z.string(), +}) + +/** + * App removed successfully + */ +export const zDeleteAdminInsertExploreAppsByAppIdResponse = z.record(z.string(), z.unknown()) + +export const zPostAdminInsertExploreBannerBody = zInsertExploreBannerPayload + +/** + * Banner inserted successfully + */ +export const zPostAdminInsertExploreBannerResponse = z.record(z.string(), z.unknown()) + +export const zPostAdminUpsertNotificationBody = zUpsertNotificationPayload + +/** + * Notification upserted successfully + */ +export const zPostAdminUpsertNotificationResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/all-workspaces/orpc.gen.ts b/packages/contracts/generated/api/console/all-workspaces/orpc.gen.ts new file mode 100644 index 0000000000..91ccdbc408 --- /dev/null +++ b/packages/contracts/generated/api/console/all-workspaces/orpc.gen.ts @@ -0,0 +1,25 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { zGetAllWorkspacesQuery, zGetAllWorkspacesResponse } from './zod.gen' + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAllWorkspaces', + path: '/all-workspaces', + tags: ['console'], + }) + .input(z.object({ query: zGetAllWorkspacesQuery.optional() })) + .output(zGetAllWorkspacesResponse) + +export const allWorkspaces = { + get, +} + +export const contract = { + allWorkspaces, +} diff --git a/packages/contracts/generated/api/console/all-workspaces/types.gen.ts b/packages/contracts/generated/api/console/all-workspaces/types.gen.ts new file mode 100644 index 0000000000..2c30287835 --- /dev/null +++ b/packages/contracts/generated/api/console/all-workspaces/types.gen.ts @@ -0,0 +1,23 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type GetAllWorkspacesData = { + body?: never + path?: never + query?: { + limit?: number + page?: number + } + url: '/all-workspaces' +} + +export type GetAllWorkspacesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAllWorkspacesResponse = GetAllWorkspacesResponses[keyof GetAllWorkspacesResponses] diff --git a/packages/contracts/generated/api/console/all-workspaces/zod.gen.ts b/packages/contracts/generated/api/console/all-workspaces/zod.gen.ts new file mode 100644 index 0000000000..bdb5f0d132 --- /dev/null +++ b/packages/contracts/generated/api/console/all-workspaces/zod.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +export const zGetAllWorkspacesQuery = z.object({ + limit: z.int().gte(1).lte(100).optional().default(20), + page: z.int().gte(1).lte(99999).optional().default(1), +}) + +/** + * Success + */ +export const zGetAllWorkspacesResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/api-based-extension/orpc.gen.ts b/packages/contracts/generated/api/console/api-based-extension/orpc.gen.ts new file mode 100644 index 0000000000..b47ed17f34 --- /dev/null +++ b/packages/contracts/generated/api/console/api-based-extension/orpc.gen.ts @@ -0,0 +1,109 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteApiBasedExtensionByIdPath, + zDeleteApiBasedExtensionByIdResponse, + zGetApiBasedExtensionByIdPath, + zGetApiBasedExtensionByIdResponse, + zGetApiBasedExtensionResponse, + zPostApiBasedExtensionBody, + zPostApiBasedExtensionByIdBody, + zPostApiBasedExtensionByIdPath, + zPostApiBasedExtensionByIdResponse, + zPostApiBasedExtensionResponse, +} from './zod.gen' + +/** + * Delete API-based extension + */ +export const delete_ = oc + .route({ + description: 'Delete API-based extension', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteApiBasedExtensionById', + path: '/api-based-extension/{id}', + successStatus: 204, + tags: ['console'], + }) + .input(z.object({ params: zDeleteApiBasedExtensionByIdPath })) + .output(zDeleteApiBasedExtensionByIdResponse) + +/** + * Get API-based extension by ID + */ +export const get = oc + .route({ + description: 'Get API-based extension by ID', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getApiBasedExtensionById', + path: '/api-based-extension/{id}', + tags: ['console'], + }) + .input(z.object({ params: zGetApiBasedExtensionByIdPath })) + .output(zGetApiBasedExtensionByIdResponse) + +/** + * Update API-based extension + */ +export const post = oc + .route({ + description: 'Update API-based extension', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postApiBasedExtensionById', + path: '/api-based-extension/{id}', + tags: ['console'], + }) + .input(z.object({ body: zPostApiBasedExtensionByIdBody, params: zPostApiBasedExtensionByIdPath })) + .output(zPostApiBasedExtensionByIdResponse) + +export const byId = { + delete: delete_, + get, + post, +} + +/** + * Get all API-based extensions for current tenant + */ +export const get2 = oc + .route({ + description: 'Get all API-based extensions for current tenant', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getApiBasedExtension', + path: '/api-based-extension', + tags: ['console'], + }) + .output(zGetApiBasedExtensionResponse) + +/** + * Create a new API-based extension + */ +export const post2 = oc + .route({ + description: 'Create a new API-based extension', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postApiBasedExtension', + path: '/api-based-extension', + successStatus: 201, + tags: ['console'], + }) + .input(z.object({ body: zPostApiBasedExtensionBody })) + .output(zPostApiBasedExtensionResponse) + +export const apiBasedExtension = { + get: get2, + post: post2, + byId, +} + +export const contract = { + apiBasedExtension, +} diff --git a/packages/contracts/generated/api/console/api-based-extension/types.gen.ts b/packages/contracts/generated/api/console/api-based-extension/types.gen.ts new file mode 100644 index 0000000000..f7b12f5b3f --- /dev/null +++ b/packages/contracts/generated/api/console/api-based-extension/types.gen.ts @@ -0,0 +1,99 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type ApiBasedExtensionListResponse = Array + +export type ApiBasedExtensionPayload = { + api_endpoint: string + api_key: string + name: string +} + +export type ApiBasedExtensionResponse = { + api_endpoint: string + api_key: string + created_at?: number | null + id: string + name: string +} + +export type GetApiBasedExtensionData = { + body?: never + path?: never + query?: never + url: '/api-based-extension' +} + +export type GetApiBasedExtensionResponses = { + 200: ApiBasedExtensionListResponse +} + +export type GetApiBasedExtensionResponse + = GetApiBasedExtensionResponses[keyof GetApiBasedExtensionResponses] + +export type PostApiBasedExtensionData = { + body: ApiBasedExtensionPayload + path?: never + query?: never + url: '/api-based-extension' +} + +export type PostApiBasedExtensionResponses = { + 201: ApiBasedExtensionResponse +} + +export type PostApiBasedExtensionResponse + = PostApiBasedExtensionResponses[keyof PostApiBasedExtensionResponses] + +export type DeleteApiBasedExtensionByIdData = { + body?: never + path: { + id: string + } + query?: never + url: '/api-based-extension/{id}' +} + +export type DeleteApiBasedExtensionByIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteApiBasedExtensionByIdResponse + = DeleteApiBasedExtensionByIdResponses[keyof DeleteApiBasedExtensionByIdResponses] + +export type GetApiBasedExtensionByIdData = { + body?: never + path: { + id: string + } + query?: never + url: '/api-based-extension/{id}' +} + +export type GetApiBasedExtensionByIdResponses = { + 200: ApiBasedExtensionResponse +} + +export type GetApiBasedExtensionByIdResponse + = GetApiBasedExtensionByIdResponses[keyof GetApiBasedExtensionByIdResponses] + +export type PostApiBasedExtensionByIdData = { + body: ApiBasedExtensionPayload + path: { + id: string + } + query?: never + url: '/api-based-extension/{id}' +} + +export type PostApiBasedExtensionByIdResponses = { + 200: ApiBasedExtensionResponse +} + +export type PostApiBasedExtensionByIdResponse + = PostApiBasedExtensionByIdResponses[keyof PostApiBasedExtensionByIdResponses] diff --git a/packages/contracts/generated/api/console/api-based-extension/zod.gen.ts b/packages/contracts/generated/api/console/api-based-extension/zod.gen.ts new file mode 100644 index 0000000000..43f38a5214 --- /dev/null +++ b/packages/contracts/generated/api/console/api-based-extension/zod.gen.ts @@ -0,0 +1,66 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * APIBasedExtensionPayload + */ +export const zApiBasedExtensionPayload = z.object({ + api_endpoint: z.string(), + api_key: z.string(), + name: z.string(), +}) + +/** + * APIBasedExtensionResponse + */ +export const zApiBasedExtensionResponse = z.object({ + api_endpoint: z.string(), + api_key: z.string(), + created_at: z.int().nullish(), + id: z.string(), + name: z.string(), +}) + +export const zApiBasedExtensionListResponse = z.array(zApiBasedExtensionResponse) + +/** + * Success + */ +export const zGetApiBasedExtensionResponse = zApiBasedExtensionListResponse + +export const zPostApiBasedExtensionBody = zApiBasedExtensionPayload + +/** + * Extension created successfully + */ +export const zPostApiBasedExtensionResponse = zApiBasedExtensionResponse + +export const zDeleteApiBasedExtensionByIdPath = z.object({ + id: z.string(), +}) + +/** + * Extension deleted successfully + */ +export const zDeleteApiBasedExtensionByIdResponse = z.record(z.string(), z.unknown()) + +export const zGetApiBasedExtensionByIdPath = z.object({ + id: z.string(), +}) + +/** + * Success + */ +export const zGetApiBasedExtensionByIdResponse = zApiBasedExtensionResponse + +export const zPostApiBasedExtensionByIdBody = zApiBasedExtensionPayload + +export const zPostApiBasedExtensionByIdPath = z.object({ + id: z.string(), +}) + +/** + * Extension updated successfully + */ +export const zPostApiBasedExtensionByIdResponse = zApiBasedExtensionResponse diff --git a/packages/contracts/generated/api/console/api-key-auth/orpc.gen.ts b/packages/contracts/generated/api/console/api-key-auth/orpc.gen.ts new file mode 100644 index 0000000000..a113e39c15 --- /dev/null +++ b/packages/contracts/generated/api/console/api-key-auth/orpc.gen.ts @@ -0,0 +1,66 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteApiKeyAuthDataSourceByBindingIdPath, + zDeleteApiKeyAuthDataSourceByBindingIdResponse, + zGetApiKeyAuthDataSourceResponse, + zPostApiKeyAuthDataSourceBindingBody, + zPostApiKeyAuthDataSourceBindingResponse, +} from './zod.gen' + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postApiKeyAuthDataSourceBinding', + path: '/api-key-auth/data-source/binding', + tags: ['console'], + }) + .input(z.object({ body: zPostApiKeyAuthDataSourceBindingBody })) + .output(zPostApiKeyAuthDataSourceBindingResponse) + +export const binding = { + post, +} + +export const delete_ = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteApiKeyAuthDataSourceByBindingId', + path: '/api-key-auth/data-source/{binding_id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteApiKeyAuthDataSourceByBindingIdPath })) + .output(zDeleteApiKeyAuthDataSourceByBindingIdResponse) + +export const byBindingId = { + delete: delete_, +} + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getApiKeyAuthDataSource', + path: '/api-key-auth/data-source', + tags: ['console'], + }) + .output(zGetApiKeyAuthDataSourceResponse) + +export const dataSource = { + get, + binding, + byBindingId, +} + +export const apiKeyAuth = { + dataSource, +} + +export const contract = { + apiKeyAuth, +} diff --git a/packages/contracts/generated/api/console/api-key-auth/types.gen.ts b/packages/contracts/generated/api/console/api-key-auth/types.gen.ts new file mode 100644 index 0000000000..970b3a44e9 --- /dev/null +++ b/packages/contracts/generated/api/console/api-key-auth/types.gen.ts @@ -0,0 +1,63 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type ApiKeyAuthBindingPayload = { + category: string + credentials: { + [key: string]: unknown + } + provider: string +} + +export type GetApiKeyAuthDataSourceData = { + body?: never + path?: never + query?: never + url: '/api-key-auth/data-source' +} + +export type GetApiKeyAuthDataSourceResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetApiKeyAuthDataSourceResponse + = GetApiKeyAuthDataSourceResponses[keyof GetApiKeyAuthDataSourceResponses] + +export type PostApiKeyAuthDataSourceBindingData = { + body: ApiKeyAuthBindingPayload + path?: never + query?: never + url: '/api-key-auth/data-source/binding' +} + +export type PostApiKeyAuthDataSourceBindingResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostApiKeyAuthDataSourceBindingResponse + = PostApiKeyAuthDataSourceBindingResponses[keyof PostApiKeyAuthDataSourceBindingResponses] + +export type DeleteApiKeyAuthDataSourceByBindingIdData = { + body?: never + path: { + binding_id: string + } + query?: never + url: '/api-key-auth/data-source/{binding_id}' +} + +export type DeleteApiKeyAuthDataSourceByBindingIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteApiKeyAuthDataSourceByBindingIdResponse + = DeleteApiKeyAuthDataSourceByBindingIdResponses[keyof DeleteApiKeyAuthDataSourceByBindingIdResponses] diff --git a/packages/contracts/generated/api/console/api-key-auth/zod.gen.ts b/packages/contracts/generated/api/console/api-key-auth/zod.gen.ts new file mode 100644 index 0000000000..6c7f5ad19b --- /dev/null +++ b/packages/contracts/generated/api/console/api-key-auth/zod.gen.ts @@ -0,0 +1,33 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * ApiKeyAuthBindingPayload + */ +export const zApiKeyAuthBindingPayload = z.object({ + category: z.string(), + credentials: z.record(z.string(), z.unknown()), + provider: z.string(), +}) + +/** + * Success + */ +export const zGetApiKeyAuthDataSourceResponse = z.record(z.string(), z.unknown()) + +export const zPostApiKeyAuthDataSourceBindingBody = zApiKeyAuthBindingPayload + +/** + * Success + */ +export const zPostApiKeyAuthDataSourceBindingResponse = z.record(z.string(), z.unknown()) + +export const zDeleteApiKeyAuthDataSourceByBindingIdPath = z.object({ + binding_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteApiKeyAuthDataSourceByBindingIdResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/app/orpc.gen.ts b/packages/contracts/generated/api/console/app/orpc.gen.ts new file mode 100644 index 0000000000..7ccb933866 --- /dev/null +++ b/packages/contracts/generated/api/console/app/orpc.gen.ts @@ -0,0 +1,33 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { zGetAppPromptTemplatesQuery, zGetAppPromptTemplatesResponse } from './zod.gen' + +/** + * Get advanced prompt templates based on app mode and model configuration + */ +export const get = oc + .route({ + description: 'Get advanced prompt templates based on app mode and model configuration', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppPromptTemplates', + path: '/app/prompt-templates', + tags: ['console'], + }) + .input(z.object({ query: zGetAppPromptTemplatesQuery })) + .output(zGetAppPromptTemplatesResponse) + +export const promptTemplates = { + get, +} + +export const app = { + promptTemplates, +} + +export const contract = { + app, +} diff --git a/packages/contracts/generated/api/console/app/types.gen.ts b/packages/contracts/generated/api/console/app/types.gen.ts new file mode 100644 index 0000000000..ad8334ad6d --- /dev/null +++ b/packages/contracts/generated/api/console/app/types.gen.ts @@ -0,0 +1,35 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type GetAppPromptTemplatesData = { + body?: never + path?: never + query: { + app_mode: string + has_context?: string + model_mode: string + model_name: string + } + url: '/app/prompt-templates' +} + +export type GetAppPromptTemplatesErrors = { + 400: { + [key: string]: unknown + } +} + +export type GetAppPromptTemplatesError + = GetAppPromptTemplatesErrors[keyof GetAppPromptTemplatesErrors] + +export type GetAppPromptTemplatesResponses = { + 200: Array<{ + [key: string]: unknown + }> +} + +export type GetAppPromptTemplatesResponse + = GetAppPromptTemplatesResponses[keyof GetAppPromptTemplatesResponses] diff --git a/packages/contracts/generated/api/console/app/zod.gen.ts b/packages/contracts/generated/api/console/app/zod.gen.ts new file mode 100644 index 0000000000..df13f62825 --- /dev/null +++ b/packages/contracts/generated/api/console/app/zod.gen.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +export const zGetAppPromptTemplatesQuery = z.object({ + app_mode: z.string(), + has_context: z.string().optional().default('true'), + model_mode: z.string(), + model_name: z.string(), +}) + +/** + * Prompt templates retrieved successfully + */ +export const zGetAppPromptTemplatesResponse = z.array(z.record(z.string(), z.unknown())) diff --git a/packages/contracts/generated/api/console/apps/orpc.gen.ts b/packages/contracts/generated/api/console/apps/orpc.gen.ts new file mode 100644 index 0000000000..069976904d --- /dev/null +++ b/packages/contracts/generated/api/console/apps/orpc.gen.ts @@ -0,0 +1,3775 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteAppsByAppIdAnnotationsByAnnotationIdPath, + zDeleteAppsByAppIdAnnotationsByAnnotationIdResponse, + zDeleteAppsByAppIdAnnotationsPath, + zDeleteAppsByAppIdAnnotationsResponse, + zDeleteAppsByAppIdChatConversationsByConversationIdPath, + zDeleteAppsByAppIdChatConversationsByConversationIdResponse, + zDeleteAppsByAppIdCompletionConversationsByConversationIdPath, + zDeleteAppsByAppIdCompletionConversationsByConversationIdResponse, + zDeleteAppsByAppIdPath, + zDeleteAppsByAppIdResponse, + zDeleteAppsByAppIdTraceConfigBody, + zDeleteAppsByAppIdTraceConfigPath, + zDeleteAppsByAppIdTraceConfigResponse, + zDeleteAppsByAppIdWorkflowCommentsByCommentIdPath, + zDeleteAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdPath, + zDeleteAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponse, + zDeleteAppsByAppIdWorkflowCommentsByCommentIdResponse, + zDeleteAppsByAppIdWorkflowsByWorkflowIdPath, + zDeleteAppsByAppIdWorkflowsByWorkflowIdResponse, + zDeleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesPath, + zDeleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponse, + zDeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdPath, + zDeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdResponse, + zDeleteAppsByAppIdWorkflowsDraftVariablesPath, + zDeleteAppsByAppIdWorkflowsDraftVariablesResponse, + zDeleteAppsByResourceIdApiKeysByApiKeyIdPath, + zDeleteAppsByResourceIdApiKeysByApiKeyIdResponse, + zGetAppsByAppIdAdvancedChatWorkflowRunsCountPath, + zGetAppsByAppIdAdvancedChatWorkflowRunsCountQuery, + zGetAppsByAppIdAdvancedChatWorkflowRunsCountResponse, + zGetAppsByAppIdAdvancedChatWorkflowRunsPath, + zGetAppsByAppIdAdvancedChatWorkflowRunsQuery, + zGetAppsByAppIdAdvancedChatWorkflowRunsResponse, + zGetAppsByAppIdAgentLogsPath, + zGetAppsByAppIdAgentLogsQuery, + zGetAppsByAppIdAgentLogsResponse, + zGetAppsByAppIdAnnotationReplyByActionStatusByJobIdPath, + zGetAppsByAppIdAnnotationReplyByActionStatusByJobIdResponse, + zGetAppsByAppIdAnnotationsBatchImportStatusByJobIdPath, + zGetAppsByAppIdAnnotationsBatchImportStatusByJobIdResponse, + zGetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesPath, + zGetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesQuery, + zGetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesResponse, + zGetAppsByAppIdAnnotationsCountPath, + zGetAppsByAppIdAnnotationsCountResponse, + zGetAppsByAppIdAnnotationSettingPath, + zGetAppsByAppIdAnnotationSettingResponse, + zGetAppsByAppIdAnnotationsExportPath, + zGetAppsByAppIdAnnotationsExportResponse, + zGetAppsByAppIdAnnotationsPath, + zGetAppsByAppIdAnnotationsQuery, + zGetAppsByAppIdAnnotationsResponse, + zGetAppsByAppIdChatConversationsByConversationIdPath, + zGetAppsByAppIdChatConversationsByConversationIdResponse, + zGetAppsByAppIdChatConversationsPath, + zGetAppsByAppIdChatConversationsQuery, + zGetAppsByAppIdChatConversationsResponse, + zGetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsPath, + zGetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsResponse, + zGetAppsByAppIdChatMessagesPath, + zGetAppsByAppIdChatMessagesQuery, + zGetAppsByAppIdChatMessagesResponse, + zGetAppsByAppIdCompletionConversationsByConversationIdPath, + zGetAppsByAppIdCompletionConversationsByConversationIdResponse, + zGetAppsByAppIdCompletionConversationsPath, + zGetAppsByAppIdCompletionConversationsQuery, + zGetAppsByAppIdCompletionConversationsResponse, + zGetAppsByAppIdConversationVariablesPath, + zGetAppsByAppIdConversationVariablesQuery, + zGetAppsByAppIdConversationVariablesResponse, + zGetAppsByAppIdExportPath, + zGetAppsByAppIdExportQuery, + zGetAppsByAppIdExportResponse, + zGetAppsByAppIdFeedbacksExportPath, + zGetAppsByAppIdFeedbacksExportQuery, + zGetAppsByAppIdFeedbacksExportResponse, + zGetAppsByAppIdMessagesByMessageIdPath, + zGetAppsByAppIdMessagesByMessageIdResponse, + zGetAppsByAppIdPath, + zGetAppsByAppIdResponse, + zGetAppsByAppIdServerPath, + zGetAppsByAppIdServerResponse, + zGetAppsByAppIdStatisticsAverageResponseTimePath, + zGetAppsByAppIdStatisticsAverageResponseTimeQuery, + zGetAppsByAppIdStatisticsAverageResponseTimeResponse, + zGetAppsByAppIdStatisticsAverageSessionInteractionsPath, + zGetAppsByAppIdStatisticsAverageSessionInteractionsQuery, + zGetAppsByAppIdStatisticsAverageSessionInteractionsResponse, + zGetAppsByAppIdStatisticsDailyConversationsPath, + zGetAppsByAppIdStatisticsDailyConversationsQuery, + zGetAppsByAppIdStatisticsDailyConversationsResponse, + zGetAppsByAppIdStatisticsDailyEndUsersPath, + zGetAppsByAppIdStatisticsDailyEndUsersQuery, + zGetAppsByAppIdStatisticsDailyEndUsersResponse, + zGetAppsByAppIdStatisticsDailyMessagesPath, + zGetAppsByAppIdStatisticsDailyMessagesQuery, + zGetAppsByAppIdStatisticsDailyMessagesResponse, + zGetAppsByAppIdStatisticsTokenCostsPath, + zGetAppsByAppIdStatisticsTokenCostsQuery, + zGetAppsByAppIdStatisticsTokenCostsResponse, + zGetAppsByAppIdStatisticsTokensPerSecondPath, + zGetAppsByAppIdStatisticsTokensPerSecondQuery, + zGetAppsByAppIdStatisticsTokensPerSecondResponse, + zGetAppsByAppIdStatisticsUserSatisfactionRatePath, + zGetAppsByAppIdStatisticsUserSatisfactionRateQuery, + zGetAppsByAppIdStatisticsUserSatisfactionRateResponse, + zGetAppsByAppIdTextToAudioVoicesPath, + zGetAppsByAppIdTextToAudioVoicesQuery, + zGetAppsByAppIdTextToAudioVoicesResponse, + zGetAppsByAppIdTraceConfigPath, + zGetAppsByAppIdTraceConfigQuery, + zGetAppsByAppIdTraceConfigResponse, + zGetAppsByAppIdTracePath, + zGetAppsByAppIdTraceResponse, + zGetAppsByAppIdTriggersPath, + zGetAppsByAppIdTriggersResponse, + zGetAppsByAppIdWorkflowAppLogsPath, + zGetAppsByAppIdWorkflowAppLogsQuery, + zGetAppsByAppIdWorkflowAppLogsResponse, + zGetAppsByAppIdWorkflowArchivedLogsPath, + zGetAppsByAppIdWorkflowArchivedLogsQuery, + zGetAppsByAppIdWorkflowArchivedLogsResponse, + zGetAppsByAppIdWorkflowCommentsByCommentIdPath, + zGetAppsByAppIdWorkflowCommentsByCommentIdResponse, + zGetAppsByAppIdWorkflowCommentsMentionUsersPath, + zGetAppsByAppIdWorkflowCommentsMentionUsersResponse, + zGetAppsByAppIdWorkflowCommentsPath, + zGetAppsByAppIdWorkflowCommentsResponse, + zGetAppsByAppIdWorkflowRunsByRunIdExportPath, + zGetAppsByAppIdWorkflowRunsByRunIdExportResponse, + zGetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsPath, + zGetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsResponse, + zGetAppsByAppIdWorkflowRunsByRunIdPath, + zGetAppsByAppIdWorkflowRunsByRunIdResponse, + zGetAppsByAppIdWorkflowRunsCountPath, + zGetAppsByAppIdWorkflowRunsCountQuery, + zGetAppsByAppIdWorkflowRunsCountResponse, + zGetAppsByAppIdWorkflowRunsPath, + zGetAppsByAppIdWorkflowRunsQuery, + zGetAppsByAppIdWorkflowRunsResponse, + zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypePath, + zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeQuery, + zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse, + zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsPath, + zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsResponse, + zGetAppsByAppIdWorkflowsDraftConversationVariablesPath, + zGetAppsByAppIdWorkflowsDraftConversationVariablesResponse, + zGetAppsByAppIdWorkflowsDraftEnvironmentVariablesPath, + zGetAppsByAppIdWorkflowsDraftEnvironmentVariablesResponse, + zGetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunPath, + zGetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunResponse, + zGetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesPath, + zGetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponse, + zGetAppsByAppIdWorkflowsDraftPath, + zGetAppsByAppIdWorkflowsDraftResponse, + zGetAppsByAppIdWorkflowsDraftSystemVariablesPath, + zGetAppsByAppIdWorkflowsDraftSystemVariablesResponse, + zGetAppsByAppIdWorkflowsDraftVariablesByVariableIdPath, + zGetAppsByAppIdWorkflowsDraftVariablesByVariableIdResponse, + zGetAppsByAppIdWorkflowsDraftVariablesPath, + zGetAppsByAppIdWorkflowsDraftVariablesQuery, + zGetAppsByAppIdWorkflowsDraftVariablesResponse, + zGetAppsByAppIdWorkflowsPath, + zGetAppsByAppIdWorkflowsPublishPath, + zGetAppsByAppIdWorkflowsPublishResponse, + zGetAppsByAppIdWorkflowsQuery, + zGetAppsByAppIdWorkflowsResponse, + zGetAppsByAppIdWorkflowStatisticsAverageAppInteractionsPath, + zGetAppsByAppIdWorkflowStatisticsAverageAppInteractionsQuery, + zGetAppsByAppIdWorkflowStatisticsAverageAppInteractionsResponse, + zGetAppsByAppIdWorkflowStatisticsDailyConversationsPath, + zGetAppsByAppIdWorkflowStatisticsDailyConversationsQuery, + zGetAppsByAppIdWorkflowStatisticsDailyConversationsResponse, + zGetAppsByAppIdWorkflowStatisticsDailyTerminalsPath, + zGetAppsByAppIdWorkflowStatisticsDailyTerminalsQuery, + zGetAppsByAppIdWorkflowStatisticsDailyTerminalsResponse, + zGetAppsByAppIdWorkflowStatisticsTokenCostsPath, + zGetAppsByAppIdWorkflowStatisticsTokenCostsQuery, + zGetAppsByAppIdWorkflowStatisticsTokenCostsResponse, + zGetAppsByAppIdWorkflowsTriggersWebhookPath, + zGetAppsByAppIdWorkflowsTriggersWebhookQuery, + zGetAppsByAppIdWorkflowsTriggersWebhookResponse, + zGetAppsByResourceIdApiKeysPath, + zGetAppsByResourceIdApiKeysResponse, + zGetAppsByServerIdServerRefreshPath, + zGetAppsByServerIdServerRefreshResponse, + zGetAppsImportsByAppIdCheckDependenciesPath, + zGetAppsImportsByAppIdCheckDependenciesResponse, + zGetAppsQuery, + zGetAppsResponse, + zGetAppsWorkflowsOnlineUsersQuery, + zGetAppsWorkflowsOnlineUsersResponse, + zPatchAppsByAppIdTraceConfigBody, + zPatchAppsByAppIdTraceConfigPath, + zPatchAppsByAppIdTraceConfigResponse, + zPatchAppsByAppIdWorkflowsByWorkflowIdBody, + zPatchAppsByAppIdWorkflowsByWorkflowIdPath, + zPatchAppsByAppIdWorkflowsByWorkflowIdResponse, + zPatchAppsByAppIdWorkflowsDraftVariablesByVariableIdBody, + zPatchAppsByAppIdWorkflowsDraftVariablesByVariableIdPath, + zPatchAppsByAppIdWorkflowsDraftVariablesByVariableIdResponse, + zPostAppsBody, + zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewBody, + zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewPath, + zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponse, + zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunBody, + zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunPath, + zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunResponse, + zPostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunBody, + zPostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunPath, + zPostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunResponse, + zPostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunBody, + zPostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunPath, + zPostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunResponse, + zPostAppsByAppIdAdvancedChatWorkflowsDraftRunBody, + zPostAppsByAppIdAdvancedChatWorkflowsDraftRunPath, + zPostAppsByAppIdAdvancedChatWorkflowsDraftRunResponse, + zPostAppsByAppIdAnnotationReplyByActionBody, + zPostAppsByAppIdAnnotationReplyByActionPath, + zPostAppsByAppIdAnnotationReplyByActionResponse, + zPostAppsByAppIdAnnotationsBatchImportPath, + zPostAppsByAppIdAnnotationsBatchImportResponse, + zPostAppsByAppIdAnnotationsBody, + zPostAppsByAppIdAnnotationsByAnnotationIdBody, + zPostAppsByAppIdAnnotationsByAnnotationIdPath, + zPostAppsByAppIdAnnotationsByAnnotationIdResponse, + zPostAppsByAppIdAnnotationSettingsByAnnotationSettingIdBody, + zPostAppsByAppIdAnnotationSettingsByAnnotationSettingIdPath, + zPostAppsByAppIdAnnotationSettingsByAnnotationSettingIdResponse, + zPostAppsByAppIdAnnotationsPath, + zPostAppsByAppIdAnnotationsResponse, + zPostAppsByAppIdApiEnableBody, + zPostAppsByAppIdApiEnablePath, + zPostAppsByAppIdApiEnableResponse, + zPostAppsByAppIdAudioToTextPath, + zPostAppsByAppIdAudioToTextResponse, + zPostAppsByAppIdChatMessagesByTaskIdStopPath, + zPostAppsByAppIdChatMessagesByTaskIdStopResponse, + zPostAppsByAppIdCompletionMessagesBody, + zPostAppsByAppIdCompletionMessagesByTaskIdStopPath, + zPostAppsByAppIdCompletionMessagesByTaskIdStopResponse, + zPostAppsByAppIdCompletionMessagesPath, + zPostAppsByAppIdCompletionMessagesResponse, + zPostAppsByAppIdConvertToWorkflowBody, + zPostAppsByAppIdConvertToWorkflowPath, + zPostAppsByAppIdConvertToWorkflowResponse, + zPostAppsByAppIdCopyBody, + zPostAppsByAppIdCopyPath, + zPostAppsByAppIdCopyResponse, + zPostAppsByAppIdFeedbacksBody, + zPostAppsByAppIdFeedbacksPath, + zPostAppsByAppIdFeedbacksResponse, + zPostAppsByAppIdIconBody, + zPostAppsByAppIdIconPath, + zPostAppsByAppIdIconResponse, + zPostAppsByAppIdModelConfigBody, + zPostAppsByAppIdModelConfigPath, + zPostAppsByAppIdModelConfigResponse, + zPostAppsByAppIdNameBody, + zPostAppsByAppIdNamePath, + zPostAppsByAppIdNameResponse, + zPostAppsByAppIdPublishToCreatorsPlatformPath, + zPostAppsByAppIdPublishToCreatorsPlatformResponse, + zPostAppsByAppIdServerBody, + zPostAppsByAppIdServerPath, + zPostAppsByAppIdServerResponse, + zPostAppsByAppIdSiteAccessTokenResetPath, + zPostAppsByAppIdSiteAccessTokenResetResponse, + zPostAppsByAppIdSiteBody, + zPostAppsByAppIdSiteEnableBody, + zPostAppsByAppIdSiteEnablePath, + zPostAppsByAppIdSiteEnableResponse, + zPostAppsByAppIdSitePath, + zPostAppsByAppIdSiteResponse, + zPostAppsByAppIdTextToAudioBody, + zPostAppsByAppIdTextToAudioPath, + zPostAppsByAppIdTextToAudioResponse, + zPostAppsByAppIdTraceBody, + zPostAppsByAppIdTraceConfigBody, + zPostAppsByAppIdTraceConfigPath, + zPostAppsByAppIdTraceConfigResponse, + zPostAppsByAppIdTracePath, + zPostAppsByAppIdTraceResponse, + zPostAppsByAppIdTriggerEnableBody, + zPostAppsByAppIdTriggerEnablePath, + zPostAppsByAppIdTriggerEnableResponse, + zPostAppsByAppIdWorkflowCommentsBody, + zPostAppsByAppIdWorkflowCommentsByCommentIdRepliesBody, + zPostAppsByAppIdWorkflowCommentsByCommentIdRepliesPath, + zPostAppsByAppIdWorkflowCommentsByCommentIdRepliesResponse, + zPostAppsByAppIdWorkflowCommentsByCommentIdResolvePath, + zPostAppsByAppIdWorkflowCommentsByCommentIdResolveResponse, + zPostAppsByAppIdWorkflowCommentsPath, + zPostAppsByAppIdWorkflowCommentsResponse, + zPostAppsByAppIdWorkflowRunsTasksByTaskIdStopPath, + zPostAppsByAppIdWorkflowRunsTasksByTaskIdStopResponse, + zPostAppsByAppIdWorkflowsByWorkflowIdRestorePath, + zPostAppsByAppIdWorkflowsByWorkflowIdRestoreResponse, + zPostAppsByAppIdWorkflowsDraftBody, + zPostAppsByAppIdWorkflowsDraftConversationVariablesBody, + zPostAppsByAppIdWorkflowsDraftConversationVariablesPath, + zPostAppsByAppIdWorkflowsDraftConversationVariablesResponse, + zPostAppsByAppIdWorkflowsDraftEnvironmentVariablesBody, + zPostAppsByAppIdWorkflowsDraftEnvironmentVariablesPath, + zPostAppsByAppIdWorkflowsDraftEnvironmentVariablesResponse, + zPostAppsByAppIdWorkflowsDraftFeaturesBody, + zPostAppsByAppIdWorkflowsDraftFeaturesPath, + zPostAppsByAppIdWorkflowsDraftFeaturesResponse, + zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestBody, + zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestPath, + zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestResponse, + zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewBody, + zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewPath, + zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponse, + zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunBody, + zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunPath, + zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunResponse, + zPostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunBody, + zPostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunPath, + zPostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunResponse, + zPostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunBody, + zPostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunPath, + zPostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunResponse, + zPostAppsByAppIdWorkflowsDraftNodesByNodeIdRunBody, + zPostAppsByAppIdWorkflowsDraftNodesByNodeIdRunPath, + zPostAppsByAppIdWorkflowsDraftNodesByNodeIdRunResponse, + zPostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunPath, + zPostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunResponse, + zPostAppsByAppIdWorkflowsDraftPath, + zPostAppsByAppIdWorkflowsDraftResponse, + zPostAppsByAppIdWorkflowsDraftRunBody, + zPostAppsByAppIdWorkflowsDraftRunPath, + zPostAppsByAppIdWorkflowsDraftRunResponse, + zPostAppsByAppIdWorkflowsDraftTriggerRunAllBody, + zPostAppsByAppIdWorkflowsDraftTriggerRunAllPath, + zPostAppsByAppIdWorkflowsDraftTriggerRunAllResponse, + zPostAppsByAppIdWorkflowsDraftTriggerRunBody, + zPostAppsByAppIdWorkflowsDraftTriggerRunPath, + zPostAppsByAppIdWorkflowsDraftTriggerRunResponse, + zPostAppsByAppIdWorkflowsPublishBody, + zPostAppsByAppIdWorkflowsPublishPath, + zPostAppsByAppIdWorkflowsPublishResponse, + zPostAppsByResourceIdApiKeysPath, + zPostAppsByResourceIdApiKeysResponse, + zPostAppsImportsBody, + zPostAppsImportsByImportIdConfirmPath, + zPostAppsImportsByImportIdConfirmResponse, + zPostAppsImportsResponse, + zPostAppsResponse, + zPutAppsByAppIdBody, + zPutAppsByAppIdPath, + zPutAppsByAppIdResponse, + zPutAppsByAppIdServerBody, + zPutAppsByAppIdServerPath, + zPutAppsByAppIdServerResponse, + zPutAppsByAppIdWorkflowCommentsByCommentIdBody, + zPutAppsByAppIdWorkflowCommentsByCommentIdPath, + zPutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdBody, + zPutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdPath, + zPutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponse, + zPutAppsByAppIdWorkflowCommentsByCommentIdResponse, + zPutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetPath, + zPutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetResponse, +} from './zod.gen' + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsImportsByAppIdCheckDependencies', + path: '/apps/imports/{app_id}/check-dependencies', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsImportsByAppIdCheckDependenciesPath })) + .output(zGetAppsImportsByAppIdCheckDependenciesResponse) + +export const checkDependencies = { + get, +} + +export const byAppId = { + checkDependencies, +} + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsImportsByImportIdConfirm', + path: '/apps/imports/{import_id}/confirm', + tags: ['console'], + }) + .input(z.object({ params: zPostAppsImportsByImportIdConfirmPath })) + .output(zPostAppsImportsByImportIdConfirmResponse) + +export const confirm = { + post, +} + +export const byImportId = { + confirm, +} + +export const post2 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsImports', + path: '/apps/imports', + tags: ['console'], + }) + .input(z.object({ body: zPostAppsImportsBody })) + .output(zPostAppsImportsResponse) + +export const imports = { + post: post2, + byAppId, + byImportId, +} + +/** + * Get workflow online users + */ +export const get2 = oc + .route({ + description: 'Get workflow online users', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsWorkflowsOnlineUsers', + path: '/apps/workflows/online-users', + tags: ['console'], + }) + .input(z.object({ query: zGetAppsWorkflowsOnlineUsersQuery })) + .output(zGetAppsWorkflowsOnlineUsersResponse) + +export const onlineUsers = { + get: get2, +} + +export const workflows = { + onlineUsers, +} + +/** + * Get advanced chat workflow runs count statistics + * + * Get advanced chat workflow runs count statistics + */ +export const get3 = oc + .route({ + description: 'Get advanced chat workflow runs count statistics', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdAdvancedChatWorkflowRunsCount', + path: '/apps/{app_id}/advanced-chat/workflow-runs/count', + summary: 'Get advanced chat workflow runs count statistics', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdAdvancedChatWorkflowRunsCountPath, + query: zGetAppsByAppIdAdvancedChatWorkflowRunsCountQuery.optional(), + }), + ) + .output(zGetAppsByAppIdAdvancedChatWorkflowRunsCountResponse) + +export const count = { + get: get3, +} + +/** + * Get advanced chat app workflow run list + * + * Get advanced chat workflow run list + */ +export const get4 = oc + .route({ + description: 'Get advanced chat workflow run list', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdAdvancedChatWorkflowRuns', + path: '/apps/{app_id}/advanced-chat/workflow-runs', + summary: 'Get advanced chat app workflow run list', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdAdvancedChatWorkflowRunsPath, + query: zGetAppsByAppIdAdvancedChatWorkflowRunsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdAdvancedChatWorkflowRunsResponse) + +export const workflowRuns = { + get: get4, + count, +} + +/** + * Preview human input form content and placeholders + * + * Get human input form preview for advanced chat workflow + */ +export const post3 = oc + .route({ + description: 'Get human input form preview for advanced chat workflow', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreview', + path: '/apps/{app_id}/advanced-chat/workflows/draft/human-input/nodes/{node_id}/form/preview', + summary: 'Preview human input form content and placeholders', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewBody, + params: zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewPath, + }), + ) + .output(zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponse) + +export const preview = { + post: post3, +} + +/** + * Submit human input form preview + * + * Submit human input form preview for advanced chat workflow + */ +export const post4 = oc + .route({ + description: 'Submit human input form preview for advanced chat workflow', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRun', + path: '/apps/{app_id}/advanced-chat/workflows/draft/human-input/nodes/{node_id}/form/run', + summary: 'Submit human input form preview', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunBody, + params: zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunPath, + }), + ) + .output(zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunResponse) + +export const run = { + post: post4, +} + +export const form = { + preview, + run, +} + +export const byNodeId = { + form, +} + +export const nodes = { + byNodeId, +} + +export const humanInput = { + nodes, +} + +/** + * Run draft workflow iteration node + * + * Run draft workflow iteration node for advanced chat + */ +export const post5 = oc + .route({ + description: 'Run draft workflow iteration node for advanced chat', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRun', + path: '/apps/{app_id}/advanced-chat/workflows/draft/iteration/nodes/{node_id}/run', + summary: 'Run draft workflow iteration node', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunBody, + params: zPostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunPath, + }), + ) + .output(zPostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunResponse) + +export const run2 = { + post: post5, +} + +export const byNodeId2 = { + run: run2, +} + +export const nodes2 = { + byNodeId: byNodeId2, +} + +export const iteration = { + nodes: nodes2, +} + +/** + * Run draft workflow loop node + * + * Run draft workflow loop node for advanced chat + */ +export const post6 = oc + .route({ + description: 'Run draft workflow loop node for advanced chat', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRun', + path: '/apps/{app_id}/advanced-chat/workflows/draft/loop/nodes/{node_id}/run', + summary: 'Run draft workflow loop node', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunBody, + params: zPostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunPath, + }), + ) + .output(zPostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunResponse) + +export const run3 = { + post: post6, +} + +export const byNodeId3 = { + run: run3, +} + +export const nodes3 = { + byNodeId: byNodeId3, +} + +export const loop = { + nodes: nodes3, +} + +/** + * Run draft workflow + * + * Run draft workflow for advanced chat application + */ +export const post7 = oc + .route({ + description: 'Run draft workflow for advanced chat application', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdAdvancedChatWorkflowsDraftRun', + path: '/apps/{app_id}/advanced-chat/workflows/draft/run', + summary: 'Run draft workflow', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdAdvancedChatWorkflowsDraftRunBody, + params: zPostAppsByAppIdAdvancedChatWorkflowsDraftRunPath, + }), + ) + .output(zPostAppsByAppIdAdvancedChatWorkflowsDraftRunResponse) + +export const run4 = { + post: post7, +} + +export const draft = { + humanInput, + iteration, + loop, + run: run4, +} + +export const workflows2 = { + draft, +} + +export const advancedChat = { + workflowRuns, + workflows: workflows2, +} + +/** + * Get agent logs + * + * Get agent execution logs for an application + */ +export const get5 = oc + .route({ + description: 'Get agent execution logs for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdAgentLogs', + path: '/apps/{app_id}/agent/logs', + summary: 'Get agent logs', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdAgentLogsPath, query: zGetAppsByAppIdAgentLogsQuery })) + .output(zGetAppsByAppIdAgentLogsResponse) + +export const logs = { + get: get5, +} + +export const agent = { + logs, +} + +/** + * Get status of annotation reply action job + */ +export const get6 = oc + .route({ + description: 'Get status of annotation reply action job', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdAnnotationReplyByActionStatusByJobId', + path: '/apps/{app_id}/annotation-reply/{action}/status/{job_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdAnnotationReplyByActionStatusByJobIdPath })) + .output(zGetAppsByAppIdAnnotationReplyByActionStatusByJobIdResponse) + +export const byJobId = { + get: get6, +} + +export const status = { + byJobId, +} + +/** + * Enable or disable annotation reply for an app + */ +export const post8 = oc + .route({ + description: 'Enable or disable annotation reply for an app', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdAnnotationReplyByAction', + path: '/apps/{app_id}/annotation-reply/{action}', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdAnnotationReplyByActionBody, + params: zPostAppsByAppIdAnnotationReplyByActionPath, + }), + ) + .output(zPostAppsByAppIdAnnotationReplyByActionResponse) + +export const byAction = { + post: post8, + status, +} + +export const annotationReply = { + byAction, +} + +/** + * Get annotation settings for an app + */ +export const get7 = oc + .route({ + description: 'Get annotation settings for an app', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdAnnotationSetting', + path: '/apps/{app_id}/annotation-setting', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdAnnotationSettingPath })) + .output(zGetAppsByAppIdAnnotationSettingResponse) + +export const annotationSetting = { + get: get7, +} + +/** + * Update annotation settings for an app + */ +export const post9 = oc + .route({ + description: 'Update annotation settings for an app', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdAnnotationSettingsByAnnotationSettingId', + path: '/apps/{app_id}/annotation-settings/{annotation_setting_id}', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdAnnotationSettingsByAnnotationSettingIdBody, + params: zPostAppsByAppIdAnnotationSettingsByAnnotationSettingIdPath, + }), + ) + .output(zPostAppsByAppIdAnnotationSettingsByAnnotationSettingIdResponse) + +export const byAnnotationSettingId = { + post: post9, +} + +export const annotationSettings = { + byAnnotationSettingId, +} + +/** + * Batch import annotations from CSV file with rate limiting and security checks + */ +export const post10 = oc + .route({ + description: 'Batch import annotations from CSV file with rate limiting and security checks', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdAnnotationsBatchImport', + path: '/apps/{app_id}/annotations/batch-import', + tags: ['console'], + }) + .input(z.object({ params: zPostAppsByAppIdAnnotationsBatchImportPath })) + .output(zPostAppsByAppIdAnnotationsBatchImportResponse) + +export const batchImport = { + post: post10, +} + +/** + * Get status of batch import job + */ +export const get8 = oc + .route({ + description: 'Get status of batch import job', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdAnnotationsBatchImportStatusByJobId', + path: '/apps/{app_id}/annotations/batch-import-status/{job_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdAnnotationsBatchImportStatusByJobIdPath })) + .output(zGetAppsByAppIdAnnotationsBatchImportStatusByJobIdResponse) + +export const byJobId2 = { + get: get8, +} + +export const batchImportStatus = { + byJobId: byJobId2, +} + +/** + * Get count of message annotations for the app + */ +export const get9 = oc + .route({ + description: 'Get count of message annotations for the app', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdAnnotationsCount', + path: '/apps/{app_id}/annotations/count', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdAnnotationsCountPath })) + .output(zGetAppsByAppIdAnnotationsCountResponse) + +export const count2 = { + get: get9, +} + +/** + * Export all annotations for an app with CSV injection protection + */ +export const get10 = oc + .route({ + description: 'Export all annotations for an app with CSV injection protection', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdAnnotationsExport', + path: '/apps/{app_id}/annotations/export', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdAnnotationsExportPath })) + .output(zGetAppsByAppIdAnnotationsExportResponse) + +export const export_ = { + get: get10, +} + +/** + * Get hit histories for an annotation + */ +export const get11 = oc + .route({ + description: 'Get hit histories for an annotation', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdAnnotationsByAnnotationIdHitHistories', + path: '/apps/{app_id}/annotations/{annotation_id}/hit-histories', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesPath, + query: zGetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesQuery.optional(), + }), + ) + .output(zGetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesResponse) + +export const hitHistories = { + get: get11, +} + +export const delete_ = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByAppIdAnnotationsByAnnotationId', + path: '/apps/{app_id}/annotations/{annotation_id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteAppsByAppIdAnnotationsByAnnotationIdPath })) + .output(zDeleteAppsByAppIdAnnotationsByAnnotationIdResponse) + +/** + * Update or delete an annotation + */ +export const post11 = oc + .route({ + description: 'Update or delete an annotation', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdAnnotationsByAnnotationId', + path: '/apps/{app_id}/annotations/{annotation_id}', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdAnnotationsByAnnotationIdBody, + params: zPostAppsByAppIdAnnotationsByAnnotationIdPath, + }), + ) + .output(zPostAppsByAppIdAnnotationsByAnnotationIdResponse) + +export const byAnnotationId = { + delete: delete_, + post: post11, + hitHistories, +} + +export const delete2 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByAppIdAnnotations', + path: '/apps/{app_id}/annotations', + tags: ['console'], + }) + .input(z.object({ params: zDeleteAppsByAppIdAnnotationsPath })) + .output(zDeleteAppsByAppIdAnnotationsResponse) + +/** + * Get annotations for an app with pagination + */ +export const get12 = oc + .route({ + description: 'Get annotations for an app with pagination', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdAnnotations', + path: '/apps/{app_id}/annotations', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdAnnotationsPath, + query: zGetAppsByAppIdAnnotationsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdAnnotationsResponse) + +/** + * Create a new annotation for an app + */ +export const post12 = oc + .route({ + description: 'Create a new annotation for an app', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdAnnotations', + path: '/apps/{app_id}/annotations', + successStatus: 201, + tags: ['console'], + }) + .input( + z.object({ body: zPostAppsByAppIdAnnotationsBody, params: zPostAppsByAppIdAnnotationsPath }), + ) + .output(zPostAppsByAppIdAnnotationsResponse) + +export const annotations = { + delete: delete2, + get: get12, + post: post12, + batchImport, + batchImportStatus, + count: count2, + export: export_, + byAnnotationId, +} + +/** + * Enable or disable app API + */ +export const post13 = oc + .route({ + description: 'Enable or disable app API', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdApiEnable', + path: '/apps/{app_id}/api-enable', + tags: ['console'], + }) + .input(z.object({ body: zPostAppsByAppIdApiEnableBody, params: zPostAppsByAppIdApiEnablePath })) + .output(zPostAppsByAppIdApiEnableResponse) + +export const apiEnable = { + post: post13, +} + +/** + * Transcript audio to text for chat messages + */ +export const post14 = oc + .route({ + description: 'Transcript audio to text for chat messages', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdAudioToText', + path: '/apps/{app_id}/audio-to-text', + tags: ['console'], + }) + .input(z.object({ params: zPostAppsByAppIdAudioToTextPath })) + .output(zPostAppsByAppIdAudioToTextResponse) + +export const audioToText = { + post: post14, +} + +/** + * Delete a chat conversation + */ +export const delete3 = oc + .route({ + description: 'Delete a chat conversation', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByAppIdChatConversationsByConversationId', + path: '/apps/{app_id}/chat-conversations/{conversation_id}', + successStatus: 204, + tags: ['console'], + }) + .input(z.object({ params: zDeleteAppsByAppIdChatConversationsByConversationIdPath })) + .output(zDeleteAppsByAppIdChatConversationsByConversationIdResponse) + +/** + * Get chat conversation details + */ +export const get13 = oc + .route({ + description: 'Get chat conversation details', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdChatConversationsByConversationId', + path: '/apps/{app_id}/chat-conversations/{conversation_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdChatConversationsByConversationIdPath })) + .output(zGetAppsByAppIdChatConversationsByConversationIdResponse) + +export const byConversationId = { + delete: delete3, + get: get13, +} + +/** + * Get chat conversations with pagination, filtering and summary + */ +export const get14 = oc + .route({ + description: 'Get chat conversations with pagination, filtering and summary', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdChatConversations', + path: '/apps/{app_id}/chat-conversations', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdChatConversationsPath, + query: zGetAppsByAppIdChatConversationsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdChatConversationsResponse) + +export const chatConversations = { + get: get14, + byConversationId, +} + +/** + * Get suggested questions for a message + */ +export const get15 = oc + .route({ + description: 'Get suggested questions for a message', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdChatMessagesByMessageIdSuggestedQuestions', + path: '/apps/{app_id}/chat-messages/{message_id}/suggested-questions', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsPath })) + .output(zGetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsResponse) + +export const suggestedQuestions = { + get: get15, +} + +export const byMessageId = { + suggestedQuestions, +} + +/** + * Stop a running chat message generation + */ +export const post15 = oc + .route({ + description: 'Stop a running chat message generation', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdChatMessagesByTaskIdStop', + path: '/apps/{app_id}/chat-messages/{task_id}/stop', + tags: ['console'], + }) + .input(z.object({ params: zPostAppsByAppIdChatMessagesByTaskIdStopPath })) + .output(zPostAppsByAppIdChatMessagesByTaskIdStopResponse) + +export const stop = { + post: post15, +} + +export const byTaskId = { + stop, +} + +/** + * Get chat messages for a conversation with pagination + */ +export const get16 = oc + .route({ + description: 'Get chat messages for a conversation with pagination', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdChatMessages', + path: '/apps/{app_id}/chat-messages', + tags: ['console'], + }) + .input( + z.object({ params: zGetAppsByAppIdChatMessagesPath, query: zGetAppsByAppIdChatMessagesQuery }), + ) + .output(zGetAppsByAppIdChatMessagesResponse) + +export const chatMessages = { + get: get16, + byMessageId, + byTaskId, +} + +/** + * Delete a completion conversation + */ +export const delete4 = oc + .route({ + description: 'Delete a completion conversation', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByAppIdCompletionConversationsByConversationId', + path: '/apps/{app_id}/completion-conversations/{conversation_id}', + successStatus: 204, + tags: ['console'], + }) + .input(z.object({ params: zDeleteAppsByAppIdCompletionConversationsByConversationIdPath })) + .output(zDeleteAppsByAppIdCompletionConversationsByConversationIdResponse) + +/** + * Get completion conversation details with messages + */ +export const get17 = oc + .route({ + description: 'Get completion conversation details with messages', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdCompletionConversationsByConversationId', + path: '/apps/{app_id}/completion-conversations/{conversation_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdCompletionConversationsByConversationIdPath })) + .output(zGetAppsByAppIdCompletionConversationsByConversationIdResponse) + +export const byConversationId2 = { + delete: delete4, + get: get17, +} + +/** + * Get completion conversations with pagination and filtering + */ +export const get18 = oc + .route({ + description: 'Get completion conversations with pagination and filtering', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdCompletionConversations', + path: '/apps/{app_id}/completion-conversations', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdCompletionConversationsPath, + query: zGetAppsByAppIdCompletionConversationsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdCompletionConversationsResponse) + +export const completionConversations = { + get: get18, + byConversationId: byConversationId2, +} + +/** + * Stop a running completion message generation + */ +export const post16 = oc + .route({ + description: 'Stop a running completion message generation', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdCompletionMessagesByTaskIdStop', + path: '/apps/{app_id}/completion-messages/{task_id}/stop', + tags: ['console'], + }) + .input(z.object({ params: zPostAppsByAppIdCompletionMessagesByTaskIdStopPath })) + .output(zPostAppsByAppIdCompletionMessagesByTaskIdStopResponse) + +export const stop2 = { + post: post16, +} + +export const byTaskId2 = { + stop: stop2, +} + +/** + * Generate completion message for debugging + */ +export const post17 = oc + .route({ + description: 'Generate completion message for debugging', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdCompletionMessages', + path: '/apps/{app_id}/completion-messages', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdCompletionMessagesBody, + params: zPostAppsByAppIdCompletionMessagesPath, + }), + ) + .output(zPostAppsByAppIdCompletionMessagesResponse) + +export const completionMessages = { + post: post17, + byTaskId: byTaskId2, +} + +/** + * Get conversation variables for an application + */ +export const get19 = oc + .route({ + description: 'Get conversation variables for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdConversationVariables', + path: '/apps/{app_id}/conversation-variables', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdConversationVariablesPath, + query: zGetAppsByAppIdConversationVariablesQuery, + }), + ) + .output(zGetAppsByAppIdConversationVariablesResponse) + +export const conversationVariables = { + get: get19, +} + +/** + * Convert basic mode of chatbot app to workflow mode + * + * Convert application to workflow mode + * Convert expert mode of chatbot app to workflow mode + * Convert Completion App to Workflow App + */ +export const post18 = oc + .route({ + description: + 'Convert application to workflow mode\nConvert expert mode of chatbot app to workflow mode\nConvert Completion App to Workflow App', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdConvertToWorkflow', + path: '/apps/{app_id}/convert-to-workflow', + summary: 'Convert basic mode of chatbot app to workflow mode', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdConvertToWorkflowBody, + params: zPostAppsByAppIdConvertToWorkflowPath, + }), + ) + .output(zPostAppsByAppIdConvertToWorkflowResponse) + +export const convertToWorkflow = { + post: post18, +} + +/** + * Copy app + * + * Create a copy of an existing application + */ +export const post19 = oc + .route({ + description: 'Create a copy of an existing application', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdCopy', + path: '/apps/{app_id}/copy', + successStatus: 201, + summary: 'Copy app', + tags: ['console'], + }) + .input(z.object({ body: zPostAppsByAppIdCopyBody, params: zPostAppsByAppIdCopyPath })) + .output(zPostAppsByAppIdCopyResponse) + +export const copy = { + post: post19, +} + +/** + * Export app + * + * Export application configuration as DSL + */ +export const get20 = oc + .route({ + description: 'Export application configuration as DSL', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdExport', + path: '/apps/{app_id}/export', + summary: 'Export app', + tags: ['console'], + }) + .input( + z.object({ params: zGetAppsByAppIdExportPath, query: zGetAppsByAppIdExportQuery.optional() }), + ) + .output(zGetAppsByAppIdExportResponse) + +export const export2 = { + get: get20, +} + +/** + * Export user feedback data for Google Sheets + */ +export const get21 = oc + .route({ + description: 'Export user feedback data for Google Sheets', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdFeedbacksExport', + path: '/apps/{app_id}/feedbacks/export', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdFeedbacksExportPath, + query: zGetAppsByAppIdFeedbacksExportQuery.optional(), + }), + ) + .output(zGetAppsByAppIdFeedbacksExportResponse) + +export const export3 = { + get: get21, +} + +/** + * Create or update message feedback (like/dislike) + */ +export const post20 = oc + .route({ + description: 'Create or update message feedback (like/dislike)', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdFeedbacks', + path: '/apps/{app_id}/feedbacks', + tags: ['console'], + }) + .input(z.object({ body: zPostAppsByAppIdFeedbacksBody, params: zPostAppsByAppIdFeedbacksPath })) + .output(zPostAppsByAppIdFeedbacksResponse) + +export const feedbacks = { + post: post20, + export: export3, +} + +/** + * Update application icon + */ +export const post21 = oc + .route({ + description: 'Update application icon', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdIcon', + path: '/apps/{app_id}/icon', + tags: ['console'], + }) + .input(z.object({ body: zPostAppsByAppIdIconBody, params: zPostAppsByAppIdIconPath })) + .output(zPostAppsByAppIdIconResponse) + +export const icon = { + post: post21, +} + +/** + * Get message details by ID + */ +export const get22 = oc + .route({ + description: 'Get message details by ID', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdMessagesByMessageId', + path: '/apps/{app_id}/messages/{message_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdMessagesByMessageIdPath })) + .output(zGetAppsByAppIdMessagesByMessageIdResponse) + +export const byMessageId2 = { + get: get22, +} + +export const messages = { + byMessageId: byMessageId2, +} + +/** + * Modify app model config + * + * Update application model configuration + */ +export const post22 = oc + .route({ + description: 'Update application model configuration', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdModelConfig', + path: '/apps/{app_id}/model-config', + summary: 'Modify app model config', + tags: ['console'], + }) + .input( + z.object({ body: zPostAppsByAppIdModelConfigBody, params: zPostAppsByAppIdModelConfigPath }), + ) + .output(zPostAppsByAppIdModelConfigResponse) + +export const modelConfig = { + post: post22, +} + +/** + * Check if app name is available + */ +export const post23 = oc + .route({ + description: 'Check if app name is available', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdName', + path: '/apps/{app_id}/name', + tags: ['console'], + }) + .input(z.object({ body: zPostAppsByAppIdNameBody, params: zPostAppsByAppIdNamePath })) + .output(zPostAppsByAppIdNameResponse) + +export const name = { + post: post23, +} + +/** + * Publish app to Creators Platform + */ +export const post24 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdPublishToCreatorsPlatform', + path: '/apps/{app_id}/publish-to-creators-platform', + summary: 'Publish app to Creators Platform', + tags: ['console'], + }) + .input(z.object({ params: zPostAppsByAppIdPublishToCreatorsPlatformPath })) + .output(zPostAppsByAppIdPublishToCreatorsPlatformResponse) + +export const publishToCreatorsPlatform = { + post: post24, +} + +/** + * Get MCP server configuration for an application + */ +export const get23 = oc + .route({ + description: 'Get MCP server configuration for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdServer', + path: '/apps/{app_id}/server', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdServerPath })) + .output(zGetAppsByAppIdServerResponse) + +/** + * Create MCP server configuration for an application + */ +export const post25 = oc + .route({ + description: 'Create MCP server configuration for an application', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdServer', + path: '/apps/{app_id}/server', + successStatus: 201, + tags: ['console'], + }) + .input(z.object({ body: zPostAppsByAppIdServerBody, params: zPostAppsByAppIdServerPath })) + .output(zPostAppsByAppIdServerResponse) + +/** + * Update MCP server configuration for an application + */ +export const put = oc + .route({ + description: 'Update MCP server configuration for an application', + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putAppsByAppIdServer', + path: '/apps/{app_id}/server', + tags: ['console'], + }) + .input(z.object({ body: zPutAppsByAppIdServerBody, params: zPutAppsByAppIdServerPath })) + .output(zPutAppsByAppIdServerResponse) + +export const server = { + get: get23, + post: post25, + put, +} + +/** + * Reset access token for application site + */ +export const post26 = oc + .route({ + description: 'Reset access token for application site', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdSiteAccessTokenReset', + path: '/apps/{app_id}/site/access-token-reset', + tags: ['console'], + }) + .input(z.object({ params: zPostAppsByAppIdSiteAccessTokenResetPath })) + .output(zPostAppsByAppIdSiteAccessTokenResetResponse) + +export const accessTokenReset = { + post: post26, +} + +/** + * Update application site configuration + */ +export const post27 = oc + .route({ + description: 'Update application site configuration', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdSite', + path: '/apps/{app_id}/site', + tags: ['console'], + }) + .input(z.object({ body: zPostAppsByAppIdSiteBody, params: zPostAppsByAppIdSitePath })) + .output(zPostAppsByAppIdSiteResponse) + +export const site = { + post: post27, + accessTokenReset, +} + +/** + * Enable or disable app site + */ +export const post28 = oc + .route({ + description: 'Enable or disable app site', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdSiteEnable', + path: '/apps/{app_id}/site-enable', + tags: ['console'], + }) + .input(z.object({ body: zPostAppsByAppIdSiteEnableBody, params: zPostAppsByAppIdSiteEnablePath })) + .output(zPostAppsByAppIdSiteEnableResponse) + +export const siteEnable = { + post: post28, +} + +/** + * Get average response time statistics for an application + */ +export const get24 = oc + .route({ + description: 'Get average response time statistics for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdStatisticsAverageResponseTime', + path: '/apps/{app_id}/statistics/average-response-time', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdStatisticsAverageResponseTimePath, + query: zGetAppsByAppIdStatisticsAverageResponseTimeQuery.optional(), + }), + ) + .output(zGetAppsByAppIdStatisticsAverageResponseTimeResponse) + +export const averageResponseTime = { + get: get24, +} + +/** + * Get average session interaction statistics for an application + */ +export const get25 = oc + .route({ + description: 'Get average session interaction statistics for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdStatisticsAverageSessionInteractions', + path: '/apps/{app_id}/statistics/average-session-interactions', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdStatisticsAverageSessionInteractionsPath, + query: zGetAppsByAppIdStatisticsAverageSessionInteractionsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdStatisticsAverageSessionInteractionsResponse) + +export const averageSessionInteractions = { + get: get25, +} + +/** + * Get daily conversation statistics for an application + */ +export const get26 = oc + .route({ + description: 'Get daily conversation statistics for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdStatisticsDailyConversations', + path: '/apps/{app_id}/statistics/daily-conversations', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdStatisticsDailyConversationsPath, + query: zGetAppsByAppIdStatisticsDailyConversationsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdStatisticsDailyConversationsResponse) + +export const dailyConversations = { + get: get26, +} + +/** + * Get daily terminal/end-user statistics for an application + */ +export const get27 = oc + .route({ + description: 'Get daily terminal/end-user statistics for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdStatisticsDailyEndUsers', + path: '/apps/{app_id}/statistics/daily-end-users', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdStatisticsDailyEndUsersPath, + query: zGetAppsByAppIdStatisticsDailyEndUsersQuery.optional(), + }), + ) + .output(zGetAppsByAppIdStatisticsDailyEndUsersResponse) + +export const dailyEndUsers = { + get: get27, +} + +/** + * Get daily message statistics for an application + */ +export const get28 = oc + .route({ + description: 'Get daily message statistics for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdStatisticsDailyMessages', + path: '/apps/{app_id}/statistics/daily-messages', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdStatisticsDailyMessagesPath, + query: zGetAppsByAppIdStatisticsDailyMessagesQuery.optional(), + }), + ) + .output(zGetAppsByAppIdStatisticsDailyMessagesResponse) + +export const dailyMessages = { + get: get28, +} + +/** + * Get daily token cost statistics for an application + */ +export const get29 = oc + .route({ + description: 'Get daily token cost statistics for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdStatisticsTokenCosts', + path: '/apps/{app_id}/statistics/token-costs', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdStatisticsTokenCostsPath, + query: zGetAppsByAppIdStatisticsTokenCostsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdStatisticsTokenCostsResponse) + +export const tokenCosts = { + get: get29, +} + +/** + * Get tokens per second statistics for an application + */ +export const get30 = oc + .route({ + description: 'Get tokens per second statistics for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdStatisticsTokensPerSecond', + path: '/apps/{app_id}/statistics/tokens-per-second', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdStatisticsTokensPerSecondPath, + query: zGetAppsByAppIdStatisticsTokensPerSecondQuery.optional(), + }), + ) + .output(zGetAppsByAppIdStatisticsTokensPerSecondResponse) + +export const tokensPerSecond = { + get: get30, +} + +/** + * Get user satisfaction rate statistics for an application + */ +export const get31 = oc + .route({ + description: 'Get user satisfaction rate statistics for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdStatisticsUserSatisfactionRate', + path: '/apps/{app_id}/statistics/user-satisfaction-rate', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdStatisticsUserSatisfactionRatePath, + query: zGetAppsByAppIdStatisticsUserSatisfactionRateQuery.optional(), + }), + ) + .output(zGetAppsByAppIdStatisticsUserSatisfactionRateResponse) + +export const userSatisfactionRate = { + get: get31, +} + +export const statistics = { + averageResponseTime, + averageSessionInteractions, + dailyConversations, + dailyEndUsers, + dailyMessages, + tokenCosts, + tokensPerSecond, + userSatisfactionRate, +} + +/** + * Get available TTS voices for a specific language + */ +export const get32 = oc + .route({ + description: 'Get available TTS voices for a specific language', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdTextToAudioVoices', + path: '/apps/{app_id}/text-to-audio/voices', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdTextToAudioVoicesPath, + query: zGetAppsByAppIdTextToAudioVoicesQuery, + }), + ) + .output(zGetAppsByAppIdTextToAudioVoicesResponse) + +export const voices = { + get: get32, +} + +/** + * Convert text to speech for chat messages + */ +export const post29 = oc + .route({ + description: 'Convert text to speech for chat messages', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdTextToAudio', + path: '/apps/{app_id}/text-to-audio', + tags: ['console'], + }) + .input( + z.object({ body: zPostAppsByAppIdTextToAudioBody, params: zPostAppsByAppIdTextToAudioPath }), + ) + .output(zPostAppsByAppIdTextToAudioResponse) + +export const textToAudio = { + post: post29, + voices, +} + +/** + * Get app trace + * + * Get app tracing configuration + */ +export const get33 = oc + .route({ + description: 'Get app tracing configuration', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdTrace', + path: '/apps/{app_id}/trace', + summary: 'Get app trace', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdTracePath })) + .output(zGetAppsByAppIdTraceResponse) + +/** + * Update app tracing configuration + */ +export const post30 = oc + .route({ + description: 'Update app tracing configuration', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdTrace', + path: '/apps/{app_id}/trace', + tags: ['console'], + }) + .input(z.object({ body: zPostAppsByAppIdTraceBody, params: zPostAppsByAppIdTracePath })) + .output(zPostAppsByAppIdTraceResponse) + +export const trace = { + get: get33, + post: post30, +} + +/** + * Delete an existing trace app configuration + * + * Delete an existing tracing configuration for an application + */ +export const delete5 = oc + .route({ + description: 'Delete an existing tracing configuration for an application', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByAppIdTraceConfig', + path: '/apps/{app_id}/trace-config', + successStatus: 204, + summary: 'Delete an existing trace app configuration', + tags: ['console'], + }) + .input( + z.object({ + body: zDeleteAppsByAppIdTraceConfigBody, + params: zDeleteAppsByAppIdTraceConfigPath, + }), + ) + .output(zDeleteAppsByAppIdTraceConfigResponse) + +/** + * Get tracing configuration for an application + */ +export const get34 = oc + .route({ + description: 'Get tracing configuration for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdTraceConfig', + path: '/apps/{app_id}/trace-config', + tags: ['console'], + }) + .input( + z.object({ params: zGetAppsByAppIdTraceConfigPath, query: zGetAppsByAppIdTraceConfigQuery }), + ) + .output(zGetAppsByAppIdTraceConfigResponse) + +/** + * Update an existing trace app configuration + * + * Update an existing tracing configuration for an application + */ +export const patch = oc + .route({ + description: 'Update an existing tracing configuration for an application', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchAppsByAppIdTraceConfig', + path: '/apps/{app_id}/trace-config', + summary: 'Update an existing trace app configuration', + tags: ['console'], + }) + .input( + z.object({ body: zPatchAppsByAppIdTraceConfigBody, params: zPatchAppsByAppIdTraceConfigPath }), + ) + .output(zPatchAppsByAppIdTraceConfigResponse) + +/** + * Create a new trace app configuration + * + * Create a new tracing configuration for an application + */ +export const post31 = oc + .route({ + description: 'Create a new tracing configuration for an application', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdTraceConfig', + path: '/apps/{app_id}/trace-config', + successStatus: 201, + summary: 'Create a new trace app configuration', + tags: ['console'], + }) + .input( + z.object({ body: zPostAppsByAppIdTraceConfigBody, params: zPostAppsByAppIdTraceConfigPath }), + ) + .output(zPostAppsByAppIdTraceConfigResponse) + +export const traceConfig = { + delete: delete5, + get: get34, + patch, + post: post31, +} + +/** + * Update app trigger (enable/disable) + */ +export const post32 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdTriggerEnable', + path: '/apps/{app_id}/trigger-enable', + summary: 'Update app trigger (enable/disable)', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdTriggerEnableBody, + params: zPostAppsByAppIdTriggerEnablePath, + }), + ) + .output(zPostAppsByAppIdTriggerEnableResponse) + +export const triggerEnable = { + post: post32, +} + +/** + * Get app triggers list + */ +export const get35 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdTriggers', + path: '/apps/{app_id}/triggers', + summary: 'Get app triggers list', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdTriggersPath })) + .output(zGetAppsByAppIdTriggersResponse) + +export const triggers = { + get: get35, +} + +/** + * Get workflow app logs + * + * Get workflow application execution logs + */ +export const get36 = oc + .route({ + description: 'Get workflow application execution logs', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowAppLogs', + path: '/apps/{app_id}/workflow-app-logs', + summary: 'Get workflow app logs', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdWorkflowAppLogsPath, + query: zGetAppsByAppIdWorkflowAppLogsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdWorkflowAppLogsResponse) + +export const workflowAppLogs = { + get: get36, +} + +/** + * Get workflow archived logs + * + * Get workflow archived execution logs + */ +export const get37 = oc + .route({ + description: 'Get workflow archived execution logs', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowArchivedLogs', + path: '/apps/{app_id}/workflow-archived-logs', + summary: 'Get workflow archived logs', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdWorkflowArchivedLogsPath, + query: zGetAppsByAppIdWorkflowArchivedLogsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdWorkflowArchivedLogsResponse) + +export const workflowArchivedLogs = { + get: get37, +} + +/** + * Get workflow runs count statistics + * + * Get workflow runs count statistics + */ +export const get38 = oc + .route({ + description: 'Get workflow runs count statistics', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowRunsCount', + path: '/apps/{app_id}/workflow-runs/count', + summary: 'Get workflow runs count statistics', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdWorkflowRunsCountPath, + query: zGetAppsByAppIdWorkflowRunsCountQuery.optional(), + }), + ) + .output(zGetAppsByAppIdWorkflowRunsCountResponse) + +export const count3 = { + get: get38, +} + +/** + * Stop workflow task + * + * Stop running workflow task + */ +export const post33 = oc + .route({ + description: 'Stop running workflow task', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowRunsTasksByTaskIdStop', + path: '/apps/{app_id}/workflow-runs/tasks/{task_id}/stop', + summary: 'Stop workflow task', + tags: ['console'], + }) + .input(z.object({ params: zPostAppsByAppIdWorkflowRunsTasksByTaskIdStopPath })) + .output(zPostAppsByAppIdWorkflowRunsTasksByTaskIdStopResponse) + +export const stop3 = { + post: post33, +} + +export const byTaskId3 = { + stop: stop3, +} + +export const tasks = { + byTaskId: byTaskId3, +} + +/** + * Generate a download URL for an archived workflow run. + */ +export const get39 = oc + .route({ + description: 'Generate a download URL for an archived workflow run.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowRunsByRunIdExport', + path: '/apps/{app_id}/workflow-runs/{run_id}/export', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowRunsByRunIdExportPath })) + .output(zGetAppsByAppIdWorkflowRunsByRunIdExportResponse) + +export const export4 = { + get: get39, +} + +/** + * Get workflow run node execution list + * + * Get workflow run node execution list + */ +export const get40 = oc + .route({ + description: 'Get workflow run node execution list', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowRunsByRunIdNodeExecutions', + path: '/apps/{app_id}/workflow-runs/{run_id}/node-executions', + summary: 'Get workflow run node execution list', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsPath })) + .output(zGetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsResponse) + +export const nodeExecutions = { + get: get40, +} + +/** + * Get workflow run detail + * + * Get workflow run detail + */ +export const get41 = oc + .route({ + description: 'Get workflow run detail', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowRunsByRunId', + path: '/apps/{app_id}/workflow-runs/{run_id}', + summary: 'Get workflow run detail', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowRunsByRunIdPath })) + .output(zGetAppsByAppIdWorkflowRunsByRunIdResponse) + +export const byRunId = { + get: get41, + export: export4, + nodeExecutions, +} + +/** + * Get workflow run list + * + * Get workflow run list + */ +export const get42 = oc + .route({ + description: 'Get workflow run list', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowRuns', + path: '/apps/{app_id}/workflow-runs', + summary: 'Get workflow run list', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdWorkflowRunsPath, + query: zGetAppsByAppIdWorkflowRunsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdWorkflowRunsResponse) + +export const workflowRuns2 = { + get: get42, + count: count3, + tasks, + byRunId, +} + +/** + * Get all users in current tenant for mentions + * + * Get all users in current tenant for mentions + */ +export const get43 = oc + .route({ + description: 'Get all users in current tenant for mentions', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowCommentsMentionUsers', + path: '/apps/{app_id}/workflow/comments/mention-users', + summary: 'Get all users in current tenant for mentions', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowCommentsMentionUsersPath })) + .output(zGetAppsByAppIdWorkflowCommentsMentionUsersResponse) + +export const mentionUsers = { + get: get43, +} + +/** + * Delete a comment reply + * + * Delete a comment reply + */ +export const delete6 = oc + .route({ + description: 'Delete a comment reply', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyId', + path: '/apps/{app_id}/workflow/comments/{comment_id}/replies/{reply_id}', + successStatus: 204, + summary: 'Delete a comment reply', + tags: ['console'], + }) + .input(z.object({ params: zDeleteAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdPath })) + .output(zDeleteAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponse) + +/** + * Update a comment reply + * + * Update a comment reply + */ +export const put2 = oc + .route({ + description: 'Update a comment reply', + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyId', + path: '/apps/{app_id}/workflow/comments/{comment_id}/replies/{reply_id}', + summary: 'Update a comment reply', + tags: ['console'], + }) + .input( + z.object({ + body: zPutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdBody, + params: zPutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdPath, + }), + ) + .output(zPutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponse) + +export const byReplyId = { + delete: delete6, + put: put2, +} + +/** + * Add a reply to a workflow comment + * + * Add a reply to a workflow comment + */ +export const post34 = oc + .route({ + description: 'Add a reply to a workflow comment', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowCommentsByCommentIdReplies', + path: '/apps/{app_id}/workflow/comments/{comment_id}/replies', + successStatus: 201, + summary: 'Add a reply to a workflow comment', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowCommentsByCommentIdRepliesBody, + params: zPostAppsByAppIdWorkflowCommentsByCommentIdRepliesPath, + }), + ) + .output(zPostAppsByAppIdWorkflowCommentsByCommentIdRepliesResponse) + +export const replies = { + post: post34, + byReplyId, +} + +/** + * Resolve a workflow comment + * + * Resolve a workflow comment + */ +export const post35 = oc + .route({ + description: 'Resolve a workflow comment', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowCommentsByCommentIdResolve', + path: '/apps/{app_id}/workflow/comments/{comment_id}/resolve', + summary: 'Resolve a workflow comment', + tags: ['console'], + }) + .input(z.object({ params: zPostAppsByAppIdWorkflowCommentsByCommentIdResolvePath })) + .output(zPostAppsByAppIdWorkflowCommentsByCommentIdResolveResponse) + +export const resolve = { + post: post35, +} + +/** + * Delete a workflow comment + * + * Delete a workflow comment + */ +export const delete7 = oc + .route({ + description: 'Delete a workflow comment', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByAppIdWorkflowCommentsByCommentId', + path: '/apps/{app_id}/workflow/comments/{comment_id}', + successStatus: 204, + summary: 'Delete a workflow comment', + tags: ['console'], + }) + .input(z.object({ params: zDeleteAppsByAppIdWorkflowCommentsByCommentIdPath })) + .output(zDeleteAppsByAppIdWorkflowCommentsByCommentIdResponse) + +/** + * Get a specific workflow comment + * + * Get a specific workflow comment + */ +export const get44 = oc + .route({ + description: 'Get a specific workflow comment', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowCommentsByCommentId', + path: '/apps/{app_id}/workflow/comments/{comment_id}', + summary: 'Get a specific workflow comment', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowCommentsByCommentIdPath })) + .output(zGetAppsByAppIdWorkflowCommentsByCommentIdResponse) + +/** + * Update a workflow comment + * + * Update a workflow comment + */ +export const put3 = oc + .route({ + description: 'Update a workflow comment', + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putAppsByAppIdWorkflowCommentsByCommentId', + path: '/apps/{app_id}/workflow/comments/{comment_id}', + summary: 'Update a workflow comment', + tags: ['console'], + }) + .input( + z.object({ + body: zPutAppsByAppIdWorkflowCommentsByCommentIdBody, + params: zPutAppsByAppIdWorkflowCommentsByCommentIdPath, + }), + ) + .output(zPutAppsByAppIdWorkflowCommentsByCommentIdResponse) + +export const byCommentId = { + delete: delete7, + get: get44, + put: put3, + replies, + resolve, +} + +/** + * Get all comments for a workflow + * + * Get all comments for a workflow + */ +export const get45 = oc + .route({ + description: 'Get all comments for a workflow', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowComments', + path: '/apps/{app_id}/workflow/comments', + summary: 'Get all comments for a workflow', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowCommentsPath })) + .output(zGetAppsByAppIdWorkflowCommentsResponse) + +/** + * Create a new workflow comment + * + * Create a new workflow comment + */ +export const post36 = oc + .route({ + description: 'Create a new workflow comment', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowComments', + path: '/apps/{app_id}/workflow/comments', + successStatus: 201, + summary: 'Create a new workflow comment', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowCommentsBody, + params: zPostAppsByAppIdWorkflowCommentsPath, + }), + ) + .output(zPostAppsByAppIdWorkflowCommentsResponse) + +export const comments = { + get: get45, + post: post36, + mentionUsers, + byCommentId, +} + +/** + * Get workflow average app interaction statistics + */ +export const get46 = oc + .route({ + description: 'Get workflow average app interaction statistics', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowStatisticsAverageAppInteractions', + path: '/apps/{app_id}/workflow/statistics/average-app-interactions', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdWorkflowStatisticsAverageAppInteractionsPath, + query: zGetAppsByAppIdWorkflowStatisticsAverageAppInteractionsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdWorkflowStatisticsAverageAppInteractionsResponse) + +export const averageAppInteractions = { + get: get46, +} + +/** + * Get workflow daily runs statistics + */ +export const get47 = oc + .route({ + description: 'Get workflow daily runs statistics', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowStatisticsDailyConversations', + path: '/apps/{app_id}/workflow/statistics/daily-conversations', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdWorkflowStatisticsDailyConversationsPath, + query: zGetAppsByAppIdWorkflowStatisticsDailyConversationsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdWorkflowStatisticsDailyConversationsResponse) + +export const dailyConversations2 = { + get: get47, +} + +/** + * Get workflow daily terminals statistics + */ +export const get48 = oc + .route({ + description: 'Get workflow daily terminals statistics', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowStatisticsDailyTerminals', + path: '/apps/{app_id}/workflow/statistics/daily-terminals', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdWorkflowStatisticsDailyTerminalsPath, + query: zGetAppsByAppIdWorkflowStatisticsDailyTerminalsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdWorkflowStatisticsDailyTerminalsResponse) + +export const dailyTerminals = { + get: get48, +} + +/** + * Get workflow daily token cost statistics + */ +export const get49 = oc + .route({ + description: 'Get workflow daily token cost statistics', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowStatisticsTokenCosts', + path: '/apps/{app_id}/workflow/statistics/token-costs', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdWorkflowStatisticsTokenCostsPath, + query: zGetAppsByAppIdWorkflowStatisticsTokenCostsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdWorkflowStatisticsTokenCostsResponse) + +export const tokenCosts2 = { + get: get49, +} + +export const statistics2 = { + averageAppInteractions, + dailyConversations: dailyConversations2, + dailyTerminals, + tokenCosts: tokenCosts2, +} + +export const workflow = { + comments, + statistics: statistics2, +} + +/** + * Get default block config + * + * Get default block configuration by type + */ +export const get50 = oc + .route({ + description: 'Get default block configuration by type', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockType', + path: '/apps/{app_id}/workflows/default-workflow-block-configs/{block_type}', + summary: 'Get default block config', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypePath, + query: zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeQuery.optional(), + }), + ) + .output(zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse) + +export const byBlockType = { + get: get50, +} + +/** + * Get default block config + * + * Get default block configurations for workflow + */ +export const get51 = oc + .route({ + description: 'Get default block configurations for workflow', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowsDefaultWorkflowBlockConfigs', + path: '/apps/{app_id}/workflows/default-workflow-block-configs', + summary: 'Get default block config', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsPath })) + .output(zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsResponse) + +export const defaultWorkflowBlockConfigs = { + get: get51, + byBlockType, +} + +/** + * Get conversation variables for workflow + */ +export const get52 = oc + .route({ + description: 'Get conversation variables for workflow', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowsDraftConversationVariables', + path: '/apps/{app_id}/workflows/draft/conversation-variables', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowsDraftConversationVariablesPath })) + .output(zGetAppsByAppIdWorkflowsDraftConversationVariablesResponse) + +/** + * Update conversation variables for workflow draft + */ +export const post37 = oc + .route({ + description: 'Update conversation variables for workflow draft', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftConversationVariables', + path: '/apps/{app_id}/workflows/draft/conversation-variables', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftConversationVariablesBody, + params: zPostAppsByAppIdWorkflowsDraftConversationVariablesPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftConversationVariablesResponse) + +export const conversationVariables2 = { + get: get52, + post: post37, +} + +/** + * Get draft workflow + * + * Get environment variables for workflow + */ +export const get53 = oc + .route({ + description: 'Get environment variables for workflow', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowsDraftEnvironmentVariables', + path: '/apps/{app_id}/workflows/draft/environment-variables', + summary: 'Get draft workflow', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowsDraftEnvironmentVariablesPath })) + .output(zGetAppsByAppIdWorkflowsDraftEnvironmentVariablesResponse) + +/** + * Update environment variables for workflow draft + */ +export const post38 = oc + .route({ + description: 'Update environment variables for workflow draft', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftEnvironmentVariables', + path: '/apps/{app_id}/workflows/draft/environment-variables', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftEnvironmentVariablesBody, + params: zPostAppsByAppIdWorkflowsDraftEnvironmentVariablesPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftEnvironmentVariablesResponse) + +export const environmentVariables = { + get: get53, + post: post38, +} + +/** + * Update draft workflow features + */ +export const post39 = oc + .route({ + description: 'Update draft workflow features', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftFeatures', + path: '/apps/{app_id}/workflows/draft/features', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftFeaturesBody, + params: zPostAppsByAppIdWorkflowsDraftFeaturesPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftFeaturesResponse) + +export const features = { + post: post39, +} + +/** + * Test human input delivery + * + * Test human input delivery for workflow + */ +export const post40 = oc + .route({ + description: 'Test human input delivery for workflow', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTest', + path: '/apps/{app_id}/workflows/draft/human-input/nodes/{node_id}/delivery-test', + summary: 'Test human input delivery', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestBody, + params: zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestResponse) + +export const deliveryTest = { + post: post40, +} + +/** + * Preview human input form content and placeholders + * + * Get human input form preview for workflow + */ +export const post41 = oc + .route({ + description: 'Get human input form preview for workflow', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreview', + path: '/apps/{app_id}/workflows/draft/human-input/nodes/{node_id}/form/preview', + summary: 'Preview human input form content and placeholders', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewBody, + params: zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponse) + +export const preview2 = { + post: post41, +} + +/** + * Submit human input form preview + * + * Submit human input form preview for workflow + */ +export const post42 = oc + .route({ + description: 'Submit human input form preview for workflow', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRun', + path: '/apps/{app_id}/workflows/draft/human-input/nodes/{node_id}/form/run', + summary: 'Submit human input form preview', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunBody, + params: zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunResponse) + +export const run5 = { + post: post42, +} + +export const form2 = { + preview: preview2, + run: run5, +} + +export const byNodeId4 = { + deliveryTest, + form: form2, +} + +export const nodes4 = { + byNodeId: byNodeId4, +} + +export const humanInput2 = { + nodes: nodes4, +} + +/** + * Run draft workflow iteration node + * + * Run draft workflow iteration node + */ +export const post43 = oc + .route({ + description: 'Run draft workflow iteration node', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRun', + path: '/apps/{app_id}/workflows/draft/iteration/nodes/{node_id}/run', + summary: 'Run draft workflow iteration node', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunBody, + params: zPostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunResponse) + +export const run6 = { + post: post43, +} + +export const byNodeId5 = { + run: run6, +} + +export const nodes5 = { + byNodeId: byNodeId5, +} + +export const iteration2 = { + nodes: nodes5, +} + +/** + * Run draft workflow loop node + * + * Run draft workflow loop node + */ +export const post44 = oc + .route({ + description: 'Run draft workflow loop node', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRun', + path: '/apps/{app_id}/workflows/draft/loop/nodes/{node_id}/run', + summary: 'Run draft workflow loop node', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunBody, + params: zPostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunResponse) + +export const run7 = { + post: post44, +} + +export const byNodeId6 = { + run: run7, +} + +export const nodes6 = { + byNodeId: byNodeId6, +} + +export const loop2 = { + nodes: nodes6, +} + +/** + * Get last run result for draft workflow node + */ +export const get54 = oc + .route({ + description: 'Get last run result for draft workflow node', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowsDraftNodesByNodeIdLastRun', + path: '/apps/{app_id}/workflows/draft/nodes/{node_id}/last-run', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunPath })) + .output(zGetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunResponse) + +export const lastRun = { + get: get54, +} + +/** + * Run draft workflow node + * + * Run draft workflow node + */ +export const post45 = oc + .route({ + description: 'Run draft workflow node', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftNodesByNodeIdRun', + path: '/apps/{app_id}/workflows/draft/nodes/{node_id}/run', + summary: 'Run draft workflow node', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftNodesByNodeIdRunBody, + params: zPostAppsByAppIdWorkflowsDraftNodesByNodeIdRunPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftNodesByNodeIdRunResponse) + +export const run8 = { + post: post45, +} + +/** + * Poll for trigger events and execute single node when event arrives + * + * Poll for trigger events and execute single node when event arrives + */ +export const post46 = oc + .route({ + description: 'Poll for trigger events and execute single node when event arrives', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRun', + path: '/apps/{app_id}/workflows/draft/nodes/{node_id}/trigger/run', + summary: 'Poll for trigger events and execute single node when event arrives', + tags: ['console'], + }) + .input(z.object({ params: zPostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunPath })) + .output(zPostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunResponse) + +export const run9 = { + post: post46, +} + +export const trigger = { + run: run9, +} + +/** + * Delete all variables for a specific node + */ +export const delete8 = oc + .route({ + description: 'Delete all variables for a specific node', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariables', + path: '/apps/{app_id}/workflows/draft/nodes/{node_id}/variables', + successStatus: 204, + tags: ['console'], + }) + .input(z.object({ params: zDeleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesPath })) + .output(zDeleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponse) + +/** + * Get variables for a specific node + */ +export const get55 = oc + .route({ + description: 'Get variables for a specific node', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowsDraftNodesByNodeIdVariables', + path: '/apps/{app_id}/workflows/draft/nodes/{node_id}/variables', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesPath })) + .output(zGetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponse) + +export const variables = { + delete: delete8, + get: get55, +} + +export const byNodeId7 = { + lastRun, + run: run8, + trigger, + variables, +} + +export const nodes7 = { + byNodeId: byNodeId7, +} + +/** + * Run draft workflow + * + * Run draft workflow + */ +export const post47 = oc + .route({ + description: 'Run draft workflow', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftRun', + path: '/apps/{app_id}/workflows/draft/run', + summary: 'Run draft workflow', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftRunBody, + params: zPostAppsByAppIdWorkflowsDraftRunPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftRunResponse) + +export const run10 = { + post: post47, +} + +/** + * Get system variables for workflow + */ +export const get56 = oc + .route({ + description: 'Get system variables for workflow', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowsDraftSystemVariables', + path: '/apps/{app_id}/workflows/draft/system-variables', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowsDraftSystemVariablesPath })) + .output(zGetAppsByAppIdWorkflowsDraftSystemVariablesResponse) + +export const systemVariables = { + get: get56, +} + +/** + * Poll for trigger events and execute full workflow when event arrives + * + * Poll for trigger events and execute full workflow when event arrives + */ +export const post48 = oc + .route({ + description: 'Poll for trigger events and execute full workflow when event arrives', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftTriggerRun', + path: '/apps/{app_id}/workflows/draft/trigger/run', + summary: 'Poll for trigger events and execute full workflow when event arrives', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftTriggerRunBody, + params: zPostAppsByAppIdWorkflowsDraftTriggerRunPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftTriggerRunResponse) + +export const run11 = { + post: post48, +} + +/** + * Full workflow debug when the start node is a trigger + * + * Full workflow debug when the start node is a trigger + */ +export const post49 = oc + .route({ + description: 'Full workflow debug when the start node is a trigger', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraftTriggerRunAll', + path: '/apps/{app_id}/workflows/draft/trigger/run-all', + summary: 'Full workflow debug when the start node is a trigger', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftTriggerRunAllBody, + params: zPostAppsByAppIdWorkflowsDraftTriggerRunAllPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftTriggerRunAllResponse) + +export const runAll = { + post: post49, +} + +export const trigger2 = { + run: run11, + runAll, +} + +/** + * Reset a workflow variable to its default value + */ +export const put4 = oc + .route({ + description: 'Reset a workflow variable to its default value', + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putAppsByAppIdWorkflowsDraftVariablesByVariableIdReset', + path: '/apps/{app_id}/workflows/draft/variables/{variable_id}/reset', + tags: ['console'], + }) + .input(z.object({ params: zPutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetPath })) + .output(zPutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetResponse) + +export const reset = { + put: put4, +} + +/** + * Delete a workflow variable + */ +export const delete9 = oc + .route({ + description: 'Delete a workflow variable', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByAppIdWorkflowsDraftVariablesByVariableId', + path: '/apps/{app_id}/workflows/draft/variables/{variable_id}', + successStatus: 204, + tags: ['console'], + }) + .input(z.object({ params: zDeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdPath })) + .output(zDeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdResponse) + +/** + * Get a specific workflow variable + */ +export const get57 = oc + .route({ + description: 'Get a specific workflow variable', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowsDraftVariablesByVariableId', + path: '/apps/{app_id}/workflows/draft/variables/{variable_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowsDraftVariablesByVariableIdPath })) + .output(zGetAppsByAppIdWorkflowsDraftVariablesByVariableIdResponse) + +/** + * Update a workflow variable + */ +export const patch2 = oc + .route({ + description: 'Update a workflow variable', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchAppsByAppIdWorkflowsDraftVariablesByVariableId', + path: '/apps/{app_id}/workflows/draft/variables/{variable_id}', + tags: ['console'], + }) + .input( + z.object({ + body: zPatchAppsByAppIdWorkflowsDraftVariablesByVariableIdBody, + params: zPatchAppsByAppIdWorkflowsDraftVariablesByVariableIdPath, + }), + ) + .output(zPatchAppsByAppIdWorkflowsDraftVariablesByVariableIdResponse) + +export const byVariableId = { + delete: delete9, + get: get57, + patch: patch2, + reset, +} + +/** + * Delete all draft workflow variables + */ +export const delete10 = oc + .route({ + description: 'Delete all draft workflow variables', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByAppIdWorkflowsDraftVariables', + path: '/apps/{app_id}/workflows/draft/variables', + successStatus: 204, + tags: ['console'], + }) + .input(z.object({ params: zDeleteAppsByAppIdWorkflowsDraftVariablesPath })) + .output(zDeleteAppsByAppIdWorkflowsDraftVariablesResponse) + +/** + * Get draft workflow + * + * Get draft workflow variables + */ +export const get58 = oc + .route({ + description: 'Get draft workflow variables', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowsDraftVariables', + path: '/apps/{app_id}/workflows/draft/variables', + summary: 'Get draft workflow', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdWorkflowsDraftVariablesPath, + query: zGetAppsByAppIdWorkflowsDraftVariablesQuery.optional(), + }), + ) + .output(zGetAppsByAppIdWorkflowsDraftVariablesResponse) + +export const variables2 = { + delete: delete10, + get: get58, + byVariableId, +} + +/** + * Get draft workflow + * + * Get draft workflow for an application + */ +export const get59 = oc + .route({ + description: 'Get draft workflow for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowsDraft', + path: '/apps/{app_id}/workflows/draft', + summary: 'Get draft workflow', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowsDraftPath })) + .output(zGetAppsByAppIdWorkflowsDraftResponse) + +/** + * Sync draft workflow + * + * Sync draft workflow configuration + */ +export const post50 = oc + .route({ + description: 'Sync draft workflow configuration', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsDraft', + path: '/apps/{app_id}/workflows/draft', + summary: 'Sync draft workflow', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsDraftBody, + params: zPostAppsByAppIdWorkflowsDraftPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsDraftResponse) + +export const draft2 = { + get: get59, + post: post50, + conversationVariables: conversationVariables2, + environmentVariables, + features, + humanInput: humanInput2, + iteration: iteration2, + loop: loop2, + nodes: nodes7, + run: run10, + systemVariables, + trigger: trigger2, + variables: variables2, +} + +/** + * Get published workflow + * + * Get published workflow for an application + */ +export const get60 = oc + .route({ + description: 'Get published workflow for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowsPublish', + path: '/apps/{app_id}/workflows/publish', + summary: 'Get published workflow', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdWorkflowsPublishPath })) + .output(zGetAppsByAppIdWorkflowsPublishResponse) + +/** + * Publish workflow + */ +export const post51 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsPublish', + path: '/apps/{app_id}/workflows/publish', + summary: 'Publish workflow', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAppsByAppIdWorkflowsPublishBody, + params: zPostAppsByAppIdWorkflowsPublishPath, + }), + ) + .output(zPostAppsByAppIdWorkflowsPublishResponse) + +export const publish = { + get: get60, + post: post51, +} + +/** + * Get webhook trigger for a node + */ +export const get61 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflowsTriggersWebhook', + path: '/apps/{app_id}/workflows/triggers/webhook', + summary: 'Get webhook trigger for a node', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdWorkflowsTriggersWebhookPath, + query: zGetAppsByAppIdWorkflowsTriggersWebhookQuery, + }), + ) + .output(zGetAppsByAppIdWorkflowsTriggersWebhookResponse) + +export const webhook = { + get: get61, +} + +export const triggers2 = { + webhook, +} + +/** + * Restore a published workflow version into the draft workflow + */ +export const post52 = oc + .route({ + description: 'Restore a published workflow version into the draft workflow', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByAppIdWorkflowsByWorkflowIdRestore', + path: '/apps/{app_id}/workflows/{workflow_id}/restore', + tags: ['console'], + }) + .input(z.object({ params: zPostAppsByAppIdWorkflowsByWorkflowIdRestorePath })) + .output(zPostAppsByAppIdWorkflowsByWorkflowIdRestoreResponse) + +export const restore = { + post: post52, +} + +/** + * Delete workflow + */ +export const delete11 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByAppIdWorkflowsByWorkflowId', + path: '/apps/{app_id}/workflows/{workflow_id}', + summary: 'Delete workflow', + tags: ['console'], + }) + .input(z.object({ params: zDeleteAppsByAppIdWorkflowsByWorkflowIdPath })) + .output(zDeleteAppsByAppIdWorkflowsByWorkflowIdResponse) + +/** + * Update workflow attributes + * + * Update workflow by ID + */ +export const patch3 = oc + .route({ + description: 'Update workflow by ID', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchAppsByAppIdWorkflowsByWorkflowId', + path: '/apps/{app_id}/workflows/{workflow_id}', + summary: 'Update workflow attributes', + tags: ['console'], + }) + .input( + z.object({ + body: zPatchAppsByAppIdWorkflowsByWorkflowIdBody, + params: zPatchAppsByAppIdWorkflowsByWorkflowIdPath, + }), + ) + .output(zPatchAppsByAppIdWorkflowsByWorkflowIdResponse) + +export const byWorkflowId = { + delete: delete11, + patch: patch3, + restore, +} + +/** + * Get published workflows + * + * Get all published workflows for an application + */ +export const get62 = oc + .route({ + description: 'Get all published workflows for an application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppIdWorkflows', + path: '/apps/{app_id}/workflows', + summary: 'Get published workflows', + tags: ['console'], + }) + .input( + z.object({ + params: zGetAppsByAppIdWorkflowsPath, + query: zGetAppsByAppIdWorkflowsQuery.optional(), + }), + ) + .output(zGetAppsByAppIdWorkflowsResponse) + +export const workflows3 = { + get: get62, + defaultWorkflowBlockConfigs, + draft: draft2, + publish, + triggers: triggers2, + byWorkflowId, +} + +/** + * Delete app + * + * Delete application + */ +export const delete12 = oc + .route({ + description: 'Delete application', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByAppId', + path: '/apps/{app_id}', + successStatus: 204, + summary: 'Delete app', + tags: ['console'], + }) + .input(z.object({ params: zDeleteAppsByAppIdPath })) + .output(zDeleteAppsByAppIdResponse) + +/** + * Get app detail + * + * Get application details + */ +export const get63 = oc + .route({ + description: 'Get application details', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByAppId', + path: '/apps/{app_id}', + summary: 'Get app detail', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByAppIdPath })) + .output(zGetAppsByAppIdResponse) + +/** + * Update app + * + * Update application details + */ +export const put5 = oc + .route({ + description: 'Update application details', + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putAppsByAppId', + path: '/apps/{app_id}', + summary: 'Update app', + tags: ['console'], + }) + .input(z.object({ body: zPutAppsByAppIdBody, params: zPutAppsByAppIdPath })) + .output(zPutAppsByAppIdResponse) + +export const byAppId2 = { + delete: delete12, + get: get63, + put: put5, + advancedChat, + agent, + annotationReply, + annotationSetting, + annotationSettings, + annotations, + apiEnable, + audioToText, + chatConversations, + chatMessages, + completionConversations, + completionMessages, + conversationVariables, + convertToWorkflow, + copy, + export: export2, + feedbacks, + icon, + messages, + modelConfig, + name, + publishToCreatorsPlatform, + server, + site, + siteEnable, + statistics, + textToAudio, + trace, + traceConfig, + triggerEnable, + triggers, + workflowAppLogs, + workflowArchivedLogs, + workflowRuns: workflowRuns2, + workflow, + workflows: workflows3, +} + +/** + * Delete an API key for an app + * + * Delete an API key for an app + */ +export const delete13 = oc + .route({ + description: 'Delete an API key for an app', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsByResourceIdApiKeysByApiKeyId', + path: '/apps/{resource_id}/api-keys/{api_key_id}', + successStatus: 204, + summary: 'Delete an API key for an app', + tags: ['console'], + }) + .input(z.object({ params: zDeleteAppsByResourceIdApiKeysByApiKeyIdPath })) + .output(zDeleteAppsByResourceIdApiKeysByApiKeyIdResponse) + +export const byApiKeyId = { + delete: delete13, +} + +/** + * Get all API keys for an app + * + * Get all API keys for an app + */ +export const get64 = oc + .route({ + description: 'Get all API keys for an app', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByResourceIdApiKeys', + path: '/apps/{resource_id}/api-keys', + summary: 'Get all API keys for an app', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByResourceIdApiKeysPath })) + .output(zGetAppsByResourceIdApiKeysResponse) + +/** + * Create a new API key for an app + * + * Create a new API key for an app + */ +export const post53 = oc + .route({ + description: 'Create a new API key for an app', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsByResourceIdApiKeys', + path: '/apps/{resource_id}/api-keys', + successStatus: 201, + summary: 'Create a new API key for an app', + tags: ['console'], + }) + .input(z.object({ params: zPostAppsByResourceIdApiKeysPath })) + .output(zPostAppsByResourceIdApiKeysResponse) + +export const apiKeys = { + get: get64, + post: post53, + byApiKeyId, +} + +export const byResourceId = { + apiKeys, +} + +/** + * Refresh MCP server configuration and regenerate server code + */ +export const get65 = oc + .route({ + description: 'Refresh MCP server configuration and regenerate server code', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsByServerIdServerRefresh', + path: '/apps/{server_id}/server/refresh', + tags: ['console'], + }) + .input(z.object({ params: zGetAppsByServerIdServerRefreshPath })) + .output(zGetAppsByServerIdServerRefreshResponse) + +export const refresh = { + get: get65, +} + +export const server2 = { + refresh, +} + +export const byServerId = { + server: server2, +} + +/** + * Get app list + * + * Get list of applications with pagination and filtering + */ +export const get66 = oc + .route({ + description: 'Get list of applications with pagination and filtering', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getApps', + path: '/apps', + summary: 'Get app list', + tags: ['console'], + }) + .input(z.object({ query: zGetAppsQuery.optional() })) + .output(zGetAppsResponse) + +/** + * Create app + * + * Create a new application + */ +export const post54 = oc + .route({ + description: 'Create a new application', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postApps', + path: '/apps', + successStatus: 201, + summary: 'Create app', + tags: ['console'], + }) + .input(z.object({ body: zPostAppsBody })) + .output(zPostAppsResponse) + +export const apps = { + get: get66, + post: post54, + imports, + workflows, + byAppId: byAppId2, + byResourceId, + byServerId, +} + +export const contract = { + apps, +} diff --git a/packages/contracts/generated/api/console/apps/types.gen.ts b/packages/contracts/generated/api/console/apps/types.gen.ts new file mode 100644 index 0000000000..4a4742adcf --- /dev/null +++ b/packages/contracts/generated/api/console/apps/types.gen.ts @@ -0,0 +1,4493 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type AppPagination = { + has_next: boolean + items: Array + page: number + per_page: number + total: number +} + +export type CreateAppPayload = { + description?: string | null + icon?: string | null + icon_background?: string | null + icon_type?: IconType + mode: 'chat' | 'agent-chat' | 'advanced-chat' | 'workflow' | 'completion' + name: string +} + +export type AppDetail = { + access_mode?: string | null + app_model_config?: ModelConfig + created_at?: number | null + created_by?: string | null + description?: string | null + enable_api: boolean + enable_site: boolean + icon?: string | null + icon_background?: string | null + id: string + mode_compatible_with_agent: string + name: string + tags?: Array + tracing?: JsonValue + updated_at?: number | null + updated_by?: string | null + use_icon_as_answer_icon?: boolean | null + workflow?: WorkflowPartial +} + +export type AppImportPayload = { + app_id?: string | null + description?: string | null + icon?: string | null + icon_background?: string | null + icon_type?: string | null + mode: string + name?: string | null + yaml_content?: string | null + yaml_url?: string | null +} + +export type Import = { + app_id?: string | null + app_mode?: string | null + current_dsl_version?: string + error?: string + id: string + imported_dsl_version?: string + status: ImportStatus +} + +export type CheckDependenciesResult = { + leaked_dependencies?: Array +} + +export type AppDetailWithSite = { + access_mode?: string | null + api_base_url?: string | null + app_model_config?: ModelConfig + created_at?: number | null + created_by?: string | null + deleted_tools?: Array + description?: string | null + enable_api: boolean + enable_site: boolean + icon?: string | null + icon_background?: string | null + icon_type?: string | null + id: string + max_active_requests?: number | null + mode_compatible_with_agent: string + name: string + site?: Site + tags?: Array + tracing?: JsonValue + updated_at?: number | null + updated_by?: string | null + use_icon_as_answer_icon?: boolean | null + workflow?: WorkflowPartial +} + +export type UpdateAppPayload = { + description?: string | null + icon?: string | null + icon_background?: string | null + icon_type?: IconType + max_active_requests?: number | null + name: string + use_icon_as_answer_icon?: boolean | null +} + +export type AdvancedChatWorkflowRunPagination = { + [key: string]: unknown +} + +export type WorkflowRunCount = { + [key: string]: unknown +} + +export type HumanInputFormPreviewPayload = { + inputs?: { + [key: string]: unknown + } +} + +export type HumanInputFormSubmitPayload = { + action: string + form_inputs: { + [key: string]: unknown + } + inputs: { + [key: string]: unknown + } +} + +export type IterationNodeRunPayload = { + inputs?: { + [key: string]: unknown + } | null +} + +export type LoopNodeRunPayload = { + inputs?: { + [key: string]: unknown + } | null +} + +export type AdvancedChatWorkflowRunPayload = { + conversation_id?: string | null + files?: Array<{ + [key: string]: unknown + }> | null + inputs?: { + [key: string]: unknown + } | null + parent_message_id?: string | null + query?: string +} + +export type AnnotationReplyPayload = { + embedding_model_name: string + embedding_provider_name: string + score_threshold: number +} + +export type AnnotationSettingUpdatePayload = { + score_threshold: number +} + +export type CreateAnnotationPayload = { + annotation_reply?: { + [key: string]: unknown + } | null + answer?: string | null + content?: string | null + message_id?: string | null + question?: string | null +} + +export type Annotation = { + content?: string | null + created_at?: number | null + hit_count?: number | null + id: string + question?: string | null +} + +export type AnnotationCountResponse = { + count: number +} + +export type AnnotationExportList = { + data: Array +} + +export type UpdateAnnotationPayload = { + annotation_reply?: { + [key: string]: unknown + } | null + answer?: string | null + content?: string | null + question?: string | null +} + +export type AnnotationHitHistoryList = { + data: Array + has_more: boolean + limit: number + page: number + total: number +} + +export type AppApiStatusPayload = { + enable_api: boolean +} + +export type AudioTranscriptResponse = { + text: string +} + +export type ConversationWithSummaryPagination = { + has_next: boolean + items: Array + page: number + per_page: number + total: number +} + +export type ConversationDetail = { + admin_feedback_stats?: FeedbackStat + annotated: boolean + created_at?: number | null + from_account_id?: string | null + from_end_user_id?: string | null + from_source: string + id: string + introduction?: string | null + message_count: number + model_config?: ModelConfig + status: string + updated_at?: number | null + user_feedback_stats?: FeedbackStat +} + +export type MessageInfiniteScrollPaginationResponse = { + data: Array + has_more: boolean + limit: number +} + +export type SuggestedQuestionsResponse = { + data: Array +} + +export type ConversationPagination = { + has_next: boolean + items: Array + page: number + per_page: number + total: number +} + +export type ConversationMessageDetail = { + created_at?: number | null + first_message?: MessageDetail + from_account_id?: string | null + from_end_user_id?: string | null + from_source: string + id: string + model_config?: ModelConfig + status: string +} + +export type CompletionMessagePayload = { + files?: Array | null + inputs: { + [key: string]: unknown + } + model_config: { + [key: string]: unknown + } + query?: string + response_mode?: 'blocking' | 'streaming' + retriever_from?: string +} + +export type PaginatedConversationVariableResponse = { + data: Array + has_more: boolean + limit: number + page: number + total: number +} + +export type ConvertToWorkflowPayload = { + icon?: string | null + icon_background?: string | null + icon_type?: string | null + name?: string | null +} + +export type CopyAppPayload = { + description?: string | null + icon?: string | null + icon_background?: string | null + icon_type?: IconType + name?: string | null +} + +export type AppExportResponse = { + data: string +} + +export type MessageFeedbackPayload = { + content?: string | null + message_id: string + rating?: 'like' | 'dislike' | null +} + +export type AppIconPayload = { + icon?: string | null + icon_background?: string | null + icon_type?: IconType +} + +export type MessageDetailResponse = { + agent_thoughts?: Array + annotation?: ConversationAnnotation + annotation_hit_history?: ConversationAnnotationHitHistory + answer_tokens?: number | null + conversation_id: string + created_at?: number | null + error?: string | null + extra_contents?: Array + feedbacks?: Array + from_account_id?: string | null + from_end_user_id?: string | null + from_source: string + id: string + inputs: { + [key: string]: JsonValue + } + message?: JsonValue + message_files?: Array + message_metadata_dict?: JsonValue + message_tokens?: number | null + parent_message_id?: string | null + provider_response_latency?: number | null + query: string + re_sign_file_url_answer: string + status: string + workflow_run_id?: string | null +} + +export type ModelConfigRequest = { + agent_mode?: { + [key: string]: unknown + } | null + configs?: { + [key: string]: unknown + } | null + dataset_configs?: { + [key: string]: unknown + } | null + model?: string | null + more_like_this?: { + [key: string]: unknown + } | null + opening_statement?: string | null + provider?: string | null + retrieval_model?: { + [key: string]: unknown + } | null + speech_to_text?: { + [key: string]: unknown + } | null + suggested_questions?: Array | null + text_to_speech?: { + [key: string]: unknown + } | null + tools?: Array<{ + [key: string]: unknown + }> | null +} + +export type AppNamePayload = { + name: string +} + +export type AppMcpServerResponse = { + created_at?: number | null + description: string + id: string + name: string + parameters: unknown + server_code: string + status: AppMcpServerStatus + updated_at?: number | null +} + +export type McpServerCreatePayload = { + description?: string | null + parameters: { + [key: string]: unknown + } +} + +export type McpServerUpdatePayload = { + description?: string | null + id: string + parameters: { + [key: string]: unknown + } + status?: string | null +} + +export type AppSiteUpdatePayload = { + chat_color_theme?: string | null + chat_color_theme_inverted?: boolean | null + copyright?: string | null + custom_disclaimer?: string | null + customize_domain?: string | null + customize_token_strategy?: 'must' | 'allow' | 'not_allow' | null + default_language?: string | null + description?: string | null + icon?: string | null + icon_background?: string | null + icon_type?: string | null + privacy_policy?: string | null + prompt_public?: boolean | null + show_workflow_steps?: boolean | null + title?: string | null + use_icon_as_answer_icon?: boolean | null +} + +export type AppSiteResponse = { + app_id: string + code?: string | null + copyright?: string | null + custom_disclaimer?: string | null + customize_domain?: string | null + customize_token_strategy: string + default_language: string + description?: string | null + icon?: string | null + icon_background?: string | null + privacy_policy?: string | null + prompt_public: boolean + show_workflow_steps: boolean + title: string + use_icon_as_answer_icon: boolean +} + +export type AppSiteStatusPayload = { + enable_site: boolean +} + +export type TextToSpeechPayload = { + message_id?: string | null + streaming?: boolean | null + text: string + voice?: string | null +} + +export type AppTracePayload = { + enabled: boolean + tracing_provider?: string | null +} + +export type TraceProviderQuery = { + tracing_provider: string +} + +export type TraceConfigPayload = { + tracing_config: { + [key: string]: unknown + } + tracing_provider: string +} + +export type ParserEnable = { + enable_trigger: boolean + trigger_id: string +} + +export type WorkflowTriggerResponse = { + created_at?: string | null + icon: string + id: string + node_id: string + provider_name: string + status: string + title: string + trigger_type: string + updated_at?: string | null +} + +export type WorkflowTriggerListResponse = { + data: Array +} + +export type WorkflowAppLogPaginationResponse = { + data: Array + has_more: boolean + limit: number + page: number + total: number +} + +export type WorkflowArchivedLogPaginationResponse = { + data: Array + has_more: boolean + limit: number + page: number + total: number +} + +export type WorkflowRunPagination = { + [key: string]: unknown +} + +export type WorkflowRunDetail = { + [key: string]: unknown +} + +export type WorkflowRunExport = { + [key: string]: unknown +} + +export type WorkflowRunNodeExecutionList = { + [key: string]: unknown +} + +export type WorkflowCommentBasic = { + [key: string]: unknown +} + +export type WorkflowCommentCreatePayload = { + content: string + mentioned_user_ids?: Array + position_x: number + position_y: number +} + +export type WorkflowCommentCreate = { + [key: string]: unknown +} + +export type WorkflowCommentMentionUsersPayload = { + users: Array +} + +export type WorkflowCommentDetail = { + [key: string]: unknown +} + +export type WorkflowCommentUpdatePayload = { + content: string + mentioned_user_ids?: Array | null + position_x?: number | null + position_y?: number | null +} + +export type WorkflowCommentUpdate = { + [key: string]: unknown +} + +export type WorkflowCommentReplyPayload = { + content: string + mentioned_user_ids?: Array +} + +export type WorkflowCommentReplyCreate = { + [key: string]: unknown +} + +export type WorkflowCommentReplyUpdate = { + [key: string]: unknown +} + +export type WorkflowCommentResolve = { + [key: string]: unknown +} + +export type WorkflowPagination = { + [key: string]: unknown +} + +export type Workflow = { + [key: string]: unknown +} + +export type SyncDraftWorkflowPayload = { + conversation_variables?: Array<{ + [key: string]: unknown + }> + environment_variables?: Array<{ + [key: string]: unknown + }> + features: { + [key: string]: unknown + } + graph: { + [key: string]: unknown + } + hash?: string | null +} + +export type SyncDraftWorkflowResponse = { + [key: string]: unknown +} + +export type WorkflowDraftVariableList = { + [key: string]: unknown +} + +export type ConversationVariableUpdatePayload = { + conversation_variables: Array<{ + [key: string]: unknown + }> +} + +export type EnvironmentVariableUpdatePayload = { + environment_variables: Array<{ + [key: string]: unknown + }> +} + +export type WorkflowFeaturesPayload = { + features: { + [key: string]: unknown + } +} + +export type HumanInputDeliveryTestPayload = { + delivery_method_id: string + inputs?: { + [key: string]: unknown + } +} + +export type WorkflowRunNodeExecution = { + [key: string]: unknown +} + +export type DraftWorkflowNodeRunPayload = { + files?: Array<{ + [key: string]: unknown + }> | null + inputs: { + [key: string]: unknown + } + query?: string +} + +export type DraftWorkflowRunPayload = { + datasource_info_list: Array<{ + [key: string]: unknown + }> + datasource_type: string + inputs: { + [key: string]: unknown + } + start_node_id: string +} + +export type DraftWorkflowTriggerRunRequest = { + [key: string]: unknown +} + +export type DraftWorkflowTriggerRunAllPayload = { + node_ids: Array +} + +export type WorkflowDraftVariableListWithoutValue = { + [key: string]: unknown +} + +export type WorkflowDraftVariable = { + [key: string]: unknown +} + +export type WorkflowDraftVariableUpdatePayload = { + name?: string | null + value?: unknown +} + +export type PublishWorkflowPayload = { + marked_comment?: string | null + marked_name?: string | null +} + +export type WebhookTriggerResponse = { + created_at?: string | null + id: string + node_id: string + webhook_debug_url: string + webhook_id: string + webhook_url: string +} + +export type WorkflowUpdatePayload = { + marked_comment?: string | null + marked_name?: string | null +} + +export type ApiKeyList = { + data: Array +} + +export type ApiKeyItem = { + created_at?: number | null + id: string + last_used_at?: number | null + token: string + type: string +} + +export type AppPartial = { + access_mode?: string | null + app_model_config?: ModelConfigPartial + author_name?: string | null + create_user_name?: string | null + created_at?: number | null + created_by?: string | null + desc_or_prompt?: string | null + has_draft_trigger?: boolean | null + icon?: string | null + icon_background?: string | null + icon_type?: string | null + id: string + max_active_requests?: number | null + mode_compatible_with_agent: string + name: string + tags?: Array + updated_at?: number | null + updated_by?: string | null + use_icon_as_answer_icon?: boolean | null + workflow?: WorkflowPartial +} + +export type IconType = 'image' | 'emoji' | 'link' + +export type ModelConfig = { + agent_mode_dict?: JsonValue + annotation_reply_dict?: JsonValue + chat_prompt_config_dict?: JsonValue + completion_prompt_config_dict?: JsonValue + created_at?: number | null + created_by?: string | null + dataset_configs_dict?: JsonValue + dataset_query_variable?: string | null + external_data_tools_list?: JsonValue + file_upload_dict?: JsonValue + model_dict?: JsonValue + more_like_this_dict?: JsonValue + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource_dict?: JsonValue + sensitive_word_avoidance_dict?: JsonValue + speech_to_text_dict?: JsonValue + suggested_questions_after_answer_dict?: JsonValue + suggested_questions_list?: JsonValue + text_to_speech_dict?: JsonValue + updated_at?: number | null + updated_by?: string | null + user_input_form_list?: JsonValue +} + +export type Tag = { + id: string + name: string + type: string +} + +export type JsonValue = unknown + +export type WorkflowPartial = { + created_at?: number | null + created_by?: string | null + id: string + updated_at?: number | null + updated_by?: string | null +} + +export type ImportStatus = 'completed' | 'completed-with-warnings' | 'pending' | 'failed' + +export type PluginDependency = { + current_identifier?: string | null + type: Type + value: unknown +} + +export type DeletedTool = { + provider_id: string + tool_name: string + type: string +} + +export type Site = { + app_base_url?: string | null + chat_color_theme?: string | null + chat_color_theme_inverted?: boolean | null + code?: string | null + copyright?: string | null + created_at?: number | null + created_by?: string | null + custom_disclaimer?: string | null + customize_domain?: string | null + customize_token_strategy?: string | null + default_language?: string | null + description?: string | null + icon?: string | null + icon_background?: string | null + icon_type?: unknown + privacy_policy?: string | null + prompt_public?: boolean | null + show_workflow_steps?: boolean | null + title?: string | null + updated_at?: number | null + updated_by?: string | null + use_icon_as_answer_icon?: boolean | null +} + +export type AnnotationHitHistory = { + annotation_content?: string | null + annotation_question?: string | null + created_at?: number | null + id: string + question?: string | null + score?: number | null + source?: string | null +} + +export type ConversationWithSummary = { + admin_feedback_stats?: FeedbackStat + annotated: boolean + created_at?: number | null + from_account_id?: string | null + from_account_name?: string | null + from_end_user_id?: string | null + from_end_user_session_id?: string | null + from_source: string + id: string + message_count: number + model_config?: SimpleModelConfig + name: string + read_at?: number | null + status: string + status_count?: StatusCount + summary_or_query: string + updated_at?: number | null + user_feedback_stats?: FeedbackStat +} + +export type FeedbackStat = { + dislike: number + like: number +} + +export type Conversation = { + admin_feedback_stats?: FeedbackStat + annotation?: ConversationAnnotation + created_at?: number | null + first_message?: SimpleMessageDetail + from_account_id?: string | null + from_account_name?: string | null + from_end_user_id?: string | null + from_end_user_session_id?: string | null + from_source: string + id: string + model_config?: SimpleModelConfig + read_at?: number | null + status: string + updated_at?: number | null + user_feedback_stats?: FeedbackStat +} + +export type MessageDetail = { + agent_thoughts: Array + annotation?: ConversationAnnotation + annotation_hit_history?: ConversationAnnotationHitHistory + answer_tokens: number + conversation_id: string + created_at?: number | null + error?: string | null + feedbacks: Array + from_account_id?: string | null + from_end_user_id?: string | null + from_source: string + id: string + inputs: { + [key: string]: JsonValue + } + message: JsonValue + message_files: Array + message_metadata_dict: JsonValue + message_tokens: number + parent_message_id?: string | null + provider_response_latency: number + query: string + re_sign_file_url_answer: string + status: string + workflow_run_id?: string | null +} + +export type ConversationVariableResponse = { + created_at?: number | null + description?: string | null + id: string + name: string + updated_at?: number | null + value?: string | null + value_type: string +} + +export type AgentThought = { + chain_id?: string | null + created_at?: number | null + files: Array + id: string + message_chain_id?: string | null + message_id: string + observation?: string | null + position: number + thought?: string | null + tool?: string | null + tool_input?: string | null + tool_labels: JsonValue +} + +export type ConversationAnnotation = { + account?: SimpleAccount + content: string + created_at?: number | null + id: string + question?: string | null +} + +export type ConversationAnnotationHitHistory = { + annotation_create_account?: SimpleAccount + created_at?: number | null + id: string +} + +export type HumanInputContent = { + form_definition?: HumanInputFormDefinition + form_submission_data?: HumanInputFormSubmissionData + submitted: boolean + type?: ExecutionContentType + workflow_run_id: string +} + +export type Feedback = { + content?: string | null + from_account?: SimpleAccount + from_end_user_id?: string | null + from_source: string + rating: string +} + +export type MessageFile = { + belongs_to?: string | null + filename: string + id: string + mime_type?: string | null + size?: number | null + transfer_method: string + type: string + upload_file_id?: string | null + url?: string | null +} + +export type AppMcpServerStatus = 'normal' | 'active' | 'inactive' + +export type WorkflowAppLogPartialResponse = { + created_at?: number | null + created_by_account?: SimpleAccount + created_by_end_user?: SimpleEndUser + created_by_role?: string | null + created_from?: string | null + details?: unknown + id: string + workflow_run?: WorkflowRunForLogResponse +} + +export type WorkflowArchivedLogPartialResponse = { + created_at?: number | null + created_by_account?: SimpleAccount + created_by_end_user?: SimpleEndUser + id: string + trigger_metadata?: unknown + workflow_run?: WorkflowRunForArchivedLogResponse +} + +export type AccountWithRole = { + avatar?: string | null + created_at?: number | null + email: string + id: string + last_active_at?: number | null + last_login_at?: number | null + name: string + role: string + status: string +} + +export type ModelConfigPartial = { + created_at?: number | null + created_by?: string | null + model_dict?: JsonValue + pre_prompt?: string | null + updated_at?: number | null + updated_by?: string | null +} + +export type Type = 'github' | 'marketplace' | 'package' + +export type Github = { + github_plugin_unique_identifier: string + package: string + repo: string + version: string +} + +export type Marketplace = { + marketplace_plugin_unique_identifier: string + version?: string | null +} + +export type Package = { + plugin_unique_identifier: string + version?: string | null +} + +export type SimpleModelConfig = { + model_dict?: JsonValue + pre_prompt?: string | null +} + +export type StatusCount = { + failed: number + partial_success: number + paused: number + success: number +} + +export type SimpleMessageDetail = { + answer: string + inputs: { + [key: string]: JsonValue + } + message: string + query: string +} + +export type SimpleAccount = { + email: string + id: string + name: string +} + +export type HumanInputFormDefinition = { + actions?: Array + display_in_ui?: boolean + expiration_time: number + form_content: string + form_id: string + form_token?: string | null + inputs?: Array + node_id: string + node_title: string + resolved_default_values?: { + [key: string]: unknown + } +} + +export type HumanInputFormSubmissionData = { + action_id: string + action_text: string + node_id: string + node_title: string + rendered_content: string +} + +export type ExecutionContentType = 'human_input' + +export type SimpleEndUser = { + id: string + is_anonymous: boolean + session_id?: string | null + type: string +} + +export type WorkflowRunForLogResponse = { + created_at?: number | null + elapsed_time?: number | null + error?: string | null + exceptions_count?: number | null + finished_at?: number | null + id: string + status?: string | null + total_steps?: number | null + total_tokens?: number | null + triggered_from?: string | null + version?: string | null +} + +export type WorkflowRunForArchivedLogResponse = { + elapsed_time?: number | null + id: string + status?: string | null + total_tokens?: number | null + triggered_from?: string | null +} + +export type UserAction = { + button_style?: ButtonStyle + id: string + title: string +} + +export type FormInput = { + default?: FormInputDefault + output_variable_name: string + type: FormInputType +} + +export type ButtonStyle = 'primary' | 'default' | 'accent' | 'ghost' + +export type FormInputDefault = { + selector?: Array + type: PlaceholderType + value?: string +} + +export type FormInputType = 'text_input' | 'paragraph' + +export type PlaceholderType = 'variable' | 'constant' + +export type GetAppsData = { + body?: never + path?: never + query?: { + is_created_by_me?: boolean | null + limit?: number + mode?: 'completion' | 'chat' | 'advanced-chat' | 'workflow' | 'agent-chat' | 'channel' | 'all' + name?: string | null + page?: number + tag_ids?: Array | null + } + url: '/apps' +} + +export type GetAppsResponses = { + 200: AppPagination +} + +export type GetAppsResponse = GetAppsResponses[keyof GetAppsResponses] + +export type PostAppsData = { + body: CreateAppPayload + path?: never + query?: never + url: '/apps' +} + +export type PostAppsErrors = { + 400: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type PostAppsError = PostAppsErrors[keyof PostAppsErrors] + +export type PostAppsResponses = { + 201: AppDetail +} + +export type PostAppsResponse = PostAppsResponses[keyof PostAppsResponses] + +export type PostAppsImportsData = { + body: AppImportPayload + path?: never + query?: never + url: '/apps/imports' +} + +export type PostAppsImportsErrors = { + 400: Import +} + +export type PostAppsImportsError = PostAppsImportsErrors[keyof PostAppsImportsErrors] + +export type PostAppsImportsResponses = { + 200: Import + 202: Import +} + +export type PostAppsImportsResponse = PostAppsImportsResponses[keyof PostAppsImportsResponses] + +export type GetAppsImportsByAppIdCheckDependenciesData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/imports/{app_id}/check-dependencies' +} + +export type GetAppsImportsByAppIdCheckDependenciesResponses = { + 200: CheckDependenciesResult +} + +export type GetAppsImportsByAppIdCheckDependenciesResponse + = GetAppsImportsByAppIdCheckDependenciesResponses[keyof GetAppsImportsByAppIdCheckDependenciesResponses] + +export type PostAppsImportsByImportIdConfirmData = { + body?: never + path: { + import_id: string + } + query?: never + url: '/apps/imports/{import_id}/confirm' +} + +export type PostAppsImportsByImportIdConfirmErrors = { + 400: Import +} + +export type PostAppsImportsByImportIdConfirmError + = PostAppsImportsByImportIdConfirmErrors[keyof PostAppsImportsByImportIdConfirmErrors] + +export type PostAppsImportsByImportIdConfirmResponses = { + 200: Import +} + +export type PostAppsImportsByImportIdConfirmResponse + = PostAppsImportsByImportIdConfirmResponses[keyof PostAppsImportsByImportIdConfirmResponses] + +export type GetAppsWorkflowsOnlineUsersData = { + body?: never + path?: never + query: { + app_ids: string + } + url: '/apps/workflows/online-users' +} + +export type GetAppsWorkflowsOnlineUsersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsWorkflowsOnlineUsersResponse + = GetAppsWorkflowsOnlineUsersResponses[keyof GetAppsWorkflowsOnlineUsersResponses] + +export type DeleteAppsByAppIdData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}' +} + +export type DeleteAppsByAppIdErrors = { + 403: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdError = DeleteAppsByAppIdErrors[keyof DeleteAppsByAppIdErrors] + +export type DeleteAppsByAppIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdResponse = DeleteAppsByAppIdResponses[keyof DeleteAppsByAppIdResponses] + +export type GetAppsByAppIdData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}' +} + +export type GetAppsByAppIdResponses = { + 200: AppDetailWithSite +} + +export type GetAppsByAppIdResponse = GetAppsByAppIdResponses[keyof GetAppsByAppIdResponses] + +export type PutAppsByAppIdData = { + body: UpdateAppPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}' +} + +export type PutAppsByAppIdErrors = { + 400: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type PutAppsByAppIdError = PutAppsByAppIdErrors[keyof PutAppsByAppIdErrors] + +export type PutAppsByAppIdResponses = { + 200: AppDetailWithSite +} + +export type PutAppsByAppIdResponse = PutAppsByAppIdResponses[keyof PutAppsByAppIdResponses] + +export type GetAppsByAppIdAdvancedChatWorkflowRunsData = { + body?: never + path: { + app_id: string + } + query?: { + triggered_from?: 'debugging' | 'app-run' | null + status?: 'running' | 'succeeded' | 'failed' | 'stopped' | 'partial-succeeded' | null + last_id?: string | null + limit?: number + } + url: '/apps/{app_id}/advanced-chat/workflow-runs' +} + +export type GetAppsByAppIdAdvancedChatWorkflowRunsResponses = { + 200: AdvancedChatWorkflowRunPagination +} + +export type GetAppsByAppIdAdvancedChatWorkflowRunsResponse + = GetAppsByAppIdAdvancedChatWorkflowRunsResponses[keyof GetAppsByAppIdAdvancedChatWorkflowRunsResponses] + +export type GetAppsByAppIdAdvancedChatWorkflowRunsCountData = { + body?: never + path: { + app_id: string + } + query?: { + triggered_from?: 'debugging' | 'app-run' | null + time_range?: string | null + status?: 'running' | 'succeeded' | 'failed' | 'stopped' | 'partial-succeeded' | null + } + url: '/apps/{app_id}/advanced-chat/workflow-runs/count' +} + +export type GetAppsByAppIdAdvancedChatWorkflowRunsCountResponses = { + 200: WorkflowRunCount +} + +export type GetAppsByAppIdAdvancedChatWorkflowRunsCountResponse + = GetAppsByAppIdAdvancedChatWorkflowRunsCountResponses[keyof GetAppsByAppIdAdvancedChatWorkflowRunsCountResponses] + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewData = { + body: HumanInputFormPreviewPayload + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/advanced-chat/workflows/draft/human-input/nodes/{node_id}/form/preview' +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponse + = PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponses[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponses] + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunData = { + body: HumanInputFormSubmitPayload + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/advanced-chat/workflows/draft/human-input/nodes/{node_id}/form/run' +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunResponse + = PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunResponses[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunResponses] + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunData = { + body: IterationNodeRunPayload + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/advanced-chat/workflows/draft/iteration/nodes/{node_id}/run' +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunError + = PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunErrors[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunErrors] + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunResponse + = PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunResponses[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunResponses] + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunData = { + body: LoopNodeRunPayload + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/advanced-chat/workflows/draft/loop/nodes/{node_id}/run' +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunError + = PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunErrors[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunErrors] + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunResponse + = PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunResponses[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunResponses] + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftRunData = { + body: AdvancedChatWorkflowRunPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/advanced-chat/workflows/draft/run' +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftRunErrors = { + 400: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftRunError + = PostAppsByAppIdAdvancedChatWorkflowsDraftRunErrors[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftRunErrors] + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAdvancedChatWorkflowsDraftRunResponse + = PostAppsByAppIdAdvancedChatWorkflowsDraftRunResponses[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftRunResponses] + +export type GetAppsByAppIdAgentLogsData = { + body?: never + path: { + app_id: string + } + query: { + conversation_id: string + message_id: string + } + url: '/apps/{app_id}/agent/logs' +} + +export type GetAppsByAppIdAgentLogsErrors = { + 400: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdAgentLogsError + = GetAppsByAppIdAgentLogsErrors[keyof GetAppsByAppIdAgentLogsErrors] + +export type GetAppsByAppIdAgentLogsResponses = { + 200: Array<{ + [key: string]: unknown + }> +} + +export type GetAppsByAppIdAgentLogsResponse + = GetAppsByAppIdAgentLogsResponses[keyof GetAppsByAppIdAgentLogsResponses] + +export type PostAppsByAppIdAnnotationReplyByActionData = { + body: AnnotationReplyPayload + path: { + app_id: string + action: string + } + query?: never + url: '/apps/{app_id}/annotation-reply/{action}' +} + +export type PostAppsByAppIdAnnotationReplyByActionErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAnnotationReplyByActionError + = PostAppsByAppIdAnnotationReplyByActionErrors[keyof PostAppsByAppIdAnnotationReplyByActionErrors] + +export type PostAppsByAppIdAnnotationReplyByActionResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAnnotationReplyByActionResponse + = PostAppsByAppIdAnnotationReplyByActionResponses[keyof PostAppsByAppIdAnnotationReplyByActionResponses] + +export type GetAppsByAppIdAnnotationReplyByActionStatusByJobIdData = { + body?: never + path: { + app_id: string + action: string + job_id: string + } + query?: never + url: '/apps/{app_id}/annotation-reply/{action}/status/{job_id}' +} + +export type GetAppsByAppIdAnnotationReplyByActionStatusByJobIdErrors = { + 403: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdAnnotationReplyByActionStatusByJobIdError + = GetAppsByAppIdAnnotationReplyByActionStatusByJobIdErrors[keyof GetAppsByAppIdAnnotationReplyByActionStatusByJobIdErrors] + +export type GetAppsByAppIdAnnotationReplyByActionStatusByJobIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdAnnotationReplyByActionStatusByJobIdResponse + = GetAppsByAppIdAnnotationReplyByActionStatusByJobIdResponses[keyof GetAppsByAppIdAnnotationReplyByActionStatusByJobIdResponses] + +export type GetAppsByAppIdAnnotationSettingData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/annotation-setting' +} + +export type GetAppsByAppIdAnnotationSettingErrors = { + 403: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdAnnotationSettingError + = GetAppsByAppIdAnnotationSettingErrors[keyof GetAppsByAppIdAnnotationSettingErrors] + +export type GetAppsByAppIdAnnotationSettingResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdAnnotationSettingResponse + = GetAppsByAppIdAnnotationSettingResponses[keyof GetAppsByAppIdAnnotationSettingResponses] + +export type PostAppsByAppIdAnnotationSettingsByAnnotationSettingIdData = { + body: AnnotationSettingUpdatePayload + path: { + app_id: string + annotation_setting_id: string + } + query?: never + url: '/apps/{app_id}/annotation-settings/{annotation_setting_id}' +} + +export type PostAppsByAppIdAnnotationSettingsByAnnotationSettingIdErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAnnotationSettingsByAnnotationSettingIdError + = PostAppsByAppIdAnnotationSettingsByAnnotationSettingIdErrors[keyof PostAppsByAppIdAnnotationSettingsByAnnotationSettingIdErrors] + +export type PostAppsByAppIdAnnotationSettingsByAnnotationSettingIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAnnotationSettingsByAnnotationSettingIdResponse + = PostAppsByAppIdAnnotationSettingsByAnnotationSettingIdResponses[keyof PostAppsByAppIdAnnotationSettingsByAnnotationSettingIdResponses] + +export type DeleteAppsByAppIdAnnotationsData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/annotations' +} + +export type DeleteAppsByAppIdAnnotationsResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdAnnotationsResponse + = DeleteAppsByAppIdAnnotationsResponses[keyof DeleteAppsByAppIdAnnotationsResponses] + +export type GetAppsByAppIdAnnotationsData = { + body?: never + path: { + app_id: string + } + query?: { + keyword?: string + limit?: number + page?: number + } + url: '/apps/{app_id}/annotations' +} + +export type GetAppsByAppIdAnnotationsErrors = { + 403: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdAnnotationsError + = GetAppsByAppIdAnnotationsErrors[keyof GetAppsByAppIdAnnotationsErrors] + +export type GetAppsByAppIdAnnotationsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdAnnotationsResponse + = GetAppsByAppIdAnnotationsResponses[keyof GetAppsByAppIdAnnotationsResponses] + +export type PostAppsByAppIdAnnotationsData = { + body: CreateAnnotationPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/annotations' +} + +export type PostAppsByAppIdAnnotationsErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAnnotationsError + = PostAppsByAppIdAnnotationsErrors[keyof PostAppsByAppIdAnnotationsErrors] + +export type PostAppsByAppIdAnnotationsResponses = { + 201: Annotation +} + +export type PostAppsByAppIdAnnotationsResponse + = PostAppsByAppIdAnnotationsResponses[keyof PostAppsByAppIdAnnotationsResponses] + +export type PostAppsByAppIdAnnotationsBatchImportData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/annotations/batch-import' +} + +export type PostAppsByAppIdAnnotationsBatchImportErrors = { + 400: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 413: { + [key: string]: unknown + } + 429: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAnnotationsBatchImportError + = PostAppsByAppIdAnnotationsBatchImportErrors[keyof PostAppsByAppIdAnnotationsBatchImportErrors] + +export type PostAppsByAppIdAnnotationsBatchImportResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAnnotationsBatchImportResponse + = PostAppsByAppIdAnnotationsBatchImportResponses[keyof PostAppsByAppIdAnnotationsBatchImportResponses] + +export type GetAppsByAppIdAnnotationsBatchImportStatusByJobIdData = { + body?: never + path: { + app_id: string + job_id: string + } + query?: never + url: '/apps/{app_id}/annotations/batch-import-status/{job_id}' +} + +export type GetAppsByAppIdAnnotationsBatchImportStatusByJobIdErrors = { + 403: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdAnnotationsBatchImportStatusByJobIdError + = GetAppsByAppIdAnnotationsBatchImportStatusByJobIdErrors[keyof GetAppsByAppIdAnnotationsBatchImportStatusByJobIdErrors] + +export type GetAppsByAppIdAnnotationsBatchImportStatusByJobIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdAnnotationsBatchImportStatusByJobIdResponse + = GetAppsByAppIdAnnotationsBatchImportStatusByJobIdResponses[keyof GetAppsByAppIdAnnotationsBatchImportStatusByJobIdResponses] + +export type GetAppsByAppIdAnnotationsCountData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/annotations/count' +} + +export type GetAppsByAppIdAnnotationsCountResponses = { + 200: AnnotationCountResponse +} + +export type GetAppsByAppIdAnnotationsCountResponse + = GetAppsByAppIdAnnotationsCountResponses[keyof GetAppsByAppIdAnnotationsCountResponses] + +export type GetAppsByAppIdAnnotationsExportData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/annotations/export' +} + +export type GetAppsByAppIdAnnotationsExportErrors = { + 403: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdAnnotationsExportError + = GetAppsByAppIdAnnotationsExportErrors[keyof GetAppsByAppIdAnnotationsExportErrors] + +export type GetAppsByAppIdAnnotationsExportResponses = { + 200: AnnotationExportList +} + +export type GetAppsByAppIdAnnotationsExportResponse + = GetAppsByAppIdAnnotationsExportResponses[keyof GetAppsByAppIdAnnotationsExportResponses] + +export type DeleteAppsByAppIdAnnotationsByAnnotationIdData = { + body?: never + path: { + annotation_id: string + app_id: string + } + query?: never + url: '/apps/{app_id}/annotations/{annotation_id}' +} + +export type DeleteAppsByAppIdAnnotationsByAnnotationIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdAnnotationsByAnnotationIdResponse + = DeleteAppsByAppIdAnnotationsByAnnotationIdResponses[keyof DeleteAppsByAppIdAnnotationsByAnnotationIdResponses] + +export type PostAppsByAppIdAnnotationsByAnnotationIdData = { + body: UpdateAnnotationPayload + path: { + app_id: string + annotation_id: string + } + query?: never + url: '/apps/{app_id}/annotations/{annotation_id}' +} + +export type PostAppsByAppIdAnnotationsByAnnotationIdErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAnnotationsByAnnotationIdError + = PostAppsByAppIdAnnotationsByAnnotationIdErrors[keyof PostAppsByAppIdAnnotationsByAnnotationIdErrors] + +export type PostAppsByAppIdAnnotationsByAnnotationIdResponses = { + 200: Annotation + 204: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAnnotationsByAnnotationIdResponse + = PostAppsByAppIdAnnotationsByAnnotationIdResponses[keyof PostAppsByAppIdAnnotationsByAnnotationIdResponses] + +export type GetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesData = { + body?: never + path: { + app_id: string + annotation_id: string + } + query?: { + page?: number + limit?: number + } + url: '/apps/{app_id}/annotations/{annotation_id}/hit-histories' +} + +export type GetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesErrors = { + 403: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesError + = GetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesErrors[keyof GetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesErrors] + +export type GetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesResponses = { + 200: AnnotationHitHistoryList +} + +export type GetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesResponse + = GetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesResponses[keyof GetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesResponses] + +export type PostAppsByAppIdApiEnableData = { + body: AppApiStatusPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/api-enable' +} + +export type PostAppsByAppIdApiEnableErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdApiEnableError + = PostAppsByAppIdApiEnableErrors[keyof PostAppsByAppIdApiEnableErrors] + +export type PostAppsByAppIdApiEnableResponses = { + 200: AppDetail +} + +export type PostAppsByAppIdApiEnableResponse + = PostAppsByAppIdApiEnableResponses[keyof PostAppsByAppIdApiEnableResponses] + +export type PostAppsByAppIdAudioToTextData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/audio-to-text' +} + +export type PostAppsByAppIdAudioToTextErrors = { + 400: { + [key: string]: unknown + } + 413: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdAudioToTextError + = PostAppsByAppIdAudioToTextErrors[keyof PostAppsByAppIdAudioToTextErrors] + +export type PostAppsByAppIdAudioToTextResponses = { + 200: AudioTranscriptResponse +} + +export type PostAppsByAppIdAudioToTextResponse + = PostAppsByAppIdAudioToTextResponses[keyof PostAppsByAppIdAudioToTextResponses] + +export type GetAppsByAppIdChatConversationsData = { + body?: never + path: { + app_id: string + } + query?: { + annotation_status?: 'annotated' | 'not_annotated' | 'all' + end?: string | null + keyword?: string | null + limit?: number + page?: number + sort_by?: 'created_at' | '-created_at' | 'updated_at' | '-updated_at' + start?: string | null + } + url: '/apps/{app_id}/chat-conversations' +} + +export type GetAppsByAppIdChatConversationsErrors = { + 403: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdChatConversationsError + = GetAppsByAppIdChatConversationsErrors[keyof GetAppsByAppIdChatConversationsErrors] + +export type GetAppsByAppIdChatConversationsResponses = { + 200: ConversationWithSummaryPagination +} + +export type GetAppsByAppIdChatConversationsResponse + = GetAppsByAppIdChatConversationsResponses[keyof GetAppsByAppIdChatConversationsResponses] + +export type DeleteAppsByAppIdChatConversationsByConversationIdData = { + body?: never + path: { + app_id: string + conversation_id: string + } + query?: never + url: '/apps/{app_id}/chat-conversations/{conversation_id}' +} + +export type DeleteAppsByAppIdChatConversationsByConversationIdErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdChatConversationsByConversationIdError + = DeleteAppsByAppIdChatConversationsByConversationIdErrors[keyof DeleteAppsByAppIdChatConversationsByConversationIdErrors] + +export type DeleteAppsByAppIdChatConversationsByConversationIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdChatConversationsByConversationIdResponse + = DeleteAppsByAppIdChatConversationsByConversationIdResponses[keyof DeleteAppsByAppIdChatConversationsByConversationIdResponses] + +export type GetAppsByAppIdChatConversationsByConversationIdData = { + body?: never + path: { + app_id: string + conversation_id: string + } + query?: never + url: '/apps/{app_id}/chat-conversations/{conversation_id}' +} + +export type GetAppsByAppIdChatConversationsByConversationIdErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdChatConversationsByConversationIdError + = GetAppsByAppIdChatConversationsByConversationIdErrors[keyof GetAppsByAppIdChatConversationsByConversationIdErrors] + +export type GetAppsByAppIdChatConversationsByConversationIdResponses = { + 200: ConversationDetail +} + +export type GetAppsByAppIdChatConversationsByConversationIdResponse + = GetAppsByAppIdChatConversationsByConversationIdResponses[keyof GetAppsByAppIdChatConversationsByConversationIdResponses] + +export type GetAppsByAppIdChatMessagesData = { + body?: never + path: { + app_id: string + } + query: { + conversation_id: string + first_id?: string | null + limit?: number + } + url: '/apps/{app_id}/chat-messages' +} + +export type GetAppsByAppIdChatMessagesErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdChatMessagesError + = GetAppsByAppIdChatMessagesErrors[keyof GetAppsByAppIdChatMessagesErrors] + +export type GetAppsByAppIdChatMessagesResponses = { + 200: MessageInfiniteScrollPaginationResponse +} + +export type GetAppsByAppIdChatMessagesResponse + = GetAppsByAppIdChatMessagesResponses[keyof GetAppsByAppIdChatMessagesResponses] + +export type GetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsData = { + body?: never + path: { + app_id: string + message_id: string + } + query?: never + url: '/apps/{app_id}/chat-messages/{message_id}/suggested-questions' +} + +export type GetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsError + = GetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsErrors[keyof GetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsErrors] + +export type GetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsResponses = { + 200: SuggestedQuestionsResponse +} + +export type GetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsResponse + = GetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsResponses[keyof GetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsResponses] + +export type PostAppsByAppIdChatMessagesByTaskIdStopData = { + body?: never + path: { + app_id: string + task_id: string + } + query?: never + url: '/apps/{app_id}/chat-messages/{task_id}/stop' +} + +export type PostAppsByAppIdChatMessagesByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdChatMessagesByTaskIdStopResponse + = PostAppsByAppIdChatMessagesByTaskIdStopResponses[keyof PostAppsByAppIdChatMessagesByTaskIdStopResponses] + +export type GetAppsByAppIdCompletionConversationsData = { + body?: never + path: { + app_id: string + } + query?: { + annotation_status?: 'annotated' | 'not_annotated' | 'all' + end?: string | null + keyword?: string | null + limit?: number + page?: number + start?: string | null + } + url: '/apps/{app_id}/completion-conversations' +} + +export type GetAppsByAppIdCompletionConversationsErrors = { + 403: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdCompletionConversationsError + = GetAppsByAppIdCompletionConversationsErrors[keyof GetAppsByAppIdCompletionConversationsErrors] + +export type GetAppsByAppIdCompletionConversationsResponses = { + 200: ConversationPagination +} + +export type GetAppsByAppIdCompletionConversationsResponse + = GetAppsByAppIdCompletionConversationsResponses[keyof GetAppsByAppIdCompletionConversationsResponses] + +export type DeleteAppsByAppIdCompletionConversationsByConversationIdData = { + body?: never + path: { + app_id: string + conversation_id: string + } + query?: never + url: '/apps/{app_id}/completion-conversations/{conversation_id}' +} + +export type DeleteAppsByAppIdCompletionConversationsByConversationIdErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdCompletionConversationsByConversationIdError + = DeleteAppsByAppIdCompletionConversationsByConversationIdErrors[keyof DeleteAppsByAppIdCompletionConversationsByConversationIdErrors] + +export type DeleteAppsByAppIdCompletionConversationsByConversationIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdCompletionConversationsByConversationIdResponse + = DeleteAppsByAppIdCompletionConversationsByConversationIdResponses[keyof DeleteAppsByAppIdCompletionConversationsByConversationIdResponses] + +export type GetAppsByAppIdCompletionConversationsByConversationIdData = { + body?: never + path: { + app_id: string + conversation_id: string + } + query?: never + url: '/apps/{app_id}/completion-conversations/{conversation_id}' +} + +export type GetAppsByAppIdCompletionConversationsByConversationIdErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdCompletionConversationsByConversationIdError + = GetAppsByAppIdCompletionConversationsByConversationIdErrors[keyof GetAppsByAppIdCompletionConversationsByConversationIdErrors] + +export type GetAppsByAppIdCompletionConversationsByConversationIdResponses = { + 200: ConversationMessageDetail +} + +export type GetAppsByAppIdCompletionConversationsByConversationIdResponse + = GetAppsByAppIdCompletionConversationsByConversationIdResponses[keyof GetAppsByAppIdCompletionConversationsByConversationIdResponses] + +export type PostAppsByAppIdCompletionMessagesData = { + body: CompletionMessagePayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/completion-messages' +} + +export type PostAppsByAppIdCompletionMessagesErrors = { + 400: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdCompletionMessagesError + = PostAppsByAppIdCompletionMessagesErrors[keyof PostAppsByAppIdCompletionMessagesErrors] + +export type PostAppsByAppIdCompletionMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdCompletionMessagesResponse + = PostAppsByAppIdCompletionMessagesResponses[keyof PostAppsByAppIdCompletionMessagesResponses] + +export type PostAppsByAppIdCompletionMessagesByTaskIdStopData = { + body?: never + path: { + app_id: string + task_id: string + } + query?: never + url: '/apps/{app_id}/completion-messages/{task_id}/stop' +} + +export type PostAppsByAppIdCompletionMessagesByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdCompletionMessagesByTaskIdStopResponse + = PostAppsByAppIdCompletionMessagesByTaskIdStopResponses[keyof PostAppsByAppIdCompletionMessagesByTaskIdStopResponses] + +export type GetAppsByAppIdConversationVariablesData = { + body?: never + path: { + app_id: string + } + query: { + conversation_id: string + } + url: '/apps/{app_id}/conversation-variables' +} + +export type GetAppsByAppIdConversationVariablesResponses = { + 200: PaginatedConversationVariableResponse +} + +export type GetAppsByAppIdConversationVariablesResponse + = GetAppsByAppIdConversationVariablesResponses[keyof GetAppsByAppIdConversationVariablesResponses] + +export type PostAppsByAppIdConvertToWorkflowData = { + body: ConvertToWorkflowPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/convert-to-workflow' +} + +export type PostAppsByAppIdConvertToWorkflowErrors = { + 400: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdConvertToWorkflowError + = PostAppsByAppIdConvertToWorkflowErrors[keyof PostAppsByAppIdConvertToWorkflowErrors] + +export type PostAppsByAppIdConvertToWorkflowResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdConvertToWorkflowResponse + = PostAppsByAppIdConvertToWorkflowResponses[keyof PostAppsByAppIdConvertToWorkflowResponses] + +export type PostAppsByAppIdCopyData = { + body: CopyAppPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/copy' +} + +export type PostAppsByAppIdCopyErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdCopyError = PostAppsByAppIdCopyErrors[keyof PostAppsByAppIdCopyErrors] + +export type PostAppsByAppIdCopyResponses = { + 201: AppDetailWithSite +} + +export type PostAppsByAppIdCopyResponse + = PostAppsByAppIdCopyResponses[keyof PostAppsByAppIdCopyResponses] + +export type GetAppsByAppIdExportData = { + body?: never + path: { + app_id: string + } + query?: { + include_secret?: boolean + workflow_id?: string | null + } + url: '/apps/{app_id}/export' +} + +export type GetAppsByAppIdExportErrors = { + 403: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdExportError = GetAppsByAppIdExportErrors[keyof GetAppsByAppIdExportErrors] + +export type GetAppsByAppIdExportResponses = { + 200: AppExportResponse +} + +export type GetAppsByAppIdExportResponse + = GetAppsByAppIdExportResponses[keyof GetAppsByAppIdExportResponses] + +export type PostAppsByAppIdFeedbacksData = { + body: MessageFeedbackPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/feedbacks' +} + +export type PostAppsByAppIdFeedbacksErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdFeedbacksError + = PostAppsByAppIdFeedbacksErrors[keyof PostAppsByAppIdFeedbacksErrors] + +export type PostAppsByAppIdFeedbacksResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdFeedbacksResponse + = PostAppsByAppIdFeedbacksResponses[keyof PostAppsByAppIdFeedbacksResponses] + +export type GetAppsByAppIdFeedbacksExportData = { + body?: never + path: { + app_id: string + } + query?: { + end_date?: string | null + format?: 'csv' | 'json' + from_source?: 'user' | 'admin' | null + has_comment?: boolean | null + rating?: 'like' | 'dislike' | null + start_date?: string | null + } + url: '/apps/{app_id}/feedbacks/export' +} + +export type GetAppsByAppIdFeedbacksExportErrors = { + 400: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdFeedbacksExportError + = GetAppsByAppIdFeedbacksExportErrors[keyof GetAppsByAppIdFeedbacksExportErrors] + +export type GetAppsByAppIdFeedbacksExportResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdFeedbacksExportResponse + = GetAppsByAppIdFeedbacksExportResponses[keyof GetAppsByAppIdFeedbacksExportResponses] + +export type PostAppsByAppIdIconData = { + body: AppIconPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/icon' +} + +export type PostAppsByAppIdIconErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdIconError = PostAppsByAppIdIconErrors[keyof PostAppsByAppIdIconErrors] + +export type PostAppsByAppIdIconResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdIconResponse + = PostAppsByAppIdIconResponses[keyof PostAppsByAppIdIconResponses] + +export type GetAppsByAppIdMessagesByMessageIdData = { + body?: never + path: { + app_id: string + message_id: string + } + query?: never + url: '/apps/{app_id}/messages/{message_id}' +} + +export type GetAppsByAppIdMessagesByMessageIdErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdMessagesByMessageIdError + = GetAppsByAppIdMessagesByMessageIdErrors[keyof GetAppsByAppIdMessagesByMessageIdErrors] + +export type GetAppsByAppIdMessagesByMessageIdResponses = { + 200: MessageDetailResponse +} + +export type GetAppsByAppIdMessagesByMessageIdResponse + = GetAppsByAppIdMessagesByMessageIdResponses[keyof GetAppsByAppIdMessagesByMessageIdResponses] + +export type PostAppsByAppIdModelConfigData = { + body: ModelConfigRequest + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/model-config' +} + +export type PostAppsByAppIdModelConfigErrors = { + 400: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdModelConfigError + = PostAppsByAppIdModelConfigErrors[keyof PostAppsByAppIdModelConfigErrors] + +export type PostAppsByAppIdModelConfigResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdModelConfigResponse + = PostAppsByAppIdModelConfigResponses[keyof PostAppsByAppIdModelConfigResponses] + +export type PostAppsByAppIdNameData = { + body: AppNamePayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/name' +} + +export type PostAppsByAppIdNameResponses = { + 200: AppDetail +} + +export type PostAppsByAppIdNameResponse + = PostAppsByAppIdNameResponses[keyof PostAppsByAppIdNameResponses] + +export type PostAppsByAppIdPublishToCreatorsPlatformData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/publish-to-creators-platform' +} + +export type PostAppsByAppIdPublishToCreatorsPlatformResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdPublishToCreatorsPlatformResponse + = PostAppsByAppIdPublishToCreatorsPlatformResponses[keyof PostAppsByAppIdPublishToCreatorsPlatformResponses] + +export type GetAppsByAppIdServerData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/server' +} + +export type GetAppsByAppIdServerResponses = { + 200: AppMcpServerResponse +} + +export type GetAppsByAppIdServerResponse + = GetAppsByAppIdServerResponses[keyof GetAppsByAppIdServerResponses] + +export type PostAppsByAppIdServerData = { + body: McpServerCreatePayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/server' +} + +export type PostAppsByAppIdServerErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdServerError + = PostAppsByAppIdServerErrors[keyof PostAppsByAppIdServerErrors] + +export type PostAppsByAppIdServerResponses = { + 201: AppMcpServerResponse +} + +export type PostAppsByAppIdServerResponse + = PostAppsByAppIdServerResponses[keyof PostAppsByAppIdServerResponses] + +export type PutAppsByAppIdServerData = { + body: McpServerUpdatePayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/server' +} + +export type PutAppsByAppIdServerErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PutAppsByAppIdServerError = PutAppsByAppIdServerErrors[keyof PutAppsByAppIdServerErrors] + +export type PutAppsByAppIdServerResponses = { + 200: AppMcpServerResponse +} + +export type PutAppsByAppIdServerResponse + = PutAppsByAppIdServerResponses[keyof PutAppsByAppIdServerResponses] + +export type PostAppsByAppIdSiteData = { + body: AppSiteUpdatePayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/site' +} + +export type PostAppsByAppIdSiteErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdSiteError = PostAppsByAppIdSiteErrors[keyof PostAppsByAppIdSiteErrors] + +export type PostAppsByAppIdSiteResponses = { + 200: AppSiteResponse +} + +export type PostAppsByAppIdSiteResponse + = PostAppsByAppIdSiteResponses[keyof PostAppsByAppIdSiteResponses] + +export type PostAppsByAppIdSiteEnableData = { + body: AppSiteStatusPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/site-enable' +} + +export type PostAppsByAppIdSiteEnableErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdSiteEnableError + = PostAppsByAppIdSiteEnableErrors[keyof PostAppsByAppIdSiteEnableErrors] + +export type PostAppsByAppIdSiteEnableResponses = { + 200: AppDetail +} + +export type PostAppsByAppIdSiteEnableResponse + = PostAppsByAppIdSiteEnableResponses[keyof PostAppsByAppIdSiteEnableResponses] + +export type PostAppsByAppIdSiteAccessTokenResetData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/site/access-token-reset' +} + +export type PostAppsByAppIdSiteAccessTokenResetErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdSiteAccessTokenResetError + = PostAppsByAppIdSiteAccessTokenResetErrors[keyof PostAppsByAppIdSiteAccessTokenResetErrors] + +export type PostAppsByAppIdSiteAccessTokenResetResponses = { + 200: AppSiteResponse +} + +export type PostAppsByAppIdSiteAccessTokenResetResponse + = PostAppsByAppIdSiteAccessTokenResetResponses[keyof PostAppsByAppIdSiteAccessTokenResetResponses] + +export type GetAppsByAppIdStatisticsAverageResponseTimeData = { + body?: never + path: { + app_id: string + } + query?: { + end?: string | null + start?: string | null + } + url: '/apps/{app_id}/statistics/average-response-time' +} + +export type GetAppsByAppIdStatisticsAverageResponseTimeResponses = { + 200: Array<{ + [key: string]: unknown + }> +} + +export type GetAppsByAppIdStatisticsAverageResponseTimeResponse + = GetAppsByAppIdStatisticsAverageResponseTimeResponses[keyof GetAppsByAppIdStatisticsAverageResponseTimeResponses] + +export type GetAppsByAppIdStatisticsAverageSessionInteractionsData = { + body?: never + path: { + app_id: string + } + query?: { + end?: string | null + start?: string | null + } + url: '/apps/{app_id}/statistics/average-session-interactions' +} + +export type GetAppsByAppIdStatisticsAverageSessionInteractionsResponses = { + 200: Array<{ + [key: string]: unknown + }> +} + +export type GetAppsByAppIdStatisticsAverageSessionInteractionsResponse + = GetAppsByAppIdStatisticsAverageSessionInteractionsResponses[keyof GetAppsByAppIdStatisticsAverageSessionInteractionsResponses] + +export type GetAppsByAppIdStatisticsDailyConversationsData = { + body?: never + path: { + app_id: string + } + query?: { + end?: string | null + start?: string | null + } + url: '/apps/{app_id}/statistics/daily-conversations' +} + +export type GetAppsByAppIdStatisticsDailyConversationsResponses = { + 200: Array<{ + [key: string]: unknown + }> +} + +export type GetAppsByAppIdStatisticsDailyConversationsResponse + = GetAppsByAppIdStatisticsDailyConversationsResponses[keyof GetAppsByAppIdStatisticsDailyConversationsResponses] + +export type GetAppsByAppIdStatisticsDailyEndUsersData = { + body?: never + path: { + app_id: string + } + query?: { + end?: string | null + start?: string | null + } + url: '/apps/{app_id}/statistics/daily-end-users' +} + +export type GetAppsByAppIdStatisticsDailyEndUsersResponses = { + 200: Array<{ + [key: string]: unknown + }> +} + +export type GetAppsByAppIdStatisticsDailyEndUsersResponse + = GetAppsByAppIdStatisticsDailyEndUsersResponses[keyof GetAppsByAppIdStatisticsDailyEndUsersResponses] + +export type GetAppsByAppIdStatisticsDailyMessagesData = { + body?: never + path: { + app_id: string + } + query?: { + end?: string | null + start?: string | null + } + url: '/apps/{app_id}/statistics/daily-messages' +} + +export type GetAppsByAppIdStatisticsDailyMessagesResponses = { + 200: Array<{ + [key: string]: unknown + }> +} + +export type GetAppsByAppIdStatisticsDailyMessagesResponse + = GetAppsByAppIdStatisticsDailyMessagesResponses[keyof GetAppsByAppIdStatisticsDailyMessagesResponses] + +export type GetAppsByAppIdStatisticsTokenCostsData = { + body?: never + path: { + app_id: string + } + query?: { + end?: string | null + start?: string | null + } + url: '/apps/{app_id}/statistics/token-costs' +} + +export type GetAppsByAppIdStatisticsTokenCostsResponses = { + 200: Array<{ + [key: string]: unknown + }> +} + +export type GetAppsByAppIdStatisticsTokenCostsResponse + = GetAppsByAppIdStatisticsTokenCostsResponses[keyof GetAppsByAppIdStatisticsTokenCostsResponses] + +export type GetAppsByAppIdStatisticsTokensPerSecondData = { + body?: never + path: { + app_id: string + } + query?: { + end?: string | null + start?: string | null + } + url: '/apps/{app_id}/statistics/tokens-per-second' +} + +export type GetAppsByAppIdStatisticsTokensPerSecondResponses = { + 200: Array<{ + [key: string]: unknown + }> +} + +export type GetAppsByAppIdStatisticsTokensPerSecondResponse + = GetAppsByAppIdStatisticsTokensPerSecondResponses[keyof GetAppsByAppIdStatisticsTokensPerSecondResponses] + +export type GetAppsByAppIdStatisticsUserSatisfactionRateData = { + body?: never + path: { + app_id: string + } + query?: { + end?: string | null + start?: string | null + } + url: '/apps/{app_id}/statistics/user-satisfaction-rate' +} + +export type GetAppsByAppIdStatisticsUserSatisfactionRateResponses = { + 200: Array<{ + [key: string]: unknown + }> +} + +export type GetAppsByAppIdStatisticsUserSatisfactionRateResponse + = GetAppsByAppIdStatisticsUserSatisfactionRateResponses[keyof GetAppsByAppIdStatisticsUserSatisfactionRateResponses] + +export type PostAppsByAppIdTextToAudioData = { + body: TextToSpeechPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/text-to-audio' +} + +export type PostAppsByAppIdTextToAudioErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdTextToAudioError + = PostAppsByAppIdTextToAudioErrors[keyof PostAppsByAppIdTextToAudioErrors] + +export type PostAppsByAppIdTextToAudioResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdTextToAudioResponse + = PostAppsByAppIdTextToAudioResponses[keyof PostAppsByAppIdTextToAudioResponses] + +export type GetAppsByAppIdTextToAudioVoicesData = { + body?: never + path: { + app_id: string + } + query: { + language: string + } + url: '/apps/{app_id}/text-to-audio/voices' +} + +export type GetAppsByAppIdTextToAudioVoicesErrors = { + 400: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdTextToAudioVoicesError + = GetAppsByAppIdTextToAudioVoicesErrors[keyof GetAppsByAppIdTextToAudioVoicesErrors] + +export type GetAppsByAppIdTextToAudioVoicesResponses = { + 200: Array<{ + [key: string]: unknown + }> +} + +export type GetAppsByAppIdTextToAudioVoicesResponse + = GetAppsByAppIdTextToAudioVoicesResponses[keyof GetAppsByAppIdTextToAudioVoicesResponses] + +export type GetAppsByAppIdTraceData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/trace' +} + +export type GetAppsByAppIdTraceResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdTraceResponse + = GetAppsByAppIdTraceResponses[keyof GetAppsByAppIdTraceResponses] + +export type PostAppsByAppIdTraceData = { + body: AppTracePayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/trace' +} + +export type PostAppsByAppIdTraceErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdTraceError = PostAppsByAppIdTraceErrors[keyof PostAppsByAppIdTraceErrors] + +export type PostAppsByAppIdTraceResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdTraceResponse + = PostAppsByAppIdTraceResponses[keyof PostAppsByAppIdTraceResponses] + +export type DeleteAppsByAppIdTraceConfigData = { + body: TraceProviderQuery + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/trace-config' +} + +export type DeleteAppsByAppIdTraceConfigErrors = { + 400: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdTraceConfigError + = DeleteAppsByAppIdTraceConfigErrors[keyof DeleteAppsByAppIdTraceConfigErrors] + +export type DeleteAppsByAppIdTraceConfigResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdTraceConfigResponse + = DeleteAppsByAppIdTraceConfigResponses[keyof DeleteAppsByAppIdTraceConfigResponses] + +export type GetAppsByAppIdTraceConfigData = { + body?: never + path: { + app_id: string + } + query: { + tracing_provider: string + } + url: '/apps/{app_id}/trace-config' +} + +export type GetAppsByAppIdTraceConfigErrors = { + 400: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdTraceConfigError + = GetAppsByAppIdTraceConfigErrors[keyof GetAppsByAppIdTraceConfigErrors] + +export type GetAppsByAppIdTraceConfigResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdTraceConfigResponse + = GetAppsByAppIdTraceConfigResponses[keyof GetAppsByAppIdTraceConfigResponses] + +export type PatchAppsByAppIdTraceConfigData = { + body: TraceConfigPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/trace-config' +} + +export type PatchAppsByAppIdTraceConfigErrors = { + 400: { + [key: string]: unknown + } +} + +export type PatchAppsByAppIdTraceConfigError + = PatchAppsByAppIdTraceConfigErrors[keyof PatchAppsByAppIdTraceConfigErrors] + +export type PatchAppsByAppIdTraceConfigResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchAppsByAppIdTraceConfigResponse + = PatchAppsByAppIdTraceConfigResponses[keyof PatchAppsByAppIdTraceConfigResponses] + +export type PostAppsByAppIdTraceConfigData = { + body: TraceConfigPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/trace-config' +} + +export type PostAppsByAppIdTraceConfigErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdTraceConfigError + = PostAppsByAppIdTraceConfigErrors[keyof PostAppsByAppIdTraceConfigErrors] + +export type PostAppsByAppIdTraceConfigResponses = { + 201: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdTraceConfigResponse + = PostAppsByAppIdTraceConfigResponses[keyof PostAppsByAppIdTraceConfigResponses] + +export type PostAppsByAppIdTriggerEnableData = { + body: ParserEnable + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/trigger-enable' +} + +export type PostAppsByAppIdTriggerEnableResponses = { + 200: WorkflowTriggerResponse +} + +export type PostAppsByAppIdTriggerEnableResponse + = PostAppsByAppIdTriggerEnableResponses[keyof PostAppsByAppIdTriggerEnableResponses] + +export type GetAppsByAppIdTriggersData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/triggers' +} + +export type GetAppsByAppIdTriggersResponses = { + 200: WorkflowTriggerListResponse +} + +export type GetAppsByAppIdTriggersResponse + = GetAppsByAppIdTriggersResponses[keyof GetAppsByAppIdTriggersResponses] + +export type GetAppsByAppIdWorkflowAppLogsData = { + body?: never + path: { + app_id: string + } + query?: { + created_at__after?: string | null + created_at__before?: string | null + created_by_account?: string | null + created_by_end_user_session_id?: string | null + detail?: boolean + keyword?: string | null + limit?: number + page?: number + status?: string | null + } + url: '/apps/{app_id}/workflow-app-logs' +} + +export type GetAppsByAppIdWorkflowAppLogsResponses = { + 200: WorkflowAppLogPaginationResponse +} + +export type GetAppsByAppIdWorkflowAppLogsResponse + = GetAppsByAppIdWorkflowAppLogsResponses[keyof GetAppsByAppIdWorkflowAppLogsResponses] + +export type GetAppsByAppIdWorkflowArchivedLogsData = { + body?: never + path: { + app_id: string + } + query?: { + created_at__after?: string | null + created_at__before?: string | null + created_by_account?: string | null + created_by_end_user_session_id?: string | null + detail?: boolean + keyword?: string | null + limit?: number + page?: number + status?: string | null + } + url: '/apps/{app_id}/workflow-archived-logs' +} + +export type GetAppsByAppIdWorkflowArchivedLogsResponses = { + 200: WorkflowArchivedLogPaginationResponse +} + +export type GetAppsByAppIdWorkflowArchivedLogsResponse + = GetAppsByAppIdWorkflowArchivedLogsResponses[keyof GetAppsByAppIdWorkflowArchivedLogsResponses] + +export type GetAppsByAppIdWorkflowRunsData = { + body?: never + path: { + app_id: string + } + query?: { + triggered_from?: 'debugging' | 'app-run' | null + status?: 'running' | 'succeeded' | 'failed' | 'stopped' | 'partial-succeeded' | null + last_id?: string | null + limit?: number + } + url: '/apps/{app_id}/workflow-runs' +} + +export type GetAppsByAppIdWorkflowRunsResponses = { + 200: WorkflowRunPagination +} + +export type GetAppsByAppIdWorkflowRunsResponse + = GetAppsByAppIdWorkflowRunsResponses[keyof GetAppsByAppIdWorkflowRunsResponses] + +export type GetAppsByAppIdWorkflowRunsCountData = { + body?: never + path: { + app_id: string + } + query?: { + triggered_from?: 'debugging' | 'app-run' | null + time_range?: string | null + status?: 'running' | 'succeeded' | 'failed' | 'stopped' | 'partial-succeeded' | null + } + url: '/apps/{app_id}/workflow-runs/count' +} + +export type GetAppsByAppIdWorkflowRunsCountResponses = { + 200: WorkflowRunCount +} + +export type GetAppsByAppIdWorkflowRunsCountResponse + = GetAppsByAppIdWorkflowRunsCountResponses[keyof GetAppsByAppIdWorkflowRunsCountResponses] + +export type PostAppsByAppIdWorkflowRunsTasksByTaskIdStopData = { + body?: never + path: { + app_id: string + task_id: string + } + query?: never + url: '/apps/{app_id}/workflow-runs/tasks/{task_id}/stop' +} + +export type PostAppsByAppIdWorkflowRunsTasksByTaskIdStopErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowRunsTasksByTaskIdStopError + = PostAppsByAppIdWorkflowRunsTasksByTaskIdStopErrors[keyof PostAppsByAppIdWorkflowRunsTasksByTaskIdStopErrors] + +export type PostAppsByAppIdWorkflowRunsTasksByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowRunsTasksByTaskIdStopResponse + = PostAppsByAppIdWorkflowRunsTasksByTaskIdStopResponses[keyof PostAppsByAppIdWorkflowRunsTasksByTaskIdStopResponses] + +export type GetAppsByAppIdWorkflowRunsByRunIdData = { + body?: never + path: { + app_id: string + run_id: string + } + query?: never + url: '/apps/{app_id}/workflow-runs/{run_id}' +} + +export type GetAppsByAppIdWorkflowRunsByRunIdErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowRunsByRunIdError + = GetAppsByAppIdWorkflowRunsByRunIdErrors[keyof GetAppsByAppIdWorkflowRunsByRunIdErrors] + +export type GetAppsByAppIdWorkflowRunsByRunIdResponses = { + 200: WorkflowRunDetail +} + +export type GetAppsByAppIdWorkflowRunsByRunIdResponse + = GetAppsByAppIdWorkflowRunsByRunIdResponses[keyof GetAppsByAppIdWorkflowRunsByRunIdResponses] + +export type GetAppsByAppIdWorkflowRunsByRunIdExportData = { + body?: never + path: { + app_id: string + run_id: string + } + query?: never + url: '/apps/{app_id}/workflow-runs/{run_id}/export' +} + +export type GetAppsByAppIdWorkflowRunsByRunIdExportResponses = { + 200: WorkflowRunExport +} + +export type GetAppsByAppIdWorkflowRunsByRunIdExportResponse + = GetAppsByAppIdWorkflowRunsByRunIdExportResponses[keyof GetAppsByAppIdWorkflowRunsByRunIdExportResponses] + +export type GetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsData = { + body?: never + path: { + app_id: string + run_id: string + } + query?: never + url: '/apps/{app_id}/workflow-runs/{run_id}/node-executions' +} + +export type GetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsError + = GetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsErrors[keyof GetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsErrors] + +export type GetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsResponses = { + 200: WorkflowRunNodeExecutionList +} + +export type GetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsResponse + = GetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsResponses[keyof GetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsResponses] + +export type GetAppsByAppIdWorkflowCommentsData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflow/comments' +} + +export type GetAppsByAppIdWorkflowCommentsResponses = { + 200: WorkflowCommentBasic +} + +export type GetAppsByAppIdWorkflowCommentsResponse + = GetAppsByAppIdWorkflowCommentsResponses[keyof GetAppsByAppIdWorkflowCommentsResponses] + +export type PostAppsByAppIdWorkflowCommentsData = { + body: WorkflowCommentCreatePayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflow/comments' +} + +export type PostAppsByAppIdWorkflowCommentsResponses = { + 201: WorkflowCommentCreate +} + +export type PostAppsByAppIdWorkflowCommentsResponse + = PostAppsByAppIdWorkflowCommentsResponses[keyof PostAppsByAppIdWorkflowCommentsResponses] + +export type GetAppsByAppIdWorkflowCommentsMentionUsersData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflow/comments/mention-users' +} + +export type GetAppsByAppIdWorkflowCommentsMentionUsersResponses = { + 200: WorkflowCommentMentionUsersPayload +} + +export type GetAppsByAppIdWorkflowCommentsMentionUsersResponse + = GetAppsByAppIdWorkflowCommentsMentionUsersResponses[keyof GetAppsByAppIdWorkflowCommentsMentionUsersResponses] + +export type DeleteAppsByAppIdWorkflowCommentsByCommentIdData = { + body?: never + path: { + app_id: string + comment_id: string + } + query?: never + url: '/apps/{app_id}/workflow/comments/{comment_id}' +} + +export type DeleteAppsByAppIdWorkflowCommentsByCommentIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdWorkflowCommentsByCommentIdResponse + = DeleteAppsByAppIdWorkflowCommentsByCommentIdResponses[keyof DeleteAppsByAppIdWorkflowCommentsByCommentIdResponses] + +export type GetAppsByAppIdWorkflowCommentsByCommentIdData = { + body?: never + path: { + app_id: string + comment_id: string + } + query?: never + url: '/apps/{app_id}/workflow/comments/{comment_id}' +} + +export type GetAppsByAppIdWorkflowCommentsByCommentIdResponses = { + 200: WorkflowCommentDetail +} + +export type GetAppsByAppIdWorkflowCommentsByCommentIdResponse + = GetAppsByAppIdWorkflowCommentsByCommentIdResponses[keyof GetAppsByAppIdWorkflowCommentsByCommentIdResponses] + +export type PutAppsByAppIdWorkflowCommentsByCommentIdData = { + body: WorkflowCommentUpdatePayload + path: { + app_id: string + comment_id: string + } + query?: never + url: '/apps/{app_id}/workflow/comments/{comment_id}' +} + +export type PutAppsByAppIdWorkflowCommentsByCommentIdResponses = { + 200: WorkflowCommentUpdate +} + +export type PutAppsByAppIdWorkflowCommentsByCommentIdResponse + = PutAppsByAppIdWorkflowCommentsByCommentIdResponses[keyof PutAppsByAppIdWorkflowCommentsByCommentIdResponses] + +export type PostAppsByAppIdWorkflowCommentsByCommentIdRepliesData = { + body: WorkflowCommentReplyPayload + path: { + app_id: string + comment_id: string + } + query?: never + url: '/apps/{app_id}/workflow/comments/{comment_id}/replies' +} + +export type PostAppsByAppIdWorkflowCommentsByCommentIdRepliesResponses = { + 201: WorkflowCommentReplyCreate +} + +export type PostAppsByAppIdWorkflowCommentsByCommentIdRepliesResponse + = PostAppsByAppIdWorkflowCommentsByCommentIdRepliesResponses[keyof PostAppsByAppIdWorkflowCommentsByCommentIdRepliesResponses] + +export type DeleteAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdData = { + body?: never + path: { + app_id: string + comment_id: string + reply_id: string + } + query?: never + url: '/apps/{app_id}/workflow/comments/{comment_id}/replies/{reply_id}' +} + +export type DeleteAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponse + = DeleteAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponses[keyof DeleteAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponses] + +export type PutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdData = { + body: WorkflowCommentReplyPayload + path: { + app_id: string + comment_id: string + reply_id: string + } + query?: never + url: '/apps/{app_id}/workflow/comments/{comment_id}/replies/{reply_id}' +} + +export type PutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponses = { + 200: WorkflowCommentReplyUpdate +} + +export type PutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponse + = PutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponses[keyof PutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponses] + +export type PostAppsByAppIdWorkflowCommentsByCommentIdResolveData = { + body?: never + path: { + app_id: string + comment_id: string + } + query?: never + url: '/apps/{app_id}/workflow/comments/{comment_id}/resolve' +} + +export type PostAppsByAppIdWorkflowCommentsByCommentIdResolveResponses = { + 200: WorkflowCommentResolve +} + +export type PostAppsByAppIdWorkflowCommentsByCommentIdResolveResponse + = PostAppsByAppIdWorkflowCommentsByCommentIdResolveResponses[keyof PostAppsByAppIdWorkflowCommentsByCommentIdResolveResponses] + +export type GetAppsByAppIdWorkflowStatisticsAverageAppInteractionsData = { + body?: never + path: { + app_id: string + } + query?: { + end?: string | null + start?: string | null + } + url: '/apps/{app_id}/workflow/statistics/average-app-interactions' +} + +export type GetAppsByAppIdWorkflowStatisticsAverageAppInteractionsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowStatisticsAverageAppInteractionsResponse + = GetAppsByAppIdWorkflowStatisticsAverageAppInteractionsResponses[keyof GetAppsByAppIdWorkflowStatisticsAverageAppInteractionsResponses] + +export type GetAppsByAppIdWorkflowStatisticsDailyConversationsData = { + body?: never + path: { + app_id: string + } + query?: { + end?: string | null + start?: string | null + } + url: '/apps/{app_id}/workflow/statistics/daily-conversations' +} + +export type GetAppsByAppIdWorkflowStatisticsDailyConversationsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowStatisticsDailyConversationsResponse + = GetAppsByAppIdWorkflowStatisticsDailyConversationsResponses[keyof GetAppsByAppIdWorkflowStatisticsDailyConversationsResponses] + +export type GetAppsByAppIdWorkflowStatisticsDailyTerminalsData = { + body?: never + path: { + app_id: string + } + query?: { + end?: string | null + start?: string | null + } + url: '/apps/{app_id}/workflow/statistics/daily-terminals' +} + +export type GetAppsByAppIdWorkflowStatisticsDailyTerminalsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowStatisticsDailyTerminalsResponse + = GetAppsByAppIdWorkflowStatisticsDailyTerminalsResponses[keyof GetAppsByAppIdWorkflowStatisticsDailyTerminalsResponses] + +export type GetAppsByAppIdWorkflowStatisticsTokenCostsData = { + body?: never + path: { + app_id: string + } + query?: { + end?: string | null + start?: string | null + } + url: '/apps/{app_id}/workflow/statistics/token-costs' +} + +export type GetAppsByAppIdWorkflowStatisticsTokenCostsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowStatisticsTokenCostsResponse + = GetAppsByAppIdWorkflowStatisticsTokenCostsResponses[keyof GetAppsByAppIdWorkflowStatisticsTokenCostsResponses] + +export type GetAppsByAppIdWorkflowsData = { + body?: never + path: { + app_id: string + } + query?: { + limit?: number + named_only?: boolean + page?: number + user_id?: string | null + } + url: '/apps/{app_id}/workflows' +} + +export type GetAppsByAppIdWorkflowsResponses = { + 200: WorkflowPagination +} + +export type GetAppsByAppIdWorkflowsResponse + = GetAppsByAppIdWorkflowsResponses[keyof GetAppsByAppIdWorkflowsResponses] + +export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/default-workflow-block-configs' +} + +export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsResponse + = GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsResponses[keyof GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsResponses] + +export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeData = { + body?: never + path: { + app_id: string + block_type: string + } + query?: { + q?: string | null + } + url: '/apps/{app_id}/workflows/default-workflow-block-configs/{block_type}' +} + +export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeError + = GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeErrors[keyof GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeErrors] + +export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse + = GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponses[keyof GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponses] + +export type GetAppsByAppIdWorkflowsDraftData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft' +} + +export type GetAppsByAppIdWorkflowsDraftErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowsDraftError + = GetAppsByAppIdWorkflowsDraftErrors[keyof GetAppsByAppIdWorkflowsDraftErrors] + +export type GetAppsByAppIdWorkflowsDraftResponses = { + 200: Workflow +} + +export type GetAppsByAppIdWorkflowsDraftResponse + = GetAppsByAppIdWorkflowsDraftResponses[keyof GetAppsByAppIdWorkflowsDraftResponses] + +export type PostAppsByAppIdWorkflowsDraftData = { + body: SyncDraftWorkflowPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft' +} + +export type PostAppsByAppIdWorkflowsDraftErrors = { + 400: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftError + = PostAppsByAppIdWorkflowsDraftErrors[keyof PostAppsByAppIdWorkflowsDraftErrors] + +export type PostAppsByAppIdWorkflowsDraftResponses = { + 200: SyncDraftWorkflowResponse +} + +export type PostAppsByAppIdWorkflowsDraftResponse + = PostAppsByAppIdWorkflowsDraftResponses[keyof PostAppsByAppIdWorkflowsDraftResponses] + +export type GetAppsByAppIdWorkflowsDraftConversationVariablesData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/conversation-variables' +} + +export type GetAppsByAppIdWorkflowsDraftConversationVariablesErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowsDraftConversationVariablesError + = GetAppsByAppIdWorkflowsDraftConversationVariablesErrors[keyof GetAppsByAppIdWorkflowsDraftConversationVariablesErrors] + +export type GetAppsByAppIdWorkflowsDraftConversationVariablesResponses = { + 200: WorkflowDraftVariableList +} + +export type GetAppsByAppIdWorkflowsDraftConversationVariablesResponse + = GetAppsByAppIdWorkflowsDraftConversationVariablesResponses[keyof GetAppsByAppIdWorkflowsDraftConversationVariablesResponses] + +export type PostAppsByAppIdWorkflowsDraftConversationVariablesData = { + body: ConversationVariableUpdatePayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/conversation-variables' +} + +export type PostAppsByAppIdWorkflowsDraftConversationVariablesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftConversationVariablesResponse + = PostAppsByAppIdWorkflowsDraftConversationVariablesResponses[keyof PostAppsByAppIdWorkflowsDraftConversationVariablesResponses] + +export type GetAppsByAppIdWorkflowsDraftEnvironmentVariablesData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/environment-variables' +} + +export type GetAppsByAppIdWorkflowsDraftEnvironmentVariablesErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowsDraftEnvironmentVariablesError + = GetAppsByAppIdWorkflowsDraftEnvironmentVariablesErrors[keyof GetAppsByAppIdWorkflowsDraftEnvironmentVariablesErrors] + +export type GetAppsByAppIdWorkflowsDraftEnvironmentVariablesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowsDraftEnvironmentVariablesResponse + = GetAppsByAppIdWorkflowsDraftEnvironmentVariablesResponses[keyof GetAppsByAppIdWorkflowsDraftEnvironmentVariablesResponses] + +export type PostAppsByAppIdWorkflowsDraftEnvironmentVariablesData = { + body: EnvironmentVariableUpdatePayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/environment-variables' +} + +export type PostAppsByAppIdWorkflowsDraftEnvironmentVariablesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftEnvironmentVariablesResponse + = PostAppsByAppIdWorkflowsDraftEnvironmentVariablesResponses[keyof PostAppsByAppIdWorkflowsDraftEnvironmentVariablesResponses] + +export type PostAppsByAppIdWorkflowsDraftFeaturesData = { + body: WorkflowFeaturesPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/features' +} + +export type PostAppsByAppIdWorkflowsDraftFeaturesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftFeaturesResponse + = PostAppsByAppIdWorkflowsDraftFeaturesResponses[keyof PostAppsByAppIdWorkflowsDraftFeaturesResponses] + +export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestData = { + body: HumanInputDeliveryTestPayload + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/human-input/nodes/{node_id}/delivery-test' +} + +export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestResponse + = PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestResponses[keyof PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestResponses] + +export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewData = { + body: HumanInputFormPreviewPayload + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/human-input/nodes/{node_id}/form/preview' +} + +export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponse + = PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponses[keyof PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponses] + +export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunData = { + body: HumanInputFormSubmitPayload + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/human-input/nodes/{node_id}/form/run' +} + +export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunResponse + = PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunResponses[keyof PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunResponses] + +export type PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunData = { + body: IterationNodeRunPayload + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/iteration/nodes/{node_id}/run' +} + +export type PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunError + = PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunErrors[keyof PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunErrors] + +export type PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunResponse + = PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunResponses[keyof PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunResponses] + +export type PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunData = { + body: LoopNodeRunPayload + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/loop/nodes/{node_id}/run' +} + +export type PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunError + = PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunErrors[keyof PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunErrors] + +export type PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunResponse + = PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunResponses[keyof PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunResponses] + +export type GetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunData = { + body?: never + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/nodes/{node_id}/last-run' +} + +export type GetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunError + = GetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunErrors[keyof GetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunErrors] + +export type GetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunResponses = { + 200: WorkflowRunNodeExecution +} + +export type GetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunResponse + = GetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunResponses[keyof GetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunResponses] + +export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdRunData = { + body: DraftWorkflowNodeRunPayload + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/nodes/{node_id}/run' +} + +export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdRunErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdRunError + = PostAppsByAppIdWorkflowsDraftNodesByNodeIdRunErrors[keyof PostAppsByAppIdWorkflowsDraftNodesByNodeIdRunErrors] + +export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdRunResponses = { + 200: WorkflowRunNodeExecution +} + +export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdRunResponse + = PostAppsByAppIdWorkflowsDraftNodesByNodeIdRunResponses[keyof PostAppsByAppIdWorkflowsDraftNodesByNodeIdRunResponses] + +export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunData = { + body?: never + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/nodes/{node_id}/trigger/run' +} + +export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunErrors = { + 403: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunError + = PostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunErrors[keyof PostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunErrors] + +export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunResponse + = PostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunResponses[keyof PostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunResponses] + +export type DeleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesData = { + body?: never + path: { + node_id: string + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/nodes/{node_id}/variables' +} + +export type DeleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponse + = DeleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponses[keyof DeleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponses] + +export type GetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesData = { + body?: never + path: { + app_id: string + node_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/nodes/{node_id}/variables' +} + +export type GetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponses = { + 200: WorkflowDraftVariableList +} + +export type GetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponse + = GetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponses[keyof GetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponses] + +export type PostAppsByAppIdWorkflowsDraftRunData = { + body: DraftWorkflowRunPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/run' +} + +export type PostAppsByAppIdWorkflowsDraftRunErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftRunError + = PostAppsByAppIdWorkflowsDraftRunErrors[keyof PostAppsByAppIdWorkflowsDraftRunErrors] + +export type PostAppsByAppIdWorkflowsDraftRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftRunResponse + = PostAppsByAppIdWorkflowsDraftRunResponses[keyof PostAppsByAppIdWorkflowsDraftRunResponses] + +export type GetAppsByAppIdWorkflowsDraftSystemVariablesData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/system-variables' +} + +export type GetAppsByAppIdWorkflowsDraftSystemVariablesResponses = { + 200: WorkflowDraftVariableList +} + +export type GetAppsByAppIdWorkflowsDraftSystemVariablesResponse + = GetAppsByAppIdWorkflowsDraftSystemVariablesResponses[keyof GetAppsByAppIdWorkflowsDraftSystemVariablesResponses] + +export type PostAppsByAppIdWorkflowsDraftTriggerRunData = { + body: DraftWorkflowTriggerRunRequest + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/trigger/run' +} + +export type PostAppsByAppIdWorkflowsDraftTriggerRunErrors = { + 403: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftTriggerRunError + = PostAppsByAppIdWorkflowsDraftTriggerRunErrors[keyof PostAppsByAppIdWorkflowsDraftTriggerRunErrors] + +export type PostAppsByAppIdWorkflowsDraftTriggerRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftTriggerRunResponse + = PostAppsByAppIdWorkflowsDraftTriggerRunResponses[keyof PostAppsByAppIdWorkflowsDraftTriggerRunResponses] + +export type PostAppsByAppIdWorkflowsDraftTriggerRunAllData = { + body: DraftWorkflowTriggerRunAllPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/trigger/run-all' +} + +export type PostAppsByAppIdWorkflowsDraftTriggerRunAllErrors = { + 403: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftTriggerRunAllError + = PostAppsByAppIdWorkflowsDraftTriggerRunAllErrors[keyof PostAppsByAppIdWorkflowsDraftTriggerRunAllErrors] + +export type PostAppsByAppIdWorkflowsDraftTriggerRunAllResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsDraftTriggerRunAllResponse + = PostAppsByAppIdWorkflowsDraftTriggerRunAllResponses[keyof PostAppsByAppIdWorkflowsDraftTriggerRunAllResponses] + +export type DeleteAppsByAppIdWorkflowsDraftVariablesData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/variables' +} + +export type DeleteAppsByAppIdWorkflowsDraftVariablesResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdWorkflowsDraftVariablesResponse + = DeleteAppsByAppIdWorkflowsDraftVariablesResponses[keyof DeleteAppsByAppIdWorkflowsDraftVariablesResponses] + +export type GetAppsByAppIdWorkflowsDraftVariablesData = { + body?: never + path: { + app_id: string + } + query?: { + page?: number + limit?: number + } + url: '/apps/{app_id}/workflows/draft/variables' +} + +export type GetAppsByAppIdWorkflowsDraftVariablesResponses = { + 200: WorkflowDraftVariableListWithoutValue +} + +export type GetAppsByAppIdWorkflowsDraftVariablesResponse + = GetAppsByAppIdWorkflowsDraftVariablesResponses[keyof GetAppsByAppIdWorkflowsDraftVariablesResponses] + +export type DeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdData = { + body?: never + path: { + variable_id: string + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/variables/{variable_id}' +} + +export type DeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdErrors = { + 404: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdError + = DeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdErrors[keyof DeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdErrors] + +export type DeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdResponse + = DeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdResponses[keyof DeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdResponses] + +export type GetAppsByAppIdWorkflowsDraftVariablesByVariableIdData = { + body?: never + path: { + app_id: string + variable_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/variables/{variable_id}' +} + +export type GetAppsByAppIdWorkflowsDraftVariablesByVariableIdErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowsDraftVariablesByVariableIdError + = GetAppsByAppIdWorkflowsDraftVariablesByVariableIdErrors[keyof GetAppsByAppIdWorkflowsDraftVariablesByVariableIdErrors] + +export type GetAppsByAppIdWorkflowsDraftVariablesByVariableIdResponses = { + 200: WorkflowDraftVariable +} + +export type GetAppsByAppIdWorkflowsDraftVariablesByVariableIdResponse + = GetAppsByAppIdWorkflowsDraftVariablesByVariableIdResponses[keyof GetAppsByAppIdWorkflowsDraftVariablesByVariableIdResponses] + +export type PatchAppsByAppIdWorkflowsDraftVariablesByVariableIdData = { + body: WorkflowDraftVariableUpdatePayload + path: { + variable_id: string + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/variables/{variable_id}' +} + +export type PatchAppsByAppIdWorkflowsDraftVariablesByVariableIdErrors = { + 404: { + [key: string]: unknown + } +} + +export type PatchAppsByAppIdWorkflowsDraftVariablesByVariableIdError + = PatchAppsByAppIdWorkflowsDraftVariablesByVariableIdErrors[keyof PatchAppsByAppIdWorkflowsDraftVariablesByVariableIdErrors] + +export type PatchAppsByAppIdWorkflowsDraftVariablesByVariableIdResponses = { + 200: WorkflowDraftVariable +} + +export type PatchAppsByAppIdWorkflowsDraftVariablesByVariableIdResponse + = PatchAppsByAppIdWorkflowsDraftVariablesByVariableIdResponses[keyof PatchAppsByAppIdWorkflowsDraftVariablesByVariableIdResponses] + +export type PutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetData = { + body?: never + path: { + app_id: string + variable_id: string + } + query?: never + url: '/apps/{app_id}/workflows/draft/variables/{variable_id}/reset' +} + +export type PutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetErrors = { + 404: { + [key: string]: unknown + } +} + +export type PutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetError + = PutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetErrors[keyof PutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetErrors] + +export type PutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetResponses = { + 200: WorkflowDraftVariable + 204: { + [key: string]: unknown + } +} + +export type PutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetResponse + = PutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetResponses[keyof PutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetResponses] + +export type GetAppsByAppIdWorkflowsPublishData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/publish' +} + +export type GetAppsByAppIdWorkflowsPublishErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetAppsByAppIdWorkflowsPublishError + = GetAppsByAppIdWorkflowsPublishErrors[keyof GetAppsByAppIdWorkflowsPublishErrors] + +export type GetAppsByAppIdWorkflowsPublishResponses = { + 200: Workflow +} + +export type GetAppsByAppIdWorkflowsPublishResponse + = GetAppsByAppIdWorkflowsPublishResponses[keyof GetAppsByAppIdWorkflowsPublishResponses] + +export type PostAppsByAppIdWorkflowsPublishData = { + body: PublishWorkflowPayload + path: { + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/publish' +} + +export type PostAppsByAppIdWorkflowsPublishResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsPublishResponse + = PostAppsByAppIdWorkflowsPublishResponses[keyof PostAppsByAppIdWorkflowsPublishResponses] + +export type GetAppsByAppIdWorkflowsTriggersWebhookData = { + body?: never + path: { + app_id: string + } + query: { + credential_id?: string | null + datasource_type: string + inputs: string + } + url: '/apps/{app_id}/workflows/triggers/webhook' +} + +export type GetAppsByAppIdWorkflowsTriggersWebhookResponses = { + 200: WebhookTriggerResponse +} + +export type GetAppsByAppIdWorkflowsTriggersWebhookResponse + = GetAppsByAppIdWorkflowsTriggersWebhookResponses[keyof GetAppsByAppIdWorkflowsTriggersWebhookResponses] + +export type DeleteAppsByAppIdWorkflowsByWorkflowIdData = { + body?: never + path: { + workflow_id: string + app_id: string + } + query?: never + url: '/apps/{app_id}/workflows/{workflow_id}' +} + +export type DeleteAppsByAppIdWorkflowsByWorkflowIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteAppsByAppIdWorkflowsByWorkflowIdResponse + = DeleteAppsByAppIdWorkflowsByWorkflowIdResponses[keyof DeleteAppsByAppIdWorkflowsByWorkflowIdResponses] + +export type PatchAppsByAppIdWorkflowsByWorkflowIdData = { + body: WorkflowUpdatePayload + path: { + app_id: string + workflow_id: string + } + query?: never + url: '/apps/{app_id}/workflows/{workflow_id}' +} + +export type PatchAppsByAppIdWorkflowsByWorkflowIdErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PatchAppsByAppIdWorkflowsByWorkflowIdError + = PatchAppsByAppIdWorkflowsByWorkflowIdErrors[keyof PatchAppsByAppIdWorkflowsByWorkflowIdErrors] + +export type PatchAppsByAppIdWorkflowsByWorkflowIdResponses = { + 200: Workflow +} + +export type PatchAppsByAppIdWorkflowsByWorkflowIdResponse + = PatchAppsByAppIdWorkflowsByWorkflowIdResponses[keyof PatchAppsByAppIdWorkflowsByWorkflowIdResponses] + +export type PostAppsByAppIdWorkflowsByWorkflowIdRestoreData = { + body?: never + path: { + app_id: string + workflow_id: string + } + query?: never + url: '/apps/{app_id}/workflows/{workflow_id}/restore' +} + +export type PostAppsByAppIdWorkflowsByWorkflowIdRestoreErrors = { + 400: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsByWorkflowIdRestoreError + = PostAppsByAppIdWorkflowsByWorkflowIdRestoreErrors[keyof PostAppsByAppIdWorkflowsByWorkflowIdRestoreErrors] + +export type PostAppsByAppIdWorkflowsByWorkflowIdRestoreResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsByAppIdWorkflowsByWorkflowIdRestoreResponse + = PostAppsByAppIdWorkflowsByWorkflowIdRestoreResponses[keyof PostAppsByAppIdWorkflowsByWorkflowIdRestoreResponses] + +export type GetAppsByResourceIdApiKeysData = { + body?: never + path: { + resource_id: string + } + query?: never + url: '/apps/{resource_id}/api-keys' +} + +export type GetAppsByResourceIdApiKeysResponses = { + 200: ApiKeyList +} + +export type GetAppsByResourceIdApiKeysResponse + = GetAppsByResourceIdApiKeysResponses[keyof GetAppsByResourceIdApiKeysResponses] + +export type PostAppsByResourceIdApiKeysData = { + body?: never + path: { + resource_id: string + } + query?: never + url: '/apps/{resource_id}/api-keys' +} + +export type PostAppsByResourceIdApiKeysErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostAppsByResourceIdApiKeysError + = PostAppsByResourceIdApiKeysErrors[keyof PostAppsByResourceIdApiKeysErrors] + +export type PostAppsByResourceIdApiKeysResponses = { + 201: ApiKeyItem +} + +export type PostAppsByResourceIdApiKeysResponse + = PostAppsByResourceIdApiKeysResponses[keyof PostAppsByResourceIdApiKeysResponses] + +export type DeleteAppsByResourceIdApiKeysByApiKeyIdData = { + body?: never + path: { + resource_id: string + api_key_id: string + } + query?: never + url: '/apps/{resource_id}/api-keys/{api_key_id}' +} + +export type DeleteAppsByResourceIdApiKeysByApiKeyIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAppsByResourceIdApiKeysByApiKeyIdResponse + = DeleteAppsByResourceIdApiKeysByApiKeyIdResponses[keyof DeleteAppsByResourceIdApiKeysByApiKeyIdResponses] + +export type GetAppsByServerIdServerRefreshData = { + body?: never + path: { + server_id: string + } + query?: never + url: '/apps/{server_id}/server/refresh' +} + +export type GetAppsByServerIdServerRefreshErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetAppsByServerIdServerRefreshError + = GetAppsByServerIdServerRefreshErrors[keyof GetAppsByServerIdServerRefreshErrors] + +export type GetAppsByServerIdServerRefreshResponses = { + 200: AppMcpServerResponse +} + +export type GetAppsByServerIdServerRefreshResponse + = GetAppsByServerIdServerRefreshResponses[keyof GetAppsByServerIdServerRefreshResponses] diff --git a/packages/contracts/generated/api/console/apps/zod.gen.ts b/packages/contracts/generated/api/console/apps/zod.gen.ts new file mode 100644 index 0000000000..9798d22cc0 --- /dev/null +++ b/packages/contracts/generated/api/console/apps/zod.gen.ts @@ -0,0 +1,3133 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * AppImportPayload + */ +export const zAppImportPayload = z.object({ + app_id: z.string().nullish(), + description: z.string().nullish(), + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: z.string().nullish(), + mode: z.string(), + name: z.string().nullish(), + yaml_content: z.string().nullish(), + yaml_url: z.string().nullish(), +}) + +export const zAdvancedChatWorkflowRunPagination = z.record(z.string(), z.unknown()) + +export const zWorkflowRunCount = z.record(z.string(), z.unknown()) + +/** + * HumanInputFormPreviewPayload + */ +export const zHumanInputFormPreviewPayload = z.object({ + inputs: z.record(z.string(), z.unknown()).optional(), +}) + +/** + * HumanInputFormSubmitPayload + */ +export const zHumanInputFormSubmitPayload = z.object({ + action: z.string(), + form_inputs: z.record(z.string(), z.unknown()), + inputs: z.record(z.string(), z.unknown()), +}) + +/** + * IterationNodeRunPayload + */ +export const zIterationNodeRunPayload = z.object({ + inputs: z.record(z.string(), z.unknown()).nullish(), +}) + +/** + * LoopNodeRunPayload + */ +export const zLoopNodeRunPayload = z.object({ + inputs: z.record(z.string(), z.unknown()).nullish(), +}) + +/** + * AdvancedChatWorkflowRunPayload + */ +export const zAdvancedChatWorkflowRunPayload = z.object({ + conversation_id: z.string().nullish(), + files: z.array(z.record(z.string(), z.unknown())).nullish(), + inputs: z.record(z.string(), z.unknown()).nullish(), + parent_message_id: z.string().nullish(), + query: z.string().optional().default(''), +}) + +/** + * AnnotationReplyPayload + */ +export const zAnnotationReplyPayload = z.object({ + embedding_model_name: z.string(), + embedding_provider_name: z.string(), + score_threshold: z.number(), +}) + +/** + * AnnotationSettingUpdatePayload + */ +export const zAnnotationSettingUpdatePayload = z.object({ + score_threshold: z.number(), +}) + +/** + * CreateAnnotationPayload + */ +export const zCreateAnnotationPayload = z.object({ + annotation_reply: z.record(z.string(), z.unknown()).nullish(), + answer: z.string().nullish(), + content: z.string().nullish(), + message_id: z.string().nullish(), + question: z.string().nullish(), +}) + +/** + * Annotation + */ +export const zAnnotation = z.object({ + content: z.string().nullish(), + created_at: z.int().nullish(), + hit_count: z.int().nullish(), + id: z.string(), + question: z.string().nullish(), +}) + +/** + * AnnotationCountResponse + */ +export const zAnnotationCountResponse = z.object({ + count: z.int(), +}) + +/** + * AnnotationExportList + */ +export const zAnnotationExportList = z.object({ + data: z.array(zAnnotation), +}) + +/** + * UpdateAnnotationPayload + */ +export const zUpdateAnnotationPayload = z.object({ + annotation_reply: z.record(z.string(), z.unknown()).nullish(), + answer: z.string().nullish(), + content: z.string().nullish(), + question: z.string().nullish(), +}) + +/** + * AppApiStatusPayload + */ +export const zAppApiStatusPayload = z.object({ + enable_api: z.boolean(), +}) + +/** + * AudioTranscriptResponse + */ +export const zAudioTranscriptResponse = z.object({ + text: z.string(), +}) + +/** + * SuggestedQuestionsResponse + */ +export const zSuggestedQuestionsResponse = z.object({ + data: z.array(z.string()), +}) + +/** + * CompletionMessagePayload + */ +export const zCompletionMessagePayload = z.object({ + files: z.array(z.unknown()).nullish(), + inputs: z.record(z.string(), z.unknown()), + model_config: z.record(z.string(), z.unknown()), + query: z.string().optional().default(''), + response_mode: z.enum(['blocking', 'streaming']).optional().default('blocking'), + retriever_from: z.string().optional().default('dev'), +}) + +/** + * ConvertToWorkflowPayload + */ +export const zConvertToWorkflowPayload = z.object({ + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: z.string().nullish(), + name: z.string().nullish(), +}) + +/** + * AppExportResponse + */ +export const zAppExportResponse = z.object({ + data: z.string(), +}) + +/** + * MessageFeedbackPayload + */ +export const zMessageFeedbackPayload = z.object({ + content: z.string().nullish(), + message_id: z.string(), + rating: z.enum(['like', 'dislike']).nullish(), +}) + +/** + * ModelConfigRequest + */ +export const zModelConfigRequest = z.object({ + agent_mode: z.record(z.string(), z.unknown()).nullish(), + configs: z.record(z.string(), z.unknown()).nullish(), + dataset_configs: z.record(z.string(), z.unknown()).nullish(), + model: z.string().nullish(), + more_like_this: z.record(z.string(), z.unknown()).nullish(), + opening_statement: z.string().nullish(), + provider: z.string().nullish(), + retrieval_model: z.record(z.string(), z.unknown()).nullish(), + speech_to_text: z.record(z.string(), z.unknown()).nullish(), + suggested_questions: z.array(z.string()).nullish(), + text_to_speech: z.record(z.string(), z.unknown()).nullish(), + tools: z.array(z.record(z.string(), z.unknown())).nullish(), +}) + +/** + * AppNamePayload + */ +export const zAppNamePayload = z.object({ + name: z.string().min(1), +}) + +/** + * MCPServerCreatePayload + */ +export const zMcpServerCreatePayload = z.object({ + description: z.string().nullish(), + parameters: z.record(z.string(), z.unknown()), +}) + +/** + * MCPServerUpdatePayload + */ +export const zMcpServerUpdatePayload = z.object({ + description: z.string().nullish(), + id: z.string(), + parameters: z.record(z.string(), z.unknown()), + status: z.string().nullish(), +}) + +/** + * AppSiteUpdatePayload + */ +export const zAppSiteUpdatePayload = z.object({ + chat_color_theme: z.string().nullish(), + chat_color_theme_inverted: z.boolean().nullish(), + copyright: z.string().nullish(), + custom_disclaimer: z.string().nullish(), + customize_domain: z.string().nullish(), + customize_token_strategy: z.enum(['must', 'allow', 'not_allow']).nullish(), + default_language: z.string().nullish(), + description: z.string().nullish(), + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: z.string().nullish(), + privacy_policy: z.string().nullish(), + prompt_public: z.boolean().nullish(), + show_workflow_steps: z.boolean().nullish(), + title: z.string().nullish(), + use_icon_as_answer_icon: z.boolean().nullish(), +}) + +/** + * AppSiteResponse + */ +export const zAppSiteResponse = z.object({ + app_id: z.string(), + code: z.string().nullish(), + copyright: z.string().nullish(), + custom_disclaimer: z.string().nullish(), + customize_domain: z.string().nullish(), + customize_token_strategy: z.string(), + default_language: z.string(), + description: z.string().nullish(), + icon: z.string().nullish(), + icon_background: z.string().nullish(), + privacy_policy: z.string().nullish(), + prompt_public: z.boolean(), + show_workflow_steps: z.boolean(), + title: z.string(), + use_icon_as_answer_icon: z.boolean(), +}) + +/** + * AppSiteStatusPayload + */ +export const zAppSiteStatusPayload = z.object({ + enable_site: z.boolean(), +}) + +/** + * TextToSpeechPayload + */ +export const zTextToSpeechPayload = z.object({ + message_id: z.string().nullish(), + streaming: z.boolean().nullish(), + text: z.string(), + voice: z.string().nullish(), +}) + +/** + * AppTracePayload + */ +export const zAppTracePayload = z.object({ + enabled: z.boolean(), + tracing_provider: z.string().nullish(), +}) + +/** + * TraceProviderQuery + */ +export const zTraceProviderQuery = z.object({ + tracing_provider: z.string(), +}) + +/** + * TraceConfigPayload + */ +export const zTraceConfigPayload = z.object({ + tracing_config: z.record(z.string(), z.unknown()), + tracing_provider: z.string(), +}) + +/** + * ParserEnable + */ +export const zParserEnable = z.object({ + enable_trigger: z.boolean(), + trigger_id: z.string(), +}) + +/** + * WorkflowTriggerResponse + */ +export const zWorkflowTriggerResponse = z.object({ + created_at: z.iso.datetime().nullish(), + icon: z.string(), + id: z.string(), + node_id: z.string(), + provider_name: z.string(), + status: z.string(), + title: z.string(), + trigger_type: z.string(), + updated_at: z.iso.datetime().nullish(), +}) + +/** + * WorkflowTriggerListResponse + */ +export const zWorkflowTriggerListResponse = z.object({ + data: z.array(zWorkflowTriggerResponse), +}) + +export const zWorkflowRunPagination = z.record(z.string(), z.unknown()) + +export const zWorkflowRunDetail = z.record(z.string(), z.unknown()) + +export const zWorkflowRunExport = z.record(z.string(), z.unknown()) + +export const zWorkflowRunNodeExecutionList = z.record(z.string(), z.unknown()) + +export const zWorkflowCommentBasic = z.record(z.string(), z.unknown()) + +/** + * WorkflowCommentCreatePayload + */ +export const zWorkflowCommentCreatePayload = z.object({ + content: z.string(), + mentioned_user_ids: z.array(z.string()).optional(), + position_x: z.number(), + position_y: z.number(), +}) + +export const zWorkflowCommentCreate = z.record(z.string(), z.unknown()) + +export const zWorkflowCommentDetail = z.record(z.string(), z.unknown()) + +/** + * WorkflowCommentUpdatePayload + */ +export const zWorkflowCommentUpdatePayload = z.object({ + content: z.string(), + mentioned_user_ids: z.array(z.string()).nullish(), + position_x: z.number().nullish(), + position_y: z.number().nullish(), +}) + +export const zWorkflowCommentUpdate = z.record(z.string(), z.unknown()) + +/** + * WorkflowCommentReplyPayload + */ +export const zWorkflowCommentReplyPayload = z.object({ + content: z.string(), + mentioned_user_ids: z.array(z.string()).optional(), +}) + +export const zWorkflowCommentReplyCreate = z.record(z.string(), z.unknown()) + +export const zWorkflowCommentReplyUpdate = z.record(z.string(), z.unknown()) + +export const zWorkflowCommentResolve = z.record(z.string(), z.unknown()) + +export const zWorkflowPagination = z.record(z.string(), z.unknown()) + +export const zWorkflow = z.record(z.string(), z.unknown()) + +/** + * SyncDraftWorkflowPayload + */ +export const zSyncDraftWorkflowPayload = z.object({ + conversation_variables: z.array(z.record(z.string(), z.unknown())).optional(), + environment_variables: z.array(z.record(z.string(), z.unknown())).optional(), + features: z.record(z.string(), z.unknown()), + graph: z.record(z.string(), z.unknown()), + hash: z.string().nullish(), +}) + +export const zSyncDraftWorkflowResponse = z.record(z.string(), z.unknown()) + +export const zWorkflowDraftVariableList = z.record(z.string(), z.unknown()) + +/** + * ConversationVariableUpdatePayload + */ +export const zConversationVariableUpdatePayload = z.object({ + conversation_variables: z.array(z.record(z.string(), z.unknown())), +}) + +/** + * EnvironmentVariableUpdatePayload + */ +export const zEnvironmentVariableUpdatePayload = z.object({ + environment_variables: z.array(z.record(z.string(), z.unknown())), +}) + +/** + * WorkflowFeaturesPayload + */ +export const zWorkflowFeaturesPayload = z.object({ + features: z.record(z.string(), z.unknown()), +}) + +/** + * HumanInputDeliveryTestPayload + */ +export const zHumanInputDeliveryTestPayload = z.object({ + delivery_method_id: z.string(), + inputs: z.record(z.string(), z.unknown()).optional(), +}) + +export const zWorkflowRunNodeExecution = z.record(z.string(), z.unknown()) + +/** + * DraftWorkflowNodeRunPayload + */ +export const zDraftWorkflowNodeRunPayload = z.object({ + files: z.array(z.record(z.string(), z.unknown())).nullish(), + inputs: z.record(z.string(), z.unknown()), + query: z.string().optional().default(''), +}) + +/** + * DraftWorkflowRunPayload + */ +export const zDraftWorkflowRunPayload = z.object({ + datasource_info_list: z.array(z.record(z.string(), z.unknown())), + datasource_type: z.string(), + inputs: z.record(z.string(), z.unknown()), + start_node_id: z.string(), +}) + +export const zDraftWorkflowTriggerRunRequest = z.record(z.string(), z.unknown()) + +/** + * DraftWorkflowTriggerRunAllPayload + */ +export const zDraftWorkflowTriggerRunAllPayload = z.object({ + node_ids: z.array(z.string()), +}) + +export const zWorkflowDraftVariableListWithoutValue = z.record(z.string(), z.unknown()) + +export const zWorkflowDraftVariable = z.record(z.string(), z.unknown()) + +/** + * WorkflowDraftVariableUpdatePayload + */ +export const zWorkflowDraftVariableUpdatePayload = z.object({ + name: z.string().nullish(), + value: z.unknown().optional(), +}) + +/** + * PublishWorkflowPayload + */ +export const zPublishWorkflowPayload = z.object({ + marked_comment: z.string().max(100).nullish(), + marked_name: z.string().max(20).nullish(), +}) + +/** + * WebhookTriggerResponse + */ +export const zWebhookTriggerResponse = z.object({ + created_at: z.iso.datetime().nullish(), + id: z.string(), + node_id: z.string(), + webhook_debug_url: z.string(), + webhook_id: z.string(), + webhook_url: z.string(), +}) + +/** + * WorkflowUpdatePayload + */ +export const zWorkflowUpdatePayload = z.object({ + marked_comment: z.string().max(100).nullish(), + marked_name: z.string().max(20).nullish(), +}) + +/** + * ApiKeyItem + */ +export const zApiKeyItem = z.object({ + created_at: z.int().nullish(), + id: z.string(), + last_used_at: z.int().nullish(), + token: z.string(), + type: z.string(), +}) + +/** + * ApiKeyList + */ +export const zApiKeyList = z.object({ + data: z.array(zApiKeyItem), +}) + +/** + * IconType + */ +export const zIconType = z.enum(['image', 'emoji', 'link']) + +/** + * CreateAppPayload + */ +export const zCreateAppPayload = z.object({ + description: z.string().max(400).nullish(), + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: zIconType.optional(), + mode: z.enum(['chat', 'agent-chat', 'advanced-chat', 'workflow', 'completion']), + name: z.string().min(1), +}) + +/** + * UpdateAppPayload + */ +export const zUpdateAppPayload = z.object({ + description: z.string().max(400).nullish(), + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: zIconType.optional(), + max_active_requests: z.int().nullish(), + name: z.string().min(1), + use_icon_as_answer_icon: z.boolean().nullish(), +}) + +/** + * CopyAppPayload + */ +export const zCopyAppPayload = z.object({ + description: z.string().max(400).nullish(), + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: zIconType.optional(), + name: z.string().nullish(), +}) + +/** + * AppIconPayload + */ +export const zAppIconPayload = z.object({ + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: zIconType.optional(), +}) + +/** + * Tag + */ +export const zTag = z.object({ + id: z.string(), + name: z.string(), + type: z.string(), +}) + +export const zJsonValue = z.unknown() + +/** + * ModelConfig + */ +export const zModelConfig = z.object({ + agent_mode_dict: zJsonValue.optional(), + annotation_reply_dict: zJsonValue.optional(), + chat_prompt_config_dict: zJsonValue.optional(), + completion_prompt_config_dict: zJsonValue.optional(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs_dict: zJsonValue.optional(), + dataset_query_variable: z.string().nullish(), + external_data_tools_list: zJsonValue.optional(), + file_upload_dict: zJsonValue.optional(), + model_dict: zJsonValue.optional(), + more_like_this_dict: zJsonValue.optional(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource_dict: zJsonValue.optional(), + sensitive_word_avoidance_dict: zJsonValue.optional(), + speech_to_text_dict: zJsonValue.optional(), + suggested_questions_after_answer_dict: zJsonValue.optional(), + suggested_questions_list: zJsonValue.optional(), + text_to_speech_dict: zJsonValue.optional(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form_list: zJsonValue.optional(), +}) + +/** + * WorkflowPartial + */ +export const zWorkflowPartial = z.object({ + created_at: z.int().nullish(), + created_by: z.string().nullish(), + id: z.string(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), +}) + +/** + * AppDetail + */ +export const zAppDetail = z.object({ + access_mode: z.string().nullish(), + app_model_config: zModelConfig.optional(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + description: z.string().nullish(), + enable_api: z.boolean(), + enable_site: z.boolean(), + icon: z.string().nullish(), + icon_background: z.string().nullish(), + id: z.string(), + mode_compatible_with_agent: z.string(), + name: z.string(), + tags: z.array(zTag).optional(), + tracing: zJsonValue.optional(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + use_icon_as_answer_icon: z.boolean().nullish(), + workflow: zWorkflowPartial.optional(), +}) + +/** + * ImportStatus + */ +export const zImportStatus = z.enum(['completed', 'completed-with-warnings', 'pending', 'failed']) + +/** + * Import + */ +export const zImport = z.object({ + app_id: z.string().nullish(), + app_mode: z.string().nullish(), + current_dsl_version: z.string().optional().default('0.6.0'), + error: z.string().optional().default(''), + id: z.string(), + imported_dsl_version: z.string().optional().default(''), + status: zImportStatus, +}) + +/** + * DeletedTool + */ +export const zDeletedTool = z.object({ + provider_id: z.string(), + tool_name: z.string(), + type: z.string(), +}) + +/** + * Site + */ +export const zSite = z.object({ + app_base_url: z.string().nullish(), + chat_color_theme: z.string().nullish(), + chat_color_theme_inverted: z.boolean().nullish(), + code: z.string().nullish(), + copyright: z.string().nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + custom_disclaimer: z.string().nullish(), + customize_domain: z.string().nullish(), + customize_token_strategy: z.string().nullish(), + default_language: z.string().nullish(), + description: z.string().nullish(), + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: z.unknown().optional(), + privacy_policy: z.string().nullish(), + prompt_public: z.boolean().nullish(), + show_workflow_steps: z.boolean().nullish(), + title: z.string().nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + use_icon_as_answer_icon: z.boolean().nullish(), +}) + +/** + * AppDetailWithSite + */ +export const zAppDetailWithSite = z.object({ + access_mode: z.string().nullish(), + api_base_url: z.string().nullish(), + app_model_config: zModelConfig.optional(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + deleted_tools: z.array(zDeletedTool).optional(), + description: z.string().nullish(), + enable_api: z.boolean(), + enable_site: z.boolean(), + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: z.string().nullish(), + id: z.string(), + max_active_requests: z.int().nullish(), + mode_compatible_with_agent: z.string(), + name: z.string(), + site: zSite.optional(), + tags: z.array(zTag).optional(), + tracing: zJsonValue.optional(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + use_icon_as_answer_icon: z.boolean().nullish(), + workflow: zWorkflowPartial.optional(), +}) + +/** + * AnnotationHitHistory + */ +export const zAnnotationHitHistory = z.object({ + annotation_content: z.string().nullish(), + annotation_question: z.string().nullish(), + created_at: z.int().nullish(), + id: z.string(), + question: z.string().nullish(), + score: z.number().nullish(), + source: z.string().nullish(), +}) + +/** + * AnnotationHitHistoryList + */ +export const zAnnotationHitHistoryList = z.object({ + data: z.array(zAnnotationHitHistory), + has_more: z.boolean(), + limit: z.int(), + page: z.int(), + total: z.int(), +}) + +/** + * FeedbackStat + */ +export const zFeedbackStat = z.object({ + dislike: z.int(), + like: z.int(), +}) + +/** + * ConversationDetail + */ +export const zConversationDetail = z.object({ + admin_feedback_stats: zFeedbackStat.optional(), + annotated: z.boolean(), + created_at: z.int().nullish(), + from_account_id: z.string().nullish(), + from_end_user_id: z.string().nullish(), + from_source: z.string(), + id: z.string(), + introduction: z.string().nullish(), + message_count: z.int(), + model_config: zModelConfig.optional(), + status: z.string(), + updated_at: z.int().nullish(), + user_feedback_stats: zFeedbackStat.optional(), +}) + +/** + * ConversationVariableResponse + */ +export const zConversationVariableResponse = z.object({ + created_at: z.int().nullish(), + description: z.string().nullish(), + id: z.string(), + name: z.string(), + updated_at: z.int().nullish(), + value: z.string().nullish(), + value_type: z.string(), +}) + +/** + * PaginatedConversationVariableResponse + */ +export const zPaginatedConversationVariableResponse = z.object({ + data: z.array(zConversationVariableResponse), + has_more: z.boolean(), + limit: z.int(), + page: z.int(), + total: z.int(), +}) + +/** + * AgentThought + */ +export const zAgentThought = z.object({ + chain_id: z.string().nullish(), + created_at: z.int().nullish(), + files: z.array(z.string()), + id: z.string(), + message_chain_id: z.string().nullish(), + message_id: z.string(), + observation: z.string().nullish(), + position: z.int(), + thought: z.string().nullish(), + tool: z.string().nullish(), + tool_input: z.string().nullish(), + tool_labels: zJsonValue, +}) + +/** + * MessageFile + */ +export const zMessageFile = z.object({ + belongs_to: z.string().nullish(), + filename: z.string(), + id: z.string(), + mime_type: z.string().nullish(), + size: z.int().nullish(), + transfer_method: z.string(), + type: z.string(), + upload_file_id: z.string().nullish(), + url: z.string().nullish(), +}) + +/** + * AppMCPServerStatus + * + * AppMCPServer Status Enum + */ +export const zAppMcpServerStatus = z.enum(['normal', 'active', 'inactive']) + +/** + * AppMCPServerResponse + */ +export const zAppMcpServerResponse = z.object({ + created_at: z.int().nullish(), + description: z.string(), + id: z.string(), + name: z.string(), + parameters: z.unknown(), + server_code: z.string(), + status: zAppMcpServerStatus, + updated_at: z.int().nullish(), +}) + +/** + * AccountWithRole + */ +export const zAccountWithRole = z.object({ + avatar: z.string().nullish(), + created_at: z.int().nullish(), + email: z.string(), + id: z.string(), + last_active_at: z.int().nullish(), + last_login_at: z.int().nullish(), + name: z.string(), + role: z.string(), + status: z.string(), +}) + +/** + * WorkflowCommentMentionUsersPayload + */ +export const zWorkflowCommentMentionUsersPayload = z.object({ + users: z.array(zAccountWithRole), +}) + +/** + * ModelConfigPartial + */ +export const zModelConfigPartial = z.object({ + created_at: z.int().nullish(), + created_by: z.string().nullish(), + model_dict: zJsonValue.optional(), + pre_prompt: z.string().nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), +}) + +/** + * AppPartial + */ +export const zAppPartial = z.object({ + access_mode: z.string().nullish(), + app_model_config: zModelConfigPartial.optional(), + author_name: z.string().nullish(), + create_user_name: z.string().nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + desc_or_prompt: z.string().nullish(), + has_draft_trigger: z.boolean().nullish(), + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: z.string().nullish(), + id: z.string(), + max_active_requests: z.int().nullish(), + mode_compatible_with_agent: z.string(), + name: z.string(), + tags: z.array(zTag).optional(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + use_icon_as_answer_icon: z.boolean().nullish(), + workflow: zWorkflowPartial.optional(), +}) + +/** + * AppPagination + */ +export const zAppPagination = z.object({ + has_next: z.boolean(), + items: z.array(zAppPartial), + page: z.int(), + per_page: z.int(), + total: z.int(), +}) + +/** + * Type + */ +export const zType = z.enum(['github', 'marketplace', 'package']) + +/** + * PluginDependency + */ +export const zPluginDependency = z.object({ + current_identifier: z.string().nullish(), + type: zType, + value: z.unknown(), +}) + +/** + * CheckDependenciesResult + */ +export const zCheckDependenciesResult = z.object({ + leaked_dependencies: z.array(zPluginDependency).optional(), +}) + +/** + * Github + */ +export const zGithub = z.object({ + github_plugin_unique_identifier: z.string(), + package: z.string(), + repo: z.string(), + version: z.string(), +}) + +/** + * Marketplace + */ +export const zMarketplace = z.object({ + marketplace_plugin_unique_identifier: z.string(), + version: z.string().nullish(), +}) + +/** + * Package + */ +export const zPackage = z.object({ + plugin_unique_identifier: z.string(), + version: z.string().nullish(), +}) + +/** + * SimpleModelConfig + */ +export const zSimpleModelConfig = z.object({ + model_dict: zJsonValue.optional(), + pre_prompt: z.string().nullish(), +}) + +/** + * StatusCount + */ +export const zStatusCount = z.object({ + failed: z.int(), + partial_success: z.int(), + paused: z.int(), + success: z.int(), +}) + +/** + * ConversationWithSummary + */ +export const zConversationWithSummary = z.object({ + admin_feedback_stats: zFeedbackStat.optional(), + annotated: z.boolean(), + created_at: z.int().nullish(), + from_account_id: z.string().nullish(), + from_account_name: z.string().nullish(), + from_end_user_id: z.string().nullish(), + from_end_user_session_id: z.string().nullish(), + from_source: z.string(), + id: z.string(), + message_count: z.int(), + model_config: zSimpleModelConfig.optional(), + name: z.string(), + read_at: z.int().nullish(), + status: z.string(), + status_count: zStatusCount.optional(), + summary_or_query: z.string(), + updated_at: z.int().nullish(), + user_feedback_stats: zFeedbackStat.optional(), +}) + +/** + * ConversationWithSummaryPagination + */ +export const zConversationWithSummaryPagination = z.object({ + has_next: z.boolean(), + items: z.array(zConversationWithSummary), + page: z.int(), + per_page: z.int(), + total: z.int(), +}) + +/** + * SimpleMessageDetail + */ +export const zSimpleMessageDetail = z.object({ + answer: z.string(), + inputs: z.record(z.string(), zJsonValue), + message: z.string(), + query: z.string(), +}) + +/** + * SimpleAccount + */ +export const zSimpleAccount = z.object({ + email: z.string(), + id: z.string(), + name: z.string(), +}) + +/** + * ConversationAnnotation + */ +export const zConversationAnnotation = z.object({ + account: zSimpleAccount.optional(), + content: z.string(), + created_at: z.int().nullish(), + id: z.string(), + question: z.string().nullish(), +}) + +/** + * Conversation + */ +export const zConversation = z.object({ + admin_feedback_stats: zFeedbackStat.optional(), + annotation: zConversationAnnotation.optional(), + created_at: z.int().nullish(), + first_message: zSimpleMessageDetail.optional(), + from_account_id: z.string().nullish(), + from_account_name: z.string().nullish(), + from_end_user_id: z.string().nullish(), + from_end_user_session_id: z.string().nullish(), + from_source: z.string(), + id: z.string(), + model_config: zSimpleModelConfig.optional(), + read_at: z.int().nullish(), + status: z.string(), + updated_at: z.int().nullish(), + user_feedback_stats: zFeedbackStat.optional(), +}) + +/** + * ConversationPagination + */ +export const zConversationPagination = z.object({ + has_next: z.boolean(), + items: z.array(zConversation), + page: z.int(), + per_page: z.int(), + total: z.int(), +}) + +/** + * ConversationAnnotationHitHistory + */ +export const zConversationAnnotationHitHistory = z.object({ + annotation_create_account: zSimpleAccount.optional(), + created_at: z.int().nullish(), + id: z.string(), +}) + +/** + * Feedback + */ +export const zFeedback = z.object({ + content: z.string().nullish(), + from_account: zSimpleAccount.optional(), + from_end_user_id: z.string().nullish(), + from_source: z.string(), + rating: z.string(), +}) + +/** + * MessageDetail + */ +export const zMessageDetail = z.object({ + agent_thoughts: z.array(zAgentThought), + annotation: zConversationAnnotation.optional(), + annotation_hit_history: zConversationAnnotationHitHistory.optional(), + answer_tokens: z.int(), + conversation_id: z.string(), + created_at: z.int().nullish(), + error: z.string().nullish(), + feedbacks: z.array(zFeedback), + from_account_id: z.string().nullish(), + from_end_user_id: z.string().nullish(), + from_source: z.string(), + id: z.string(), + inputs: z.record(z.string(), zJsonValue), + message: zJsonValue, + message_files: z.array(zMessageFile), + message_metadata_dict: zJsonValue, + message_tokens: z.int(), + parent_message_id: z.string().nullish(), + provider_response_latency: z.number(), + query: z.string(), + re_sign_file_url_answer: z.string(), + status: z.string(), + workflow_run_id: z.string().nullish(), +}) + +/** + * ConversationMessageDetail + */ +export const zConversationMessageDetail = z.object({ + created_at: z.int().nullish(), + first_message: zMessageDetail.optional(), + from_account_id: z.string().nullish(), + from_end_user_id: z.string().nullish(), + from_source: z.string(), + id: z.string(), + model_config: zModelConfig.optional(), + status: z.string(), +}) + +/** + * HumanInputFormSubmissionData + */ +export const zHumanInputFormSubmissionData = z.object({ + action_id: z.string(), + action_text: z.string(), + node_id: z.string(), + node_title: z.string(), + rendered_content: z.string(), +}) + +/** + * ExecutionContentType + */ +export const zExecutionContentType = z.enum(['human_input']) + +/** + * SimpleEndUser + */ +export const zSimpleEndUser = z.object({ + id: z.string(), + is_anonymous: z.boolean(), + session_id: z.string().nullish(), + type: z.string(), +}) + +/** + * WorkflowRunForLogResponse + */ +export const zWorkflowRunForLogResponse = z.object({ + created_at: z.int().nullish(), + elapsed_time: z.number().nullish(), + error: z.string().nullish(), + exceptions_count: z.int().nullish(), + finished_at: z.int().nullish(), + id: z.string(), + status: z.string().nullish(), + total_steps: z.int().nullish(), + total_tokens: z.int().nullish(), + triggered_from: z.string().nullish(), + version: z.string().nullish(), +}) + +/** + * WorkflowAppLogPartialResponse + */ +export const zWorkflowAppLogPartialResponse = z.object({ + created_at: z.int().nullish(), + created_by_account: zSimpleAccount.optional(), + created_by_end_user: zSimpleEndUser.optional(), + created_by_role: z.string().nullish(), + created_from: z.string().nullish(), + details: z.unknown().optional(), + id: z.string(), + workflow_run: zWorkflowRunForLogResponse.optional(), +}) + +/** + * WorkflowAppLogPaginationResponse + */ +export const zWorkflowAppLogPaginationResponse = z.object({ + data: z.array(zWorkflowAppLogPartialResponse), + has_more: z.boolean(), + limit: z.int(), + page: z.int(), + total: z.int(), +}) + +/** + * WorkflowRunForArchivedLogResponse + */ +export const zWorkflowRunForArchivedLogResponse = z.object({ + elapsed_time: z.number().nullish(), + id: z.string(), + status: z.string().nullish(), + total_tokens: z.int().nullish(), + triggered_from: z.string().nullish(), +}) + +/** + * WorkflowArchivedLogPartialResponse + */ +export const zWorkflowArchivedLogPartialResponse = z.object({ + created_at: z.int().nullish(), + created_by_account: zSimpleAccount.optional(), + created_by_end_user: zSimpleEndUser.optional(), + id: z.string(), + trigger_metadata: z.unknown().optional(), + workflow_run: zWorkflowRunForArchivedLogResponse.optional(), +}) + +/** + * WorkflowArchivedLogPaginationResponse + */ +export const zWorkflowArchivedLogPaginationResponse = z.object({ + data: z.array(zWorkflowArchivedLogPartialResponse), + has_more: z.boolean(), + limit: z.int(), + page: z.int(), + total: z.int(), +}) + +/** + * ButtonStyle + * + * Button styles for user actions. + */ +export const zButtonStyle = z.enum(['primary', 'default', 'accent', 'ghost']) + +/** + * UserAction + * + * User action configuration. + */ +export const zUserAction = z.object({ + button_style: zButtonStyle.optional(), + id: z.string().max(20), + title: z.string().max(20), +}) + +/** + * FormInputType + * + * Form input types. + */ +export const zFormInputType = z.enum(['text_input', 'paragraph']) + +/** + * PlaceholderType + * + * Default value types for form inputs. + */ +export const zPlaceholderType = z.enum(['variable', 'constant']) + +/** + * FormInputDefault + * + * Default configuration for form inputs. + */ +export const zFormInputDefault = z.object({ + selector: z.array(z.string()).optional(), + type: zPlaceholderType, + value: z.string().optional().default(''), +}) + +/** + * FormInput + * + * Form input definition. + */ +export const zFormInput = z.object({ + default: zFormInputDefault.optional(), + output_variable_name: z.string(), + type: zFormInputType, +}) + +/** + * HumanInputFormDefinition + */ +export const zHumanInputFormDefinition = z.object({ + actions: z.array(zUserAction).optional(), + display_in_ui: z.boolean().optional().default(false), + expiration_time: z.int(), + form_content: z.string(), + form_id: z.string(), + form_token: z.string().nullish(), + inputs: z.array(zFormInput).optional(), + node_id: z.string(), + node_title: z.string(), + resolved_default_values: z.record(z.string(), z.unknown()).optional(), +}) + +/** + * HumanInputContent + */ +export const zHumanInputContent = z.object({ + form_definition: zHumanInputFormDefinition.optional(), + form_submission_data: zHumanInputFormSubmissionData.optional(), + submitted: z.boolean(), + type: zExecutionContentType.optional(), + workflow_run_id: z.string(), +}) + +/** + * MessageDetailResponse + */ +export const zMessageDetailResponse = z.object({ + agent_thoughts: z.array(zAgentThought).optional(), + annotation: zConversationAnnotation.optional(), + annotation_hit_history: zConversationAnnotationHitHistory.optional(), + answer_tokens: z.int().nullish(), + conversation_id: z.string(), + created_at: z.int().nullish(), + error: z.string().nullish(), + extra_contents: z.array(zHumanInputContent).optional(), + feedbacks: z.array(zFeedback).optional(), + from_account_id: z.string().nullish(), + from_end_user_id: z.string().nullish(), + from_source: z.string(), + id: z.string(), + inputs: z.record(z.string(), zJsonValue), + message: zJsonValue.optional(), + message_files: z.array(zMessageFile).optional(), + message_metadata_dict: zJsonValue.optional(), + message_tokens: z.int().nullish(), + parent_message_id: z.string().nullish(), + provider_response_latency: z.number().nullish(), + query: z.string(), + re_sign_file_url_answer: z.string(), + status: z.string(), + workflow_run_id: z.string().nullish(), +}) + +/** + * MessageInfiniteScrollPaginationResponse + */ +export const zMessageInfiniteScrollPaginationResponse = z.object({ + data: z.array(zMessageDetailResponse), + has_more: z.boolean(), + limit: z.int(), +}) + +export const zGetAppsQuery = z.object({ + is_created_by_me: z.boolean().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), + mode: z + .enum(['completion', 'chat', 'advanced-chat', 'workflow', 'agent-chat', 'channel', 'all']) + .optional() + .default('all'), + name: z.string().nullish(), + page: z.int().gte(1).lte(99999).optional().default(1), + tag_ids: z.array(z.string()).nullish(), +}) + +/** + * Success + */ +export const zGetAppsResponse = zAppPagination + +export const zPostAppsBody = zCreateAppPayload + +/** + * App created successfully + */ +export const zPostAppsResponse = zAppDetail + +export const zPostAppsImportsBody = zAppImportPayload + +/** + * Import completed + */ +export const zPostAppsImportsResponse = zImport + +export const zGetAppsImportsByAppIdCheckDependenciesPath = z.object({ + app_id: z.string(), +}) + +/** + * Dependencies checked + */ +export const zGetAppsImportsByAppIdCheckDependenciesResponse = zCheckDependenciesResult + +export const zPostAppsImportsByImportIdConfirmPath = z.object({ + import_id: z.string(), +}) + +/** + * Import confirmed + */ +export const zPostAppsImportsByImportIdConfirmResponse = zImport + +export const zGetAppsWorkflowsOnlineUsersQuery = z.object({ + app_ids: z.string(), +}) + +/** + * Success + */ +export const zGetAppsWorkflowsOnlineUsersResponse = z.record(z.string(), z.unknown()) + +export const zDeleteAppsByAppIdPath = z.object({ + app_id: z.string(), +}) + +/** + * App deleted successfully + */ +export const zDeleteAppsByAppIdResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zGetAppsByAppIdResponse = zAppDetailWithSite + +export const zPutAppsByAppIdBody = zUpdateAppPayload + +export const zPutAppsByAppIdPath = z.object({ + app_id: z.string(), +}) + +/** + * App updated successfully + */ +export const zPutAppsByAppIdResponse = zAppDetailWithSite + +export const zGetAppsByAppIdAdvancedChatWorkflowRunsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdAdvancedChatWorkflowRunsQuery = z.object({ + triggered_from: z.enum(['debugging', 'app-run']).nullish(), + status: z.enum(['running', 'succeeded', 'failed', 'stopped', 'partial-succeeded']).nullish(), + last_id: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), +}) + +/** + * Workflow runs retrieved successfully + */ +export const zGetAppsByAppIdAdvancedChatWorkflowRunsResponse = zAdvancedChatWorkflowRunPagination + +export const zGetAppsByAppIdAdvancedChatWorkflowRunsCountPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdAdvancedChatWorkflowRunsCountQuery = z.object({ + triggered_from: z.enum(['debugging', 'app-run']).nullish(), + time_range: z.string().nullish(), + status: z.enum(['running', 'succeeded', 'failed', 'stopped', 'partial-succeeded']).nullish(), +}) + +/** + * Workflow runs count retrieved successfully + */ +export const zGetAppsByAppIdAdvancedChatWorkflowRunsCountResponse = zWorkflowRunCount + +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewBody + = zHumanInputFormPreviewPayload + +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewPath + = z.object({ + app_id: z.string(), + node_id: z.string(), + }) + +/** + * Success + */ +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponse + = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunBody + = zHumanInputFormSubmitPayload + +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunPath + = z.object({ + app_id: z.string(), + node_id: z.string(), + }) + +/** + * Success + */ +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunResponse + = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunBody + = zIterationNodeRunPayload + +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunPath = z.object({ + app_id: z.string(), + node_id: z.string(), +}) + +/** + * Iteration node run started successfully + */ +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunBody + = zLoopNodeRunPayload + +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunPath = z.object({ + app_id: z.string(), + node_id: z.string(), +}) + +/** + * Loop node run started successfully + */ +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftRunBody = zAdvancedChatWorkflowRunPayload + +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftRunPath = z.object({ + app_id: z.string(), +}) + +/** + * Workflow run started successfully + */ +export const zPostAppsByAppIdAdvancedChatWorkflowsDraftRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdAgentLogsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdAgentLogsQuery = z.object({ + conversation_id: z.string(), + message_id: z.string(), +}) + +/** + * Agent logs retrieved successfully + */ +export const zGetAppsByAppIdAgentLogsResponse = z.array(z.record(z.string(), z.unknown())) + +export const zPostAppsByAppIdAnnotationReplyByActionBody = zAnnotationReplyPayload + +export const zPostAppsByAppIdAnnotationReplyByActionPath = z.object({ + app_id: z.string(), + action: z.string(), +}) + +/** + * Action completed successfully + */ +export const zPostAppsByAppIdAnnotationReplyByActionResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdAnnotationReplyByActionStatusByJobIdPath = z.object({ + app_id: z.string(), + action: z.string(), + job_id: z.string(), +}) + +/** + * Job status retrieved successfully + */ +export const zGetAppsByAppIdAnnotationReplyByActionStatusByJobIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdAnnotationSettingPath = z.object({ + app_id: z.string(), +}) + +/** + * Annotation settings retrieved successfully + */ +export const zGetAppsByAppIdAnnotationSettingResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdAnnotationSettingsByAnnotationSettingIdBody + = zAnnotationSettingUpdatePayload + +export const zPostAppsByAppIdAnnotationSettingsByAnnotationSettingIdPath = z.object({ + app_id: z.string(), + annotation_setting_id: z.string(), +}) + +/** + * Settings updated successfully + */ +export const zPostAppsByAppIdAnnotationSettingsByAnnotationSettingIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteAppsByAppIdAnnotationsPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteAppsByAppIdAnnotationsResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdAnnotationsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdAnnotationsQuery = z.object({ + keyword: z.string().optional().default(''), + limit: z.int().gte(1).optional().default(20), + page: z.int().gte(1).optional().default(1), +}) + +/** + * Annotations retrieved successfully + */ +export const zGetAppsByAppIdAnnotationsResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdAnnotationsBody = zCreateAnnotationPayload + +export const zPostAppsByAppIdAnnotationsPath = z.object({ + app_id: z.string(), +}) + +/** + * Annotation created successfully + */ +export const zPostAppsByAppIdAnnotationsResponse = zAnnotation + +export const zPostAppsByAppIdAnnotationsBatchImportPath = z.object({ + app_id: z.string(), +}) + +/** + * Batch import started successfully + */ +export const zPostAppsByAppIdAnnotationsBatchImportResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdAnnotationsBatchImportStatusByJobIdPath = z.object({ + app_id: z.string(), + job_id: z.string(), +}) + +/** + * Job status retrieved successfully + */ +export const zGetAppsByAppIdAnnotationsBatchImportStatusByJobIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdAnnotationsCountPath = z.object({ + app_id: z.string(), +}) + +/** + * Annotation count retrieved successfully + */ +export const zGetAppsByAppIdAnnotationsCountResponse = zAnnotationCountResponse + +export const zGetAppsByAppIdAnnotationsExportPath = z.object({ + app_id: z.string(), +}) + +/** + * Annotations exported successfully + */ +export const zGetAppsByAppIdAnnotationsExportResponse = zAnnotationExportList + +export const zDeleteAppsByAppIdAnnotationsByAnnotationIdPath = z.object({ + annotation_id: z.string(), + app_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteAppsByAppIdAnnotationsByAnnotationIdResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdAnnotationsByAnnotationIdBody = zUpdateAnnotationPayload + +export const zPostAppsByAppIdAnnotationsByAnnotationIdPath = z.object({ + app_id: z.string(), + annotation_id: z.string(), +}) + +export const zPostAppsByAppIdAnnotationsByAnnotationIdResponse = z.union([ + zAnnotation, + z.record(z.string(), z.unknown()), +]) + +export const zGetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesPath = z.object({ + app_id: z.string(), + annotation_id: z.string(), +}) + +export const zGetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesQuery = z.object({ + page: z.int().optional().default(1), + limit: z.int().optional().default(20), +}) + +/** + * Hit histories retrieved successfully + */ +export const zGetAppsByAppIdAnnotationsByAnnotationIdHitHistoriesResponse + = zAnnotationHitHistoryList + +export const zPostAppsByAppIdApiEnableBody = zAppApiStatusPayload + +export const zPostAppsByAppIdApiEnablePath = z.object({ + app_id: z.string(), +}) + +/** + * API status updated successfully + */ +export const zPostAppsByAppIdApiEnableResponse = zAppDetail + +export const zPostAppsByAppIdAudioToTextPath = z.object({ + app_id: z.string(), +}) + +/** + * Audio transcription successful + */ +export const zPostAppsByAppIdAudioToTextResponse = zAudioTranscriptResponse + +export const zGetAppsByAppIdChatConversationsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdChatConversationsQuery = z.object({ + annotation_status: z.enum(['annotated', 'not_annotated', 'all']).optional().default('all'), + end: z.string().nullish(), + keyword: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), + page: z.int().gte(1).lte(99999).optional().default(1), + sort_by: z + .enum(['created_at', '-created_at', 'updated_at', '-updated_at']) + .optional() + .default('-updated_at'), + start: z.string().nullish(), +}) + +/** + * Success + */ +export const zGetAppsByAppIdChatConversationsResponse = zConversationWithSummaryPagination + +export const zDeleteAppsByAppIdChatConversationsByConversationIdPath = z.object({ + app_id: z.string(), + conversation_id: z.string(), +}) + +/** + * Conversation deleted successfully + */ +export const zDeleteAppsByAppIdChatConversationsByConversationIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdChatConversationsByConversationIdPath = z.object({ + app_id: z.string(), + conversation_id: z.string(), +}) + +/** + * Success + */ +export const zGetAppsByAppIdChatConversationsByConversationIdResponse = zConversationDetail + +export const zGetAppsByAppIdChatMessagesPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdChatMessagesQuery = z.object({ + conversation_id: z.string(), + first_id: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), +}) + +/** + * Success + */ +export const zGetAppsByAppIdChatMessagesResponse = zMessageInfiniteScrollPaginationResponse + +export const zGetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsPath = z.object({ + app_id: z.string(), + message_id: z.string(), +}) + +/** + * Suggested questions retrieved successfully + */ +export const zGetAppsByAppIdChatMessagesByMessageIdSuggestedQuestionsResponse + = zSuggestedQuestionsResponse + +export const zPostAppsByAppIdChatMessagesByTaskIdStopPath = z.object({ + app_id: z.string(), + task_id: z.string(), +}) + +/** + * Task stopped successfully + */ +export const zPostAppsByAppIdChatMessagesByTaskIdStopResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdCompletionConversationsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdCompletionConversationsQuery = z.object({ + annotation_status: z.enum(['annotated', 'not_annotated', 'all']).optional().default('all'), + end: z.string().nullish(), + keyword: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), + page: z.int().gte(1).lte(99999).optional().default(1), + start: z.string().nullish(), +}) + +/** + * Success + */ +export const zGetAppsByAppIdCompletionConversationsResponse = zConversationPagination + +export const zDeleteAppsByAppIdCompletionConversationsByConversationIdPath = z.object({ + app_id: z.string(), + conversation_id: z.string(), +}) + +/** + * Conversation deleted successfully + */ +export const zDeleteAppsByAppIdCompletionConversationsByConversationIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdCompletionConversationsByConversationIdPath = z.object({ + app_id: z.string(), + conversation_id: z.string(), +}) + +/** + * Success + */ +export const zGetAppsByAppIdCompletionConversationsByConversationIdResponse + = zConversationMessageDetail + +export const zPostAppsByAppIdCompletionMessagesBody = zCompletionMessagePayload + +export const zPostAppsByAppIdCompletionMessagesPath = z.object({ + app_id: z.string(), +}) + +/** + * Completion generated successfully + */ +export const zPostAppsByAppIdCompletionMessagesResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdCompletionMessagesByTaskIdStopPath = z.object({ + app_id: z.string(), + task_id: z.string(), +}) + +/** + * Task stopped successfully + */ +export const zPostAppsByAppIdCompletionMessagesByTaskIdStopResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdConversationVariablesPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdConversationVariablesQuery = z.object({ + conversation_id: z.string(), +}) + +/** + * Conversation variables retrieved successfully + */ +export const zGetAppsByAppIdConversationVariablesResponse = zPaginatedConversationVariableResponse + +export const zPostAppsByAppIdConvertToWorkflowBody = zConvertToWorkflowPayload + +export const zPostAppsByAppIdConvertToWorkflowPath = z.object({ + app_id: z.string(), +}) + +/** + * Application converted to workflow successfully + */ +export const zPostAppsByAppIdConvertToWorkflowResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdCopyBody = zCopyAppPayload + +export const zPostAppsByAppIdCopyPath = z.object({ + app_id: z.string(), +}) + +/** + * App copied successfully + */ +export const zPostAppsByAppIdCopyResponse = zAppDetailWithSite + +export const zGetAppsByAppIdExportPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdExportQuery = z.object({ + include_secret: z.boolean().optional().default(false), + workflow_id: z.string().nullish(), +}) + +/** + * App exported successfully + */ +export const zGetAppsByAppIdExportResponse = zAppExportResponse + +export const zPostAppsByAppIdFeedbacksBody = zMessageFeedbackPayload + +export const zPostAppsByAppIdFeedbacksPath = z.object({ + app_id: z.string(), +}) + +/** + * Feedback updated successfully + */ +export const zPostAppsByAppIdFeedbacksResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdFeedbacksExportPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdFeedbacksExportQuery = z.object({ + end_date: z.string().nullish(), + format: z.enum(['csv', 'json']).optional().default('csv'), + from_source: z.enum(['user', 'admin']).nullish(), + has_comment: z.boolean().nullish(), + rating: z.enum(['like', 'dislike']).nullish(), + start_date: z.string().nullish(), +}) + +/** + * Feedback data exported successfully + */ +export const zGetAppsByAppIdFeedbacksExportResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdIconBody = zAppIconPayload + +export const zPostAppsByAppIdIconPath = z.object({ + app_id: z.string(), +}) + +/** + * Icon updated successfully + */ +export const zPostAppsByAppIdIconResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdMessagesByMessageIdPath = z.object({ + app_id: z.string(), + message_id: z.string(), +}) + +/** + * Message retrieved successfully + */ +export const zGetAppsByAppIdMessagesByMessageIdResponse = zMessageDetailResponse + +export const zPostAppsByAppIdModelConfigBody = zModelConfigRequest + +export const zPostAppsByAppIdModelConfigPath = z.object({ + app_id: z.string(), +}) + +/** + * Model configuration updated successfully + */ +export const zPostAppsByAppIdModelConfigResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdNameBody = zAppNamePayload + +export const zPostAppsByAppIdNamePath = z.object({ + app_id: z.string(), +}) + +/** + * Name availability checked + */ +export const zPostAppsByAppIdNameResponse = zAppDetail + +export const zPostAppsByAppIdPublishToCreatorsPlatformPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zPostAppsByAppIdPublishToCreatorsPlatformResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdServerPath = z.object({ + app_id: z.string(), +}) + +/** + * MCP server configuration retrieved successfully + */ +export const zGetAppsByAppIdServerResponse = zAppMcpServerResponse + +export const zPostAppsByAppIdServerBody = zMcpServerCreatePayload + +export const zPostAppsByAppIdServerPath = z.object({ + app_id: z.string(), +}) + +/** + * MCP server configuration created successfully + */ +export const zPostAppsByAppIdServerResponse = zAppMcpServerResponse + +export const zPutAppsByAppIdServerBody = zMcpServerUpdatePayload + +export const zPutAppsByAppIdServerPath = z.object({ + app_id: z.string(), +}) + +/** + * MCP server configuration updated successfully + */ +export const zPutAppsByAppIdServerResponse = zAppMcpServerResponse + +export const zPostAppsByAppIdSiteBody = zAppSiteUpdatePayload + +export const zPostAppsByAppIdSitePath = z.object({ + app_id: z.string(), +}) + +/** + * Site configuration updated successfully + */ +export const zPostAppsByAppIdSiteResponse = zAppSiteResponse + +export const zPostAppsByAppIdSiteEnableBody = zAppSiteStatusPayload + +export const zPostAppsByAppIdSiteEnablePath = z.object({ + app_id: z.string(), +}) + +/** + * Site status updated successfully + */ +export const zPostAppsByAppIdSiteEnableResponse = zAppDetail + +export const zPostAppsByAppIdSiteAccessTokenResetPath = z.object({ + app_id: z.string(), +}) + +/** + * Access token reset successfully + */ +export const zPostAppsByAppIdSiteAccessTokenResetResponse = zAppSiteResponse + +export const zGetAppsByAppIdStatisticsAverageResponseTimePath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdStatisticsAverageResponseTimeQuery = z.object({ + end: z.string().nullish(), + start: z.string().nullish(), +}) + +/** + * Average response time statistics retrieved successfully + */ +export const zGetAppsByAppIdStatisticsAverageResponseTimeResponse = z.array( + z.record(z.string(), z.unknown()), +) + +export const zGetAppsByAppIdStatisticsAverageSessionInteractionsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdStatisticsAverageSessionInteractionsQuery = z.object({ + end: z.string().nullish(), + start: z.string().nullish(), +}) + +/** + * Average session interaction statistics retrieved successfully + */ +export const zGetAppsByAppIdStatisticsAverageSessionInteractionsResponse = z.array( + z.record(z.string(), z.unknown()), +) + +export const zGetAppsByAppIdStatisticsDailyConversationsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdStatisticsDailyConversationsQuery = z.object({ + end: z.string().nullish(), + start: z.string().nullish(), +}) + +/** + * Daily conversation statistics retrieved successfully + */ +export const zGetAppsByAppIdStatisticsDailyConversationsResponse = z.array( + z.record(z.string(), z.unknown()), +) + +export const zGetAppsByAppIdStatisticsDailyEndUsersPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdStatisticsDailyEndUsersQuery = z.object({ + end: z.string().nullish(), + start: z.string().nullish(), +}) + +/** + * Daily terminal statistics retrieved successfully + */ +export const zGetAppsByAppIdStatisticsDailyEndUsersResponse = z.array( + z.record(z.string(), z.unknown()), +) + +export const zGetAppsByAppIdStatisticsDailyMessagesPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdStatisticsDailyMessagesQuery = z.object({ + end: z.string().nullish(), + start: z.string().nullish(), +}) + +/** + * Daily message statistics retrieved successfully + */ +export const zGetAppsByAppIdStatisticsDailyMessagesResponse = z.array( + z.record(z.string(), z.unknown()), +) + +export const zGetAppsByAppIdStatisticsTokenCostsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdStatisticsTokenCostsQuery = z.object({ + end: z.string().nullish(), + start: z.string().nullish(), +}) + +/** + * Daily token cost statistics retrieved successfully + */ +export const zGetAppsByAppIdStatisticsTokenCostsResponse = z.array( + z.record(z.string(), z.unknown()), +) + +export const zGetAppsByAppIdStatisticsTokensPerSecondPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdStatisticsTokensPerSecondQuery = z.object({ + end: z.string().nullish(), + start: z.string().nullish(), +}) + +/** + * Tokens per second statistics retrieved successfully + */ +export const zGetAppsByAppIdStatisticsTokensPerSecondResponse = z.array( + z.record(z.string(), z.unknown()), +) + +export const zGetAppsByAppIdStatisticsUserSatisfactionRatePath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdStatisticsUserSatisfactionRateQuery = z.object({ + end: z.string().nullish(), + start: z.string().nullish(), +}) + +/** + * User satisfaction rate statistics retrieved successfully + */ +export const zGetAppsByAppIdStatisticsUserSatisfactionRateResponse = z.array( + z.record(z.string(), z.unknown()), +) + +export const zPostAppsByAppIdTextToAudioBody = zTextToSpeechPayload + +export const zPostAppsByAppIdTextToAudioPath = z.object({ + app_id: z.string(), +}) + +/** + * Text to speech conversion successful + */ +export const zPostAppsByAppIdTextToAudioResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdTextToAudioVoicesPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdTextToAudioVoicesQuery = z.object({ + language: z.string(), +}) + +/** + * TTS voices retrieved successfully + */ +export const zGetAppsByAppIdTextToAudioVoicesResponse = z.array(z.record(z.string(), z.unknown())) + +export const zGetAppsByAppIdTracePath = z.object({ + app_id: z.string(), +}) + +/** + * Trace configuration retrieved successfully + */ +export const zGetAppsByAppIdTraceResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdTraceBody = zAppTracePayload + +export const zPostAppsByAppIdTracePath = z.object({ + app_id: z.string(), +}) + +/** + * Trace configuration updated successfully + */ +export const zPostAppsByAppIdTraceResponse = z.record(z.string(), z.unknown()) + +export const zDeleteAppsByAppIdTraceConfigBody = zTraceProviderQuery + +export const zDeleteAppsByAppIdTraceConfigPath = z.object({ + app_id: z.string(), +}) + +/** + * Tracing configuration deleted successfully + */ +export const zDeleteAppsByAppIdTraceConfigResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdTraceConfigPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdTraceConfigQuery = z.object({ + tracing_provider: z.string(), +}) + +/** + * Tracing configuration data + */ +export const zGetAppsByAppIdTraceConfigResponse = z.record(z.string(), z.unknown()) + +export const zPatchAppsByAppIdTraceConfigBody = zTraceConfigPayload + +export const zPatchAppsByAppIdTraceConfigPath = z.object({ + app_id: z.string(), +}) + +/** + * Success response + */ +export const zPatchAppsByAppIdTraceConfigResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdTraceConfigBody = zTraceConfigPayload + +export const zPostAppsByAppIdTraceConfigPath = z.object({ + app_id: z.string(), +}) + +/** + * Created configuration data + */ +export const zPostAppsByAppIdTraceConfigResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdTriggerEnableBody = zParserEnable + +export const zPostAppsByAppIdTriggerEnablePath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zPostAppsByAppIdTriggerEnableResponse = zWorkflowTriggerResponse + +export const zGetAppsByAppIdTriggersPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zGetAppsByAppIdTriggersResponse = zWorkflowTriggerListResponse + +export const zGetAppsByAppIdWorkflowAppLogsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdWorkflowAppLogsQuery = z.object({ + created_at__after: z.iso.datetime().nullish(), + created_at__before: z.iso.datetime().nullish(), + created_by_account: z.string().nullish(), + created_by_end_user_session_id: z.string().nullish(), + detail: z.boolean().optional().default(false), + keyword: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), + page: z.int().gte(1).lte(99999).optional().default(1), + status: z.string().nullish(), +}) + +/** + * Workflow app logs retrieved successfully + */ +export const zGetAppsByAppIdWorkflowAppLogsResponse = zWorkflowAppLogPaginationResponse + +export const zGetAppsByAppIdWorkflowArchivedLogsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdWorkflowArchivedLogsQuery = z.object({ + created_at__after: z.iso.datetime().nullish(), + created_at__before: z.iso.datetime().nullish(), + created_by_account: z.string().nullish(), + created_by_end_user_session_id: z.string().nullish(), + detail: z.boolean().optional().default(false), + keyword: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), + page: z.int().gte(1).lte(99999).optional().default(1), + status: z.string().nullish(), +}) + +/** + * Workflow archived logs retrieved successfully + */ +export const zGetAppsByAppIdWorkflowArchivedLogsResponse = zWorkflowArchivedLogPaginationResponse + +export const zGetAppsByAppIdWorkflowRunsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdWorkflowRunsQuery = z.object({ + triggered_from: z.enum(['debugging', 'app-run']).nullish(), + status: z.enum(['running', 'succeeded', 'failed', 'stopped', 'partial-succeeded']).nullish(), + last_id: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), +}) + +/** + * Workflow runs retrieved successfully + */ +export const zGetAppsByAppIdWorkflowRunsResponse = zWorkflowRunPagination + +export const zGetAppsByAppIdWorkflowRunsCountPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdWorkflowRunsCountQuery = z.object({ + triggered_from: z.enum(['debugging', 'app-run']).nullish(), + time_range: z.string().nullish(), + status: z.enum(['running', 'succeeded', 'failed', 'stopped', 'partial-succeeded']).nullish(), +}) + +/** + * Workflow runs count retrieved successfully + */ +export const zGetAppsByAppIdWorkflowRunsCountResponse = zWorkflowRunCount + +export const zPostAppsByAppIdWorkflowRunsTasksByTaskIdStopPath = z.object({ + app_id: z.string(), + task_id: z.string(), +}) + +/** + * Task stopped successfully + */ +export const zPostAppsByAppIdWorkflowRunsTasksByTaskIdStopResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdWorkflowRunsByRunIdPath = z.object({ + app_id: z.string(), + run_id: z.string(), +}) + +/** + * Workflow run detail retrieved successfully + */ +export const zGetAppsByAppIdWorkflowRunsByRunIdResponse = zWorkflowRunDetail + +export const zGetAppsByAppIdWorkflowRunsByRunIdExportPath = z.object({ + app_id: z.string(), + run_id: z.string(), +}) + +/** + * Export URL generated + */ +export const zGetAppsByAppIdWorkflowRunsByRunIdExportResponse = zWorkflowRunExport + +export const zGetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsPath = z.object({ + app_id: z.string(), + run_id: z.string(), +}) + +/** + * Node executions retrieved successfully + */ +export const zGetAppsByAppIdWorkflowRunsByRunIdNodeExecutionsResponse + = zWorkflowRunNodeExecutionList + +export const zGetAppsByAppIdWorkflowCommentsPath = z.object({ + app_id: z.string(), +}) + +/** + * Comments retrieved successfully + */ +export const zGetAppsByAppIdWorkflowCommentsResponse = zWorkflowCommentBasic + +export const zPostAppsByAppIdWorkflowCommentsBody = zWorkflowCommentCreatePayload + +export const zPostAppsByAppIdWorkflowCommentsPath = z.object({ + app_id: z.string(), +}) + +/** + * Comment created successfully + */ +export const zPostAppsByAppIdWorkflowCommentsResponse = zWorkflowCommentCreate + +export const zGetAppsByAppIdWorkflowCommentsMentionUsersPath = z.object({ + app_id: z.string(), +}) + +/** + * Mentionable users retrieved successfully + */ +export const zGetAppsByAppIdWorkflowCommentsMentionUsersResponse + = zWorkflowCommentMentionUsersPayload + +export const zDeleteAppsByAppIdWorkflowCommentsByCommentIdPath = z.object({ + app_id: z.string(), + comment_id: z.string(), +}) + +/** + * Comment deleted successfully + */ +export const zDeleteAppsByAppIdWorkflowCommentsByCommentIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdWorkflowCommentsByCommentIdPath = z.object({ + app_id: z.string(), + comment_id: z.string(), +}) + +/** + * Comment retrieved successfully + */ +export const zGetAppsByAppIdWorkflowCommentsByCommentIdResponse = zWorkflowCommentDetail + +export const zPutAppsByAppIdWorkflowCommentsByCommentIdBody = zWorkflowCommentUpdatePayload + +export const zPutAppsByAppIdWorkflowCommentsByCommentIdPath = z.object({ + app_id: z.string(), + comment_id: z.string(), +}) + +/** + * Comment updated successfully + */ +export const zPutAppsByAppIdWorkflowCommentsByCommentIdResponse = zWorkflowCommentUpdate + +export const zPostAppsByAppIdWorkflowCommentsByCommentIdRepliesBody = zWorkflowCommentReplyPayload + +export const zPostAppsByAppIdWorkflowCommentsByCommentIdRepliesPath = z.object({ + app_id: z.string(), + comment_id: z.string(), +}) + +/** + * Reply created successfully + */ +export const zPostAppsByAppIdWorkflowCommentsByCommentIdRepliesResponse + = zWorkflowCommentReplyCreate + +export const zDeleteAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdPath = z.object({ + app_id: z.string(), + comment_id: z.string(), + reply_id: z.string(), +}) + +/** + * Reply deleted successfully + */ +export const zDeleteAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdBody + = zWorkflowCommentReplyPayload + +export const zPutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdPath = z.object({ + app_id: z.string(), + comment_id: z.string(), + reply_id: z.string(), +}) + +/** + * Reply updated successfully + */ +export const zPutAppsByAppIdWorkflowCommentsByCommentIdRepliesByReplyIdResponse + = zWorkflowCommentReplyUpdate + +export const zPostAppsByAppIdWorkflowCommentsByCommentIdResolvePath = z.object({ + app_id: z.string(), + comment_id: z.string(), +}) + +/** + * Comment resolved successfully + */ +export const zPostAppsByAppIdWorkflowCommentsByCommentIdResolveResponse = zWorkflowCommentResolve + +export const zGetAppsByAppIdWorkflowStatisticsAverageAppInteractionsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdWorkflowStatisticsAverageAppInteractionsQuery = z.object({ + end: z.string().nullish(), + start: z.string().nullish(), +}) + +/** + * Average app interaction statistics retrieved successfully + */ +export const zGetAppsByAppIdWorkflowStatisticsAverageAppInteractionsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdWorkflowStatisticsDailyConversationsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdWorkflowStatisticsDailyConversationsQuery = z.object({ + end: z.string().nullish(), + start: z.string().nullish(), +}) + +/** + * Daily runs statistics retrieved successfully + */ +export const zGetAppsByAppIdWorkflowStatisticsDailyConversationsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdWorkflowStatisticsDailyTerminalsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdWorkflowStatisticsDailyTerminalsQuery = z.object({ + end: z.string().nullish(), + start: z.string().nullish(), +}) + +/** + * Daily terminals statistics retrieved successfully + */ +export const zGetAppsByAppIdWorkflowStatisticsDailyTerminalsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdWorkflowStatisticsTokenCostsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdWorkflowStatisticsTokenCostsQuery = z.object({ + end: z.string().nullish(), + start: z.string().nullish(), +}) + +/** + * Daily token cost statistics retrieved successfully + */ +export const zGetAppsByAppIdWorkflowStatisticsTokenCostsResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdWorkflowsPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdWorkflowsQuery = z.object({ + limit: z.int().gte(1).lte(100).optional().default(10), + named_only: z.boolean().optional().default(false), + page: z.int().gte(1).lte(99999).optional().default(1), + user_id: z.string().nullish(), +}) + +/** + * Published workflows retrieved successfully + */ +export const zGetAppsByAppIdWorkflowsResponse = zWorkflowPagination + +export const zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsPath = z.object({ + app_id: z.string(), +}) + +/** + * Default block configurations retrieved successfully + */ +export const zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypePath = z.object({ + app_id: z.string(), + block_type: z.string(), +}) + +export const zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeQuery = z.object({ + q: z.string().nullish(), +}) + +/** + * Default block configuration retrieved successfully + */ +export const zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdWorkflowsDraftPath = z.object({ + app_id: z.string(), +}) + +/** + * Draft workflow retrieved successfully + */ +export const zGetAppsByAppIdWorkflowsDraftResponse = zWorkflow + +export const zPostAppsByAppIdWorkflowsDraftBody = zSyncDraftWorkflowPayload + +export const zPostAppsByAppIdWorkflowsDraftPath = z.object({ + app_id: z.string(), +}) + +/** + * Draft workflow synced successfully + */ +export const zPostAppsByAppIdWorkflowsDraftResponse = zSyncDraftWorkflowResponse + +export const zGetAppsByAppIdWorkflowsDraftConversationVariablesPath = z.object({ + app_id: z.string(), +}) + +/** + * Conversation variables retrieved successfully + */ +export const zGetAppsByAppIdWorkflowsDraftConversationVariablesResponse = zWorkflowDraftVariableList + +export const zPostAppsByAppIdWorkflowsDraftConversationVariablesBody + = zConversationVariableUpdatePayload + +export const zPostAppsByAppIdWorkflowsDraftConversationVariablesPath = z.object({ + app_id: z.string(), +}) + +/** + * Conversation variables updated successfully + */ +export const zPostAppsByAppIdWorkflowsDraftConversationVariablesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdWorkflowsDraftEnvironmentVariablesPath = z.object({ + app_id: z.string(), +}) + +/** + * Environment variables retrieved successfully + */ +export const zGetAppsByAppIdWorkflowsDraftEnvironmentVariablesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostAppsByAppIdWorkflowsDraftEnvironmentVariablesBody + = zEnvironmentVariableUpdatePayload + +export const zPostAppsByAppIdWorkflowsDraftEnvironmentVariablesPath = z.object({ + app_id: z.string(), +}) + +/** + * Environment variables updated successfully + */ +export const zPostAppsByAppIdWorkflowsDraftEnvironmentVariablesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostAppsByAppIdWorkflowsDraftFeaturesBody = zWorkflowFeaturesPayload + +export const zPostAppsByAppIdWorkflowsDraftFeaturesPath = z.object({ + app_id: z.string(), +}) + +/** + * Workflow features updated successfully + */ +export const zPostAppsByAppIdWorkflowsDraftFeaturesResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestBody + = zHumanInputDeliveryTestPayload + +export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestPath = z.object({ + app_id: z.string(), + node_id: z.string(), +}) + +/** + * Success + */ +export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewBody + = zHumanInputFormPreviewPayload + +export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewPath = z.object({ + app_id: z.string(), + node_id: z.string(), +}) + +/** + * Success + */ +export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunBody + = zHumanInputFormSubmitPayload + +export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunPath = z.object({ + app_id: z.string(), + node_id: z.string(), +}) + +/** + * Success + */ +export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunBody = zIterationNodeRunPayload + +export const zPostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunPath = z.object({ + app_id: z.string(), + node_id: z.string(), +}) + +/** + * Workflow iteration node run started successfully + */ +export const zPostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunBody = zLoopNodeRunPayload + +export const zPostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunPath = z.object({ + app_id: z.string(), + node_id: z.string(), +}) + +/** + * Workflow loop node run started successfully + */ +export const zPostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunPath = z.object({ + app_id: z.string(), + node_id: z.string(), +}) + +/** + * Node last run retrieved successfully + */ +export const zGetAppsByAppIdWorkflowsDraftNodesByNodeIdLastRunResponse = zWorkflowRunNodeExecution + +export const zPostAppsByAppIdWorkflowsDraftNodesByNodeIdRunBody = zDraftWorkflowNodeRunPayload + +export const zPostAppsByAppIdWorkflowsDraftNodesByNodeIdRunPath = z.object({ + app_id: z.string(), + node_id: z.string(), +}) + +/** + * Node run started successfully + */ +export const zPostAppsByAppIdWorkflowsDraftNodesByNodeIdRunResponse = zWorkflowRunNodeExecution + +export const zPostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunPath = z.object({ + app_id: z.string(), + node_id: z.string(), +}) + +/** + * Trigger event received and node executed successfully + */ +export const zPostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesPath = z.object({ + node_id: z.string(), + app_id: z.string(), +}) + +/** + * Node variables deleted successfully + */ +export const zDeleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesPath = z.object({ + app_id: z.string(), + node_id: z.string(), +}) + +/** + * Node variables retrieved successfully + */ +export const zGetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponse + = zWorkflowDraftVariableList + +export const zPostAppsByAppIdWorkflowsDraftRunBody = zDraftWorkflowRunPayload + +export const zPostAppsByAppIdWorkflowsDraftRunPath = z.object({ + app_id: z.string(), +}) + +/** + * Draft workflow run started successfully + */ +export const zPostAppsByAppIdWorkflowsDraftRunResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdWorkflowsDraftSystemVariablesPath = z.object({ + app_id: z.string(), +}) + +/** + * System variables retrieved successfully + */ +export const zGetAppsByAppIdWorkflowsDraftSystemVariablesResponse = zWorkflowDraftVariableList + +export const zPostAppsByAppIdWorkflowsDraftTriggerRunBody = zDraftWorkflowTriggerRunRequest + +export const zPostAppsByAppIdWorkflowsDraftTriggerRunPath = z.object({ + app_id: z.string(), +}) + +/** + * Trigger event received and workflow executed successfully + */ +export const zPostAppsByAppIdWorkflowsDraftTriggerRunResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsByAppIdWorkflowsDraftTriggerRunAllBody = zDraftWorkflowTriggerRunAllPayload + +export const zPostAppsByAppIdWorkflowsDraftTriggerRunAllPath = z.object({ + app_id: z.string(), +}) + +/** + * Workflow executed successfully + */ +export const zPostAppsByAppIdWorkflowsDraftTriggerRunAllResponse = z.record(z.string(), z.unknown()) + +export const zDeleteAppsByAppIdWorkflowsDraftVariablesPath = z.object({ + app_id: z.string(), +}) + +/** + * Workflow variables deleted successfully + */ +export const zDeleteAppsByAppIdWorkflowsDraftVariablesResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdWorkflowsDraftVariablesPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdWorkflowsDraftVariablesQuery = z.object({ + page: z.int().gte(1).lte(100000).optional().default(1), + limit: z.int().gte(1).lte(100).optional().default(20), +}) + +/** + * Workflow variables retrieved successfully + */ +export const zGetAppsByAppIdWorkflowsDraftVariablesResponse = zWorkflowDraftVariableListWithoutValue + +export const zDeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdPath = z.object({ + variable_id: z.string(), + app_id: z.string(), +}) + +/** + * Variable deleted successfully + */ +export const zDeleteAppsByAppIdWorkflowsDraftVariablesByVariableIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByAppIdWorkflowsDraftVariablesByVariableIdPath = z.object({ + app_id: z.string(), + variable_id: z.string(), +}) + +/** + * Variable retrieved successfully + */ +export const zGetAppsByAppIdWorkflowsDraftVariablesByVariableIdResponse = zWorkflowDraftVariable + +export const zPatchAppsByAppIdWorkflowsDraftVariablesByVariableIdBody + = zWorkflowDraftVariableUpdatePayload + +export const zPatchAppsByAppIdWorkflowsDraftVariablesByVariableIdPath = z.object({ + variable_id: z.string(), + app_id: z.string(), +}) + +/** + * Variable updated successfully + */ +export const zPatchAppsByAppIdWorkflowsDraftVariablesByVariableIdResponse = zWorkflowDraftVariable + +export const zPutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetPath = z.object({ + app_id: z.string(), + variable_id: z.string(), +}) + +export const zPutAppsByAppIdWorkflowsDraftVariablesByVariableIdResetResponse = z.union([ + zWorkflowDraftVariable, + z.record(z.string(), z.unknown()), +]) + +export const zGetAppsByAppIdWorkflowsPublishPath = z.object({ + app_id: z.string(), +}) + +/** + * Published workflow retrieved successfully + */ +export const zGetAppsByAppIdWorkflowsPublishResponse = zWorkflow + +export const zPostAppsByAppIdWorkflowsPublishBody = zPublishWorkflowPayload + +export const zPostAppsByAppIdWorkflowsPublishPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zPostAppsByAppIdWorkflowsPublishResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByAppIdWorkflowsTriggersWebhookPath = z.object({ + app_id: z.string(), +}) + +export const zGetAppsByAppIdWorkflowsTriggersWebhookQuery = z.object({ + credential_id: z.string().nullish(), + datasource_type: z.string(), + inputs: z.string(), +}) + +/** + * Success + */ +export const zGetAppsByAppIdWorkflowsTriggersWebhookResponse = zWebhookTriggerResponse + +export const zDeleteAppsByAppIdWorkflowsByWorkflowIdPath = z.object({ + workflow_id: z.string(), + app_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteAppsByAppIdWorkflowsByWorkflowIdResponse = z.record(z.string(), z.unknown()) + +export const zPatchAppsByAppIdWorkflowsByWorkflowIdBody = zWorkflowUpdatePayload + +export const zPatchAppsByAppIdWorkflowsByWorkflowIdPath = z.object({ + app_id: z.string(), + workflow_id: z.string(), +}) + +/** + * Workflow updated successfully + */ +export const zPatchAppsByAppIdWorkflowsByWorkflowIdResponse = zWorkflow + +export const zPostAppsByAppIdWorkflowsByWorkflowIdRestorePath = z.object({ + app_id: z.string(), + workflow_id: z.string(), +}) + +/** + * Workflow restored successfully + */ +export const zPostAppsByAppIdWorkflowsByWorkflowIdRestoreResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetAppsByResourceIdApiKeysPath = z.object({ + resource_id: z.string(), +}) + +/** + * API keys retrieved successfully + */ +export const zGetAppsByResourceIdApiKeysResponse = zApiKeyList + +export const zPostAppsByResourceIdApiKeysPath = z.object({ + resource_id: z.string(), +}) + +/** + * API key created successfully + */ +export const zPostAppsByResourceIdApiKeysResponse = zApiKeyItem + +export const zDeleteAppsByResourceIdApiKeysByApiKeyIdPath = z.object({ + resource_id: z.string(), + api_key_id: z.string(), +}) + +/** + * API key deleted successfully + */ +export const zDeleteAppsByResourceIdApiKeysByApiKeyIdResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsByServerIdServerRefreshPath = z.object({ + server_id: z.string(), +}) + +/** + * MCP server refreshed successfully + */ +export const zGetAppsByServerIdServerRefreshResponse = zAppMcpServerResponse diff --git a/packages/contracts/generated/api/console/auth/orpc.gen.ts b/packages/contracts/generated/api/console/auth/orpc.gen.ts new file mode 100644 index 0000000000..7a95a96f10 --- /dev/null +++ b/packages/contracts/generated/api/console/auth/orpc.gen.ts @@ -0,0 +1,226 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteAuthPluginDatasourceByProviderIdCustomClientPath, + zDeleteAuthPluginDatasourceByProviderIdCustomClientResponse, + zGetAuthPluginDatasourceByProviderIdPath, + zGetAuthPluginDatasourceByProviderIdResponse, + zGetAuthPluginDatasourceDefaultListResponse, + zGetAuthPluginDatasourceListResponse, + zPostAuthPluginDatasourceByProviderIdBody, + zPostAuthPluginDatasourceByProviderIdCustomClientBody, + zPostAuthPluginDatasourceByProviderIdCustomClientPath, + zPostAuthPluginDatasourceByProviderIdCustomClientResponse, + zPostAuthPluginDatasourceByProviderIdDefaultBody, + zPostAuthPluginDatasourceByProviderIdDefaultPath, + zPostAuthPluginDatasourceByProviderIdDefaultResponse, + zPostAuthPluginDatasourceByProviderIdDeleteBody, + zPostAuthPluginDatasourceByProviderIdDeletePath, + zPostAuthPluginDatasourceByProviderIdDeleteResponse, + zPostAuthPluginDatasourceByProviderIdPath, + zPostAuthPluginDatasourceByProviderIdResponse, + zPostAuthPluginDatasourceByProviderIdUpdateBody, + zPostAuthPluginDatasourceByProviderIdUpdateNameBody, + zPostAuthPluginDatasourceByProviderIdUpdateNamePath, + zPostAuthPluginDatasourceByProviderIdUpdateNameResponse, + zPostAuthPluginDatasourceByProviderIdUpdatePath, + zPostAuthPluginDatasourceByProviderIdUpdateResponse, +} from './zod.gen' + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAuthPluginDatasourceDefaultList', + path: '/auth/plugin/datasource/default-list', + tags: ['console'], + }) + .output(zGetAuthPluginDatasourceDefaultListResponse) + +export const defaultList = { + get, +} + +export const get2 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAuthPluginDatasourceList', + path: '/auth/plugin/datasource/list', + tags: ['console'], + }) + .output(zGetAuthPluginDatasourceListResponse) + +export const list = { + get: get2, +} + +export const delete_ = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAuthPluginDatasourceByProviderIdCustomClient', + path: '/auth/plugin/datasource/{provider_id}/custom-client', + tags: ['console'], + }) + .input(z.object({ params: zDeleteAuthPluginDatasourceByProviderIdCustomClientPath })) + .output(zDeleteAuthPluginDatasourceByProviderIdCustomClientResponse) + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAuthPluginDatasourceByProviderIdCustomClient', + path: '/auth/plugin/datasource/{provider_id}/custom-client', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAuthPluginDatasourceByProviderIdCustomClientBody, + params: zPostAuthPluginDatasourceByProviderIdCustomClientPath, + }), + ) + .output(zPostAuthPluginDatasourceByProviderIdCustomClientResponse) + +export const customClient = { + delete: delete_, + post, +} + +export const post2 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAuthPluginDatasourceByProviderIdDefault', + path: '/auth/plugin/datasource/{provider_id}/default', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAuthPluginDatasourceByProviderIdDefaultBody, + params: zPostAuthPluginDatasourceByProviderIdDefaultPath, + }), + ) + .output(zPostAuthPluginDatasourceByProviderIdDefaultResponse) + +export const default_ = { + post: post2, +} + +export const post3 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAuthPluginDatasourceByProviderIdDelete', + path: '/auth/plugin/datasource/{provider_id}/delete', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAuthPluginDatasourceByProviderIdDeleteBody, + params: zPostAuthPluginDatasourceByProviderIdDeletePath, + }), + ) + .output(zPostAuthPluginDatasourceByProviderIdDeleteResponse) + +export const delete2 = { + post: post3, +} + +export const post4 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAuthPluginDatasourceByProviderIdUpdate', + path: '/auth/plugin/datasource/{provider_id}/update', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAuthPluginDatasourceByProviderIdUpdateBody, + params: zPostAuthPluginDatasourceByProviderIdUpdatePath, + }), + ) + .output(zPostAuthPluginDatasourceByProviderIdUpdateResponse) + +export const update = { + post: post4, +} + +export const post5 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAuthPluginDatasourceByProviderIdUpdateName', + path: '/auth/plugin/datasource/{provider_id}/update-name', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAuthPluginDatasourceByProviderIdUpdateNameBody, + params: zPostAuthPluginDatasourceByProviderIdUpdateNamePath, + }), + ) + .output(zPostAuthPluginDatasourceByProviderIdUpdateNameResponse) + +export const updateName = { + post: post5, +} + +export const get3 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAuthPluginDatasourceByProviderId', + path: '/auth/plugin/datasource/{provider_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetAuthPluginDatasourceByProviderIdPath })) + .output(zGetAuthPluginDatasourceByProviderIdResponse) + +export const post6 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAuthPluginDatasourceByProviderId', + path: '/auth/plugin/datasource/{provider_id}', + tags: ['console'], + }) + .input( + z.object({ + body: zPostAuthPluginDatasourceByProviderIdBody, + params: zPostAuthPluginDatasourceByProviderIdPath, + }), + ) + .output(zPostAuthPluginDatasourceByProviderIdResponse) + +export const byProviderId = { + get: get3, + post: post6, + customClient, + default: default_, + delete: delete2, + update, + updateName, +} + +export const datasource = { + defaultList, + list, + byProviderId, +} + +export const plugin = { + datasource, +} + +export const auth = { + plugin, +} + +export const contract = { + auth, +} diff --git a/packages/contracts/generated/api/console/auth/types.gen.ts b/packages/contracts/generated/api/console/auth/types.gen.ts new file mode 100644 index 0000000000..1a974f626b --- /dev/null +++ b/packages/contracts/generated/api/console/auth/types.gen.ts @@ -0,0 +1,216 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type DatasourceCredentialPayload = { + credentials: { + [key: string]: unknown + } + name?: string | null +} + +export type DatasourceCustomClientPayload = { + client_params?: { + [key: string]: unknown + } | null + enable_oauth_custom_client?: boolean | null +} + +export type DatasourceDefaultPayload = { + id: string +} + +export type DatasourceCredentialDeletePayload = { + credential_id: string +} + +export type DatasourceCredentialUpdatePayload = { + credential_id: string + credentials?: { + [key: string]: unknown + } | null + name?: string | null +} + +export type DatasourceUpdateNamePayload = { + credential_id: string + name: string +} + +export type GetAuthPluginDatasourceDefaultListData = { + body?: never + path?: never + query?: never + url: '/auth/plugin/datasource/default-list' +} + +export type GetAuthPluginDatasourceDefaultListResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAuthPluginDatasourceDefaultListResponse + = GetAuthPluginDatasourceDefaultListResponses[keyof GetAuthPluginDatasourceDefaultListResponses] + +export type GetAuthPluginDatasourceListData = { + body?: never + path?: never + query?: never + url: '/auth/plugin/datasource/list' +} + +export type GetAuthPluginDatasourceListResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAuthPluginDatasourceListResponse + = GetAuthPluginDatasourceListResponses[keyof GetAuthPluginDatasourceListResponses] + +export type GetAuthPluginDatasourceByProviderIdData = { + body?: never + path: { + provider_id: string + } + query?: never + url: '/auth/plugin/datasource/{provider_id}' +} + +export type GetAuthPluginDatasourceByProviderIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAuthPluginDatasourceByProviderIdResponse + = GetAuthPluginDatasourceByProviderIdResponses[keyof GetAuthPluginDatasourceByProviderIdResponses] + +export type PostAuthPluginDatasourceByProviderIdData = { + body: DatasourceCredentialPayload + path: { + provider_id: string + } + query?: never + url: '/auth/plugin/datasource/{provider_id}' +} + +export type PostAuthPluginDatasourceByProviderIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAuthPluginDatasourceByProviderIdResponse + = PostAuthPluginDatasourceByProviderIdResponses[keyof PostAuthPluginDatasourceByProviderIdResponses] + +export type DeleteAuthPluginDatasourceByProviderIdCustomClientData = { + body?: never + path: { + provider_id: string + } + query?: never + url: '/auth/plugin/datasource/{provider_id}/custom-client' +} + +export type DeleteAuthPluginDatasourceByProviderIdCustomClientResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteAuthPluginDatasourceByProviderIdCustomClientResponse + = DeleteAuthPluginDatasourceByProviderIdCustomClientResponses[keyof DeleteAuthPluginDatasourceByProviderIdCustomClientResponses] + +export type PostAuthPluginDatasourceByProviderIdCustomClientData = { + body: DatasourceCustomClientPayload + path: { + provider_id: string + } + query?: never + url: '/auth/plugin/datasource/{provider_id}/custom-client' +} + +export type PostAuthPluginDatasourceByProviderIdCustomClientResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAuthPluginDatasourceByProviderIdCustomClientResponse + = PostAuthPluginDatasourceByProviderIdCustomClientResponses[keyof PostAuthPluginDatasourceByProviderIdCustomClientResponses] + +export type PostAuthPluginDatasourceByProviderIdDefaultData = { + body: DatasourceDefaultPayload + path: { + provider_id: string + } + query?: never + url: '/auth/plugin/datasource/{provider_id}/default' +} + +export type PostAuthPluginDatasourceByProviderIdDefaultResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAuthPluginDatasourceByProviderIdDefaultResponse + = PostAuthPluginDatasourceByProviderIdDefaultResponses[keyof PostAuthPluginDatasourceByProviderIdDefaultResponses] + +export type PostAuthPluginDatasourceByProviderIdDeleteData = { + body: DatasourceCredentialDeletePayload + path: { + provider_id: string + } + query?: never + url: '/auth/plugin/datasource/{provider_id}/delete' +} + +export type PostAuthPluginDatasourceByProviderIdDeleteResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAuthPluginDatasourceByProviderIdDeleteResponse + = PostAuthPluginDatasourceByProviderIdDeleteResponses[keyof PostAuthPluginDatasourceByProviderIdDeleteResponses] + +export type PostAuthPluginDatasourceByProviderIdUpdateData = { + body: DatasourceCredentialUpdatePayload + path: { + provider_id: string + } + query?: never + url: '/auth/plugin/datasource/{provider_id}/update' +} + +export type PostAuthPluginDatasourceByProviderIdUpdateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAuthPluginDatasourceByProviderIdUpdateResponse + = PostAuthPluginDatasourceByProviderIdUpdateResponses[keyof PostAuthPluginDatasourceByProviderIdUpdateResponses] + +export type PostAuthPluginDatasourceByProviderIdUpdateNameData = { + body: DatasourceUpdateNamePayload + path: { + provider_id: string + } + query?: never + url: '/auth/plugin/datasource/{provider_id}/update-name' +} + +export type PostAuthPluginDatasourceByProviderIdUpdateNameResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAuthPluginDatasourceByProviderIdUpdateNameResponse + = PostAuthPluginDatasourceByProviderIdUpdateNameResponses[keyof PostAuthPluginDatasourceByProviderIdUpdateNameResponses] diff --git a/packages/contracts/generated/api/console/auth/zod.gen.ts b/packages/contracts/generated/api/console/auth/zod.gen.ts new file mode 100644 index 0000000000..3d183e09cd --- /dev/null +++ b/packages/contracts/generated/api/console/auth/zod.gen.ts @@ -0,0 +1,156 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * DatasourceCredentialPayload + */ +export const zDatasourceCredentialPayload = z.object({ + credentials: z.record(z.string(), z.unknown()), + name: z.string().max(100).nullish(), +}) + +/** + * DatasourceCustomClientPayload + */ +export const zDatasourceCustomClientPayload = z.object({ + client_params: z.record(z.string(), z.unknown()).nullish(), + enable_oauth_custom_client: z.boolean().nullish(), +}) + +/** + * DatasourceDefaultPayload + */ +export const zDatasourceDefaultPayload = z.object({ + id: z.string(), +}) + +/** + * DatasourceCredentialDeletePayload + */ +export const zDatasourceCredentialDeletePayload = z.object({ + credential_id: z.string(), +}) + +/** + * DatasourceCredentialUpdatePayload + */ +export const zDatasourceCredentialUpdatePayload = z.object({ + credential_id: z.string(), + credentials: z.record(z.string(), z.unknown()).nullish(), + name: z.string().max(100).nullish(), +}) + +/** + * DatasourceUpdateNamePayload + */ +export const zDatasourceUpdateNamePayload = z.object({ + credential_id: z.string(), + name: z.string().max(100), +}) + +/** + * Success + */ +export const zGetAuthPluginDatasourceDefaultListResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetAuthPluginDatasourceListResponse = z.record(z.string(), z.unknown()) + +export const zGetAuthPluginDatasourceByProviderIdPath = z.object({ + provider_id: z.string(), +}) + +/** + * Success + */ +export const zGetAuthPluginDatasourceByProviderIdResponse = z.record(z.string(), z.unknown()) + +export const zPostAuthPluginDatasourceByProviderIdBody = zDatasourceCredentialPayload + +export const zPostAuthPluginDatasourceByProviderIdPath = z.object({ + provider_id: z.string(), +}) + +/** + * Success + */ +export const zPostAuthPluginDatasourceByProviderIdResponse = z.record(z.string(), z.unknown()) + +export const zDeleteAuthPluginDatasourceByProviderIdCustomClientPath = z.object({ + provider_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteAuthPluginDatasourceByProviderIdCustomClientResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostAuthPluginDatasourceByProviderIdCustomClientBody = zDatasourceCustomClientPayload + +export const zPostAuthPluginDatasourceByProviderIdCustomClientPath = z.object({ + provider_id: z.string(), +}) + +/** + * Success + */ +export const zPostAuthPluginDatasourceByProviderIdCustomClientResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostAuthPluginDatasourceByProviderIdDefaultBody = zDatasourceDefaultPayload + +export const zPostAuthPluginDatasourceByProviderIdDefaultPath = z.object({ + provider_id: z.string(), +}) + +/** + * Success + */ +export const zPostAuthPluginDatasourceByProviderIdDefaultResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostAuthPluginDatasourceByProviderIdDeleteBody = zDatasourceCredentialDeletePayload + +export const zPostAuthPluginDatasourceByProviderIdDeletePath = z.object({ + provider_id: z.string(), +}) + +/** + * Success + */ +export const zPostAuthPluginDatasourceByProviderIdDeleteResponse = z.record(z.string(), z.unknown()) + +export const zPostAuthPluginDatasourceByProviderIdUpdateBody = zDatasourceCredentialUpdatePayload + +export const zPostAuthPluginDatasourceByProviderIdUpdatePath = z.object({ + provider_id: z.string(), +}) + +/** + * Success + */ +export const zPostAuthPluginDatasourceByProviderIdUpdateResponse = z.record(z.string(), z.unknown()) + +export const zPostAuthPluginDatasourceByProviderIdUpdateNameBody = zDatasourceUpdateNamePayload + +export const zPostAuthPluginDatasourceByProviderIdUpdateNamePath = z.object({ + provider_id: z.string(), +}) + +/** + * Success + */ +export const zPostAuthPluginDatasourceByProviderIdUpdateNameResponse = z.record( + z.string(), + z.unknown(), +) diff --git a/packages/contracts/generated/api/console/billing/orpc.gen.ts b/packages/contracts/generated/api/console/billing/orpc.gen.ts new file mode 100644 index 0000000000..09d25c072e --- /dev/null +++ b/packages/contracts/generated/api/console/billing/orpc.gen.ts @@ -0,0 +1,82 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetBillingInvoicesResponse, + zGetBillingSubscriptionResponse, + zPutBillingPartnersByPartnerKeyTenantsBody, + zPutBillingPartnersByPartnerKeyTenantsPath, + zPutBillingPartnersByPartnerKeyTenantsResponse, +} from './zod.gen' + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getBillingInvoices', + path: '/billing/invoices', + tags: ['console'], + }) + .output(zGetBillingInvoicesResponse) + +export const invoices = { + get, +} + +/** + * Sync partner tenants bindings + */ +export const put = oc + .route({ + description: 'Sync partner tenants bindings', + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putBillingPartnersByPartnerKeyTenants', + path: '/billing/partners/{partner_key}/tenants', + tags: ['console'], + }) + .input( + z.object({ + body: zPutBillingPartnersByPartnerKeyTenantsBody, + params: zPutBillingPartnersByPartnerKeyTenantsPath, + }), + ) + .output(zPutBillingPartnersByPartnerKeyTenantsResponse) + +export const tenants = { + put, +} + +export const byPartnerKey = { + tenants, +} + +export const partners = { + byPartnerKey, +} + +export const get2 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getBillingSubscription', + path: '/billing/subscription', + tags: ['console'], + }) + .output(zGetBillingSubscriptionResponse) + +export const subscription = { + get: get2, +} + +export const billing = { + invoices, + partners, + subscription, +} + +export const contract = { + billing, +} diff --git a/packages/contracts/generated/api/console/billing/types.gen.ts b/packages/contracts/generated/api/console/billing/types.gen.ts new file mode 100644 index 0000000000..7a9880c03e --- /dev/null +++ b/packages/contracts/generated/api/console/billing/types.gen.ts @@ -0,0 +1,68 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type PartnerTenantsPayload = { + click_id: string +} + +export type GetBillingInvoicesData = { + body?: never + path?: never + query?: never + url: '/billing/invoices' +} + +export type GetBillingInvoicesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetBillingInvoicesResponse + = GetBillingInvoicesResponses[keyof GetBillingInvoicesResponses] + +export type PutBillingPartnersByPartnerKeyTenantsData = { + body: PartnerTenantsPayload + path: { + partner_key: string + } + query?: never + url: '/billing/partners/{partner_key}/tenants' +} + +export type PutBillingPartnersByPartnerKeyTenantsErrors = { + 400: { + [key: string]: unknown + } +} + +export type PutBillingPartnersByPartnerKeyTenantsError + = PutBillingPartnersByPartnerKeyTenantsErrors[keyof PutBillingPartnersByPartnerKeyTenantsErrors] + +export type PutBillingPartnersByPartnerKeyTenantsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PutBillingPartnersByPartnerKeyTenantsResponse + = PutBillingPartnersByPartnerKeyTenantsResponses[keyof PutBillingPartnersByPartnerKeyTenantsResponses] + +export type GetBillingSubscriptionData = { + body?: never + path?: never + query?: never + url: '/billing/subscription' +} + +export type GetBillingSubscriptionResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetBillingSubscriptionResponse + = GetBillingSubscriptionResponses[keyof GetBillingSubscriptionResponses] diff --git a/packages/contracts/generated/api/console/billing/zod.gen.ts b/packages/contracts/generated/api/console/billing/zod.gen.ts new file mode 100644 index 0000000000..7b5412c7f4 --- /dev/null +++ b/packages/contracts/generated/api/console/billing/zod.gen.ts @@ -0,0 +1,31 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * PartnerTenantsPayload + */ +export const zPartnerTenantsPayload = z.object({ + click_id: z.string(), +}) + +/** + * Success + */ +export const zGetBillingInvoicesResponse = z.record(z.string(), z.unknown()) + +export const zPutBillingPartnersByPartnerKeyTenantsBody = zPartnerTenantsPayload + +export const zPutBillingPartnersByPartnerKeyTenantsPath = z.object({ + partner_key: z.string(), +}) + +/** + * Tenants synced to partner successfully + */ +export const zPutBillingPartnersByPartnerKeyTenantsResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetBillingSubscriptionResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/code-based-extension/orpc.gen.ts b/packages/contracts/generated/api/console/code-based-extension/orpc.gen.ts new file mode 100644 index 0000000000..b3baddafd4 --- /dev/null +++ b/packages/contracts/generated/api/console/code-based-extension/orpc.gen.ts @@ -0,0 +1,29 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { zGetCodeBasedExtensionQuery, zGetCodeBasedExtensionResponse } from './zod.gen' + +/** + * Get code-based extension data by module name + */ +export const get = oc + .route({ + description: 'Get code-based extension data by module name', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getCodeBasedExtension', + path: '/code-based-extension', + tags: ['console'], + }) + .input(z.object({ query: zGetCodeBasedExtensionQuery.optional() })) + .output(zGetCodeBasedExtensionResponse) + +export const codeBasedExtension = { + get, +} + +export const contract = { + codeBasedExtension, +} diff --git a/packages/contracts/generated/api/console/code-based-extension/types.gen.ts b/packages/contracts/generated/api/console/code-based-extension/types.gen.ts new file mode 100644 index 0000000000..85d224f8d1 --- /dev/null +++ b/packages/contracts/generated/api/console/code-based-extension/types.gen.ts @@ -0,0 +1,26 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type CodeBasedExtensionResponse = { + data: unknown + module: string +} + +export type GetCodeBasedExtensionData = { + body?: never + path?: never + query?: { + module?: string + } + url: '/code-based-extension' +} + +export type GetCodeBasedExtensionResponses = { + 200: CodeBasedExtensionResponse +} + +export type GetCodeBasedExtensionResponse + = GetCodeBasedExtensionResponses[keyof GetCodeBasedExtensionResponses] diff --git a/packages/contracts/generated/api/console/code-based-extension/zod.gen.ts b/packages/contracts/generated/api/console/code-based-extension/zod.gen.ts new file mode 100644 index 0000000000..3cd520cb97 --- /dev/null +++ b/packages/contracts/generated/api/console/code-based-extension/zod.gen.ts @@ -0,0 +1,20 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * CodeBasedExtensionResponse + */ +export const zCodeBasedExtensionResponse = z.object({ + data: z.unknown(), + module: z.string(), +}) + +export const zGetCodeBasedExtensionQuery = z.object({ + module: z.string().optional(), +}) + +/** + * Success + */ +export const zGetCodeBasedExtensionResponse = zCodeBasedExtensionResponse diff --git a/packages/contracts/generated/api/console/compliance/orpc.gen.ts b/packages/contracts/generated/api/console/compliance/orpc.gen.ts new file mode 100644 index 0000000000..e68c87e7eb --- /dev/null +++ b/packages/contracts/generated/api/console/compliance/orpc.gen.ts @@ -0,0 +1,33 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { zGetComplianceDownloadQuery, zGetComplianceDownloadResponse } from './zod.gen' + +/** + * Get compliance document download link + */ +export const get = oc + .route({ + description: 'Get compliance document download link', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getComplianceDownload', + path: '/compliance/download', + tags: ['console'], + }) + .input(z.object({ query: zGetComplianceDownloadQuery })) + .output(zGetComplianceDownloadResponse) + +export const download = { + get, +} + +export const compliance = { + download, +} + +export const contract = { + compliance, +} diff --git a/packages/contracts/generated/api/console/compliance/types.gen.ts b/packages/contracts/generated/api/console/compliance/types.gen.ts new file mode 100644 index 0000000000..12ab2a82a8 --- /dev/null +++ b/packages/contracts/generated/api/console/compliance/types.gen.ts @@ -0,0 +1,23 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type GetComplianceDownloadData = { + body?: never + path?: never + query: { + doc_name: string + } + url: '/compliance/download' +} + +export type GetComplianceDownloadResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetComplianceDownloadResponse + = GetComplianceDownloadResponses[keyof GetComplianceDownloadResponses] diff --git a/packages/contracts/generated/api/console/compliance/zod.gen.ts b/packages/contracts/generated/api/console/compliance/zod.gen.ts new file mode 100644 index 0000000000..2d42e75fbc --- /dev/null +++ b/packages/contracts/generated/api/console/compliance/zod.gen.ts @@ -0,0 +1,12 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +export const zGetComplianceDownloadQuery = z.object({ + doc_name: z.string(), +}) + +/** + * Success + */ +export const zGetComplianceDownloadResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/data-source/orpc.gen.ts b/packages/contracts/generated/api/console/data-source/orpc.gen.ts new file mode 100644 index 0000000000..209447236a --- /dev/null +++ b/packages/contracts/generated/api/console/data-source/orpc.gen.ts @@ -0,0 +1,78 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetDataSourceIntegratesByBindingIdByActionPath, + zGetDataSourceIntegratesByBindingIdByActionResponse, + zGetDataSourceIntegratesResponse, + zPatchDataSourceIntegratesByBindingIdByActionPath, + zPatchDataSourceIntegratesByBindingIdByActionResponse, + zPatchDataSourceIntegratesResponse, +} from './zod.gen' + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDataSourceIntegratesByBindingIdByAction', + path: '/data-source/integrates/{binding_id}/{action}', + tags: ['console'], + }) + .input(z.object({ params: zGetDataSourceIntegratesByBindingIdByActionPath })) + .output(zGetDataSourceIntegratesByBindingIdByActionResponse) + +export const patch = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDataSourceIntegratesByBindingIdByAction', + path: '/data-source/integrates/{binding_id}/{action}', + tags: ['console'], + }) + .input(z.object({ params: zPatchDataSourceIntegratesByBindingIdByActionPath })) + .output(zPatchDataSourceIntegratesByBindingIdByActionResponse) + +export const byAction = { + get, + patch, +} + +export const byBindingId = { + byAction, +} + +export const get2 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDataSourceIntegrates', + path: '/data-source/integrates', + tags: ['console'], + }) + .output(zGetDataSourceIntegratesResponse) + +export const patch2 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDataSourceIntegrates', + path: '/data-source/integrates', + tags: ['console'], + }) + .output(zPatchDataSourceIntegratesResponse) + +export const integrates = { + get: get2, + patch: patch2, + byBindingId, +} + +export const dataSource = { + integrates, +} + +export const contract = { + dataSource, +} diff --git a/packages/contracts/generated/api/console/data-source/types.gen.ts b/packages/contracts/generated/api/console/data-source/types.gen.ts new file mode 100644 index 0000000000..db83d81ec1 --- /dev/null +++ b/packages/contracts/generated/api/console/data-source/types.gen.ts @@ -0,0 +1,75 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type GetDataSourceIntegratesData = { + body?: never + path?: never + query?: never + url: '/data-source/integrates' +} + +export type GetDataSourceIntegratesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDataSourceIntegratesResponse + = GetDataSourceIntegratesResponses[keyof GetDataSourceIntegratesResponses] + +export type PatchDataSourceIntegratesData = { + body?: never + path?: never + query?: never + url: '/data-source/integrates' +} + +export type PatchDataSourceIntegratesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDataSourceIntegratesResponse + = PatchDataSourceIntegratesResponses[keyof PatchDataSourceIntegratesResponses] + +export type GetDataSourceIntegratesByBindingIdByActionData = { + body?: never + path: { + binding_id: string + action: string + } + query?: never + url: '/data-source/integrates/{binding_id}/{action}' +} + +export type GetDataSourceIntegratesByBindingIdByActionResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDataSourceIntegratesByBindingIdByActionResponse + = GetDataSourceIntegratesByBindingIdByActionResponses[keyof GetDataSourceIntegratesByBindingIdByActionResponses] + +export type PatchDataSourceIntegratesByBindingIdByActionData = { + body?: never + path: { + binding_id: string + action: string + } + query?: never + url: '/data-source/integrates/{binding_id}/{action}' +} + +export type PatchDataSourceIntegratesByBindingIdByActionResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDataSourceIntegratesByBindingIdByActionResponse + = PatchDataSourceIntegratesByBindingIdByActionResponses[keyof PatchDataSourceIntegratesByBindingIdByActionResponses] diff --git a/packages/contracts/generated/api/console/data-source/zod.gen.ts b/packages/contracts/generated/api/console/data-source/zod.gen.ts new file mode 100644 index 0000000000..1684b7e637 --- /dev/null +++ b/packages/contracts/generated/api/console/data-source/zod.gen.ts @@ -0,0 +1,36 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * Success + */ +export const zGetDataSourceIntegratesResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPatchDataSourceIntegratesResponse = z.record(z.string(), z.unknown()) + +export const zGetDataSourceIntegratesByBindingIdByActionPath = z.object({ + binding_id: z.string(), + action: z.string(), +}) + +/** + * Success + */ +export const zGetDataSourceIntegratesByBindingIdByActionResponse = z.record(z.string(), z.unknown()) + +export const zPatchDataSourceIntegratesByBindingIdByActionPath = z.object({ + binding_id: z.string(), + action: z.string(), +}) + +/** + * Success + */ +export const zPatchDataSourceIntegratesByBindingIdByActionResponse = z.record( + z.string(), + z.unknown(), +) diff --git a/packages/contracts/generated/api/console/datasets/orpc.gen.ts b/packages/contracts/generated/api/console/datasets/orpc.gen.ts new file mode 100644 index 0000000000..37a0b7cb8c --- /dev/null +++ b/packages/contracts/generated/api/console/datasets/orpc.gen.ts @@ -0,0 +1,1786 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteDatasetsApiKeysByApiKeyIdPath, + zDeleteDatasetsApiKeysByApiKeyIdResponse, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdPath, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdPath, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse, + zDeleteDatasetsByDatasetIdDocumentsPath, + zDeleteDatasetsByDatasetIdDocumentsResponse, + zDeleteDatasetsByDatasetIdMetadataByMetadataIdPath, + zDeleteDatasetsByDatasetIdMetadataByMetadataIdResponse, + zDeleteDatasetsByDatasetIdPath, + zDeleteDatasetsByDatasetIdResponse, + zDeleteDatasetsByResourceIdApiKeysByApiKeyIdPath, + zDeleteDatasetsByResourceIdApiKeysByApiKeyIdResponse, + zDeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdPath, + zDeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse, + zGetDatasetsApiBaseInfoResponse, + zGetDatasetsApiKeysResponse, + zGetDatasetsBatchImportStatusByJobIdPath, + zGetDatasetsBatchImportStatusByJobIdResponse, + zGetDatasetsByDatasetIdAutoDisableLogsPath, + zGetDatasetsByDatasetIdAutoDisableLogsResponse, + zGetDatasetsByDatasetIdBatchByBatchIndexingEstimatePath, + zGetDatasetsByDatasetIdBatchByBatchIndexingEstimateResponse, + zGetDatasetsByDatasetIdBatchByBatchIndexingStatusPath, + zGetDatasetsByDatasetIdBatchByBatchIndexingStatusResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdDownloadPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimatePath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimateResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdNotionSyncPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdNotionSyncResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdPipelineExecutionLogPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdPipelineExecutionLogResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdQuery, + zGetDatasetsByDatasetIdDocumentsByDocumentIdResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdWebsiteSyncPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdWebsiteSyncResponse, + zGetDatasetsByDatasetIdDocumentsPath, + zGetDatasetsByDatasetIdDocumentsQuery, + zGetDatasetsByDatasetIdDocumentsResponse, + zGetDatasetsByDatasetIdErrorDocsPath, + zGetDatasetsByDatasetIdErrorDocsResponse, + zGetDatasetsByDatasetIdIndexingStatusPath, + zGetDatasetsByDatasetIdIndexingStatusResponse, + zGetDatasetsByDatasetIdMetadataPath, + zGetDatasetsByDatasetIdMetadataResponse, + zGetDatasetsByDatasetIdNotionSyncPath, + zGetDatasetsByDatasetIdNotionSyncResponse, + zGetDatasetsByDatasetIdPath, + zGetDatasetsByDatasetIdPermissionPartUsersPath, + zGetDatasetsByDatasetIdPermissionPartUsersResponse, + zGetDatasetsByDatasetIdQueriesPath, + zGetDatasetsByDatasetIdQueriesResponse, + zGetDatasetsByDatasetIdRelatedAppsPath, + zGetDatasetsByDatasetIdRelatedAppsResponse, + zGetDatasetsByDatasetIdResponse, + zGetDatasetsByDatasetIdUseCheckPath, + zGetDatasetsByDatasetIdUseCheckResponse, + zGetDatasetsByResourceIdApiKeysPath, + zGetDatasetsByResourceIdApiKeysResponse, + zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdPath, + zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse, + zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdUseCheckPath, + zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdUseCheckResponse, + zGetDatasetsExternalKnowledgeApiQuery, + zGetDatasetsExternalKnowledgeApiResponse, + zGetDatasetsMetadataBuiltInResponse, + zGetDatasetsNotionIndexingEstimateResponse, + zGetDatasetsProcessRuleQuery, + zGetDatasetsProcessRuleResponse, + zGetDatasetsQuery, + zGetDatasetsResponse, + zGetDatasetsRetrievalSettingByVectorTypePath, + zGetDatasetsRetrievalSettingByVectorTypeResponse, + zGetDatasetsRetrievalSettingResponse, + zPatchDatasetsByDatasetIdBody, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionPath, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionResponse, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPausePath, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseResponse, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumePath, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeResponse, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentByActionPath, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentByActionResponse, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdBody, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdBody, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdPath, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse, + zPatchDatasetsByDatasetIdDocumentsStatusByActionBatchPath, + zPatchDatasetsByDatasetIdDocumentsStatusByActionBatchResponse, + zPatchDatasetsByDatasetIdMetadataByMetadataIdBody, + zPatchDatasetsByDatasetIdMetadataByMetadataIdPath, + zPatchDatasetsByDatasetIdMetadataByMetadataIdResponse, + zPatchDatasetsByDatasetIdPath, + zPatchDatasetsByDatasetIdResponse, + zPatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdBody, + zPatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdPath, + zPatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse, + zPostDatasetsApiKeysResponse, + zPostDatasetsBatchImportStatusByJobIdBody, + zPostDatasetsBatchImportStatusByJobIdPath, + zPostDatasetsBatchImportStatusByJobIdResponse, + zPostDatasetsBody, + zPostDatasetsByDatasetIdApiKeysByStatusPath, + zPostDatasetsByDatasetIdApiKeysByStatusResponse, + zPostDatasetsByDatasetIdDocumentsBody, + zPostDatasetsByDatasetIdDocumentsByDocumentIdRenameBody, + zPostDatasetsByDatasetIdDocumentsByDocumentIdRenamePath, + zPostDatasetsByDatasetIdDocumentsByDocumentIdRenameResponse, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentBody, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentPath, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentResponse, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportBody, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportPath, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponse, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksBody, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse, + zPostDatasetsByDatasetIdDocumentsDownloadZipBody, + zPostDatasetsByDatasetIdDocumentsDownloadZipPath, + zPostDatasetsByDatasetIdDocumentsDownloadZipResponse, + zPostDatasetsByDatasetIdDocumentsGenerateSummaryBody, + zPostDatasetsByDatasetIdDocumentsGenerateSummaryPath, + zPostDatasetsByDatasetIdDocumentsGenerateSummaryResponse, + zPostDatasetsByDatasetIdDocumentsMetadataBody, + zPostDatasetsByDatasetIdDocumentsMetadataPath, + zPostDatasetsByDatasetIdDocumentsMetadataResponse, + zPostDatasetsByDatasetIdDocumentsPath, + zPostDatasetsByDatasetIdDocumentsResponse, + zPostDatasetsByDatasetIdExternalHitTestingBody, + zPostDatasetsByDatasetIdExternalHitTestingPath, + zPostDatasetsByDatasetIdExternalHitTestingResponse, + zPostDatasetsByDatasetIdHitTestingBody, + zPostDatasetsByDatasetIdHitTestingPath, + zPostDatasetsByDatasetIdHitTestingResponse, + zPostDatasetsByDatasetIdMetadataBody, + zPostDatasetsByDatasetIdMetadataBuiltInByActionPath, + zPostDatasetsByDatasetIdMetadataBuiltInByActionResponse, + zPostDatasetsByDatasetIdMetadataPath, + zPostDatasetsByDatasetIdMetadataResponse, + zPostDatasetsByDatasetIdRetryBody, + zPostDatasetsByDatasetIdRetryPath, + zPostDatasetsByDatasetIdRetryResponse, + zPostDatasetsByResourceIdApiKeysPath, + zPostDatasetsByResourceIdApiKeysResponse, + zPostDatasetsExternalBody, + zPostDatasetsExternalKnowledgeApiBody, + zPostDatasetsExternalKnowledgeApiResponse, + zPostDatasetsExternalResponse, + zPostDatasetsIndexingEstimateBody, + zPostDatasetsIndexingEstimateResponse, + zPostDatasetsInitBody, + zPostDatasetsInitResponse, + zPostDatasetsNotionIndexingEstimateBody, + zPostDatasetsNotionIndexingEstimateResponse, + zPostDatasetsResponse, + zPutDatasetsByDatasetIdDocumentsByDocumentIdMetadataBody, + zPutDatasetsByDatasetIdDocumentsByDocumentIdMetadataPath, + zPutDatasetsByDatasetIdDocumentsByDocumentIdMetadataResponse, +} from './zod.gen' + +/** + * Get dataset API base information + */ +export const get = oc + .route({ + description: 'Get dataset API base information', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsApiBaseInfo', + path: '/datasets/api-base-info', + tags: ['console'], + }) + .output(zGetDatasetsApiBaseInfoResponse) + +export const apiBaseInfo = { + get, +} + +/** + * Delete dataset API key + */ +export const delete_ = oc + .route({ + description: 'Delete dataset API key', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsApiKeysByApiKeyId', + path: '/datasets/api-keys/{api_key_id}', + successStatus: 204, + tags: ['console'], + }) + .input(z.object({ params: zDeleteDatasetsApiKeysByApiKeyIdPath })) + .output(zDeleteDatasetsApiKeysByApiKeyIdResponse) + +export const byApiKeyId = { + delete: delete_, +} + +/** + * Get dataset API keys + */ +export const get2 = oc + .route({ + description: 'Get dataset API keys', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsApiKeys', + path: '/datasets/api-keys', + tags: ['console'], + }) + .output(zGetDatasetsApiKeysResponse) + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsApiKeys', + path: '/datasets/api-keys', + tags: ['console'], + }) + .output(zPostDatasetsApiKeysResponse) + +export const apiKeys = { + get: get2, + post, + byApiKeyId, +} + +export const get3 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsBatchImportStatusByJobId', + path: '/datasets/batch_import_status/{job_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsBatchImportStatusByJobIdPath })) + .output(zGetDatasetsBatchImportStatusByJobIdResponse) + +export const post2 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsBatchImportStatusByJobId', + path: '/datasets/batch_import_status/{job_id}', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsBatchImportStatusByJobIdBody, + params: zPostDatasetsBatchImportStatusByJobIdPath, + }), + ) + .output(zPostDatasetsBatchImportStatusByJobIdResponse) + +export const byJobId = { + get: get3, + post: post2, +} + +export const batchImportStatus = { + byJobId, +} + +/** + * Create external knowledge dataset + */ +export const post3 = oc + .route({ + description: 'Create external knowledge dataset', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsExternal', + path: '/datasets/external', + successStatus: 201, + tags: ['console'], + }) + .input(z.object({ body: zPostDatasetsExternalBody })) + .output(zPostDatasetsExternalResponse) + +export const external = { + post: post3, +} + +/** + * Check if external knowledge API is being used + */ +export const get4 = oc + .route({ + description: 'Check if external knowledge API is being used', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdUseCheck', + path: '/datasets/external-knowledge-api/{external_knowledge_api_id}/use-check', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdUseCheckPath })) + .output(zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdUseCheckResponse) + +export const useCheck = { + get: get4, +} + +export const delete2 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiId', + path: '/datasets/external-knowledge-api/{external_knowledge_api_id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdPath })) + .output(zDeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse) + +/** + * Get external knowledge API template details + */ +export const get5 = oc + .route({ + description: 'Get external knowledge API template details', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsExternalKnowledgeApiByExternalKnowledgeApiId', + path: '/datasets/external-knowledge-api/{external_knowledge_api_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdPath })) + .output(zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse) + +export const patch = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsExternalKnowledgeApiByExternalKnowledgeApiId', + path: '/datasets/external-knowledge-api/{external_knowledge_api_id}', + tags: ['console'], + }) + .input( + z.object({ + body: zPatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdBody, + params: zPatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdPath, + }), + ) + .output(zPatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse) + +export const byExternalKnowledgeApiId = { + delete: delete2, + get: get5, + patch, + useCheck, +} + +/** + * Get external knowledge API templates + */ +export const get6 = oc + .route({ + description: 'Get external knowledge API templates', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsExternalKnowledgeApi', + path: '/datasets/external-knowledge-api', + tags: ['console'], + }) + .input(z.object({ query: zGetDatasetsExternalKnowledgeApiQuery.optional() })) + .output(zGetDatasetsExternalKnowledgeApiResponse) + +export const post4 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsExternalKnowledgeApi', + path: '/datasets/external-knowledge-api', + tags: ['console'], + }) + .input(z.object({ body: zPostDatasetsExternalKnowledgeApiBody })) + .output(zPostDatasetsExternalKnowledgeApiResponse) + +export const externalKnowledgeApi = { + get: get6, + post: post4, + byExternalKnowledgeApiId, +} + +/** + * Estimate dataset indexing cost + */ +export const post5 = oc + .route({ + description: 'Estimate dataset indexing cost', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsIndexingEstimate', + path: '/datasets/indexing-estimate', + tags: ['console'], + }) + .input(z.object({ body: zPostDatasetsIndexingEstimateBody })) + .output(zPostDatasetsIndexingEstimateResponse) + +export const indexingEstimate = { + post: post5, +} + +/** + * Initialize dataset with documents + */ +export const post6 = oc + .route({ + description: 'Initialize dataset with documents', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsInit', + path: '/datasets/init', + successStatus: 201, + tags: ['console'], + }) + .input(z.object({ body: zPostDatasetsInitBody })) + .output(zPostDatasetsInitResponse) + +export const init = { + post: post6, +} + +export const get7 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsMetadataBuiltIn', + path: '/datasets/metadata/built-in', + tags: ['console'], + }) + .output(zGetDatasetsMetadataBuiltInResponse) + +export const builtIn = { + get: get7, +} + +export const metadata = { + builtIn, +} + +export const get8 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsNotionIndexingEstimate', + path: '/datasets/notion-indexing-estimate', + tags: ['console'], + }) + .output(zGetDatasetsNotionIndexingEstimateResponse) + +export const post7 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsNotionIndexingEstimate', + path: '/datasets/notion-indexing-estimate', + tags: ['console'], + }) + .input(z.object({ body: zPostDatasetsNotionIndexingEstimateBody })) + .output(zPostDatasetsNotionIndexingEstimateResponse) + +export const notionIndexingEstimate = { + get: get8, + post: post7, +} + +/** + * Get dataset document processing rules + */ +export const get9 = oc + .route({ + description: 'Get dataset document processing rules', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsProcessRule', + path: '/datasets/process-rule', + tags: ['console'], + }) + .input(z.object({ query: zGetDatasetsProcessRuleQuery.optional() })) + .output(zGetDatasetsProcessRuleResponse) + +export const processRule = { + get: get9, +} + +/** + * Get mock dataset retrieval settings by vector type + */ +export const get10 = oc + .route({ + description: 'Get mock dataset retrieval settings by vector type', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsRetrievalSettingByVectorType', + path: '/datasets/retrieval-setting/{vector_type}', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsRetrievalSettingByVectorTypePath })) + .output(zGetDatasetsRetrievalSettingByVectorTypeResponse) + +export const byVectorType = { + get: get10, +} + +/** + * Get dataset retrieval settings + */ +export const get11 = oc + .route({ + description: 'Get dataset retrieval settings', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsRetrievalSetting', + path: '/datasets/retrieval-setting', + tags: ['console'], + }) + .output(zGetDatasetsRetrievalSettingResponse) + +export const retrievalSetting = { + get: get11, + byVectorType, +} + +export const post8 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdApiKeysByStatus', + path: '/datasets/{dataset_id}/api-keys/{status}', + tags: ['console'], + }) + .input(z.object({ params: zPostDatasetsByDatasetIdApiKeysByStatusPath })) + .output(zPostDatasetsByDatasetIdApiKeysByStatusResponse) + +export const byStatus = { + post: post8, +} + +export const apiKeys2 = { + byStatus, +} + +/** + * Get dataset auto disable logs + */ +export const get12 = oc + .route({ + description: 'Get dataset auto disable logs', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdAutoDisableLogs', + path: '/datasets/{dataset_id}/auto-disable-logs', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdAutoDisableLogsPath })) + .output(zGetDatasetsByDatasetIdAutoDisableLogsResponse) + +export const autoDisableLogs = { + get: get12, +} + +export const get13 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdBatchByBatchIndexingEstimate', + path: '/datasets/{dataset_id}/batch/{batch}/indexing-estimate', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdBatchByBatchIndexingEstimatePath })) + .output(zGetDatasetsByDatasetIdBatchByBatchIndexingEstimateResponse) + +export const indexingEstimate2 = { + get: get13, +} + +export const get14 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdBatchByBatchIndexingStatus', + path: '/datasets/{dataset_id}/batch/{batch}/indexing-status', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdBatchByBatchIndexingStatusPath })) + .output(zGetDatasetsByDatasetIdBatchByBatchIndexingStatusResponse) + +export const indexingStatus = { + get: get14, +} + +export const byBatch = { + indexingEstimate: indexingEstimate2, + indexingStatus, +} + +export const batch = { + byBatch, +} + +/** + * Stream a ZIP archive containing the requested uploaded documents + * + * Download selected dataset documents as a single ZIP archive (upload-file only) + */ +export const post9 = oc + .route({ + description: 'Download selected dataset documents as a single ZIP archive (upload-file only)', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsDownloadZip', + path: '/datasets/{dataset_id}/documents/download-zip', + summary: 'Stream a ZIP archive containing the requested uploaded documents', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsDownloadZipBody, + params: zPostDatasetsByDatasetIdDocumentsDownloadZipPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsDownloadZipResponse) + +export const downloadZip = { + post: post9, +} + +/** + * Generate summary index for specified documents + * + * Generate summary index for documents + * This endpoint checks if the dataset configuration supports summary generation + * (indexing_technique must be 'high_quality' and summary_index_setting.enable must be true), + * then asynchronously generates summary indexes for the provided documents. + */ +export const post10 = oc + .route({ + description: + 'Generate summary index for documents\nThis endpoint checks if the dataset configuration supports summary generation\n(indexing_technique must be \'high_quality\' and summary_index_setting.enable must be true),\nthen asynchronously generates summary indexes for the provided documents.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsGenerateSummary', + path: '/datasets/{dataset_id}/documents/generate-summary', + summary: 'Generate summary index for specified documents', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsGenerateSummaryBody, + params: zPostDatasetsByDatasetIdDocumentsGenerateSummaryPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsGenerateSummaryResponse) + +export const generateSummary = { + post: post10, +} + +export const post11 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsMetadata', + path: '/datasets/{dataset_id}/documents/metadata', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsMetadataBody, + params: zPostDatasetsByDatasetIdDocumentsMetadataPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsMetadataResponse) + +export const metadata2 = { + post: post11, +} + +export const patch2 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetIdDocumentsStatusByActionBatch', + path: '/datasets/{dataset_id}/documents/status/{action}/batch', + tags: ['console'], + }) + .input(z.object({ params: zPatchDatasetsByDatasetIdDocumentsStatusByActionBatchPath })) + .output(zPatchDatasetsByDatasetIdDocumentsStatusByActionBatchResponse) + +export const batch2 = { + patch: patch2, +} + +export const byAction = { + batch: batch2, +} + +export const status = { + byAction, +} + +/** + * Get a signed download URL for a dataset document's original uploaded file + */ +export const get15 = oc + .route({ + description: 'Get a signed download URL for a dataset document\'s original uploaded file', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdDownload', + path: '/datasets/{dataset_id}/documents/{document_id}/download', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByDocumentIdDownloadPath })) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponse) + +export const download = { + get: get15, +} + +/** + * Estimate document indexing cost + */ +export const get16 = oc + .route({ + description: 'Estimate document indexing cost', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimate', + path: '/datasets/{dataset_id}/documents/{document_id}/indexing-estimate', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimatePath })) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimateResponse) + +export const indexingEstimate3 = { + get: get16, +} + +/** + * Get document indexing status + */ +export const get17 = oc + .route({ + description: 'Get document indexing status', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatus', + path: '/datasets/{dataset_id}/documents/{document_id}/indexing-status', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusPath })) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusResponse) + +export const indexingStatus2 = { + get: get17, +} + +/** + * Update document metadata + */ +export const put = oc + .route({ + description: 'Update document metadata', + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putDatasetsByDatasetIdDocumentsByDocumentIdMetadata', + path: '/datasets/{dataset_id}/documents/{document_id}/metadata', + tags: ['console'], + }) + .input( + z.object({ + body: zPutDatasetsByDatasetIdDocumentsByDocumentIdMetadataBody, + params: zPutDatasetsByDatasetIdDocumentsByDocumentIdMetadataPath, + }), + ) + .output(zPutDatasetsByDatasetIdDocumentsByDocumentIdMetadataResponse) + +export const metadata3 = { + put, +} + +export const get18 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdNotionSync', + path: '/datasets/{dataset_id}/documents/{document_id}/notion/sync', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByDocumentIdNotionSyncPath })) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdNotionSyncResponse) + +export const sync = { + get: get18, +} + +export const notion = { + sync, +} + +export const get19 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdPipelineExecutionLog', + path: '/datasets/{dataset_id}/documents/{document_id}/pipeline-execution-log', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByDocumentIdPipelineExecutionLogPath })) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdPipelineExecutionLogResponse) + +export const pipelineExecutionLog = { + get: get19, +} + +/** + * pause document + */ +export const patch3 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPause', + path: '/datasets/{dataset_id}/documents/{document_id}/processing/pause', + summary: 'pause document', + tags: ['console'], + }) + .input(z.object({ params: zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPausePath })) + .output(zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseResponse) + +export const pause = { + patch: patch3, +} + +/** + * recover document + */ +export const patch4 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResume', + path: '/datasets/{dataset_id}/documents/{document_id}/processing/resume', + summary: 'recover document', + tags: ['console'], + }) + .input(z.object({ params: zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumePath })) + .output(zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeResponse) + +export const resume = { + patch: patch4, +} + +/** + * Update document processing status (pause/resume) + */ +export const patch5 = oc + .route({ + description: 'Update document processing status (pause/resume)', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByAction', + path: '/datasets/{dataset_id}/documents/{document_id}/processing/{action}', + tags: ['console'], + }) + .input(z.object({ params: zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionPath })) + .output(zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionResponse) + +export const byAction2 = { + patch: patch5, +} + +export const processing = { + pause, + resume, + byAction: byAction2, +} + +export const post12 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsByDocumentIdRename', + path: '/datasets/{dataset_id}/documents/{document_id}/rename', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsByDocumentIdRenameBody, + params: zPostDatasetsByDatasetIdDocumentsByDocumentIdRenamePath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsByDocumentIdRenameResponse) + +export const rename = { + post: post12, +} + +export const patch6 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetIdDocumentsByDocumentIdSegmentByAction', + path: '/datasets/{dataset_id}/documents/{document_id}/segment/{action}', + tags: ['console'], + }) + .input(z.object({ params: zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentByActionPath })) + .output(zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentByActionResponse) + +export const byAction3 = { + patch: patch6, +} + +export const post13 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsByDocumentIdSegment', + path: '/datasets/{dataset_id}/documents/{document_id}/segment', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentBody, + params: zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentResponse) + +export const segment = { + post: post13, + byAction: byAction3, +} + +export const get20 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImport', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/batch_import', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportPath })) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponse) + +export const post14 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImport', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/batch_import', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportBody, + params: zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponse) + +export const batchImport = { + get: get20, + post: post14, +} + +export const delete3 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: + 'deleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkId', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}', + tags: ['console'], + }) + .input( + z.object({ + params: + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdPath, + }), + ) + .output( + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse, + ) + +export const patch7 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: + 'patchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkId', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}', + tags: ['console'], + }) + .input( + z.object({ + body: zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdBody, + params: + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdPath, + }), + ) + .output( + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse, + ) + +export const byChildChunkId = { + delete: delete3, + patch: patch7, +} + +export const get21 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunks', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks', + tags: ['console'], + }) + .input( + z.object({ + params: zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath, + }), + ) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse) + +export const patch8 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunks', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks', + tags: ['console'], + }) + .input( + z.object({ + params: zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath, + }), + ) + .output(zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse) + +export const post15 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunks', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksBody, + params: zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse) + +export const childChunks = { + get: get21, + patch: patch8, + post: post15, + byChildChunkId, +} + +export const delete4 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentId', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}', + tags: ['console'], + }) + .input( + z.object({ params: zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath }), + ) + .output(zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse) + +export const patch9 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentId', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}', + tags: ['console'], + }) + .input( + z.object({ + body: zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdBody, + params: zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath, + }), + ) + .output(zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse) + +export const bySegmentId = { + delete: delete4, + patch: patch9, + childChunks, +} + +export const delete5 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsByDatasetIdDocumentsByDocumentIdSegments', + path: '/datasets/{dataset_id}/documents/{document_id}/segments', + tags: ['console'], + }) + .input(z.object({ params: zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath })) + .output(zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse) + +export const get22 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdSegments', + path: '/datasets/{dataset_id}/documents/{document_id}/segments', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath })) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse) + +export const segments = { + delete: delete5, + get: get22, + batchImport, + bySegmentId, +} + +/** + * Get summary index generation status for a document + * + * Get summary index generation status for a document + * Returns: + * - total_segments: Total number of segments in the document + * - summary_status: Dictionary with status counts + * - completed: Number of summaries completed + * - generating: Number of summaries being generated + * - error: Number of summaries with errors + * - not_started: Number of segments without summary records + * - summaries: List of summary records with status and content preview + */ +export const get23 = oc + .route({ + description: + 'Get summary index generation status for a document\nReturns:\n- total_segments: Total number of segments in the document\n- summary_status: Dictionary with status counts\n - completed: Number of summaries completed\n - generating: Number of summaries being generated\n - error: Number of summaries with errors\n - not_started: Number of segments without summary records\n- summaries: List of summary records with status and content preview', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatus', + path: '/datasets/{dataset_id}/documents/{document_id}/summary-status', + summary: 'Get summary index generation status for a document', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusPath })) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusResponse) + +export const summaryStatus = { + get: get23, +} + +/** + * sync website document + */ +export const get24 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdWebsiteSync', + path: '/datasets/{dataset_id}/documents/{document_id}/website-sync', + summary: 'sync website document', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByDocumentIdWebsiteSyncPath })) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdWebsiteSyncResponse) + +export const websiteSync = { + get: get24, +} + +export const delete6 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsByDatasetIdDocumentsByDocumentId', + path: '/datasets/{dataset_id}/documents/{document_id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteDatasetsByDatasetIdDocumentsByDocumentIdPath })) + .output(zDeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse) + +/** + * Get document details + */ +export const get25 = oc + .route({ + description: 'Get document details', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentId', + path: '/datasets/{dataset_id}/documents/{document_id}', + tags: ['console'], + }) + .input( + z.object({ + params: zGetDatasetsByDatasetIdDocumentsByDocumentIdPath, + query: zGetDatasetsByDatasetIdDocumentsByDocumentIdQuery.optional(), + }), + ) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdResponse) + +export const byDocumentId = { + delete: delete6, + get: get25, + download, + indexingEstimate: indexingEstimate3, + indexingStatus: indexingStatus2, + metadata: metadata3, + notion, + pipelineExecutionLog, + processing, + rename, + segment, + segments, + summaryStatus, + websiteSync, +} + +export const delete7 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsByDatasetIdDocuments', + path: '/datasets/{dataset_id}/documents', + tags: ['console'], + }) + .input(z.object({ params: zDeleteDatasetsByDatasetIdDocumentsPath })) + .output(zDeleteDatasetsByDatasetIdDocumentsResponse) + +/** + * Get documents in a dataset + */ +export const get26 = oc + .route({ + description: 'Get documents in a dataset', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocuments', + path: '/datasets/{dataset_id}/documents', + tags: ['console'], + }) + .input( + z.object({ + params: zGetDatasetsByDatasetIdDocumentsPath, + query: zGetDatasetsByDatasetIdDocumentsQuery.optional(), + }), + ) + .output(zGetDatasetsByDatasetIdDocumentsResponse) + +export const post16 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocuments', + path: '/datasets/{dataset_id}/documents', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsBody, + params: zPostDatasetsByDatasetIdDocumentsPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsResponse) + +export const documents = { + delete: delete7, + get: get26, + post: post16, + downloadZip, + generateSummary, + metadata: metadata2, + status, + byDocumentId, +} + +/** + * Get dataset error documents + */ +export const get27 = oc + .route({ + description: 'Get dataset error documents', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdErrorDocs', + path: '/datasets/{dataset_id}/error-docs', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdErrorDocsPath })) + .output(zGetDatasetsByDatasetIdErrorDocsResponse) + +export const errorDocs = { + get: get27, +} + +/** + * Test external knowledge retrieval for dataset + */ +export const post17 = oc + .route({ + description: 'Test external knowledge retrieval for dataset', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdExternalHitTesting', + path: '/datasets/{dataset_id}/external-hit-testing', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdExternalHitTestingBody, + params: zPostDatasetsByDatasetIdExternalHitTestingPath, + }), + ) + .output(zPostDatasetsByDatasetIdExternalHitTestingResponse) + +export const externalHitTesting = { + post: post17, +} + +/** + * Test dataset knowledge retrieval + */ +export const post18 = oc + .route({ + description: 'Test dataset knowledge retrieval', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdHitTesting', + path: '/datasets/{dataset_id}/hit-testing', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdHitTestingBody, + params: zPostDatasetsByDatasetIdHitTestingPath, + }), + ) + .output(zPostDatasetsByDatasetIdHitTestingResponse) + +export const hitTesting = { + post: post18, +} + +/** + * Get dataset indexing status + */ +export const get28 = oc + .route({ + description: 'Get dataset indexing status', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdIndexingStatus', + path: '/datasets/{dataset_id}/indexing-status', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdIndexingStatusPath })) + .output(zGetDatasetsByDatasetIdIndexingStatusResponse) + +export const indexingStatus3 = { + get: get28, +} + +export const post19 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdMetadataBuiltInByAction', + path: '/datasets/{dataset_id}/metadata/built-in/{action}', + tags: ['console'], + }) + .input(z.object({ params: zPostDatasetsByDatasetIdMetadataBuiltInByActionPath })) + .output(zPostDatasetsByDatasetIdMetadataBuiltInByActionResponse) + +export const byAction4 = { + post: post19, +} + +export const builtIn2 = { + byAction: byAction4, +} + +export const delete8 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsByDatasetIdMetadataByMetadataId', + path: '/datasets/{dataset_id}/metadata/{metadata_id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteDatasetsByDatasetIdMetadataByMetadataIdPath })) + .output(zDeleteDatasetsByDatasetIdMetadataByMetadataIdResponse) + +export const patch10 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetIdMetadataByMetadataId', + path: '/datasets/{dataset_id}/metadata/{metadata_id}', + tags: ['console'], + }) + .input( + z.object({ + body: zPatchDatasetsByDatasetIdMetadataByMetadataIdBody, + params: zPatchDatasetsByDatasetIdMetadataByMetadataIdPath, + }), + ) + .output(zPatchDatasetsByDatasetIdMetadataByMetadataIdResponse) + +export const byMetadataId = { + delete: delete8, + patch: patch10, +} + +export const get29 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdMetadata', + path: '/datasets/{dataset_id}/metadata', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdMetadataPath })) + .output(zGetDatasetsByDatasetIdMetadataResponse) + +export const post20 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdMetadata', + path: '/datasets/{dataset_id}/metadata', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdMetadataBody, + params: zPostDatasetsByDatasetIdMetadataPath, + }), + ) + .output(zPostDatasetsByDatasetIdMetadataResponse) + +export const metadata4 = { + get: get29, + post: post20, + builtIn: builtIn2, + byMetadataId, +} + +export const get30 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdNotionSync', + path: '/datasets/{dataset_id}/notion/sync', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdNotionSyncPath })) + .output(zGetDatasetsByDatasetIdNotionSyncResponse) + +export const sync2 = { + get: get30, +} + +export const notion2 = { + sync: sync2, +} + +/** + * Get dataset permission user list + */ +export const get31 = oc + .route({ + description: 'Get dataset permission user list', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdPermissionPartUsers', + path: '/datasets/{dataset_id}/permission-part-users', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdPermissionPartUsersPath })) + .output(zGetDatasetsByDatasetIdPermissionPartUsersResponse) + +export const permissionPartUsers = { + get: get31, +} + +/** + * Get dataset query history + */ +export const get32 = oc + .route({ + description: 'Get dataset query history', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdQueries', + path: '/datasets/{dataset_id}/queries', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdQueriesPath })) + .output(zGetDatasetsByDatasetIdQueriesResponse) + +export const queries = { + get: get32, +} + +/** + * Get applications related to dataset + */ +export const get33 = oc + .route({ + description: 'Get applications related to dataset', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdRelatedApps', + path: '/datasets/{dataset_id}/related-apps', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdRelatedAppsPath })) + .output(zGetDatasetsByDatasetIdRelatedAppsResponse) + +export const relatedApps = { + get: get33, +} + +/** + * retry document + */ +export const post21 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdRetry', + path: '/datasets/{dataset_id}/retry', + summary: 'retry document', + tags: ['console'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdRetryBody, + params: zPostDatasetsByDatasetIdRetryPath, + }), + ) + .output(zPostDatasetsByDatasetIdRetryResponse) + +export const retry = { + post: post21, +} + +/** + * Check if dataset is in use + */ +export const get34 = oc + .route({ + description: 'Check if dataset is in use', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdUseCheck', + path: '/datasets/{dataset_id}/use-check', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdUseCheckPath })) + .output(zGetDatasetsByDatasetIdUseCheckResponse) + +export const useCheck2 = { + get: get34, +} + +export const delete9 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsByDatasetId', + path: '/datasets/{dataset_id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteDatasetsByDatasetIdPath })) + .output(zDeleteDatasetsByDatasetIdResponse) + +/** + * Get dataset details + */ +export const get35 = oc + .route({ + description: 'Get dataset details', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetId', + path: '/datasets/{dataset_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdPath })) + .output(zGetDatasetsByDatasetIdResponse) + +/** + * Update dataset details + */ +export const patch11 = oc + .route({ + description: 'Update dataset details', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetId', + path: '/datasets/{dataset_id}', + tags: ['console'], + }) + .input(z.object({ body: zPatchDatasetsByDatasetIdBody, params: zPatchDatasetsByDatasetIdPath })) + .output(zPatchDatasetsByDatasetIdResponse) + +export const byDatasetId = { + delete: delete9, + get: get35, + patch: patch11, + apiKeys: apiKeys2, + autoDisableLogs, + batch, + documents, + errorDocs, + externalHitTesting, + hitTesting, + indexingStatus: indexingStatus3, + metadata: metadata4, + notion: notion2, + permissionPartUsers, + queries, + relatedApps, + retry, + useCheck: useCheck2, +} + +/** + * Delete an API key for a dataset + * + * Delete an API key for a dataset + */ +export const delete10 = oc + .route({ + description: 'Delete an API key for a dataset', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsByResourceIdApiKeysByApiKeyId', + path: '/datasets/{resource_id}/api-keys/{api_key_id}', + successStatus: 204, + summary: 'Delete an API key for a dataset', + tags: ['console'], + }) + .input(z.object({ params: zDeleteDatasetsByResourceIdApiKeysByApiKeyIdPath })) + .output(zDeleteDatasetsByResourceIdApiKeysByApiKeyIdResponse) + +export const byApiKeyId2 = { + delete: delete10, +} + +/** + * Get all API keys for a dataset + * + * Get all API keys for a dataset + */ +export const get36 = oc + .route({ + description: 'Get all API keys for a dataset', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByResourceIdApiKeys', + path: '/datasets/{resource_id}/api-keys', + summary: 'Get all API keys for a dataset', + tags: ['console'], + }) + .input(z.object({ params: zGetDatasetsByResourceIdApiKeysPath })) + .output(zGetDatasetsByResourceIdApiKeysResponse) + +/** + * Create a new API key for a dataset + * + * Create a new API key for a dataset + */ +export const post22 = oc + .route({ + description: 'Create a new API key for a dataset', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByResourceIdApiKeys', + path: '/datasets/{resource_id}/api-keys', + successStatus: 201, + summary: 'Create a new API key for a dataset', + tags: ['console'], + }) + .input(z.object({ params: zPostDatasetsByResourceIdApiKeysPath })) + .output(zPostDatasetsByResourceIdApiKeysResponse) + +export const apiKeys3 = { + get: get36, + post: post22, + byApiKeyId: byApiKeyId2, +} + +export const byResourceId = { + apiKeys: apiKeys3, +} + +/** + * Get list of datasets + */ +export const get37 = oc + .route({ + description: 'Get list of datasets', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasets', + path: '/datasets', + tags: ['console'], + }) + .input(z.object({ query: zGetDatasetsQuery.optional() })) + .output(zGetDatasetsResponse) + +/** + * Create a new dataset + */ +export const post23 = oc + .route({ + description: 'Create a new dataset', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasets', + path: '/datasets', + successStatus: 201, + tags: ['console'], + }) + .input(z.object({ body: zPostDatasetsBody })) + .output(zPostDatasetsResponse) + +export const datasets = { + get: get37, + post: post23, + apiBaseInfo, + apiKeys, + batchImportStatus, + external, + externalKnowledgeApi, + indexingEstimate, + init, + metadata, + notionIndexingEstimate, + processRule, + retrievalSetting, + byDatasetId, + byResourceId, +} + +export const contract = { + datasets, +} diff --git a/packages/contracts/generated/api/console/datasets/types.gen.ts b/packages/contracts/generated/api/console/datasets/types.gen.ts new file mode 100644 index 0000000000..61d380d686 --- /dev/null +++ b/packages/contracts/generated/api/console/datasets/types.gen.ts @@ -0,0 +1,2165 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type DatasetCreatePayload = { + description?: string + external_knowledge_api_id?: string | null + external_knowledge_id?: string | null + indexing_technique?: string | null + name: string + permission?: DatasetPermissionEnum + provider?: string +} + +export type ApiKeyList = { + data: Array +} + +export type ApiKeyItem = { + created_at?: number | null + id: string + last_used_at?: number | null + token: string + type: string +} + +export type BatchImportPayload = { + upload_file_id: string +} + +export type ExternalDatasetCreatePayload = { + description?: string | null + external_knowledge_api_id: string + external_knowledge_id: string + external_retrieval_model?: { + [key: string]: unknown + } | null + name: string +} + +export type DatasetDetail = { + [key: string]: unknown +} + +export type ExternalKnowledgeApiPayload = { + name: string + settings: { + [key: string]: unknown + } +} + +export type IndexingEstimatePayload = { + dataset_id?: string | null + doc_form?: string + doc_language?: string + indexing_technique: string + info_list: { + [key: string]: unknown + } + process_rule: { + [key: string]: unknown + } +} + +export type KnowledgeConfig = { + data_source?: DataSource + doc_form?: string + doc_language?: string + duplicate?: boolean + embedding_model?: string | null + embedding_model_provider?: string | null + indexing_technique: 'high_quality' | 'economy' + is_multimodal?: boolean + name?: string | null + original_document_id?: string | null + process_rule?: ProcessRule + retrieval_model?: RetrievalModel + summary_index_setting?: { + [key: string]: unknown + } | null +} + +export type DatasetAndDocumentResponse = { + batch: string + dataset: DatasetResponse + documents: Array +} + +export type NotionEstimatePayload = { + doc_form?: string + doc_language?: string + notion_info_list: Array<{ + [key: string]: unknown + }> + process_rule: { + [key: string]: unknown + } +} + +export type DatasetUpdatePayload = { + description?: string | null + embedding_model?: string | null + embedding_model_provider?: string | null + external_knowledge_api_id?: string | null + external_knowledge_id?: string | null + external_retrieval_model?: { + [key: string]: unknown + } | null + icon_info?: { + [key: string]: unknown + } | null + indexing_technique?: string | null + is_multimodal?: boolean | null + name?: string | null + partial_member_list?: Array<{ + [key: string]: string + }> | null + permission?: DatasetPermissionEnum + retrieval_model?: { + [key: string]: unknown + } | null + summary_index_setting?: { + [key: string]: unknown + } | null +} + +export type DocumentBatchDownloadZipPayload = { + document_ids: Array +} + +export type GenerateSummaryPayload = { + document_list: Array +} + +export type MetadataOperationData = { + operation_data: Array +} + +export type DocumentMetadataUpdatePayload = { + doc_metadata?: unknown + doc_type?: string | null +} + +export type DocumentRenamePayload = { + name: string +} + +export type DocumentResponse = { + archived?: boolean | null + created_at?: number | null + created_by?: string | null + created_from?: string | null + data_source_detail_dict?: unknown + data_source_info_dict?: unknown + data_source_type?: string | null + dataset_process_rule_id?: string | null + disabled_at?: number | null + disabled_by?: string | null + display_status?: string | null + doc_form?: string | null + doc_metadata_details?: Array + enabled?: boolean | null + error?: string | null + hit_count?: number | null + id: string + indexing_status?: string | null + name: string + need_summary?: boolean | null + position?: number | null + summary_index_status?: string | null + tokens?: number | null + word_count?: number | null +} + +export type SegmentCreatePayload = { + answer?: string | null + attachment_ids?: Array | null + content: string + keywords?: Array | null +} + +export type SegmentUpdatePayload = { + answer?: string | null + attachment_ids?: Array | null + content: string + keywords?: Array | null + regenerate_child_chunks?: boolean + summary?: string | null +} + +export type ChildChunkCreatePayload = { + content: string +} + +export type ChildChunkUpdatePayload = { + content: string +} + +export type ExternalHitTestingPayload = { + external_retrieval_model?: { + [key: string]: unknown + } | null + metadata_filtering_conditions?: { + [key: string]: unknown + } | null + query: string +} + +export type HitTestingPayload = { + attachment_ids?: Array | null + external_retrieval_model?: { + [key: string]: unknown + } | null + query: string + retrieval_model?: RetrievalModel +} + +export type HitTestingResponse = { + query: string + records?: Array +} + +export type MetadataArgs = { + name: string + type: 'string' | 'number' | 'time' +} + +export type MetadataUpdatePayload = { + name: string +} + +export type DatasetQueryDetail = { + [key: string]: unknown +} + +export type RelatedAppList = { + [key: string]: unknown +} + +export type DocumentRetryPayload = { + document_ids: Array +} + +export type DatasetPermissionEnum = 'only_me' | 'all_team_members' | 'partial_members' + +export type DataSource = { + info_list: InfoList +} + +export type ProcessRule = { + mode: 'automatic' | 'custom' | 'hierarchical' + rules?: Rule +} + +export type RetrievalModel = { + metadata_filtering_conditions?: MetadataFilteringCondition + reranking_enable: boolean + reranking_mode?: string | null + reranking_model?: RerankingModel + score_threshold?: number | null + score_threshold_enabled: boolean + search_method: RetrievalMethod + top_k: number + weights?: WeightModel +} + +export type DatasetResponse = { + created_at?: number | null + created_by?: string | null + data_source_type?: string | null + description?: string | null + id: string + indexing_technique?: string | null + name: string + permission?: string | null +} + +export type DocumentMetadataOperation = { + document_id: string + metadata_list: Array + partial_update?: boolean +} + +export type DocumentMetadataResponse = { + id: string + name: string + type: string + value?: string | null +} + +export type HitTestingRecord = { + child_chunks?: Array + files?: Array + score?: number | null + segment?: HitTestingSegment + summary?: string | null + tsne_position?: unknown +} + +export type InfoList = { + data_source_type: 'upload_file' | 'notion_import' | 'website_crawl' + file_info_list?: FileInfo + notion_info_list?: Array | null + website_info_list?: WebsiteInfo +} + +export type Rule = { + parent_mode?: 'full-doc' | 'paragraph' | null + pre_processing_rules?: Array | null + segmentation?: Segmentation + subchunk_segmentation?: Segmentation +} + +export type MetadataFilteringCondition = { + conditions?: Array | null + logical_operator?: 'and' | 'or' | null +} + +export type RerankingModel = { + reranking_model_name?: string | null + reranking_provider_name?: string | null +} + +export type RetrievalMethod + = | 'semantic_search' + | 'full_text_search' + | 'hybrid_search' + | 'keyword_search' + +export type WeightModel = { + keyword_setting?: WeightKeywordSetting + vector_setting?: WeightVectorSetting + weight_type?: 'semantic_first' | 'keyword_first' | 'customized' | null +} + +export type MetadataDetail = { + id: string + name: string + value?: unknown +} + +export type HitTestingChildChunk = { + content?: string | null + id?: string | null + position?: number | null + score?: number | null +} + +export type HitTestingFile = { + extension?: string | null + id?: string | null + mime_type?: string | null + name?: string | null + size?: number | null + source_url?: string | null +} + +export type HitTestingSegment = { + answer?: string | null + completed_at?: number | null + content?: string | null + created_at?: number | null + created_by?: string | null + disabled_at?: number | null + disabled_by?: string | null + document?: HitTestingDocument + document_id?: string | null + enabled?: boolean | null + error?: string | null + hit_count?: number | null + id?: string | null + index_node_hash?: string | null + index_node_id?: string | null + indexing_at?: number | null + keywords?: Array + position?: number | null + sign_content?: string | null + status?: string | null + stopped_at?: number | null + tokens?: number | null + word_count?: number | null +} + +export type FileInfo = { + file_ids: Array +} + +export type NotionInfo = { + credential_id: string + pages: Array + workspace_id: string +} + +export type WebsiteInfo = { + job_id: string + only_main_content?: boolean + provider: string + urls: Array +} + +export type PreProcessingRule = { + enabled: boolean + id: string +} + +export type Segmentation = { + chunk_overlap?: number + max_tokens: number + separator?: string +} + +export type Condition = { + comparison_operator: + | 'contains' + | 'not contains' + | 'start with' + | 'end with' + | 'is' + | 'is not' + | 'empty' + | 'not empty' + | 'in' + | 'not in' + | '=' + | '≠' + | '>' + | '<' + | '≥' + | '≤' + | 'before' + | 'after' + name: string + value?: unknown +} + +export type WeightKeywordSetting = { + keyword_weight: number +} + +export type WeightVectorSetting = { + embedding_model_name: string + embedding_provider_name: string + vector_weight: number +} + +export type HitTestingDocument = { + data_source_type?: string | null + doc_metadata?: unknown + doc_type?: string | null + id?: string | null + name?: string | null +} + +export type NotionPage = { + page_icon?: NotionIcon + page_id: string + page_name: string + type: string +} + +export type NotionIcon = { + emoji?: string | null + type: string + url?: string | null +} + +export type GetDatasetsData = { + body?: never + path?: never + query?: { + page?: string + limit?: string + ids?: string + keyword?: string + tag_ids?: string + include_all?: string + } + url: '/datasets' +} + +export type GetDatasetsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsResponse = GetDatasetsResponses[keyof GetDatasetsResponses] + +export type PostDatasetsData = { + body: DatasetCreatePayload + path?: never + query?: never + url: '/datasets' +} + +export type PostDatasetsErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostDatasetsError = PostDatasetsErrors[keyof PostDatasetsErrors] + +export type PostDatasetsResponses = { + 201: { + [key: string]: unknown + } +} + +export type PostDatasetsResponse = PostDatasetsResponses[keyof PostDatasetsResponses] + +export type GetDatasetsApiBaseInfoData = { + body?: never + path?: never + query?: never + url: '/datasets/api-base-info' +} + +export type GetDatasetsApiBaseInfoResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsApiBaseInfoResponse + = GetDatasetsApiBaseInfoResponses[keyof GetDatasetsApiBaseInfoResponses] + +export type GetDatasetsApiKeysData = { + body?: never + path?: never + query?: never + url: '/datasets/api-keys' +} + +export type GetDatasetsApiKeysResponses = { + 200: ApiKeyList +} + +export type GetDatasetsApiKeysResponse + = GetDatasetsApiKeysResponses[keyof GetDatasetsApiKeysResponses] + +export type PostDatasetsApiKeysData = { + body?: never + path?: never + query?: never + url: '/datasets/api-keys' +} + +export type PostDatasetsApiKeysErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostDatasetsApiKeysError = PostDatasetsApiKeysErrors[keyof PostDatasetsApiKeysErrors] + +export type PostDatasetsApiKeysResponses = { + 200: ApiKeyItem +} + +export type PostDatasetsApiKeysResponse + = PostDatasetsApiKeysResponses[keyof PostDatasetsApiKeysResponses] + +export type DeleteDatasetsApiKeysByApiKeyIdData = { + body?: never + path: { + api_key_id: string + } + query?: never + url: '/datasets/api-keys/{api_key_id}' +} + +export type DeleteDatasetsApiKeysByApiKeyIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteDatasetsApiKeysByApiKeyIdResponse + = DeleteDatasetsApiKeysByApiKeyIdResponses[keyof DeleteDatasetsApiKeysByApiKeyIdResponses] + +export type GetDatasetsBatchImportStatusByJobIdData = { + body?: never + path: { + job_id: string + } + query?: never + url: '/datasets/batch_import_status/{job_id}' +} + +export type GetDatasetsBatchImportStatusByJobIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsBatchImportStatusByJobIdResponse + = GetDatasetsBatchImportStatusByJobIdResponses[keyof GetDatasetsBatchImportStatusByJobIdResponses] + +export type PostDatasetsBatchImportStatusByJobIdData = { + body: BatchImportPayload + path: { + job_id: string + } + query?: never + url: '/datasets/batch_import_status/{job_id}' +} + +export type PostDatasetsBatchImportStatusByJobIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsBatchImportStatusByJobIdResponse + = PostDatasetsBatchImportStatusByJobIdResponses[keyof PostDatasetsBatchImportStatusByJobIdResponses] + +export type PostDatasetsExternalData = { + body: ExternalDatasetCreatePayload + path?: never + query?: never + url: '/datasets/external' +} + +export type PostDatasetsExternalErrors = { + 400: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type PostDatasetsExternalError = PostDatasetsExternalErrors[keyof PostDatasetsExternalErrors] + +export type PostDatasetsExternalResponses = { + 201: DatasetDetail +} + +export type PostDatasetsExternalResponse + = PostDatasetsExternalResponses[keyof PostDatasetsExternalResponses] + +export type GetDatasetsExternalKnowledgeApiData = { + body?: never + path?: never + query?: { + page?: string + limit?: string + keyword?: string + } + url: '/datasets/external-knowledge-api' +} + +export type GetDatasetsExternalKnowledgeApiResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsExternalKnowledgeApiResponse + = GetDatasetsExternalKnowledgeApiResponses[keyof GetDatasetsExternalKnowledgeApiResponses] + +export type PostDatasetsExternalKnowledgeApiData = { + body: ExternalKnowledgeApiPayload + path?: never + query?: never + url: '/datasets/external-knowledge-api' +} + +export type PostDatasetsExternalKnowledgeApiResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsExternalKnowledgeApiResponse + = PostDatasetsExternalKnowledgeApiResponses[keyof PostDatasetsExternalKnowledgeApiResponses] + +export type DeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdData = { + body?: never + path: { + external_knowledge_api_id: string + } + query?: never + url: '/datasets/external-knowledge-api/{external_knowledge_api_id}' +} + +export type DeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse + = DeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponses[keyof DeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponses] + +export type GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdData = { + body?: never + path: { + external_knowledge_api_id: string + } + query?: never + url: '/datasets/external-knowledge-api/{external_knowledge_api_id}' +} + +export type GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdError + = GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdErrors[keyof GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdErrors] + +export type GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse + = GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponses[keyof GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponses] + +export type PatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdData = { + body: ExternalKnowledgeApiPayload + path: { + external_knowledge_api_id: string + } + query?: never + url: '/datasets/external-knowledge-api/{external_knowledge_api_id}' +} + +export type PatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse + = PatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponses[keyof PatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponses] + +export type GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdUseCheckData = { + body?: never + path: { + external_knowledge_api_id: string + } + query?: never + url: '/datasets/external-knowledge-api/{external_knowledge_api_id}/use-check' +} + +export type GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdUseCheckResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdUseCheckResponse + = GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdUseCheckResponses[keyof GetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdUseCheckResponses] + +export type PostDatasetsIndexingEstimateData = { + body: IndexingEstimatePayload + path?: never + query?: never + url: '/datasets/indexing-estimate' +} + +export type PostDatasetsIndexingEstimateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsIndexingEstimateResponse + = PostDatasetsIndexingEstimateResponses[keyof PostDatasetsIndexingEstimateResponses] + +export type PostDatasetsInitData = { + body: KnowledgeConfig + path?: never + query?: never + url: '/datasets/init' +} + +export type PostDatasetsInitErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostDatasetsInitError = PostDatasetsInitErrors[keyof PostDatasetsInitErrors] + +export type PostDatasetsInitResponses = { + 201: DatasetAndDocumentResponse +} + +export type PostDatasetsInitResponse = PostDatasetsInitResponses[keyof PostDatasetsInitResponses] + +export type GetDatasetsMetadataBuiltInData = { + body?: never + path?: never + query?: never + url: '/datasets/metadata/built-in' +} + +export type GetDatasetsMetadataBuiltInResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsMetadataBuiltInResponse + = GetDatasetsMetadataBuiltInResponses[keyof GetDatasetsMetadataBuiltInResponses] + +export type GetDatasetsNotionIndexingEstimateData = { + body?: never + path?: never + query?: never + url: '/datasets/notion-indexing-estimate' +} + +export type GetDatasetsNotionIndexingEstimateResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsNotionIndexingEstimateResponse + = GetDatasetsNotionIndexingEstimateResponses[keyof GetDatasetsNotionIndexingEstimateResponses] + +export type PostDatasetsNotionIndexingEstimateData = { + body: NotionEstimatePayload + path?: never + query?: never + url: '/datasets/notion-indexing-estimate' +} + +export type PostDatasetsNotionIndexingEstimateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsNotionIndexingEstimateResponse + = PostDatasetsNotionIndexingEstimateResponses[keyof PostDatasetsNotionIndexingEstimateResponses] + +export type GetDatasetsProcessRuleData = { + body?: never + path?: never + query?: { + document_id?: string + } + url: '/datasets/process-rule' +} + +export type GetDatasetsProcessRuleResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsProcessRuleResponse + = GetDatasetsProcessRuleResponses[keyof GetDatasetsProcessRuleResponses] + +export type GetDatasetsRetrievalSettingData = { + body?: never + path?: never + query?: never + url: '/datasets/retrieval-setting' +} + +export type GetDatasetsRetrievalSettingResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsRetrievalSettingResponse + = GetDatasetsRetrievalSettingResponses[keyof GetDatasetsRetrievalSettingResponses] + +export type GetDatasetsRetrievalSettingByVectorTypeData = { + body?: never + path: { + vector_type: string + } + query?: never + url: '/datasets/retrieval-setting/{vector_type}' +} + +export type GetDatasetsRetrievalSettingByVectorTypeResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsRetrievalSettingByVectorTypeResponse + = GetDatasetsRetrievalSettingByVectorTypeResponses[keyof GetDatasetsRetrievalSettingByVectorTypeResponses] + +export type DeleteDatasetsByDatasetIdData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}' +} + +export type DeleteDatasetsByDatasetIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdResponse + = DeleteDatasetsByDatasetIdResponses[keyof DeleteDatasetsByDatasetIdResponses] + +export type GetDatasetsByDatasetIdData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}' +} + +export type GetDatasetsByDatasetIdErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdError + = GetDatasetsByDatasetIdErrors[keyof GetDatasetsByDatasetIdErrors] + +export type GetDatasetsByDatasetIdResponses = { + 200: DatasetDetail +} + +export type GetDatasetsByDatasetIdResponse + = GetDatasetsByDatasetIdResponses[keyof GetDatasetsByDatasetIdResponses] + +export type PatchDatasetsByDatasetIdData = { + body: DatasetUpdatePayload + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}' +} + +export type PatchDatasetsByDatasetIdErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdError + = PatchDatasetsByDatasetIdErrors[keyof PatchDatasetsByDatasetIdErrors] + +export type PatchDatasetsByDatasetIdResponses = { + 200: DatasetDetail +} + +export type PatchDatasetsByDatasetIdResponse + = PatchDatasetsByDatasetIdResponses[keyof PatchDatasetsByDatasetIdResponses] + +export type PostDatasetsByDatasetIdApiKeysByStatusData = { + body?: never + path: { + dataset_id: string + status: string + } + query?: never + url: '/datasets/{dataset_id}/api-keys/{status}' +} + +export type PostDatasetsByDatasetIdApiKeysByStatusResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdApiKeysByStatusResponse + = PostDatasetsByDatasetIdApiKeysByStatusResponses[keyof PostDatasetsByDatasetIdApiKeysByStatusResponses] + +export type GetDatasetsByDatasetIdAutoDisableLogsData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/auto-disable-logs' +} + +export type GetDatasetsByDatasetIdAutoDisableLogsErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdAutoDisableLogsError + = GetDatasetsByDatasetIdAutoDisableLogsErrors[keyof GetDatasetsByDatasetIdAutoDisableLogsErrors] + +export type GetDatasetsByDatasetIdAutoDisableLogsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdAutoDisableLogsResponse + = GetDatasetsByDatasetIdAutoDisableLogsResponses[keyof GetDatasetsByDatasetIdAutoDisableLogsResponses] + +export type GetDatasetsByDatasetIdBatchByBatchIndexingEstimateData = { + body?: never + path: { + dataset_id: string + batch: string + } + query?: never + url: '/datasets/{dataset_id}/batch/{batch}/indexing-estimate' +} + +export type GetDatasetsByDatasetIdBatchByBatchIndexingEstimateResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdBatchByBatchIndexingEstimateResponse + = GetDatasetsByDatasetIdBatchByBatchIndexingEstimateResponses[keyof GetDatasetsByDatasetIdBatchByBatchIndexingEstimateResponses] + +export type GetDatasetsByDatasetIdBatchByBatchIndexingStatusData = { + body?: never + path: { + dataset_id: string + batch: string + } + query?: never + url: '/datasets/{dataset_id}/batch/{batch}/indexing-status' +} + +export type GetDatasetsByDatasetIdBatchByBatchIndexingStatusResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdBatchByBatchIndexingStatusResponse + = GetDatasetsByDatasetIdBatchByBatchIndexingStatusResponses[keyof GetDatasetsByDatasetIdBatchByBatchIndexingStatusResponses] + +export type DeleteDatasetsByDatasetIdDocumentsData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents' +} + +export type DeleteDatasetsByDatasetIdDocumentsResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdDocumentsResponse + = DeleteDatasetsByDatasetIdDocumentsResponses[keyof DeleteDatasetsByDatasetIdDocumentsResponses] + +export type GetDatasetsByDatasetIdDocumentsData = { + body?: never + path: { + dataset_id: string + } + query?: { + page?: string + limit?: string + keyword?: string + sort?: string + fetch?: string + status?: string + } + url: '/datasets/{dataset_id}/documents' +} + +export type GetDatasetsByDatasetIdDocumentsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsResponse + = GetDatasetsByDatasetIdDocumentsResponses[keyof GetDatasetsByDatasetIdDocumentsResponses] + +export type PostDatasetsByDatasetIdDocumentsData = { + body: KnowledgeConfig + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents' +} + +export type PostDatasetsByDatasetIdDocumentsResponses = { + 200: DatasetAndDocumentResponse +} + +export type PostDatasetsByDatasetIdDocumentsResponse + = PostDatasetsByDatasetIdDocumentsResponses[keyof PostDatasetsByDatasetIdDocumentsResponses] + +export type PostDatasetsByDatasetIdDocumentsDownloadZipData = { + body: DocumentBatchDownloadZipPayload + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/download-zip' +} + +export type PostDatasetsByDatasetIdDocumentsDownloadZipResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsDownloadZipResponse + = PostDatasetsByDatasetIdDocumentsDownloadZipResponses[keyof PostDatasetsByDatasetIdDocumentsDownloadZipResponses] + +export type PostDatasetsByDatasetIdDocumentsGenerateSummaryData = { + body: GenerateSummaryPayload + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/generate-summary' +} + +export type PostDatasetsByDatasetIdDocumentsGenerateSummaryErrors = { + 400: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsGenerateSummaryError + = PostDatasetsByDatasetIdDocumentsGenerateSummaryErrors[keyof PostDatasetsByDatasetIdDocumentsGenerateSummaryErrors] + +export type PostDatasetsByDatasetIdDocumentsGenerateSummaryResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsGenerateSummaryResponse + = PostDatasetsByDatasetIdDocumentsGenerateSummaryResponses[keyof PostDatasetsByDatasetIdDocumentsGenerateSummaryResponses] + +export type PostDatasetsByDatasetIdDocumentsMetadataData = { + body: MetadataOperationData + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/metadata' +} + +export type PostDatasetsByDatasetIdDocumentsMetadataResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsMetadataResponse + = PostDatasetsByDatasetIdDocumentsMetadataResponses[keyof PostDatasetsByDatasetIdDocumentsMetadataResponses] + +export type PatchDatasetsByDatasetIdDocumentsStatusByActionBatchData = { + body?: never + path: { + dataset_id: string + action: string + } + query?: never + url: '/datasets/{dataset_id}/documents/status/{action}/batch' +} + +export type PatchDatasetsByDatasetIdDocumentsStatusByActionBatchResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdDocumentsStatusByActionBatchResponse + = PatchDatasetsByDatasetIdDocumentsStatusByActionBatchResponses[keyof PatchDatasetsByDatasetIdDocumentsStatusByActionBatchResponses] + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdData = { + body?: never + path: { + document_id: string + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}' +} + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse + = DeleteDatasetsByDatasetIdDocumentsByDocumentIdResponses[keyof DeleteDatasetsByDatasetIdDocumentsByDocumentIdResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: { + metadata?: string + } + url: '/datasets/{dataset_id}/documents/{document_id}' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdError + = GetDatasetsByDatasetIdDocumentsByDocumentIdErrors[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdErrors] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/download' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimateData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/indexing-estimate' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimateErrors = { + 400: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimateError + = GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimateErrors[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimateErrors] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimateResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimateResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimateResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimateResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/indexing-status' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusError + = GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusErrors[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusErrors] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusResponses] + +export type PutDatasetsByDatasetIdDocumentsByDocumentIdMetadataData = { + body: DocumentMetadataUpdatePayload + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/metadata' +} + +export type PutDatasetsByDatasetIdDocumentsByDocumentIdMetadataErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PutDatasetsByDatasetIdDocumentsByDocumentIdMetadataError + = PutDatasetsByDatasetIdDocumentsByDocumentIdMetadataErrors[keyof PutDatasetsByDatasetIdDocumentsByDocumentIdMetadataErrors] + +export type PutDatasetsByDatasetIdDocumentsByDocumentIdMetadataResponses = { + 200: { + [key: string]: unknown + } +} + +export type PutDatasetsByDatasetIdDocumentsByDocumentIdMetadataResponse + = PutDatasetsByDatasetIdDocumentsByDocumentIdMetadataResponses[keyof PutDatasetsByDatasetIdDocumentsByDocumentIdMetadataResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdNotionSyncData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/notion/sync' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdNotionSyncResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdNotionSyncResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdNotionSyncResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdNotionSyncResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdPipelineExecutionLogData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/pipeline-execution-log' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdPipelineExecutionLogResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdPipelineExecutionLogResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdPipelineExecutionLogResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdPipelineExecutionLogResponses] + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/processing/pause' +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseResponse + = PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseResponses[keyof PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseResponses] + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/processing/resume' +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeResponse + = PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeResponses[keyof PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeResponses] + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionData = { + body?: never + path: { + dataset_id: string + document_id: string + action: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/processing/{action}' +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionErrors = { + 400: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionError + = PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionErrors[keyof PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionErrors] + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionResponse + = PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionResponses[keyof PatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionResponses] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdRenameData = { + body: DocumentRenamePayload + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/rename' +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdRenameResponses = { + 200: DocumentResponse +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdRenameResponse + = PostDatasetsByDatasetIdDocumentsByDocumentIdRenameResponses[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdRenameResponses] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentData = { + body: SegmentCreatePayload + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segment' +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentResponse + = PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentResponses[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentResponses] + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentByActionData = { + body?: never + path: { + dataset_id: string + document_id: string + action: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segment/{action}' +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentByActionResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentByActionResponse + = PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentByActionResponses[keyof PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentByActionResponses] + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments' +} + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse + = DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses[keyof DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/batch_import' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponses] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportData = { + body: BatchImportPayload + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/batch_import' +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponse + = PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponses[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponses] + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdData = { + body?: never + path: { + dataset_id: string + document_id: string + segment_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' +} + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse + = DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses[keyof DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses] + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdData = { + body: SegmentUpdatePayload + path: { + dataset_id: string + document_id: string + segment_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse + = PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses[keyof PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksData = { + body?: never + path: { + dataset_id: string + document_id: string + segment_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses] + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksData = { + body?: never + path: { + dataset_id: string + document_id: string + segment_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks' +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse + = PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses[keyof PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksData = { + body: ChildChunkCreatePayload + path: { + dataset_id: string + document_id: string + segment_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks' +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse + = PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses] + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdData + = { + body?: never + path: { + dataset_id: string + document_id: string + segment_id: string + child_chunk_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' + } + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses + = { + 200: { + [key: string]: unknown + } + } + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse + = DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses[keyof DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses] + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdData + = { + body: ChildChunkUpdatePayload + path: { + dataset_id: string + document_id: string + segment_id: string + child_chunk_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' + } + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses + = { + 200: { + [key: string]: unknown + } + } + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse + = PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses[keyof PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/summary-status' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusError + = GetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusErrors[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusErrors] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdWebsiteSyncData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/website-sync' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdWebsiteSyncResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdWebsiteSyncResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdWebsiteSyncResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdWebsiteSyncResponses] + +export type GetDatasetsByDatasetIdErrorDocsData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/error-docs' +} + +export type GetDatasetsByDatasetIdErrorDocsErrors = { + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdErrorDocsError + = GetDatasetsByDatasetIdErrorDocsErrors[keyof GetDatasetsByDatasetIdErrorDocsErrors] + +export type GetDatasetsByDatasetIdErrorDocsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdErrorDocsResponse + = GetDatasetsByDatasetIdErrorDocsResponses[keyof GetDatasetsByDatasetIdErrorDocsResponses] + +export type PostDatasetsByDatasetIdExternalHitTestingData = { + body: ExternalHitTestingPayload + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/external-hit-testing' +} + +export type PostDatasetsByDatasetIdExternalHitTestingErrors = { + 400: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdExternalHitTestingError + = PostDatasetsByDatasetIdExternalHitTestingErrors[keyof PostDatasetsByDatasetIdExternalHitTestingErrors] + +export type PostDatasetsByDatasetIdExternalHitTestingResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdExternalHitTestingResponse + = PostDatasetsByDatasetIdExternalHitTestingResponses[keyof PostDatasetsByDatasetIdExternalHitTestingResponses] + +export type PostDatasetsByDatasetIdHitTestingData = { + body: HitTestingPayload + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/hit-testing' +} + +export type PostDatasetsByDatasetIdHitTestingErrors = { + 400: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdHitTestingError + = PostDatasetsByDatasetIdHitTestingErrors[keyof PostDatasetsByDatasetIdHitTestingErrors] + +export type PostDatasetsByDatasetIdHitTestingResponses = { + 200: HitTestingResponse +} + +export type PostDatasetsByDatasetIdHitTestingResponse + = PostDatasetsByDatasetIdHitTestingResponses[keyof PostDatasetsByDatasetIdHitTestingResponses] + +export type GetDatasetsByDatasetIdIndexingStatusData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/indexing-status' +} + +export type GetDatasetsByDatasetIdIndexingStatusResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdIndexingStatusResponse + = GetDatasetsByDatasetIdIndexingStatusResponses[keyof GetDatasetsByDatasetIdIndexingStatusResponses] + +export type GetDatasetsByDatasetIdMetadataData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/metadata' +} + +export type GetDatasetsByDatasetIdMetadataResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdMetadataResponse + = GetDatasetsByDatasetIdMetadataResponses[keyof GetDatasetsByDatasetIdMetadataResponses] + +export type PostDatasetsByDatasetIdMetadataData = { + body: MetadataArgs + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/metadata' +} + +export type PostDatasetsByDatasetIdMetadataResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdMetadataResponse + = PostDatasetsByDatasetIdMetadataResponses[keyof PostDatasetsByDatasetIdMetadataResponses] + +export type PostDatasetsByDatasetIdMetadataBuiltInByActionData = { + body?: never + path: { + dataset_id: string + action: string + } + query?: never + url: '/datasets/{dataset_id}/metadata/built-in/{action}' +} + +export type PostDatasetsByDatasetIdMetadataBuiltInByActionResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdMetadataBuiltInByActionResponse + = PostDatasetsByDatasetIdMetadataBuiltInByActionResponses[keyof PostDatasetsByDatasetIdMetadataBuiltInByActionResponses] + +export type DeleteDatasetsByDatasetIdMetadataByMetadataIdData = { + body?: never + path: { + dataset_id: string + metadata_id: string + } + query?: never + url: '/datasets/{dataset_id}/metadata/{metadata_id}' +} + +export type DeleteDatasetsByDatasetIdMetadataByMetadataIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdMetadataByMetadataIdResponse + = DeleteDatasetsByDatasetIdMetadataByMetadataIdResponses[keyof DeleteDatasetsByDatasetIdMetadataByMetadataIdResponses] + +export type PatchDatasetsByDatasetIdMetadataByMetadataIdData = { + body: MetadataUpdatePayload + path: { + dataset_id: string + metadata_id: string + } + query?: never + url: '/datasets/{dataset_id}/metadata/{metadata_id}' +} + +export type PatchDatasetsByDatasetIdMetadataByMetadataIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdMetadataByMetadataIdResponse + = PatchDatasetsByDatasetIdMetadataByMetadataIdResponses[keyof PatchDatasetsByDatasetIdMetadataByMetadataIdResponses] + +export type GetDatasetsByDatasetIdNotionSyncData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/notion/sync' +} + +export type GetDatasetsByDatasetIdNotionSyncResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdNotionSyncResponse + = GetDatasetsByDatasetIdNotionSyncResponses[keyof GetDatasetsByDatasetIdNotionSyncResponses] + +export type GetDatasetsByDatasetIdPermissionPartUsersData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/permission-part-users' +} + +export type GetDatasetsByDatasetIdPermissionPartUsersErrors = { + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdPermissionPartUsersError + = GetDatasetsByDatasetIdPermissionPartUsersErrors[keyof GetDatasetsByDatasetIdPermissionPartUsersErrors] + +export type GetDatasetsByDatasetIdPermissionPartUsersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdPermissionPartUsersResponse + = GetDatasetsByDatasetIdPermissionPartUsersResponses[keyof GetDatasetsByDatasetIdPermissionPartUsersResponses] + +export type GetDatasetsByDatasetIdQueriesData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/queries' +} + +export type GetDatasetsByDatasetIdQueriesResponses = { + 200: DatasetQueryDetail +} + +export type GetDatasetsByDatasetIdQueriesResponse + = GetDatasetsByDatasetIdQueriesResponses[keyof GetDatasetsByDatasetIdQueriesResponses] + +export type GetDatasetsByDatasetIdRelatedAppsData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/related-apps' +} + +export type GetDatasetsByDatasetIdRelatedAppsResponses = { + 200: RelatedAppList +} + +export type GetDatasetsByDatasetIdRelatedAppsResponse + = GetDatasetsByDatasetIdRelatedAppsResponses[keyof GetDatasetsByDatasetIdRelatedAppsResponses] + +export type PostDatasetsByDatasetIdRetryData = { + body: DocumentRetryPayload + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/retry' +} + +export type PostDatasetsByDatasetIdRetryResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdRetryResponse + = PostDatasetsByDatasetIdRetryResponses[keyof PostDatasetsByDatasetIdRetryResponses] + +export type GetDatasetsByDatasetIdUseCheckData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/use-check' +} + +export type GetDatasetsByDatasetIdUseCheckResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdUseCheckResponse + = GetDatasetsByDatasetIdUseCheckResponses[keyof GetDatasetsByDatasetIdUseCheckResponses] + +export type GetDatasetsByResourceIdApiKeysData = { + body?: never + path: { + resource_id: string + } + query?: never + url: '/datasets/{resource_id}/api-keys' +} + +export type GetDatasetsByResourceIdApiKeysResponses = { + 200: ApiKeyList +} + +export type GetDatasetsByResourceIdApiKeysResponse + = GetDatasetsByResourceIdApiKeysResponses[keyof GetDatasetsByResourceIdApiKeysResponses] + +export type PostDatasetsByResourceIdApiKeysData = { + body?: never + path: { + resource_id: string + } + query?: never + url: '/datasets/{resource_id}/api-keys' +} + +export type PostDatasetsByResourceIdApiKeysErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostDatasetsByResourceIdApiKeysError + = PostDatasetsByResourceIdApiKeysErrors[keyof PostDatasetsByResourceIdApiKeysErrors] + +export type PostDatasetsByResourceIdApiKeysResponses = { + 201: ApiKeyItem +} + +export type PostDatasetsByResourceIdApiKeysResponse + = PostDatasetsByResourceIdApiKeysResponses[keyof PostDatasetsByResourceIdApiKeysResponses] + +export type DeleteDatasetsByResourceIdApiKeysByApiKeyIdData = { + body?: never + path: { + resource_id: string + api_key_id: string + } + query?: never + url: '/datasets/{resource_id}/api-keys/{api_key_id}' +} + +export type DeleteDatasetsByResourceIdApiKeysByApiKeyIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByResourceIdApiKeysByApiKeyIdResponse + = DeleteDatasetsByResourceIdApiKeysByApiKeyIdResponses[keyof DeleteDatasetsByResourceIdApiKeysByApiKeyIdResponses] diff --git a/packages/contracts/generated/api/console/datasets/zod.gen.ts b/packages/contracts/generated/api/console/datasets/zod.gen.ts new file mode 100644 index 0000000000..76491c52a0 --- /dev/null +++ b/packages/contracts/generated/api/console/datasets/zod.gen.ts @@ -0,0 +1,1531 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * ApiKeyItem + */ +export const zApiKeyItem = z.object({ + created_at: z.int().nullish(), + id: z.string(), + last_used_at: z.int().nullish(), + token: z.string(), + type: z.string(), +}) + +/** + * ApiKeyList + */ +export const zApiKeyList = z.object({ + data: z.array(zApiKeyItem), +}) + +/** + * BatchImportPayload + */ +export const zBatchImportPayload = z.object({ + upload_file_id: z.string(), +}) + +/** + * ExternalDatasetCreatePayload + */ +export const zExternalDatasetCreatePayload = z.object({ + description: z.string().max(400).nullish(), + external_knowledge_api_id: z.string(), + external_knowledge_id: z.string(), + external_retrieval_model: z.record(z.string(), z.unknown()).nullish(), + name: z.string().min(1).max(100), +}) + +export const zDatasetDetail = z.record(z.string(), z.unknown()) + +/** + * ExternalKnowledgeApiPayload + */ +export const zExternalKnowledgeApiPayload = z.object({ + name: z.string().min(1).max(40), + settings: z.record(z.string(), z.unknown()), +}) + +/** + * IndexingEstimatePayload + */ +export const zIndexingEstimatePayload = z.object({ + dataset_id: z.string().nullish(), + doc_form: z.string().optional().default('text_model'), + doc_language: z.string().optional().default('English'), + indexing_technique: z.string(), + info_list: z.record(z.string(), z.unknown()), + process_rule: z.record(z.string(), z.unknown()), +}) + +/** + * NotionEstimatePayload + */ +export const zNotionEstimatePayload = z.object({ + doc_form: z.string().optional().default('text_model'), + doc_language: z.string().optional().default('English'), + notion_info_list: z.array(z.record(z.string(), z.unknown())), + process_rule: z.record(z.string(), z.unknown()), +}) + +/** + * DocumentBatchDownloadZipPayload + * + * Request payload for bulk downloading documents as a zip archive. + */ +export const zDocumentBatchDownloadZipPayload = z.object({ + document_ids: z.array(z.uuid()).min(1).max(100), +}) + +/** + * GenerateSummaryPayload + */ +export const zGenerateSummaryPayload = z.object({ + document_list: z.array(z.string()), +}) + +/** + * DocumentMetadataUpdatePayload + */ +export const zDocumentMetadataUpdatePayload = z.object({ + doc_metadata: z.unknown().optional(), + doc_type: z.string().nullish(), +}) + +/** + * DocumentRenamePayload + */ +export const zDocumentRenamePayload = z.object({ + name: z.string(), +}) + +/** + * SegmentCreatePayload + */ +export const zSegmentCreatePayload = z.object({ + answer: z.string().nullish(), + attachment_ids: z.array(z.string()).nullish(), + content: z.string(), + keywords: z.array(z.string()).nullish(), +}) + +/** + * SegmentUpdatePayload + */ +export const zSegmentUpdatePayload = z.object({ + answer: z.string().nullish(), + attachment_ids: z.array(z.string()).nullish(), + content: z.string(), + keywords: z.array(z.string()).nullish(), + regenerate_child_chunks: z.boolean().optional().default(false), + summary: z.string().nullish(), +}) + +/** + * ChildChunkCreatePayload + */ +export const zChildChunkCreatePayload = z.object({ + content: z.string(), +}) + +/** + * ChildChunkUpdatePayload + */ +export const zChildChunkUpdatePayload = z.object({ + content: z.string(), +}) + +/** + * ExternalHitTestingPayload + */ +export const zExternalHitTestingPayload = z.object({ + external_retrieval_model: z.record(z.string(), z.unknown()).nullish(), + metadata_filtering_conditions: z.record(z.string(), z.unknown()).nullish(), + query: z.string(), +}) + +/** + * MetadataArgs + */ +export const zMetadataArgs = z.object({ + name: z.string(), + type: z.enum(['string', 'number', 'time']), +}) + +/** + * MetadataUpdatePayload + */ +export const zMetadataUpdatePayload = z.object({ + name: z.string(), +}) + +export const zDatasetQueryDetail = z.record(z.string(), z.unknown()) + +export const zRelatedAppList = z.record(z.string(), z.unknown()) + +/** + * DocumentRetryPayload + */ +export const zDocumentRetryPayload = z.object({ + document_ids: z.array(z.string()), +}) + +/** + * DatasetPermissionEnum + */ +export const zDatasetPermissionEnum = z.enum(['only_me', 'all_team_members', 'partial_members']) + +/** + * DatasetCreatePayload + */ +export const zDatasetCreatePayload = z.object({ + description: z.string().max(400).optional().default(''), + external_knowledge_api_id: z.string().nullish(), + external_knowledge_id: z.string().nullish(), + indexing_technique: z.string().nullish(), + name: z.string().min(1).max(40), + permission: zDatasetPermissionEnum.optional(), + provider: z.string().optional().default('vendor'), +}) + +/** + * DatasetUpdatePayload + */ +export const zDatasetUpdatePayload = z.object({ + description: z.string().max(400).nullish(), + embedding_model: z.string().nullish(), + embedding_model_provider: z.string().nullish(), + external_knowledge_api_id: z.string().nullish(), + external_knowledge_id: z.string().nullish(), + external_retrieval_model: z.record(z.string(), z.unknown()).nullish(), + icon_info: z.record(z.string(), z.unknown()).nullish(), + indexing_technique: z.string().nullish(), + 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: zDatasetPermissionEnum.optional(), + retrieval_model: z.record(z.string(), z.unknown()).nullish(), + summary_index_setting: z.record(z.string(), z.unknown()).nullish(), +}) + +/** + * DatasetResponse + */ +export const zDatasetResponse = z.object({ + created_at: z.int().nullish(), + created_by: z.string().nullish(), + data_source_type: z.string().nullish(), + description: z.string().nullish(), + id: z.string(), + indexing_technique: z.string().nullish(), + name: z.string(), + permission: z.string().nullish(), +}) + +/** + * DocumentMetadataResponse + */ +export const zDocumentMetadataResponse = z.object({ + id: z.string(), + name: z.string(), + type: z.string(), + value: z.string().nullish(), +}) + +/** + * DocumentResponse + */ +export const zDocumentResponse = z.object({ + archived: z.boolean().nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + created_from: z.string().nullish(), + data_source_detail_dict: z.unknown().optional(), + data_source_info_dict: z.unknown().optional(), + data_source_type: z.string().nullish(), + dataset_process_rule_id: z.string().nullish(), + disabled_at: z.int().nullish(), + disabled_by: z.string().nullish(), + display_status: z.string().nullish(), + doc_form: z.string().nullish(), + doc_metadata_details: z.array(zDocumentMetadataResponse).optional(), + enabled: z.boolean().nullish(), + error: z.string().nullish(), + hit_count: z.int().nullish(), + id: z.string(), + indexing_status: z.string().nullish(), + name: z.string(), + need_summary: z.boolean().nullish(), + position: z.int().nullish(), + summary_index_status: z.string().nullish(), + tokens: z.int().nullish(), + word_count: z.int().nullish(), +}) + +/** + * DatasetAndDocumentResponse + */ +export const zDatasetAndDocumentResponse = z.object({ + batch: z.string(), + dataset: zDatasetResponse, + documents: z.array(zDocumentResponse), +}) + +/** + * RerankingModel + */ +export const zRerankingModel = z.object({ + reranking_model_name: z.string().nullish(), + reranking_provider_name: z.string().nullish(), +}) + +/** + * RetrievalMethod + */ +export const zRetrievalMethod = z.enum([ + 'semantic_search', + 'full_text_search', + 'hybrid_search', + 'keyword_search', +]) + +/** + * MetadataDetail + */ +export const zMetadataDetail = z.object({ + id: z.string(), + name: z.string(), + value: z.unknown().optional(), +}) + +/** + * DocumentMetadataOperation + */ +export const zDocumentMetadataOperation = z.object({ + document_id: z.string(), + metadata_list: z.array(zMetadataDetail), + partial_update: z.boolean().optional().default(false), +}) + +/** + * MetadataOperationData + * + * Metadata operation data + */ +export const zMetadataOperationData = z.object({ + operation_data: z.array(zDocumentMetadataOperation), +}) + +/** + * HitTestingChildChunk + */ +export const zHitTestingChildChunk = z.object({ + content: z.string().nullish(), + id: z.string().nullish(), + position: z.int().nullish(), + score: z.number().nullish(), +}) + +/** + * HitTestingFile + */ +export const zHitTestingFile = z.object({ + extension: z.string().nullish(), + id: z.string().nullish(), + mime_type: z.string().nullish(), + name: z.string().nullish(), + size: z.int().nullish(), + source_url: z.string().nullish(), +}) + +/** + * FileInfo + */ +export const zFileInfo = z.object({ + file_ids: z.array(z.string()), +}) + +/** + * WebsiteInfo + */ +export const zWebsiteInfo = z.object({ + job_id: z.string(), + only_main_content: z.boolean().optional().default(true), + provider: z.string(), + urls: z.array(z.string()), +}) + +/** + * PreProcessingRule + */ +export const zPreProcessingRule = z.object({ + enabled: z.boolean(), + id: z.string(), +}) + +/** + * Segmentation + */ +export const zSegmentation = z.object({ + chunk_overlap: z.int().optional().default(0), + max_tokens: z.int(), + separator: z.string().optional().default('\n'), +}) + +/** + * Rule + */ +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(), +}) + +/** + * ProcessRule + */ +export const zProcessRule = z.object({ + mode: z.enum(['automatic', 'custom', 'hierarchical']), + rules: zRule.optional(), +}) + +/** + * Condition + * + * Condition detail + */ +export const zCondition = z.object({ + comparison_operator: z.enum([ + 'contains', + 'not contains', + 'start with', + 'end with', + 'is', + 'is not', + 'empty', + 'not empty', + 'in', + 'not in', + '=', + '≠', + '>', + '<', + '≥', + '≤', + 'before', + 'after', + ]), + name: z.string(), + value: z.unknown().optional(), +}) + +/** + * MetadataFilteringCondition + * + * Metadata Filtering Condition. + */ +export const zMetadataFilteringCondition = z.object({ + conditions: z.array(zCondition).nullish(), + logical_operator: z.enum(['and', 'or']).nullish().default('and'), +}) + +/** + * WeightKeywordSetting + */ +export const zWeightKeywordSetting = z.object({ + keyword_weight: z.number(), +}) + +/** + * WeightVectorSetting + */ +export const zWeightVectorSetting = z.object({ + embedding_model_name: z.string(), + embedding_provider_name: z.string(), + vector_weight: z.number(), +}) + +/** + * WeightModel + */ +export const zWeightModel = z.object({ + keyword_setting: zWeightKeywordSetting.optional(), + vector_setting: zWeightVectorSetting.optional(), + weight_type: z.enum(['semantic_first', 'keyword_first', 'customized']).nullish(), +}) + +/** + * RetrievalModel + */ +export const zRetrievalModel = z.object({ + metadata_filtering_conditions: zMetadataFilteringCondition.optional(), + reranking_enable: z.boolean(), + reranking_mode: z.string().nullish(), + reranking_model: zRerankingModel.optional(), + score_threshold: z.number().nullish(), + score_threshold_enabled: z.boolean(), + search_method: zRetrievalMethod, + top_k: z.int(), + weights: zWeightModel.optional(), +}) + +/** + * HitTestingPayload + */ +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(), +}) + +/** + * HitTestingDocument + */ +export const zHitTestingDocument = z.object({ + data_source_type: z.string().nullish(), + doc_metadata: z.unknown().optional(), + doc_type: z.string().nullish(), + id: z.string().nullish(), + name: z.string().nullish(), +}) + +/** + * HitTestingSegment + */ +export const zHitTestingSegment = z.object({ + answer: z.string().nullish(), + completed_at: z.int().nullish(), + content: z.string().nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + disabled_at: z.int().nullish(), + disabled_by: z.string().nullish(), + document: zHitTestingDocument.optional(), + document_id: z.string().nullish(), + enabled: z.boolean().nullish(), + error: z.string().nullish(), + hit_count: z.int().nullish(), + id: z.string().nullish(), + index_node_hash: z.string().nullish(), + index_node_id: z.string().nullish(), + indexing_at: z.int().nullish(), + keywords: z.array(z.string()).optional(), + position: z.int().nullish(), + sign_content: z.string().nullish(), + status: z.string().nullish(), + stopped_at: z.int().nullish(), + tokens: z.int().nullish(), + word_count: z.int().nullish(), +}) + +/** + * HitTestingRecord + */ +export const zHitTestingRecord = z.object({ + child_chunks: z.array(zHitTestingChildChunk).optional(), + files: z.array(zHitTestingFile).optional(), + score: z.number().nullish(), + segment: zHitTestingSegment.optional(), + summary: z.string().nullish(), + tsne_position: z.unknown().optional(), +}) + +/** + * HitTestingResponse + */ +export const zHitTestingResponse = z.object({ + query: z.string(), + records: z.array(zHitTestingRecord).optional(), +}) + +/** + * NotionIcon + */ +export const zNotionIcon = z.object({ + emoji: z.string().nullish(), + type: z.string(), + url: z.string().nullish(), +}) + +/** + * NotionPage + */ +export const zNotionPage = z.object({ + page_icon: zNotionIcon.optional(), + page_id: z.string(), + page_name: z.string(), + type: z.string(), +}) + +/** + * NotionInfo + */ +export const zNotionInfo = z.object({ + credential_id: z.string(), + pages: z.array(zNotionPage), + workspace_id: z.string(), +}) + +/** + * InfoList + */ +export const zInfoList = z.object({ + data_source_type: z.enum(['upload_file', 'notion_import', 'website_crawl']), + file_info_list: zFileInfo.optional(), + notion_info_list: z.array(zNotionInfo).nullish(), + website_info_list: zWebsiteInfo.optional(), +}) + +/** + * DataSource + */ +export const zDataSource = z.object({ + info_list: zInfoList, +}) + +/** + * KnowledgeConfig + */ +export const zKnowledgeConfig = z.object({ + data_source: zDataSource.optional(), + doc_form: z.string().optional().default('text_model'), + doc_language: z.string().optional().default('English'), + duplicate: z.boolean().optional().default(true), + embedding_model: z.string().nullish(), + embedding_model_provider: z.string().nullish(), + indexing_technique: z.enum(['high_quality', 'economy']), + 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(), + summary_index_setting: z.record(z.string(), z.unknown()).nullish(), +}) + +export const zGetDatasetsQuery = z.object({ + page: z.string().optional(), + limit: z.string().optional(), + ids: z.string().optional(), + keyword: z.string().optional(), + tag_ids: z.string().optional(), + include_all: z.string().optional(), +}) + +/** + * Datasets retrieved successfully + */ +export const zGetDatasetsResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsBody = zDatasetCreatePayload + +/** + * Dataset created successfully + */ +export const zPostDatasetsResponse = z.record(z.string(), z.unknown()) + +/** + * API base info retrieved successfully + */ +export const zGetDatasetsApiBaseInfoResponse = z.record(z.string(), z.unknown()) + +/** + * API keys retrieved successfully + */ +export const zGetDatasetsApiKeysResponse = zApiKeyList + +/** + * API key created successfully + */ +export const zPostDatasetsApiKeysResponse = zApiKeyItem + +export const zDeleteDatasetsApiKeysByApiKeyIdPath = z.object({ + api_key_id: z.string(), +}) + +/** + * API key deleted successfully + */ +export const zDeleteDatasetsApiKeysByApiKeyIdResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsBatchImportStatusByJobIdPath = z.object({ + job_id: z.string(), +}) + +/** + * Success + */ +export const zGetDatasetsBatchImportStatusByJobIdResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsBatchImportStatusByJobIdBody = zBatchImportPayload + +export const zPostDatasetsBatchImportStatusByJobIdPath = z.object({ + job_id: z.string(), +}) + +/** + * Success + */ +export const zPostDatasetsBatchImportStatusByJobIdResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsExternalBody = zExternalDatasetCreatePayload + +/** + * External dataset created successfully + */ +export const zPostDatasetsExternalResponse = zDatasetDetail + +export const zGetDatasetsExternalKnowledgeApiQuery = z.object({ + page: z.string().optional(), + limit: z.string().optional(), + keyword: z.string().optional(), +}) + +/** + * External API templates retrieved successfully + */ +export const zGetDatasetsExternalKnowledgeApiResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsExternalKnowledgeApiBody = zExternalKnowledgeApiPayload + +/** + * Success + */ +export const zPostDatasetsExternalKnowledgeApiResponse = z.record(z.string(), z.unknown()) + +export const zDeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdPath = z.object({ + external_knowledge_api_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdPath = z.object({ + external_knowledge_api_id: z.string(), +}) + +/** + * External API template retrieved successfully + */ +export const zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdBody + = zExternalKnowledgeApiPayload + +export const zPatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdPath = z.object({ + external_knowledge_api_id: z.string(), +}) + +/** + * Success + */ +export const zPatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdUseCheckPath = z.object({ + external_knowledge_api_id: z.string(), +}) + +/** + * Usage check completed successfully + */ +export const zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdUseCheckResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsIndexingEstimateBody = zIndexingEstimatePayload + +/** + * Indexing estimate calculated successfully + */ +export const zPostDatasetsIndexingEstimateResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsInitBody = zKnowledgeConfig + +/** + * Dataset initialized successfully + */ +export const zPostDatasetsInitResponse = zDatasetAndDocumentResponse + +/** + * Success + */ +export const zGetDatasetsMetadataBuiltInResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetDatasetsNotionIndexingEstimateResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsNotionIndexingEstimateBody = zNotionEstimatePayload + +/** + * Success + */ +export const zPostDatasetsNotionIndexingEstimateResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsProcessRuleQuery = z.object({ + document_id: z.string().optional(), +}) + +/** + * Process rules retrieved successfully + */ +export const zGetDatasetsProcessRuleResponse = z.record(z.string(), z.unknown()) + +/** + * Retrieval settings retrieved successfully + */ +export const zGetDatasetsRetrievalSettingResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsRetrievalSettingByVectorTypePath = z.object({ + vector_type: z.string(), +}) + +/** + * Mock retrieval settings retrieved successfully + */ +export const zGetDatasetsRetrievalSettingByVectorTypeResponse = z.record(z.string(), z.unknown()) + +export const zDeleteDatasetsByDatasetIdPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteDatasetsByDatasetIdResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Dataset retrieved successfully + */ +export const zGetDatasetsByDatasetIdResponse = zDatasetDetail + +export const zPatchDatasetsByDatasetIdBody = zDatasetUpdatePayload + +export const zPatchDatasetsByDatasetIdPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Dataset updated successfully + */ +export const zPatchDatasetsByDatasetIdResponse = zDatasetDetail + +export const zPostDatasetsByDatasetIdApiKeysByStatusPath = z.object({ + dataset_id: z.string(), + status: z.string(), +}) + +/** + * Success + */ +export const zPostDatasetsByDatasetIdApiKeysByStatusResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdAutoDisableLogsPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Auto disable logs retrieved successfully + */ +export const zGetDatasetsByDatasetIdAutoDisableLogsResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdBatchByBatchIndexingEstimatePath = z.object({ + dataset_id: z.string(), + batch: z.string(), +}) + +/** + * Success + */ +export const zGetDatasetsByDatasetIdBatchByBatchIndexingEstimateResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdBatchByBatchIndexingStatusPath = z.object({ + dataset_id: z.string(), + batch: z.string(), +}) + +/** + * Success + */ +export const zGetDatasetsByDatasetIdBatchByBatchIndexingStatusResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteDatasetsByDatasetIdDocumentsPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteDatasetsByDatasetIdDocumentsResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdDocumentsPath = z.object({ + dataset_id: z.string(), +}) + +export const zGetDatasetsByDatasetIdDocumentsQuery = z.object({ + page: z.string().optional(), + limit: z.string().optional(), + keyword: z.string().optional(), + sort: z.string().optional(), + fetch: z.string().optional(), + status: z.string().optional(), +}) + +/** + * Documents retrieved successfully + */ +export const zGetDatasetsByDatasetIdDocumentsResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdDocumentsBody = zKnowledgeConfig + +export const zPostDatasetsByDatasetIdDocumentsPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Documents created successfully + */ +export const zPostDatasetsByDatasetIdDocumentsResponse = zDatasetAndDocumentResponse + +export const zPostDatasetsByDatasetIdDocumentsDownloadZipBody = zDocumentBatchDownloadZipPayload + +export const zPostDatasetsByDatasetIdDocumentsDownloadZipPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Success + */ +export const zPostDatasetsByDatasetIdDocumentsDownloadZipResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentsGenerateSummaryBody = zGenerateSummaryPayload + +export const zPostDatasetsByDatasetIdDocumentsGenerateSummaryPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Summary generation started successfully + */ +export const zPostDatasetsByDatasetIdDocumentsGenerateSummaryResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentsMetadataBody = zMetadataOperationData + +export const zPostDatasetsByDatasetIdDocumentsMetadataPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Success + */ +export const zPostDatasetsByDatasetIdDocumentsMetadataResponse = z.record(z.string(), z.unknown()) + +export const zPatchDatasetsByDatasetIdDocumentsStatusByActionBatchPath = z.object({ + dataset_id: z.string(), + action: z.string(), +}) + +/** + * Success + */ +export const zPatchDatasetsByDatasetIdDocumentsStatusByActionBatchResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdPath = z.object({ + document_id: z.string(), + dataset_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdQuery = z.object({ + metadata: z.string().optional(), +}) + +/** + * Document retrieved successfully + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdDownloadPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Success + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimatePath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Indexing estimate calculated successfully + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdIndexingEstimateResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Indexing status retrieved successfully + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdIndexingStatusResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPutDatasetsByDatasetIdDocumentsByDocumentIdMetadataBody + = zDocumentMetadataUpdatePayload + +export const zPutDatasetsByDatasetIdDocumentsByDocumentIdMetadataPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Document metadata updated successfully + */ +export const zPutDatasetsByDatasetIdDocumentsByDocumentIdMetadataResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdNotionSyncPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Success + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdNotionSyncResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdPipelineExecutionLogPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Success + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdPipelineExecutionLogResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPausePath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Success + */ +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingPauseResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumePath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Success + */ +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingResumeResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), + action: z.string(), +}) + +/** + * Processing status updated successfully + */ +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdProcessingByActionResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdRenameBody = zDocumentRenamePayload + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdRenamePath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Document renamed successfully + */ +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdRenameResponse = zDocumentResponse + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentBody = zSegmentCreatePayload + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Success + */ +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentByActionPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), + action: z.string(), +}) + +/** + * Success + */ +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentByActionResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Success + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Success + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportBody + = zBatchImportPayload + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Success + */ +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBatchImportResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdBody + = zSegmentUpdatePayload + +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), +}) + +/** + * Success + */ +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath + = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), + }) + +/** + * Success + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse + = z.record(z.string(), z.unknown()) + +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath + = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), + }) + +/** + * Success + */ +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse + = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksBody + = zChildChunkCreatePayload + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath + = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), + }) + +/** + * Success + */ +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse + = z.record(z.string(), z.unknown()) + +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdPath + = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), + child_chunk_id: z.string(), + }) + +/** + * Success + */ +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse + = z.record(z.string(), z.unknown()) + +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdBody + = zChildChunkUpdatePayload + +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdPath + = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), + child_chunk_id: z.string(), + }) + +/** + * Success + */ +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse + = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Summary status retrieved successfully + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSummaryStatusResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdWebsiteSyncPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Success + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdWebsiteSyncResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdErrorDocsPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Error documents retrieved successfully + */ +export const zGetDatasetsByDatasetIdErrorDocsResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdExternalHitTestingBody = zExternalHitTestingPayload + +export const zPostDatasetsByDatasetIdExternalHitTestingPath = z.object({ + dataset_id: z.string(), +}) + +/** + * External hit testing completed successfully + */ +export const zPostDatasetsByDatasetIdExternalHitTestingResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdHitTestingBody = zHitTestingPayload + +export const zPostDatasetsByDatasetIdHitTestingPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Hit testing completed successfully + */ +export const zPostDatasetsByDatasetIdHitTestingResponse = zHitTestingResponse + +export const zGetDatasetsByDatasetIdIndexingStatusPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Indexing status retrieved successfully + */ +export const zGetDatasetsByDatasetIdIndexingStatusResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdMetadataPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Success + */ +export const zGetDatasetsByDatasetIdMetadataResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdMetadataBody = zMetadataArgs + +export const zPostDatasetsByDatasetIdMetadataPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Success + */ +export const zPostDatasetsByDatasetIdMetadataResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdMetadataBuiltInByActionPath = z.object({ + dataset_id: z.string(), + action: z.string(), +}) + +/** + * Success + */ +export const zPostDatasetsByDatasetIdMetadataBuiltInByActionResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteDatasetsByDatasetIdMetadataByMetadataIdPath = z.object({ + dataset_id: z.string(), + metadata_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteDatasetsByDatasetIdMetadataByMetadataIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchDatasetsByDatasetIdMetadataByMetadataIdBody = zMetadataUpdatePayload + +export const zPatchDatasetsByDatasetIdMetadataByMetadataIdPath = z.object({ + dataset_id: z.string(), + metadata_id: z.string(), +}) + +/** + * Success + */ +export const zPatchDatasetsByDatasetIdMetadataByMetadataIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdNotionSyncPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Success + */ +export const zGetDatasetsByDatasetIdNotionSyncResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdPermissionPartUsersPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Permission users retrieved successfully + */ +export const zGetDatasetsByDatasetIdPermissionPartUsersResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdQueriesPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Query history retrieved successfully + */ +export const zGetDatasetsByDatasetIdQueriesResponse = zDatasetQueryDetail + +export const zGetDatasetsByDatasetIdRelatedAppsPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Related apps retrieved successfully + */ +export const zGetDatasetsByDatasetIdRelatedAppsResponse = zRelatedAppList + +export const zPostDatasetsByDatasetIdRetryBody = zDocumentRetryPayload + +export const zPostDatasetsByDatasetIdRetryPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Success + */ +export const zPostDatasetsByDatasetIdRetryResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdUseCheckPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Dataset use status retrieved successfully + */ +export const zGetDatasetsByDatasetIdUseCheckResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByResourceIdApiKeysPath = z.object({ + resource_id: z.string(), +}) + +/** + * API keys retrieved successfully + */ +export const zGetDatasetsByResourceIdApiKeysResponse = zApiKeyList + +export const zPostDatasetsByResourceIdApiKeysPath = z.object({ + resource_id: z.string(), +}) + +/** + * API key created successfully + */ +export const zPostDatasetsByResourceIdApiKeysResponse = zApiKeyItem + +export const zDeleteDatasetsByResourceIdApiKeysByApiKeyIdPath = z.object({ + resource_id: z.string(), + api_key_id: z.string(), +}) + +/** + * API key deleted successfully + */ +export const zDeleteDatasetsByResourceIdApiKeysByApiKeyIdResponse = z.record( + z.string(), + z.unknown(), +) diff --git a/packages/contracts/generated/api/console/email-code-login/orpc.gen.ts b/packages/contracts/generated/api/console/email-code-login/orpc.gen.ts new file mode 100644 index 0000000000..54edabc29f --- /dev/null +++ b/packages/contracts/generated/api/console/email-code-login/orpc.gen.ts @@ -0,0 +1,46 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zPostEmailCodeLoginBody, + zPostEmailCodeLoginResponse, + zPostEmailCodeLoginValidityBody, + zPostEmailCodeLoginValidityResponse, +} from './zod.gen' + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postEmailCodeLoginValidity', + path: '/email-code-login/validity', + tags: ['console'], + }) + .input(z.object({ body: zPostEmailCodeLoginValidityBody })) + .output(zPostEmailCodeLoginValidityResponse) + +export const validity = { + post, +} + +export const post2 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postEmailCodeLogin', + path: '/email-code-login', + tags: ['console'], + }) + .input(z.object({ body: zPostEmailCodeLoginBody })) + .output(zPostEmailCodeLoginResponse) + +export const emailCodeLogin = { + post: post2, + validity, +} + +export const contract = { + emailCodeLogin, +} diff --git a/packages/contracts/generated/api/console/email-code-login/types.gen.ts b/packages/contracts/generated/api/console/email-code-login/types.gen.ts new file mode 100644 index 0000000000..851a8d568d --- /dev/null +++ b/packages/contracts/generated/api/console/email-code-login/types.gen.ts @@ -0,0 +1,49 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type EmailPayload = { + email: string + language?: string | null +} + +export type EmailCodeLoginPayload = { + code: string + email: string + language?: string | null + token: string +} + +export type PostEmailCodeLoginData = { + body: EmailPayload + path?: never + query?: never + url: '/email-code-login' +} + +export type PostEmailCodeLoginResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostEmailCodeLoginResponse + = PostEmailCodeLoginResponses[keyof PostEmailCodeLoginResponses] + +export type PostEmailCodeLoginValidityData = { + body: EmailCodeLoginPayload + path?: never + query?: never + url: '/email-code-login/validity' +} + +export type PostEmailCodeLoginValidityResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostEmailCodeLoginValidityResponse + = PostEmailCodeLoginValidityResponses[keyof PostEmailCodeLoginValidityResponses] diff --git a/packages/contracts/generated/api/console/email-code-login/zod.gen.ts b/packages/contracts/generated/api/console/email-code-login/zod.gen.ts new file mode 100644 index 0000000000..0ff511c722 --- /dev/null +++ b/packages/contracts/generated/api/console/email-code-login/zod.gen.ts @@ -0,0 +1,35 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * EmailPayload + */ +export const zEmailPayload = z.object({ + email: z.string(), + language: z.string().nullish(), +}) + +/** + * EmailCodeLoginPayload + */ +export const zEmailCodeLoginPayload = z.object({ + code: z.string(), + email: z.string(), + language: z.string().nullish(), + token: z.string(), +}) + +export const zPostEmailCodeLoginBody = zEmailPayload + +/** + * Success + */ +export const zPostEmailCodeLoginResponse = z.record(z.string(), z.unknown()) + +export const zPostEmailCodeLoginValidityBody = zEmailCodeLoginPayload + +/** + * Success + */ +export const zPostEmailCodeLoginValidityResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/email-register/orpc.gen.ts b/packages/contracts/generated/api/console/email-register/orpc.gen.ts new file mode 100644 index 0000000000..0bd724aba9 --- /dev/null +++ b/packages/contracts/generated/api/console/email-register/orpc.gen.ts @@ -0,0 +1,57 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' + +import { + zPostEmailRegisterResponse, + zPostEmailRegisterSendEmailResponse, + zPostEmailRegisterValidityResponse, +} from './zod.gen' + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postEmailRegisterSendEmail', + path: '/email-register/send-email', + tags: ['console'], + }) + .output(zPostEmailRegisterSendEmailResponse) + +export const sendEmail = { + post, +} + +export const post2 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postEmailRegisterValidity', + path: '/email-register/validity', + tags: ['console'], + }) + .output(zPostEmailRegisterValidityResponse) + +export const validity = { + post: post2, +} + +export const post3 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postEmailRegister', + path: '/email-register', + tags: ['console'], + }) + .output(zPostEmailRegisterResponse) + +export const emailRegister = { + post: post3, + sendEmail, + validity, +} + +export const contract = { + emailRegister, +} diff --git a/packages/contracts/generated/api/console/email-register/types.gen.ts b/packages/contracts/generated/api/console/email-register/types.gen.ts new file mode 100644 index 0000000000..3fe5129fbf --- /dev/null +++ b/packages/contracts/generated/api/console/email-register/types.gen.ts @@ -0,0 +1,52 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type PostEmailRegisterData = { + body?: never + path?: never + query?: never + url: '/email-register' +} + +export type PostEmailRegisterResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostEmailRegisterResponse = PostEmailRegisterResponses[keyof PostEmailRegisterResponses] + +export type PostEmailRegisterSendEmailData = { + body?: never + path?: never + query?: never + url: '/email-register/send-email' +} + +export type PostEmailRegisterSendEmailResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostEmailRegisterSendEmailResponse + = PostEmailRegisterSendEmailResponses[keyof PostEmailRegisterSendEmailResponses] + +export type PostEmailRegisterValidityData = { + body?: never + path?: never + query?: never + url: '/email-register/validity' +} + +export type PostEmailRegisterValidityResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostEmailRegisterValidityResponse + = PostEmailRegisterValidityResponses[keyof PostEmailRegisterValidityResponses] diff --git a/packages/contracts/generated/api/console/email-register/zod.gen.ts b/packages/contracts/generated/api/console/email-register/zod.gen.ts new file mode 100644 index 0000000000..11720317f2 --- /dev/null +++ b/packages/contracts/generated/api/console/email-register/zod.gen.ts @@ -0,0 +1,18 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * Success + */ +export const zPostEmailRegisterResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPostEmailRegisterSendEmailResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPostEmailRegisterValidityResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/explore/orpc.gen.ts b/packages/contracts/generated/api/console/explore/orpc.gen.ts new file mode 100644 index 0000000000..4b37a0a4fd --- /dev/null +++ b/packages/contracts/generated/api/console/explore/orpc.gen.ts @@ -0,0 +1,70 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetExploreAppsByAppIdPath, + zGetExploreAppsByAppIdResponse, + zGetExploreAppsQuery, + zGetExploreAppsResponse, + zGetExploreBannersResponse, +} from './zod.gen' + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getExploreAppsByAppId', + path: '/explore/apps/{app_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetExploreAppsByAppIdPath })) + .output(zGetExploreAppsByAppIdResponse) + +export const byAppId = { + get, +} + +export const get2 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getExploreApps', + path: '/explore/apps', + tags: ['console'], + }) + .input(z.object({ query: zGetExploreAppsQuery.optional() })) + .output(zGetExploreAppsResponse) + +export const apps = { + get: get2, + byAppId, +} + +/** + * Get banner list + */ +export const get3 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getExploreBanners', + path: '/explore/banners', + summary: 'Get banner list', + tags: ['default'], + }) + .output(zGetExploreBannersResponse) + +export const banners = { + get: get3, +} + +export const explore = { + apps, + banners, +} + +export const contract = { + explore, +} diff --git a/packages/contracts/generated/api/console/explore/types.gen.ts b/packages/contracts/generated/api/console/explore/types.gen.ts new file mode 100644 index 0000000000..db56dbdac0 --- /dev/null +++ b/packages/contracts/generated/api/console/explore/types.gen.ts @@ -0,0 +1,80 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type RecommendedAppListResponse = { + categories: Array + recommended_apps: Array +} + +export type RecommendedAppResponse = { + app?: RecommendedAppInfoResponse + app_id: string + can_trial?: boolean | null + category?: string | null + copyright?: string | null + custom_disclaimer?: string | null + description?: string | null + is_listed?: boolean | null + position?: number | null + privacy_policy?: string | null +} + +export type RecommendedAppInfoResponse = { + icon?: string | null + icon_background?: string | null + icon_type?: string | null + id: string + mode?: string | null + name?: string | null +} + +export type GetExploreAppsData = { + body?: never + path?: never + query?: { + language?: string | null + } + url: '/explore/apps' +} + +export type GetExploreAppsResponses = { + 200: RecommendedAppListResponse +} + +export type GetExploreAppsResponse = GetExploreAppsResponses[keyof GetExploreAppsResponses] + +export type GetExploreAppsByAppIdData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/explore/apps/{app_id}' +} + +export type GetExploreAppsByAppIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetExploreAppsByAppIdResponse + = GetExploreAppsByAppIdResponses[keyof GetExploreAppsByAppIdResponses] + +export type GetExploreBannersData = { + body?: never + path?: never + query?: never + url: '/explore/banners' +} + +export type GetExploreBannersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetExploreBannersResponse = GetExploreBannersResponses[keyof GetExploreBannersResponses] diff --git a/packages/contracts/generated/api/console/explore/zod.gen.ts b/packages/contracts/generated/api/console/explore/zod.gen.ts new file mode 100644 index 0000000000..2ceb54e7bd --- /dev/null +++ b/packages/contracts/generated/api/console/explore/zod.gen.ts @@ -0,0 +1,62 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * RecommendedAppInfoResponse + */ +export const zRecommendedAppInfoResponse = z.object({ + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: z.string().nullish(), + id: z.string(), + mode: z.string().nullish(), + name: z.string().nullish(), +}) + +/** + * RecommendedAppResponse + */ +export const zRecommendedAppResponse = z.object({ + app: zRecommendedAppInfoResponse.optional(), + app_id: z.string(), + can_trial: z.boolean().nullish(), + category: z.string().nullish(), + copyright: z.string().nullish(), + custom_disclaimer: z.string().nullish(), + description: z.string().nullish(), + is_listed: z.boolean().nullish(), + position: z.int().nullish(), + privacy_policy: z.string().nullish(), +}) + +/** + * RecommendedAppListResponse + */ +export const zRecommendedAppListResponse = z.object({ + categories: z.array(z.string()), + recommended_apps: z.array(zRecommendedAppResponse), +}) + +export const zGetExploreAppsQuery = z.object({ + language: z.string().nullish(), +}) + +/** + * Success + */ +export const zGetExploreAppsResponse = zRecommendedAppListResponse + +export const zGetExploreAppsByAppIdPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zGetExploreAppsByAppIdResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetExploreBannersResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/features/orpc.gen.ts b/packages/contracts/generated/api/console/features/orpc.gen.ts new file mode 100644 index 0000000000..e24ec3d964 --- /dev/null +++ b/packages/contracts/generated/api/console/features/orpc.gen.ts @@ -0,0 +1,30 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' + +import { zGetFeaturesResponse } from './zod.gen' + +/** + * Get feature configuration for current tenant + * + * Get feature configuration for current tenant + */ +export const get = oc + .route({ + description: 'Get feature configuration for current tenant', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getFeatures', + path: '/features', + summary: 'Get feature configuration for current tenant', + tags: ['console'], + }) + .output(zGetFeaturesResponse) + +export const features = { + get, +} + +export const contract = { + features, +} diff --git a/packages/contracts/generated/api/console/features/types.gen.ts b/packages/contracts/generated/api/console/features/types.gen.ts new file mode 100644 index 0000000000..eed18d5344 --- /dev/null +++ b/packages/contracts/generated/api/console/features/types.gen.ts @@ -0,0 +1,22 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type FeatureResponse = { + [key: string]: unknown +} + +export type GetFeaturesData = { + body?: never + path?: never + query?: never + url: '/features' +} + +export type GetFeaturesResponses = { + 200: FeatureResponse +} + +export type GetFeaturesResponse = GetFeaturesResponses[keyof GetFeaturesResponses] diff --git a/packages/contracts/generated/api/console/features/zod.gen.ts b/packages/contracts/generated/api/console/features/zod.gen.ts new file mode 100644 index 0000000000..1e967fb879 --- /dev/null +++ b/packages/contracts/generated/api/console/features/zod.gen.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +export const zFeatureResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetFeaturesResponse = zFeatureResponse diff --git a/packages/contracts/generated/api/console/files/orpc.gen.ts b/packages/contracts/generated/api/console/files/orpc.gen.ts new file mode 100644 index 0000000000..2ee949edc2 --- /dev/null +++ b/packages/contracts/generated/api/console/files/orpc.gen.ts @@ -0,0 +1,81 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetFilesByFileIdPreviewPath, + zGetFilesByFileIdPreviewResponse, + zGetFilesSupportTypeResponse, + zGetFilesUploadResponse, + zPostFilesUploadResponse, +} from './zod.gen' + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getFilesSupportType', + path: '/files/support-type', + tags: ['console'], + }) + .output(zGetFilesSupportTypeResponse) + +export const supportType = { + get, +} + +export const get2 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getFilesUpload', + path: '/files/upload', + tags: ['console'], + }) + .output(zGetFilesUploadResponse) + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postFilesUpload', + path: '/files/upload', + successStatus: 201, + tags: ['console'], + }) + .output(zPostFilesUploadResponse) + +export const upload = { + get: get2, + post, +} + +export const get3 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getFilesByFileIdPreview', + path: '/files/{file_id}/preview', + tags: ['console'], + }) + .input(z.object({ params: zGetFilesByFileIdPreviewPath })) + .output(zGetFilesByFileIdPreviewResponse) + +export const preview = { + get: get3, +} + +export const byFileId = { + preview, +} + +export const files = { + supportType, + upload, + byFileId, +} + +export const contract = { + files, +} diff --git a/packages/contracts/generated/api/console/files/types.gen.ts b/packages/contracts/generated/api/console/files/types.gen.ts new file mode 100644 index 0000000000..5620235461 --- /dev/null +++ b/packages/contracts/generated/api/console/files/types.gen.ts @@ -0,0 +1,95 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type UploadConfig = { + attachment_image_file_size_limit?: number | null + audio_file_size_limit: number + batch_count_limit: number + file_size_limit: number + file_upload_limit?: number | null + image_file_batch_limit: number + image_file_size_limit: number + single_chunk_attachment_limit: number + video_file_size_limit: number + workflow_file_upload_limit: number +} + +export type FileResponse = { + conversation_id?: string | null + created_at?: number | null + created_by?: string | null + extension?: string | null + file_key?: string | null + id: string + mime_type?: string | null + name: string + original_url?: string | null + preview_url?: string | null + size: number + source_url?: string | null + tenant_id?: string | null + user_id?: string | null +} + +export type GetFilesSupportTypeData = { + body?: never + path?: never + query?: never + url: '/files/support-type' +} + +export type GetFilesSupportTypeResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetFilesSupportTypeResponse + = GetFilesSupportTypeResponses[keyof GetFilesSupportTypeResponses] + +export type GetFilesUploadData = { + body?: never + path?: never + query?: never + url: '/files/upload' +} + +export type GetFilesUploadResponses = { + 200: UploadConfig +} + +export type GetFilesUploadResponse = GetFilesUploadResponses[keyof GetFilesUploadResponses] + +export type PostFilesUploadData = { + body?: never + path?: never + query?: never + url: '/files/upload' +} + +export type PostFilesUploadResponses = { + 201: FileResponse +} + +export type PostFilesUploadResponse = PostFilesUploadResponses[keyof PostFilesUploadResponses] + +export type GetFilesByFileIdPreviewData = { + body?: never + path: { + file_id: string + } + query?: never + url: '/files/{file_id}/preview' +} + +export type GetFilesByFileIdPreviewResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetFilesByFileIdPreviewResponse + = GetFilesByFileIdPreviewResponses[keyof GetFilesByFileIdPreviewResponses] diff --git a/packages/contracts/generated/api/console/files/zod.gen.ts b/packages/contracts/generated/api/console/files/zod.gen.ts new file mode 100644 index 0000000000..d61e7795ce --- /dev/null +++ b/packages/contracts/generated/api/console/files/zod.gen.ts @@ -0,0 +1,63 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * UploadConfig + */ +export const zUploadConfig = z.object({ + attachment_image_file_size_limit: z.int().nullish(), + audio_file_size_limit: z.int(), + batch_count_limit: z.int(), + file_size_limit: z.int(), + file_upload_limit: z.int().nullish(), + image_file_batch_limit: z.int(), + image_file_size_limit: z.int(), + single_chunk_attachment_limit: z.int(), + video_file_size_limit: z.int(), + workflow_file_upload_limit: z.int(), +}) + +/** + * FileResponse + */ +export const zFileResponse = z.object({ + conversation_id: z.string().nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + extension: z.string().nullish(), + file_key: z.string().nullish(), + id: z.string(), + mime_type: z.string().nullish(), + name: z.string(), + original_url: z.string().nullish(), + preview_url: z.string().nullish(), + size: z.int(), + source_url: z.string().nullish(), + tenant_id: z.string().nullish(), + user_id: z.string().nullish(), +}) + +/** + * Success + */ +export const zGetFilesSupportTypeResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetFilesUploadResponse = zUploadConfig + +/** + * File uploaded successfully + */ +export const zPostFilesUploadResponse = zFileResponse + +export const zGetFilesByFileIdPreviewPath = z.object({ + file_id: z.string(), +}) + +/** + * Success + */ +export const zGetFilesByFileIdPreviewResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/forgot-password/orpc.gen.ts b/packages/contracts/generated/api/console/forgot-password/orpc.gen.ts new file mode 100644 index 0000000000..a5a33f407b --- /dev/null +++ b/packages/contracts/generated/api/console/forgot-password/orpc.gen.ts @@ -0,0 +1,76 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zPostForgotPasswordBody, + zPostForgotPasswordResetsBody, + zPostForgotPasswordResetsResponse, + zPostForgotPasswordResponse, + zPostForgotPasswordValidityBody, + zPostForgotPasswordValidityResponse, +} from './zod.gen' + +/** + * Reset password with verification token + */ +export const post = oc + .route({ + description: 'Reset password with verification token', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postForgotPasswordResets', + path: '/forgot-password/resets', + tags: ['console'], + }) + .input(z.object({ body: zPostForgotPasswordResetsBody })) + .output(zPostForgotPasswordResetsResponse) + +export const resets = { + post, +} + +/** + * Verify password reset code + */ +export const post2 = oc + .route({ + description: 'Verify password reset code', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postForgotPasswordValidity', + path: '/forgot-password/validity', + tags: ['console'], + }) + .input(z.object({ body: zPostForgotPasswordValidityBody })) + .output(zPostForgotPasswordValidityResponse) + +export const validity = { + post: post2, +} + +/** + * Send password reset email + */ +export const post3 = oc + .route({ + description: 'Send password reset email', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postForgotPassword', + path: '/forgot-password', + tags: ['console'], + }) + .input(z.object({ body: zPostForgotPasswordBody })) + .output(zPostForgotPasswordResponse) + +export const forgotPassword = { + post: post3, + resets, + validity, +} + +export const contract = { + forgotPassword, +} diff --git a/packages/contracts/generated/api/console/forgot-password/types.gen.ts b/packages/contracts/generated/api/console/forgot-password/types.gen.ts new file mode 100644 index 0000000000..b58165c8eb --- /dev/null +++ b/packages/contracts/generated/api/console/forgot-password/types.gen.ts @@ -0,0 +1,106 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type ForgotPasswordSendPayload = { + email: string + language?: string | null +} + +export type ForgotPasswordEmailResponse = { + code?: string | null + data?: string | null + result: string +} + +export type ForgotPasswordResetPayload = { + new_password: string + password_confirm: string + token: string +} + +export type ForgotPasswordResetResponse = { + result: string +} + +export type ForgotPasswordCheckPayload = { + code: string + email: string + token: string +} + +export type ForgotPasswordCheckResponse = { + email: string + is_valid: boolean + token: string +} + +export type PostForgotPasswordData = { + body: ForgotPasswordSendPayload + path?: never + query?: never + url: '/forgot-password' +} + +export type PostForgotPasswordErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostForgotPasswordError = PostForgotPasswordErrors[keyof PostForgotPasswordErrors] + +export type PostForgotPasswordResponses = { + 200: ForgotPasswordEmailResponse +} + +export type PostForgotPasswordResponse + = PostForgotPasswordResponses[keyof PostForgotPasswordResponses] + +export type PostForgotPasswordResetsData = { + body: ForgotPasswordResetPayload + path?: never + query?: never + url: '/forgot-password/resets' +} + +export type PostForgotPasswordResetsErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostForgotPasswordResetsError + = PostForgotPasswordResetsErrors[keyof PostForgotPasswordResetsErrors] + +export type PostForgotPasswordResetsResponses = { + 200: ForgotPasswordResetResponse +} + +export type PostForgotPasswordResetsResponse + = PostForgotPasswordResetsResponses[keyof PostForgotPasswordResetsResponses] + +export type PostForgotPasswordValidityData = { + body: ForgotPasswordCheckPayload + path?: never + query?: never + url: '/forgot-password/validity' +} + +export type PostForgotPasswordValidityErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostForgotPasswordValidityError + = PostForgotPasswordValidityErrors[keyof PostForgotPasswordValidityErrors] + +export type PostForgotPasswordValidityResponses = { + 200: ForgotPasswordCheckResponse +} + +export type PostForgotPasswordValidityResponse + = PostForgotPasswordValidityResponses[keyof PostForgotPasswordValidityResponses] diff --git a/packages/contracts/generated/api/console/forgot-password/zod.gen.ts b/packages/contracts/generated/api/console/forgot-password/zod.gen.ts new file mode 100644 index 0000000000..fdbb7b033d --- /dev/null +++ b/packages/contracts/generated/api/console/forgot-password/zod.gen.ts @@ -0,0 +1,75 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * ForgotPasswordSendPayload + */ +export const zForgotPasswordSendPayload = z.object({ + email: z.string(), + language: z.string().nullish(), +}) + +/** + * ForgotPasswordEmailResponse + */ +export const zForgotPasswordEmailResponse = z.object({ + code: z.string().nullish(), + data: z.string().nullish(), + result: z.string(), +}) + +/** + * ForgotPasswordResetPayload + */ +export const zForgotPasswordResetPayload = z.object({ + new_password: z.string(), + password_confirm: z.string(), + token: z.string().min(1), +}) + +/** + * ForgotPasswordResetResponse + */ +export const zForgotPasswordResetResponse = z.object({ + result: z.string(), +}) + +/** + * ForgotPasswordCheckPayload + */ +export const zForgotPasswordCheckPayload = z.object({ + code: z.string(), + email: z.string(), + token: z.string().min(1), +}) + +/** + * ForgotPasswordCheckResponse + */ +export const zForgotPasswordCheckResponse = z.object({ + email: z.string(), + is_valid: z.boolean(), + token: z.string(), +}) + +export const zPostForgotPasswordBody = zForgotPasswordSendPayload + +/** + * Email sent successfully + */ +export const zPostForgotPasswordResponse = zForgotPasswordEmailResponse + +export const zPostForgotPasswordResetsBody = zForgotPasswordResetPayload + +/** + * Password reset successfully + */ +export const zPostForgotPasswordResetsResponse = zForgotPasswordResetResponse + +export const zPostForgotPasswordValidityBody = zForgotPasswordCheckPayload + +/** + * Code verified successfully + */ +export const zPostForgotPasswordValidityResponse = zForgotPasswordCheckResponse diff --git a/packages/contracts/generated/api/console/form/orpc.gen.ts b/packages/contracts/generated/api/console/form/orpc.gen.ts new file mode 100644 index 0000000000..f6d76b28c0 --- /dev/null +++ b/packages/contracts/generated/api/console/form/orpc.gen.ts @@ -0,0 +1,73 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetFormHumanInputByFormTokenPath, + zGetFormHumanInputByFormTokenResponse, + zPostFormHumanInputByFormTokenPath, + zPostFormHumanInputByFormTokenResponse, +} from './zod.gen' + +/** + * Get human input form definition by form token + * + * GET /console/api/form/human_input/ + */ +export const get = oc + .route({ + description: 'GET /console/api/form/human_input/', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getFormHumanInputByFormToken', + path: '/form/human_input/{form_token}', + summary: 'Get human input form definition by form token', + tags: ['console'], + }) + .input(z.object({ params: zGetFormHumanInputByFormTokenPath })) + .output(zGetFormHumanInputByFormTokenResponse) + +/** + * Submit human input form by form token + * + * POST /console/api/form/human_input/ + * + * Request body: + * { + * "inputs": { + * "content": "User input content" + * }, + * "action": "Approve" + * } + */ +export const post = oc + .route({ + description: + 'POST /console/api/form/human_input/\n\nRequest body:\n{\n "inputs": {\n "content": "User input content"\n },\n "action": "Approve"\n}', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postFormHumanInputByFormToken', + path: '/form/human_input/{form_token}', + summary: 'Submit human input form by form token', + tags: ['console'], + }) + .input(z.object({ params: zPostFormHumanInputByFormTokenPath })) + .output(zPostFormHumanInputByFormTokenResponse) + +export const byFormToken = { + get, + post, +} + +export const humanInput = { + byFormToken, +} + +export const form = { + humanInput, +} + +export const contract = { + form, +} diff --git a/packages/contracts/generated/api/console/form/types.gen.ts b/packages/contracts/generated/api/console/form/types.gen.ts new file mode 100644 index 0000000000..80c0c1a474 --- /dev/null +++ b/packages/contracts/generated/api/console/form/types.gen.ts @@ -0,0 +1,41 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type GetFormHumanInputByFormTokenData = { + body?: never + path: { + form_token: string + } + query?: never + url: '/form/human_input/{form_token}' +} + +export type GetFormHumanInputByFormTokenResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetFormHumanInputByFormTokenResponse + = GetFormHumanInputByFormTokenResponses[keyof GetFormHumanInputByFormTokenResponses] + +export type PostFormHumanInputByFormTokenData = { + body?: never + path: { + form_token: string + } + query?: never + url: '/form/human_input/{form_token}' +} + +export type PostFormHumanInputByFormTokenResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostFormHumanInputByFormTokenResponse + = PostFormHumanInputByFormTokenResponses[keyof PostFormHumanInputByFormTokenResponses] diff --git a/packages/contracts/generated/api/console/form/zod.gen.ts b/packages/contracts/generated/api/console/form/zod.gen.ts new file mode 100644 index 0000000000..840b04383e --- /dev/null +++ b/packages/contracts/generated/api/console/form/zod.gen.ts @@ -0,0 +1,21 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +export const zGetFormHumanInputByFormTokenPath = z.object({ + form_token: z.string(), +}) + +/** + * Success + */ +export const zGetFormHumanInputByFormTokenResponse = z.record(z.string(), z.unknown()) + +export const zPostFormHumanInputByFormTokenPath = z.object({ + form_token: z.string(), +}) + +/** + * Success + */ +export const zPostFormHumanInputByFormTokenResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/info/orpc.gen.ts b/packages/contracts/generated/api/console/info/orpc.gen.ts new file mode 100644 index 0000000000..4eb342e9cf --- /dev/null +++ b/packages/contracts/generated/api/console/info/orpc.gen.ts @@ -0,0 +1,23 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' + +import { zPostInfoResponse } from './zod.gen' + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInfo', + path: '/info', + tags: ['console'], + }) + .output(zPostInfoResponse) + +export const info = { + post, +} + +export const contract = { + info, +} diff --git a/packages/contracts/generated/api/console/info/types.gen.ts b/packages/contracts/generated/api/console/info/types.gen.ts new file mode 100644 index 0000000000..975f887a99 --- /dev/null +++ b/packages/contracts/generated/api/console/info/types.gen.ts @@ -0,0 +1,35 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type TenantInfoResponse = { + created_at?: number | null + custom_config?: { + [key: string]: unknown + } | null + id: string + in_trial?: boolean | null + name?: string | null + next_credit_reset_date?: number | null + plan?: string | null + role?: string | null + status?: string | null + trial_credits?: number | null + trial_credits_used?: number | null + trial_end_reason?: string | null +} + +export type PostInfoData = { + body?: never + path?: never + query?: never + url: '/info' +} + +export type PostInfoResponses = { + 200: TenantInfoResponse +} + +export type PostInfoResponse = PostInfoResponses[keyof PostInfoResponses] diff --git a/packages/contracts/generated/api/console/info/zod.gen.ts b/packages/contracts/generated/api/console/info/zod.gen.ts new file mode 100644 index 0000000000..adb1ea23f2 --- /dev/null +++ b/packages/contracts/generated/api/console/info/zod.gen.ts @@ -0,0 +1,26 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * TenantInfoResponse + */ +export const zTenantInfoResponse = z.object({ + created_at: z.int().nullish(), + custom_config: z.record(z.string(), z.unknown()).nullish(), + id: z.string(), + in_trial: z.boolean().nullish(), + name: z.string().nullish(), + next_credit_reset_date: z.int().nullish(), + plan: z.string().nullish(), + role: z.string().nullish(), + status: z.string().nullish(), + trial_credits: z.int().nullish(), + trial_credits_used: z.int().nullish(), + trial_end_reason: z.string().nullish(), +}) + +/** + * Success + */ +export const zPostInfoResponse = zTenantInfoResponse diff --git a/packages/contracts/generated/api/console/installed-apps/orpc.gen.ts b/packages/contracts/generated/api/console/installed-apps/orpc.gen.ts new file mode 100644 index 0000000000..c2b0b2eb37 --- /dev/null +++ b/packages/contracts/generated/api/console/installed-apps/orpc.gen.ts @@ -0,0 +1,572 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteInstalledAppsByInstalledAppIdConversationsByCIdPath, + zDeleteInstalledAppsByInstalledAppIdConversationsByCIdResponse, + zDeleteInstalledAppsByInstalledAppIdPath, + zDeleteInstalledAppsByInstalledAppIdResponse, + zDeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdPath, + zDeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdResponse, + zGetInstalledAppsByInstalledAppIdConversationsPath, + zGetInstalledAppsByInstalledAppIdConversationsQuery, + zGetInstalledAppsByInstalledAppIdConversationsResponse, + zGetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisPath, + zGetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisQuery, + zGetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisResponse, + zGetInstalledAppsByInstalledAppIdMessagesByMessageIdSuggestedQuestionsPath, + zGetInstalledAppsByInstalledAppIdMessagesByMessageIdSuggestedQuestionsResponse, + zGetInstalledAppsByInstalledAppIdMessagesPath, + zGetInstalledAppsByInstalledAppIdMessagesQuery, + zGetInstalledAppsByInstalledAppIdMessagesResponse, + zGetInstalledAppsByInstalledAppIdMetaPath, + zGetInstalledAppsByInstalledAppIdMetaResponse, + zGetInstalledAppsByInstalledAppIdParametersPath, + zGetInstalledAppsByInstalledAppIdParametersResponse, + zGetInstalledAppsByInstalledAppIdSavedMessagesPath, + zGetInstalledAppsByInstalledAppIdSavedMessagesQuery, + zGetInstalledAppsByInstalledAppIdSavedMessagesResponse, + zGetInstalledAppsResponse, + zPatchInstalledAppsByInstalledAppIdConversationsByCIdPinPath, + zPatchInstalledAppsByInstalledAppIdConversationsByCIdPinResponse, + zPatchInstalledAppsByInstalledAppIdConversationsByCIdUnpinPath, + zPatchInstalledAppsByInstalledAppIdConversationsByCIdUnpinResponse, + zPatchInstalledAppsByInstalledAppIdPath, + zPatchInstalledAppsByInstalledAppIdResponse, + zPostInstalledAppsByInstalledAppIdAudioToTextPath, + zPostInstalledAppsByInstalledAppIdAudioToTextResponse, + zPostInstalledAppsByInstalledAppIdChatMessagesBody, + zPostInstalledAppsByInstalledAppIdChatMessagesByTaskIdStopPath, + zPostInstalledAppsByInstalledAppIdChatMessagesByTaskIdStopResponse, + zPostInstalledAppsByInstalledAppIdChatMessagesPath, + zPostInstalledAppsByInstalledAppIdChatMessagesResponse, + zPostInstalledAppsByInstalledAppIdCompletionMessagesBody, + zPostInstalledAppsByInstalledAppIdCompletionMessagesByTaskIdStopPath, + zPostInstalledAppsByInstalledAppIdCompletionMessagesByTaskIdStopResponse, + zPostInstalledAppsByInstalledAppIdCompletionMessagesPath, + zPostInstalledAppsByInstalledAppIdCompletionMessagesResponse, + zPostInstalledAppsByInstalledAppIdConversationsByCIdNameBody, + zPostInstalledAppsByInstalledAppIdConversationsByCIdNamePath, + zPostInstalledAppsByInstalledAppIdConversationsByCIdNameResponse, + zPostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksBody, + zPostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksPath, + zPostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksResponse, + zPostInstalledAppsByInstalledAppIdSavedMessagesBody, + zPostInstalledAppsByInstalledAppIdSavedMessagesPath, + zPostInstalledAppsByInstalledAppIdSavedMessagesResponse, + zPostInstalledAppsByInstalledAppIdTextToAudioBody, + zPostInstalledAppsByInstalledAppIdTextToAudioPath, + zPostInstalledAppsByInstalledAppIdTextToAudioResponse, + zPostInstalledAppsByInstalledAppIdWorkflowsRunBody, + zPostInstalledAppsByInstalledAppIdWorkflowsRunPath, + zPostInstalledAppsByInstalledAppIdWorkflowsRunResponse, + zPostInstalledAppsByInstalledAppIdWorkflowsTasksByTaskIdStopPath, + zPostInstalledAppsByInstalledAppIdWorkflowsTasksByTaskIdStopResponse, + zPostInstalledAppsResponse, +} from './zod.gen' + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstalledAppsByInstalledAppIdAudioToText', + path: '/installed-apps/{installed_app_id}/audio-to-text', + tags: ['console'], + }) + .input(z.object({ params: zPostInstalledAppsByInstalledAppIdAudioToTextPath })) + .output(zPostInstalledAppsByInstalledAppIdAudioToTextResponse) + +export const audioToText = { + post, +} + +export const post2 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstalledAppsByInstalledAppIdChatMessagesByTaskIdStop', + path: '/installed-apps/{installed_app_id}/chat-messages/{task_id}/stop', + tags: ['console'], + }) + .input(z.object({ params: zPostInstalledAppsByInstalledAppIdChatMessagesByTaskIdStopPath })) + .output(zPostInstalledAppsByInstalledAppIdChatMessagesByTaskIdStopResponse) + +export const stop = { + post: post2, +} + +export const byTaskId = { + stop, +} + +export const post3 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstalledAppsByInstalledAppIdChatMessages', + path: '/installed-apps/{installed_app_id}/chat-messages', + tags: ['console'], + }) + .input( + z.object({ + body: zPostInstalledAppsByInstalledAppIdChatMessagesBody, + params: zPostInstalledAppsByInstalledAppIdChatMessagesPath, + }), + ) + .output(zPostInstalledAppsByInstalledAppIdChatMessagesResponse) + +export const chatMessages = { + post: post3, + byTaskId, +} + +export const post4 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstalledAppsByInstalledAppIdCompletionMessagesByTaskIdStop', + path: '/installed-apps/{installed_app_id}/completion-messages/{task_id}/stop', + tags: ['console'], + }) + .input(z.object({ params: zPostInstalledAppsByInstalledAppIdCompletionMessagesByTaskIdStopPath })) + .output(zPostInstalledAppsByInstalledAppIdCompletionMessagesByTaskIdStopResponse) + +export const stop2 = { + post: post4, +} + +export const byTaskId2 = { + stop: stop2, +} + +export const post5 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstalledAppsByInstalledAppIdCompletionMessages', + path: '/installed-apps/{installed_app_id}/completion-messages', + tags: ['console'], + }) + .input( + z.object({ + body: zPostInstalledAppsByInstalledAppIdCompletionMessagesBody, + params: zPostInstalledAppsByInstalledAppIdCompletionMessagesPath, + }), + ) + .output(zPostInstalledAppsByInstalledAppIdCompletionMessagesResponse) + +export const completionMessages = { + post: post5, + byTaskId: byTaskId2, +} + +export const post6 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstalledAppsByInstalledAppIdConversationsByCIdName', + path: '/installed-apps/{installed_app_id}/conversations/{c_id}/name', + tags: ['console'], + }) + .input( + z.object({ + body: zPostInstalledAppsByInstalledAppIdConversationsByCIdNameBody, + params: zPostInstalledAppsByInstalledAppIdConversationsByCIdNamePath, + }), + ) + .output(zPostInstalledAppsByInstalledAppIdConversationsByCIdNameResponse) + +export const name = { + post: post6, +} + +export const patch = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchInstalledAppsByInstalledAppIdConversationsByCIdPin', + path: '/installed-apps/{installed_app_id}/conversations/{c_id}/pin', + tags: ['console'], + }) + .input(z.object({ params: zPatchInstalledAppsByInstalledAppIdConversationsByCIdPinPath })) + .output(zPatchInstalledAppsByInstalledAppIdConversationsByCIdPinResponse) + +export const pin = { + patch, +} + +export const patch2 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchInstalledAppsByInstalledAppIdConversationsByCIdUnpin', + path: '/installed-apps/{installed_app_id}/conversations/{c_id}/unpin', + tags: ['console'], + }) + .input(z.object({ params: zPatchInstalledAppsByInstalledAppIdConversationsByCIdUnpinPath })) + .output(zPatchInstalledAppsByInstalledAppIdConversationsByCIdUnpinResponse) + +export const unpin = { + patch: patch2, +} + +export const delete_ = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteInstalledAppsByInstalledAppIdConversationsByCId', + path: '/installed-apps/{installed_app_id}/conversations/{c_id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteInstalledAppsByInstalledAppIdConversationsByCIdPath })) + .output(zDeleteInstalledAppsByInstalledAppIdConversationsByCIdResponse) + +export const byCId = { + delete: delete_, + name, + pin, + unpin, +} + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getInstalledAppsByInstalledAppIdConversations', + path: '/installed-apps/{installed_app_id}/conversations', + tags: ['console'], + }) + .input( + z.object({ + params: zGetInstalledAppsByInstalledAppIdConversationsPath, + query: zGetInstalledAppsByInstalledAppIdConversationsQuery.optional(), + }), + ) + .output(zGetInstalledAppsByInstalledAppIdConversationsResponse) + +export const conversations = { + get, + byCId, +} + +export const post7 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacks', + path: '/installed-apps/{installed_app_id}/messages/{message_id}/feedbacks', + tags: ['console'], + }) + .input( + z.object({ + body: zPostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksBody, + params: zPostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksPath, + }), + ) + .output(zPostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksResponse) + +export const feedbacks = { + post: post7, +} + +export const get2 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThis', + path: '/installed-apps/{installed_app_id}/messages/{message_id}/more-like-this', + tags: ['console'], + }) + .input( + z.object({ + params: zGetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisPath, + query: zGetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisQuery, + }), + ) + .output(zGetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisResponse) + +export const moreLikeThis = { + get: get2, +} + +export const get3 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getInstalledAppsByInstalledAppIdMessagesByMessageIdSuggestedQuestions', + path: '/installed-apps/{installed_app_id}/messages/{message_id}/suggested-questions', + tags: ['console'], + }) + .input( + z.object({ + params: zGetInstalledAppsByInstalledAppIdMessagesByMessageIdSuggestedQuestionsPath, + }), + ) + .output(zGetInstalledAppsByInstalledAppIdMessagesByMessageIdSuggestedQuestionsResponse) + +export const suggestedQuestions = { + get: get3, +} + +export const byMessageId = { + feedbacks, + moreLikeThis, + suggestedQuestions, +} + +export const get4 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getInstalledAppsByInstalledAppIdMessages', + path: '/installed-apps/{installed_app_id}/messages', + tags: ['console'], + }) + .input( + z.object({ + params: zGetInstalledAppsByInstalledAppIdMessagesPath, + query: zGetInstalledAppsByInstalledAppIdMessagesQuery, + }), + ) + .output(zGetInstalledAppsByInstalledAppIdMessagesResponse) + +export const messages = { + get: get4, + byMessageId, +} + +/** + * Get app meta + */ +export const get5 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getInstalledAppsByInstalledAppIdMeta', + path: '/installed-apps/{installed_app_id}/meta', + summary: 'Get app meta', + tags: ['console'], + }) + .input(z.object({ params: zGetInstalledAppsByInstalledAppIdMetaPath })) + .output(zGetInstalledAppsByInstalledAppIdMetaResponse) + +export const meta = { + get: get5, +} + +/** + * Retrieve app parameters + */ +export const get6 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getInstalledAppsByInstalledAppIdParameters', + path: '/installed-apps/{installed_app_id}/parameters', + summary: 'Retrieve app parameters', + tags: ['console'], + }) + .input(z.object({ params: zGetInstalledAppsByInstalledAppIdParametersPath })) + .output(zGetInstalledAppsByInstalledAppIdParametersResponse) + +export const parameters = { + get: get6, +} + +export const delete2 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteInstalledAppsByInstalledAppIdSavedMessagesByMessageId', + path: '/installed-apps/{installed_app_id}/saved-messages/{message_id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdPath })) + .output(zDeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdResponse) + +export const byMessageId2 = { + delete: delete2, +} + +export const get7 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getInstalledAppsByInstalledAppIdSavedMessages', + path: '/installed-apps/{installed_app_id}/saved-messages', + tags: ['console'], + }) + .input( + z.object({ + params: zGetInstalledAppsByInstalledAppIdSavedMessagesPath, + query: zGetInstalledAppsByInstalledAppIdSavedMessagesQuery.optional(), + }), + ) + .output(zGetInstalledAppsByInstalledAppIdSavedMessagesResponse) + +export const post8 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstalledAppsByInstalledAppIdSavedMessages', + path: '/installed-apps/{installed_app_id}/saved-messages', + tags: ['console'], + }) + .input( + z.object({ + body: zPostInstalledAppsByInstalledAppIdSavedMessagesBody, + params: zPostInstalledAppsByInstalledAppIdSavedMessagesPath, + }), + ) + .output(zPostInstalledAppsByInstalledAppIdSavedMessagesResponse) + +export const savedMessages = { + get: get7, + post: post8, + byMessageId: byMessageId2, +} + +export const post9 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstalledAppsByInstalledAppIdTextToAudio', + path: '/installed-apps/{installed_app_id}/text-to-audio', + tags: ['console'], + }) + .input( + z.object({ + body: zPostInstalledAppsByInstalledAppIdTextToAudioBody, + params: zPostInstalledAppsByInstalledAppIdTextToAudioPath, + }), + ) + .output(zPostInstalledAppsByInstalledAppIdTextToAudioResponse) + +export const textToAudio = { + post: post9, +} + +/** + * Run workflow + */ +export const post10 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstalledAppsByInstalledAppIdWorkflowsRun', + path: '/installed-apps/{installed_app_id}/workflows/run', + summary: 'Run workflow', + tags: ['console'], + }) + .input( + z.object({ + body: zPostInstalledAppsByInstalledAppIdWorkflowsRunBody, + params: zPostInstalledAppsByInstalledAppIdWorkflowsRunPath, + }), + ) + .output(zPostInstalledAppsByInstalledAppIdWorkflowsRunResponse) + +export const run = { + post: post10, +} + +/** + * Stop workflow task + */ +export const post11 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstalledAppsByInstalledAppIdWorkflowsTasksByTaskIdStop', + path: '/installed-apps/{installed_app_id}/workflows/tasks/{task_id}/stop', + summary: 'Stop workflow task', + tags: ['console'], + }) + .input(z.object({ params: zPostInstalledAppsByInstalledAppIdWorkflowsTasksByTaskIdStopPath })) + .output(zPostInstalledAppsByInstalledAppIdWorkflowsTasksByTaskIdStopResponse) + +export const stop3 = { + post: post11, +} + +export const byTaskId3 = { + stop: stop3, +} + +export const tasks = { + byTaskId: byTaskId3, +} + +export const workflows = { + run, + tasks, +} + +export const delete3 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteInstalledAppsByInstalledAppId', + path: '/installed-apps/{installed_app_id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteInstalledAppsByInstalledAppIdPath })) + .output(zDeleteInstalledAppsByInstalledAppIdResponse) + +export const patch3 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchInstalledAppsByInstalledAppId', + path: '/installed-apps/{installed_app_id}', + tags: ['console'], + }) + .input(z.object({ params: zPatchInstalledAppsByInstalledAppIdPath })) + .output(zPatchInstalledAppsByInstalledAppIdResponse) + +export const byInstalledAppId = { + delete: delete3, + patch: patch3, + audioToText, + chatMessages, + completionMessages, + conversations, + messages, + meta, + parameters, + savedMessages, + textToAudio, + workflows, +} + +export const get8 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getInstalledApps', + path: '/installed-apps', + tags: ['console'], + }) + .output(zGetInstalledAppsResponse) + +export const post12 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstalledApps', + path: '/installed-apps', + tags: ['console'], + }) + .output(zPostInstalledAppsResponse) + +export const installedApps = { + get: get8, + post: post12, + byInstalledAppId, +} + +export const contract = { + installedApps, +} diff --git a/packages/contracts/generated/api/console/installed-apps/types.gen.ts b/packages/contracts/generated/api/console/installed-apps/types.gen.ts new file mode 100644 index 0000000000..897fc29b8b --- /dev/null +++ b/packages/contracts/generated/api/console/installed-apps/types.gen.ts @@ -0,0 +1,571 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type InstalledAppListResponse = { + installed_apps: Array +} + +export type ChatMessagePayload = { + conversation_id?: string | null + files?: Array | null + inputs: { + [key: string]: unknown + } + model_config: { + [key: string]: unknown + } + parent_message_id?: string | null + query: string + response_mode?: 'blocking' | 'streaming' + retriever_from?: string +} + +export type CompletionMessageExplorePayload = { + files?: Array<{ + [key: string]: unknown + }> | null + inputs: { + [key: string]: unknown + } + query?: string + response_mode?: 'blocking' | 'streaming' | null + retriever_from?: string +} + +export type ConversationRenamePayload = { + auto_generate?: boolean + name?: string | null +} + +export type MessageFeedbackPayload = { + content?: string | null + message_id: string + rating?: 'like' | 'dislike' | null +} + +export type SavedMessageCreatePayload = { + message_id: string +} + +export type TextToAudioPayload = { + message_id?: string | null + streaming?: boolean | null + text?: string | null + voice?: string | null +} + +export type WorkflowRunPayload = { + files?: Array<{ + [key: string]: unknown + }> | null + inputs: { + [key: string]: unknown + } +} + +export type InstalledAppResponse = { + app: InstalledAppInfoResponse + app_owner_tenant_id: string + editable: boolean + id: string + is_pinned: boolean + last_used_at?: number | null + uninstallable: boolean +} + +export type InstalledAppInfoResponse = { + icon?: string | null + icon_background?: string | null + icon_type?: string | null + id: string + mode?: string | null + name?: string | null + use_icon_as_answer_icon?: boolean | null +} + +export type GetInstalledAppsData = { + body?: never + path?: never + query?: never + url: '/installed-apps' +} + +export type GetInstalledAppsResponses = { + 200: InstalledAppListResponse +} + +export type GetInstalledAppsResponse = GetInstalledAppsResponses[keyof GetInstalledAppsResponses] + +export type PostInstalledAppsData = { + body?: never + path?: never + query?: never + url: '/installed-apps' +} + +export type PostInstalledAppsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstalledAppsResponse = PostInstalledAppsResponses[keyof PostInstalledAppsResponses] + +export type DeleteInstalledAppsByInstalledAppIdData = { + body?: never + path: { + installed_app_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}' +} + +export type DeleteInstalledAppsByInstalledAppIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteInstalledAppsByInstalledAppIdResponse + = DeleteInstalledAppsByInstalledAppIdResponses[keyof DeleteInstalledAppsByInstalledAppIdResponses] + +export type PatchInstalledAppsByInstalledAppIdData = { + body?: never + path: { + installed_app_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}' +} + +export type PatchInstalledAppsByInstalledAppIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchInstalledAppsByInstalledAppIdResponse + = PatchInstalledAppsByInstalledAppIdResponses[keyof PatchInstalledAppsByInstalledAppIdResponses] + +export type PostInstalledAppsByInstalledAppIdAudioToTextData = { + body?: never + path: { + installed_app_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/audio-to-text' +} + +export type PostInstalledAppsByInstalledAppIdAudioToTextResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstalledAppsByInstalledAppIdAudioToTextResponse + = PostInstalledAppsByInstalledAppIdAudioToTextResponses[keyof PostInstalledAppsByInstalledAppIdAudioToTextResponses] + +export type PostInstalledAppsByInstalledAppIdChatMessagesData = { + body: ChatMessagePayload + path: { + installed_app_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/chat-messages' +} + +export type PostInstalledAppsByInstalledAppIdChatMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstalledAppsByInstalledAppIdChatMessagesResponse + = PostInstalledAppsByInstalledAppIdChatMessagesResponses[keyof PostInstalledAppsByInstalledAppIdChatMessagesResponses] + +export type PostInstalledAppsByInstalledAppIdChatMessagesByTaskIdStopData = { + body?: never + path: { + installed_app_id: string + task_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/chat-messages/{task_id}/stop' +} + +export type PostInstalledAppsByInstalledAppIdChatMessagesByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstalledAppsByInstalledAppIdChatMessagesByTaskIdStopResponse + = PostInstalledAppsByInstalledAppIdChatMessagesByTaskIdStopResponses[keyof PostInstalledAppsByInstalledAppIdChatMessagesByTaskIdStopResponses] + +export type PostInstalledAppsByInstalledAppIdCompletionMessagesData = { + body: CompletionMessageExplorePayload + path: { + installed_app_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/completion-messages' +} + +export type PostInstalledAppsByInstalledAppIdCompletionMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstalledAppsByInstalledAppIdCompletionMessagesResponse + = PostInstalledAppsByInstalledAppIdCompletionMessagesResponses[keyof PostInstalledAppsByInstalledAppIdCompletionMessagesResponses] + +export type PostInstalledAppsByInstalledAppIdCompletionMessagesByTaskIdStopData = { + body?: never + path: { + installed_app_id: string + task_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/completion-messages/{task_id}/stop' +} + +export type PostInstalledAppsByInstalledAppIdCompletionMessagesByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstalledAppsByInstalledAppIdCompletionMessagesByTaskIdStopResponse + = PostInstalledAppsByInstalledAppIdCompletionMessagesByTaskIdStopResponses[keyof PostInstalledAppsByInstalledAppIdCompletionMessagesByTaskIdStopResponses] + +export type GetInstalledAppsByInstalledAppIdConversationsData = { + body?: never + path: { + installed_app_id: string + } + query?: { + last_id?: string | null + limit?: number + pinned?: boolean | null + } + url: '/installed-apps/{installed_app_id}/conversations' +} + +export type GetInstalledAppsByInstalledAppIdConversationsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetInstalledAppsByInstalledAppIdConversationsResponse + = GetInstalledAppsByInstalledAppIdConversationsResponses[keyof GetInstalledAppsByInstalledAppIdConversationsResponses] + +export type DeleteInstalledAppsByInstalledAppIdConversationsByCIdData = { + body?: never + path: { + installed_app_id: string + c_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/conversations/{c_id}' +} + +export type DeleteInstalledAppsByInstalledAppIdConversationsByCIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteInstalledAppsByInstalledAppIdConversationsByCIdResponse + = DeleteInstalledAppsByInstalledAppIdConversationsByCIdResponses[keyof DeleteInstalledAppsByInstalledAppIdConversationsByCIdResponses] + +export type PostInstalledAppsByInstalledAppIdConversationsByCIdNameData = { + body: ConversationRenamePayload + path: { + installed_app_id: string + c_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/conversations/{c_id}/name' +} + +export type PostInstalledAppsByInstalledAppIdConversationsByCIdNameResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstalledAppsByInstalledAppIdConversationsByCIdNameResponse + = PostInstalledAppsByInstalledAppIdConversationsByCIdNameResponses[keyof PostInstalledAppsByInstalledAppIdConversationsByCIdNameResponses] + +export type PatchInstalledAppsByInstalledAppIdConversationsByCIdPinData = { + body?: never + path: { + installed_app_id: string + c_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/conversations/{c_id}/pin' +} + +export type PatchInstalledAppsByInstalledAppIdConversationsByCIdPinResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchInstalledAppsByInstalledAppIdConversationsByCIdPinResponse + = PatchInstalledAppsByInstalledAppIdConversationsByCIdPinResponses[keyof PatchInstalledAppsByInstalledAppIdConversationsByCIdPinResponses] + +export type PatchInstalledAppsByInstalledAppIdConversationsByCIdUnpinData = { + body?: never + path: { + installed_app_id: string + c_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/conversations/{c_id}/unpin' +} + +export type PatchInstalledAppsByInstalledAppIdConversationsByCIdUnpinResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchInstalledAppsByInstalledAppIdConversationsByCIdUnpinResponse + = PatchInstalledAppsByInstalledAppIdConversationsByCIdUnpinResponses[keyof PatchInstalledAppsByInstalledAppIdConversationsByCIdUnpinResponses] + +export type GetInstalledAppsByInstalledAppIdMessagesData = { + body?: never + path: { + installed_app_id: string + } + query: { + conversation_id: string + first_id?: string | null + limit?: number + } + url: '/installed-apps/{installed_app_id}/messages' +} + +export type GetInstalledAppsByInstalledAppIdMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetInstalledAppsByInstalledAppIdMessagesResponse + = GetInstalledAppsByInstalledAppIdMessagesResponses[keyof GetInstalledAppsByInstalledAppIdMessagesResponses] + +export type PostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksData = { + body: MessageFeedbackPayload + path: { + installed_app_id: string + message_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/messages/{message_id}/feedbacks' +} + +export type PostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksResponse + = PostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksResponses[keyof PostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksResponses] + +export type GetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisData = { + body?: never + path: { + installed_app_id: string + message_id: string + } + query: { + response_mode: 'blocking' | 'streaming' + } + url: '/installed-apps/{installed_app_id}/messages/{message_id}/more-like-this' +} + +export type GetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisResponse + = GetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisResponses[keyof GetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisResponses] + +export type GetInstalledAppsByInstalledAppIdMessagesByMessageIdSuggestedQuestionsData = { + body?: never + path: { + installed_app_id: string + message_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/messages/{message_id}/suggested-questions' +} + +export type GetInstalledAppsByInstalledAppIdMessagesByMessageIdSuggestedQuestionsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetInstalledAppsByInstalledAppIdMessagesByMessageIdSuggestedQuestionsResponse + = GetInstalledAppsByInstalledAppIdMessagesByMessageIdSuggestedQuestionsResponses[keyof GetInstalledAppsByInstalledAppIdMessagesByMessageIdSuggestedQuestionsResponses] + +export type GetInstalledAppsByInstalledAppIdMetaData = { + body?: never + path: { + installed_app_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/meta' +} + +export type GetInstalledAppsByInstalledAppIdMetaResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetInstalledAppsByInstalledAppIdMetaResponse + = GetInstalledAppsByInstalledAppIdMetaResponses[keyof GetInstalledAppsByInstalledAppIdMetaResponses] + +export type GetInstalledAppsByInstalledAppIdParametersData = { + body?: never + path: { + installed_app_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/parameters' +} + +export type GetInstalledAppsByInstalledAppIdParametersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetInstalledAppsByInstalledAppIdParametersResponse + = GetInstalledAppsByInstalledAppIdParametersResponses[keyof GetInstalledAppsByInstalledAppIdParametersResponses] + +export type GetInstalledAppsByInstalledAppIdSavedMessagesData = { + body?: never + path: { + installed_app_id: string + } + query?: { + last_id?: string | null + limit?: number + } + url: '/installed-apps/{installed_app_id}/saved-messages' +} + +export type GetInstalledAppsByInstalledAppIdSavedMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetInstalledAppsByInstalledAppIdSavedMessagesResponse + = GetInstalledAppsByInstalledAppIdSavedMessagesResponses[keyof GetInstalledAppsByInstalledAppIdSavedMessagesResponses] + +export type PostInstalledAppsByInstalledAppIdSavedMessagesData = { + body: SavedMessageCreatePayload + path: { + installed_app_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/saved-messages' +} + +export type PostInstalledAppsByInstalledAppIdSavedMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstalledAppsByInstalledAppIdSavedMessagesResponse + = PostInstalledAppsByInstalledAppIdSavedMessagesResponses[keyof PostInstalledAppsByInstalledAppIdSavedMessagesResponses] + +export type DeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdData = { + body?: never + path: { + installed_app_id: string + message_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/saved-messages/{message_id}' +} + +export type DeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdResponse + = DeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdResponses[keyof DeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdResponses] + +export type PostInstalledAppsByInstalledAppIdTextToAudioData = { + body: TextToAudioPayload + path: { + installed_app_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/text-to-audio' +} + +export type PostInstalledAppsByInstalledAppIdTextToAudioResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstalledAppsByInstalledAppIdTextToAudioResponse + = PostInstalledAppsByInstalledAppIdTextToAudioResponses[keyof PostInstalledAppsByInstalledAppIdTextToAudioResponses] + +export type PostInstalledAppsByInstalledAppIdWorkflowsRunData = { + body: WorkflowRunPayload + path: { + installed_app_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/workflows/run' +} + +export type PostInstalledAppsByInstalledAppIdWorkflowsRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstalledAppsByInstalledAppIdWorkflowsRunResponse + = PostInstalledAppsByInstalledAppIdWorkflowsRunResponses[keyof PostInstalledAppsByInstalledAppIdWorkflowsRunResponses] + +export type PostInstalledAppsByInstalledAppIdWorkflowsTasksByTaskIdStopData = { + body?: never + path: { + installed_app_id: string + task_id: string + } + query?: never + url: '/installed-apps/{installed_app_id}/workflows/tasks/{task_id}/stop' +} + +export type PostInstalledAppsByInstalledAppIdWorkflowsTasksByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstalledAppsByInstalledAppIdWorkflowsTasksByTaskIdStopResponse + = PostInstalledAppsByInstalledAppIdWorkflowsTasksByTaskIdStopResponses[keyof PostInstalledAppsByInstalledAppIdWorkflowsTasksByTaskIdStopResponses] diff --git a/packages/contracts/generated/api/console/installed-apps/zod.gen.ts b/packages/contracts/generated/api/console/installed-apps/zod.gen.ts new file mode 100644 index 0000000000..c8683e092c --- /dev/null +++ b/packages/contracts/generated/api/console/installed-apps/zod.gen.ts @@ -0,0 +1,433 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * ChatMessagePayload + */ +export const zChatMessagePayload = z.object({ + conversation_id: z.string().nullish(), + files: z.array(z.unknown()).nullish(), + inputs: z.record(z.string(), z.unknown()), + model_config: z.record(z.string(), z.unknown()), + parent_message_id: z.string().nullish(), + query: z.string(), + response_mode: z.enum(['blocking', 'streaming']).optional().default('blocking'), + retriever_from: z.string().optional().default('dev'), +}) + +/** + * CompletionMessageExplorePayload + */ +export const zCompletionMessageExplorePayload = z.object({ + files: z.array(z.record(z.string(), z.unknown())).nullish(), + inputs: z.record(z.string(), z.unknown()), + query: z.string().optional().default(''), + response_mode: z.enum(['blocking', 'streaming']).nullish(), + retriever_from: z.string().optional().default('explore_app'), +}) + +/** + * ConversationRenamePayload + */ +export const zConversationRenamePayload = z.object({ + auto_generate: z.boolean().optional().default(false), + name: z.string().nullish(), +}) + +/** + * MessageFeedbackPayload + */ +export const zMessageFeedbackPayload = z.object({ + content: z.string().nullish(), + message_id: z.string(), + rating: z.enum(['like', 'dislike']).nullish(), +}) + +/** + * SavedMessageCreatePayload + */ +export const zSavedMessageCreatePayload = z.object({ + message_id: z.string(), +}) + +/** + * TextToAudioPayload + */ +export const zTextToAudioPayload = z.object({ + message_id: z.string().nullish(), + streaming: z.boolean().nullish(), + text: z.string().nullish(), + voice: z.string().nullish(), +}) + +/** + * WorkflowRunPayload + */ +export const zWorkflowRunPayload = z.object({ + files: z.array(z.record(z.string(), z.unknown())).nullish(), + inputs: z.record(z.string(), z.unknown()), +}) + +/** + * InstalledAppInfoResponse + */ +export const zInstalledAppInfoResponse = z.object({ + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: z.string().nullish(), + id: z.string(), + mode: z.string().nullish(), + name: z.string().nullish(), + use_icon_as_answer_icon: z.boolean().nullish(), +}) + +/** + * InstalledAppResponse + */ +export const zInstalledAppResponse = z.object({ + app: zInstalledAppInfoResponse, + app_owner_tenant_id: z.string(), + editable: z.boolean(), + id: z.string(), + is_pinned: z.boolean(), + last_used_at: z.int().nullish(), + uninstallable: z.boolean(), +}) + +/** + * InstalledAppListResponse + */ +export const zInstalledAppListResponse = z.object({ + installed_apps: z.array(zInstalledAppResponse), +}) + +/** + * Success + */ +export const zGetInstalledAppsResponse = zInstalledAppListResponse + +/** + * Success + */ +export const zPostInstalledAppsResponse = z.record(z.string(), z.unknown()) + +export const zDeleteInstalledAppsByInstalledAppIdPath = z.object({ + installed_app_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteInstalledAppsByInstalledAppIdResponse = z.record(z.string(), z.unknown()) + +export const zPatchInstalledAppsByInstalledAppIdPath = z.object({ + installed_app_id: z.string(), +}) + +/** + * Success + */ +export const zPatchInstalledAppsByInstalledAppIdResponse = z.record(z.string(), z.unknown()) + +export const zPostInstalledAppsByInstalledAppIdAudioToTextPath = z.object({ + installed_app_id: z.string(), +}) + +/** + * Success + */ +export const zPostInstalledAppsByInstalledAppIdAudioToTextResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostInstalledAppsByInstalledAppIdChatMessagesBody = zChatMessagePayload + +export const zPostInstalledAppsByInstalledAppIdChatMessagesPath = z.object({ + installed_app_id: z.string(), +}) + +/** + * Success + */ +export const zPostInstalledAppsByInstalledAppIdChatMessagesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostInstalledAppsByInstalledAppIdChatMessagesByTaskIdStopPath = z.object({ + installed_app_id: z.string(), + task_id: z.string(), +}) + +/** + * Success + */ +export const zPostInstalledAppsByInstalledAppIdChatMessagesByTaskIdStopResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostInstalledAppsByInstalledAppIdCompletionMessagesBody + = zCompletionMessageExplorePayload + +export const zPostInstalledAppsByInstalledAppIdCompletionMessagesPath = z.object({ + installed_app_id: z.string(), +}) + +/** + * Success + */ +export const zPostInstalledAppsByInstalledAppIdCompletionMessagesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostInstalledAppsByInstalledAppIdCompletionMessagesByTaskIdStopPath = z.object({ + installed_app_id: z.string(), + task_id: z.string(), +}) + +/** + * Success + */ +export const zPostInstalledAppsByInstalledAppIdCompletionMessagesByTaskIdStopResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetInstalledAppsByInstalledAppIdConversationsPath = z.object({ + installed_app_id: z.string(), +}) + +export const zGetInstalledAppsByInstalledAppIdConversationsQuery = z.object({ + last_id: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), + pinned: z.boolean().nullish(), +}) + +/** + * Success + */ +export const zGetInstalledAppsByInstalledAppIdConversationsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteInstalledAppsByInstalledAppIdConversationsByCIdPath = z.object({ + installed_app_id: z.string(), + c_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteInstalledAppsByInstalledAppIdConversationsByCIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostInstalledAppsByInstalledAppIdConversationsByCIdNameBody + = zConversationRenamePayload + +export const zPostInstalledAppsByInstalledAppIdConversationsByCIdNamePath = z.object({ + installed_app_id: z.string(), + c_id: z.string(), +}) + +/** + * Success + */ +export const zPostInstalledAppsByInstalledAppIdConversationsByCIdNameResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchInstalledAppsByInstalledAppIdConversationsByCIdPinPath = z.object({ + installed_app_id: z.string(), + c_id: z.string(), +}) + +/** + * Success + */ +export const zPatchInstalledAppsByInstalledAppIdConversationsByCIdPinResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchInstalledAppsByInstalledAppIdConversationsByCIdUnpinPath = z.object({ + installed_app_id: z.string(), + c_id: z.string(), +}) + +/** + * Success + */ +export const zPatchInstalledAppsByInstalledAppIdConversationsByCIdUnpinResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetInstalledAppsByInstalledAppIdMessagesPath = z.object({ + installed_app_id: z.string(), +}) + +export const zGetInstalledAppsByInstalledAppIdMessagesQuery = z.object({ + conversation_id: z.string(), + first_id: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), +}) + +/** + * Success + */ +export const zGetInstalledAppsByInstalledAppIdMessagesResponse = z.record(z.string(), z.unknown()) + +export const zPostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksBody + = zMessageFeedbackPayload + +export const zPostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksPath = z.object({ + installed_app_id: z.string(), + message_id: z.string(), +}) + +/** + * Success + */ +export const zPostInstalledAppsByInstalledAppIdMessagesByMessageIdFeedbacksResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisPath = z.object({ + installed_app_id: z.string(), + message_id: z.string(), +}) + +export const zGetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisQuery = z.object({ + response_mode: z.enum(['blocking', 'streaming']), +}) + +/** + * Success + */ +export const zGetInstalledAppsByInstalledAppIdMessagesByMessageIdMoreLikeThisResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetInstalledAppsByInstalledAppIdMessagesByMessageIdSuggestedQuestionsPath = z.object({ + installed_app_id: z.string(), + message_id: z.string(), +}) + +/** + * Success + */ +export const zGetInstalledAppsByInstalledAppIdMessagesByMessageIdSuggestedQuestionsResponse + = z.record(z.string(), z.unknown()) + +export const zGetInstalledAppsByInstalledAppIdMetaPath = z.object({ + installed_app_id: z.string(), +}) + +/** + * Success + */ +export const zGetInstalledAppsByInstalledAppIdMetaResponse = z.record(z.string(), z.unknown()) + +export const zGetInstalledAppsByInstalledAppIdParametersPath = z.object({ + installed_app_id: z.string(), +}) + +/** + * Success + */ +export const zGetInstalledAppsByInstalledAppIdParametersResponse = z.record(z.string(), z.unknown()) + +export const zGetInstalledAppsByInstalledAppIdSavedMessagesPath = z.object({ + installed_app_id: z.string(), +}) + +export const zGetInstalledAppsByInstalledAppIdSavedMessagesQuery = z.object({ + last_id: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), +}) + +/** + * Success + */ +export const zGetInstalledAppsByInstalledAppIdSavedMessagesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostInstalledAppsByInstalledAppIdSavedMessagesBody = zSavedMessageCreatePayload + +export const zPostInstalledAppsByInstalledAppIdSavedMessagesPath = z.object({ + installed_app_id: z.string(), +}) + +/** + * Success + */ +export const zPostInstalledAppsByInstalledAppIdSavedMessagesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdPath = z.object({ + installed_app_id: z.string(), + message_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteInstalledAppsByInstalledAppIdSavedMessagesByMessageIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostInstalledAppsByInstalledAppIdTextToAudioBody = zTextToAudioPayload + +export const zPostInstalledAppsByInstalledAppIdTextToAudioPath = z.object({ + installed_app_id: z.string(), +}) + +/** + * Success + */ +export const zPostInstalledAppsByInstalledAppIdTextToAudioResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostInstalledAppsByInstalledAppIdWorkflowsRunBody = zWorkflowRunPayload + +export const zPostInstalledAppsByInstalledAppIdWorkflowsRunPath = z.object({ + installed_app_id: z.string(), +}) + +/** + * Success + */ +export const zPostInstalledAppsByInstalledAppIdWorkflowsRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostInstalledAppsByInstalledAppIdWorkflowsTasksByTaskIdStopPath = z.object({ + installed_app_id: z.string(), + task_id: z.string(), +}) + +/** + * Success + */ +export const zPostInstalledAppsByInstalledAppIdWorkflowsTasksByTaskIdStopResponse = z.record( + z.string(), + z.unknown(), +) diff --git a/packages/contracts/generated/api/console/instruction-generate/orpc.gen.ts b/packages/contracts/generated/api/console/instruction-generate/orpc.gen.ts new file mode 100644 index 0000000000..3aff6a9a3b --- /dev/null +++ b/packages/contracts/generated/api/console/instruction-generate/orpc.gen.ts @@ -0,0 +1,54 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zPostInstructionGenerateBody, + zPostInstructionGenerateResponse, + zPostInstructionGenerateTemplateBody, + zPostInstructionGenerateTemplateResponse, +} from './zod.gen' + +/** + * Get instruction generation template + */ +export const post = oc + .route({ + description: 'Get instruction generation template', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstructionGenerateTemplate', + path: '/instruction-generate/template', + tags: ['console'], + }) + .input(z.object({ body: zPostInstructionGenerateTemplateBody })) + .output(zPostInstructionGenerateTemplateResponse) + +export const template = { + post, +} + +/** + * Generate instruction for workflow nodes or general use + */ +export const post2 = oc + .route({ + description: 'Generate instruction for workflow nodes or general use', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postInstructionGenerate', + path: '/instruction-generate', + tags: ['console'], + }) + .input(z.object({ body: zPostInstructionGenerateBody })) + .output(zPostInstructionGenerateResponse) + +export const instructionGenerate = { + post: post2, + template, +} + +export const contract = { + instructionGenerate, +} diff --git a/packages/contracts/generated/api/console/instruction-generate/types.gen.ts b/packages/contracts/generated/api/console/instruction-generate/types.gen.ts new file mode 100644 index 0000000000..1dd3530d44 --- /dev/null +++ b/packages/contracts/generated/api/console/instruction-generate/types.gen.ts @@ -0,0 +1,101 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type InstructionGeneratePayload = { + current?: string + flow_id: string + ideal_output?: string + instruction: string + language?: string + model_config: ModelConfig + node_id?: string +} + +export type InstructionTemplatePayload = { + type: string +} + +export type ModelConfig = { + agent_mode_dict?: JsonValue + annotation_reply_dict?: JsonValue + chat_prompt_config_dict?: JsonValue + completion_prompt_config_dict?: JsonValue + created_at?: number | null + created_by?: string | null + dataset_configs_dict?: JsonValue + dataset_query_variable?: string | null + external_data_tools_list?: JsonValue + file_upload_dict?: JsonValue + model_dict?: JsonValue + more_like_this_dict?: JsonValue + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource_dict?: JsonValue + sensitive_word_avoidance_dict?: JsonValue + speech_to_text_dict?: JsonValue + suggested_questions_after_answer_dict?: JsonValue + suggested_questions_list?: JsonValue + text_to_speech_dict?: JsonValue + updated_at?: number | null + updated_by?: string | null + user_input_form_list?: JsonValue +} + +export type JsonValue = unknown + +export type PostInstructionGenerateData = { + body: InstructionGeneratePayload + path?: never + query?: never + url: '/instruction-generate' +} + +export type PostInstructionGenerateErrors = { + 400: { + [key: string]: unknown + } + 402: { + [key: string]: unknown + } +} + +export type PostInstructionGenerateError + = PostInstructionGenerateErrors[keyof PostInstructionGenerateErrors] + +export type PostInstructionGenerateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstructionGenerateResponse + = PostInstructionGenerateResponses[keyof PostInstructionGenerateResponses] + +export type PostInstructionGenerateTemplateData = { + body: InstructionTemplatePayload + path?: never + query?: never + url: '/instruction-generate/template' +} + +export type PostInstructionGenerateTemplateErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostInstructionGenerateTemplateError + = PostInstructionGenerateTemplateErrors[keyof PostInstructionGenerateTemplateErrors] + +export type PostInstructionGenerateTemplateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostInstructionGenerateTemplateResponse + = PostInstructionGenerateTemplateResponses[keyof PostInstructionGenerateTemplateResponses] diff --git a/packages/contracts/generated/api/console/instruction-generate/zod.gen.ts b/packages/contracts/generated/api/console/instruction-generate/zod.gen.ts new file mode 100644 index 0000000000..35135fdcf7 --- /dev/null +++ b/packages/contracts/generated/api/console/instruction-generate/zod.gen.ts @@ -0,0 +1,69 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * InstructionTemplatePayload + */ +export const zInstructionTemplatePayload = z.object({ + type: z.string(), +}) + +export const zJsonValue = z.unknown() + +/** + * ModelConfig + */ +export const zModelConfig = z.object({ + agent_mode_dict: zJsonValue.optional(), + annotation_reply_dict: zJsonValue.optional(), + chat_prompt_config_dict: zJsonValue.optional(), + completion_prompt_config_dict: zJsonValue.optional(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs_dict: zJsonValue.optional(), + dataset_query_variable: z.string().nullish(), + external_data_tools_list: zJsonValue.optional(), + file_upload_dict: zJsonValue.optional(), + model_dict: zJsonValue.optional(), + more_like_this_dict: zJsonValue.optional(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource_dict: zJsonValue.optional(), + sensitive_word_avoidance_dict: zJsonValue.optional(), + speech_to_text_dict: zJsonValue.optional(), + suggested_questions_after_answer_dict: zJsonValue.optional(), + suggested_questions_list: zJsonValue.optional(), + text_to_speech_dict: zJsonValue.optional(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form_list: zJsonValue.optional(), +}) + +/** + * InstructionGeneratePayload + */ +export const zInstructionGeneratePayload = z.object({ + current: z.string().optional().default(''), + flow_id: z.string(), + ideal_output: z.string().optional().default(''), + instruction: z.string(), + language: z.string().optional().default('javascript'), + model_config: zModelConfig, + node_id: z.string().optional().default(''), +}) + +export const zPostInstructionGenerateBody = zInstructionGeneratePayload + +/** + * Instruction generated successfully + */ +export const zPostInstructionGenerateResponse = z.record(z.string(), z.unknown()) + +export const zPostInstructionGenerateTemplateBody = zInstructionTemplatePayload + +/** + * Template retrieved successfully + */ +export const zPostInstructionGenerateTemplateResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/login/orpc.gen.ts b/packages/contracts/generated/api/console/login/orpc.gen.ts new file mode 100644 index 0000000000..b8e647a11d --- /dev/null +++ b/packages/contracts/generated/api/console/login/orpc.gen.ts @@ -0,0 +1,29 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { zPostLoginBody, zPostLoginResponse } from './zod.gen' + +/** + * Authenticate user and login + */ +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postLogin', + path: '/login', + summary: 'Authenticate user and login', + tags: ['console'], + }) + .input(z.object({ body: zPostLoginBody })) + .output(zPostLoginResponse) + +export const login = { + post, +} + +export const contract = { + login, +} diff --git a/packages/contracts/generated/api/console/login/types.gen.ts b/packages/contracts/generated/api/console/login/types.gen.ts new file mode 100644 index 0000000000..8646c56c2a --- /dev/null +++ b/packages/contracts/generated/api/console/login/types.gen.ts @@ -0,0 +1,27 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type LoginPayload = { + email: string + invite_token?: string | null + password: string + remember_me?: boolean +} + +export type PostLoginData = { + body: LoginPayload + path?: never + query?: never + url: '/login' +} + +export type PostLoginResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostLoginResponse = PostLoginResponses[keyof PostLoginResponses] diff --git a/packages/contracts/generated/api/console/login/zod.gen.ts b/packages/contracts/generated/api/console/login/zod.gen.ts new file mode 100644 index 0000000000..612ab8d3be --- /dev/null +++ b/packages/contracts/generated/api/console/login/zod.gen.ts @@ -0,0 +1,20 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * LoginPayload + */ +export const zLoginPayload = z.object({ + email: z.string(), + invite_token: z.string().nullish(), + password: z.string(), + remember_me: z.boolean().optional().default(false), +}) + +export const zPostLoginBody = zLoginPayload + +/** + * Success + */ +export const zPostLoginResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/logout/orpc.gen.ts b/packages/contracts/generated/api/console/logout/orpc.gen.ts new file mode 100644 index 0000000000..02ecd2c82d --- /dev/null +++ b/packages/contracts/generated/api/console/logout/orpc.gen.ts @@ -0,0 +1,23 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' + +import { zPostLogoutResponse } from './zod.gen' + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postLogout', + path: '/logout', + tags: ['console'], + }) + .output(zPostLogoutResponse) + +export const logout = { + post, +} + +export const contract = { + logout, +} diff --git a/packages/contracts/generated/api/console/logout/types.gen.ts b/packages/contracts/generated/api/console/logout/types.gen.ts new file mode 100644 index 0000000000..9834d78dc1 --- /dev/null +++ b/packages/contracts/generated/api/console/logout/types.gen.ts @@ -0,0 +1,20 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type PostLogoutData = { + body?: never + path?: never + query?: never + url: '/logout' +} + +export type PostLogoutResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostLogoutResponse = PostLogoutResponses[keyof PostLogoutResponses] diff --git a/packages/contracts/generated/api/console/logout/zod.gen.ts b/packages/contracts/generated/api/console/logout/zod.gen.ts new file mode 100644 index 0000000000..2e2be21264 --- /dev/null +++ b/packages/contracts/generated/api/console/logout/zod.gen.ts @@ -0,0 +1,8 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * Success + */ +export const zPostLogoutResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/mcp/orpc.gen.ts b/packages/contracts/generated/api/console/mcp/orpc.gen.ts new file mode 100644 index 0000000000..211e8cb2f2 --- /dev/null +++ b/packages/contracts/generated/api/console/mcp/orpc.gen.ts @@ -0,0 +1,31 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' + +import { zGetMcpOauthCallbackResponse } from './zod.gen' + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getMcpOauthCallback', + path: '/mcp/oauth/callback', + tags: ['console'], + }) + .output(zGetMcpOauthCallbackResponse) + +export const callback = { + get, +} + +export const oauth = { + callback, +} + +export const mcp = { + oauth, +} + +export const contract = { + mcp, +} diff --git a/packages/contracts/generated/api/console/mcp/types.gen.ts b/packages/contracts/generated/api/console/mcp/types.gen.ts new file mode 100644 index 0000000000..4e96a66393 --- /dev/null +++ b/packages/contracts/generated/api/console/mcp/types.gen.ts @@ -0,0 +1,21 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type GetMcpOauthCallbackData = { + body?: never + path?: never + query?: never + url: '/mcp/oauth/callback' +} + +export type GetMcpOauthCallbackResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetMcpOauthCallbackResponse + = GetMcpOauthCallbackResponses[keyof GetMcpOauthCallbackResponses] diff --git a/packages/contracts/generated/api/console/mcp/zod.gen.ts b/packages/contracts/generated/api/console/mcp/zod.gen.ts new file mode 100644 index 0000000000..ade0c01f7a --- /dev/null +++ b/packages/contracts/generated/api/console/mcp/zod.gen.ts @@ -0,0 +1,8 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * Success + */ +export const zGetMcpOauthCallbackResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/notification/orpc.gen.ts b/packages/contracts/generated/api/console/notification/orpc.gen.ts new file mode 100644 index 0000000000..f7125346cf --- /dev/null +++ b/packages/contracts/generated/api/console/notification/orpc.gen.ts @@ -0,0 +1,47 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' + +import { zGetNotificationResponse, zPostNotificationDismissResponse } from './zod.gen' + +/** + * Mark a notification as dismissed for the current user. + */ +export const post = oc + .route({ + description: 'Mark a notification as dismissed for the current user.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postNotificationDismiss', + path: '/notification/dismiss', + tags: ['console'], + }) + .output(zPostNotificationDismissResponse) + +export const dismiss = { + post, +} + +/** + * Return the active in-product notification for the current user in their interface language (falls back to English if unavailable). The notification is NOT marked as seen here; call POST /notification/dismiss when the user explicitly closes the modal. + */ +export const get = oc + .route({ + description: + 'Return the active in-product notification for the current user in their interface language (falls back to English if unavailable). The notification is NOT marked as seen here; call POST /notification/dismiss when the user explicitly closes the modal.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getNotification', + path: '/notification', + tags: ['console'], + }) + .output(zGetNotificationResponse) + +export const notification = { + get, + dismiss, +} + +export const contract = { + notification, +} diff --git a/packages/contracts/generated/api/console/notification/types.gen.ts b/packages/contracts/generated/api/console/notification/types.gen.ts new file mode 100644 index 0000000000..8fe661016b --- /dev/null +++ b/packages/contracts/generated/api/console/notification/types.gen.ts @@ -0,0 +1,53 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type GetNotificationData = { + body?: never + path?: never + query?: never + url: '/notification' +} + +export type GetNotificationErrors = { + 401: { + [key: string]: unknown + } +} + +export type GetNotificationError = GetNotificationErrors[keyof GetNotificationErrors] + +export type GetNotificationResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetNotificationResponse = GetNotificationResponses[keyof GetNotificationResponses] + +export type PostNotificationDismissData = { + body?: never + path?: never + query?: never + url: '/notification/dismiss' +} + +export type PostNotificationDismissErrors = { + 401: { + [key: string]: unknown + } +} + +export type PostNotificationDismissError + = PostNotificationDismissErrors[keyof PostNotificationDismissErrors] + +export type PostNotificationDismissResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostNotificationDismissResponse + = PostNotificationDismissResponses[keyof PostNotificationDismissResponses] diff --git a/packages/contracts/generated/api/console/notification/zod.gen.ts b/packages/contracts/generated/api/console/notification/zod.gen.ts new file mode 100644 index 0000000000..c17e436ed9 --- /dev/null +++ b/packages/contracts/generated/api/console/notification/zod.gen.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * Success — inspect should_show to decide whether to render the modal + */ +export const zGetNotificationResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPostNotificationDismissResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/notion/orpc.gen.ts b/packages/contracts/generated/api/console/notion/orpc.gen.ts new file mode 100644 index 0000000000..b8de9e89f2 --- /dev/null +++ b/packages/contracts/generated/api/console/notion/orpc.gen.ts @@ -0,0 +1,84 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetNotionPagesByPageIdByPageTypePreviewPath, + zGetNotionPagesByPageIdByPageTypePreviewResponse, + zGetNotionPreImportPagesResponse, + zPostNotionPagesByPageIdByPageTypePreviewBody, + zPostNotionPagesByPageIdByPageTypePreviewPath, + zPostNotionPagesByPageIdByPageTypePreviewResponse, +} from './zod.gen' + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getNotionPagesByPageIdByPageTypePreview', + path: '/notion/pages/{page_id}/{page_type}/preview', + tags: ['console'], + }) + .input(z.object({ params: zGetNotionPagesByPageIdByPageTypePreviewPath })) + .output(zGetNotionPagesByPageIdByPageTypePreviewResponse) + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postNotionPagesByPageIdByPageTypePreview', + path: '/notion/pages/{page_id}/{page_type}/preview', + tags: ['console'], + }) + .input( + z.object({ + body: zPostNotionPagesByPageIdByPageTypePreviewBody, + params: zPostNotionPagesByPageIdByPageTypePreviewPath, + }), + ) + .output(zPostNotionPagesByPageIdByPageTypePreviewResponse) + +export const preview = { + get, + post, +} + +export const byPageType = { + preview, +} + +export const byPageId = { + byPageType, +} + +export const pages = { + byPageId, +} + +export const get2 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getNotionPreImportPages', + path: '/notion/pre-import/pages', + tags: ['console'], + }) + .output(zGetNotionPreImportPagesResponse) + +export const pages2 = { + get: get2, +} + +export const preImport = { + pages: pages2, +} + +export const notion = { + pages, + preImport, +} + +export const contract = { + notion, +} diff --git a/packages/contracts/generated/api/console/notion/types.gen.ts b/packages/contracts/generated/api/console/notion/types.gen.ts new file mode 100644 index 0000000000..c616a22286 --- /dev/null +++ b/packages/contracts/generated/api/console/notion/types.gen.ts @@ -0,0 +1,70 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type NotionEstimatePayload = { + doc_form?: string + doc_language?: string + notion_info_list: Array<{ + [key: string]: unknown + }> + process_rule: { + [key: string]: unknown + } +} + +export type GetNotionPagesByPageIdByPageTypePreviewData = { + body?: never + path: { + page_id: string + page_type: string + } + query?: never + url: '/notion/pages/{page_id}/{page_type}/preview' +} + +export type GetNotionPagesByPageIdByPageTypePreviewResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetNotionPagesByPageIdByPageTypePreviewResponse + = GetNotionPagesByPageIdByPageTypePreviewResponses[keyof GetNotionPagesByPageIdByPageTypePreviewResponses] + +export type PostNotionPagesByPageIdByPageTypePreviewData = { + body: NotionEstimatePayload + path: { + page_id: string + page_type: string + } + query?: never + url: '/notion/pages/{page_id}/{page_type}/preview' +} + +export type PostNotionPagesByPageIdByPageTypePreviewResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostNotionPagesByPageIdByPageTypePreviewResponse + = PostNotionPagesByPageIdByPageTypePreviewResponses[keyof PostNotionPagesByPageIdByPageTypePreviewResponses] + +export type GetNotionPreImportPagesData = { + body?: never + path?: never + query?: never + url: '/notion/pre-import/pages' +} + +export type GetNotionPreImportPagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetNotionPreImportPagesResponse + = GetNotionPreImportPagesResponses[keyof GetNotionPreImportPagesResponses] diff --git a/packages/contracts/generated/api/console/notion/zod.gen.ts b/packages/contracts/generated/api/console/notion/zod.gen.ts new file mode 100644 index 0000000000..0aad7b682c --- /dev/null +++ b/packages/contracts/generated/api/console/notion/zod.gen.ts @@ -0,0 +1,40 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * NotionEstimatePayload + */ +export const zNotionEstimatePayload = z.object({ + doc_form: z.string().optional().default('text_model'), + doc_language: z.string().optional().default('English'), + notion_info_list: z.array(z.record(z.string(), z.unknown())), + process_rule: z.record(z.string(), z.unknown()), +}) + +export const zGetNotionPagesByPageIdByPageTypePreviewPath = z.object({ + page_id: z.string(), + page_type: z.string(), +}) + +/** + * Success + */ +export const zGetNotionPagesByPageIdByPageTypePreviewResponse = z.record(z.string(), z.unknown()) + +export const zPostNotionPagesByPageIdByPageTypePreviewBody = zNotionEstimatePayload + +export const zPostNotionPagesByPageIdByPageTypePreviewPath = z.object({ + page_id: z.string(), + page_type: z.string(), +}) + +/** + * Success + */ +export const zPostNotionPagesByPageIdByPageTypePreviewResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetNotionPreImportPagesResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/oauth/orpc.gen.ts b/packages/contracts/generated/api/console/oauth/orpc.gen.ts new file mode 100644 index 0000000000..b9a57e3e88 --- /dev/null +++ b/packages/contracts/generated/api/console/oauth/orpc.gen.ts @@ -0,0 +1,376 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetOauthAuthorizeByProviderPath, + zGetOauthAuthorizeByProviderQuery, + zGetOauthAuthorizeByProviderResponse, + zGetOauthDataSourceBindingByProviderPath, + zGetOauthDataSourceBindingByProviderQuery, + zGetOauthDataSourceBindingByProviderResponse, + zGetOauthDataSourceByProviderByBindingIdSyncPath, + zGetOauthDataSourceByProviderByBindingIdSyncResponse, + zGetOauthDataSourceByProviderPath, + zGetOauthDataSourceByProviderResponse, + zGetOauthDataSourceCallbackByProviderPath, + zGetOauthDataSourceCallbackByProviderQuery, + zGetOauthDataSourceCallbackByProviderResponse, + zGetOauthLoginByProviderPath, + zGetOauthLoginByProviderQuery, + zGetOauthLoginByProviderResponse, + zGetOauthPluginByProviderIdDatasourceCallbackPath, + zGetOauthPluginByProviderIdDatasourceCallbackResponse, + zGetOauthPluginByProviderIdDatasourceGetAuthorizationUrlPath, + zGetOauthPluginByProviderIdDatasourceGetAuthorizationUrlResponse, + zGetOauthPluginByProviderToolAuthorizationUrlPath, + zGetOauthPluginByProviderToolAuthorizationUrlResponse, + zGetOauthPluginByProviderToolCallbackPath, + zGetOauthPluginByProviderToolCallbackResponse, + zGetOauthPluginByProviderTriggerCallbackPath, + zGetOauthPluginByProviderTriggerCallbackResponse, + zPostOauthProviderAccountResponse, + zPostOauthProviderAuthorizeResponse, + zPostOauthProviderResponse, + zPostOauthProviderTokenResponse, +} from './zod.gen' + +/** + * Handle OAuth callback and complete login process + */ +export const get = oc + .route({ + description: 'Handle OAuth callback and complete login process', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getOauthAuthorizeByProvider', + path: '/oauth/authorize/{provider}', + tags: ['console'], + }) + .input( + z.object({ + params: zGetOauthAuthorizeByProviderPath, + query: zGetOauthAuthorizeByProviderQuery.optional(), + }), + ) + .output(zGetOauthAuthorizeByProviderResponse) + +export const byProvider = { + get, +} + +export const authorize = { + byProvider, +} + +/** + * Bind OAuth data source with authorization code + */ +export const get2 = oc + .route({ + description: 'Bind OAuth data source with authorization code', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getOauthDataSourceBindingByProvider', + path: '/oauth/data-source/binding/{provider}', + tags: ['console'], + }) + .input( + z.object({ + params: zGetOauthDataSourceBindingByProviderPath, + query: zGetOauthDataSourceBindingByProviderQuery.optional(), + }), + ) + .output(zGetOauthDataSourceBindingByProviderResponse) + +export const byProvider2 = { + get: get2, +} + +export const binding = { + byProvider: byProvider2, +} + +/** + * Handle OAuth callback from data source provider + */ +export const get3 = oc + .route({ + description: 'Handle OAuth callback from data source provider', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getOauthDataSourceCallbackByProvider', + path: '/oauth/data-source/callback/{provider}', + tags: ['console'], + }) + .input( + z.object({ + params: zGetOauthDataSourceCallbackByProviderPath, + query: zGetOauthDataSourceCallbackByProviderQuery.optional(), + }), + ) + .output(zGetOauthDataSourceCallbackByProviderResponse) + +export const byProvider3 = { + get: get3, +} + +export const callback = { + byProvider: byProvider3, +} + +/** + * Sync data from OAuth data source + */ +export const get4 = oc + .route({ + description: 'Sync data from OAuth data source', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getOauthDataSourceByProviderByBindingIdSync', + path: '/oauth/data-source/{provider}/{binding_id}/sync', + tags: ['console'], + }) + .input(z.object({ params: zGetOauthDataSourceByProviderByBindingIdSyncPath })) + .output(zGetOauthDataSourceByProviderByBindingIdSyncResponse) + +export const sync = { + get: get4, +} + +export const byBindingId = { + sync, +} + +/** + * Get OAuth authorization URL for data source provider + */ +export const get5 = oc + .route({ + description: 'Get OAuth authorization URL for data source provider', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getOauthDataSourceByProvider', + path: '/oauth/data-source/{provider}', + tags: ['console'], + }) + .input(z.object({ params: zGetOauthDataSourceByProviderPath })) + .output(zGetOauthDataSourceByProviderResponse) + +export const byProvider4 = { + get: get5, + byBindingId, +} + +export const dataSource = { + binding, + callback, + byProvider: byProvider4, +} + +/** + * Initiate OAuth login process + */ +export const get6 = oc + .route({ + description: 'Initiate OAuth login process', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getOauthLoginByProvider', + path: '/oauth/login/{provider}', + tags: ['console'], + }) + .input( + z.object({ + params: zGetOauthLoginByProviderPath, + query: zGetOauthLoginByProviderQuery.optional(), + }), + ) + .output(zGetOauthLoginByProviderResponse) + +export const byProvider5 = { + get: get6, +} + +export const login = { + byProvider: byProvider5, +} + +export const get7 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getOauthPluginByProviderIdDatasourceCallback', + path: '/oauth/plugin/{provider_id}/datasource/callback', + tags: ['console'], + }) + .input(z.object({ params: zGetOauthPluginByProviderIdDatasourceCallbackPath })) + .output(zGetOauthPluginByProviderIdDatasourceCallbackResponse) + +export const callback2 = { + get: get7, +} + +export const get8 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getOauthPluginByProviderIdDatasourceGetAuthorizationUrl', + path: '/oauth/plugin/{provider_id}/datasource/get-authorization-url', + tags: ['console'], + }) + .input(z.object({ params: zGetOauthPluginByProviderIdDatasourceGetAuthorizationUrlPath })) + .output(zGetOauthPluginByProviderIdDatasourceGetAuthorizationUrlResponse) + +export const getAuthorizationUrl = { + get: get8, +} + +export const datasource = { + callback: callback2, + getAuthorizationUrl, +} + +export const byProviderId = { + datasource, +} + +export const get9 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getOauthPluginByProviderToolAuthorizationUrl', + path: '/oauth/plugin/{provider}/tool/authorization-url', + tags: ['console'], + }) + .input(z.object({ params: zGetOauthPluginByProviderToolAuthorizationUrlPath })) + .output(zGetOauthPluginByProviderToolAuthorizationUrlResponse) + +export const authorizationUrl = { + get: get9, +} + +export const get10 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getOauthPluginByProviderToolCallback', + path: '/oauth/plugin/{provider}/tool/callback', + tags: ['console'], + }) + .input(z.object({ params: zGetOauthPluginByProviderToolCallbackPath })) + .output(zGetOauthPluginByProviderToolCallbackResponse) + +export const callback3 = { + get: get10, +} + +export const tool = { + authorizationUrl, + callback: callback3, +} + +/** + * Handle OAuth callback for trigger provider + */ +export const get11 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getOauthPluginByProviderTriggerCallback', + path: '/oauth/plugin/{provider}/trigger/callback', + summary: 'Handle OAuth callback for trigger provider', + tags: ['console'], + }) + .input(z.object({ params: zGetOauthPluginByProviderTriggerCallbackPath })) + .output(zGetOauthPluginByProviderTriggerCallbackResponse) + +export const callback4 = { + get: get11, +} + +export const trigger = { + callback: callback4, +} + +export const byProvider6 = { + tool, + trigger, +} + +export const plugin = { + byProviderId, + byProvider: byProvider6, +} + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postOauthProviderAccount', + path: '/oauth/provider/account', + tags: ['console'], + }) + .output(zPostOauthProviderAccountResponse) + +export const account = { + post, +} + +export const post2 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postOauthProviderAuthorize', + path: '/oauth/provider/authorize', + tags: ['console'], + }) + .output(zPostOauthProviderAuthorizeResponse) + +export const authorize2 = { + post: post2, +} + +export const post3 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postOauthProviderToken', + path: '/oauth/provider/token', + tags: ['console'], + }) + .output(zPostOauthProviderTokenResponse) + +export const token = { + post: post3, +} + +export const post4 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postOauthProvider', + path: '/oauth/provider', + tags: ['console'], + }) + .output(zPostOauthProviderResponse) + +export const provider = { + post: post4, + account, + authorize: authorize2, + token, +} + +export const oauth = { + authorize, + dataSource, + login, + plugin, + provider, +} + +export const contract = { + oauth, +} diff --git a/packages/contracts/generated/api/console/oauth/types.gen.ts b/packages/contracts/generated/api/console/oauth/types.gen.ts new file mode 100644 index 0000000000..7091cdab7c --- /dev/null +++ b/packages/contracts/generated/api/console/oauth/types.gen.ts @@ -0,0 +1,340 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type OAuthDataSourceBindingResponse = { + result: string +} + +export type OAuthDataSourceResponse = { + data: string +} + +export type OAuthDataSourceSyncResponse = { + result: string +} + +export type GetOauthAuthorizeByProviderData = { + body?: never + path: { + provider: string + } + query?: { + code?: string + state?: string + } + url: '/oauth/authorize/{provider}' +} + +export type GetOauthAuthorizeByProviderErrors = { + 400: { + [key: string]: unknown + } +} + +export type GetOauthAuthorizeByProviderError + = GetOauthAuthorizeByProviderErrors[keyof GetOauthAuthorizeByProviderErrors] + +export type GetOauthAuthorizeByProviderResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetOauthAuthorizeByProviderResponse + = GetOauthAuthorizeByProviderResponses[keyof GetOauthAuthorizeByProviderResponses] + +export type GetOauthDataSourceBindingByProviderData = { + body?: never + path: { + provider: string + } + query?: { + code?: string + } + url: '/oauth/data-source/binding/{provider}' +} + +export type GetOauthDataSourceBindingByProviderErrors = { + 400: { + [key: string]: unknown + } +} + +export type GetOauthDataSourceBindingByProviderError + = GetOauthDataSourceBindingByProviderErrors[keyof GetOauthDataSourceBindingByProviderErrors] + +export type GetOauthDataSourceBindingByProviderResponses = { + 200: OAuthDataSourceBindingResponse +} + +export type GetOauthDataSourceBindingByProviderResponse + = GetOauthDataSourceBindingByProviderResponses[keyof GetOauthDataSourceBindingByProviderResponses] + +export type GetOauthDataSourceCallbackByProviderData = { + body?: never + path: { + provider: string + } + query?: { + code?: string + error?: string + } + url: '/oauth/data-source/callback/{provider}' +} + +export type GetOauthDataSourceCallbackByProviderErrors = { + 400: { + [key: string]: unknown + } +} + +export type GetOauthDataSourceCallbackByProviderError + = GetOauthDataSourceCallbackByProviderErrors[keyof GetOauthDataSourceCallbackByProviderErrors] + +export type GetOauthDataSourceCallbackByProviderResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetOauthDataSourceCallbackByProviderResponse + = GetOauthDataSourceCallbackByProviderResponses[keyof GetOauthDataSourceCallbackByProviderResponses] + +export type GetOauthDataSourceByProviderData = { + body?: never + path: { + provider: string + } + query?: never + url: '/oauth/data-source/{provider}' +} + +export type GetOauthDataSourceByProviderErrors = { + 400: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type GetOauthDataSourceByProviderError + = GetOauthDataSourceByProviderErrors[keyof GetOauthDataSourceByProviderErrors] + +export type GetOauthDataSourceByProviderResponses = { + 200: OAuthDataSourceResponse +} + +export type GetOauthDataSourceByProviderResponse + = GetOauthDataSourceByProviderResponses[keyof GetOauthDataSourceByProviderResponses] + +export type GetOauthDataSourceByProviderByBindingIdSyncData = { + body?: never + path: { + provider: string + binding_id: string + } + query?: never + url: '/oauth/data-source/{provider}/{binding_id}/sync' +} + +export type GetOauthDataSourceByProviderByBindingIdSyncErrors = { + 400: { + [key: string]: unknown + } +} + +export type GetOauthDataSourceByProviderByBindingIdSyncError + = GetOauthDataSourceByProviderByBindingIdSyncErrors[keyof GetOauthDataSourceByProviderByBindingIdSyncErrors] + +export type GetOauthDataSourceByProviderByBindingIdSyncResponses = { + 200: OAuthDataSourceSyncResponse +} + +export type GetOauthDataSourceByProviderByBindingIdSyncResponse + = GetOauthDataSourceByProviderByBindingIdSyncResponses[keyof GetOauthDataSourceByProviderByBindingIdSyncResponses] + +export type GetOauthLoginByProviderData = { + body?: never + path: { + provider: string + } + query?: { + invite_token?: string + } + url: '/oauth/login/{provider}' +} + +export type GetOauthLoginByProviderErrors = { + 400: { + [key: string]: unknown + } +} + +export type GetOauthLoginByProviderError + = GetOauthLoginByProviderErrors[keyof GetOauthLoginByProviderErrors] + +export type GetOauthLoginByProviderResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetOauthLoginByProviderResponse + = GetOauthLoginByProviderResponses[keyof GetOauthLoginByProviderResponses] + +export type GetOauthPluginByProviderIdDatasourceCallbackData = { + body?: never + path: { + provider_id: string + } + query?: never + url: '/oauth/plugin/{provider_id}/datasource/callback' +} + +export type GetOauthPluginByProviderIdDatasourceCallbackResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetOauthPluginByProviderIdDatasourceCallbackResponse + = GetOauthPluginByProviderIdDatasourceCallbackResponses[keyof GetOauthPluginByProviderIdDatasourceCallbackResponses] + +export type GetOauthPluginByProviderIdDatasourceGetAuthorizationUrlData = { + body?: never + path: { + provider_id: string + } + query?: never + url: '/oauth/plugin/{provider_id}/datasource/get-authorization-url' +} + +export type GetOauthPluginByProviderIdDatasourceGetAuthorizationUrlResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetOauthPluginByProviderIdDatasourceGetAuthorizationUrlResponse + = GetOauthPluginByProviderIdDatasourceGetAuthorizationUrlResponses[keyof GetOauthPluginByProviderIdDatasourceGetAuthorizationUrlResponses] + +export type GetOauthPluginByProviderToolAuthorizationUrlData = { + body?: never + path: { + provider: string + } + query?: never + url: '/oauth/plugin/{provider}/tool/authorization-url' +} + +export type GetOauthPluginByProviderToolAuthorizationUrlResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetOauthPluginByProviderToolAuthorizationUrlResponse + = GetOauthPluginByProviderToolAuthorizationUrlResponses[keyof GetOauthPluginByProviderToolAuthorizationUrlResponses] + +export type GetOauthPluginByProviderToolCallbackData = { + body?: never + path: { + provider: string + } + query?: never + url: '/oauth/plugin/{provider}/tool/callback' +} + +export type GetOauthPluginByProviderToolCallbackResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetOauthPluginByProviderToolCallbackResponse + = GetOauthPluginByProviderToolCallbackResponses[keyof GetOauthPluginByProviderToolCallbackResponses] + +export type GetOauthPluginByProviderTriggerCallbackData = { + body?: never + path: { + provider: string + } + query?: never + url: '/oauth/plugin/{provider}/trigger/callback' +} + +export type GetOauthPluginByProviderTriggerCallbackResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetOauthPluginByProviderTriggerCallbackResponse + = GetOauthPluginByProviderTriggerCallbackResponses[keyof GetOauthPluginByProviderTriggerCallbackResponses] + +export type PostOauthProviderData = { + body?: never + path?: never + query?: never + url: '/oauth/provider' +} + +export type PostOauthProviderResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostOauthProviderResponse = PostOauthProviderResponses[keyof PostOauthProviderResponses] + +export type PostOauthProviderAccountData = { + body?: never + path?: never + query?: never + url: '/oauth/provider/account' +} + +export type PostOauthProviderAccountResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostOauthProviderAccountResponse + = PostOauthProviderAccountResponses[keyof PostOauthProviderAccountResponses] + +export type PostOauthProviderAuthorizeData = { + body?: never + path?: never + query?: never + url: '/oauth/provider/authorize' +} + +export type PostOauthProviderAuthorizeResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostOauthProviderAuthorizeResponse + = PostOauthProviderAuthorizeResponses[keyof PostOauthProviderAuthorizeResponses] + +export type PostOauthProviderTokenData = { + body?: never + path?: never + query?: never + url: '/oauth/provider/token' +} + +export type PostOauthProviderTokenResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostOauthProviderTokenResponse + = PostOauthProviderTokenResponses[keyof PostOauthProviderTokenResponses] diff --git a/packages/contracts/generated/api/console/oauth/zod.gen.ts b/packages/contracts/generated/api/console/oauth/zod.gen.ts new file mode 100644 index 0000000000..22f2c4bd76 --- /dev/null +++ b/packages/contracts/generated/api/console/oauth/zod.gen.ts @@ -0,0 +1,171 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * OAuthDataSourceBindingResponse + */ +export const zOAuthDataSourceBindingResponse = z.object({ + result: z.string(), +}) + +/** + * OAuthDataSourceResponse + */ +export const zOAuthDataSourceResponse = z.object({ + data: z.string(), +}) + +/** + * OAuthDataSourceSyncResponse + */ +export const zOAuthDataSourceSyncResponse = z.object({ + result: z.string(), +}) + +export const zGetOauthAuthorizeByProviderPath = z.object({ + provider: z.string(), +}) + +export const zGetOauthAuthorizeByProviderQuery = z.object({ + code: z.string().optional(), + state: z.string().optional(), +}) + +/** + * Success + */ +export const zGetOauthAuthorizeByProviderResponse = z.record(z.string(), z.unknown()) + +export const zGetOauthDataSourceBindingByProviderPath = z.object({ + provider: z.string(), +}) + +export const zGetOauthDataSourceBindingByProviderQuery = z.object({ + code: z.string().optional(), +}) + +/** + * Data source binding success + */ +export const zGetOauthDataSourceBindingByProviderResponse = zOAuthDataSourceBindingResponse + +export const zGetOauthDataSourceCallbackByProviderPath = z.object({ + provider: z.string(), +}) + +export const zGetOauthDataSourceCallbackByProviderQuery = z.object({ + code: z.string().optional(), + error: z.string().optional(), +}) + +/** + * Success + */ +export const zGetOauthDataSourceCallbackByProviderResponse = z.record(z.string(), z.unknown()) + +export const zGetOauthDataSourceByProviderPath = z.object({ + provider: z.string(), +}) + +/** + * Authorization URL or internal setup success + */ +export const zGetOauthDataSourceByProviderResponse = zOAuthDataSourceResponse + +export const zGetOauthDataSourceByProviderByBindingIdSyncPath = z.object({ + provider: z.string(), + binding_id: z.string(), +}) + +/** + * Data source sync success + */ +export const zGetOauthDataSourceByProviderByBindingIdSyncResponse = zOAuthDataSourceSyncResponse + +export const zGetOauthLoginByProviderPath = z.object({ + provider: z.string(), +}) + +export const zGetOauthLoginByProviderQuery = z.object({ + invite_token: z.string().optional(), +}) + +/** + * Success + */ +export const zGetOauthLoginByProviderResponse = z.record(z.string(), z.unknown()) + +export const zGetOauthPluginByProviderIdDatasourceCallbackPath = z.object({ + provider_id: z.string(), +}) + +/** + * Success + */ +export const zGetOauthPluginByProviderIdDatasourceCallbackResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetOauthPluginByProviderIdDatasourceGetAuthorizationUrlPath = z.object({ + provider_id: z.string(), +}) + +/** + * Success + */ +export const zGetOauthPluginByProviderIdDatasourceGetAuthorizationUrlResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetOauthPluginByProviderToolAuthorizationUrlPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetOauthPluginByProviderToolAuthorizationUrlResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetOauthPluginByProviderToolCallbackPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetOauthPluginByProviderToolCallbackResponse = z.record(z.string(), z.unknown()) + +export const zGetOauthPluginByProviderTriggerCallbackPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetOauthPluginByProviderTriggerCallbackResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPostOauthProviderResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPostOauthProviderAccountResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPostOauthProviderAuthorizeResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPostOauthProviderTokenResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/rag/orpc.gen.ts b/packages/contracts/generated/api/console/rag/orpc.gen.ts new file mode 100644 index 0000000000..a642a91ba1 --- /dev/null +++ b/packages/contracts/generated/api/console/rag/orpc.gen.ts @@ -0,0 +1,1230 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteRagPipelineCustomizedTemplatesByTemplateIdPath, + zDeleteRagPipelineCustomizedTemplatesByTemplateIdResponse, + zDeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdPath, + zDeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponse, + zDeleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesPath, + zDeleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponse, + zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdPath, + zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse, + zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesPath, + zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesResponse, + zGetRagPipelinesByPipelineIdExportsPath, + zGetRagPipelinesByPipelineIdExportsResponse, + zGetRagPipelinesByPipelineIdWorkflowRunsByRunIdNodeExecutionsPath, + zGetRagPipelinesByPipelineIdWorkflowRunsByRunIdNodeExecutionsResponse, + zGetRagPipelinesByPipelineIdWorkflowRunsByRunIdPath, + zGetRagPipelinesByPipelineIdWorkflowRunsByRunIdResponse, + zGetRagPipelinesByPipelineIdWorkflowRunsPath, + zGetRagPipelinesByPipelineIdWorkflowRunsResponse, + zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypePath, + zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse, + zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsPath, + zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponse, + zGetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesPath, + zGetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponse, + zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunPath, + zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunResponse, + zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesPath, + zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponse, + zGetRagPipelinesByPipelineIdWorkflowsDraftPath, + zGetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersPath, + zGetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersResponse, + zGetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersPath, + zGetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponse, + zGetRagPipelinesByPipelineIdWorkflowsDraftResponse, + zGetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesPath, + zGetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesResponse, + zGetRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdPath, + zGetRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse, + zGetRagPipelinesByPipelineIdWorkflowsDraftVariablesPath, + zGetRagPipelinesByPipelineIdWorkflowsDraftVariablesResponse, + zGetRagPipelinesByPipelineIdWorkflowsPath, + zGetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersPath, + zGetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersResponse, + zGetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersPath, + zGetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponse, + zGetRagPipelinesByPipelineIdWorkflowsPublishPath, + zGetRagPipelinesByPipelineIdWorkflowsPublishResponse, + zGetRagPipelinesByPipelineIdWorkflowsResponse, + zGetRagPipelinesDatasourcePluginsResponse, + zGetRagPipelinesImportsByPipelineIdCheckDependenciesPath, + zGetRagPipelinesImportsByPipelineIdCheckDependenciesResponse, + zGetRagPipelinesRecommendedPluginsResponse, + zGetRagPipelineTemplatesByTemplateIdPath, + zGetRagPipelineTemplatesByTemplateIdResponse, + zGetRagPipelineTemplatesResponse, + zPatchRagPipelineCustomizedTemplatesByTemplateIdPath, + zPatchRagPipelineCustomizedTemplatesByTemplateIdResponse, + zPatchRagPipelinesByPipelineIdWorkflowsByWorkflowIdPath, + zPatchRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponse, + zPatchRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdPath, + zPatchRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse, + zPostRagPipelineCustomizedTemplatesByTemplateIdPath, + zPostRagPipelineCustomizedTemplatesByTemplateIdResponse, + zPostRagPipelineDatasetBody, + zPostRagPipelineDatasetResponse, + zPostRagPipelineEmptyDatasetResponse, + zPostRagPipelinesByPipelineIdCustomizedPublishBody, + zPostRagPipelinesByPipelineIdCustomizedPublishPath, + zPostRagPipelinesByPipelineIdCustomizedPublishResponse, + zPostRagPipelinesByPipelineIdWorkflowRunsTasksByTaskIdStopPath, + zPostRagPipelinesByPipelineIdWorkflowRunsTasksByTaskIdStopResponse, + zPostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestorePath, + zPostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestoreResponse, + zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunBody, + zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunPath, + zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponse, + zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectBody, + zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectPath, + zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectResponse, + zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunBody, + zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunPath, + zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponse, + zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunBody, + zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunPath, + zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponse, + zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunBody, + zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunPath, + zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunResponse, + zPostRagPipelinesByPipelineIdWorkflowsDraftPath, + zPostRagPipelinesByPipelineIdWorkflowsDraftResponse, + zPostRagPipelinesByPipelineIdWorkflowsDraftRunBody, + zPostRagPipelinesByPipelineIdWorkflowsDraftRunPath, + zPostRagPipelinesByPipelineIdWorkflowsDraftRunResponse, + zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewBody, + zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewPath, + zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponse, + zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunBody, + zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunPath, + zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponse, + zPostRagPipelinesByPipelineIdWorkflowsPublishedRunBody, + zPostRagPipelinesByPipelineIdWorkflowsPublishedRunPath, + zPostRagPipelinesByPipelineIdWorkflowsPublishedRunResponse, + zPostRagPipelinesByPipelineIdWorkflowsPublishPath, + zPostRagPipelinesByPipelineIdWorkflowsPublishResponse, + zPostRagPipelinesImportsBody, + zPostRagPipelinesImportsByImportIdConfirmPath, + zPostRagPipelinesImportsByImportIdConfirmResponse, + zPostRagPipelinesImportsResponse, + zPostRagPipelinesTransformDatasetsByDatasetIdPath, + zPostRagPipelinesTransformDatasetsByDatasetIdResponse, + zPutRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResetPath, + zPutRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResetResponse, +} from './zod.gen' + +export const delete_ = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteRagPipelineCustomizedTemplatesByTemplateId', + path: '/rag/pipeline/customized/templates/{template_id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteRagPipelineCustomizedTemplatesByTemplateIdPath })) + .output(zDeleteRagPipelineCustomizedTemplatesByTemplateIdResponse) + +export const patch = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchRagPipelineCustomizedTemplatesByTemplateId', + path: '/rag/pipeline/customized/templates/{template_id}', + tags: ['console'], + }) + .input(z.object({ params: zPatchRagPipelineCustomizedTemplatesByTemplateIdPath })) + .output(zPatchRagPipelineCustomizedTemplatesByTemplateIdResponse) + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelineCustomizedTemplatesByTemplateId', + path: '/rag/pipeline/customized/templates/{template_id}', + tags: ['console'], + }) + .input(z.object({ params: zPostRagPipelineCustomizedTemplatesByTemplateIdPath })) + .output(zPostRagPipelineCustomizedTemplatesByTemplateIdResponse) + +export const byTemplateId = { + delete: delete_, + patch, + post, +} + +export const templates = { + byTemplateId, +} + +export const customized = { + templates, +} + +export const post2 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelineDataset', + path: '/rag/pipeline/dataset', + tags: ['console'], + }) + .input(z.object({ body: zPostRagPipelineDatasetBody })) + .output(zPostRagPipelineDatasetResponse) + +export const dataset = { + post: post2, +} + +export const post3 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelineEmptyDataset', + path: '/rag/pipeline/empty-dataset', + tags: ['console'], + }) + .output(zPostRagPipelineEmptyDatasetResponse) + +export const emptyDataset = { + post: post3, +} + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelineTemplatesByTemplateId', + path: '/rag/pipeline/templates/{template_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelineTemplatesByTemplateIdPath })) + .output(zGetRagPipelineTemplatesByTemplateIdResponse) + +export const byTemplateId2 = { + get, +} + +export const get2 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelineTemplates', + path: '/rag/pipeline/templates', + tags: ['console'], + }) + .output(zGetRagPipelineTemplatesResponse) + +export const templates2 = { + get: get2, + byTemplateId: byTemplateId2, +} + +export const pipeline = { + customized, + dataset, + emptyDataset, + templates: templates2, +} + +export const get3 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesDatasourcePlugins', + path: '/rag/pipelines/datasource-plugins', + tags: ['console'], + }) + .output(zGetRagPipelinesDatasourcePluginsResponse) + +export const datasourcePlugins = { + get: get3, +} + +export const post4 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesImportsByImportIdConfirm', + path: '/rag/pipelines/imports/{import_id}/confirm', + tags: ['console'], + }) + .input(z.object({ params: zPostRagPipelinesImportsByImportIdConfirmPath })) + .output(zPostRagPipelinesImportsByImportIdConfirmResponse) + +export const confirm = { + post: post4, +} + +export const byImportId = { + confirm, +} + +export const get4 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesImportsByPipelineIdCheckDependencies', + path: '/rag/pipelines/imports/{pipeline_id}/check-dependencies', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesImportsByPipelineIdCheckDependenciesPath })) + .output(zGetRagPipelinesImportsByPipelineIdCheckDependenciesResponse) + +export const checkDependencies = { + get: get4, +} + +export const byPipelineId = { + checkDependencies, +} + +export const post5 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesImports', + path: '/rag/pipelines/imports', + tags: ['console'], + }) + .input(z.object({ body: zPostRagPipelinesImportsBody })) + .output(zPostRagPipelinesImportsResponse) + +export const imports = { + post: post5, + byImportId, + byPipelineId, +} + +export const get5 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesRecommendedPlugins', + path: '/rag/pipelines/recommended-plugins', + tags: ['console'], + }) + .output(zGetRagPipelinesRecommendedPluginsResponse) + +export const recommendedPlugins = { + get: get5, +} + +export const post6 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesTransformDatasetsByDatasetId', + path: '/rag/pipelines/transform/datasets/{dataset_id}', + tags: ['console'], + }) + .input(z.object({ params: zPostRagPipelinesTransformDatasetsByDatasetIdPath })) + .output(zPostRagPipelinesTransformDatasetsByDatasetIdResponse) + +export const byDatasetId = { + post: post6, +} + +export const datasets = { + byDatasetId, +} + +export const transform = { + datasets, +} + +export const post7 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdCustomizedPublish', + path: '/rag/pipelines/{pipeline_id}/customized/publish', + tags: ['console'], + }) + .input( + z.object({ + body: zPostRagPipelinesByPipelineIdCustomizedPublishBody, + params: zPostRagPipelinesByPipelineIdCustomizedPublishPath, + }), + ) + .output(zPostRagPipelinesByPipelineIdCustomizedPublishResponse) + +export const publish = { + post: post7, +} + +export const customized2 = { + publish, +} + +export const get6 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdExports', + path: '/rag/pipelines/{pipeline_id}/exports', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdExportsPath })) + .output(zGetRagPipelinesByPipelineIdExportsResponse) + +export const exports_ = { + get: get6, +} + +/** + * Stop workflow task + */ +export const post8 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowRunsTasksByTaskIdStop', + path: '/rag/pipelines/{pipeline_id}/workflow-runs/tasks/{task_id}/stop', + summary: 'Stop workflow task', + tags: ['console'], + }) + .input(z.object({ params: zPostRagPipelinesByPipelineIdWorkflowRunsTasksByTaskIdStopPath })) + .output(zPostRagPipelinesByPipelineIdWorkflowRunsTasksByTaskIdStopResponse) + +export const stop = { + post: post8, +} + +export const byTaskId = { + stop, +} + +export const tasks = { + byTaskId, +} + +/** + * Get workflow run node execution list + */ +export const get7 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowRunsByRunIdNodeExecutions', + path: '/rag/pipelines/{pipeline_id}/workflow-runs/{run_id}/node-executions', + summary: 'Get workflow run node execution list', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowRunsByRunIdNodeExecutionsPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowRunsByRunIdNodeExecutionsResponse) + +export const nodeExecutions = { + get: get7, +} + +/** + * Get workflow run detail + */ +export const get8 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowRunsByRunId', + path: '/rag/pipelines/{pipeline_id}/workflow-runs/{run_id}', + summary: 'Get workflow run detail', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowRunsByRunIdPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowRunsByRunIdResponse) + +export const byRunId = { + get: get8, + nodeExecutions, +} + +/** + * Get workflow run list + */ +export const get9 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowRuns', + path: '/rag/pipelines/{pipeline_id}/workflow-runs', + summary: 'Get workflow run list', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowRunsPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowRunsResponse) + +export const workflowRuns = { + get: get9, + tasks, + byRunId, +} + +/** + * Get default block config + */ +export const get10 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockType', + path: '/rag/pipelines/{pipeline_id}/workflows/default-workflow-block-configs/{block_type}', + summary: 'Get default block config', + tags: ['console'], + }) + .input( + z.object({ + params: zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypePath, + }), + ) + .output(zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse) + +export const byBlockType = { + get: get10, +} + +/** + * Get default block config + */ +export const get11 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigs', + path: '/rag/pipelines/{pipeline_id}/workflows/default-workflow-block-configs', + summary: 'Get default block config', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponse) + +export const defaultWorkflowBlockConfigs = { + get: get11, + byBlockType, +} + +/** + * Run rag pipeline datasource + */ +export const post9 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRun', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/datasource/nodes/{node_id}/run', + summary: 'Run rag pipeline datasource', + tags: ['console'], + }) + .input( + z.object({ + body: zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunBody, + params: zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunPath, + }), + ) + .output(zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponse) + +export const run = { + post: post9, +} + +export const byNodeId = { + run, +} + +export const nodes = { + byNodeId, +} + +/** + * Set datasource variables + */ +export const post10 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspect', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/datasource/variables-inspect', + summary: 'Set datasource variables', + tags: ['console'], + }) + .input( + z.object({ + body: zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectBody, + params: zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectPath, + }), + ) + .output(zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectResponse) + +export const variablesInspect = { + post: post10, +} + +export const datasource = { + nodes, + variablesInspect, +} + +export const get12 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariables', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/environment-variables', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponse) + +export const environmentVariables = { + get: get12, +} + +/** + * Run draft workflow iteration node + */ +export const post11 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRun', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/iteration/nodes/{node_id}/run', + summary: 'Run draft workflow iteration node', + tags: ['console'], + }) + .input( + z.object({ + body: zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunBody, + params: zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunPath, + }), + ) + .output(zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponse) + +export const run2 = { + post: post11, +} + +export const byNodeId2 = { + run: run2, +} + +export const nodes2 = { + byNodeId: byNodeId2, +} + +export const iteration = { + nodes: nodes2, +} + +/** + * Run draft workflow loop node + */ +export const post12 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRun', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/loop/nodes/{node_id}/run', + summary: 'Run draft workflow loop node', + tags: ['console'], + }) + .input( + z.object({ + body: zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunBody, + params: zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunPath, + }), + ) + .output(zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponse) + +export const run3 = { + post: post12, +} + +export const byNodeId3 = { + run: run3, +} + +export const nodes3 = { + byNodeId: byNodeId3, +} + +export const loop = { + nodes: nodes3, +} + +export const get13 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRun', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/nodes/{node_id}/last-run', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunResponse) + +export const lastRun = { + get: get13, +} + +/** + * Run draft workflow node + */ +export const post13 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRun', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/nodes/{node_id}/run', + summary: 'Run draft workflow node', + tags: ['console'], + }) + .input( + z.object({ + body: zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunBody, + params: zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunPath, + }), + ) + .output(zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunResponse) + +export const run4 = { + post: post13, +} + +export const delete2 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariables', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/nodes/{node_id}/variables', + tags: ['console'], + }) + .input( + z.object({ params: zDeleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesPath }), + ) + .output(zDeleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponse) + +export const get14 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariables', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/nodes/{node_id}/variables', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponse) + +export const variables = { + delete: delete2, + get: get14, +} + +export const byNodeId4 = { + lastRun, + run: run4, + variables, +} + +export const nodes4 = { + byNodeId: byNodeId4, +} + +/** + * Get first step parameters of rag pipeline + */ +export const get15 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParameters', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/pre-processing/parameters', + summary: 'Get first step parameters of rag pipeline', + tags: ['console'], + }) + .input( + z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersPath }), + ) + .output(zGetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersResponse) + +export const parameters = { + get: get15, +} + +export const preProcessing = { + parameters, +} + +/** + * Get second step parameters of rag pipeline + */ +export const get16 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsDraftProcessingParameters', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/processing/parameters', + summary: 'Get second step parameters of rag pipeline', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponse) + +export const parameters2 = { + get: get16, +} + +export const processing = { + parameters: parameters2, +} + +/** + * Run draft workflow + */ +export const post14 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowsDraftRun', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/run', + summary: 'Run draft workflow', + tags: ['console'], + }) + .input( + z.object({ + body: zPostRagPipelinesByPipelineIdWorkflowsDraftRunBody, + params: zPostRagPipelinesByPipelineIdWorkflowsDraftRunPath, + }), + ) + .output(zPostRagPipelinesByPipelineIdWorkflowsDraftRunResponse) + +export const run5 = { + post: post14, +} + +export const get17 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsDraftSystemVariables', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/system-variables', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesResponse) + +export const systemVariables = { + get: get17, +} + +export const put = oc + .route({ + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdReset', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/variables/{variable_id}/reset', + tags: ['console'], + }) + .input( + z.object({ params: zPutRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResetPath }), + ) + .output(zPutRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResetResponse) + +export const reset = { + put, +} + +export const delete3 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableId', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/variables/{variable_id}', + tags: ['console'], + }) + .input( + z.object({ params: zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdPath }), + ) + .output(zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse) + +export const get18 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableId', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/variables/{variable_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse) + +export const patch2 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableId', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/variables/{variable_id}', + tags: ['console'], + }) + .input( + z.object({ params: zPatchRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdPath }), + ) + .output(zPatchRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse) + +export const byVariableId = { + delete: delete3, + get: get18, + patch: patch2, + reset, +} + +export const delete4 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteRagPipelinesByPipelineIdWorkflowsDraftVariables', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/variables', + tags: ['console'], + }) + .input(z.object({ params: zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesPath })) + .output(zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesResponse) + +export const get19 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsDraftVariables', + path: '/rag/pipelines/{pipeline_id}/workflows/draft/variables', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsDraftVariablesPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowsDraftVariablesResponse) + +export const variables2 = { + delete: delete4, + get: get19, + byVariableId, +} + +/** + * Get draft rag pipeline's workflow + */ +export const get20 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsDraft', + path: '/rag/pipelines/{pipeline_id}/workflows/draft', + summary: 'Get draft rag pipeline\'s workflow', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsDraftPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowsDraftResponse) + +/** + * Sync draft workflow + */ +export const post15 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowsDraft', + path: '/rag/pipelines/{pipeline_id}/workflows/draft', + summary: 'Sync draft workflow', + tags: ['console'], + }) + .input(z.object({ params: zPostRagPipelinesByPipelineIdWorkflowsDraftPath })) + .output(zPostRagPipelinesByPipelineIdWorkflowsDraftResponse) + +export const draft = { + get: get20, + post: post15, + datasource, + environmentVariables, + iteration, + loop, + nodes: nodes4, + preProcessing, + processing, + run: run5, + systemVariables, + variables: variables2, +} + +/** + * Get published pipeline + */ +export const get21 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsPublish', + path: '/rag/pipelines/{pipeline_id}/workflows/publish', + summary: 'Get published pipeline', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsPublishPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowsPublishResponse) + +/** + * Publish workflow + */ +export const post16 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowsPublish', + path: '/rag/pipelines/{pipeline_id}/workflows/publish', + summary: 'Publish workflow', + tags: ['console'], + }) + .input(z.object({ params: zPostRagPipelinesByPipelineIdWorkflowsPublishPath })) + .output(zPostRagPipelinesByPipelineIdWorkflowsPublishResponse) + +export const publish2 = { + get: get21, + post: post16, +} + +/** + * Run datasource content preview + */ +export const post17 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreview', + path: '/rag/pipelines/{pipeline_id}/workflows/published/datasource/nodes/{node_id}/preview', + summary: 'Run datasource content preview', + tags: ['console'], + }) + .input( + z.object({ + body: zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewBody, + params: zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewPath, + }), + ) + .output(zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponse) + +export const preview = { + post: post17, +} + +/** + * Run rag pipeline datasource + */ +export const post18 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRun', + path: '/rag/pipelines/{pipeline_id}/workflows/published/datasource/nodes/{node_id}/run', + summary: 'Run rag pipeline datasource', + tags: ['console'], + }) + .input( + z.object({ + body: zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunBody, + params: zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunPath, + }), + ) + .output(zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponse) + +export const run6 = { + post: post18, +} + +export const byNodeId5 = { + preview, + run: run6, +} + +export const nodes5 = { + byNodeId: byNodeId5, +} + +export const datasource2 = { + nodes: nodes5, +} + +/** + * Get first step parameters of rag pipeline + */ +export const get22 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParameters', + path: '/rag/pipelines/{pipeline_id}/workflows/published/pre-processing/parameters', + summary: 'Get first step parameters of rag pipeline', + tags: ['console'], + }) + .input( + z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersPath }), + ) + .output(zGetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersResponse) + +export const parameters3 = { + get: get22, +} + +export const preProcessing2 = { + parameters: parameters3, +} + +/** + * Get second step parameters of rag pipeline + */ +export const get23 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflowsPublishedProcessingParameters', + path: '/rag/pipelines/{pipeline_id}/workflows/published/processing/parameters', + summary: 'Get second step parameters of rag pipeline', + tags: ['console'], + }) + .input( + z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersPath }), + ) + .output(zGetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponse) + +export const parameters4 = { + get: get23, +} + +export const processing2 = { + parameters: parameters4, +} + +/** + * Run published workflow + */ +export const post19 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowsPublishedRun', + path: '/rag/pipelines/{pipeline_id}/workflows/published/run', + summary: 'Run published workflow', + tags: ['console'], + }) + .input( + z.object({ + body: zPostRagPipelinesByPipelineIdWorkflowsPublishedRunBody, + params: zPostRagPipelinesByPipelineIdWorkflowsPublishedRunPath, + }), + ) + .output(zPostRagPipelinesByPipelineIdWorkflowsPublishedRunResponse) + +export const run7 = { + post: post19, +} + +export const published = { + datasource: datasource2, + preProcessing: preProcessing2, + processing: processing2, + run: run7, +} + +export const post20 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestore', + path: '/rag/pipelines/{pipeline_id}/workflows/{workflow_id}/restore', + tags: ['console'], + }) + .input(z.object({ params: zPostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestorePath })) + .output(zPostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestoreResponse) + +export const restore = { + post: post20, +} + +/** + * Delete a published workflow version that is not currently active on the pipeline + */ +export const delete5 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteRagPipelinesByPipelineIdWorkflowsByWorkflowId', + path: '/rag/pipelines/{pipeline_id}/workflows/{workflow_id}', + summary: 'Delete a published workflow version that is not currently active on the pipeline', + tags: ['console'], + }) + .input(z.object({ params: zDeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdPath })) + .output(zDeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponse) + +/** + * Update workflow attributes + */ +export const patch3 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchRagPipelinesByPipelineIdWorkflowsByWorkflowId', + path: '/rag/pipelines/{pipeline_id}/workflows/{workflow_id}', + summary: 'Update workflow attributes', + tags: ['console'], + }) + .input(z.object({ params: zPatchRagPipelinesByPipelineIdWorkflowsByWorkflowIdPath })) + .output(zPatchRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponse) + +export const byWorkflowId = { + delete: delete5, + patch: patch3, + restore, +} + +/** + * Get published workflows + */ +export const get24 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRagPipelinesByPipelineIdWorkflows', + path: '/rag/pipelines/{pipeline_id}/workflows', + summary: 'Get published workflows', + tags: ['console'], + }) + .input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsPath })) + .output(zGetRagPipelinesByPipelineIdWorkflowsResponse) + +export const workflows = { + get: get24, + defaultWorkflowBlockConfigs, + draft, + publish: publish2, + published, + byWorkflowId, +} + +export const byPipelineId2 = { + customized: customized2, + exports: exports_, + workflowRuns, + workflows, +} + +export const pipelines = { + datasourcePlugins, + imports, + recommendedPlugins, + transform, + byPipelineId: byPipelineId2, +} + +export const rag = { + pipeline, + pipelines, +} + +export const contract = { + rag, +} diff --git a/packages/contracts/generated/api/console/rag/types.gen.ts b/packages/contracts/generated/api/console/rag/types.gen.ts new file mode 100644 index 0000000000..e300ff443c --- /dev/null +++ b/packages/contracts/generated/api/console/rag/types.gen.ts @@ -0,0 +1,1054 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type RagPipelineDatasetImportPayload = { + yaml_content: string +} + +export type RagPipelineImportPayload = { + description?: string | null + icon?: string | null + icon_background?: string | null + icon_type?: string | null + mode: string + name?: string | null + pipeline_id?: string | null + yaml_content?: string | null + yaml_url?: string | null +} + +export type Payload = { + description?: string + icon_info?: { + [key: string]: unknown + } | null + name: string +} + +export type DatasourceNodeRunPayload = { + credential_id?: string | null + datasource_type: string + inputs: { + [key: string]: unknown + } +} + +export type DatasourceVariablesPayload = { + datasource_info: { + [key: string]: unknown + } + datasource_type: string + start_node_id: string + start_node_title: string +} + +export type NodeRunPayload = { + inputs?: { + [key: string]: unknown + } | null +} + +export type NodeRunRequiredPayload = { + inputs: { + [key: string]: unknown + } +} + +export type DraftWorkflowRunPayload = { + datasource_info_list: Array<{ + [key: string]: unknown + }> + datasource_type: string + inputs: { + [key: string]: unknown + } + start_node_id: string +} + +export type Parser = { + credential_id?: string | null + datasource_type: string + inputs: { + [key: string]: unknown + } +} + +export type PublishedWorkflowRunPayload = { + datasource_info_list: Array<{ + [key: string]: unknown + }> + datasource_type: string + inputs: { + [key: string]: unknown + } + is_preview?: boolean + original_document_id?: string | null + response_mode?: 'streaming' | 'blocking' + start_node_id: string +} + +export type DeleteRagPipelineCustomizedTemplatesByTemplateIdData = { + body?: never + path: { + template_id: string + } + query?: never + url: '/rag/pipeline/customized/templates/{template_id}' +} + +export type DeleteRagPipelineCustomizedTemplatesByTemplateIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteRagPipelineCustomizedTemplatesByTemplateIdResponse + = DeleteRagPipelineCustomizedTemplatesByTemplateIdResponses[keyof DeleteRagPipelineCustomizedTemplatesByTemplateIdResponses] + +export type PatchRagPipelineCustomizedTemplatesByTemplateIdData = { + body?: never + path: { + template_id: string + } + query?: never + url: '/rag/pipeline/customized/templates/{template_id}' +} + +export type PatchRagPipelineCustomizedTemplatesByTemplateIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchRagPipelineCustomizedTemplatesByTemplateIdResponse + = PatchRagPipelineCustomizedTemplatesByTemplateIdResponses[keyof PatchRagPipelineCustomizedTemplatesByTemplateIdResponses] + +export type PostRagPipelineCustomizedTemplatesByTemplateIdData = { + body?: never + path: { + template_id: string + } + query?: never + url: '/rag/pipeline/customized/templates/{template_id}' +} + +export type PostRagPipelineCustomizedTemplatesByTemplateIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelineCustomizedTemplatesByTemplateIdResponse + = PostRagPipelineCustomizedTemplatesByTemplateIdResponses[keyof PostRagPipelineCustomizedTemplatesByTemplateIdResponses] + +export type PostRagPipelineDatasetData = { + body: RagPipelineDatasetImportPayload + path?: never + query?: never + url: '/rag/pipeline/dataset' +} + +export type PostRagPipelineDatasetResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelineDatasetResponse + = PostRagPipelineDatasetResponses[keyof PostRagPipelineDatasetResponses] + +export type PostRagPipelineEmptyDatasetData = { + body?: never + path?: never + query?: never + url: '/rag/pipeline/empty-dataset' +} + +export type PostRagPipelineEmptyDatasetResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelineEmptyDatasetResponse + = PostRagPipelineEmptyDatasetResponses[keyof PostRagPipelineEmptyDatasetResponses] + +export type GetRagPipelineTemplatesData = { + body?: never + path?: never + query?: never + url: '/rag/pipeline/templates' +} + +export type GetRagPipelineTemplatesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelineTemplatesResponse + = GetRagPipelineTemplatesResponses[keyof GetRagPipelineTemplatesResponses] + +export type GetRagPipelineTemplatesByTemplateIdData = { + body?: never + path: { + template_id: string + } + query?: never + url: '/rag/pipeline/templates/{template_id}' +} + +export type GetRagPipelineTemplatesByTemplateIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelineTemplatesByTemplateIdResponse + = GetRagPipelineTemplatesByTemplateIdResponses[keyof GetRagPipelineTemplatesByTemplateIdResponses] + +export type GetRagPipelinesDatasourcePluginsData = { + body?: never + path?: never + query?: never + url: '/rag/pipelines/datasource-plugins' +} + +export type GetRagPipelinesDatasourcePluginsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesDatasourcePluginsResponse + = GetRagPipelinesDatasourcePluginsResponses[keyof GetRagPipelinesDatasourcePluginsResponses] + +export type PostRagPipelinesImportsData = { + body: RagPipelineImportPayload + path?: never + query?: never + url: '/rag/pipelines/imports' +} + +export type PostRagPipelinesImportsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesImportsResponse + = PostRagPipelinesImportsResponses[keyof PostRagPipelinesImportsResponses] + +export type PostRagPipelinesImportsByImportIdConfirmData = { + body?: never + path: { + import_id: string + } + query?: never + url: '/rag/pipelines/imports/{import_id}/confirm' +} + +export type PostRagPipelinesImportsByImportIdConfirmResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesImportsByImportIdConfirmResponse + = PostRagPipelinesImportsByImportIdConfirmResponses[keyof PostRagPipelinesImportsByImportIdConfirmResponses] + +export type GetRagPipelinesImportsByPipelineIdCheckDependenciesData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/imports/{pipeline_id}/check-dependencies' +} + +export type GetRagPipelinesImportsByPipelineIdCheckDependenciesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesImportsByPipelineIdCheckDependenciesResponse + = GetRagPipelinesImportsByPipelineIdCheckDependenciesResponses[keyof GetRagPipelinesImportsByPipelineIdCheckDependenciesResponses] + +export type GetRagPipelinesRecommendedPluginsData = { + body?: never + path?: never + query?: never + url: '/rag/pipelines/recommended-plugins' +} + +export type GetRagPipelinesRecommendedPluginsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesRecommendedPluginsResponse + = GetRagPipelinesRecommendedPluginsResponses[keyof GetRagPipelinesRecommendedPluginsResponses] + +export type PostRagPipelinesTransformDatasetsByDatasetIdData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/rag/pipelines/transform/datasets/{dataset_id}' +} + +export type PostRagPipelinesTransformDatasetsByDatasetIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesTransformDatasetsByDatasetIdResponse + = PostRagPipelinesTransformDatasetsByDatasetIdResponses[keyof PostRagPipelinesTransformDatasetsByDatasetIdResponses] + +export type PostRagPipelinesByPipelineIdCustomizedPublishData = { + body: Payload + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/customized/publish' +} + +export type PostRagPipelinesByPipelineIdCustomizedPublishResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdCustomizedPublishResponse + = PostRagPipelinesByPipelineIdCustomizedPublishResponses[keyof PostRagPipelinesByPipelineIdCustomizedPublishResponses] + +export type GetRagPipelinesByPipelineIdExportsData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/exports' +} + +export type GetRagPipelinesByPipelineIdExportsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdExportsResponse + = GetRagPipelinesByPipelineIdExportsResponses[keyof GetRagPipelinesByPipelineIdExportsResponses] + +export type GetRagPipelinesByPipelineIdWorkflowRunsData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflow-runs' +} + +export type GetRagPipelinesByPipelineIdWorkflowRunsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowRunsResponse + = GetRagPipelinesByPipelineIdWorkflowRunsResponses[keyof GetRagPipelinesByPipelineIdWorkflowRunsResponses] + +export type PostRagPipelinesByPipelineIdWorkflowRunsTasksByTaskIdStopData = { + body?: never + path: { + pipeline_id: string + task_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflow-runs/tasks/{task_id}/stop' +} + +export type PostRagPipelinesByPipelineIdWorkflowRunsTasksByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdWorkflowRunsTasksByTaskIdStopResponse + = PostRagPipelinesByPipelineIdWorkflowRunsTasksByTaskIdStopResponses[keyof PostRagPipelinesByPipelineIdWorkflowRunsTasksByTaskIdStopResponses] + +export type GetRagPipelinesByPipelineIdWorkflowRunsByRunIdData = { + body?: never + path: { + pipeline_id: string + run_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflow-runs/{run_id}' +} + +export type GetRagPipelinesByPipelineIdWorkflowRunsByRunIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowRunsByRunIdResponse + = GetRagPipelinesByPipelineIdWorkflowRunsByRunIdResponses[keyof GetRagPipelinesByPipelineIdWorkflowRunsByRunIdResponses] + +export type GetRagPipelinesByPipelineIdWorkflowRunsByRunIdNodeExecutionsData = { + body?: never + path: { + pipeline_id: string + run_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflow-runs/{run_id}/node-executions' +} + +export type GetRagPipelinesByPipelineIdWorkflowRunsByRunIdNodeExecutionsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowRunsByRunIdNodeExecutionsResponse + = GetRagPipelinesByPipelineIdWorkflowRunsByRunIdNodeExecutionsResponses[keyof GetRagPipelinesByPipelineIdWorkflowRunsByRunIdNodeExecutionsResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows' +} + +export type GetRagPipelinesByPipelineIdWorkflowsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsResponse + = GetRagPipelinesByPipelineIdWorkflowsResponses[keyof GetRagPipelinesByPipelineIdWorkflowsResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/default-workflow-block-configs' +} + +export type GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponse + = GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeData = { + body?: never + path: { + pipeline_id: string + block_type: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/default-workflow-block-configs/{block_type}' +} + +export type GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse + = GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsDraftData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft' +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftResponse + = GetRagPipelinesByPipelineIdWorkflowsDraftResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDraftResponses] + +export type PostRagPipelinesByPipelineIdWorkflowsDraftData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft' +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftResponse + = PostRagPipelinesByPipelineIdWorkflowsDraftResponses[keyof PostRagPipelinesByPipelineIdWorkflowsDraftResponses] + +export type PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunData = { + body: DatasourceNodeRunPayload + path: { + pipeline_id: string + node_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/datasource/nodes/{node_id}/run' +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponse + = PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponses] + +export type PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectData = { + body: DatasourceVariablesPayload + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/datasource/variables-inspect' +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectResponse + = PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectResponses[keyof PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/environment-variables' +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponse + = GetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponses] + +export type PostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunData = { + body: NodeRunPayload + path: { + pipeline_id: string + node_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/iteration/nodes/{node_id}/run' +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponse + = PostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponses] + +export type PostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunData = { + body: NodeRunPayload + path: { + pipeline_id: string + node_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/loop/nodes/{node_id}/run' +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponse + = PostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunData = { + body?: never + path: { + pipeline_id: string + node_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/nodes/{node_id}/last-run' +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunResponse + = GetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunResponses] + +export type PostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunData = { + body: NodeRunRequiredPayload + path: { + pipeline_id: string + node_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/nodes/{node_id}/run' +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunResponse + = PostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunResponses] + +export type DeleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesData = { + body?: never + path: { + pipeline_id: string + node_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/nodes/{node_id}/variables' +} + +export type DeleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponse + = DeleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponses[keyof DeleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesData = { + body?: never + path: { + pipeline_id: string + node_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/nodes/{node_id}/variables' +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponse + = GetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/pre-processing/parameters' +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersResponse + = GetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/processing/parameters' +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponse + = GetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponses] + +export type PostRagPipelinesByPipelineIdWorkflowsDraftRunData = { + body: DraftWorkflowRunPayload + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/run' +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdWorkflowsDraftRunResponse + = PostRagPipelinesByPipelineIdWorkflowsDraftRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsDraftRunResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/system-variables' +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesResponse + = GetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesResponses] + +export type DeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/variables' +} + +export type DeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesResponse + = DeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesResponses[keyof DeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsDraftVariablesData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/variables' +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftVariablesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftVariablesResponse + = GetRagPipelinesByPipelineIdWorkflowsDraftVariablesResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDraftVariablesResponses] + +export type DeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdData = { + body?: never + path: { + pipeline_id: string + variable_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/variables/{variable_id}' +} + +export type DeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse + = DeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponses[keyof DeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdData = { + body?: never + path: { + pipeline_id: string + variable_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/variables/{variable_id}' +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse + = GetRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponses] + +export type PatchRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdData = { + body?: never + path: { + pipeline_id: string + variable_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/variables/{variable_id}' +} + +export type PatchRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse + = PatchRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponses[keyof PatchRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponses] + +export type PutRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResetData = { + body?: never + path: { + pipeline_id: string + variable_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/draft/variables/{variable_id}/reset' +} + +export type PutRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResetResponses = { + 200: { + [key: string]: unknown + } +} + +export type PutRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResetResponse + = PutRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResetResponses[keyof PutRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResetResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsPublishData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/publish' +} + +export type GetRagPipelinesByPipelineIdWorkflowsPublishResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsPublishResponse + = GetRagPipelinesByPipelineIdWorkflowsPublishResponses[keyof GetRagPipelinesByPipelineIdWorkflowsPublishResponses] + +export type PostRagPipelinesByPipelineIdWorkflowsPublishData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/publish' +} + +export type PostRagPipelinesByPipelineIdWorkflowsPublishResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdWorkflowsPublishResponse + = PostRagPipelinesByPipelineIdWorkflowsPublishResponses[keyof PostRagPipelinesByPipelineIdWorkflowsPublishResponses] + +export type PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewData = { + body: Parser + path: { + pipeline_id: string + node_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/published/datasource/nodes/{node_id}/preview' +} + +export type PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponses + = { + 200: { + [key: string]: unknown + } + } + +export type PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponse + = PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponses[keyof PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponses] + +export type PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunData = { + body: DatasourceNodeRunPayload + path: { + pipeline_id: string + node_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/published/datasource/nodes/{node_id}/run' +} + +export type PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponse + = PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/published/pre-processing/parameters' +} + +export type GetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersResponse + = GetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersResponses[keyof GetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersResponses] + +export type GetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersData = { + body?: never + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/published/processing/parameters' +} + +export type GetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponse + = GetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponses[keyof GetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponses] + +export type PostRagPipelinesByPipelineIdWorkflowsPublishedRunData = { + body: PublishedWorkflowRunPayload + path: { + pipeline_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/published/run' +} + +export type PostRagPipelinesByPipelineIdWorkflowsPublishedRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdWorkflowsPublishedRunResponse + = PostRagPipelinesByPipelineIdWorkflowsPublishedRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsPublishedRunResponses] + +export type DeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdData = { + body?: never + path: { + pipeline_id: string + workflow_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/{workflow_id}' +} + +export type DeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponse + = DeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponses[keyof DeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponses] + +export type PatchRagPipelinesByPipelineIdWorkflowsByWorkflowIdData = { + body?: never + path: { + pipeline_id: string + workflow_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/{workflow_id}' +} + +export type PatchRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponse + = PatchRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponses[keyof PatchRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponses] + +export type PostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestoreData = { + body?: never + path: { + pipeline_id: string + workflow_id: string + } + query?: never + url: '/rag/pipelines/{pipeline_id}/workflows/{workflow_id}/restore' +} + +export type PostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestoreResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestoreResponse + = PostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestoreResponses[keyof PostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestoreResponses] diff --git a/packages/contracts/generated/api/console/rag/zod.gen.ts b/packages/contracts/generated/api/console/rag/zod.gen.ts new file mode 100644 index 0000000000..b28d7fafc7 --- /dev/null +++ b/packages/contracts/generated/api/console/rag/zod.gen.ts @@ -0,0 +1,709 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * RagPipelineDatasetImportPayload + */ +export const zRagPipelineDatasetImportPayload = z.object({ + yaml_content: z.string(), +}) + +/** + * RagPipelineImportPayload + */ +export const zRagPipelineImportPayload = z.object({ + description: z.string().nullish(), + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: z.string().nullish(), + mode: z.string(), + name: z.string().nullish(), + pipeline_id: z.string().nullish(), + yaml_content: z.string().nullish(), + yaml_url: z.string().nullish(), +}) + +/** + * Payload + */ +export const zPayload = z.object({ + description: z.string().max(400).optional().default(''), + icon_info: z.record(z.string(), z.unknown()).nullish(), + name: z.string().min(1).max(40), +}) + +/** + * DatasourceNodeRunPayload + */ +export const zDatasourceNodeRunPayload = z.object({ + credential_id: z.string().nullish(), + datasource_type: z.string(), + inputs: z.record(z.string(), z.unknown()), +}) + +/** + * DatasourceVariablesPayload + */ +export const zDatasourceVariablesPayload = z.object({ + datasource_info: z.record(z.string(), z.unknown()), + datasource_type: z.string(), + start_node_id: z.string(), + start_node_title: z.string(), +}) + +/** + * NodeRunPayload + */ +export const zNodeRunPayload = z.object({ + inputs: z.record(z.string(), z.unknown()).nullish(), +}) + +/** + * NodeRunRequiredPayload + */ +export const zNodeRunRequiredPayload = z.object({ + inputs: z.record(z.string(), z.unknown()), +}) + +/** + * DraftWorkflowRunPayload + */ +export const zDraftWorkflowRunPayload = z.object({ + datasource_info_list: z.array(z.record(z.string(), z.unknown())), + datasource_type: z.string(), + inputs: z.record(z.string(), z.unknown()), + start_node_id: z.string(), +}) + +/** + * Parser + */ +export const zParser = z.object({ + credential_id: z.string().nullish(), + datasource_type: z.string(), + inputs: z.record(z.string(), z.unknown()), +}) + +/** + * PublishedWorkflowRunPayload + */ +export const zPublishedWorkflowRunPayload = z.object({ + datasource_info_list: z.array(z.record(z.string(), z.unknown())), + datasource_type: z.string(), + inputs: z.record(z.string(), z.unknown()), + is_preview: z.boolean().optional().default(false), + original_document_id: z.string().nullish(), + response_mode: z.enum(['streaming', 'blocking']).optional().default('streaming'), + start_node_id: z.string(), +}) + +export const zDeleteRagPipelineCustomizedTemplatesByTemplateIdPath = z.object({ + template_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteRagPipelineCustomizedTemplatesByTemplateIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchRagPipelineCustomizedTemplatesByTemplateIdPath = z.object({ + template_id: z.string(), +}) + +/** + * Success + */ +export const zPatchRagPipelineCustomizedTemplatesByTemplateIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostRagPipelineCustomizedTemplatesByTemplateIdPath = z.object({ + template_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelineCustomizedTemplatesByTemplateIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostRagPipelineDatasetBody = zRagPipelineDatasetImportPayload + +/** + * Success + */ +export const zPostRagPipelineDatasetResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPostRagPipelineEmptyDatasetResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetRagPipelineTemplatesResponse = z.record(z.string(), z.unknown()) + +export const zGetRagPipelineTemplatesByTemplateIdPath = z.object({ + template_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelineTemplatesByTemplateIdResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetRagPipelinesDatasourcePluginsResponse = z.record(z.string(), z.unknown()) + +export const zPostRagPipelinesImportsBody = zRagPipelineImportPayload + +/** + * Success + */ +export const zPostRagPipelinesImportsResponse = z.record(z.string(), z.unknown()) + +export const zPostRagPipelinesImportsByImportIdConfirmPath = z.object({ + import_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesImportsByImportIdConfirmResponse = z.record(z.string(), z.unknown()) + +export const zGetRagPipelinesImportsByPipelineIdCheckDependenciesPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesImportsByPipelineIdCheckDependenciesResponse = z.record( + z.string(), + z.unknown(), +) + +/** + * Success + */ +export const zGetRagPipelinesRecommendedPluginsResponse = z.record(z.string(), z.unknown()) + +export const zPostRagPipelinesTransformDatasetsByDatasetIdPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesTransformDatasetsByDatasetIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostRagPipelinesByPipelineIdCustomizedPublishBody = zPayload + +export const zPostRagPipelinesByPipelineIdCustomizedPublishPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdCustomizedPublishResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetRagPipelinesByPipelineIdExportsPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdExportsResponse = z.record(z.string(), z.unknown()) + +export const zGetRagPipelinesByPipelineIdWorkflowRunsPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowRunsResponse = z.record(z.string(), z.unknown()) + +export const zPostRagPipelinesByPipelineIdWorkflowRunsTasksByTaskIdStopPath = z.object({ + pipeline_id: z.string(), + task_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowRunsTasksByTaskIdStopResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetRagPipelinesByPipelineIdWorkflowRunsByRunIdPath = z.object({ + pipeline_id: z.string(), + run_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowRunsByRunIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetRagPipelinesByPipelineIdWorkflowRunsByRunIdNodeExecutionsPath = z.object({ + pipeline_id: z.string(), + run_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowRunsByRunIdNodeExecutionsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetRagPipelinesByPipelineIdWorkflowsPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsResponse = z.record(z.string(), z.unknown()) + +export const zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypePath + = z.object({ + pipeline_id: z.string(), + block_type: z.string(), + }) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse + = z.record(z.string(), z.unknown()) + +export const zGetRagPipelinesByPipelineIdWorkflowsDraftPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsDraftResponse = z.record(z.string(), z.unknown()) + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowsDraftResponse = z.record(z.string(), z.unknown()) + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunBody + = zDatasourceNodeRunPayload + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunPath = z.object({ + pipeline_id: z.string(), + node_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponse + = z.record(z.string(), z.unknown()) + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectBody + = zDatasourceVariablesPayload + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectResponse + = z.record(z.string(), z.unknown()) + +export const zGetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunBody + = zNodeRunPayload + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunPath = z.object({ + pipeline_id: z.string(), + node_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponse + = z.record(z.string(), z.unknown()) + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunBody = zNodeRunPayload + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunPath = z.object({ + pipeline_id: z.string(), + node_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunPath = z.object({ + pipeline_id: z.string(), + node_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunBody + = zNodeRunRequiredPayload + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunPath = z.object({ + pipeline_id: z.string(), + node_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesPath = z.object({ + pipeline_id: z.string(), + node_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesPath = z.object({ + pipeline_id: z.string(), + node_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftRunBody = zDraftWorkflowRunPayload + +export const zPostRagPipelinesByPipelineIdWorkflowsDraftRunPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowsDraftRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetRagPipelinesByPipelineIdWorkflowsDraftVariablesPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsDraftVariablesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdPath = z.object({ + pipeline_id: z.string(), + variable_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdPath = z.object({ + pipeline_id: z.string(), + variable_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdPath = z.object({ + pipeline_id: z.string(), + variable_id: z.string(), +}) + +/** + * Success + */ +export const zPatchRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPutRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResetPath = z.object({ + pipeline_id: z.string(), + variable_id: z.string(), +}) + +/** + * Success + */ +export const zPutRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResetResponse + = z.record(z.string(), z.unknown()) + +export const zGetRagPipelinesByPipelineIdWorkflowsPublishPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsPublishResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostRagPipelinesByPipelineIdWorkflowsPublishPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowsPublishResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewBody + = zParser + +export const zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewPath + = z.object({ + pipeline_id: z.string(), + node_id: z.string(), + }) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponse + = z.record(z.string(), z.unknown()) + +export const zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunBody + = zDatasourceNodeRunPayload + +export const zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunPath + = z.object({ + pipeline_id: z.string(), + node_id: z.string(), + }) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponse + = z.record(z.string(), z.unknown()) + +export const zGetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersResponse + = z.record(z.string(), z.unknown()) + +export const zGetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zGetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostRagPipelinesByPipelineIdWorkflowsPublishedRunBody = zPublishedWorkflowRunPayload + +export const zPostRagPipelinesByPipelineIdWorkflowsPublishedRunPath = z.object({ + pipeline_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowsPublishedRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdPath = z.object({ + pipeline_id: z.string(), + workflow_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchRagPipelinesByPipelineIdWorkflowsByWorkflowIdPath = z.object({ + pipeline_id: z.string(), + workflow_id: z.string(), +}) + +/** + * Success + */ +export const zPatchRagPipelinesByPipelineIdWorkflowsByWorkflowIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestorePath = z.object({ + pipeline_id: z.string(), + workflow_id: z.string(), +}) + +/** + * Success + */ +export const zPostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestoreResponse = z.record( + z.string(), + z.unknown(), +) diff --git a/packages/contracts/generated/api/console/refresh-token/orpc.gen.ts b/packages/contracts/generated/api/console/refresh-token/orpc.gen.ts new file mode 100644 index 0000000000..4faa4d7d23 --- /dev/null +++ b/packages/contracts/generated/api/console/refresh-token/orpc.gen.ts @@ -0,0 +1,23 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' + +import { zPostRefreshTokenResponse } from './zod.gen' + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRefreshToken', + path: '/refresh-token', + tags: ['console'], + }) + .output(zPostRefreshTokenResponse) + +export const refreshToken = { + post, +} + +export const contract = { + refreshToken, +} diff --git a/packages/contracts/generated/api/console/refresh-token/types.gen.ts b/packages/contracts/generated/api/console/refresh-token/types.gen.ts new file mode 100644 index 0000000000..15c939b947 --- /dev/null +++ b/packages/contracts/generated/api/console/refresh-token/types.gen.ts @@ -0,0 +1,20 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type PostRefreshTokenData = { + body?: never + path?: never + query?: never + url: '/refresh-token' +} + +export type PostRefreshTokenResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRefreshTokenResponse = PostRefreshTokenResponses[keyof PostRefreshTokenResponses] diff --git a/packages/contracts/generated/api/console/refresh-token/zod.gen.ts b/packages/contracts/generated/api/console/refresh-token/zod.gen.ts new file mode 100644 index 0000000000..d76067552c --- /dev/null +++ b/packages/contracts/generated/api/console/refresh-token/zod.gen.ts @@ -0,0 +1,8 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * Success + */ +export const zPostRefreshTokenResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/remote-files/orpc.gen.ts b/packages/contracts/generated/api/console/remote-files/orpc.gen.ts new file mode 100644 index 0000000000..977af4a09c --- /dev/null +++ b/packages/contracts/generated/api/console/remote-files/orpc.gen.ts @@ -0,0 +1,48 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetRemoteFilesByUrlPath, + zGetRemoteFilesByUrlResponse, + zPostRemoteFilesUploadResponse, +} from './zod.gen' + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRemoteFilesUpload', + path: '/remote-files/upload', + tags: ['console'], + }) + .output(zPostRemoteFilesUploadResponse) + +export const upload = { + post, +} + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRemoteFilesByUrl', + path: '/remote-files/{url}', + tags: ['console'], + }) + .input(z.object({ params: zGetRemoteFilesByUrlPath })) + .output(zGetRemoteFilesByUrlResponse) + +export const byUrl = { + get, +} + +export const remoteFiles = { + upload, + byUrl, +} + +export const contract = { + remoteFiles, +} diff --git a/packages/contracts/generated/api/console/remote-files/types.gen.ts b/packages/contracts/generated/api/console/remote-files/types.gen.ts new file mode 100644 index 0000000000..ea61592a76 --- /dev/null +++ b/packages/contracts/generated/api/console/remote-files/types.gen.ts @@ -0,0 +1,39 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type PostRemoteFilesUploadData = { + body?: never + path?: never + query?: never + url: '/remote-files/upload' +} + +export type PostRemoteFilesUploadResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRemoteFilesUploadResponse + = PostRemoteFilesUploadResponses[keyof PostRemoteFilesUploadResponses] + +export type GetRemoteFilesByUrlData = { + body?: never + path: { + url: string + } + query?: never + url: '/remote-files/{url}' +} + +export type GetRemoteFilesByUrlResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRemoteFilesByUrlResponse + = GetRemoteFilesByUrlResponses[keyof GetRemoteFilesByUrlResponses] diff --git a/packages/contracts/generated/api/console/remote-files/zod.gen.ts b/packages/contracts/generated/api/console/remote-files/zod.gen.ts new file mode 100644 index 0000000000..cee96cf65f --- /dev/null +++ b/packages/contracts/generated/api/console/remote-files/zod.gen.ts @@ -0,0 +1,17 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * Success + */ +export const zPostRemoteFilesUploadResponse = z.record(z.string(), z.unknown()) + +export const zGetRemoteFilesByUrlPath = z.object({ + url: z.string(), +}) + +/** + * Success + */ +export const zGetRemoteFilesByUrlResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/reset-password/orpc.gen.ts b/packages/contracts/generated/api/console/reset-password/orpc.gen.ts new file mode 100644 index 0000000000..93701280db --- /dev/null +++ b/packages/contracts/generated/api/console/reset-password/orpc.gen.ts @@ -0,0 +1,25 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { zPostResetPasswordBody, zPostResetPasswordResponse } from './zod.gen' + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postResetPassword', + path: '/reset-password', + tags: ['console'], + }) + .input(z.object({ body: zPostResetPasswordBody })) + .output(zPostResetPasswordResponse) + +export const resetPassword = { + post, +} + +export const contract = { + resetPassword, +} diff --git a/packages/contracts/generated/api/console/reset-password/types.gen.ts b/packages/contracts/generated/api/console/reset-password/types.gen.ts new file mode 100644 index 0000000000..6c2467aab4 --- /dev/null +++ b/packages/contracts/generated/api/console/reset-password/types.gen.ts @@ -0,0 +1,25 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type EmailPayload = { + email: string + language?: string | null +} + +export type PostResetPasswordData = { + body: EmailPayload + path?: never + query?: never + url: '/reset-password' +} + +export type PostResetPasswordResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostResetPasswordResponse = PostResetPasswordResponses[keyof PostResetPasswordResponses] diff --git a/packages/contracts/generated/api/console/reset-password/zod.gen.ts b/packages/contracts/generated/api/console/reset-password/zod.gen.ts new file mode 100644 index 0000000000..055ed9e127 --- /dev/null +++ b/packages/contracts/generated/api/console/reset-password/zod.gen.ts @@ -0,0 +1,18 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * EmailPayload + */ +export const zEmailPayload = z.object({ + email: z.string(), + language: z.string().nullish(), +}) + +export const zPostResetPasswordBody = zEmailPayload + +/** + * Success + */ +export const zPostResetPasswordResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/rule-code-generate/orpc.gen.ts b/packages/contracts/generated/api/console/rule-code-generate/orpc.gen.ts new file mode 100644 index 0000000000..1c5252525c --- /dev/null +++ b/packages/contracts/generated/api/console/rule-code-generate/orpc.gen.ts @@ -0,0 +1,29 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { zPostRuleCodeGenerateBody, zPostRuleCodeGenerateResponse } from './zod.gen' + +/** + * Generate code rules using LLM + */ +export const post = oc + .route({ + description: 'Generate code rules using LLM', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRuleCodeGenerate', + path: '/rule-code-generate', + tags: ['console'], + }) + .input(z.object({ body: zPostRuleCodeGenerateBody })) + .output(zPostRuleCodeGenerateResponse) + +export const ruleCodeGenerate = { + post, +} + +export const contract = { + ruleCodeGenerate, +} diff --git a/packages/contracts/generated/api/console/rule-code-generate/types.gen.ts b/packages/contracts/generated/api/console/rule-code-generate/types.gen.ts new file mode 100644 index 0000000000..dc1b045285 --- /dev/null +++ b/packages/contracts/generated/api/console/rule-code-generate/types.gen.ts @@ -0,0 +1,68 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type RuleCodeGeneratePayload = { + code_language?: string + instruction: string + model_config: ModelConfig + no_variable?: boolean +} + +export type ModelConfig = { + agent_mode_dict?: JsonValue + annotation_reply_dict?: JsonValue + chat_prompt_config_dict?: JsonValue + completion_prompt_config_dict?: JsonValue + created_at?: number | null + created_by?: string | null + dataset_configs_dict?: JsonValue + dataset_query_variable?: string | null + external_data_tools_list?: JsonValue + file_upload_dict?: JsonValue + model_dict?: JsonValue + more_like_this_dict?: JsonValue + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource_dict?: JsonValue + sensitive_word_avoidance_dict?: JsonValue + speech_to_text_dict?: JsonValue + suggested_questions_after_answer_dict?: JsonValue + suggested_questions_list?: JsonValue + text_to_speech_dict?: JsonValue + updated_at?: number | null + updated_by?: string | null + user_input_form_list?: JsonValue +} + +export type JsonValue = unknown + +export type PostRuleCodeGenerateData = { + body: RuleCodeGeneratePayload + path?: never + query?: never + url: '/rule-code-generate' +} + +export type PostRuleCodeGenerateErrors = { + 400: { + [key: string]: unknown + } + 402: { + [key: string]: unknown + } +} + +export type PostRuleCodeGenerateError = PostRuleCodeGenerateErrors[keyof PostRuleCodeGenerateErrors] + +export type PostRuleCodeGenerateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRuleCodeGenerateResponse + = PostRuleCodeGenerateResponses[keyof PostRuleCodeGenerateResponses] diff --git a/packages/contracts/generated/api/console/rule-code-generate/zod.gen.ts b/packages/contracts/generated/api/console/rule-code-generate/zod.gen.ts new file mode 100644 index 0000000000..40b840dc8a --- /dev/null +++ b/packages/contracts/generated/api/console/rule-code-generate/zod.gen.ts @@ -0,0 +1,52 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +export const zJsonValue = z.unknown() + +/** + * ModelConfig + */ +export const zModelConfig = z.object({ + agent_mode_dict: zJsonValue.optional(), + annotation_reply_dict: zJsonValue.optional(), + chat_prompt_config_dict: zJsonValue.optional(), + completion_prompt_config_dict: zJsonValue.optional(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs_dict: zJsonValue.optional(), + dataset_query_variable: z.string().nullish(), + external_data_tools_list: zJsonValue.optional(), + file_upload_dict: zJsonValue.optional(), + model_dict: zJsonValue.optional(), + more_like_this_dict: zJsonValue.optional(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource_dict: zJsonValue.optional(), + sensitive_word_avoidance_dict: zJsonValue.optional(), + speech_to_text_dict: zJsonValue.optional(), + suggested_questions_after_answer_dict: zJsonValue.optional(), + suggested_questions_list: zJsonValue.optional(), + text_to_speech_dict: zJsonValue.optional(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form_list: zJsonValue.optional(), +}) + +/** + * RuleCodeGeneratePayload + */ +export const zRuleCodeGeneratePayload = z.object({ + code_language: z.string().optional().default('javascript'), + instruction: z.string(), + model_config: zModelConfig, + no_variable: z.boolean().optional().default(false), +}) + +export const zPostRuleCodeGenerateBody = zRuleCodeGeneratePayload + +/** + * Code rules generated successfully + */ +export const zPostRuleCodeGenerateResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/rule-generate/orpc.gen.ts b/packages/contracts/generated/api/console/rule-generate/orpc.gen.ts new file mode 100644 index 0000000000..7bd233de2b --- /dev/null +++ b/packages/contracts/generated/api/console/rule-generate/orpc.gen.ts @@ -0,0 +1,29 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { zPostRuleGenerateBody, zPostRuleGenerateResponse } from './zod.gen' + +/** + * Generate rule configuration using LLM + */ +export const post = oc + .route({ + description: 'Generate rule configuration using LLM', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRuleGenerate', + path: '/rule-generate', + tags: ['console'], + }) + .input(z.object({ body: zPostRuleGenerateBody })) + .output(zPostRuleGenerateResponse) + +export const ruleGenerate = { + post, +} + +export const contract = { + ruleGenerate, +} diff --git a/packages/contracts/generated/api/console/rule-generate/types.gen.ts b/packages/contracts/generated/api/console/rule-generate/types.gen.ts new file mode 100644 index 0000000000..265ca5013d --- /dev/null +++ b/packages/contracts/generated/api/console/rule-generate/types.gen.ts @@ -0,0 +1,66 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type RuleGeneratePayload = { + instruction: string + model_config: ModelConfig + no_variable?: boolean +} + +export type ModelConfig = { + agent_mode_dict?: JsonValue + annotation_reply_dict?: JsonValue + chat_prompt_config_dict?: JsonValue + completion_prompt_config_dict?: JsonValue + created_at?: number | null + created_by?: string | null + dataset_configs_dict?: JsonValue + dataset_query_variable?: string | null + external_data_tools_list?: JsonValue + file_upload_dict?: JsonValue + model_dict?: JsonValue + more_like_this_dict?: JsonValue + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource_dict?: JsonValue + sensitive_word_avoidance_dict?: JsonValue + speech_to_text_dict?: JsonValue + suggested_questions_after_answer_dict?: JsonValue + suggested_questions_list?: JsonValue + text_to_speech_dict?: JsonValue + updated_at?: number | null + updated_by?: string | null + user_input_form_list?: JsonValue +} + +export type JsonValue = unknown + +export type PostRuleGenerateData = { + body: RuleGeneratePayload + path?: never + query?: never + url: '/rule-generate' +} + +export type PostRuleGenerateErrors = { + 400: { + [key: string]: unknown + } + 402: { + [key: string]: unknown + } +} + +export type PostRuleGenerateError = PostRuleGenerateErrors[keyof PostRuleGenerateErrors] + +export type PostRuleGenerateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRuleGenerateResponse = PostRuleGenerateResponses[keyof PostRuleGenerateResponses] diff --git a/packages/contracts/generated/api/console/rule-generate/zod.gen.ts b/packages/contracts/generated/api/console/rule-generate/zod.gen.ts new file mode 100644 index 0000000000..7a346a58fc --- /dev/null +++ b/packages/contracts/generated/api/console/rule-generate/zod.gen.ts @@ -0,0 +1,51 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +export const zJsonValue = z.unknown() + +/** + * ModelConfig + */ +export const zModelConfig = z.object({ + agent_mode_dict: zJsonValue.optional(), + annotation_reply_dict: zJsonValue.optional(), + chat_prompt_config_dict: zJsonValue.optional(), + completion_prompt_config_dict: zJsonValue.optional(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs_dict: zJsonValue.optional(), + dataset_query_variable: z.string().nullish(), + external_data_tools_list: zJsonValue.optional(), + file_upload_dict: zJsonValue.optional(), + model_dict: zJsonValue.optional(), + more_like_this_dict: zJsonValue.optional(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource_dict: zJsonValue.optional(), + sensitive_word_avoidance_dict: zJsonValue.optional(), + speech_to_text_dict: zJsonValue.optional(), + suggested_questions_after_answer_dict: zJsonValue.optional(), + suggested_questions_list: zJsonValue.optional(), + text_to_speech_dict: zJsonValue.optional(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form_list: zJsonValue.optional(), +}) + +/** + * RuleGeneratePayload + */ +export const zRuleGeneratePayload = z.object({ + instruction: z.string(), + model_config: zModelConfig, + no_variable: z.boolean().optional().default(false), +}) + +export const zPostRuleGenerateBody = zRuleGeneratePayload + +/** + * Rule configuration generated successfully + */ +export const zPostRuleGenerateResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/rule-structured-output-generate/orpc.gen.ts b/packages/contracts/generated/api/console/rule-structured-output-generate/orpc.gen.ts new file mode 100644 index 0000000000..276442f1c9 --- /dev/null +++ b/packages/contracts/generated/api/console/rule-structured-output-generate/orpc.gen.ts @@ -0,0 +1,32 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zPostRuleStructuredOutputGenerateBody, + zPostRuleStructuredOutputGenerateResponse, +} from './zod.gen' + +/** + * Generate structured output rules using LLM + */ +export const post = oc + .route({ + description: 'Generate structured output rules using LLM', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRuleStructuredOutputGenerate', + path: '/rule-structured-output-generate', + tags: ['console'], + }) + .input(z.object({ body: zPostRuleStructuredOutputGenerateBody })) + .output(zPostRuleStructuredOutputGenerateResponse) + +export const ruleStructuredOutputGenerate = { + post, +} + +export const contract = { + ruleStructuredOutputGenerate, +} diff --git a/packages/contracts/generated/api/console/rule-structured-output-generate/types.gen.ts b/packages/contracts/generated/api/console/rule-structured-output-generate/types.gen.ts new file mode 100644 index 0000000000..f6124c6956 --- /dev/null +++ b/packages/contracts/generated/api/console/rule-structured-output-generate/types.gen.ts @@ -0,0 +1,67 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type RuleStructuredOutputPayload = { + instruction: string + model_config: ModelConfig +} + +export type ModelConfig = { + agent_mode_dict?: JsonValue + annotation_reply_dict?: JsonValue + chat_prompt_config_dict?: JsonValue + completion_prompt_config_dict?: JsonValue + created_at?: number | null + created_by?: string | null + dataset_configs_dict?: JsonValue + dataset_query_variable?: string | null + external_data_tools_list?: JsonValue + file_upload_dict?: JsonValue + model_dict?: JsonValue + more_like_this_dict?: JsonValue + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource_dict?: JsonValue + sensitive_word_avoidance_dict?: JsonValue + speech_to_text_dict?: JsonValue + suggested_questions_after_answer_dict?: JsonValue + suggested_questions_list?: JsonValue + text_to_speech_dict?: JsonValue + updated_at?: number | null + updated_by?: string | null + user_input_form_list?: JsonValue +} + +export type JsonValue = unknown + +export type PostRuleStructuredOutputGenerateData = { + body: RuleStructuredOutputPayload + path?: never + query?: never + url: '/rule-structured-output-generate' +} + +export type PostRuleStructuredOutputGenerateErrors = { + 400: { + [key: string]: unknown + } + 402: { + [key: string]: unknown + } +} + +export type PostRuleStructuredOutputGenerateError + = PostRuleStructuredOutputGenerateErrors[keyof PostRuleStructuredOutputGenerateErrors] + +export type PostRuleStructuredOutputGenerateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostRuleStructuredOutputGenerateResponse + = PostRuleStructuredOutputGenerateResponses[keyof PostRuleStructuredOutputGenerateResponses] diff --git a/packages/contracts/generated/api/console/rule-structured-output-generate/zod.gen.ts b/packages/contracts/generated/api/console/rule-structured-output-generate/zod.gen.ts new file mode 100644 index 0000000000..231b5a072c --- /dev/null +++ b/packages/contracts/generated/api/console/rule-structured-output-generate/zod.gen.ts @@ -0,0 +1,50 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +export const zJsonValue = z.unknown() + +/** + * ModelConfig + */ +export const zModelConfig = z.object({ + agent_mode_dict: zJsonValue.optional(), + annotation_reply_dict: zJsonValue.optional(), + chat_prompt_config_dict: zJsonValue.optional(), + completion_prompt_config_dict: zJsonValue.optional(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs_dict: zJsonValue.optional(), + dataset_query_variable: z.string().nullish(), + external_data_tools_list: zJsonValue.optional(), + file_upload_dict: zJsonValue.optional(), + model_dict: zJsonValue.optional(), + more_like_this_dict: zJsonValue.optional(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource_dict: zJsonValue.optional(), + sensitive_word_avoidance_dict: zJsonValue.optional(), + speech_to_text_dict: zJsonValue.optional(), + suggested_questions_after_answer_dict: zJsonValue.optional(), + suggested_questions_list: zJsonValue.optional(), + text_to_speech_dict: zJsonValue.optional(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form_list: zJsonValue.optional(), +}) + +/** + * RuleStructuredOutputPayload + */ +export const zRuleStructuredOutputPayload = z.object({ + instruction: z.string(), + model_config: zModelConfig, +}) + +export const zPostRuleStructuredOutputGenerateBody = zRuleStructuredOutputPayload + +/** + * Structured output generated successfully + */ +export const zPostRuleStructuredOutputGenerateResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/spec/orpc.gen.ts b/packages/contracts/generated/api/console/spec/orpc.gen.ts new file mode 100644 index 0000000000..bd2e750e6d --- /dev/null +++ b/packages/contracts/generated/api/console/spec/orpc.gen.ts @@ -0,0 +1,34 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' + +import { zGetSpecSchemaDefinitionsResponse } from './zod.gen' + +/** + * Get system JSON Schema definitions specification + * + * Used for frontend component type mapping + */ +export const get = oc + .route({ + description: 'Used for frontend component type mapping', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getSpecSchemaDefinitions', + path: '/spec/schema-definitions', + summary: 'Get system JSON Schema definitions specification', + tags: ['console'], + }) + .output(zGetSpecSchemaDefinitionsResponse) + +export const schemaDefinitions = { + get, +} + +export const spec = { + schemaDefinitions, +} + +export const contract = { + spec, +} diff --git a/packages/contracts/generated/api/console/spec/types.gen.ts b/packages/contracts/generated/api/console/spec/types.gen.ts new file mode 100644 index 0000000000..eaad80aa9a --- /dev/null +++ b/packages/contracts/generated/api/console/spec/types.gen.ts @@ -0,0 +1,21 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type GetSpecSchemaDefinitionsData = { + body?: never + path?: never + query?: never + url: '/spec/schema-definitions' +} + +export type GetSpecSchemaDefinitionsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetSpecSchemaDefinitionsResponse + = GetSpecSchemaDefinitionsResponses[keyof GetSpecSchemaDefinitionsResponses] diff --git a/packages/contracts/generated/api/console/spec/zod.gen.ts b/packages/contracts/generated/api/console/spec/zod.gen.ts new file mode 100644 index 0000000000..fa057bc269 --- /dev/null +++ b/packages/contracts/generated/api/console/spec/zod.gen.ts @@ -0,0 +1,8 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * Success + */ +export const zGetSpecSchemaDefinitionsResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/system-features/orpc.gen.ts b/packages/contracts/generated/api/console/system-features/orpc.gen.ts new file mode 100644 index 0000000000..5c0a475585 --- /dev/null +++ b/packages/contracts/generated/api/console/system-features/orpc.gen.ts @@ -0,0 +1,37 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' + +import { zGetSystemFeaturesResponse } from './zod.gen' + +/** + * Get system-wide feature configuration + * + * Get system-wide feature configuration + * NOTE: This endpoint is unauthenticated by design, as it provides system features + * data required for dashboard initialization. + * + * Authentication would create circular dependency (can't login without dashboard loading). + * + * Only non-sensitive configuration data should be returned by this endpoint. + */ +export const get = oc + .route({ + description: + 'Get system-wide feature configuration\nNOTE: This endpoint is unauthenticated by design, as it provides system features\ndata required for dashboard initialization.\n\nAuthentication would create circular dependency (can\'t login without dashboard loading).\n\nOnly non-sensitive configuration data should be returned by this endpoint.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getSystemFeatures', + path: '/system-features', + summary: 'Get system-wide feature configuration', + tags: ['console'], + }) + .output(zGetSystemFeaturesResponse) + +export const systemFeatures = { + get, +} + +export const contract = { + systemFeatures, +} diff --git a/packages/contracts/generated/api/console/system-features/types.gen.ts b/packages/contracts/generated/api/console/system-features/types.gen.ts new file mode 100644 index 0000000000..0fbea39beb --- /dev/null +++ b/packages/contracts/generated/api/console/system-features/types.gen.ts @@ -0,0 +1,22 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type SystemFeatureResponse = { + [key: string]: unknown +} + +export type GetSystemFeaturesData = { + body?: never + path?: never + query?: never + url: '/system-features' +} + +export type GetSystemFeaturesResponses = { + 200: SystemFeatureResponse +} + +export type GetSystemFeaturesResponse = GetSystemFeaturesResponses[keyof GetSystemFeaturesResponses] diff --git a/packages/contracts/generated/api/console/system-features/zod.gen.ts b/packages/contracts/generated/api/console/system-features/zod.gen.ts new file mode 100644 index 0000000000..affb2a10a3 --- /dev/null +++ b/packages/contracts/generated/api/console/system-features/zod.gen.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +export const zSystemFeatureResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetSystemFeaturesResponse = zSystemFeatureResponse diff --git a/packages/contracts/generated/api/console/tag-bindings/orpc.gen.ts b/packages/contracts/generated/api/console/tag-bindings/orpc.gen.ts new file mode 100644 index 0000000000..8b58d2c47d --- /dev/null +++ b/packages/contracts/generated/api/console/tag-bindings/orpc.gen.ts @@ -0,0 +1,97 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteTagBindingsByIdBody, + zDeleteTagBindingsByIdPath, + zDeleteTagBindingsByIdResponse, + zPostTagBindingsBody, + zPostTagBindingsCreateBody, + zPostTagBindingsCreateResponse, + zPostTagBindingsRemoveBody, + zPostTagBindingsRemoveResponse, + zPostTagBindingsResponse, +} from './zod.gen' + +/** + * Deprecated legacy alias. Use POST /tag-bindings instead. + * + * @deprecated + */ +export const post = oc + .route({ + deprecated: true, + description: 'Deprecated legacy alias. Use POST /tag-bindings instead.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTagBindingsCreate', + path: '/tag-bindings/create', + tags: ['console'], + }) + .input(z.object({ body: zPostTagBindingsCreateBody })) + .output(zPostTagBindingsCreateResponse) + +export const create = { + post, +} + +/** + * Deprecated legacy alias. Use DELETE /tag-bindings/{id} instead. + * + * @deprecated + */ +export const post2 = oc + .route({ + deprecated: true, + description: 'Deprecated legacy alias. Use DELETE /tag-bindings/{id} instead.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTagBindingsRemove', + path: '/tag-bindings/remove', + tags: ['console'], + }) + .input(z.object({ body: zPostTagBindingsRemoveBody })) + .output(zPostTagBindingsRemoveResponse) + +export const remove = { + post: post2, +} + +export const delete_ = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteTagBindingsById', + path: '/tag-bindings/{id}', + tags: ['console'], + }) + .input(z.object({ body: zDeleteTagBindingsByIdBody, params: zDeleteTagBindingsByIdPath })) + .output(zDeleteTagBindingsByIdResponse) + +export const byId = { + delete: delete_, +} + +export const post3 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTagBindings', + path: '/tag-bindings', + tags: ['console'], + }) + .input(z.object({ body: zPostTagBindingsBody })) + .output(zPostTagBindingsResponse) + +export const tagBindings = { + post: post3, + create, + remove, + byId, +} + +export const contract = { + tagBindings, +} diff --git a/packages/contracts/generated/api/console/tag-bindings/types.gen.ts b/packages/contracts/generated/api/console/tag-bindings/types.gen.ts new file mode 100644 index 0000000000..e9426766ed --- /dev/null +++ b/packages/contracts/generated/api/console/tag-bindings/types.gen.ts @@ -0,0 +1,89 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type TagBindingPayload = { + tag_ids: Array + target_id: string + type: TagType +} + +export type TagBindingRemovePayload = { + tag_id: string + target_id: string + type: TagType +} + +export type TagBindingItemDeletePayload = { + target_id: string + type: TagType +} + +export type TagType = 'knowledge' | 'app' + +export type PostTagBindingsData = { + body: TagBindingPayload + path?: never + query?: never + url: '/tag-bindings' +} + +export type PostTagBindingsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTagBindingsResponse = PostTagBindingsResponses[keyof PostTagBindingsResponses] + +export type PostTagBindingsCreateData = { + body: TagBindingPayload + path?: never + query?: never + url: '/tag-bindings/create' +} + +export type PostTagBindingsCreateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTagBindingsCreateResponse + = PostTagBindingsCreateResponses[keyof PostTagBindingsCreateResponses] + +export type PostTagBindingsRemoveData = { + body: TagBindingRemovePayload + path?: never + query?: never + url: '/tag-bindings/remove' +} + +export type PostTagBindingsRemoveResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTagBindingsRemoveResponse + = PostTagBindingsRemoveResponses[keyof PostTagBindingsRemoveResponses] + +export type DeleteTagBindingsByIdData = { + body: TagBindingItemDeletePayload + path: { + id: string + } + query?: never + url: '/tag-bindings/{id}' +} + +export type DeleteTagBindingsByIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteTagBindingsByIdResponse + = DeleteTagBindingsByIdResponses[keyof DeleteTagBindingsByIdResponses] diff --git a/packages/contracts/generated/api/console/tag-bindings/zod.gen.ts b/packages/contracts/generated/api/console/tag-bindings/zod.gen.ts new file mode 100644 index 0000000000..3dead1ec1b --- /dev/null +++ b/packages/contracts/generated/api/console/tag-bindings/zod.gen.ts @@ -0,0 +1,68 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * TagType + * + * Tag type + */ +export const zTagType = z.enum(['knowledge', 'app']) + +/** + * TagBindingPayload + */ +export const zTagBindingPayload = z.object({ + tag_ids: z.array(z.string()), + target_id: z.string(), + type: zTagType, +}) + +/** + * TagBindingRemovePayload + */ +export const zTagBindingRemovePayload = z.object({ + tag_id: z.string(), + target_id: z.string(), + type: zTagType, +}) + +/** + * TagBindingItemDeletePayload + */ +export const zTagBindingItemDeletePayload = z.object({ + target_id: z.string(), + type: zTagType, +}) + +export const zPostTagBindingsBody = zTagBindingPayload + +/** + * Success + */ +export const zPostTagBindingsResponse = z.record(z.string(), z.unknown()) + +export const zPostTagBindingsCreateBody = zTagBindingPayload + +/** + * Success + */ +export const zPostTagBindingsCreateResponse = z.record(z.string(), z.unknown()) + +export const zPostTagBindingsRemoveBody = zTagBindingRemovePayload + +/** + * Success + */ +export const zPostTagBindingsRemoveResponse = z.record(z.string(), z.unknown()) + +export const zDeleteTagBindingsByIdBody = zTagBindingItemDeletePayload + +export const zDeleteTagBindingsByIdPath = z.object({ + id: z.string(), +}) + +/** + * Success + */ +export const zDeleteTagBindingsByIdResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/tags/orpc.gen.ts b/packages/contracts/generated/api/console/tags/orpc.gen.ts new file mode 100644 index 0000000000..937ccce634 --- /dev/null +++ b/packages/contracts/generated/api/console/tags/orpc.gen.ts @@ -0,0 +1,75 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteTagsByTagIdPath, + zDeleteTagsByTagIdResponse, + zGetTagsQuery, + zGetTagsResponse, + zPatchTagsByTagIdBody, + zPatchTagsByTagIdPath, + zPatchTagsByTagIdResponse, + zPostTagsBody, + zPostTagsResponse, +} from './zod.gen' + +export const delete_ = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteTagsByTagId', + path: '/tags/{tag_id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteTagsByTagIdPath })) + .output(zDeleteTagsByTagIdResponse) + +export const patch = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchTagsByTagId', + path: '/tags/{tag_id}', + tags: ['console'], + }) + .input(z.object({ body: zPatchTagsByTagIdBody, params: zPatchTagsByTagIdPath })) + .output(zPatchTagsByTagIdResponse) + +export const byTagId = { + delete: delete_, + patch, +} + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getTags', + path: '/tags', + tags: ['console'], + }) + .input(z.object({ query: zGetTagsQuery.optional() })) + .output(zGetTagsResponse) + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTags', + path: '/tags', + tags: ['console'], + }) + .input(z.object({ body: zPostTagsBody })) + .output(zPostTagsResponse) + +export const tags = { + get, + post, + byTagId, +} + +export const contract = { + tags, +} diff --git a/packages/contracts/generated/api/console/tags/types.gen.ts b/packages/contracts/generated/api/console/tags/types.gen.ts new file mode 100644 index 0000000000..f3c3b1eb3f --- /dev/null +++ b/packages/contracts/generated/api/console/tags/types.gen.ts @@ -0,0 +1,84 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type TagResponse = { + binding_count?: string | null + id: string + name: string + type?: string | null +} + +export type TagBasePayload = { + name: string + type: TagType +} + +export type TagType = 'knowledge' | 'app' + +export type GetTagsData = { + body?: never + path?: never + query?: { + type?: string + keyword?: string + } + url: '/tags' +} + +export type GetTagsResponses = { + 200: Array +} + +export type GetTagsResponse = GetTagsResponses[keyof GetTagsResponses] + +export type PostTagsData = { + body: TagBasePayload + path?: never + query?: never + url: '/tags' +} + +export type PostTagsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTagsResponse = PostTagsResponses[keyof PostTagsResponses] + +export type DeleteTagsByTagIdData = { + body?: never + path: { + tag_id: string + } + query?: never + url: '/tags/{tag_id}' +} + +export type DeleteTagsByTagIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteTagsByTagIdResponse = DeleteTagsByTagIdResponses[keyof DeleteTagsByTagIdResponses] + +export type PatchTagsByTagIdData = { + body: TagBasePayload + path: { + tag_id: string + } + query?: never + url: '/tags/{tag_id}' +} + +export type PatchTagsByTagIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchTagsByTagIdResponse = PatchTagsByTagIdResponses[keyof PatchTagsByTagIdResponses] diff --git a/packages/contracts/generated/api/console/tags/zod.gen.ts b/packages/contracts/generated/api/console/tags/zod.gen.ts new file mode 100644 index 0000000000..4bb8e1783c --- /dev/null +++ b/packages/contracts/generated/api/console/tags/zod.gen.ts @@ -0,0 +1,65 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * TagResponse + */ +export const zTagResponse = z.object({ + binding_count: z.string().nullish(), + id: z.string(), + name: z.string(), + type: z.string().nullish(), +}) + +/** + * TagType + * + * Tag type + */ +export const zTagType = z.enum(['knowledge', 'app']) + +/** + * TagBasePayload + */ +export const zTagBasePayload = z.object({ + name: z.string().min(1).max(50), + type: zTagType, +}) + +export const zGetTagsQuery = z.object({ + type: z.string().optional(), + keyword: z.string().optional(), +}) + +/** + * Success + */ +export const zGetTagsResponse = z.array(zTagResponse) + +export const zPostTagsBody = zTagBasePayload + +/** + * Success + */ +export const zPostTagsResponse = z.record(z.string(), z.unknown()) + +export const zDeleteTagsByTagIdPath = z.object({ + tag_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteTagsByTagIdResponse = z.record(z.string(), z.unknown()) + +export const zPatchTagsByTagIdBody = zTagBasePayload + +export const zPatchTagsByTagIdPath = z.object({ + tag_id: z.string(), +}) + +/** + * Success + */ +export const zPatchTagsByTagIdResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/test/orpc.gen.ts b/packages/contracts/generated/api/console/test/orpc.gen.ts new file mode 100644 index 0000000000..1bdf526b70 --- /dev/null +++ b/packages/contracts/generated/api/console/test/orpc.gen.ts @@ -0,0 +1,33 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { zPostTestRetrievalBody, zPostTestRetrievalResponse } from './zod.gen' + +/** + * Bedrock retrieval test (internal use only) + */ +export const post = oc + .route({ + description: 'Bedrock retrieval test (internal use only)', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTestRetrieval', + path: '/test/retrieval', + tags: ['console'], + }) + .input(z.object({ body: zPostTestRetrievalBody })) + .output(zPostTestRetrievalResponse) + +export const retrieval = { + post, +} + +export const test = { + retrieval, +} + +export const contract = { + test, +} diff --git a/packages/contracts/generated/api/console/test/types.gen.ts b/packages/contracts/generated/api/console/test/types.gen.ts new file mode 100644 index 0000000000..3e04b732ee --- /dev/null +++ b/packages/contracts/generated/api/console/test/types.gen.ts @@ -0,0 +1,31 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type BedrockRetrievalPayload = { + knowledge_id: string + query: string + retrieval_setting: BedrockRetrievalSetting +} + +export type BedrockRetrievalSetting = { + score_threshold?: number + top_k?: number | null +} + +export type PostTestRetrievalData = { + body: BedrockRetrievalPayload + path?: never + query?: never + url: '/test/retrieval' +} + +export type PostTestRetrievalResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTestRetrievalResponse = PostTestRetrievalResponses[keyof PostTestRetrievalResponses] diff --git a/packages/contracts/generated/api/console/test/zod.gen.ts b/packages/contracts/generated/api/console/test/zod.gen.ts new file mode 100644 index 0000000000..9421c6c03f --- /dev/null +++ b/packages/contracts/generated/api/console/test/zod.gen.ts @@ -0,0 +1,29 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * BedrockRetrievalSetting + * + * Retrieval settings for Amazon Bedrock knowledge base queries. + */ +export const zBedrockRetrievalSetting = z.object({ + score_threshold: z.number().optional().default(0), + top_k: z.int().nullish(), +}) + +/** + * BedrockRetrievalPayload + */ +export const zBedrockRetrievalPayload = z.object({ + knowledge_id: z.string(), + query: z.string(), + retrieval_setting: zBedrockRetrievalSetting, +}) + +export const zPostTestRetrievalBody = zBedrockRetrievalPayload + +/** + * Bedrock retrieval test completed + */ +export const zPostTestRetrievalResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/trial-apps/orpc.gen.ts b/packages/contracts/generated/api/console/trial-apps/orpc.gen.ts new file mode 100644 index 0000000000..eca85c206f --- /dev/null +++ b/packages/contracts/generated/api/console/trial-apps/orpc.gen.ts @@ -0,0 +1,298 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetTrialAppsByAppIdDatasetsPath, + zGetTrialAppsByAppIdDatasetsResponse, + zGetTrialAppsByAppIdMessagesByMessageIdSuggestedQuestionsPath, + zGetTrialAppsByAppIdMessagesByMessageIdSuggestedQuestionsResponse, + zGetTrialAppsByAppIdParametersPath, + zGetTrialAppsByAppIdParametersResponse, + zGetTrialAppsByAppIdPath, + zGetTrialAppsByAppIdResponse, + zGetTrialAppsByAppIdSitePath, + zGetTrialAppsByAppIdSiteResponse, + zGetTrialAppsByAppIdWorkflowsPath, + zGetTrialAppsByAppIdWorkflowsResponse, + zPostTrialAppsByAppIdAudioToTextPath, + zPostTrialAppsByAppIdAudioToTextResponse, + zPostTrialAppsByAppIdChatMessagesBody, + zPostTrialAppsByAppIdChatMessagesPath, + zPostTrialAppsByAppIdChatMessagesResponse, + zPostTrialAppsByAppIdCompletionMessagesBody, + zPostTrialAppsByAppIdCompletionMessagesPath, + zPostTrialAppsByAppIdCompletionMessagesResponse, + zPostTrialAppsByAppIdTextToAudioBody, + zPostTrialAppsByAppIdTextToAudioPath, + zPostTrialAppsByAppIdTextToAudioResponse, + zPostTrialAppsByAppIdWorkflowsRunBody, + zPostTrialAppsByAppIdWorkflowsRunPath, + zPostTrialAppsByAppIdWorkflowsRunResponse, + zPostTrialAppsByAppIdWorkflowsTasksByTaskIdStopPath, + zPostTrialAppsByAppIdWorkflowsTasksByTaskIdStopResponse, +} from './zod.gen' + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTrialAppsByAppIdAudioToText', + path: '/trial-apps/{app_id}/audio-to-text', + tags: ['console'], + }) + .input(z.object({ params: zPostTrialAppsByAppIdAudioToTextPath })) + .output(zPostTrialAppsByAppIdAudioToTextResponse) + +export const audioToText = { + post, +} + +export const post2 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTrialAppsByAppIdChatMessages', + path: '/trial-apps/{app_id}/chat-messages', + tags: ['console'], + }) + .input( + z.object({ + body: zPostTrialAppsByAppIdChatMessagesBody, + params: zPostTrialAppsByAppIdChatMessagesPath, + }), + ) + .output(zPostTrialAppsByAppIdChatMessagesResponse) + +export const chatMessages = { + post: post2, +} + +export const post3 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTrialAppsByAppIdCompletionMessages', + path: '/trial-apps/{app_id}/completion-messages', + tags: ['console'], + }) + .input( + z.object({ + body: zPostTrialAppsByAppIdCompletionMessagesBody, + params: zPostTrialAppsByAppIdCompletionMessagesPath, + }), + ) + .output(zPostTrialAppsByAppIdCompletionMessagesResponse) + +export const completionMessages = { + post: post3, +} + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getTrialAppsByAppIdDatasets', + path: '/trial-apps/{app_id}/datasets', + tags: ['console'], + }) + .input(z.object({ params: zGetTrialAppsByAppIdDatasetsPath })) + .output(zGetTrialAppsByAppIdDatasetsResponse) + +export const datasets = { + get, +} + +export const get2 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getTrialAppsByAppIdMessagesByMessageIdSuggestedQuestions', + path: '/trial-apps/{app_id}/messages/{message_id}/suggested-questions', + tags: ['console'], + }) + .input(z.object({ params: zGetTrialAppsByAppIdMessagesByMessageIdSuggestedQuestionsPath })) + .output(zGetTrialAppsByAppIdMessagesByMessageIdSuggestedQuestionsResponse) + +export const suggestedQuestions = { + get: get2, +} + +export const byMessageId = { + suggestedQuestions, +} + +export const messages = { + byMessageId, +} + +/** + * Retrieve app parameters + */ +export const get3 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getTrialAppsByAppIdParameters', + path: '/trial-apps/{app_id}/parameters', + summary: 'Retrieve app parameters', + tags: ['console'], + }) + .input(z.object({ params: zGetTrialAppsByAppIdParametersPath })) + .output(zGetTrialAppsByAppIdParametersResponse) + +export const parameters = { + get: get3, +} + +/** + * Retrieve app site info + * + * Returns the site configuration for the application including theme, icons, and text. + */ +export const get4 = oc + .route({ + description: + 'Returns the site configuration for the application including theme, icons, and text.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getTrialAppsByAppIdSite', + path: '/trial-apps/{app_id}/site', + summary: 'Retrieve app site info', + tags: ['console'], + }) + .input(z.object({ params: zGetTrialAppsByAppIdSitePath })) + .output(zGetTrialAppsByAppIdSiteResponse) + +export const site = { + get: get4, +} + +export const post4 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTrialAppsByAppIdTextToAudio', + path: '/trial-apps/{app_id}/text-to-audio', + tags: ['console'], + }) + .input( + z.object({ + body: zPostTrialAppsByAppIdTextToAudioBody, + params: zPostTrialAppsByAppIdTextToAudioPath, + }), + ) + .output(zPostTrialAppsByAppIdTextToAudioResponse) + +export const textToAudio = { + post: post4, +} + +/** + * Run workflow + */ +export const post5 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTrialAppsByAppIdWorkflowsRun', + path: '/trial-apps/{app_id}/workflows/run', + summary: 'Run workflow', + tags: ['console'], + }) + .input( + z.object({ + body: zPostTrialAppsByAppIdWorkflowsRunBody, + params: zPostTrialAppsByAppIdWorkflowsRunPath, + }), + ) + .output(zPostTrialAppsByAppIdWorkflowsRunResponse) + +export const run = { + post: post5, +} + +/** + * Stop workflow task + */ +export const post6 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTrialAppsByAppIdWorkflowsTasksByTaskIdStop', + path: '/trial-apps/{app_id}/workflows/tasks/{task_id}/stop', + summary: 'Stop workflow task', + tags: ['console'], + }) + .input(z.object({ params: zPostTrialAppsByAppIdWorkflowsTasksByTaskIdStopPath })) + .output(zPostTrialAppsByAppIdWorkflowsTasksByTaskIdStopResponse) + +export const stop = { + post: post6, +} + +export const byTaskId = { + stop, +} + +export const tasks = { + byTaskId, +} + +/** + * Get workflow detail + */ +export const get5 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getTrialAppsByAppIdWorkflows', + path: '/trial-apps/{app_id}/workflows', + summary: 'Get workflow detail', + tags: ['console'], + }) + .input(z.object({ params: zGetTrialAppsByAppIdWorkflowsPath })) + .output(zGetTrialAppsByAppIdWorkflowsResponse) + +export const workflows = { + get: get5, + run, + tasks, +} + +/** + * Get app detail + */ +export const get6 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getTrialAppsByAppId', + path: '/trial-apps/{app_id}', + summary: 'Get app detail', + tags: ['console'], + }) + .input(z.object({ params: zGetTrialAppsByAppIdPath })) + .output(zGetTrialAppsByAppIdResponse) + +export const byAppId = { + get: get6, + audioToText, + chatMessages, + completionMessages, + datasets, + messages, + parameters, + site, + textToAudio, + workflows, +} + +export const trialApps = { + byAppId, +} + +export const contract = { + trialApps, +} diff --git a/packages/contracts/generated/api/console/trial-apps/types.gen.ts b/packages/contracts/generated/api/console/trial-apps/types.gen.ts new file mode 100644 index 0000000000..2965aafebf --- /dev/null +++ b/packages/contracts/generated/api/console/trial-apps/types.gen.ts @@ -0,0 +1,258 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type ChatRequest = { + conversation_id?: string | null + files?: Array | null + inputs: { + [key: string]: unknown + } + parent_message_id?: string | null + query: string + retriever_from?: string +} + +export type CompletionRequest = { + files?: Array | null + inputs: { + [key: string]: unknown + } + query?: string + response_mode?: 'blocking' | 'streaming' | null + retriever_from?: string +} + +export type TextToSpeechRequest = { + message_id?: string | null + streaming?: boolean | null + text?: string | null + voice?: string | null +} + +export type WorkflowRunRequest = { + files?: Array | null + inputs: { + [key: string]: unknown + } +} + +export type GetTrialAppsByAppIdData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/trial-apps/{app_id}' +} + +export type GetTrialAppsByAppIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetTrialAppsByAppIdResponse + = GetTrialAppsByAppIdResponses[keyof GetTrialAppsByAppIdResponses] + +export type PostTrialAppsByAppIdAudioToTextData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/trial-apps/{app_id}/audio-to-text' +} + +export type PostTrialAppsByAppIdAudioToTextResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTrialAppsByAppIdAudioToTextResponse + = PostTrialAppsByAppIdAudioToTextResponses[keyof PostTrialAppsByAppIdAudioToTextResponses] + +export type PostTrialAppsByAppIdChatMessagesData = { + body: ChatRequest + path: { + app_id: string + } + query?: never + url: '/trial-apps/{app_id}/chat-messages' +} + +export type PostTrialAppsByAppIdChatMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTrialAppsByAppIdChatMessagesResponse + = PostTrialAppsByAppIdChatMessagesResponses[keyof PostTrialAppsByAppIdChatMessagesResponses] + +export type PostTrialAppsByAppIdCompletionMessagesData = { + body: CompletionRequest + path: { + app_id: string + } + query?: never + url: '/trial-apps/{app_id}/completion-messages' +} + +export type PostTrialAppsByAppIdCompletionMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTrialAppsByAppIdCompletionMessagesResponse + = PostTrialAppsByAppIdCompletionMessagesResponses[keyof PostTrialAppsByAppIdCompletionMessagesResponses] + +export type GetTrialAppsByAppIdDatasetsData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/trial-apps/{app_id}/datasets' +} + +export type GetTrialAppsByAppIdDatasetsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetTrialAppsByAppIdDatasetsResponse + = GetTrialAppsByAppIdDatasetsResponses[keyof GetTrialAppsByAppIdDatasetsResponses] + +export type GetTrialAppsByAppIdMessagesByMessageIdSuggestedQuestionsData = { + body?: never + path: { + app_id: string + message_id: string + } + query?: never + url: '/trial-apps/{app_id}/messages/{message_id}/suggested-questions' +} + +export type GetTrialAppsByAppIdMessagesByMessageIdSuggestedQuestionsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetTrialAppsByAppIdMessagesByMessageIdSuggestedQuestionsResponse + = GetTrialAppsByAppIdMessagesByMessageIdSuggestedQuestionsResponses[keyof GetTrialAppsByAppIdMessagesByMessageIdSuggestedQuestionsResponses] + +export type GetTrialAppsByAppIdParametersData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/trial-apps/{app_id}/parameters' +} + +export type GetTrialAppsByAppIdParametersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetTrialAppsByAppIdParametersResponse + = GetTrialAppsByAppIdParametersResponses[keyof GetTrialAppsByAppIdParametersResponses] + +export type GetTrialAppsByAppIdSiteData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/trial-apps/{app_id}/site' +} + +export type GetTrialAppsByAppIdSiteResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetTrialAppsByAppIdSiteResponse + = GetTrialAppsByAppIdSiteResponses[keyof GetTrialAppsByAppIdSiteResponses] + +export type PostTrialAppsByAppIdTextToAudioData = { + body: TextToSpeechRequest + path: { + app_id: string + } + query?: never + url: '/trial-apps/{app_id}/text-to-audio' +} + +export type PostTrialAppsByAppIdTextToAudioResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTrialAppsByAppIdTextToAudioResponse + = PostTrialAppsByAppIdTextToAudioResponses[keyof PostTrialAppsByAppIdTextToAudioResponses] + +export type GetTrialAppsByAppIdWorkflowsData = { + body?: never + path: { + app_id: string + } + query?: never + url: '/trial-apps/{app_id}/workflows' +} + +export type GetTrialAppsByAppIdWorkflowsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetTrialAppsByAppIdWorkflowsResponse + = GetTrialAppsByAppIdWorkflowsResponses[keyof GetTrialAppsByAppIdWorkflowsResponses] + +export type PostTrialAppsByAppIdWorkflowsRunData = { + body: WorkflowRunRequest + path: { + app_id: string + } + query?: never + url: '/trial-apps/{app_id}/workflows/run' +} + +export type PostTrialAppsByAppIdWorkflowsRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTrialAppsByAppIdWorkflowsRunResponse + = PostTrialAppsByAppIdWorkflowsRunResponses[keyof PostTrialAppsByAppIdWorkflowsRunResponses] + +export type PostTrialAppsByAppIdWorkflowsTasksByTaskIdStopData = { + body?: never + path: { + app_id: string + task_id: string + } + query?: never + url: '/trial-apps/{app_id}/workflows/tasks/{task_id}/stop' +} + +export type PostTrialAppsByAppIdWorkflowsTasksByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTrialAppsByAppIdWorkflowsTasksByTaskIdStopResponse + = PostTrialAppsByAppIdWorkflowsTasksByTaskIdStopResponses[keyof PostTrialAppsByAppIdWorkflowsTasksByTaskIdStopResponses] diff --git a/packages/contracts/generated/api/console/trial-apps/zod.gen.ts b/packages/contracts/generated/api/console/trial-apps/zod.gen.ts new file mode 100644 index 0000000000..f7a52425a2 --- /dev/null +++ b/packages/contracts/generated/api/console/trial-apps/zod.gen.ts @@ -0,0 +1,168 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * ChatRequest + */ +export const zChatRequest = z.object({ + conversation_id: z.string().nullish(), + files: z.array(z.unknown()).nullish(), + inputs: z.record(z.string(), z.unknown()), + parent_message_id: z.string().nullish(), + query: z.string(), + retriever_from: z.string().optional().default('explore_app'), +}) + +/** + * CompletionRequest + */ +export const zCompletionRequest = z.object({ + files: z.array(z.unknown()).nullish(), + inputs: z.record(z.string(), z.unknown()), + query: z.string().optional().default(''), + response_mode: z.enum(['blocking', 'streaming']).nullish(), + retriever_from: z.string().optional().default('explore_app'), +}) + +/** + * TextToSpeechRequest + */ +export const zTextToSpeechRequest = z.object({ + message_id: z.string().nullish(), + streaming: z.boolean().nullish(), + text: z.string().nullish(), + voice: z.string().nullish(), +}) + +/** + * WorkflowRunRequest + */ +export const zWorkflowRunRequest = z.object({ + files: z.array(z.unknown()).nullish(), + inputs: z.record(z.string(), z.unknown()), +}) + +export const zGetTrialAppsByAppIdPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zGetTrialAppsByAppIdResponse = z.record(z.string(), z.unknown()) + +export const zPostTrialAppsByAppIdAudioToTextPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zPostTrialAppsByAppIdAudioToTextResponse = z.record(z.string(), z.unknown()) + +export const zPostTrialAppsByAppIdChatMessagesBody = zChatRequest + +export const zPostTrialAppsByAppIdChatMessagesPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zPostTrialAppsByAppIdChatMessagesResponse = z.record(z.string(), z.unknown()) + +export const zPostTrialAppsByAppIdCompletionMessagesBody = zCompletionRequest + +export const zPostTrialAppsByAppIdCompletionMessagesPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zPostTrialAppsByAppIdCompletionMessagesResponse = z.record(z.string(), z.unknown()) + +export const zGetTrialAppsByAppIdDatasetsPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zGetTrialAppsByAppIdDatasetsResponse = z.record(z.string(), z.unknown()) + +export const zGetTrialAppsByAppIdMessagesByMessageIdSuggestedQuestionsPath = z.object({ + app_id: z.string(), + message_id: z.string(), +}) + +/** + * Success + */ +export const zGetTrialAppsByAppIdMessagesByMessageIdSuggestedQuestionsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetTrialAppsByAppIdParametersPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zGetTrialAppsByAppIdParametersResponse = z.record(z.string(), z.unknown()) + +export const zGetTrialAppsByAppIdSitePath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zGetTrialAppsByAppIdSiteResponse = z.record(z.string(), z.unknown()) + +export const zPostTrialAppsByAppIdTextToAudioBody = zTextToSpeechRequest + +export const zPostTrialAppsByAppIdTextToAudioPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zPostTrialAppsByAppIdTextToAudioResponse = z.record(z.string(), z.unknown()) + +export const zGetTrialAppsByAppIdWorkflowsPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zGetTrialAppsByAppIdWorkflowsResponse = z.record(z.string(), z.unknown()) + +export const zPostTrialAppsByAppIdWorkflowsRunBody = zWorkflowRunRequest + +export const zPostTrialAppsByAppIdWorkflowsRunPath = z.object({ + app_id: z.string(), +}) + +/** + * Success + */ +export const zPostTrialAppsByAppIdWorkflowsRunResponse = z.record(z.string(), z.unknown()) + +export const zPostTrialAppsByAppIdWorkflowsTasksByTaskIdStopPath = z.object({ + app_id: z.string(), + task_id: z.string(), +}) + +/** + * Success + */ +export const zPostTrialAppsByAppIdWorkflowsTasksByTaskIdStopResponse = z.record( + z.string(), + z.unknown(), +) diff --git a/packages/contracts/generated/api/console/website/orpc.gen.ts b/packages/contracts/generated/api/console/website/orpc.gen.ts new file mode 100644 index 0000000000..698f656967 --- /dev/null +++ b/packages/contracts/generated/api/console/website/orpc.gen.ts @@ -0,0 +1,68 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetWebsiteCrawlStatusByJobIdPath, + zGetWebsiteCrawlStatusByJobIdQuery, + zGetWebsiteCrawlStatusByJobIdResponse, + zPostWebsiteCrawlBody, + zPostWebsiteCrawlResponse, +} from './zod.gen' + +/** + * Get website crawl status + */ +export const get = oc + .route({ + description: 'Get website crawl status', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWebsiteCrawlStatusByJobId', + path: '/website/crawl/status/{job_id}', + tags: ['console'], + }) + .input( + z.object({ + params: zGetWebsiteCrawlStatusByJobIdPath, + query: zGetWebsiteCrawlStatusByJobIdQuery, + }), + ) + .output(zGetWebsiteCrawlStatusByJobIdResponse) + +export const byJobId = { + get, +} + +export const status = { + byJobId, +} + +/** + * Crawl website content + */ +export const post = oc + .route({ + description: 'Crawl website content', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWebsiteCrawl', + path: '/website/crawl', + tags: ['console'], + }) + .input(z.object({ body: zPostWebsiteCrawlBody })) + .output(zPostWebsiteCrawlResponse) + +export const crawl = { + post, + status, +} + +export const website = { + crawl, +} + +export const contract = { + website, +} diff --git a/packages/contracts/generated/api/console/website/types.gen.ts b/packages/contracts/generated/api/console/website/types.gen.ts new file mode 100644 index 0000000000..e47b11a819 --- /dev/null +++ b/packages/contracts/generated/api/console/website/types.gen.ts @@ -0,0 +1,68 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type WebsiteCrawlPayload = { + options: { + [key: string]: unknown + } + provider: 'firecrawl' | 'watercrawl' | 'jinareader' + url: string +} + +export type PostWebsiteCrawlData = { + body: WebsiteCrawlPayload + path?: never + query?: never + url: '/website/crawl' +} + +export type PostWebsiteCrawlErrors = { + 400: { + [key: string]: unknown + } +} + +export type PostWebsiteCrawlError = PostWebsiteCrawlErrors[keyof PostWebsiteCrawlErrors] + +export type PostWebsiteCrawlResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWebsiteCrawlResponse = PostWebsiteCrawlResponses[keyof PostWebsiteCrawlResponses] + +export type GetWebsiteCrawlStatusByJobIdData = { + body?: never + path: { + job_id: string + } + query: { + provider: 'firecrawl' | 'watercrawl' | 'jinareader' + } + url: '/website/crawl/status/{job_id}' +} + +export type GetWebsiteCrawlStatusByJobIdErrors = { + 400: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetWebsiteCrawlStatusByJobIdError + = GetWebsiteCrawlStatusByJobIdErrors[keyof GetWebsiteCrawlStatusByJobIdErrors] + +export type GetWebsiteCrawlStatusByJobIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWebsiteCrawlStatusByJobIdResponse + = GetWebsiteCrawlStatusByJobIdResponses[keyof GetWebsiteCrawlStatusByJobIdResponses] diff --git a/packages/contracts/generated/api/console/website/zod.gen.ts b/packages/contracts/generated/api/console/website/zod.gen.ts new file mode 100644 index 0000000000..a7590ec9ee --- /dev/null +++ b/packages/contracts/generated/api/console/website/zod.gen.ts @@ -0,0 +1,32 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * WebsiteCrawlPayload + */ +export const zWebsiteCrawlPayload = z.object({ + options: z.record(z.string(), z.unknown()), + provider: z.enum(['firecrawl', 'watercrawl', 'jinareader']), + url: z.string(), +}) + +export const zPostWebsiteCrawlBody = zWebsiteCrawlPayload + +/** + * Website crawl initiated successfully + */ +export const zPostWebsiteCrawlResponse = z.record(z.string(), z.unknown()) + +export const zGetWebsiteCrawlStatusByJobIdPath = z.object({ + job_id: z.string(), +}) + +export const zGetWebsiteCrawlStatusByJobIdQuery = z.object({ + provider: z.enum(['firecrawl', 'watercrawl', 'jinareader']), +}) + +/** + * Crawl status retrieved successfully + */ +export const zGetWebsiteCrawlStatusByJobIdResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/workflow/orpc.gen.ts b/packages/contracts/generated/api/console/workflow/orpc.gen.ts new file mode 100644 index 0000000000..bf139e6ac1 --- /dev/null +++ b/packages/contracts/generated/api/console/workflow/orpc.gen.ts @@ -0,0 +1,74 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zGetWorkflowByWorkflowRunIdEventsPath, + zGetWorkflowByWorkflowRunIdEventsResponse, + zGetWorkflowByWorkflowRunIdPauseDetailsPath, + zGetWorkflowByWorkflowRunIdPauseDetailsResponse, +} from './zod.gen' + +/** + * Get workflow execution events stream after resume + * + * GET /console/api/workflow//events + * + * Returns Server-Sent Events stream. + */ +export const get = oc + .route({ + description: + 'GET /console/api/workflow//events\n\nReturns Server-Sent Events stream.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkflowByWorkflowRunIdEvents', + path: '/workflow/{workflow_run_id}/events', + summary: 'Get workflow execution events stream after resume', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkflowByWorkflowRunIdEventsPath })) + .output(zGetWorkflowByWorkflowRunIdEventsResponse) + +export const events = { + get, +} + +/** + * Get workflow pause details + * + * GET /console/api/workflow//pause-details + * + * Returns information about why and where the workflow is paused. + */ +export const get2 = oc + .route({ + description: + 'GET /console/api/workflow//pause-details\n\nReturns information about why and where the workflow is paused.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkflowByWorkflowRunIdPauseDetails', + path: '/workflow/{workflow_run_id}/pause-details', + summary: 'Get workflow pause details', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkflowByWorkflowRunIdPauseDetailsPath })) + .output(zGetWorkflowByWorkflowRunIdPauseDetailsResponse) + +export const pauseDetails = { + get: get2, +} + +export const byWorkflowRunId = { + events, + pauseDetails, +} + +export const workflow = { + byWorkflowRunId, +} + +export const contract = { + workflow, +} diff --git a/packages/contracts/generated/api/console/workflow/types.gen.ts b/packages/contracts/generated/api/console/workflow/types.gen.ts new file mode 100644 index 0000000000..a3fae60eae --- /dev/null +++ b/packages/contracts/generated/api/console/workflow/types.gen.ts @@ -0,0 +1,41 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type GetWorkflowByWorkflowRunIdEventsData = { + body?: never + path: { + workflow_run_id: string + } + query?: never + url: '/workflow/{workflow_run_id}/events' +} + +export type GetWorkflowByWorkflowRunIdEventsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkflowByWorkflowRunIdEventsResponse + = GetWorkflowByWorkflowRunIdEventsResponses[keyof GetWorkflowByWorkflowRunIdEventsResponses] + +export type GetWorkflowByWorkflowRunIdPauseDetailsData = { + body?: never + path: { + workflow_run_id: string + } + query?: never + url: '/workflow/{workflow_run_id}/pause-details' +} + +export type GetWorkflowByWorkflowRunIdPauseDetailsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkflowByWorkflowRunIdPauseDetailsResponse + = GetWorkflowByWorkflowRunIdPauseDetailsResponses[keyof GetWorkflowByWorkflowRunIdPauseDetailsResponses] diff --git a/packages/contracts/generated/api/console/workflow/zod.gen.ts b/packages/contracts/generated/api/console/workflow/zod.gen.ts new file mode 100644 index 0000000000..315085f60f --- /dev/null +++ b/packages/contracts/generated/api/console/workflow/zod.gen.ts @@ -0,0 +1,21 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +export const zGetWorkflowByWorkflowRunIdEventsPath = z.object({ + workflow_run_id: z.string(), +}) + +/** + * Success + */ +export const zGetWorkflowByWorkflowRunIdEventsResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkflowByWorkflowRunIdPauseDetailsPath = z.object({ + workflow_run_id: z.string(), +}) + +/** + * Success + */ +export const zGetWorkflowByWorkflowRunIdPauseDetailsResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/api/console/workspaces/orpc.gen.ts b/packages/contracts/generated/api/console/workspaces/orpc.gen.ts new file mode 100644 index 0000000000..4d16e3120f --- /dev/null +++ b/packages/contracts/generated/api/console/workspaces/orpc.gen.ts @@ -0,0 +1,3012 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteWorkspacesCurrentEndpointsByIdPath, + zDeleteWorkspacesCurrentEndpointsByIdResponse, + zDeleteWorkspacesCurrentMembersByMemberIdPath, + zDeleteWorkspacesCurrentMembersByMemberIdResponse, + zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsBody, + zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsPath, + zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponse, + zDeleteWorkspacesCurrentModelProvidersByProviderModelsBody, + zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsBody, + zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath, + zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse, + zDeleteWorkspacesCurrentModelProvidersByProviderModelsPath, + zDeleteWorkspacesCurrentModelProvidersByProviderModelsResponse, + zDeleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientPath, + zDeleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse, + zDeleteWorkspacesCurrentToolProviderMcpBody, + zDeleteWorkspacesCurrentToolProviderMcpResponse, + zDeleteWorkspacesCurrentTriggerProviderByProviderOauthClientPath, + zDeleteWorkspacesCurrentTriggerProviderByProviderOauthClientResponse, + zGetWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLangPath, + zGetWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLangResponse, + zGetWorkspacesCurrentAgentProviderByProviderNamePath, + zGetWorkspacesCurrentAgentProviderByProviderNameResponse, + zGetWorkspacesCurrentAgentProvidersResponse, + zGetWorkspacesCurrentDatasetOperatorsResponse, + zGetWorkspacesCurrentDefaultModelQuery, + zGetWorkspacesCurrentDefaultModelResponse, + zGetWorkspacesCurrentEndpointsListPluginQuery, + zGetWorkspacesCurrentEndpointsListPluginResponse, + zGetWorkspacesCurrentEndpointsListQuery, + zGetWorkspacesCurrentEndpointsListResponse, + zGetWorkspacesCurrentMembersResponse, + zGetWorkspacesCurrentModelProvidersByProviderCheckoutUrlPath, + zGetWorkspacesCurrentModelProvidersByProviderCheckoutUrlResponse, + zGetWorkspacesCurrentModelProvidersByProviderCredentialsPath, + zGetWorkspacesCurrentModelProvidersByProviderCredentialsQuery, + zGetWorkspacesCurrentModelProvidersByProviderCredentialsResponse, + zGetWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath, + zGetWorkspacesCurrentModelProvidersByProviderModelsCredentialsQuery, + zGetWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse, + zGetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesPath, + zGetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesQuery, + zGetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesResponse, + zGetWorkspacesCurrentModelProvidersByProviderModelsPath, + zGetWorkspacesCurrentModelProvidersByProviderModelsResponse, + zGetWorkspacesCurrentModelProvidersQuery, + zGetWorkspacesCurrentModelProvidersResponse, + zGetWorkspacesCurrentModelsModelTypesByModelTypePath, + zGetWorkspacesCurrentModelsModelTypesByModelTypeResponse, + zGetWorkspacesCurrentPermissionResponse, + zGetWorkspacesCurrentPluginAssetQuery, + zGetWorkspacesCurrentPluginAssetResponse, + zGetWorkspacesCurrentPluginDebuggingKeyResponse, + zGetWorkspacesCurrentPluginFetchManifestQuery, + zGetWorkspacesCurrentPluginFetchManifestResponse, + zGetWorkspacesCurrentPluginIconQuery, + zGetWorkspacesCurrentPluginIconResponse, + zGetWorkspacesCurrentPluginListQuery, + zGetWorkspacesCurrentPluginListResponse, + zGetWorkspacesCurrentPluginMarketplacePkgQuery, + zGetWorkspacesCurrentPluginMarketplacePkgResponse, + zGetWorkspacesCurrentPluginParametersDynamicOptionsQuery, + zGetWorkspacesCurrentPluginParametersDynamicOptionsResponse, + zGetWorkspacesCurrentPluginPermissionFetchResponse, + zGetWorkspacesCurrentPluginPreferencesFetchResponse, + zGetWorkspacesCurrentPluginReadmeQuery, + zGetWorkspacesCurrentPluginReadmeResponse, + zGetWorkspacesCurrentPluginTasksByTaskIdPath, + zGetWorkspacesCurrentPluginTasksByTaskIdResponse, + zGetWorkspacesCurrentPluginTasksQuery, + zGetWorkspacesCurrentPluginTasksResponse, + zGetWorkspacesCurrentToolLabelsResponse, + zGetWorkspacesCurrentToolProviderApiGetResponse, + zGetWorkspacesCurrentToolProviderApiRemoteResponse, + zGetWorkspacesCurrentToolProviderApiToolsResponse, + zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoPath, + zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoResponse, + zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypePath, + zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypeResponse, + zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsPath, + zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsResponse, + zGetWorkspacesCurrentToolProviderBuiltinByProviderIconPath, + zGetWorkspacesCurrentToolProviderBuiltinByProviderIconResponse, + zGetWorkspacesCurrentToolProviderBuiltinByProviderInfoPath, + zGetWorkspacesCurrentToolProviderBuiltinByProviderInfoResponse, + zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaPath, + zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaResponse, + zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientPath, + zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse, + zGetWorkspacesCurrentToolProviderBuiltinByProviderToolsPath, + zGetWorkspacesCurrentToolProviderBuiltinByProviderToolsResponse, + zGetWorkspacesCurrentToolProviderMcpToolsByProviderIdPath, + zGetWorkspacesCurrentToolProviderMcpToolsByProviderIdResponse, + zGetWorkspacesCurrentToolProviderMcpUpdateByProviderIdPath, + zGetWorkspacesCurrentToolProviderMcpUpdateByProviderIdResponse, + zGetWorkspacesCurrentToolProvidersResponse, + zGetWorkspacesCurrentToolProviderWorkflowGetResponse, + zGetWorkspacesCurrentToolProviderWorkflowToolsResponse, + zGetWorkspacesCurrentToolsApiResponse, + zGetWorkspacesCurrentToolsBuiltinResponse, + zGetWorkspacesCurrentToolsMcpResponse, + zGetWorkspacesCurrentToolsWorkflowResponse, + zGetWorkspacesCurrentTriggerProviderByProviderIconPath, + zGetWorkspacesCurrentTriggerProviderByProviderIconResponse, + zGetWorkspacesCurrentTriggerProviderByProviderInfoPath, + zGetWorkspacesCurrentTriggerProviderByProviderInfoResponse, + zGetWorkspacesCurrentTriggerProviderByProviderOauthClientPath, + zGetWorkspacesCurrentTriggerProviderByProviderOauthClientResponse, + zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBySubscriptionBuilderIdPath, + zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBySubscriptionBuilderIdResponse, + zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderLogsBySubscriptionBuilderIdPath, + zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderLogsBySubscriptionBuilderIdResponse, + zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListPath, + zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListResponse, + zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorizePath, + zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorizeResponse, + zGetWorkspacesCurrentTriggersResponse, + zGetWorkspacesResponse, + zPatchWorkspacesCurrentEndpointsByIdBody, + zPatchWorkspacesCurrentEndpointsByIdPath, + zPatchWorkspacesCurrentEndpointsByIdResponse, + zPatchWorkspacesCurrentModelProvidersByProviderModelsDisableBody, + zPatchWorkspacesCurrentModelProvidersByProviderModelsDisablePath, + zPatchWorkspacesCurrentModelProvidersByProviderModelsDisableResponse, + zPatchWorkspacesCurrentModelProvidersByProviderModelsEnableBody, + zPatchWorkspacesCurrentModelProvidersByProviderModelsEnablePath, + zPatchWorkspacesCurrentModelProvidersByProviderModelsEnableResponse, + zPostWorkspacesCurrentDefaultModelBody, + zPostWorkspacesCurrentDefaultModelResponse, + zPostWorkspacesCurrentEndpointsBody, + zPostWorkspacesCurrentEndpointsCreateBody, + zPostWorkspacesCurrentEndpointsCreateResponse, + zPostWorkspacesCurrentEndpointsDeleteBody, + zPostWorkspacesCurrentEndpointsDeleteResponse, + zPostWorkspacesCurrentEndpointsDisableBody, + zPostWorkspacesCurrentEndpointsDisableResponse, + zPostWorkspacesCurrentEndpointsEnableBody, + zPostWorkspacesCurrentEndpointsEnableResponse, + zPostWorkspacesCurrentEndpointsResponse, + zPostWorkspacesCurrentEndpointsUpdateBody, + zPostWorkspacesCurrentEndpointsUpdateResponse, + zPostWorkspacesCurrentMembersByMemberIdOwnerTransferBody, + zPostWorkspacesCurrentMembersByMemberIdOwnerTransferPath, + zPostWorkspacesCurrentMembersByMemberIdOwnerTransferResponse, + zPostWorkspacesCurrentMembersInviteEmailBody, + zPostWorkspacesCurrentMembersInviteEmailResponse, + zPostWorkspacesCurrentMembersOwnerTransferCheckBody, + zPostWorkspacesCurrentMembersOwnerTransferCheckResponse, + zPostWorkspacesCurrentMembersSendOwnerTransferConfirmEmailBody, + zPostWorkspacesCurrentMembersSendOwnerTransferConfirmEmailResponse, + zPostWorkspacesCurrentModelProvidersByProviderCredentialsBody, + zPostWorkspacesCurrentModelProvidersByProviderCredentialsPath, + zPostWorkspacesCurrentModelProvidersByProviderCredentialsResponse, + zPostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchBody, + zPostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchPath, + zPostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchResponse, + zPostWorkspacesCurrentModelProvidersByProviderCredentialsValidateBody, + zPostWorkspacesCurrentModelProvidersByProviderCredentialsValidatePath, + zPostWorkspacesCurrentModelProvidersByProviderCredentialsValidateResponse, + zPostWorkspacesCurrentModelProvidersByProviderModelsBody, + zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsBody, + zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath, + zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse, + zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchBody, + zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchPath, + zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchResponse, + zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidateBody, + zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidatePath, + zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidateResponse, + zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidateBody, + zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidatePath, + zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidateResponse, + zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidateBody, + zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidatePath, + zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidateResponse, + zPostWorkspacesCurrentModelProvidersByProviderModelsPath, + zPostWorkspacesCurrentModelProvidersByProviderModelsResponse, + zPostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypeBody, + zPostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypePath, + zPostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypeResponse, + zPostWorkspacesCurrentPluginInstallGithubBody, + zPostWorkspacesCurrentPluginInstallGithubResponse, + zPostWorkspacesCurrentPluginInstallMarketplaceBody, + zPostWorkspacesCurrentPluginInstallMarketplaceResponse, + zPostWorkspacesCurrentPluginInstallPkgBody, + zPostWorkspacesCurrentPluginInstallPkgResponse, + zPostWorkspacesCurrentPluginListInstallationsIdsBody, + zPostWorkspacesCurrentPluginListInstallationsIdsResponse, + zPostWorkspacesCurrentPluginListLatestVersionsBody, + zPostWorkspacesCurrentPluginListLatestVersionsResponse, + zPostWorkspacesCurrentPluginParametersDynamicOptionsWithCredentialsBody, + zPostWorkspacesCurrentPluginParametersDynamicOptionsWithCredentialsResponse, + zPostWorkspacesCurrentPluginPermissionChangeBody, + zPostWorkspacesCurrentPluginPermissionChangeResponse, + zPostWorkspacesCurrentPluginPreferencesAutoupgradeExcludeBody, + zPostWorkspacesCurrentPluginPreferencesAutoupgradeExcludeResponse, + zPostWorkspacesCurrentPluginPreferencesChangeBody, + zPostWorkspacesCurrentPluginPreferencesChangeResponse, + zPostWorkspacesCurrentPluginTasksByTaskIdDeleteByIdentifierPath, + zPostWorkspacesCurrentPluginTasksByTaskIdDeleteByIdentifierResponse, + zPostWorkspacesCurrentPluginTasksByTaskIdDeletePath, + zPostWorkspacesCurrentPluginTasksByTaskIdDeleteResponse, + zPostWorkspacesCurrentPluginTasksDeleteAllResponse, + zPostWorkspacesCurrentPluginUninstallBody, + zPostWorkspacesCurrentPluginUninstallResponse, + zPostWorkspacesCurrentPluginUpgradeGithubBody, + zPostWorkspacesCurrentPluginUpgradeGithubResponse, + zPostWorkspacesCurrentPluginUpgradeMarketplaceBody, + zPostWorkspacesCurrentPluginUpgradeMarketplaceResponse, + zPostWorkspacesCurrentPluginUploadBundleResponse, + zPostWorkspacesCurrentPluginUploadGithubBody, + zPostWorkspacesCurrentPluginUploadGithubResponse, + zPostWorkspacesCurrentPluginUploadPkgResponse, + zPostWorkspacesCurrentResponse, + zPostWorkspacesCurrentToolProviderApiAddBody, + zPostWorkspacesCurrentToolProviderApiAddResponse, + zPostWorkspacesCurrentToolProviderApiDeleteBody, + zPostWorkspacesCurrentToolProviderApiDeleteResponse, + zPostWorkspacesCurrentToolProviderApiSchemaBody, + zPostWorkspacesCurrentToolProviderApiSchemaResponse, + zPostWorkspacesCurrentToolProviderApiTestPreBody, + zPostWorkspacesCurrentToolProviderApiTestPreResponse, + zPostWorkspacesCurrentToolProviderApiUpdateBody, + zPostWorkspacesCurrentToolProviderApiUpdateResponse, + zPostWorkspacesCurrentToolProviderBuiltinByProviderAddBody, + zPostWorkspacesCurrentToolProviderBuiltinByProviderAddPath, + zPostWorkspacesCurrentToolProviderBuiltinByProviderAddResponse, + zPostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialBody, + zPostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialPath, + zPostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialResponse, + zPostWorkspacesCurrentToolProviderBuiltinByProviderDeleteBody, + zPostWorkspacesCurrentToolProviderBuiltinByProviderDeletePath, + zPostWorkspacesCurrentToolProviderBuiltinByProviderDeleteResponse, + zPostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientBody, + zPostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientPath, + zPostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse, + zPostWorkspacesCurrentToolProviderBuiltinByProviderUpdateBody, + zPostWorkspacesCurrentToolProviderBuiltinByProviderUpdatePath, + zPostWorkspacesCurrentToolProviderBuiltinByProviderUpdateResponse, + zPostWorkspacesCurrentToolProviderMcpAuthBody, + zPostWorkspacesCurrentToolProviderMcpAuthResponse, + zPostWorkspacesCurrentToolProviderMcpBody, + zPostWorkspacesCurrentToolProviderMcpResponse, + zPostWorkspacesCurrentToolProviderWorkflowCreateBody, + zPostWorkspacesCurrentToolProviderWorkflowCreateResponse, + zPostWorkspacesCurrentToolProviderWorkflowDeleteBody, + zPostWorkspacesCurrentToolProviderWorkflowDeleteResponse, + zPostWorkspacesCurrentToolProviderWorkflowUpdateBody, + zPostWorkspacesCurrentToolProviderWorkflowUpdateResponse, + zPostWorkspacesCurrentTriggerProviderByProviderOauthClientBody, + zPostWorkspacesCurrentTriggerProviderByProviderOauthClientPath, + zPostWorkspacesCurrentTriggerProviderByProviderOauthClientResponse, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdBody, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdPath, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdResponse, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreateBody, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreatePath, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreateResponse, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdBody, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdPath, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdResponse, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdBody, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdPath, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdResponse, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdBody, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdPath, + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdResponse, + zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsDeletePath, + zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsDeleteResponse, + zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateBody, + zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdatePath, + zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateResponse, + zPostWorkspacesCustomConfigBody, + zPostWorkspacesCustomConfigResponse, + zPostWorkspacesCustomConfigWebappLogoUploadResponse, + zPostWorkspacesInfoBody, + zPostWorkspacesInfoResponse, + zPostWorkspacesSwitchBody, + zPostWorkspacesSwitchResponse, + zPutWorkspacesCurrentMembersByMemberIdUpdateRoleBody, + zPutWorkspacesCurrentMembersByMemberIdUpdateRolePath, + zPutWorkspacesCurrentMembersByMemberIdUpdateRoleResponse, + zPutWorkspacesCurrentModelProvidersByProviderCredentialsBody, + zPutWorkspacesCurrentModelProvidersByProviderCredentialsPath, + zPutWorkspacesCurrentModelProvidersByProviderCredentialsResponse, + zPutWorkspacesCurrentModelProvidersByProviderModelsCredentialsBody, + zPutWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath, + zPutWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse, + zPutWorkspacesCurrentToolProviderMcpBody, + zPutWorkspacesCurrentToolProviderMcpResponse, +} from './zod.gen' + +/** + * Get specific agent provider details + */ +export const get = oc + .route({ + description: 'Get specific agent provider details', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentAgentProviderByProviderName', + path: '/workspaces/current/agent-provider/{provider_name}', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentAgentProviderByProviderNamePath })) + .output(zGetWorkspacesCurrentAgentProviderByProviderNameResponse) + +export const byProviderName = { + get, +} + +export const agentProvider = { + byProviderName, +} + +/** + * Get list of available agent providers + */ +export const get2 = oc + .route({ + description: 'Get list of available agent providers', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentAgentProviders', + path: '/workspaces/current/agent-providers', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentAgentProvidersResponse) + +export const agentProviders = { + get: get2, +} + +export const get3 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentDatasetOperators', + path: '/workspaces/current/dataset-operators', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentDatasetOperatorsResponse) + +export const datasetOperators = { + get: get3, +} + +export const get4 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentDefaultModel', + path: '/workspaces/current/default-model', + tags: ['console'], + }) + .input(z.object({ query: zGetWorkspacesCurrentDefaultModelQuery })) + .output(zGetWorkspacesCurrentDefaultModelResponse) + +export const post = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentDefaultModel', + path: '/workspaces/current/default-model', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentDefaultModelBody })) + .output(zPostWorkspacesCurrentDefaultModelResponse) + +export const defaultModel = { + get: get4, + post, +} + +/** + * Deprecated legacy alias for creating a plugin endpoint. Use POST /workspaces/current/endpoints instead. + * + * @deprecated + */ +export const post2 = oc + .route({ + deprecated: true, + description: + 'Deprecated legacy alias for creating a plugin endpoint. Use POST /workspaces/current/endpoints instead.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentEndpointsCreate', + path: '/workspaces/current/endpoints/create', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentEndpointsCreateBody })) + .output(zPostWorkspacesCurrentEndpointsCreateResponse) + +export const create = { + post: post2, +} + +/** + * Deprecated legacy alias for deleting a plugin endpoint. Use DELETE /workspaces/current/endpoints/{id} instead. + * + * @deprecated + */ +export const post3 = oc + .route({ + deprecated: true, + description: + 'Deprecated legacy alias for deleting a plugin endpoint. Use DELETE /workspaces/current/endpoints/{id} instead.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentEndpointsDelete', + path: '/workspaces/current/endpoints/delete', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentEndpointsDeleteBody })) + .output(zPostWorkspacesCurrentEndpointsDeleteResponse) + +export const delete_ = { + post: post3, +} + +/** + * Disable a plugin endpoint + */ +export const post4 = oc + .route({ + description: 'Disable a plugin endpoint', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentEndpointsDisable', + path: '/workspaces/current/endpoints/disable', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentEndpointsDisableBody })) + .output(zPostWorkspacesCurrentEndpointsDisableResponse) + +export const disable = { + post: post4, +} + +/** + * Enable a plugin endpoint + */ +export const post5 = oc + .route({ + description: 'Enable a plugin endpoint', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentEndpointsEnable', + path: '/workspaces/current/endpoints/enable', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentEndpointsEnableBody })) + .output(zPostWorkspacesCurrentEndpointsEnableResponse) + +export const enable = { + post: post5, +} + +/** + * List endpoints for a specific plugin + */ +export const get5 = oc + .route({ + description: 'List endpoints for a specific plugin', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentEndpointsListPlugin', + path: '/workspaces/current/endpoints/list/plugin', + tags: ['console'], + }) + .input(z.object({ query: zGetWorkspacesCurrentEndpointsListPluginQuery })) + .output(zGetWorkspacesCurrentEndpointsListPluginResponse) + +export const plugin = { + get: get5, +} + +/** + * List plugin endpoints with pagination + */ +export const get6 = oc + .route({ + description: 'List plugin endpoints with pagination', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentEndpointsList', + path: '/workspaces/current/endpoints/list', + tags: ['console'], + }) + .input(z.object({ query: zGetWorkspacesCurrentEndpointsListQuery })) + .output(zGetWorkspacesCurrentEndpointsListResponse) + +export const list = { + get: get6, + plugin, +} + +/** + * Deprecated legacy alias for updating a plugin endpoint. Use PATCH /workspaces/current/endpoints/{id} instead. + * + * @deprecated + */ +export const post6 = oc + .route({ + deprecated: true, + description: + 'Deprecated legacy alias for updating a plugin endpoint. Use PATCH /workspaces/current/endpoints/{id} instead.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentEndpointsUpdate', + path: '/workspaces/current/endpoints/update', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentEndpointsUpdateBody })) + .output(zPostWorkspacesCurrentEndpointsUpdateResponse) + +export const update = { + post: post6, +} + +/** + * Delete a plugin endpoint + */ +export const delete2 = oc + .route({ + description: 'Delete a plugin endpoint', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteWorkspacesCurrentEndpointsById', + path: '/workspaces/current/endpoints/{id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteWorkspacesCurrentEndpointsByIdPath })) + .output(zDeleteWorkspacesCurrentEndpointsByIdResponse) + +/** + * Update a plugin endpoint + */ +export const patch = oc + .route({ + description: 'Update a plugin endpoint', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchWorkspacesCurrentEndpointsById', + path: '/workspaces/current/endpoints/{id}', + tags: ['console'], + }) + .input( + z.object({ + body: zPatchWorkspacesCurrentEndpointsByIdBody, + params: zPatchWorkspacesCurrentEndpointsByIdPath, + }), + ) + .output(zPatchWorkspacesCurrentEndpointsByIdResponse) + +export const byId = { + delete: delete2, + patch, +} + +/** + * Create a new plugin endpoint + */ +export const post7 = oc + .route({ + description: 'Create a new plugin endpoint', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentEndpoints', + path: '/workspaces/current/endpoints', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentEndpointsBody })) + .output(zPostWorkspacesCurrentEndpointsResponse) + +export const endpoints = { + post: post7, + create, + delete: delete_, + disable, + enable, + list, + update, + byId, +} + +export const post8 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentMembersInviteEmail', + path: '/workspaces/current/members/invite-email', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentMembersInviteEmailBody })) + .output(zPostWorkspacesCurrentMembersInviteEmailResponse) + +export const inviteEmail = { + post: post8, +} + +export const post9 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentMembersOwnerTransferCheck', + path: '/workspaces/current/members/owner-transfer-check', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentMembersOwnerTransferCheckBody })) + .output(zPostWorkspacesCurrentMembersOwnerTransferCheckResponse) + +export const ownerTransferCheck = { + post: post9, +} + +export const post10 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentMembersSendOwnerTransferConfirmEmail', + path: '/workspaces/current/members/send-owner-transfer-confirm-email', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentMembersSendOwnerTransferConfirmEmailBody })) + .output(zPostWorkspacesCurrentMembersSendOwnerTransferConfirmEmailResponse) + +export const sendOwnerTransferConfirmEmail = { + post: post10, +} + +export const post11 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentMembersByMemberIdOwnerTransfer', + path: '/workspaces/current/members/{member_id}/owner-transfer', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentMembersByMemberIdOwnerTransferBody, + params: zPostWorkspacesCurrentMembersByMemberIdOwnerTransferPath, + }), + ) + .output(zPostWorkspacesCurrentMembersByMemberIdOwnerTransferResponse) + +export const ownerTransfer = { + post: post11, +} + +export const put = oc + .route({ + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putWorkspacesCurrentMembersByMemberIdUpdateRole', + path: '/workspaces/current/members/{member_id}/update-role', + tags: ['console'], + }) + .input( + z.object({ + body: zPutWorkspacesCurrentMembersByMemberIdUpdateRoleBody, + params: zPutWorkspacesCurrentMembersByMemberIdUpdateRolePath, + }), + ) + .output(zPutWorkspacesCurrentMembersByMemberIdUpdateRoleResponse) + +export const updateRole = { + put, +} + +export const delete3 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteWorkspacesCurrentMembersByMemberId', + path: '/workspaces/current/members/{member_id}', + tags: ['console'], + }) + .input(z.object({ params: zDeleteWorkspacesCurrentMembersByMemberIdPath })) + .output(zDeleteWorkspacesCurrentMembersByMemberIdResponse) + +export const byMemberId = { + delete: delete3, + ownerTransfer, + updateRole, +} + +export const get7 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentMembers', + path: '/workspaces/current/members', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentMembersResponse) + +export const members = { + get: get7, + inviteEmail, + ownerTransferCheck, + sendOwnerTransferConfirmEmail, + byMemberId, +} + +export const get8 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentModelProvidersByProviderCheckoutUrl', + path: '/workspaces/current/model-providers/{provider}/checkout-url', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentModelProvidersByProviderCheckoutUrlPath })) + .output(zGetWorkspacesCurrentModelProvidersByProviderCheckoutUrlResponse) + +export const checkoutUrl = { + get: get8, +} + +export const post12 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentModelProvidersByProviderCredentialsSwitch', + path: '/workspaces/current/model-providers/{provider}/credentials/switch', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchBody, + params: zPostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchPath, + }), + ) + .output(zPostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchResponse) + +export const switch_ = { + post: post12, +} + +export const post13 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentModelProvidersByProviderCredentialsValidate', + path: '/workspaces/current/model-providers/{provider}/credentials/validate', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentModelProvidersByProviderCredentialsValidateBody, + params: zPostWorkspacesCurrentModelProvidersByProviderCredentialsValidatePath, + }), + ) + .output(zPostWorkspacesCurrentModelProvidersByProviderCredentialsValidateResponse) + +export const validate = { + post: post13, +} + +export const delete4 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteWorkspacesCurrentModelProvidersByProviderCredentials', + path: '/workspaces/current/model-providers/{provider}/credentials', + tags: ['console'], + }) + .input( + z.object({ + body: zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsBody, + params: zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsPath, + }), + ) + .output(zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponse) + +export const get9 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentModelProvidersByProviderCredentials', + path: '/workspaces/current/model-providers/{provider}/credentials', + tags: ['console'], + }) + .input( + z.object({ + params: zGetWorkspacesCurrentModelProvidersByProviderCredentialsPath, + query: zGetWorkspacesCurrentModelProvidersByProviderCredentialsQuery.optional(), + }), + ) + .output(zGetWorkspacesCurrentModelProvidersByProviderCredentialsResponse) + +export const post14 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentModelProvidersByProviderCredentials', + path: '/workspaces/current/model-providers/{provider}/credentials', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentModelProvidersByProviderCredentialsBody, + params: zPostWorkspacesCurrentModelProvidersByProviderCredentialsPath, + }), + ) + .output(zPostWorkspacesCurrentModelProvidersByProviderCredentialsResponse) + +export const put2 = oc + .route({ + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putWorkspacesCurrentModelProvidersByProviderCredentials', + path: '/workspaces/current/model-providers/{provider}/credentials', + tags: ['console'], + }) + .input( + z.object({ + body: zPutWorkspacesCurrentModelProvidersByProviderCredentialsBody, + params: zPutWorkspacesCurrentModelProvidersByProviderCredentialsPath, + }), + ) + .output(zPutWorkspacesCurrentModelProvidersByProviderCredentialsResponse) + +export const credentials = { + delete: delete4, + get: get9, + post: post14, + put: put2, + switch: switch_, + validate, +} + +export const post15 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitch', + path: '/workspaces/current/model-providers/{provider}/models/credentials/switch', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchBody, + params: zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchPath, + }), + ) + .output(zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchResponse) + +export const switch2 = { + post: post15, +} + +export const post16 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidate', + path: '/workspaces/current/model-providers/{provider}/models/credentials/validate', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidateBody, + params: zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidatePath, + }), + ) + .output(zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidateResponse) + +export const validate2 = { + post: post16, +} + +export const delete5 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteWorkspacesCurrentModelProvidersByProviderModelsCredentials', + path: '/workspaces/current/model-providers/{provider}/models/credentials', + tags: ['console'], + }) + .input( + z.object({ + body: zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsBody, + params: zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath, + }), + ) + .output(zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse) + +export const get10 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentModelProvidersByProviderModelsCredentials', + path: '/workspaces/current/model-providers/{provider}/models/credentials', + tags: ['console'], + }) + .input( + z.object({ + params: zGetWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath, + query: zGetWorkspacesCurrentModelProvidersByProviderModelsCredentialsQuery, + }), + ) + .output(zGetWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse) + +export const post17 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentModelProvidersByProviderModelsCredentials', + path: '/workspaces/current/model-providers/{provider}/models/credentials', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsBody, + params: zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath, + }), + ) + .output(zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse) + +export const put3 = oc + .route({ + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putWorkspacesCurrentModelProvidersByProviderModelsCredentials', + path: '/workspaces/current/model-providers/{provider}/models/credentials', + tags: ['console'], + }) + .input( + z.object({ + body: zPutWorkspacesCurrentModelProvidersByProviderModelsCredentialsBody, + params: zPutWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath, + }), + ) + .output(zPutWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse) + +export const credentials2 = { + delete: delete5, + get: get10, + post: post17, + put: put3, + switch: switch2, + validate: validate2, +} + +export const patch2 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchWorkspacesCurrentModelProvidersByProviderModelsDisable', + path: '/workspaces/current/model-providers/{provider}/models/disable', + tags: ['console'], + }) + .input( + z.object({ + body: zPatchWorkspacesCurrentModelProvidersByProviderModelsDisableBody, + params: zPatchWorkspacesCurrentModelProvidersByProviderModelsDisablePath, + }), + ) + .output(zPatchWorkspacesCurrentModelProvidersByProviderModelsDisableResponse) + +export const disable2 = { + patch: patch2, +} + +export const patch3 = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchWorkspacesCurrentModelProvidersByProviderModelsEnable', + path: '/workspaces/current/model-providers/{provider}/models/enable', + tags: ['console'], + }) + .input( + z.object({ + body: zPatchWorkspacesCurrentModelProvidersByProviderModelsEnableBody, + params: zPatchWorkspacesCurrentModelProvidersByProviderModelsEnablePath, + }), + ) + .output(zPatchWorkspacesCurrentModelProvidersByProviderModelsEnableResponse) + +export const enable2 = { + patch: patch3, +} + +export const post18 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: + 'postWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidate', + path: '/workspaces/current/model-providers/{provider}/models/load-balancing-configs/credentials-validate', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidateBody, + params: + zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidatePath, + }), + ) + .output( + zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidateResponse, + ) + +export const credentialsValidate = { + post: post18, +} + +export const post19 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: + 'postWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidate', + path: '/workspaces/current/model-providers/{provider}/models/load-balancing-configs/{config_id}/credentials-validate', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidateBody, + params: + zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidatePath, + }), + ) + .output( + zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidateResponse, + ) + +export const credentialsValidate2 = { + post: post19, +} + +export const byConfigId = { + credentialsValidate: credentialsValidate2, +} + +export const loadBalancingConfigs = { + credentialsValidate, + byConfigId, +} + +export const get11 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentModelProvidersByProviderModelsParameterRules', + path: '/workspaces/current/model-providers/{provider}/models/parameter-rules', + tags: ['console'], + }) + .input( + z.object({ + params: zGetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesPath, + query: zGetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesQuery, + }), + ) + .output(zGetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesResponse) + +export const parameterRules = { + get: get11, +} + +export const delete6 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteWorkspacesCurrentModelProvidersByProviderModels', + path: '/workspaces/current/model-providers/{provider}/models', + tags: ['console'], + }) + .input( + z.object({ + body: zDeleteWorkspacesCurrentModelProvidersByProviderModelsBody, + params: zDeleteWorkspacesCurrentModelProvidersByProviderModelsPath, + }), + ) + .output(zDeleteWorkspacesCurrentModelProvidersByProviderModelsResponse) + +export const get12 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentModelProvidersByProviderModels', + path: '/workspaces/current/model-providers/{provider}/models', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentModelProvidersByProviderModelsPath })) + .output(zGetWorkspacesCurrentModelProvidersByProviderModelsResponse) + +export const post20 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentModelProvidersByProviderModels', + path: '/workspaces/current/model-providers/{provider}/models', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentModelProvidersByProviderModelsBody, + params: zPostWorkspacesCurrentModelProvidersByProviderModelsPath, + }), + ) + .output(zPostWorkspacesCurrentModelProvidersByProviderModelsResponse) + +export const models = { + delete: delete6, + get: get12, + post: post20, + credentials: credentials2, + disable: disable2, + enable: enable2, + loadBalancingConfigs, + parameterRules, +} + +export const post21 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentModelProvidersByProviderPreferredProviderType', + path: '/workspaces/current/model-providers/{provider}/preferred-provider-type', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypeBody, + params: zPostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypePath, + }), + ) + .output(zPostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypeResponse) + +export const preferredProviderType = { + post: post21, +} + +export const byProvider = { + checkoutUrl, + credentials, + models, + preferredProviderType, +} + +export const get13 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentModelProviders', + path: '/workspaces/current/model-providers', + tags: ['console'], + }) + .input(z.object({ query: zGetWorkspacesCurrentModelProvidersQuery.optional() })) + .output(zGetWorkspacesCurrentModelProvidersResponse) + +export const modelProviders = { + get: get13, + byProvider, +} + +export const get14 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentModelsModelTypesByModelType', + path: '/workspaces/current/models/model-types/{model_type}', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentModelsModelTypesByModelTypePath })) + .output(zGetWorkspacesCurrentModelsModelTypesByModelTypeResponse) + +export const byModelType = { + get: get14, +} + +export const modelTypes = { + byModelType, +} + +export const models2 = { + modelTypes, +} + +/** + * Get workspace permission settings + * + * Returns permission flags that control workspace features like member invitations and owner transfer. + */ +export const get15 = oc + .route({ + description: + 'Returns permission flags that control workspace features like member invitations and owner transfer.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPermission', + path: '/workspaces/current/permission', + summary: 'Get workspace permission settings', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentPermissionResponse) + +export const permission = { + get: get15, +} + +export const get16 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPluginAsset', + path: '/workspaces/current/plugin/asset', + tags: ['console'], + }) + .input(z.object({ query: zGetWorkspacesCurrentPluginAssetQuery })) + .output(zGetWorkspacesCurrentPluginAssetResponse) + +export const asset = { + get: get16, +} + +export const get17 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPluginDebuggingKey', + path: '/workspaces/current/plugin/debugging-key', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentPluginDebuggingKeyResponse) + +export const debuggingKey = { + get: get17, +} + +export const get18 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPluginFetchManifest', + path: '/workspaces/current/plugin/fetch-manifest', + tags: ['console'], + }) + .input(z.object({ query: zGetWorkspacesCurrentPluginFetchManifestQuery })) + .output(zGetWorkspacesCurrentPluginFetchManifestResponse) + +export const fetchManifest = { + get: get18, +} + +export const get19 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPluginIcon', + path: '/workspaces/current/plugin/icon', + tags: ['console'], + }) + .input(z.object({ query: zGetWorkspacesCurrentPluginIconQuery })) + .output(zGetWorkspacesCurrentPluginIconResponse) + +export const icon = { + get: get19, +} + +export const post22 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginInstallGithub', + path: '/workspaces/current/plugin/install/github', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentPluginInstallGithubBody })) + .output(zPostWorkspacesCurrentPluginInstallGithubResponse) + +export const github = { + post: post22, +} + +export const post23 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginInstallMarketplace', + path: '/workspaces/current/plugin/install/marketplace', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentPluginInstallMarketplaceBody })) + .output(zPostWorkspacesCurrentPluginInstallMarketplaceResponse) + +export const marketplace = { + post: post23, +} + +export const post24 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginInstallPkg', + path: '/workspaces/current/plugin/install/pkg', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentPluginInstallPkgBody })) + .output(zPostWorkspacesCurrentPluginInstallPkgResponse) + +export const pkg = { + post: post24, +} + +export const install = { + github, + marketplace, + pkg, +} + +export const post25 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginListInstallationsIds', + path: '/workspaces/current/plugin/list/installations/ids', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentPluginListInstallationsIdsBody })) + .output(zPostWorkspacesCurrentPluginListInstallationsIdsResponse) + +export const ids = { + post: post25, +} + +export const installations = { + ids, +} + +export const post26 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginListLatestVersions', + path: '/workspaces/current/plugin/list/latest-versions', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentPluginListLatestVersionsBody })) + .output(zPostWorkspacesCurrentPluginListLatestVersionsResponse) + +export const latestVersions = { + post: post26, +} + +export const get20 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPluginList', + path: '/workspaces/current/plugin/list', + tags: ['console'], + }) + .input(z.object({ query: zGetWorkspacesCurrentPluginListQuery.optional() })) + .output(zGetWorkspacesCurrentPluginListResponse) + +export const list2 = { + get: get20, + installations, + latestVersions, +} + +export const get21 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPluginMarketplacePkg', + path: '/workspaces/current/plugin/marketplace/pkg', + tags: ['console'], + }) + .input(z.object({ query: zGetWorkspacesCurrentPluginMarketplacePkgQuery })) + .output(zGetWorkspacesCurrentPluginMarketplacePkgResponse) + +export const pkg2 = { + get: get21, +} + +export const marketplace2 = { + pkg: pkg2, +} + +export const get22 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPluginParametersDynamicOptions', + path: '/workspaces/current/plugin/parameters/dynamic-options', + tags: ['console'], + }) + .input(z.object({ query: zGetWorkspacesCurrentPluginParametersDynamicOptionsQuery })) + .output(zGetWorkspacesCurrentPluginParametersDynamicOptionsResponse) + +export const dynamicOptions = { + get: get22, +} + +/** + * Fetch dynamic options using credentials directly (for edit mode) + */ +export const post27 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginParametersDynamicOptionsWithCredentials', + path: '/workspaces/current/plugin/parameters/dynamic-options-with-credentials', + summary: 'Fetch dynamic options using credentials directly (for edit mode)', + tags: ['console'], + }) + .input( + z.object({ body: zPostWorkspacesCurrentPluginParametersDynamicOptionsWithCredentialsBody }), + ) + .output(zPostWorkspacesCurrentPluginParametersDynamicOptionsWithCredentialsResponse) + +export const dynamicOptionsWithCredentials = { + post: post27, +} + +export const parameters = { + dynamicOptions, + dynamicOptionsWithCredentials, +} + +export const post28 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginPermissionChange', + path: '/workspaces/current/plugin/permission/change', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentPluginPermissionChangeBody })) + .output(zPostWorkspacesCurrentPluginPermissionChangeResponse) + +export const change = { + post: post28, +} + +export const get23 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPluginPermissionFetch', + path: '/workspaces/current/plugin/permission/fetch', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentPluginPermissionFetchResponse) + +export const fetch_ = { + get: get23, +} + +export const permission2 = { + change, + fetch: fetch_, +} + +export const post29 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginPreferencesAutoupgradeExclude', + path: '/workspaces/current/plugin/preferences/autoupgrade/exclude', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentPluginPreferencesAutoupgradeExcludeBody })) + .output(zPostWorkspacesCurrentPluginPreferencesAutoupgradeExcludeResponse) + +export const exclude = { + post: post29, +} + +export const autoupgrade = { + exclude, +} + +export const post30 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginPreferencesChange', + path: '/workspaces/current/plugin/preferences/change', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentPluginPreferencesChangeBody })) + .output(zPostWorkspacesCurrentPluginPreferencesChangeResponse) + +export const change2 = { + post: post30, +} + +export const get24 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPluginPreferencesFetch', + path: '/workspaces/current/plugin/preferences/fetch', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentPluginPreferencesFetchResponse) + +export const fetch2 = { + get: get24, +} + +export const preferences = { + autoupgrade, + change: change2, + fetch: fetch2, +} + +export const get25 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPluginReadme', + path: '/workspaces/current/plugin/readme', + tags: ['console'], + }) + .input(z.object({ query: zGetWorkspacesCurrentPluginReadmeQuery })) + .output(zGetWorkspacesCurrentPluginReadmeResponse) + +export const readme = { + get: get25, +} + +export const post31 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginTasksDeleteAll', + path: '/workspaces/current/plugin/tasks/delete_all', + tags: ['console'], + }) + .output(zPostWorkspacesCurrentPluginTasksDeleteAllResponse) + +export const deleteAll = { + post: post31, +} + +export const post32 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginTasksByTaskIdDeleteByIdentifier', + path: '/workspaces/current/plugin/tasks/{task_id}/delete/{identifier}', + tags: ['console'], + }) + .input(z.object({ params: zPostWorkspacesCurrentPluginTasksByTaskIdDeleteByIdentifierPath })) + .output(zPostWorkspacesCurrentPluginTasksByTaskIdDeleteByIdentifierResponse) + +export const byIdentifier = { + post: post32, +} + +export const post33 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginTasksByTaskIdDelete', + path: '/workspaces/current/plugin/tasks/{task_id}/delete', + tags: ['console'], + }) + .input(z.object({ params: zPostWorkspacesCurrentPluginTasksByTaskIdDeletePath })) + .output(zPostWorkspacesCurrentPluginTasksByTaskIdDeleteResponse) + +export const delete7 = { + post: post33, + byIdentifier, +} + +export const get26 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPluginTasksByTaskId', + path: '/workspaces/current/plugin/tasks/{task_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentPluginTasksByTaskIdPath })) + .output(zGetWorkspacesCurrentPluginTasksByTaskIdResponse) + +export const byTaskId = { + get: get26, + delete: delete7, +} + +export const get27 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentPluginTasks', + path: '/workspaces/current/plugin/tasks', + tags: ['console'], + }) + .input(z.object({ query: zGetWorkspacesCurrentPluginTasksQuery.optional() })) + .output(zGetWorkspacesCurrentPluginTasksResponse) + +export const tasks = { + get: get27, + deleteAll, + byTaskId, +} + +export const post34 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginUninstall', + path: '/workspaces/current/plugin/uninstall', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentPluginUninstallBody })) + .output(zPostWorkspacesCurrentPluginUninstallResponse) + +export const uninstall = { + post: post34, +} + +export const post35 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginUpgradeGithub', + path: '/workspaces/current/plugin/upgrade/github', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentPluginUpgradeGithubBody })) + .output(zPostWorkspacesCurrentPluginUpgradeGithubResponse) + +export const github2 = { + post: post35, +} + +export const post36 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginUpgradeMarketplace', + path: '/workspaces/current/plugin/upgrade/marketplace', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentPluginUpgradeMarketplaceBody })) + .output(zPostWorkspacesCurrentPluginUpgradeMarketplaceResponse) + +export const marketplace3 = { + post: post36, +} + +export const upgrade = { + github: github2, + marketplace: marketplace3, +} + +export const post37 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginUploadBundle', + path: '/workspaces/current/plugin/upload/bundle', + tags: ['console'], + }) + .output(zPostWorkspacesCurrentPluginUploadBundleResponse) + +export const bundle = { + post: post37, +} + +export const post38 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginUploadGithub', + path: '/workspaces/current/plugin/upload/github', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentPluginUploadGithubBody })) + .output(zPostWorkspacesCurrentPluginUploadGithubResponse) + +export const github3 = { + post: post38, +} + +export const post39 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentPluginUploadPkg', + path: '/workspaces/current/plugin/upload/pkg', + tags: ['console'], + }) + .output(zPostWorkspacesCurrentPluginUploadPkgResponse) + +export const pkg3 = { + post: post39, +} + +export const upload = { + bundle, + github: github3, + pkg: pkg3, +} + +export const plugin2 = { + asset, + debuggingKey, + fetchManifest, + icon, + install, + list: list2, + marketplace: marketplace2, + parameters, + permission: permission2, + preferences, + readme, + tasks, + uninstall, + upgrade, + upload, +} + +export const get28 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolLabels', + path: '/workspaces/current/tool-labels', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentToolLabelsResponse) + +export const toolLabels = { + get: get28, +} + +export const post40 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderApiAdd', + path: '/workspaces/current/tool-provider/api/add', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentToolProviderApiAddBody })) + .output(zPostWorkspacesCurrentToolProviderApiAddResponse) + +export const add = { + post: post40, +} + +export const post41 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderApiDelete', + path: '/workspaces/current/tool-provider/api/delete', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentToolProviderApiDeleteBody })) + .output(zPostWorkspacesCurrentToolProviderApiDeleteResponse) + +export const delete8 = { + post: post41, +} + +export const get29 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderApiGet', + path: '/workspaces/current/tool-provider/api/get', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentToolProviderApiGetResponse) + +export const get30 = { + get: get29, +} + +export const get31 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderApiRemote', + path: '/workspaces/current/tool-provider/api/remote', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentToolProviderApiRemoteResponse) + +export const remote = { + get: get31, +} + +export const post42 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderApiSchema', + path: '/workspaces/current/tool-provider/api/schema', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentToolProviderApiSchemaBody })) + .output(zPostWorkspacesCurrentToolProviderApiSchemaResponse) + +export const schema = { + post: post42, +} + +export const post43 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderApiTestPre', + path: '/workspaces/current/tool-provider/api/test/pre', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentToolProviderApiTestPreBody })) + .output(zPostWorkspacesCurrentToolProviderApiTestPreResponse) + +export const pre = { + post: post43, +} + +export const test = { + pre, +} + +export const get32 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderApiTools', + path: '/workspaces/current/tool-provider/api/tools', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentToolProviderApiToolsResponse) + +export const tools = { + get: get32, +} + +export const post44 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderApiUpdate', + path: '/workspaces/current/tool-provider/api/update', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentToolProviderApiUpdateBody })) + .output(zPostWorkspacesCurrentToolProviderApiUpdateResponse) + +export const update2 = { + post: post44, +} + +export const api = { + add, + delete: delete8, + get: get30, + remote, + schema, + test, + tools, + update: update2, +} + +export const post45 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderBuiltinByProviderAdd', + path: '/workspaces/current/tool-provider/builtin/{provider}/add', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentToolProviderBuiltinByProviderAddBody, + params: zPostWorkspacesCurrentToolProviderBuiltinByProviderAddPath, + }), + ) + .output(zPostWorkspacesCurrentToolProviderBuiltinByProviderAddResponse) + +export const add2 = { + post: post45, +} + +export const get33 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfo', + path: '/workspaces/current/tool-provider/builtin/{provider}/credential/info', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoPath })) + .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoResponse) + +export const info = { + get: get33, +} + +export const get34 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: + 'getWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialType', + path: '/workspaces/current/tool-provider/builtin/{provider}/credential/schema/{credential_type}', + tags: ['console'], + }) + .input( + z.object({ + params: + zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypePath, + }), + ) + .output( + zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypeResponse, + ) + +export const byCredentialType = { + get: get34, +} + +export const schema2 = { + byCredentialType, +} + +export const credential = { + info, + schema: schema2, +} + +export const get35 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderBuiltinByProviderCredentials', + path: '/workspaces/current/tool-provider/builtin/{provider}/credentials', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsPath })) + .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsResponse) + +export const credentials3 = { + get: get35, +} + +export const post46 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredential', + path: '/workspaces/current/tool-provider/builtin/{provider}/default-credential', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialBody, + params: zPostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialPath, + }), + ) + .output(zPostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialResponse) + +export const defaultCredential = { + post: post46, +} + +export const post47 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderBuiltinByProviderDelete', + path: '/workspaces/current/tool-provider/builtin/{provider}/delete', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentToolProviderBuiltinByProviderDeleteBody, + params: zPostWorkspacesCurrentToolProviderBuiltinByProviderDeletePath, + }), + ) + .output(zPostWorkspacesCurrentToolProviderBuiltinByProviderDeleteResponse) + +export const delete9 = { + post: post47, +} + +export const get36 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderBuiltinByProviderIcon', + path: '/workspaces/current/tool-provider/builtin/{provider}/icon', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentToolProviderBuiltinByProviderIconPath })) + .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderIconResponse) + +export const icon2 = { + get: get36, +} + +export const get37 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderBuiltinByProviderInfo', + path: '/workspaces/current/tool-provider/builtin/{provider}/info', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentToolProviderBuiltinByProviderInfoPath })) + .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderInfoResponse) + +export const info2 = { + get: get37, +} + +export const get38 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchema', + path: '/workspaces/current/tool-provider/builtin/{provider}/oauth/client-schema', + tags: ['console'], + }) + .input( + z.object({ params: zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaPath }), + ) + .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaResponse) + +export const clientSchema = { + get: get38, +} + +export const delete10 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClient', + path: '/workspaces/current/tool-provider/builtin/{provider}/oauth/custom-client', + tags: ['console'], + }) + .input( + z.object({ + params: zDeleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientPath, + }), + ) + .output(zDeleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse) + +export const get39 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClient', + path: '/workspaces/current/tool-provider/builtin/{provider}/oauth/custom-client', + tags: ['console'], + }) + .input( + z.object({ params: zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientPath }), + ) + .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse) + +export const post48 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClient', + path: '/workspaces/current/tool-provider/builtin/{provider}/oauth/custom-client', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientBody, + params: zPostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientPath, + }), + ) + .output(zPostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse) + +export const customClient = { + delete: delete10, + get: get39, + post: post48, +} + +export const oauth = { + clientSchema, + customClient, +} + +export const get40 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderBuiltinByProviderTools', + path: '/workspaces/current/tool-provider/builtin/{provider}/tools', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentToolProviderBuiltinByProviderToolsPath })) + .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderToolsResponse) + +export const tools2 = { + get: get40, +} + +export const post49 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderBuiltinByProviderUpdate', + path: '/workspaces/current/tool-provider/builtin/{provider}/update', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentToolProviderBuiltinByProviderUpdateBody, + params: zPostWorkspacesCurrentToolProviderBuiltinByProviderUpdatePath, + }), + ) + .output(zPostWorkspacesCurrentToolProviderBuiltinByProviderUpdateResponse) + +export const update3 = { + post: post49, +} + +export const byProvider2 = { + add: add2, + credential, + credentials: credentials3, + defaultCredential, + delete: delete9, + icon: icon2, + info: info2, + oauth, + tools: tools2, + update: update3, +} + +export const builtin = { + byProvider: byProvider2, +} + +export const post50 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderMcpAuth', + path: '/workspaces/current/tool-provider/mcp/auth', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentToolProviderMcpAuthBody })) + .output(zPostWorkspacesCurrentToolProviderMcpAuthResponse) + +export const auth = { + post: post50, +} + +export const get41 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderMcpToolsByProviderId', + path: '/workspaces/current/tool-provider/mcp/tools/{provider_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentToolProviderMcpToolsByProviderIdPath })) + .output(zGetWorkspacesCurrentToolProviderMcpToolsByProviderIdResponse) + +export const byProviderId = { + get: get41, +} + +export const tools3 = { + byProviderId, +} + +export const get42 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderMcpUpdateByProviderId', + path: '/workspaces/current/tool-provider/mcp/update/{provider_id}', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentToolProviderMcpUpdateByProviderIdPath })) + .output(zGetWorkspacesCurrentToolProviderMcpUpdateByProviderIdResponse) + +export const byProviderId2 = { + get: get42, +} + +export const update4 = { + byProviderId: byProviderId2, +} + +export const delete11 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteWorkspacesCurrentToolProviderMcp', + path: '/workspaces/current/tool-provider/mcp', + tags: ['console'], + }) + .input(z.object({ body: zDeleteWorkspacesCurrentToolProviderMcpBody })) + .output(zDeleteWorkspacesCurrentToolProviderMcpResponse) + +export const post51 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderMcp', + path: '/workspaces/current/tool-provider/mcp', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentToolProviderMcpBody })) + .output(zPostWorkspacesCurrentToolProviderMcpResponse) + +export const put4 = oc + .route({ + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putWorkspacesCurrentToolProviderMcp', + path: '/workspaces/current/tool-provider/mcp', + tags: ['console'], + }) + .input(z.object({ body: zPutWorkspacesCurrentToolProviderMcpBody })) + .output(zPutWorkspacesCurrentToolProviderMcpResponse) + +export const mcp = { + delete: delete11, + post: post51, + put: put4, + auth, + tools: tools3, + update: update4, +} + +export const post52 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderWorkflowCreate', + path: '/workspaces/current/tool-provider/workflow/create', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentToolProviderWorkflowCreateBody })) + .output(zPostWorkspacesCurrentToolProviderWorkflowCreateResponse) + +export const create2 = { + post: post52, +} + +export const post53 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderWorkflowDelete', + path: '/workspaces/current/tool-provider/workflow/delete', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentToolProviderWorkflowDeleteBody })) + .output(zPostWorkspacesCurrentToolProviderWorkflowDeleteResponse) + +export const delete12 = { + post: post53, +} + +export const get43 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderWorkflowGet', + path: '/workspaces/current/tool-provider/workflow/get', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentToolProviderWorkflowGetResponse) + +export const get44 = { + get: get43, +} + +export const get45 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviderWorkflowTools', + path: '/workspaces/current/tool-provider/workflow/tools', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentToolProviderWorkflowToolsResponse) + +export const tools4 = { + get: get45, +} + +export const post54 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentToolProviderWorkflowUpdate', + path: '/workspaces/current/tool-provider/workflow/update', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCurrentToolProviderWorkflowUpdateBody })) + .output(zPostWorkspacesCurrentToolProviderWorkflowUpdateResponse) + +export const update5 = { + post: post54, +} + +export const workflow = { + create: create2, + delete: delete12, + get: get44, + tools: tools4, + update: update5, +} + +export const toolProvider = { + api, + builtin, + mcp, + workflow, +} + +export const get46 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolProviders', + path: '/workspaces/current/tool-providers', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentToolProvidersResponse) + +export const toolProviders = { + get: get46, +} + +export const get47 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolsApi', + path: '/workspaces/current/tools/api', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentToolsApiResponse) + +export const api2 = { + get: get47, +} + +export const get48 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolsBuiltin', + path: '/workspaces/current/tools/builtin', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentToolsBuiltinResponse) + +export const builtin2 = { + get: get48, +} + +export const get49 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolsMcp', + path: '/workspaces/current/tools/mcp', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentToolsMcpResponse) + +export const mcp2 = { + get: get49, +} + +export const get50 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentToolsWorkflow', + path: '/workspaces/current/tools/workflow', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentToolsWorkflowResponse) + +export const workflow2 = { + get: get50, +} + +export const tools5 = { + api: api2, + builtin: builtin2, + mcp: mcp2, + workflow: workflow2, +} + +export const get51 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentTriggerProviderByProviderIcon', + path: '/workspaces/current/trigger-provider/{provider}/icon', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentTriggerProviderByProviderIconPath })) + .output(zGetWorkspacesCurrentTriggerProviderByProviderIconResponse) + +export const icon3 = { + get: get51, +} + +/** + * Get info for a trigger provider + */ +export const get52 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentTriggerProviderByProviderInfo', + path: '/workspaces/current/trigger-provider/{provider}/info', + summary: 'Get info for a trigger provider', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentTriggerProviderByProviderInfoPath })) + .output(zGetWorkspacesCurrentTriggerProviderByProviderInfoResponse) + +export const info3 = { + get: get52, +} + +/** + * Remove custom OAuth client configuration + */ +export const delete13 = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteWorkspacesCurrentTriggerProviderByProviderOauthClient', + path: '/workspaces/current/trigger-provider/{provider}/oauth/client', + summary: 'Remove custom OAuth client configuration', + tags: ['console'], + }) + .input(z.object({ params: zDeleteWorkspacesCurrentTriggerProviderByProviderOauthClientPath })) + .output(zDeleteWorkspacesCurrentTriggerProviderByProviderOauthClientResponse) + +/** + * Get OAuth client configuration for a provider + */ +export const get53 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentTriggerProviderByProviderOauthClient', + path: '/workspaces/current/trigger-provider/{provider}/oauth/client', + summary: 'Get OAuth client configuration for a provider', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentTriggerProviderByProviderOauthClientPath })) + .output(zGetWorkspacesCurrentTriggerProviderByProviderOauthClientResponse) + +/** + * Configure custom OAuth client for a provider + */ +export const post55 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentTriggerProviderByProviderOauthClient', + path: '/workspaces/current/trigger-provider/{provider}/oauth/client', + summary: 'Configure custom OAuth client for a provider', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentTriggerProviderByProviderOauthClientBody, + params: zPostWorkspacesCurrentTriggerProviderByProviderOauthClientPath, + }), + ) + .output(zPostWorkspacesCurrentTriggerProviderByProviderOauthClientResponse) + +export const client = { + delete: delete13, + get: get53, + post: post55, +} + +export const oauth2 = { + client, +} + +/** + * Build a subscription instance for a trigger provider + */ +export const post56 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: + 'postWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderId', + path: '/workspaces/current/trigger-provider/{provider}/subscriptions/builder/build/{subscription_builder_id}', + summary: 'Build a subscription instance for a trigger provider', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdBody, + params: + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdPath, + }), + ) + .output( + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdResponse, + ) + +export const bySubscriptionBuilderId = { + post: post56, +} + +export const build = { + bySubscriptionBuilderId, +} + +/** + * Add a new subscription instance for a trigger provider + */ +export const post57 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreate', + path: '/workspaces/current/trigger-provider/{provider}/subscriptions/builder/create', + summary: 'Add a new subscription instance for a trigger provider', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreateBody, + params: zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreatePath, + }), + ) + .output(zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreateResponse) + +export const create3 = { + post: post57, +} + +/** + * Get the request logs for a subscription instance for a trigger provider + */ +export const get54 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: + 'getWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderLogsBySubscriptionBuilderId', + path: '/workspaces/current/trigger-provider/{provider}/subscriptions/builder/logs/{subscription_builder_id}', + summary: 'Get the request logs for a subscription instance for a trigger provider', + tags: ['console'], + }) + .input( + z.object({ + params: + zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderLogsBySubscriptionBuilderIdPath, + }), + ) + .output( + zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderLogsBySubscriptionBuilderIdResponse, + ) + +export const bySubscriptionBuilderId2 = { + get: get54, +} + +export const logs = { + bySubscriptionBuilderId: bySubscriptionBuilderId2, +} + +/** + * Update a subscription instance for a trigger provider + */ +export const post58 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: + 'postWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderId', + path: '/workspaces/current/trigger-provider/{provider}/subscriptions/builder/update/{subscription_builder_id}', + summary: 'Update a subscription instance for a trigger provider', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdBody, + params: + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdPath, + }), + ) + .output( + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdResponse, + ) + +export const bySubscriptionBuilderId3 = { + post: post58, +} + +export const update6 = { + bySubscriptionBuilderId: bySubscriptionBuilderId3, +} + +/** + * Verify and update a subscription instance for a trigger provider + */ +export const post59 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: + 'postWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderId', + path: '/workspaces/current/trigger-provider/{provider}/subscriptions/builder/verify-and-update/{subscription_builder_id}', + summary: 'Verify and update a subscription instance for a trigger provider', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdBody, + params: + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdPath, + }), + ) + .output( + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdResponse, + ) + +export const bySubscriptionBuilderId4 = { + post: post59, +} + +export const verifyAndUpdate = { + bySubscriptionBuilderId: bySubscriptionBuilderId4, +} + +/** + * Get a subscription instance for a trigger provider + */ +export const get55 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: + 'getWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBySubscriptionBuilderId', + path: '/workspaces/current/trigger-provider/{provider}/subscriptions/builder/{subscription_builder_id}', + summary: 'Get a subscription instance for a trigger provider', + tags: ['console'], + }) + .input( + z.object({ + params: + zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBySubscriptionBuilderIdPath, + }), + ) + .output( + zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBySubscriptionBuilderIdResponse, + ) + +export const bySubscriptionBuilderId5 = { + get: get55, +} + +export const builder = { + build, + create: create3, + logs, + update: update6, + verifyAndUpdate, + bySubscriptionBuilderId: bySubscriptionBuilderId5, +} + +/** + * List all trigger subscriptions for the current tenant's provider + */ +export const get56 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentTriggerProviderByProviderSubscriptionsList', + path: '/workspaces/current/trigger-provider/{provider}/subscriptions/list', + summary: 'List all trigger subscriptions for the current tenant\'s provider', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListPath })) + .output(zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListResponse) + +export const list3 = { + get: get56, +} + +/** + * Initiate OAuth authorization flow for a trigger provider + */ +export const get57 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorize', + path: '/workspaces/current/trigger-provider/{provider}/subscriptions/oauth/authorize', + summary: 'Initiate OAuth authorization flow for a trigger provider', + tags: ['console'], + }) + .input( + z.object({ + params: zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorizePath, + }), + ) + .output(zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorizeResponse) + +export const authorize = { + get: get57, +} + +export const oauth3 = { + authorize, +} + +/** + * Verify credentials for an existing subscription (edit mode only) + */ +export const post60 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: + 'postWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionId', + path: '/workspaces/current/trigger-provider/{provider}/subscriptions/verify/{subscription_id}', + summary: 'Verify credentials for an existing subscription (edit mode only)', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdBody, + params: + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdPath, + }), + ) + .output( + zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdResponse, + ) + +export const bySubscriptionId = { + post: post60, +} + +export const verify = { + bySubscriptionId, +} + +export const subscriptions = { + builder, + list: list3, + oauth: oauth3, + verify, +} + +export const byProvider3 = { + icon: icon3, + info: info3, + oauth: oauth2, + subscriptions, +} + +/** + * Delete a subscription instance + */ +export const post61 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsDelete', + path: '/workspaces/current/trigger-provider/{subscription_id}/subscriptions/delete', + summary: 'Delete a subscription instance', + tags: ['console'], + }) + .input( + z.object({ + params: zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsDeletePath, + }), + ) + .output(zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsDeleteResponse) + +export const delete14 = { + post: post61, +} + +/** + * Update a subscription instance + */ +export const post62 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdate', + path: '/workspaces/current/trigger-provider/{subscription_id}/subscriptions/update', + summary: 'Update a subscription instance', + tags: ['console'], + }) + .input( + z.object({ + body: zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateBody, + params: zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdatePath, + }), + ) + .output(zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateResponse) + +export const update7 = { + post: post62, +} + +export const subscriptions2 = { + delete: delete14, + update: update7, +} + +export const bySubscriptionId2 = { + subscriptions: subscriptions2, +} + +export const triggerProvider = { + byProvider: byProvider3, + bySubscriptionId: bySubscriptionId2, +} + +/** + * List all trigger providers for the current tenant + */ +export const get58 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentTriggers', + path: '/workspaces/current/triggers', + summary: 'List all trigger providers for the current tenant', + tags: ['console'], + }) + .output(zGetWorkspacesCurrentTriggersResponse) + +export const triggers = { + get: get58, +} + +export const post63 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCurrent', + path: '/workspaces/current', + tags: ['console'], + }) + .output(zPostWorkspacesCurrentResponse) + +export const current = { + post: post63, + agentProvider, + agentProviders, + datasetOperators, + defaultModel, + endpoints, + members, + modelProviders, + models: models2, + permission, + plugin: plugin2, + toolLabels, + toolProvider, + toolProviders, + tools: tools5, + triggerProvider, + triggers, +} + +export const post64 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCustomConfigWebappLogoUpload', + path: '/workspaces/custom-config/webapp-logo/upload', + tags: ['console'], + }) + .output(zPostWorkspacesCustomConfigWebappLogoUploadResponse) + +export const upload2 = { + post: post64, +} + +export const webappLogo = { + upload: upload2, +} + +export const post65 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesCustomConfig', + path: '/workspaces/custom-config', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesCustomConfigBody })) + .output(zPostWorkspacesCustomConfigResponse) + +export const customConfig = { + post: post65, + webappLogo, +} + +export const post66 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesInfo', + path: '/workspaces/info', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesInfoBody })) + .output(zPostWorkspacesInfoResponse) + +export const info4 = { + post: post66, +} + +export const post67 = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkspacesSwitch', + path: '/workspaces/switch', + tags: ['console'], + }) + .input(z.object({ body: zPostWorkspacesSwitchBody })) + .output(zPostWorkspacesSwitchResponse) + +export const switch3 = { + post: post67, +} + +export const get59 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLang', + path: '/workspaces/{tenant_id}/model-providers/{provider}/{icon_type}/{lang}', + tags: ['console'], + }) + .input(z.object({ params: zGetWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLangPath })) + .output(zGetWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLangResponse) + +export const byLang = { + get: get59, +} + +export const byIconType = { + byLang, +} + +export const byProvider4 = { + byIconType, +} + +export const modelProviders2 = { + byProvider: byProvider4, +} + +export const byTenantId = { + modelProviders: modelProviders2, +} + +export const get60 = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspaces', + path: '/workspaces', + tags: ['console'], + }) + .output(zGetWorkspacesResponse) + +export const workspaces = { + get: get60, + current, + customConfig, + info: info4, + switch: switch3, + byTenantId, +} + +export const contract = { + workspaces, +} diff --git a/packages/contracts/generated/api/console/workspaces/types.gen.ts b/packages/contracts/generated/api/console/workspaces/types.gen.ts new file mode 100644 index 0000000000..a90db98f22 --- /dev/null +++ b/packages/contracts/generated/api/console/workspaces/types.gen.ts @@ -0,0 +1,3023 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/console/api` | (string & {}) +} + +export type TenantInfoResponse = { + created_at?: number | null + custom_config?: { + [key: string]: unknown + } | null + id: string + in_trial?: boolean | null + name?: string | null + next_credit_reset_date?: number | null + plan?: string | null + role?: string | null + status?: string | null + trial_credits?: number | null + trial_credits_used?: number | null + trial_end_reason?: string | null +} + +export type AccountWithRoleList = { + accounts: Array +} + +export type ParserPostDefault = { + model_settings: Array +} + +export type EndpointCreatePayload = { + name: string + plugin_unique_identifier: string + settings: { + [key: string]: unknown + } +} + +export type EndpointCreateResponse = { + success: boolean +} + +export type EndpointIdPayload = { + endpoint_id: string +} + +export type EndpointDeleteResponse = { + success: boolean +} + +export type EndpointDisableResponse = { + success: boolean +} + +export type EndpointEnableResponse = { + success: boolean +} + +export type EndpointListResponse = { + endpoints: Array<{ + [key: string]: unknown + }> +} + +export type PluginEndpointListResponse = { + endpoints: Array<{ + [key: string]: unknown + }> +} + +export type LegacyEndpointUpdatePayload = { + endpoint_id: string + name: string + settings: { + [key: string]: unknown + } +} + +export type EndpointUpdateResponse = { + success: boolean +} + +export type EndpointUpdatePayload = { + name: string + settings: { + [key: string]: unknown + } +} + +export type MemberInvitePayload = { + emails?: Array + language?: string | null + role: TenantAccountRole +} + +export type OwnerTransferCheckPayload = { + code: string + token: string +} + +export type OwnerTransferEmailPayload = { + language?: string | null +} + +export type OwnerTransferPayload = { + token: string +} + +export type MemberRoleUpdatePayload = { + role: string +} + +export type ParserCredentialDelete = { + credential_id: string +} + +export type ParserCredentialCreate = { + credentials: { + [key: string]: unknown + } + name?: string | null +} + +export type ParserCredentialUpdate = { + credential_id: string + credentials: { + [key: string]: unknown + } + name?: string | null +} + +export type ParserCredentialSwitch = { + credential_id: string +} + +export type ParserCredentialValidate = { + credentials: { + [key: string]: unknown + } +} + +export type ParserDeleteModels = { + model: string + model_type: ModelType +} + +export type ParserPostModels = { + config_from?: string | null + credential_id?: string | null + load_balancing?: LoadBalancingPayload + model: string + model_type: ModelType +} + +export type ParserDeleteCredential = { + credential_id: string + model: string + model_type: ModelType +} + +export type ParserCreateCredential = { + credentials: { + [key: string]: unknown + } + model: string + model_type: ModelType + name?: string | null +} + +export type ParserUpdateCredential = { + credential_id: string + credentials: { + [key: string]: unknown + } + model: string + model_type: ModelType + name?: string | null +} + +export type ParserSwitch = { + credential_id: string + model: string + model_type: ModelType +} + +export type ParserValidate = { + credentials: { + [key: string]: unknown + } + model: string + model_type: ModelType +} + +export type LoadBalancingCredentialPayload = { + credentials: { + [key: string]: unknown + } + model: string + model_type: ModelType +} + +export type ParserPreferredProviderType = { + preferred_provider_type: 'system' | 'custom' +} + +export type ParserGithubInstall = { + package: string + plugin_unique_identifier: string + repo: string + version: string +} + +export type ParserPluginIdentifiers = { + plugin_unique_identifiers: Array +} + +export type ParserLatest = { + plugin_ids: Array +} + +export type ParserDynamicOptionsWithCredentials = { + action: string + credential_id: string + credentials: { + [key: string]: unknown + } + parameter: string + plugin_id: string + provider: string +} + +export type ParserPermissionChange = { + debug_permission: DebugPermission + install_permission: InstallPermission +} + +export type ParserExcludePlugin = { + plugin_id: string +} + +export type ParserPreferencesChange = { + auto_upgrade: PluginAutoUpgradeSettingsPayload + permission: PluginPermissionSettingsPayload +} + +export type ParserUninstall = { + plugin_installation_id: string +} + +export type ParserGithubUpgrade = { + new_plugin_unique_identifier: string + original_plugin_unique_identifier: string + package: string + repo: string + version: string +} + +export type ParserMarketplaceUpgrade = { + new_plugin_unique_identifier: string + original_plugin_unique_identifier: string +} + +export type ParserGithubUpload = { + package: string + repo: string + version: string +} + +export type ApiToolProviderAddPayload = { + credentials: { + [key: string]: unknown + } + custom_disclaimer?: string + icon: { + [key: string]: unknown + } + labels?: Array | null + privacy_policy?: string | null + provider: string + schema: string + schema_type: ApiProviderSchemaType +} + +export type ApiToolProviderDeletePayload = { + provider: string +} + +export type ApiToolSchemaPayload = { + schema: string +} + +export type ApiToolTestPayload = { + credentials: { + [key: string]: unknown + } + parameters: { + [key: string]: unknown + } + provider_name?: string | null + schema: string + schema_type: ApiProviderSchemaType + tool_name: string +} + +export type ApiToolProviderUpdatePayload = { + credentials: { + [key: string]: unknown + } + custom_disclaimer?: string + icon: { + [key: string]: unknown + } + labels?: Array | null + original_provider: string + privacy_policy?: string | null + provider: string + schema: string + schema_type: ApiProviderSchemaType +} + +export type BuiltinToolAddPayload = { + credentials: { + [key: string]: unknown + } + name?: string | null + type: CredentialType +} + +export type BuiltinProviderDefaultCredentialPayload = { + id: string +} + +export type BuiltinToolCredentialDeletePayload = { + credential_id: string +} + +export type ToolOAuthCustomClientPayload = { + client_params?: { + [key: string]: unknown + } | null + enable_oauth_custom_client?: boolean | null +} + +export type BuiltinToolUpdatePayload = { + credential_id: string + credentials?: { + [key: string]: unknown + } | null + name?: string | null +} + +export type McpProviderDeletePayload = { + provider_id: string +} + +export type McpProviderCreatePayload = { + authentication?: { + [key: string]: unknown + } | null + configuration?: { + [key: string]: unknown + } | null + headers?: { + [key: string]: unknown + } | null + icon: string + icon_background?: string + icon_type: string + name: string + server_identifier: string + server_url: string +} + +export type McpProviderUpdatePayload = { + authentication?: { + [key: string]: unknown + } | null + configuration?: { + [key: string]: unknown + } | null + headers?: { + [key: string]: unknown + } | null + icon: string + icon_background?: string + icon_type: string + name: string + provider_id: string + server_identifier: string + server_url: string +} + +export type McpAuthPayload = { + authorization_code?: string | null + provider_id: string +} + +export type WorkflowToolCreatePayload = { + description: string + icon: { + [key: string]: unknown + } + label: string + labels?: Array | null + name: string + parameters?: Array + privacy_policy?: string | null + workflow_app_id: string +} + +export type WorkflowToolDeletePayload = { + workflow_tool_id: string +} + +export type WorkflowToolUpdatePayload = { + description: string + icon: { + [key: string]: unknown + } + label: string + labels?: Array | null + name: string + parameters?: Array + privacy_policy?: string | null + workflow_tool_id: string +} + +export type TriggerOAuthClientPayload = { + client_params?: { + [key: string]: unknown + } | null + enabled?: boolean | null +} + +export type TriggerSubscriptionBuilderUpdatePayload = { + credentials?: { + [key: string]: unknown + } | null + name?: string | null + parameters?: { + [key: string]: unknown + } | null + properties?: { + [key: string]: unknown + } | null +} + +export type TriggerSubscriptionBuilderCreatePayload = { + credential_type?: string +} + +export type TriggerSubscriptionBuilderVerifyPayload = { + credentials: { + [key: string]: unknown + } +} + +export type WorkspaceCustomConfigPayload = { + remove_webapp_brand?: boolean | null + replace_webapp_logo?: string | null +} + +export type WorkspaceInfoPayload = { + name: string +} + +export type SwitchWorkspacePayload = { + tenant_id: string +} + +export type AccountWithRole = { + avatar?: string | null + created_at?: number | null + email: string + id: string + last_active_at?: number | null + last_login_at?: number | null + name: string + role: string + status: string +} + +export type Inner = { + model?: string | null + model_type: ModelType + provider?: string | null +} + +export type TenantAccountRole = 'owner' | 'admin' | 'editor' | 'normal' | 'dataset_operator' + +export type ModelType = 'llm' | 'text-embedding' | 'rerank' | 'speech2text' | 'moderation' | 'tts' + +export type LoadBalancingPayload = { + configs?: Array<{ + [key: string]: unknown + }> | null + enabled?: boolean | null +} + +export type DebugPermission = 'everyone' | 'admins' | 'noone' + +export type InstallPermission = 'everyone' | 'admins' | 'noone' + +export type PluginAutoUpgradeSettingsPayload = { + exclude_plugins?: Array + include_plugins?: Array + strategy_setting?: StrategySetting + upgrade_mode?: UpgradeMode + upgrade_time_of_day?: number +} + +export type PluginPermissionSettingsPayload = { + debug_permission?: DebugPermission + install_permission?: InstallPermission +} + +export type ApiProviderSchemaType = 'openapi' | 'swagger' | 'openai_plugin' | 'openai_actions' + +export type CredentialType = 'api-key' | 'oauth2' | 'unauthorized' + +export type WorkflowToolParameterConfiguration = { + description: string + form: ToolParameterForm + name: string +} + +export type StrategySetting = 'disabled' | 'fix_only' | 'latest' + +export type UpgradeMode = 'all' | 'partial' | 'exclude' + +export type ToolParameterForm = 'schema' | 'form' | 'llm' + +export type GetWorkspacesData = { + body?: never + path?: never + query?: never + url: '/workspaces' +} + +export type GetWorkspacesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesResponse = GetWorkspacesResponses[keyof GetWorkspacesResponses] + +export type PostWorkspacesCurrentData = { + body?: never + path?: never + query?: never + url: '/workspaces/current' +} + +export type PostWorkspacesCurrentResponses = { + 200: TenantInfoResponse +} + +export type PostWorkspacesCurrentResponse + = PostWorkspacesCurrentResponses[keyof PostWorkspacesCurrentResponses] + +export type GetWorkspacesCurrentAgentProviderByProviderNameData = { + body?: never + path: { + provider_name: string + } + query?: never + url: '/workspaces/current/agent-provider/{provider_name}' +} + +export type GetWorkspacesCurrentAgentProviderByProviderNameResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentAgentProviderByProviderNameResponse + = GetWorkspacesCurrentAgentProviderByProviderNameResponses[keyof GetWorkspacesCurrentAgentProviderByProviderNameResponses] + +export type GetWorkspacesCurrentAgentProvidersData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/agent-providers' +} + +export type GetWorkspacesCurrentAgentProvidersResponses = { + 200: Array<{ + [key: string]: unknown + }> +} + +export type GetWorkspacesCurrentAgentProvidersResponse + = GetWorkspacesCurrentAgentProvidersResponses[keyof GetWorkspacesCurrentAgentProvidersResponses] + +export type GetWorkspacesCurrentDatasetOperatorsData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/dataset-operators' +} + +export type GetWorkspacesCurrentDatasetOperatorsResponses = { + 200: AccountWithRoleList +} + +export type GetWorkspacesCurrentDatasetOperatorsResponse + = GetWorkspacesCurrentDatasetOperatorsResponses[keyof GetWorkspacesCurrentDatasetOperatorsResponses] + +export type GetWorkspacesCurrentDefaultModelData = { + body?: never + path?: never + query: { + model_type: string + } + url: '/workspaces/current/default-model' +} + +export type GetWorkspacesCurrentDefaultModelResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentDefaultModelResponse + = GetWorkspacesCurrentDefaultModelResponses[keyof GetWorkspacesCurrentDefaultModelResponses] + +export type PostWorkspacesCurrentDefaultModelData = { + body: ParserPostDefault + path?: never + query?: never + url: '/workspaces/current/default-model' +} + +export type PostWorkspacesCurrentDefaultModelResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentDefaultModelResponse + = PostWorkspacesCurrentDefaultModelResponses[keyof PostWorkspacesCurrentDefaultModelResponses] + +export type PostWorkspacesCurrentEndpointsData = { + body: EndpointCreatePayload + path?: never + query?: never + url: '/workspaces/current/endpoints' +} + +export type PostWorkspacesCurrentEndpointsErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentEndpointsError + = PostWorkspacesCurrentEndpointsErrors[keyof PostWorkspacesCurrentEndpointsErrors] + +export type PostWorkspacesCurrentEndpointsResponses = { + 200: EndpointCreateResponse +} + +export type PostWorkspacesCurrentEndpointsResponse + = PostWorkspacesCurrentEndpointsResponses[keyof PostWorkspacesCurrentEndpointsResponses] + +export type PostWorkspacesCurrentEndpointsCreateData = { + body: EndpointCreatePayload + path?: never + query?: never + url: '/workspaces/current/endpoints/create' +} + +export type PostWorkspacesCurrentEndpointsCreateErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentEndpointsCreateError + = PostWorkspacesCurrentEndpointsCreateErrors[keyof PostWorkspacesCurrentEndpointsCreateErrors] + +export type PostWorkspacesCurrentEndpointsCreateResponses = { + 200: EndpointCreateResponse +} + +export type PostWorkspacesCurrentEndpointsCreateResponse + = PostWorkspacesCurrentEndpointsCreateResponses[keyof PostWorkspacesCurrentEndpointsCreateResponses] + +export type PostWorkspacesCurrentEndpointsDeleteData = { + body: EndpointIdPayload + path?: never + query?: never + url: '/workspaces/current/endpoints/delete' +} + +export type PostWorkspacesCurrentEndpointsDeleteErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentEndpointsDeleteError + = PostWorkspacesCurrentEndpointsDeleteErrors[keyof PostWorkspacesCurrentEndpointsDeleteErrors] + +export type PostWorkspacesCurrentEndpointsDeleteResponses = { + 200: EndpointDeleteResponse +} + +export type PostWorkspacesCurrentEndpointsDeleteResponse + = PostWorkspacesCurrentEndpointsDeleteResponses[keyof PostWorkspacesCurrentEndpointsDeleteResponses] + +export type PostWorkspacesCurrentEndpointsDisableData = { + body: EndpointIdPayload + path?: never + query?: never + url: '/workspaces/current/endpoints/disable' +} + +export type PostWorkspacesCurrentEndpointsDisableErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentEndpointsDisableError + = PostWorkspacesCurrentEndpointsDisableErrors[keyof PostWorkspacesCurrentEndpointsDisableErrors] + +export type PostWorkspacesCurrentEndpointsDisableResponses = { + 200: EndpointDisableResponse +} + +export type PostWorkspacesCurrentEndpointsDisableResponse + = PostWorkspacesCurrentEndpointsDisableResponses[keyof PostWorkspacesCurrentEndpointsDisableResponses] + +export type PostWorkspacesCurrentEndpointsEnableData = { + body: EndpointIdPayload + path?: never + query?: never + url: '/workspaces/current/endpoints/enable' +} + +export type PostWorkspacesCurrentEndpointsEnableErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentEndpointsEnableError + = PostWorkspacesCurrentEndpointsEnableErrors[keyof PostWorkspacesCurrentEndpointsEnableErrors] + +export type PostWorkspacesCurrentEndpointsEnableResponses = { + 200: EndpointEnableResponse +} + +export type PostWorkspacesCurrentEndpointsEnableResponse + = PostWorkspacesCurrentEndpointsEnableResponses[keyof PostWorkspacesCurrentEndpointsEnableResponses] + +export type GetWorkspacesCurrentEndpointsListData = { + body?: never + path?: never + query: { + page: number + page_size: number + } + url: '/workspaces/current/endpoints/list' +} + +export type GetWorkspacesCurrentEndpointsListResponses = { + 200: EndpointListResponse +} + +export type GetWorkspacesCurrentEndpointsListResponse + = GetWorkspacesCurrentEndpointsListResponses[keyof GetWorkspacesCurrentEndpointsListResponses] + +export type GetWorkspacesCurrentEndpointsListPluginData = { + body?: never + path?: never + query: { + page: number + page_size: number + plugin_id: string + } + url: '/workspaces/current/endpoints/list/plugin' +} + +export type GetWorkspacesCurrentEndpointsListPluginResponses = { + 200: PluginEndpointListResponse +} + +export type GetWorkspacesCurrentEndpointsListPluginResponse + = GetWorkspacesCurrentEndpointsListPluginResponses[keyof GetWorkspacesCurrentEndpointsListPluginResponses] + +export type PostWorkspacesCurrentEndpointsUpdateData = { + body: LegacyEndpointUpdatePayload + path?: never + query?: never + url: '/workspaces/current/endpoints/update' +} + +export type PostWorkspacesCurrentEndpointsUpdateErrors = { + 403: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentEndpointsUpdateError + = PostWorkspacesCurrentEndpointsUpdateErrors[keyof PostWorkspacesCurrentEndpointsUpdateErrors] + +export type PostWorkspacesCurrentEndpointsUpdateResponses = { + 200: EndpointUpdateResponse +} + +export type PostWorkspacesCurrentEndpointsUpdateResponse + = PostWorkspacesCurrentEndpointsUpdateResponses[keyof PostWorkspacesCurrentEndpointsUpdateResponses] + +export type DeleteWorkspacesCurrentEndpointsByIdData = { + body?: never + path: { + id: string + } + query?: never + url: '/workspaces/current/endpoints/{id}' +} + +export type DeleteWorkspacesCurrentEndpointsByIdErrors = { + 403: { + [key: string]: unknown + } +} + +export type DeleteWorkspacesCurrentEndpointsByIdError + = DeleteWorkspacesCurrentEndpointsByIdErrors[keyof DeleteWorkspacesCurrentEndpointsByIdErrors] + +export type DeleteWorkspacesCurrentEndpointsByIdResponses = { + 200: EndpointDeleteResponse +} + +export type DeleteWorkspacesCurrentEndpointsByIdResponse + = DeleteWorkspacesCurrentEndpointsByIdResponses[keyof DeleteWorkspacesCurrentEndpointsByIdResponses] + +export type PatchWorkspacesCurrentEndpointsByIdData = { + body: EndpointUpdatePayload + path: { + id: string + } + query?: never + url: '/workspaces/current/endpoints/{id}' +} + +export type PatchWorkspacesCurrentEndpointsByIdErrors = { + 403: { + [key: string]: unknown + } +} + +export type PatchWorkspacesCurrentEndpointsByIdError + = PatchWorkspacesCurrentEndpointsByIdErrors[keyof PatchWorkspacesCurrentEndpointsByIdErrors] + +export type PatchWorkspacesCurrentEndpointsByIdResponses = { + 200: EndpointUpdateResponse +} + +export type PatchWorkspacesCurrentEndpointsByIdResponse + = PatchWorkspacesCurrentEndpointsByIdResponses[keyof PatchWorkspacesCurrentEndpointsByIdResponses] + +export type GetWorkspacesCurrentMembersData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/members' +} + +export type GetWorkspacesCurrentMembersResponses = { + 200: AccountWithRoleList +} + +export type GetWorkspacesCurrentMembersResponse + = GetWorkspacesCurrentMembersResponses[keyof GetWorkspacesCurrentMembersResponses] + +export type PostWorkspacesCurrentMembersInviteEmailData = { + body: MemberInvitePayload + path?: never + query?: never + url: '/workspaces/current/members/invite-email' +} + +export type PostWorkspacesCurrentMembersInviteEmailResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentMembersInviteEmailResponse + = PostWorkspacesCurrentMembersInviteEmailResponses[keyof PostWorkspacesCurrentMembersInviteEmailResponses] + +export type PostWorkspacesCurrentMembersOwnerTransferCheckData = { + body: OwnerTransferCheckPayload + path?: never + query?: never + url: '/workspaces/current/members/owner-transfer-check' +} + +export type PostWorkspacesCurrentMembersOwnerTransferCheckResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentMembersOwnerTransferCheckResponse + = PostWorkspacesCurrentMembersOwnerTransferCheckResponses[keyof PostWorkspacesCurrentMembersOwnerTransferCheckResponses] + +export type PostWorkspacesCurrentMembersSendOwnerTransferConfirmEmailData = { + body: OwnerTransferEmailPayload + path?: never + query?: never + url: '/workspaces/current/members/send-owner-transfer-confirm-email' +} + +export type PostWorkspacesCurrentMembersSendOwnerTransferConfirmEmailResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentMembersSendOwnerTransferConfirmEmailResponse + = PostWorkspacesCurrentMembersSendOwnerTransferConfirmEmailResponses[keyof PostWorkspacesCurrentMembersSendOwnerTransferConfirmEmailResponses] + +export type DeleteWorkspacesCurrentMembersByMemberIdData = { + body?: never + path: { + member_id: string + } + query?: never + url: '/workspaces/current/members/{member_id}' +} + +export type DeleteWorkspacesCurrentMembersByMemberIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteWorkspacesCurrentMembersByMemberIdResponse + = DeleteWorkspacesCurrentMembersByMemberIdResponses[keyof DeleteWorkspacesCurrentMembersByMemberIdResponses] + +export type PostWorkspacesCurrentMembersByMemberIdOwnerTransferData = { + body: OwnerTransferPayload + path: { + member_id: string + } + query?: never + url: '/workspaces/current/members/{member_id}/owner-transfer' +} + +export type PostWorkspacesCurrentMembersByMemberIdOwnerTransferResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentMembersByMemberIdOwnerTransferResponse + = PostWorkspacesCurrentMembersByMemberIdOwnerTransferResponses[keyof PostWorkspacesCurrentMembersByMemberIdOwnerTransferResponses] + +export type PutWorkspacesCurrentMembersByMemberIdUpdateRoleData = { + body: MemberRoleUpdatePayload + path: { + member_id: string + } + query?: never + url: '/workspaces/current/members/{member_id}/update-role' +} + +export type PutWorkspacesCurrentMembersByMemberIdUpdateRoleResponses = { + 200: { + [key: string]: unknown + } +} + +export type PutWorkspacesCurrentMembersByMemberIdUpdateRoleResponse + = PutWorkspacesCurrentMembersByMemberIdUpdateRoleResponses[keyof PutWorkspacesCurrentMembersByMemberIdUpdateRoleResponses] + +export type GetWorkspacesCurrentModelProvidersData = { + body?: never + path?: never + query?: { + model_type?: string | null + } + url: '/workspaces/current/model-providers' +} + +export type GetWorkspacesCurrentModelProvidersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentModelProvidersResponse + = GetWorkspacesCurrentModelProvidersResponses[keyof GetWorkspacesCurrentModelProvidersResponses] + +export type GetWorkspacesCurrentModelProvidersByProviderCheckoutUrlData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/checkout-url' +} + +export type GetWorkspacesCurrentModelProvidersByProviderCheckoutUrlResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentModelProvidersByProviderCheckoutUrlResponse + = GetWorkspacesCurrentModelProvidersByProviderCheckoutUrlResponses[keyof GetWorkspacesCurrentModelProvidersByProviderCheckoutUrlResponses] + +export type DeleteWorkspacesCurrentModelProvidersByProviderCredentialsData = { + body: ParserCredentialDelete + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/credentials' +} + +export type DeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponse + = DeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponses[keyof DeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponses] + +export type GetWorkspacesCurrentModelProvidersByProviderCredentialsData = { + body?: never + path: { + provider: string + } + query?: { + credential_id?: string | null + } + url: '/workspaces/current/model-providers/{provider}/credentials' +} + +export type GetWorkspacesCurrentModelProvidersByProviderCredentialsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentModelProvidersByProviderCredentialsResponse + = GetWorkspacesCurrentModelProvidersByProviderCredentialsResponses[keyof GetWorkspacesCurrentModelProvidersByProviderCredentialsResponses] + +export type PostWorkspacesCurrentModelProvidersByProviderCredentialsData = { + body: ParserCredentialCreate + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/credentials' +} + +export type PostWorkspacesCurrentModelProvidersByProviderCredentialsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentModelProvidersByProviderCredentialsResponse + = PostWorkspacesCurrentModelProvidersByProviderCredentialsResponses[keyof PostWorkspacesCurrentModelProvidersByProviderCredentialsResponses] + +export type PutWorkspacesCurrentModelProvidersByProviderCredentialsData = { + body: ParserCredentialUpdate + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/credentials' +} + +export type PutWorkspacesCurrentModelProvidersByProviderCredentialsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PutWorkspacesCurrentModelProvidersByProviderCredentialsResponse + = PutWorkspacesCurrentModelProvidersByProviderCredentialsResponses[keyof PutWorkspacesCurrentModelProvidersByProviderCredentialsResponses] + +export type PostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchData = { + body: ParserCredentialSwitch + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/credentials/switch' +} + +export type PostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchResponse + = PostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchResponses[keyof PostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchResponses] + +export type PostWorkspacesCurrentModelProvidersByProviderCredentialsValidateData = { + body: ParserCredentialValidate + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/credentials/validate' +} + +export type PostWorkspacesCurrentModelProvidersByProviderCredentialsValidateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentModelProvidersByProviderCredentialsValidateResponse + = PostWorkspacesCurrentModelProvidersByProviderCredentialsValidateResponses[keyof PostWorkspacesCurrentModelProvidersByProviderCredentialsValidateResponses] + +export type DeleteWorkspacesCurrentModelProvidersByProviderModelsData = { + body: ParserDeleteModels + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/models' +} + +export type DeleteWorkspacesCurrentModelProvidersByProviderModelsResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteWorkspacesCurrentModelProvidersByProviderModelsResponse + = DeleteWorkspacesCurrentModelProvidersByProviderModelsResponses[keyof DeleteWorkspacesCurrentModelProvidersByProviderModelsResponses] + +export type GetWorkspacesCurrentModelProvidersByProviderModelsData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/models' +} + +export type GetWorkspacesCurrentModelProvidersByProviderModelsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentModelProvidersByProviderModelsResponse + = GetWorkspacesCurrentModelProvidersByProviderModelsResponses[keyof GetWorkspacesCurrentModelProvidersByProviderModelsResponses] + +export type PostWorkspacesCurrentModelProvidersByProviderModelsData = { + body: ParserPostModels + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/models' +} + +export type PostWorkspacesCurrentModelProvidersByProviderModelsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentModelProvidersByProviderModelsResponse + = PostWorkspacesCurrentModelProvidersByProviderModelsResponses[keyof PostWorkspacesCurrentModelProvidersByProviderModelsResponses] + +export type DeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsData = { + body: ParserDeleteCredential + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/models/credentials' +} + +export type DeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse + = DeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses[keyof DeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses] + +export type GetWorkspacesCurrentModelProvidersByProviderModelsCredentialsData = { + body?: never + path: { + provider: string + } + query: { + config_from?: string | null + credential_id?: string | null + model: string + model_type: string + } + url: '/workspaces/current/model-providers/{provider}/models/credentials' +} + +export type GetWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse + = GetWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses[keyof GetWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses] + +export type PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsData = { + body: ParserCreateCredential + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/models/credentials' +} + +export type PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse + = PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses[keyof PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses] + +export type PutWorkspacesCurrentModelProvidersByProviderModelsCredentialsData = { + body: ParserUpdateCredential + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/models/credentials' +} + +export type PutWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PutWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse + = PutWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses[keyof PutWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponses] + +export type PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchData = { + body: ParserSwitch + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/models/credentials/switch' +} + +export type PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchResponse + = PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchResponses[keyof PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchResponses] + +export type PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidateData = { + body: ParserValidate + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/models/credentials/validate' +} + +export type PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidateResponse + = PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidateResponses[keyof PostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidateResponses] + +export type PatchWorkspacesCurrentModelProvidersByProviderModelsDisableData = { + body: ParserDeleteModels + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/models/disable' +} + +export type PatchWorkspacesCurrentModelProvidersByProviderModelsDisableResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchWorkspacesCurrentModelProvidersByProviderModelsDisableResponse + = PatchWorkspacesCurrentModelProvidersByProviderModelsDisableResponses[keyof PatchWorkspacesCurrentModelProvidersByProviderModelsDisableResponses] + +export type PatchWorkspacesCurrentModelProvidersByProviderModelsEnableData = { + body: ParserDeleteModels + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/models/enable' +} + +export type PatchWorkspacesCurrentModelProvidersByProviderModelsEnableResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchWorkspacesCurrentModelProvidersByProviderModelsEnableResponse + = PatchWorkspacesCurrentModelProvidersByProviderModelsEnableResponses[keyof PatchWorkspacesCurrentModelProvidersByProviderModelsEnableResponses] + +export type PostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidateData + = { + body: LoadBalancingCredentialPayload + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/models/load-balancing-configs/credentials-validate' + } + +export type PostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidateResponses + = { + 200: { + [key: string]: unknown + } + } + +export type PostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidateResponse + = PostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidateResponses[keyof PostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidateResponses] + +export type PostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidateData + = { + body: LoadBalancingCredentialPayload + path: { + provider: string + config_id: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/models/load-balancing-configs/{config_id}/credentials-validate' + } + +export type PostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidateResponses + = { + 200: { + [key: string]: unknown + } + } + +export type PostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidateResponse + = PostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidateResponses[keyof PostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidateResponses] + +export type GetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesData = { + body?: never + path: { + provider: string + } + query: { + model: string + } + url: '/workspaces/current/model-providers/{provider}/models/parameter-rules' +} + +export type GetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesResponse + = GetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesResponses[keyof GetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesResponses] + +export type PostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypeData = { + body: ParserPreferredProviderType + path: { + provider: string + } + query?: never + url: '/workspaces/current/model-providers/{provider}/preferred-provider-type' +} + +export type PostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypeResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypeResponse + = PostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypeResponses[keyof PostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypeResponses] + +export type GetWorkspacesCurrentModelsModelTypesByModelTypeData = { + body?: never + path: { + model_type: string + } + query?: never + url: '/workspaces/current/models/model-types/{model_type}' +} + +export type GetWorkspacesCurrentModelsModelTypesByModelTypeResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentModelsModelTypesByModelTypeResponse + = GetWorkspacesCurrentModelsModelTypesByModelTypeResponses[keyof GetWorkspacesCurrentModelsModelTypesByModelTypeResponses] + +export type GetWorkspacesCurrentPermissionData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/permission' +} + +export type GetWorkspacesCurrentPermissionResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPermissionResponse + = GetWorkspacesCurrentPermissionResponses[keyof GetWorkspacesCurrentPermissionResponses] + +export type GetWorkspacesCurrentPluginAssetData = { + body?: never + path?: never + query: { + file_name: string + plugin_unique_identifier: string + } + url: '/workspaces/current/plugin/asset' +} + +export type GetWorkspacesCurrentPluginAssetResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPluginAssetResponse + = GetWorkspacesCurrentPluginAssetResponses[keyof GetWorkspacesCurrentPluginAssetResponses] + +export type GetWorkspacesCurrentPluginDebuggingKeyData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/plugin/debugging-key' +} + +export type GetWorkspacesCurrentPluginDebuggingKeyResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPluginDebuggingKeyResponse + = GetWorkspacesCurrentPluginDebuggingKeyResponses[keyof GetWorkspacesCurrentPluginDebuggingKeyResponses] + +export type GetWorkspacesCurrentPluginFetchManifestData = { + body?: never + path?: never + query: { + plugin_unique_identifier: string + } + url: '/workspaces/current/plugin/fetch-manifest' +} + +export type GetWorkspacesCurrentPluginFetchManifestResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPluginFetchManifestResponse + = GetWorkspacesCurrentPluginFetchManifestResponses[keyof GetWorkspacesCurrentPluginFetchManifestResponses] + +export type GetWorkspacesCurrentPluginIconData = { + body?: never + path?: never + query: { + filename: string + tenant_id: string + } + url: '/workspaces/current/plugin/icon' +} + +export type GetWorkspacesCurrentPluginIconResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPluginIconResponse + = GetWorkspacesCurrentPluginIconResponses[keyof GetWorkspacesCurrentPluginIconResponses] + +export type PostWorkspacesCurrentPluginInstallGithubData = { + body: ParserGithubInstall + path?: never + query?: never + url: '/workspaces/current/plugin/install/github' +} + +export type PostWorkspacesCurrentPluginInstallGithubResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginInstallGithubResponse + = PostWorkspacesCurrentPluginInstallGithubResponses[keyof PostWorkspacesCurrentPluginInstallGithubResponses] + +export type PostWorkspacesCurrentPluginInstallMarketplaceData = { + body: ParserPluginIdentifiers + path?: never + query?: never + url: '/workspaces/current/plugin/install/marketplace' +} + +export type PostWorkspacesCurrentPluginInstallMarketplaceResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginInstallMarketplaceResponse + = PostWorkspacesCurrentPluginInstallMarketplaceResponses[keyof PostWorkspacesCurrentPluginInstallMarketplaceResponses] + +export type PostWorkspacesCurrentPluginInstallPkgData = { + body: ParserPluginIdentifiers + path?: never + query?: never + url: '/workspaces/current/plugin/install/pkg' +} + +export type PostWorkspacesCurrentPluginInstallPkgResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginInstallPkgResponse + = PostWorkspacesCurrentPluginInstallPkgResponses[keyof PostWorkspacesCurrentPluginInstallPkgResponses] + +export type GetWorkspacesCurrentPluginListData = { + body?: never + path?: never + query?: { + page?: number + page_size?: number + } + url: '/workspaces/current/plugin/list' +} + +export type GetWorkspacesCurrentPluginListResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPluginListResponse + = GetWorkspacesCurrentPluginListResponses[keyof GetWorkspacesCurrentPluginListResponses] + +export type PostWorkspacesCurrentPluginListInstallationsIdsData = { + body: ParserLatest + path?: never + query?: never + url: '/workspaces/current/plugin/list/installations/ids' +} + +export type PostWorkspacesCurrentPluginListInstallationsIdsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginListInstallationsIdsResponse + = PostWorkspacesCurrentPluginListInstallationsIdsResponses[keyof PostWorkspacesCurrentPluginListInstallationsIdsResponses] + +export type PostWorkspacesCurrentPluginListLatestVersionsData = { + body: ParserLatest + path?: never + query?: never + url: '/workspaces/current/plugin/list/latest-versions' +} + +export type PostWorkspacesCurrentPluginListLatestVersionsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginListLatestVersionsResponse + = PostWorkspacesCurrentPluginListLatestVersionsResponses[keyof PostWorkspacesCurrentPluginListLatestVersionsResponses] + +export type GetWorkspacesCurrentPluginMarketplacePkgData = { + body?: never + path?: never + query: { + plugin_unique_identifier: string + } + url: '/workspaces/current/plugin/marketplace/pkg' +} + +export type GetWorkspacesCurrentPluginMarketplacePkgResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPluginMarketplacePkgResponse + = GetWorkspacesCurrentPluginMarketplacePkgResponses[keyof GetWorkspacesCurrentPluginMarketplacePkgResponses] + +export type GetWorkspacesCurrentPluginParametersDynamicOptionsData = { + body?: never + path?: never + query: { + action: string + credential_id?: string | null + parameter: string + plugin_id: string + provider: string + provider_type: 'tool' | 'trigger' + } + url: '/workspaces/current/plugin/parameters/dynamic-options' +} + +export type GetWorkspacesCurrentPluginParametersDynamicOptionsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPluginParametersDynamicOptionsResponse + = GetWorkspacesCurrentPluginParametersDynamicOptionsResponses[keyof GetWorkspacesCurrentPluginParametersDynamicOptionsResponses] + +export type PostWorkspacesCurrentPluginParametersDynamicOptionsWithCredentialsData = { + body: ParserDynamicOptionsWithCredentials + path?: never + query?: never + url: '/workspaces/current/plugin/parameters/dynamic-options-with-credentials' +} + +export type PostWorkspacesCurrentPluginParametersDynamicOptionsWithCredentialsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginParametersDynamicOptionsWithCredentialsResponse + = PostWorkspacesCurrentPluginParametersDynamicOptionsWithCredentialsResponses[keyof PostWorkspacesCurrentPluginParametersDynamicOptionsWithCredentialsResponses] + +export type PostWorkspacesCurrentPluginPermissionChangeData = { + body: ParserPermissionChange + path?: never + query?: never + url: '/workspaces/current/plugin/permission/change' +} + +export type PostWorkspacesCurrentPluginPermissionChangeResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginPermissionChangeResponse + = PostWorkspacesCurrentPluginPermissionChangeResponses[keyof PostWorkspacesCurrentPluginPermissionChangeResponses] + +export type GetWorkspacesCurrentPluginPermissionFetchData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/plugin/permission/fetch' +} + +export type GetWorkspacesCurrentPluginPermissionFetchResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPluginPermissionFetchResponse + = GetWorkspacesCurrentPluginPermissionFetchResponses[keyof GetWorkspacesCurrentPluginPermissionFetchResponses] + +export type PostWorkspacesCurrentPluginPreferencesAutoupgradeExcludeData = { + body: ParserExcludePlugin + path?: never + query?: never + url: '/workspaces/current/plugin/preferences/autoupgrade/exclude' +} + +export type PostWorkspacesCurrentPluginPreferencesAutoupgradeExcludeResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginPreferencesAutoupgradeExcludeResponse + = PostWorkspacesCurrentPluginPreferencesAutoupgradeExcludeResponses[keyof PostWorkspacesCurrentPluginPreferencesAutoupgradeExcludeResponses] + +export type PostWorkspacesCurrentPluginPreferencesChangeData = { + body: ParserPreferencesChange + path?: never + query?: never + url: '/workspaces/current/plugin/preferences/change' +} + +export type PostWorkspacesCurrentPluginPreferencesChangeResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginPreferencesChangeResponse + = PostWorkspacesCurrentPluginPreferencesChangeResponses[keyof PostWorkspacesCurrentPluginPreferencesChangeResponses] + +export type GetWorkspacesCurrentPluginPreferencesFetchData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/plugin/preferences/fetch' +} + +export type GetWorkspacesCurrentPluginPreferencesFetchResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPluginPreferencesFetchResponse + = GetWorkspacesCurrentPluginPreferencesFetchResponses[keyof GetWorkspacesCurrentPluginPreferencesFetchResponses] + +export type GetWorkspacesCurrentPluginReadmeData = { + body?: never + path?: never + query: { + language?: string + plugin_unique_identifier: string + } + url: '/workspaces/current/plugin/readme' +} + +export type GetWorkspacesCurrentPluginReadmeResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPluginReadmeResponse + = GetWorkspacesCurrentPluginReadmeResponses[keyof GetWorkspacesCurrentPluginReadmeResponses] + +export type GetWorkspacesCurrentPluginTasksData = { + body?: never + path?: never + query?: { + page?: number + page_size?: number + } + url: '/workspaces/current/plugin/tasks' +} + +export type GetWorkspacesCurrentPluginTasksResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPluginTasksResponse + = GetWorkspacesCurrentPluginTasksResponses[keyof GetWorkspacesCurrentPluginTasksResponses] + +export type PostWorkspacesCurrentPluginTasksDeleteAllData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/plugin/tasks/delete_all' +} + +export type PostWorkspacesCurrentPluginTasksDeleteAllResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginTasksDeleteAllResponse + = PostWorkspacesCurrentPluginTasksDeleteAllResponses[keyof PostWorkspacesCurrentPluginTasksDeleteAllResponses] + +export type GetWorkspacesCurrentPluginTasksByTaskIdData = { + body?: never + path: { + task_id: string + } + query?: never + url: '/workspaces/current/plugin/tasks/{task_id}' +} + +export type GetWorkspacesCurrentPluginTasksByTaskIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentPluginTasksByTaskIdResponse + = GetWorkspacesCurrentPluginTasksByTaskIdResponses[keyof GetWorkspacesCurrentPluginTasksByTaskIdResponses] + +export type PostWorkspacesCurrentPluginTasksByTaskIdDeleteData = { + body?: never + path: { + task_id: string + } + query?: never + url: '/workspaces/current/plugin/tasks/{task_id}/delete' +} + +export type PostWorkspacesCurrentPluginTasksByTaskIdDeleteResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginTasksByTaskIdDeleteResponse + = PostWorkspacesCurrentPluginTasksByTaskIdDeleteResponses[keyof PostWorkspacesCurrentPluginTasksByTaskIdDeleteResponses] + +export type PostWorkspacesCurrentPluginTasksByTaskIdDeleteByIdentifierData = { + body?: never + path: { + task_id: string + identifier: string + } + query?: never + url: '/workspaces/current/plugin/tasks/{task_id}/delete/{identifier}' +} + +export type PostWorkspacesCurrentPluginTasksByTaskIdDeleteByIdentifierResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginTasksByTaskIdDeleteByIdentifierResponse + = PostWorkspacesCurrentPluginTasksByTaskIdDeleteByIdentifierResponses[keyof PostWorkspacesCurrentPluginTasksByTaskIdDeleteByIdentifierResponses] + +export type PostWorkspacesCurrentPluginUninstallData = { + body: ParserUninstall + path?: never + query?: never + url: '/workspaces/current/plugin/uninstall' +} + +export type PostWorkspacesCurrentPluginUninstallResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginUninstallResponse + = PostWorkspacesCurrentPluginUninstallResponses[keyof PostWorkspacesCurrentPluginUninstallResponses] + +export type PostWorkspacesCurrentPluginUpgradeGithubData = { + body: ParserGithubUpgrade + path?: never + query?: never + url: '/workspaces/current/plugin/upgrade/github' +} + +export type PostWorkspacesCurrentPluginUpgradeGithubResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginUpgradeGithubResponse + = PostWorkspacesCurrentPluginUpgradeGithubResponses[keyof PostWorkspacesCurrentPluginUpgradeGithubResponses] + +export type PostWorkspacesCurrentPluginUpgradeMarketplaceData = { + body: ParserMarketplaceUpgrade + path?: never + query?: never + url: '/workspaces/current/plugin/upgrade/marketplace' +} + +export type PostWorkspacesCurrentPluginUpgradeMarketplaceResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginUpgradeMarketplaceResponse + = PostWorkspacesCurrentPluginUpgradeMarketplaceResponses[keyof PostWorkspacesCurrentPluginUpgradeMarketplaceResponses] + +export type PostWorkspacesCurrentPluginUploadBundleData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/plugin/upload/bundle' +} + +export type PostWorkspacesCurrentPluginUploadBundleResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginUploadBundleResponse + = PostWorkspacesCurrentPluginUploadBundleResponses[keyof PostWorkspacesCurrentPluginUploadBundleResponses] + +export type PostWorkspacesCurrentPluginUploadGithubData = { + body: ParserGithubUpload + path?: never + query?: never + url: '/workspaces/current/plugin/upload/github' +} + +export type PostWorkspacesCurrentPluginUploadGithubResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginUploadGithubResponse + = PostWorkspacesCurrentPluginUploadGithubResponses[keyof PostWorkspacesCurrentPluginUploadGithubResponses] + +export type PostWorkspacesCurrentPluginUploadPkgData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/plugin/upload/pkg' +} + +export type PostWorkspacesCurrentPluginUploadPkgResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentPluginUploadPkgResponse + = PostWorkspacesCurrentPluginUploadPkgResponses[keyof PostWorkspacesCurrentPluginUploadPkgResponses] + +export type GetWorkspacesCurrentToolLabelsData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/tool-labels' +} + +export type GetWorkspacesCurrentToolLabelsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolLabelsResponse + = GetWorkspacesCurrentToolLabelsResponses[keyof GetWorkspacesCurrentToolLabelsResponses] + +export type PostWorkspacesCurrentToolProviderApiAddData = { + body: ApiToolProviderAddPayload + path?: never + query?: never + url: '/workspaces/current/tool-provider/api/add' +} + +export type PostWorkspacesCurrentToolProviderApiAddResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderApiAddResponse + = PostWorkspacesCurrentToolProviderApiAddResponses[keyof PostWorkspacesCurrentToolProviderApiAddResponses] + +export type PostWorkspacesCurrentToolProviderApiDeleteData = { + body: ApiToolProviderDeletePayload + path?: never + query?: never + url: '/workspaces/current/tool-provider/api/delete' +} + +export type PostWorkspacesCurrentToolProviderApiDeleteResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderApiDeleteResponse + = PostWorkspacesCurrentToolProviderApiDeleteResponses[keyof PostWorkspacesCurrentToolProviderApiDeleteResponses] + +export type GetWorkspacesCurrentToolProviderApiGetData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/tool-provider/api/get' +} + +export type GetWorkspacesCurrentToolProviderApiGetResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderApiGetResponse + = GetWorkspacesCurrentToolProviderApiGetResponses[keyof GetWorkspacesCurrentToolProviderApiGetResponses] + +export type GetWorkspacesCurrentToolProviderApiRemoteData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/tool-provider/api/remote' +} + +export type GetWorkspacesCurrentToolProviderApiRemoteResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderApiRemoteResponse + = GetWorkspacesCurrentToolProviderApiRemoteResponses[keyof GetWorkspacesCurrentToolProviderApiRemoteResponses] + +export type PostWorkspacesCurrentToolProviderApiSchemaData = { + body: ApiToolSchemaPayload + path?: never + query?: never + url: '/workspaces/current/tool-provider/api/schema' +} + +export type PostWorkspacesCurrentToolProviderApiSchemaResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderApiSchemaResponse + = PostWorkspacesCurrentToolProviderApiSchemaResponses[keyof PostWorkspacesCurrentToolProviderApiSchemaResponses] + +export type PostWorkspacesCurrentToolProviderApiTestPreData = { + body: ApiToolTestPayload + path?: never + query?: never + url: '/workspaces/current/tool-provider/api/test/pre' +} + +export type PostWorkspacesCurrentToolProviderApiTestPreResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderApiTestPreResponse + = PostWorkspacesCurrentToolProviderApiTestPreResponses[keyof PostWorkspacesCurrentToolProviderApiTestPreResponses] + +export type GetWorkspacesCurrentToolProviderApiToolsData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/tool-provider/api/tools' +} + +export type GetWorkspacesCurrentToolProviderApiToolsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderApiToolsResponse + = GetWorkspacesCurrentToolProviderApiToolsResponses[keyof GetWorkspacesCurrentToolProviderApiToolsResponses] + +export type PostWorkspacesCurrentToolProviderApiUpdateData = { + body: ApiToolProviderUpdatePayload + path?: never + query?: never + url: '/workspaces/current/tool-provider/api/update' +} + +export type PostWorkspacesCurrentToolProviderApiUpdateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderApiUpdateResponse + = PostWorkspacesCurrentToolProviderApiUpdateResponses[keyof PostWorkspacesCurrentToolProviderApiUpdateResponses] + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderAddData = { + body: BuiltinToolAddPayload + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/add' +} + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderAddResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderAddResponse + = PostWorkspacesCurrentToolProviderBuiltinByProviderAddResponses[keyof PostWorkspacesCurrentToolProviderBuiltinByProviderAddResponses] + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/credential/info' +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoResponse + = GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoResponses[keyof GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoResponses] + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypeData + = { + body?: never + path: { + provider: string + credential_type: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/credential/schema/{credential_type}' + } + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypeResponses + = { + 200: { + [key: string]: unknown + } + } + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypeResponse + = GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypeResponses[keyof GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypeResponses] + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/credentials' +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsResponse + = GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsResponses[keyof GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsResponses] + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialData = { + body: BuiltinProviderDefaultCredentialPayload + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/default-credential' +} + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialResponse + = PostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialResponses[keyof PostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialResponses] + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderDeleteData = { + body: BuiltinToolCredentialDeletePayload + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/delete' +} + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderDeleteResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderDeleteResponse + = PostWorkspacesCurrentToolProviderBuiltinByProviderDeleteResponses[keyof PostWorkspacesCurrentToolProviderBuiltinByProviderDeleteResponses] + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderIconData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/icon' +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderIconResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderIconResponse + = GetWorkspacesCurrentToolProviderBuiltinByProviderIconResponses[keyof GetWorkspacesCurrentToolProviderBuiltinByProviderIconResponses] + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderInfoData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/info' +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderInfoResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderInfoResponse + = GetWorkspacesCurrentToolProviderBuiltinByProviderInfoResponses[keyof GetWorkspacesCurrentToolProviderBuiltinByProviderInfoResponses] + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/oauth/client-schema' +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaResponse + = GetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaResponses[keyof GetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaResponses] + +export type DeleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/oauth/custom-client' +} + +export type DeleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse + = DeleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponses[keyof DeleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponses] + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/oauth/custom-client' +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse + = GetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponses[keyof GetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponses] + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientData = { + body: ToolOAuthCustomClientPayload + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/oauth/custom-client' +} + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse + = PostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponses[keyof PostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponses] + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderToolsData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/tools' +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderToolsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderBuiltinByProviderToolsResponse + = GetWorkspacesCurrentToolProviderBuiltinByProviderToolsResponses[keyof GetWorkspacesCurrentToolProviderBuiltinByProviderToolsResponses] + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderUpdateData = { + body: BuiltinToolUpdatePayload + path: { + provider: string + } + query?: never + url: '/workspaces/current/tool-provider/builtin/{provider}/update' +} + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderUpdateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderBuiltinByProviderUpdateResponse + = PostWorkspacesCurrentToolProviderBuiltinByProviderUpdateResponses[keyof PostWorkspacesCurrentToolProviderBuiltinByProviderUpdateResponses] + +export type DeleteWorkspacesCurrentToolProviderMcpData = { + body: McpProviderDeletePayload + path?: never + query?: never + url: '/workspaces/current/tool-provider/mcp' +} + +export type DeleteWorkspacesCurrentToolProviderMcpResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteWorkspacesCurrentToolProviderMcpResponse + = DeleteWorkspacesCurrentToolProviderMcpResponses[keyof DeleteWorkspacesCurrentToolProviderMcpResponses] + +export type PostWorkspacesCurrentToolProviderMcpData = { + body: McpProviderCreatePayload + path?: never + query?: never + url: '/workspaces/current/tool-provider/mcp' +} + +export type PostWorkspacesCurrentToolProviderMcpResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderMcpResponse + = PostWorkspacesCurrentToolProviderMcpResponses[keyof PostWorkspacesCurrentToolProviderMcpResponses] + +export type PutWorkspacesCurrentToolProviderMcpData = { + body: McpProviderUpdatePayload + path?: never + query?: never + url: '/workspaces/current/tool-provider/mcp' +} + +export type PutWorkspacesCurrentToolProviderMcpResponses = { + 200: { + [key: string]: unknown + } +} + +export type PutWorkspacesCurrentToolProviderMcpResponse + = PutWorkspacesCurrentToolProviderMcpResponses[keyof PutWorkspacesCurrentToolProviderMcpResponses] + +export type PostWorkspacesCurrentToolProviderMcpAuthData = { + body: McpAuthPayload + path?: never + query?: never + url: '/workspaces/current/tool-provider/mcp/auth' +} + +export type PostWorkspacesCurrentToolProviderMcpAuthResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderMcpAuthResponse + = PostWorkspacesCurrentToolProviderMcpAuthResponses[keyof PostWorkspacesCurrentToolProviderMcpAuthResponses] + +export type GetWorkspacesCurrentToolProviderMcpToolsByProviderIdData = { + body?: never + path: { + provider_id: string + } + query?: never + url: '/workspaces/current/tool-provider/mcp/tools/{provider_id}' +} + +export type GetWorkspacesCurrentToolProviderMcpToolsByProviderIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderMcpToolsByProviderIdResponse + = GetWorkspacesCurrentToolProviderMcpToolsByProviderIdResponses[keyof GetWorkspacesCurrentToolProviderMcpToolsByProviderIdResponses] + +export type GetWorkspacesCurrentToolProviderMcpUpdateByProviderIdData = { + body?: never + path: { + provider_id: string + } + query?: never + url: '/workspaces/current/tool-provider/mcp/update/{provider_id}' +} + +export type GetWorkspacesCurrentToolProviderMcpUpdateByProviderIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderMcpUpdateByProviderIdResponse + = GetWorkspacesCurrentToolProviderMcpUpdateByProviderIdResponses[keyof GetWorkspacesCurrentToolProviderMcpUpdateByProviderIdResponses] + +export type PostWorkspacesCurrentToolProviderWorkflowCreateData = { + body: WorkflowToolCreatePayload + path?: never + query?: never + url: '/workspaces/current/tool-provider/workflow/create' +} + +export type PostWorkspacesCurrentToolProviderWorkflowCreateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderWorkflowCreateResponse + = PostWorkspacesCurrentToolProviderWorkflowCreateResponses[keyof PostWorkspacesCurrentToolProviderWorkflowCreateResponses] + +export type PostWorkspacesCurrentToolProviderWorkflowDeleteData = { + body: WorkflowToolDeletePayload + path?: never + query?: never + url: '/workspaces/current/tool-provider/workflow/delete' +} + +export type PostWorkspacesCurrentToolProviderWorkflowDeleteResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderWorkflowDeleteResponse + = PostWorkspacesCurrentToolProviderWorkflowDeleteResponses[keyof PostWorkspacesCurrentToolProviderWorkflowDeleteResponses] + +export type GetWorkspacesCurrentToolProviderWorkflowGetData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/tool-provider/workflow/get' +} + +export type GetWorkspacesCurrentToolProviderWorkflowGetResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderWorkflowGetResponse + = GetWorkspacesCurrentToolProviderWorkflowGetResponses[keyof GetWorkspacesCurrentToolProviderWorkflowGetResponses] + +export type GetWorkspacesCurrentToolProviderWorkflowToolsData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/tool-provider/workflow/tools' +} + +export type GetWorkspacesCurrentToolProviderWorkflowToolsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProviderWorkflowToolsResponse + = GetWorkspacesCurrentToolProviderWorkflowToolsResponses[keyof GetWorkspacesCurrentToolProviderWorkflowToolsResponses] + +export type PostWorkspacesCurrentToolProviderWorkflowUpdateData = { + body: WorkflowToolUpdatePayload + path?: never + query?: never + url: '/workspaces/current/tool-provider/workflow/update' +} + +export type PostWorkspacesCurrentToolProviderWorkflowUpdateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentToolProviderWorkflowUpdateResponse + = PostWorkspacesCurrentToolProviderWorkflowUpdateResponses[keyof PostWorkspacesCurrentToolProviderWorkflowUpdateResponses] + +export type GetWorkspacesCurrentToolProvidersData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/tool-providers' +} + +export type GetWorkspacesCurrentToolProvidersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolProvidersResponse + = GetWorkspacesCurrentToolProvidersResponses[keyof GetWorkspacesCurrentToolProvidersResponses] + +export type GetWorkspacesCurrentToolsApiData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/tools/api' +} + +export type GetWorkspacesCurrentToolsApiResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolsApiResponse + = GetWorkspacesCurrentToolsApiResponses[keyof GetWorkspacesCurrentToolsApiResponses] + +export type GetWorkspacesCurrentToolsBuiltinData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/tools/builtin' +} + +export type GetWorkspacesCurrentToolsBuiltinResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolsBuiltinResponse + = GetWorkspacesCurrentToolsBuiltinResponses[keyof GetWorkspacesCurrentToolsBuiltinResponses] + +export type GetWorkspacesCurrentToolsMcpData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/tools/mcp' +} + +export type GetWorkspacesCurrentToolsMcpResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolsMcpResponse + = GetWorkspacesCurrentToolsMcpResponses[keyof GetWorkspacesCurrentToolsMcpResponses] + +export type GetWorkspacesCurrentToolsWorkflowData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/tools/workflow' +} + +export type GetWorkspacesCurrentToolsWorkflowResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentToolsWorkflowResponse + = GetWorkspacesCurrentToolsWorkflowResponses[keyof GetWorkspacesCurrentToolsWorkflowResponses] + +export type GetWorkspacesCurrentTriggerProviderByProviderIconData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/icon' +} + +export type GetWorkspacesCurrentTriggerProviderByProviderIconResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentTriggerProviderByProviderIconResponse + = GetWorkspacesCurrentTriggerProviderByProviderIconResponses[keyof GetWorkspacesCurrentTriggerProviderByProviderIconResponses] + +export type GetWorkspacesCurrentTriggerProviderByProviderInfoData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/info' +} + +export type GetWorkspacesCurrentTriggerProviderByProviderInfoResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentTriggerProviderByProviderInfoResponse + = GetWorkspacesCurrentTriggerProviderByProviderInfoResponses[keyof GetWorkspacesCurrentTriggerProviderByProviderInfoResponses] + +export type DeleteWorkspacesCurrentTriggerProviderByProviderOauthClientData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/oauth/client' +} + +export type DeleteWorkspacesCurrentTriggerProviderByProviderOauthClientResponses = { + 200: { + [key: string]: unknown + } +} + +export type DeleteWorkspacesCurrentTriggerProviderByProviderOauthClientResponse + = DeleteWorkspacesCurrentTriggerProviderByProviderOauthClientResponses[keyof DeleteWorkspacesCurrentTriggerProviderByProviderOauthClientResponses] + +export type GetWorkspacesCurrentTriggerProviderByProviderOauthClientData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/oauth/client' +} + +export type GetWorkspacesCurrentTriggerProviderByProviderOauthClientResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentTriggerProviderByProviderOauthClientResponse + = GetWorkspacesCurrentTriggerProviderByProviderOauthClientResponses[keyof GetWorkspacesCurrentTriggerProviderByProviderOauthClientResponses] + +export type PostWorkspacesCurrentTriggerProviderByProviderOauthClientData = { + body: TriggerOAuthClientPayload + path: { + provider: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/oauth/client' +} + +export type PostWorkspacesCurrentTriggerProviderByProviderOauthClientResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentTriggerProviderByProviderOauthClientResponse + = PostWorkspacesCurrentTriggerProviderByProviderOauthClientResponses[keyof PostWorkspacesCurrentTriggerProviderByProviderOauthClientResponses] + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdData + = { + body: TriggerSubscriptionBuilderUpdatePayload + path: { + provider: string + subscription_builder_id: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/subscriptions/builder/build/{subscription_builder_id}' + } + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdResponses + = { + 200: { + [key: string]: unknown + } + } + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdResponse + = PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdResponses[keyof PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdResponses] + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreateData = { + body: TriggerSubscriptionBuilderCreatePayload + path: { + provider: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/subscriptions/builder/create' +} + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreateResponse + = PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreateResponses[keyof PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreateResponses] + +export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderLogsBySubscriptionBuilderIdData + = { + body?: never + path: { + provider: string + subscription_builder_id: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/subscriptions/builder/logs/{subscription_builder_id}' + } + +export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderLogsBySubscriptionBuilderIdResponses + = { + 200: { + [key: string]: unknown + } + } + +export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderLogsBySubscriptionBuilderIdResponse + = GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderLogsBySubscriptionBuilderIdResponses[keyof GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderLogsBySubscriptionBuilderIdResponses] + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdData + = { + body: TriggerSubscriptionBuilderUpdatePayload + path: { + provider: string + subscription_builder_id: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/subscriptions/builder/update/{subscription_builder_id}' + } + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdResponses + = { + 200: { + [key: string]: unknown + } + } + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdResponse + = PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdResponses[keyof PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdResponses] + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdData + = { + body: TriggerSubscriptionBuilderVerifyPayload + path: { + provider: string + subscription_builder_id: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/subscriptions/builder/verify-and-update/{subscription_builder_id}' + } + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdResponses + = { + 200: { + [key: string]: unknown + } + } + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdResponse + = PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdResponses[keyof PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdResponses] + +export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBySubscriptionBuilderIdData + = { + body?: never + path: { + provider: string + subscription_builder_id: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/subscriptions/builder/{subscription_builder_id}' + } + +export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBySubscriptionBuilderIdResponses + = { + 200: { + [key: string]: unknown + } + } + +export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBySubscriptionBuilderIdResponse + = GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBySubscriptionBuilderIdResponses[keyof GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBySubscriptionBuilderIdResponses] + +export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/subscriptions/list' +} + +export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListResponse + = GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListResponses[keyof GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListResponses] + +export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorizeData = { + body?: never + path: { + provider: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/subscriptions/oauth/authorize' +} + +export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorizeResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorizeResponse + = GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorizeResponses[keyof GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorizeResponses] + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdData + = { + body: TriggerSubscriptionBuilderVerifyPayload + path: { + provider: string + subscription_id: string + } + query?: never + url: '/workspaces/current/trigger-provider/{provider}/subscriptions/verify/{subscription_id}' + } + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdResponses + = { + 200: { + [key: string]: unknown + } + } + +export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdResponse + = PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdResponses[keyof PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdResponses] + +export type PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsDeleteData = { + body?: never + path: { + subscription_id: string + } + query?: never + url: '/workspaces/current/trigger-provider/{subscription_id}/subscriptions/delete' +} + +export type PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsDeleteResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsDeleteResponse + = PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsDeleteResponses[keyof PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsDeleteResponses] + +export type PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateData = { + body: TriggerSubscriptionBuilderUpdatePayload + path: { + subscription_id: string + } + query?: never + url: '/workspaces/current/trigger-provider/{subscription_id}/subscriptions/update' +} + +export type PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateResponse + = PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateResponses[keyof PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateResponses] + +export type GetWorkspacesCurrentTriggersData = { + body?: never + path?: never + query?: never + url: '/workspaces/current/triggers' +} + +export type GetWorkspacesCurrentTriggersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentTriggersResponse + = GetWorkspacesCurrentTriggersResponses[keyof GetWorkspacesCurrentTriggersResponses] + +export type PostWorkspacesCustomConfigData = { + body: WorkspaceCustomConfigPayload + path?: never + query?: never + url: '/workspaces/custom-config' +} + +export type PostWorkspacesCustomConfigResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCustomConfigResponse + = PostWorkspacesCustomConfigResponses[keyof PostWorkspacesCustomConfigResponses] + +export type PostWorkspacesCustomConfigWebappLogoUploadData = { + body?: never + path?: never + query?: never + url: '/workspaces/custom-config/webapp-logo/upload' +} + +export type PostWorkspacesCustomConfigWebappLogoUploadResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesCustomConfigWebappLogoUploadResponse + = PostWorkspacesCustomConfigWebappLogoUploadResponses[keyof PostWorkspacesCustomConfigWebappLogoUploadResponses] + +export type PostWorkspacesInfoData = { + body: WorkspaceInfoPayload + path?: never + query?: never + url: '/workspaces/info' +} + +export type PostWorkspacesInfoResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesInfoResponse + = PostWorkspacesInfoResponses[keyof PostWorkspacesInfoResponses] + +export type PostWorkspacesSwitchData = { + body: SwitchWorkspacePayload + path?: never + query?: never + url: '/workspaces/switch' +} + +export type PostWorkspacesSwitchResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkspacesSwitchResponse + = PostWorkspacesSwitchResponses[keyof PostWorkspacesSwitchResponses] + +export type GetWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLangData = { + body?: never + path: { + tenant_id: string + provider: string + icon_type: string + lang: string + } + query?: never + url: '/workspaces/{tenant_id}/model-providers/{provider}/{icon_type}/{lang}' +} + +export type GetWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLangResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLangResponse + = GetWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLangResponses[keyof GetWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLangResponses] diff --git a/packages/contracts/generated/api/console/workspaces/zod.gen.ts b/packages/contracts/generated/api/console/workspaces/zod.gen.ts new file mode 100644 index 0000000000..a381824da7 --- /dev/null +++ b/packages/contracts/generated/api/console/workspaces/zod.gen.ts @@ -0,0 +1,2150 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * TenantInfoResponse + */ +export const zTenantInfoResponse = z.object({ + created_at: z.int().nullish(), + custom_config: z.record(z.string(), z.unknown()).nullish(), + id: z.string(), + in_trial: z.boolean().nullish(), + name: z.string().nullish(), + next_credit_reset_date: z.int().nullish(), + plan: z.string().nullish(), + role: z.string().nullish(), + status: z.string().nullish(), + trial_credits: z.int().nullish(), + trial_credits_used: z.int().nullish(), + trial_end_reason: z.string().nullish(), +}) + +/** + * EndpointCreatePayload + */ +export const zEndpointCreatePayload = z.object({ + name: z.string().min(1), + plugin_unique_identifier: z.string(), + settings: z.record(z.string(), z.unknown()), +}) + +/** + * EndpointCreateResponse + */ +export const zEndpointCreateResponse = z.object({ + success: z.boolean(), +}) + +/** + * EndpointIdPayload + */ +export const zEndpointIdPayload = z.object({ + endpoint_id: z.string(), +}) + +/** + * EndpointDeleteResponse + */ +export const zEndpointDeleteResponse = z.object({ + success: z.boolean(), +}) + +/** + * EndpointDisableResponse + */ +export const zEndpointDisableResponse = z.object({ + success: z.boolean(), +}) + +/** + * EndpointEnableResponse + */ +export const zEndpointEnableResponse = z.object({ + success: z.boolean(), +}) + +/** + * EndpointListResponse + */ +export const zEndpointListResponse = z.object({ + endpoints: z.array(z.record(z.string(), z.unknown())), +}) + +/** + * PluginEndpointListResponse + */ +export const zPluginEndpointListResponse = z.object({ + endpoints: z.array(z.record(z.string(), z.unknown())), +}) + +/** + * LegacyEndpointUpdatePayload + */ +export const zLegacyEndpointUpdatePayload = z.object({ + endpoint_id: z.string(), + name: z.string().min(1), + settings: z.record(z.string(), z.unknown()), +}) + +/** + * EndpointUpdateResponse + */ +export const zEndpointUpdateResponse = z.object({ + success: z.boolean(), +}) + +/** + * EndpointUpdatePayload + */ +export const zEndpointUpdatePayload = z.object({ + name: z.string().min(1), + settings: z.record(z.string(), z.unknown()), +}) + +/** + * OwnerTransferCheckPayload + */ +export const zOwnerTransferCheckPayload = z.object({ + code: z.string(), + token: z.string(), +}) + +/** + * OwnerTransferEmailPayload + */ +export const zOwnerTransferEmailPayload = z.object({ + language: z.string().nullish(), +}) + +/** + * OwnerTransferPayload + */ +export const zOwnerTransferPayload = z.object({ + token: z.string(), +}) + +/** + * MemberRoleUpdatePayload + */ +export const zMemberRoleUpdatePayload = z.object({ + role: z.string(), +}) + +/** + * ParserCredentialDelete + */ +export const zParserCredentialDelete = z.object({ + credential_id: z.string(), +}) + +/** + * ParserCredentialCreate + */ +export const zParserCredentialCreate = z.object({ + credentials: z.record(z.string(), z.unknown()), + name: z.string().max(30).nullish(), +}) + +/** + * ParserCredentialUpdate + */ +export const zParserCredentialUpdate = z.object({ + credential_id: z.string(), + credentials: z.record(z.string(), z.unknown()), + name: z.string().max(30).nullish(), +}) + +/** + * ParserCredentialSwitch + */ +export const zParserCredentialSwitch = z.object({ + credential_id: z.string(), +}) + +/** + * ParserCredentialValidate + */ +export const zParserCredentialValidate = z.object({ + credentials: z.record(z.string(), z.unknown()), +}) + +/** + * ParserPreferredProviderType + */ +export const zParserPreferredProviderType = z.object({ + preferred_provider_type: z.enum(['system', 'custom']), +}) + +/** + * ParserGithubInstall + */ +export const zParserGithubInstall = z.object({ + package: z.string(), + plugin_unique_identifier: z.string(), + repo: z.string(), + version: z.string(), +}) + +/** + * ParserPluginIdentifiers + */ +export const zParserPluginIdentifiers = z.object({ + plugin_unique_identifiers: z.array(z.string()), +}) + +/** + * ParserLatest + */ +export const zParserLatest = z.object({ + plugin_ids: z.array(z.string()), +}) + +/** + * ParserDynamicOptionsWithCredentials + */ +export const zParserDynamicOptionsWithCredentials = z.object({ + action: z.string(), + credential_id: z.string(), + credentials: z.record(z.string(), z.unknown()), + parameter: z.string(), + plugin_id: z.string(), + provider: z.string(), +}) + +/** + * ParserExcludePlugin + */ +export const zParserExcludePlugin = z.object({ + plugin_id: z.string(), +}) + +/** + * ParserUninstall + */ +export const zParserUninstall = z.object({ + plugin_installation_id: z.string(), +}) + +/** + * ParserGithubUpgrade + */ +export const zParserGithubUpgrade = z.object({ + new_plugin_unique_identifier: z.string(), + original_plugin_unique_identifier: z.string(), + package: z.string(), + repo: z.string(), + version: z.string(), +}) + +/** + * ParserMarketplaceUpgrade + */ +export const zParserMarketplaceUpgrade = z.object({ + new_plugin_unique_identifier: z.string(), + original_plugin_unique_identifier: z.string(), +}) + +/** + * ParserGithubUpload + */ +export const zParserGithubUpload = z.object({ + package: z.string(), + repo: z.string(), + version: z.string(), +}) + +/** + * ApiToolProviderDeletePayload + */ +export const zApiToolProviderDeletePayload = z.object({ + provider: z.string(), +}) + +/** + * ApiToolSchemaPayload + */ +export const zApiToolSchemaPayload = z.object({ + schema: z.string(), +}) + +/** + * BuiltinProviderDefaultCredentialPayload + */ +export const zBuiltinProviderDefaultCredentialPayload = z.object({ + id: z.string(), +}) + +/** + * BuiltinToolCredentialDeletePayload + */ +export const zBuiltinToolCredentialDeletePayload = z.object({ + credential_id: z.string(), +}) + +/** + * ToolOAuthCustomClientPayload + */ +export const zToolOAuthCustomClientPayload = z.object({ + client_params: z.record(z.string(), z.unknown()).nullish(), + enable_oauth_custom_client: z.boolean().nullish().default(true), +}) + +/** + * BuiltinToolUpdatePayload + */ +export const zBuiltinToolUpdatePayload = z.object({ + credential_id: z.string(), + credentials: z.record(z.string(), z.unknown()).nullish(), + name: z.string().max(30).nullish(), +}) + +/** + * MCPProviderDeletePayload + */ +export const zMcpProviderDeletePayload = z.object({ + provider_id: z.string(), +}) + +/** + * MCPProviderCreatePayload + */ +export const zMcpProviderCreatePayload = z.object({ + authentication: z.record(z.string(), z.unknown()).nullish(), + configuration: z.record(z.string(), z.unknown()).nullish(), + headers: z.record(z.string(), z.unknown()).nullish(), + icon: z.string(), + icon_background: z.string().optional().default(''), + icon_type: z.string(), + name: z.string(), + server_identifier: z.string(), + server_url: z.string(), +}) + +/** + * MCPProviderUpdatePayload + */ +export const zMcpProviderUpdatePayload = z.object({ + authentication: z.record(z.string(), z.unknown()).nullish(), + configuration: z.record(z.string(), z.unknown()).nullish(), + headers: z.record(z.string(), z.unknown()).nullish(), + icon: z.string(), + icon_background: z.string().optional().default(''), + icon_type: z.string(), + name: z.string(), + provider_id: z.string(), + server_identifier: z.string(), + server_url: z.string(), +}) + +/** + * MCPAuthPayload + */ +export const zMcpAuthPayload = z.object({ + authorization_code: z.string().nullish(), + provider_id: z.string(), +}) + +/** + * WorkflowToolDeletePayload + */ +export const zWorkflowToolDeletePayload = z.object({ + workflow_tool_id: z.string(), +}) + +/** + * TriggerOAuthClientPayload + */ +export const zTriggerOAuthClientPayload = z.object({ + client_params: z.record(z.string(), z.unknown()).nullish(), + enabled: z.boolean().nullish(), +}) + +/** + * TriggerSubscriptionBuilderUpdatePayload + */ +export const zTriggerSubscriptionBuilderUpdatePayload = z.object({ + credentials: z.record(z.string(), z.unknown()).nullish(), + name: z.string().nullish(), + parameters: z.record(z.string(), z.unknown()).nullish(), + properties: z.record(z.string(), z.unknown()).nullish(), +}) + +/** + * TriggerSubscriptionBuilderCreatePayload + */ +export const zTriggerSubscriptionBuilderCreatePayload = z.object({ + credential_type: z.string().optional().default('unauthorized'), +}) + +/** + * TriggerSubscriptionBuilderVerifyPayload + */ +export const zTriggerSubscriptionBuilderVerifyPayload = z.object({ + credentials: z.record(z.string(), z.unknown()), +}) + +/** + * WorkspaceCustomConfigPayload + */ +export const zWorkspaceCustomConfigPayload = z.object({ + remove_webapp_brand: z.boolean().nullish(), + replace_webapp_logo: z.string().nullish(), +}) + +/** + * WorkspaceInfoPayload + */ +export const zWorkspaceInfoPayload = z.object({ + name: z.string(), +}) + +/** + * SwitchWorkspacePayload + */ +export const zSwitchWorkspacePayload = z.object({ + tenant_id: z.string(), +}) + +/** + * AccountWithRole + */ +export const zAccountWithRole = z.object({ + avatar: z.string().nullish(), + created_at: z.int().nullish(), + email: z.string(), + id: z.string(), + last_active_at: z.int().nullish(), + last_login_at: z.int().nullish(), + name: z.string(), + role: z.string(), + status: z.string(), +}) + +/** + * AccountWithRoleList + */ +export const zAccountWithRoleList = z.object({ + accounts: z.array(zAccountWithRole), +}) + +/** + * TenantAccountRole + */ +export const zTenantAccountRole = z.enum(['owner', 'admin', 'editor', 'normal', 'dataset_operator']) + +/** + * 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', + 'text-embedding', + 'rerank', + 'speech2text', + 'moderation', + '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 + */ +export const zInner = z.object({ + model: z.string().nullish(), + model_type: zModelType, + provider: z.string().nullish(), +}) + +/** + * ParserPostDefault + */ +export const zParserPostDefault = z.object({ + model_settings: z.array(zInner), +}) + +/** + * LoadBalancingPayload + */ +export const zLoadBalancingPayload = z.object({ + configs: z.array(z.record(z.string(), z.unknown())).nullish(), + enabled: z.boolean().nullish(), +}) + +/** + * ParserPostModels + */ +export const zParserPostModels = z.object({ + config_from: z.string().nullish(), + credential_id: z.string().nullish(), + load_balancing: zLoadBalancingPayload.optional(), + model: z.string(), + model_type: zModelType, +}) + +/** + * DebugPermission + */ +export const zDebugPermission = z.enum(['everyone', 'admins', 'noone']) + +/** + * InstallPermission + */ +export const zInstallPermission = z.enum(['everyone', 'admins', 'noone']) + +/** + * ParserPermissionChange + */ +export const zParserPermissionChange = z.object({ + debug_permission: zDebugPermission, + install_permission: zInstallPermission, +}) + +/** + * PluginPermissionSettingsPayload + */ +export const zPluginPermissionSettingsPayload = z.object({ + debug_permission: zDebugPermission.optional(), + install_permission: zInstallPermission.optional(), +}) + +/** + * ApiProviderSchemaType + * + * Enum class for api provider schema type. + */ +export const zApiProviderSchemaType = z.enum([ + 'openapi', + 'swagger', + 'openai_plugin', + 'openai_actions', +]) + +/** + * ApiToolProviderAddPayload + */ +export const zApiToolProviderAddPayload = z.object({ + credentials: z.record(z.string(), z.unknown()), + custom_disclaimer: z.string().optional().default(''), + icon: z.record(z.string(), z.unknown()), + labels: z.array(z.string()).nullish(), + privacy_policy: z.string().nullish(), + provider: z.string(), + schema: z.string(), + schema_type: zApiProviderSchemaType, +}) + +/** + * ApiToolTestPayload + */ +export const zApiToolTestPayload = z.object({ + credentials: z.record(z.string(), z.unknown()), + parameters: z.record(z.string(), z.unknown()), + provider_name: z.string().nullish(), + schema: z.string(), + schema_type: zApiProviderSchemaType, + tool_name: z.string(), +}) + +/** + * ApiToolProviderUpdatePayload + */ +export const zApiToolProviderUpdatePayload = z.object({ + credentials: z.record(z.string(), z.unknown()), + custom_disclaimer: z.string().optional().default(''), + icon: z.record(z.string(), z.unknown()), + labels: z.array(z.string()).nullish(), + original_provider: z.string(), + privacy_policy: z.string().nullish(), + provider: z.string(), + schema: z.string(), + schema_type: zApiProviderSchemaType, +}) + +/** + * CredentialType + */ +export const zCredentialType = z.enum(['api-key', 'oauth2', 'unauthorized']) + +/** + * BuiltinToolAddPayload + */ +export const zBuiltinToolAddPayload = z.object({ + credentials: z.record(z.string(), z.unknown()), + name: z.string().max(30).nullish(), + type: zCredentialType, +}) + +/** + * StrategySetting + */ +export const zStrategySetting = z.enum(['disabled', 'fix_only', 'latest']) + +/** + * UpgradeMode + */ +export const zUpgradeMode = z.enum(['all', 'partial', 'exclude']) + +/** + * PluginAutoUpgradeSettingsPayload + */ +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(), + upgrade_time_of_day: z.int().optional().default(0), +}) + +/** + * ParserPreferencesChange + */ +export const zParserPreferencesChange = z.object({ + auto_upgrade: zPluginAutoUpgradeSettingsPayload, + permission: zPluginPermissionSettingsPayload, +}) + +/** + * ToolParameterForm + */ +export const zToolParameterForm = z.enum(['schema', 'form', 'llm']) + +/** + * WorkflowToolParameterConfiguration + * + * Workflow tool configuration + */ +export const zWorkflowToolParameterConfiguration = z.object({ + description: z.string(), + form: zToolParameterForm, + name: z.string(), +}) + +/** + * WorkflowToolCreatePayload + */ +export const zWorkflowToolCreatePayload = z.object({ + description: z.string(), + icon: z.record(z.string(), z.unknown()), + label: z.string(), + labels: z.array(z.string()).nullish(), + name: z.string(), + parameters: z.array(zWorkflowToolParameterConfiguration).optional(), + privacy_policy: z.string().nullish().default(''), + workflow_app_id: z.string(), +}) + +/** + * WorkflowToolUpdatePayload + */ +export const zWorkflowToolUpdatePayload = z.object({ + description: z.string(), + icon: z.record(z.string(), z.unknown()), + label: z.string(), + labels: z.array(z.string()).nullish(), + name: z.string(), + parameters: z.array(zWorkflowToolParameterConfiguration).optional(), + privacy_policy: z.string().nullish().default(''), + workflow_tool_id: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPostWorkspacesCurrentResponse = zTenantInfoResponse + +export const zGetWorkspacesCurrentAgentProviderByProviderNamePath = z.object({ + provider_name: z.string(), +}) + +/** + * Agent provider details + */ +export const zGetWorkspacesCurrentAgentProviderByProviderNameResponse = z.record( + z.string(), + z.unknown(), +) + +/** + * Success + */ +export const zGetWorkspacesCurrentAgentProvidersResponse = z.array( + z.record(z.string(), z.unknown()), +) + +/** + * Success + */ +export const zGetWorkspacesCurrentDatasetOperatorsResponse = zAccountWithRoleList + +export const zGetWorkspacesCurrentDefaultModelQuery = z.object({ + model_type: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentDefaultModelResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentDefaultModelBody = zParserPostDefault + +/** + * Success + */ +export const zPostWorkspacesCurrentDefaultModelResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentEndpointsBody = zEndpointCreatePayload + +/** + * Endpoint created successfully + */ +export const zPostWorkspacesCurrentEndpointsResponse = zEndpointCreateResponse + +export const zPostWorkspacesCurrentEndpointsCreateBody = zEndpointCreatePayload + +/** + * Endpoint created successfully + */ +export const zPostWorkspacesCurrentEndpointsCreateResponse = zEndpointCreateResponse + +export const zPostWorkspacesCurrentEndpointsDeleteBody = zEndpointIdPayload + +/** + * Endpoint deleted successfully + */ +export const zPostWorkspacesCurrentEndpointsDeleteResponse = zEndpointDeleteResponse + +export const zPostWorkspacesCurrentEndpointsDisableBody = zEndpointIdPayload + +/** + * Endpoint disabled successfully + */ +export const zPostWorkspacesCurrentEndpointsDisableResponse = zEndpointDisableResponse + +export const zPostWorkspacesCurrentEndpointsEnableBody = zEndpointIdPayload + +/** + * Endpoint enabled successfully + */ +export const zPostWorkspacesCurrentEndpointsEnableResponse = zEndpointEnableResponse + +export const zGetWorkspacesCurrentEndpointsListQuery = z.object({ + page: z.int().gte(1), + page_size: z.int(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentEndpointsListResponse = zEndpointListResponse + +export const zGetWorkspacesCurrentEndpointsListPluginQuery = z.object({ + page: z.int().gte(1), + page_size: z.int(), + plugin_id: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentEndpointsListPluginResponse = zPluginEndpointListResponse + +export const zPostWorkspacesCurrentEndpointsUpdateBody = zLegacyEndpointUpdatePayload + +/** + * Endpoint updated successfully + */ +export const zPostWorkspacesCurrentEndpointsUpdateResponse = zEndpointUpdateResponse + +export const zDeleteWorkspacesCurrentEndpointsByIdPath = z.object({ + id: z.string(), +}) + +/** + * Endpoint deleted successfully + */ +export const zDeleteWorkspacesCurrentEndpointsByIdResponse = zEndpointDeleteResponse + +export const zPatchWorkspacesCurrentEndpointsByIdBody = zEndpointUpdatePayload + +export const zPatchWorkspacesCurrentEndpointsByIdPath = z.object({ + id: z.string(), +}) + +/** + * Endpoint updated successfully + */ +export const zPatchWorkspacesCurrentEndpointsByIdResponse = zEndpointUpdateResponse + +/** + * Success + */ +export const zGetWorkspacesCurrentMembersResponse = zAccountWithRoleList + +export const zPostWorkspacesCurrentMembersInviteEmailBody = zMemberInvitePayload + +/** + * Success + */ +export const zPostWorkspacesCurrentMembersInviteEmailResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentMembersOwnerTransferCheckBody = zOwnerTransferCheckPayload + +/** + * Success + */ +export const zPostWorkspacesCurrentMembersOwnerTransferCheckResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentMembersSendOwnerTransferConfirmEmailBody + = zOwnerTransferEmailPayload + +/** + * Success + */ +export const zPostWorkspacesCurrentMembersSendOwnerTransferConfirmEmailResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteWorkspacesCurrentMembersByMemberIdPath = z.object({ + member_id: z.string(), +}) + +/** + * Success + */ +export const zDeleteWorkspacesCurrentMembersByMemberIdResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentMembersByMemberIdOwnerTransferBody = zOwnerTransferPayload + +export const zPostWorkspacesCurrentMembersByMemberIdOwnerTransferPath = z.object({ + member_id: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentMembersByMemberIdOwnerTransferResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPutWorkspacesCurrentMembersByMemberIdUpdateRoleBody = zMemberRoleUpdatePayload + +export const zPutWorkspacesCurrentMembersByMemberIdUpdateRolePath = z.object({ + member_id: z.string(), +}) + +/** + * Success + */ +export const zPutWorkspacesCurrentMembersByMemberIdUpdateRoleResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentModelProvidersQuery = z.object({ + model_type: z.string().nullish(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentModelProvidersResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentModelProvidersByProviderCheckoutUrlPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentModelProvidersByProviderCheckoutUrlResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsBody + = zParserCredentialDelete + +export const zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentModelProvidersByProviderCredentialsPath = z.object({ + provider: z.string(), +}) + +export const zGetWorkspacesCurrentModelProvidersByProviderCredentialsQuery = z.object({ + credential_id: z.string().nullish(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentModelProvidersByProviderCredentialsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentModelProvidersByProviderCredentialsBody = zParserCredentialCreate + +export const zPostWorkspacesCurrentModelProvidersByProviderCredentialsPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentModelProvidersByProviderCredentialsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPutWorkspacesCurrentModelProvidersByProviderCredentialsBody = zParserCredentialUpdate + +export const zPutWorkspacesCurrentModelProvidersByProviderCredentialsPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPutWorkspacesCurrentModelProvidersByProviderCredentialsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchBody + = zParserCredentialSwitch + +export const zPostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentModelProvidersByProviderCredentialsSwitchResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentModelProvidersByProviderCredentialsValidateBody + = zParserCredentialValidate + +export const zPostWorkspacesCurrentModelProvidersByProviderCredentialsValidatePath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentModelProvidersByProviderCredentialsValidateResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsBody = zParserDeleteModels + +export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentModelProvidersByProviderModelsPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentModelProvidersByProviderModelsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentModelProvidersByProviderModelsBody = zParserPostModels + +export const zPostWorkspacesCurrentModelProvidersByProviderModelsPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentModelProvidersByProviderModelsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsBody + = zParserDeleteCredential + +export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath = z.object({ + provider: z.string(), +}) + +export const zGetWorkspacesCurrentModelProvidersByProviderModelsCredentialsQuery = z.object({ + config_from: z.string().nullish(), + credential_id: z.string().nullish(), + model: z.string(), + model_type: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsBody + = zParserCreateCredential + +export const zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPutWorkspacesCurrentModelProvidersByProviderModelsCredentialsBody + = zParserUpdateCredential + +export const zPutWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPutWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchBody + = zParserSwitch + +export const zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsSwitchResponse + = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidateBody + = zParserValidate + +export const zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidatePath = z.object( + { + provider: z.string(), + }, +) + +/** + * Success + */ +export const zPostWorkspacesCurrentModelProvidersByProviderModelsCredentialsValidateResponse + = z.record(z.string(), z.unknown()) + +export const zPatchWorkspacesCurrentModelProvidersByProviderModelsDisableBody = zParserDeleteModels + +export const zPatchWorkspacesCurrentModelProvidersByProviderModelsDisablePath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPatchWorkspacesCurrentModelProvidersByProviderModelsDisableResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchWorkspacesCurrentModelProvidersByProviderModelsEnableBody = zParserDeleteModels + +export const zPatchWorkspacesCurrentModelProvidersByProviderModelsEnablePath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPatchWorkspacesCurrentModelProvidersByProviderModelsEnableResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidateBody + = zLoadBalancingCredentialPayload + +export const zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidatePath + = z.object({ + provider: z.string(), + }) + +/** + * Success + */ +export const zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsCredentialsValidateResponse + = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidateBody + = zLoadBalancingCredentialPayload + +export const zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidatePath + = z.object({ + provider: z.string(), + config_id: z.string(), + }) + +/** + * Success + */ +export const zPostWorkspacesCurrentModelProvidersByProviderModelsLoadBalancingConfigsByConfigIdCredentialsValidateResponse + = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesPath = z.object({ + provider: z.string(), +}) + +export const zGetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesQuery = z.object({ + model: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypeBody + = zParserPreferredProviderType + +export const zPostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypePath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentModelProvidersByProviderPreferredProviderTypeResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentModelsModelTypesByModelTypePath = z.object({ + model_type: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentModelsModelTypesByModelTypeResponse = z.record( + z.string(), + z.unknown(), +) + +/** + * Success + */ +export const zGetWorkspacesCurrentPermissionResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentPluginAssetQuery = z.object({ + file_name: z.string(), + plugin_unique_identifier: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentPluginAssetResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetWorkspacesCurrentPluginDebuggingKeyResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentPluginFetchManifestQuery = z.object({ + plugin_unique_identifier: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentPluginFetchManifestResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentPluginIconQuery = z.object({ + filename: z.string(), + tenant_id: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentPluginIconResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentPluginInstallGithubBody = zParserGithubInstall + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginInstallGithubResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentPluginInstallMarketplaceBody = zParserPluginIdentifiers + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginInstallMarketplaceResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentPluginInstallPkgBody = zParserPluginIdentifiers + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginInstallPkgResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentPluginListQuery = z.object({ + page: z.int().gte(1).optional().default(1), + page_size: z.int().gte(1).lte(256).optional().default(256), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentPluginListResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentPluginListInstallationsIdsBody = zParserLatest + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginListInstallationsIdsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentPluginListLatestVersionsBody = zParserLatest + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginListLatestVersionsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentPluginMarketplacePkgQuery = z.object({ + plugin_unique_identifier: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentPluginMarketplacePkgResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentPluginParametersDynamicOptionsQuery = z.object({ + action: z.string(), + credential_id: z.string().nullish(), + parameter: z.string(), + plugin_id: z.string(), + provider: z.string(), + provider_type: z.enum(['tool', 'trigger']), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentPluginParametersDynamicOptionsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentPluginParametersDynamicOptionsWithCredentialsBody + = zParserDynamicOptionsWithCredentials + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginParametersDynamicOptionsWithCredentialsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentPluginPermissionChangeBody = zParserPermissionChange + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginPermissionChangeResponse = z.record( + z.string(), + z.unknown(), +) + +/** + * Success + */ +export const zGetWorkspacesCurrentPluginPermissionFetchResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentPluginPreferencesAutoupgradeExcludeBody = zParserExcludePlugin + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginPreferencesAutoupgradeExcludeResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentPluginPreferencesChangeBody = zParserPreferencesChange + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginPreferencesChangeResponse = z.record( + z.string(), + z.unknown(), +) + +/** + * Success + */ +export const zGetWorkspacesCurrentPluginPreferencesFetchResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentPluginReadmeQuery = z.object({ + language: z.string().optional().default('en-US'), + plugin_unique_identifier: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentPluginReadmeResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentPluginTasksQuery = z.object({ + page: z.int().gte(1).optional().default(1), + page_size: z.int().gte(1).lte(256).optional().default(256), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentPluginTasksResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginTasksDeleteAllResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentPluginTasksByTaskIdPath = z.object({ + task_id: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentPluginTasksByTaskIdResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentPluginTasksByTaskIdDeletePath = z.object({ + task_id: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginTasksByTaskIdDeleteResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentPluginTasksByTaskIdDeleteByIdentifierPath = z.object({ + task_id: z.string(), + identifier: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginTasksByTaskIdDeleteByIdentifierResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentPluginUninstallBody = zParserUninstall + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginUninstallResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentPluginUpgradeGithubBody = zParserGithubUpgrade + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginUpgradeGithubResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentPluginUpgradeMarketplaceBody = zParserMarketplaceUpgrade + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginUpgradeMarketplaceResponse = z.record( + z.string(), + z.unknown(), +) + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginUploadBundleResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentPluginUploadGithubBody = zParserGithubUpload + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginUploadGithubResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPostWorkspacesCurrentPluginUploadPkgResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolLabelsResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentToolProviderApiAddBody = zApiToolProviderAddPayload + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderApiAddResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentToolProviderApiDeleteBody = zApiToolProviderDeletePayload + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderApiDeleteResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderApiGetResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderApiRemoteResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentToolProviderApiSchemaBody = zApiToolSchemaPayload + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderApiSchemaResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentToolProviderApiTestPreBody = zApiToolTestPayload + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderApiTestPreResponse = z.record( + z.string(), + z.unknown(), +) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderApiToolsResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentToolProviderApiUpdateBody = zApiToolProviderUpdatePayload + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderApiUpdateResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderAddBody = zBuiltinToolAddPayload + +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderAddPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderAddResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypePath + = z.object({ + provider: z.string(), + credential_type: z.string(), + }) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypeResponse + = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialBody + = zBuiltinProviderDefaultCredentialPayload + +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialResponse + = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderDeleteBody + = zBuiltinToolCredentialDeletePayload + +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderDeletePath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderDeleteResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderIconPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderIconResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderInfoPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderInfoResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zDeleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse + = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientBody + = zToolOAuthCustomClientPayload + +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse + = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderToolsPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderBuiltinByProviderToolsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderUpdateBody + = zBuiltinToolUpdatePayload + +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderUpdatePath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderBuiltinByProviderUpdateResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteWorkspacesCurrentToolProviderMcpBody = zMcpProviderDeletePayload + +/** + * Success + */ +export const zDeleteWorkspacesCurrentToolProviderMcpResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentToolProviderMcpBody = zMcpProviderCreatePayload + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderMcpResponse = z.record(z.string(), z.unknown()) + +export const zPutWorkspacesCurrentToolProviderMcpBody = zMcpProviderUpdatePayload + +/** + * Success + */ +export const zPutWorkspacesCurrentToolProviderMcpResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentToolProviderMcpAuthBody = zMcpAuthPayload + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderMcpAuthResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentToolProviderMcpToolsByProviderIdPath = z.object({ + provider_id: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderMcpToolsByProviderIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentToolProviderMcpUpdateByProviderIdPath = z.object({ + provider_id: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderMcpUpdateByProviderIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentToolProviderWorkflowCreateBody = zWorkflowToolCreatePayload + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderWorkflowCreateResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentToolProviderWorkflowDeleteBody = zWorkflowToolDeletePayload + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderWorkflowDeleteResponse = z.record( + z.string(), + z.unknown(), +) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderWorkflowGetResponse = z.record( + z.string(), + z.unknown(), +) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProviderWorkflowToolsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentToolProviderWorkflowUpdateBody = zWorkflowToolUpdatePayload + +/** + * Success + */ +export const zPostWorkspacesCurrentToolProviderWorkflowUpdateResponse = z.record( + z.string(), + z.unknown(), +) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolProvidersResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolsApiResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolsBuiltinResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolsMcpResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetWorkspacesCurrentToolsWorkflowResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentTriggerProviderByProviderIconPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentTriggerProviderByProviderIconResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentTriggerProviderByProviderInfoPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentTriggerProviderByProviderInfoResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteWorkspacesCurrentTriggerProviderByProviderOauthClientPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zDeleteWorkspacesCurrentTriggerProviderByProviderOauthClientResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentTriggerProviderByProviderOauthClientPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentTriggerProviderByProviderOauthClientResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentTriggerProviderByProviderOauthClientBody + = zTriggerOAuthClientPayload + +export const zPostWorkspacesCurrentTriggerProviderByProviderOauthClientPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zPostWorkspacesCurrentTriggerProviderByProviderOauthClientResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdBody + = zTriggerSubscriptionBuilderUpdatePayload + +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdPath + = z.object({ + provider: z.string(), + subscription_builder_id: z.string(), + }) + +/** + * Success + */ +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdResponse + = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreateBody + = zTriggerSubscriptionBuilderCreatePayload + +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreatePath + = z.object({ + provider: z.string(), + }) + +/** + * Success + */ +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderCreateResponse + = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderLogsBySubscriptionBuilderIdPath + = z.object({ + provider: z.string(), + subscription_builder_id: z.string(), + }) + +/** + * Success + */ +export const zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderLogsBySubscriptionBuilderIdResponse + = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdBody + = zTriggerSubscriptionBuilderUpdatePayload + +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdPath + = z.object({ + provider: z.string(), + subscription_builder_id: z.string(), + }) + +/** + * Success + */ +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderUpdateBySubscriptionBuilderIdResponse + = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdBody + = zTriggerSubscriptionBuilderVerifyPayload + +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdPath + = z.object({ + provider: z.string(), + subscription_builder_id: z.string(), + }) + +/** + * Success + */ +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdResponse + = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBySubscriptionBuilderIdPath + = z.object({ + provider: z.string(), + subscription_builder_id: z.string(), + }) + +/** + * Success + */ +export const zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBySubscriptionBuilderIdResponse + = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListPath = z.object({ + provider: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorizePath + = z.object({ + provider: z.string(), + }) + +/** + * Success + */ +export const zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorizeResponse + = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdBody + = zTriggerSubscriptionBuilderVerifyPayload + +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdPath + = z.object({ + provider: z.string(), + subscription_id: z.string(), + }) + +/** + * Success + */ +export const zPostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdResponse + = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsDeletePath + = z.object({ + subscription_id: z.string(), + }) + +/** + * Success + */ +export const zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsDeleteResponse + = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateBody + = zTriggerSubscriptionBuilderUpdatePayload + +export const zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdatePath + = z.object({ + subscription_id: z.string(), + }) + +/** + * Success + */ +export const zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateResponse + = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetWorkspacesCurrentTriggersResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesCustomConfigBody = zWorkspaceCustomConfigPayload + +/** + * Success + */ +export const zPostWorkspacesCustomConfigResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zPostWorkspacesCustomConfigWebappLogoUploadResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesInfoBody = zWorkspaceInfoPayload + +/** + * Success + */ +export const zPostWorkspacesInfoResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkspacesSwitchBody = zSwitchWorkspacePayload + +/** + * Success + */ +export const zPostWorkspacesSwitchResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLangPath = z.object({ + tenant_id: z.string(), + provider: z.string(), + icon_type: z.string(), + lang: z.string(), +}) + +/** + * Success + */ +export const zGetWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLangResponse = z.record( + z.string(), + z.unknown(), +) diff --git a/packages/contracts/generated/api/service/orpc.gen.ts b/packages/contracts/generated/api/service/orpc.gen.ts new file mode 100644 index 0000000000..a5a45a6452 --- /dev/null +++ b/packages/contracts/generated/api/service/orpc.gen.ts @@ -0,0 +1,2405 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteAppsAnnotationsByAnnotationIdPath, + zDeleteAppsAnnotationsByAnnotationIdResponse, + zDeleteConversationsByCIdPath, + zDeleteConversationsByCIdResponse, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdPath, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdPath, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath, + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse, + zDeleteDatasetsByDatasetIdMetadataByMetadataIdPath, + zDeleteDatasetsByDatasetIdMetadataByMetadataIdResponse, + zDeleteDatasetsByDatasetIdPath, + zDeleteDatasetsByDatasetIdResponse, + zDeleteDatasetsTagsBody, + zDeleteDatasetsTagsResponse, + zGetAppFeedbacksQuery, + zGetAppFeedbacksResponse, + zGetAppsAnnotationReplyByActionStatusByJobIdPath, + zGetAppsAnnotationReplyByActionStatusByJobIdResponse, + zGetAppsAnnotationsResponse, + zGetConversationsByCIdVariablesPath, + zGetConversationsByCIdVariablesQuery, + zGetConversationsByCIdVariablesResponse, + zGetConversationsQuery, + zGetConversationsResponse, + zGetDatasetsByDatasetIdDocumentsByBatchIndexingStatusPath, + zGetDatasetsByDatasetIdDocumentsByBatchIndexingStatusResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdDownloadPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksQuery, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsQuery, + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse, + zGetDatasetsByDatasetIdDocumentsPath, + zGetDatasetsByDatasetIdDocumentsResponse, + zGetDatasetsByDatasetIdMetadataBuiltInPath, + zGetDatasetsByDatasetIdMetadataBuiltInResponse, + zGetDatasetsByDatasetIdMetadataPath, + zGetDatasetsByDatasetIdMetadataResponse, + zGetDatasetsByDatasetIdPath, + zGetDatasetsByDatasetIdPipelineDatasourcePluginsPath, + zGetDatasetsByDatasetIdPipelineDatasourcePluginsQuery, + zGetDatasetsByDatasetIdPipelineDatasourcePluginsResponse, + zGetDatasetsByDatasetIdResponse, + zGetDatasetsByDatasetIdTagsPath, + zGetDatasetsByDatasetIdTagsResponse, + zGetDatasetsResponse, + zGetDatasetsTagsResponse, + zGetEndUsersByEndUserIdPath, + zGetEndUsersByEndUserIdResponse, + zGetFilesByFileIdPreviewPath, + zGetFilesByFileIdPreviewQuery, + zGetFilesByFileIdPreviewResponse, + zGetFormHumanInputByFormTokenPath, + zGetFormHumanInputByFormTokenResponse, + zGetInfoResponse, + zGetMessagesByMessageIdSuggestedPath, + zGetMessagesByMessageIdSuggestedResponse, + zGetMessagesQuery, + zGetMessagesResponse, + zGetMetaResponse, + zGetParametersResponse, + zGetRootResponse, + zGetSiteResponse, + zGetWorkflowByTaskIdEventsPath, + zGetWorkflowByTaskIdEventsQuery, + zGetWorkflowByTaskIdEventsResponse, + zGetWorkflowsLogsQuery, + zGetWorkflowsLogsResponse, + zGetWorkflowsRunByWorkflowRunIdPath, + zGetWorkflowsRunByWorkflowRunIdResponse, + zGetWorkspacesCurrentModelsModelTypesByModelTypePath, + zGetWorkspacesCurrentModelsModelTypesByModelTypeResponse, + zPatchDatasetsByDatasetIdBody, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdPath, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdResponse, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdBody, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdPath, + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse, + zPatchDatasetsByDatasetIdDocumentsStatusByActionPath, + zPatchDatasetsByDatasetIdDocumentsStatusByActionResponse, + zPatchDatasetsByDatasetIdMetadataByMetadataIdBody, + zPatchDatasetsByDatasetIdMetadataByMetadataIdPath, + zPatchDatasetsByDatasetIdMetadataByMetadataIdResponse, + zPatchDatasetsByDatasetIdPath, + zPatchDatasetsByDatasetIdResponse, + zPatchDatasetsTagsBody, + zPatchDatasetsTagsResponse, + zPostAppsAnnotationReplyByActionBody, + zPostAppsAnnotationReplyByActionPath, + zPostAppsAnnotationReplyByActionResponse, + zPostAppsAnnotationsBody, + zPostAppsAnnotationsResponse, + zPostAudioToTextResponse, + zPostChatMessagesBody, + zPostChatMessagesByTaskIdStopPath, + zPostChatMessagesByTaskIdStopResponse, + zPostChatMessagesResponse, + zPostCompletionMessagesBody, + zPostCompletionMessagesByTaskIdStopPath, + zPostCompletionMessagesByTaskIdStopResponse, + zPostCompletionMessagesResponse, + zPostConversationsByCIdNameBody, + zPostConversationsByCIdNamePath, + zPostConversationsByCIdNameResponse, + zPostDatasetsBody, + zPostDatasetsByDatasetIdDocumentCreateByFile2Path, + zPostDatasetsByDatasetIdDocumentCreateByFile2Response, + zPostDatasetsByDatasetIdDocumentCreateByFilePath, + zPostDatasetsByDatasetIdDocumentCreateByFileResponse, + zPostDatasetsByDatasetIdDocumentCreateByText2Body, + zPostDatasetsByDatasetIdDocumentCreateByText2Path, + zPostDatasetsByDatasetIdDocumentCreateByText2Response, + zPostDatasetsByDatasetIdDocumentCreateByTextBody, + zPostDatasetsByDatasetIdDocumentCreateByTextPath, + zPostDatasetsByDatasetIdDocumentCreateByTextResponse, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBody, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdBody, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksBody, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath, + zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse, + zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Path, + zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Response, + zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFilePath, + zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFileResponse, + zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Body, + zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Path, + zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Response, + zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextBody, + zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextPath, + zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextResponse, + zPostDatasetsByDatasetIdDocumentsDownloadZipBody, + zPostDatasetsByDatasetIdDocumentsDownloadZipPath, + zPostDatasetsByDatasetIdDocumentsDownloadZipResponse, + zPostDatasetsByDatasetIdDocumentsMetadataBody, + zPostDatasetsByDatasetIdDocumentsMetadataPath, + zPostDatasetsByDatasetIdDocumentsMetadataResponse, + zPostDatasetsByDatasetIdHitTestingBody, + zPostDatasetsByDatasetIdHitTestingPath, + zPostDatasetsByDatasetIdHitTestingResponse, + zPostDatasetsByDatasetIdMetadataBody, + zPostDatasetsByDatasetIdMetadataBuiltInByActionPath, + zPostDatasetsByDatasetIdMetadataBuiltInByActionResponse, + zPostDatasetsByDatasetIdMetadataPath, + zPostDatasetsByDatasetIdMetadataResponse, + zPostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunPath, + zPostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunResponse, + zPostDatasetsByDatasetIdPipelineRunPath, + zPostDatasetsByDatasetIdPipelineRunResponse, + zPostDatasetsByDatasetIdRetrieveBody, + zPostDatasetsByDatasetIdRetrievePath, + zPostDatasetsByDatasetIdRetrieveResponse, + zPostDatasetsPipelineFileUploadResponse, + zPostDatasetsResponse, + zPostDatasetsTagsBindingBody, + zPostDatasetsTagsBindingResponse, + zPostDatasetsTagsBody, + zPostDatasetsTagsResponse, + zPostDatasetsTagsUnbindingBody, + zPostDatasetsTagsUnbindingResponse, + zPostFilesUploadResponse, + zPostFormHumanInputByFormTokenBody, + zPostFormHumanInputByFormTokenPath, + zPostFormHumanInputByFormTokenResponse, + zPostMessagesByMessageIdFeedbacksBody, + zPostMessagesByMessageIdFeedbacksPath, + zPostMessagesByMessageIdFeedbacksResponse, + zPostTextToAudioBody, + zPostTextToAudioResponse, + zPostWorkflowsByWorkflowIdRunBody, + zPostWorkflowsByWorkflowIdRunPath, + zPostWorkflowsByWorkflowIdRunResponse, + zPostWorkflowsRunBody, + zPostWorkflowsRunResponse, + zPostWorkflowsTasksByTaskIdStopPath, + zPostWorkflowsTasksByTaskIdStopResponse, + zPutAppsAnnotationsByAnnotationIdBody, + zPutAppsAnnotationsByAnnotationIdPath, + zPutAppsAnnotationsByAnnotationIdResponse, + zPutConversationsByCIdVariablesByVariableIdBody, + zPutConversationsByCIdVariablesByVariableIdPath, + zPutConversationsByCIdVariablesByVariableIdResponse, +} from './zod.gen' + +export const get = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRoot', + path: '/', + tags: ['service_api'], + }) + .output(zGetRootResponse) + +export const root = { + get, +} + +/** + * Get all feedbacks for the application + * + * Get all feedbacks for the application + * Returns paginated list of all feedback submitted for messages in this app. + */ +export const get2 = oc + .route({ + description: + 'Get all feedbacks for the application\nReturns paginated list of all feedback submitted for messages in this app.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppFeedbacks', + path: '/app/feedbacks', + summary: 'Get all feedbacks for the application', + tags: ['service_api'], + }) + .input(z.object({ query: zGetAppFeedbacksQuery.optional() })) + .output(zGetAppFeedbacksResponse) + +export const feedbacks = { + get: get2, +} + +export const app = { + feedbacks, +} + +/** + * Get the status of an annotation reply action job + * + * Get the status of an annotation reply action job + */ +export const get3 = oc + .route({ + description: 'Get the status of an annotation reply action job', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsAnnotationReplyByActionStatusByJobId', + path: '/apps/annotation-reply/{action}/status/{job_id}', + summary: 'Get the status of an annotation reply action job', + tags: ['service_api'], + }) + .input(z.object({ params: zGetAppsAnnotationReplyByActionStatusByJobIdPath })) + .output(zGetAppsAnnotationReplyByActionStatusByJobIdResponse) + +export const byJobId = { + get: get3, +} + +export const status = { + byJobId, +} + +/** + * Enable or disable annotation reply feature + * + * Enable or disable annotation reply feature + */ +export const post = oc + .route({ + description: 'Enable or disable annotation reply feature', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsAnnotationReplyByAction', + path: '/apps/annotation-reply/{action}', + summary: 'Enable or disable annotation reply feature', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostAppsAnnotationReplyByActionBody, + params: zPostAppsAnnotationReplyByActionPath, + }), + ) + .output(zPostAppsAnnotationReplyByActionResponse) + +export const byAction = { + post, + status, +} + +export const annotationReply = { + byAction, +} + +/** + * Delete an annotation + * + * Delete an annotation + */ +export const delete_ = oc + .route({ + description: 'Delete an annotation', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteAppsAnnotationsByAnnotationId', + path: '/apps/annotations/{annotation_id}', + successStatus: 204, + summary: 'Delete an annotation', + tags: ['service_api'], + }) + .input(z.object({ params: zDeleteAppsAnnotationsByAnnotationIdPath })) + .output(zDeleteAppsAnnotationsByAnnotationIdResponse) + +/** + * Update an existing annotation + * + * Update an existing annotation + */ +export const put = oc + .route({ + description: 'Update an existing annotation', + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putAppsAnnotationsByAnnotationId', + path: '/apps/annotations/{annotation_id}', + summary: 'Update an existing annotation', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPutAppsAnnotationsByAnnotationIdBody, + params: zPutAppsAnnotationsByAnnotationIdPath, + }), + ) + .output(zPutAppsAnnotationsByAnnotationIdResponse) + +export const byAnnotationId = { + delete: delete_, + put, +} + +/** + * List annotations for the application + * + * List annotations for the application + */ +export const get4 = oc + .route({ + description: 'List annotations for the application', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getAppsAnnotations', + path: '/apps/annotations', + summary: 'List annotations for the application', + tags: ['service_api'], + }) + .output(zGetAppsAnnotationsResponse) + +/** + * Create a new annotation + * + * Create a new annotation + */ +export const post2 = oc + .route({ + description: 'Create a new annotation', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAppsAnnotations', + path: '/apps/annotations', + successStatus: 201, + summary: 'Create a new annotation', + tags: ['service_api'], + }) + .input(z.object({ body: zPostAppsAnnotationsBody })) + .output(zPostAppsAnnotationsResponse) + +export const annotations = { + get: get4, + post: post2, + byAnnotationId, +} + +export const apps = { + annotationReply, + annotations, +} + +/** + * Convert audio to text using speech-to-text + * + * Convert audio to text using speech-to-text + * Accepts an audio file upload and returns the transcribed text. + */ +export const post3 = oc + .route({ + description: + 'Convert audio to text using speech-to-text\nAccepts an audio file upload and returns the transcribed text.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAudioToText', + path: '/audio-to-text', + summary: 'Convert audio to text using speech-to-text', + tags: ['service_api'], + }) + .output(zPostAudioToTextResponse) + +export const audioToText = { + post: post3, +} + +/** + * Stop a running chat message generation + * + * Stop a running chat message generation + */ +export const post4 = oc + .route({ + description: 'Stop a running chat message generation', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postChatMessagesByTaskIdStop', + path: '/chat-messages/{task_id}/stop', + summary: 'Stop a running chat message generation', + tags: ['service_api'], + }) + .input(z.object({ params: zPostChatMessagesByTaskIdStopPath })) + .output(zPostChatMessagesByTaskIdStopResponse) + +export const stop = { + post: post4, +} + +export const byTaskId = { + stop, +} + +/** + * Send a message in a chat conversation + * + * Send a message in a chat conversation + * This endpoint handles chat messages for chat, agent chat, and advanced chat applications. + * Supports conversation management and both blocking and streaming response modes. + */ +export const post5 = oc + .route({ + description: + 'Send a message in a chat conversation\nThis endpoint handles chat messages for chat, agent chat, and advanced chat applications.\nSupports conversation management and both blocking and streaming response modes.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postChatMessages', + path: '/chat-messages', + summary: 'Send a message in a chat conversation', + tags: ['service_api'], + }) + .input(z.object({ body: zPostChatMessagesBody })) + .output(zPostChatMessagesResponse) + +export const chatMessages = { + post: post5, + byTaskId, +} + +/** + * Stop a running completion task + * + * Stop a running completion task + */ +export const post6 = oc + .route({ + description: 'Stop a running completion task', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postCompletionMessagesByTaskIdStop', + path: '/completion-messages/{task_id}/stop', + summary: 'Stop a running completion task', + tags: ['service_api'], + }) + .input(z.object({ params: zPostCompletionMessagesByTaskIdStopPath })) + .output(zPostCompletionMessagesByTaskIdStopResponse) + +export const stop2 = { + post: post6, +} + +export const byTaskId2 = { + stop: stop2, +} + +/** + * Create a completion for the given prompt + * + * Create a completion for the given prompt + * This endpoint generates a completion based on the provided inputs and query. + * Supports both blocking and streaming response modes. + */ +export const post7 = oc + .route({ + description: + 'Create a completion for the given prompt\nThis endpoint generates a completion based on the provided inputs and query.\nSupports both blocking and streaming response modes.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postCompletionMessages', + path: '/completion-messages', + summary: 'Create a completion for the given prompt', + tags: ['service_api'], + }) + .input(z.object({ body: zPostCompletionMessagesBody })) + .output(zPostCompletionMessagesResponse) + +export const completionMessages = { + post: post7, + byTaskId: byTaskId2, +} + +/** + * Rename a conversation or auto-generate a name + * + * Rename a conversation or auto-generate a name + */ +export const post8 = oc + .route({ + description: 'Rename a conversation or auto-generate a name', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postConversationsByCIdName', + path: '/conversations/{c_id}/name', + summary: 'Rename a conversation or auto-generate a name', + tags: ['service_api'], + }) + .input( + z.object({ body: zPostConversationsByCIdNameBody, params: zPostConversationsByCIdNamePath }), + ) + .output(zPostConversationsByCIdNameResponse) + +export const name = { + post: post8, +} + +/** + * Update a conversation variable's value + * + * Update a conversation variable's value + * Allows updating the value of a specific conversation variable. + * The value must match the variable's expected type. + */ +export const put2 = oc + .route({ + description: + 'Update a conversation variable\'s value\nAllows updating the value of a specific conversation variable.\nThe value must match the variable\'s expected type.', + inputStructure: 'detailed', + method: 'PUT', + operationId: 'putConversationsByCIdVariablesByVariableId', + path: '/conversations/{c_id}/variables/{variable_id}', + summary: 'Update a conversation variable\'s value', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPutConversationsByCIdVariablesByVariableIdBody, + params: zPutConversationsByCIdVariablesByVariableIdPath, + }), + ) + .output(zPutConversationsByCIdVariablesByVariableIdResponse) + +export const byVariableId = { + put: put2, +} + +/** + * List all variables for a conversation + * + * List all variables for a conversation + * Conversational variables are only available for chat applications. + */ +export const get5 = oc + .route({ + description: + 'List all variables for a conversation\nConversational variables are only available for chat applications.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getConversationsByCIdVariables', + path: '/conversations/{c_id}/variables', + summary: 'List all variables for a conversation', + tags: ['service_api'], + }) + .input( + z.object({ + params: zGetConversationsByCIdVariablesPath, + query: zGetConversationsByCIdVariablesQuery.optional(), + }), + ) + .output(zGetConversationsByCIdVariablesResponse) + +export const variables = { + get: get5, + byVariableId, +} + +/** + * Delete a specific conversation + * + * Delete a specific conversation + */ +export const delete2 = oc + .route({ + description: 'Delete a specific conversation', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteConversationsByCId', + path: '/conversations/{c_id}', + successStatus: 204, + summary: 'Delete a specific conversation', + tags: ['service_api'], + }) + .input(z.object({ params: zDeleteConversationsByCIdPath })) + .output(zDeleteConversationsByCIdResponse) + +export const byCId = { + delete: delete2, + name, + variables, +} + +/** + * List all conversations for the current user + * + * List all conversations for the current user + * Supports pagination using last_id and limit parameters. + */ +export const get6 = oc + .route({ + description: + 'List all conversations for the current user\nSupports pagination using last_id and limit parameters.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getConversations', + path: '/conversations', + summary: 'List all conversations for the current user', + tags: ['service_api'], + }) + .input(z.object({ query: zGetConversationsQuery.optional() })) + .output(zGetConversationsResponse) + +export const conversations = { + get: get6, + byCId, +} + +/** + * Upload a file for use in conversations + * + * Upload a file to a knowledgebase pipeline + * Accepts a single file upload via multipart/form-data. + */ +export const post9 = oc + .route({ + description: + 'Upload a file to a knowledgebase pipeline\nAccepts a single file upload via multipart/form-data.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsPipelineFileUpload', + path: '/datasets/pipeline/file-upload', + successStatus: 201, + summary: 'Upload a file for use in conversations', + tags: ['service_api'], + }) + .output(zPostDatasetsPipelineFileUploadResponse) + +export const fileUpload = { + post: post9, +} + +export const pipeline = { + fileUpload, +} + +/** + * Bind tags to a dataset + */ +export const post10 = oc + .route({ + description: 'Bind tags to a dataset', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsTagsBinding', + path: '/datasets/tags/binding', + successStatus: 204, + tags: ['service_api'], + }) + .input(z.object({ body: zPostDatasetsTagsBindingBody })) + .output(zPostDatasetsTagsBindingResponse) + +export const binding = { + post: post10, +} + +/** + * Unbind a tag from a dataset + */ +export const post11 = oc + .route({ + description: 'Unbind a tag from a dataset', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsTagsUnbinding', + path: '/datasets/tags/unbinding', + successStatus: 204, + tags: ['service_api'], + }) + .input(z.object({ body: zPostDatasetsTagsUnbindingBody })) + .output(zPostDatasetsTagsUnbindingResponse) + +export const unbinding = { + post: post11, +} + +/** + * Delete a knowledge type tag + * + * Delete a knowledge type tag + */ +export const delete3 = oc + .route({ + description: 'Delete a knowledge type tag', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsTags', + path: '/datasets/tags', + successStatus: 204, + summary: 'Delete a knowledge type tag', + tags: ['service_api'], + }) + .input(z.object({ body: zDeleteDatasetsTagsBody })) + .output(zDeleteDatasetsTagsResponse) + +/** + * Get all knowledge type tags + * + * Get all knowledge type tags + */ +export const get7 = oc + .route({ + description: 'Get all knowledge type tags', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsTags', + path: '/datasets/tags', + summary: 'Get all knowledge type tags', + tags: ['service_api'], + }) + .output(zGetDatasetsTagsResponse) + +/** + * Update a knowledge type tag + */ +export const patch = oc + .route({ + description: 'Update a knowledge type tag', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsTags', + path: '/datasets/tags', + tags: ['service_api'], + }) + .input(z.object({ body: zPatchDatasetsTagsBody })) + .output(zPatchDatasetsTagsResponse) + +/** + * Add a knowledge type tag + * + * Add a knowledge type tag + */ +export const post12 = oc + .route({ + description: 'Add a knowledge type tag', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsTags', + path: '/datasets/tags', + summary: 'Add a knowledge type tag', + tags: ['service_api'], + }) + .input(z.object({ body: zPostDatasetsTagsBody })) + .output(zPostDatasetsTagsResponse) + +export const tags = { + delete: delete3, + get: get7, + patch, + post: post12, + binding, + unbinding, +} + +/** + * Create a new document by uploading a file + */ +export const post13 = oc + .route({ + description: 'Create a new document by uploading a file', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentCreateByFile', + path: '/datasets/{dataset_id}/document/create-by-file', + tags: ['service_api'], + }) + .input(z.object({ params: zPostDatasetsByDatasetIdDocumentCreateByFilePath })) + .output(zPostDatasetsByDatasetIdDocumentCreateByFileResponse) + +/** + * Create a new document by uploading a file + */ +export const post14 = oc + .route({ + description: 'Create a new document by uploading a file', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentCreateByFile', + path: '/datasets/{dataset_id}/document/create_by_file', + tags: ['service_api'], + }) + .input(z.object({ params: zPostDatasetsByDatasetIdDocumentCreateByFile2Path })) + .output(zPostDatasetsByDatasetIdDocumentCreateByFile2Response) + +export const createByFile = { + post: post14, +} + +/** + * Create a new document by providing text content + */ +export const post15 = oc + .route({ + description: 'Create a new document by providing text content', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentCreateByText', + path: '/datasets/{dataset_id}/document/create-by-text', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentCreateByTextBody, + params: zPostDatasetsByDatasetIdDocumentCreateByTextPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentCreateByTextResponse) + +/** + * Deprecated legacy alias for creating a new document by providing text content. Use /datasets/{dataset_id}/document/create-by-text instead. + * + * @deprecated + */ +export const post16 = oc + .route({ + deprecated: true, + description: + 'Deprecated legacy alias for creating a new document by providing text content. Use /datasets/{dataset_id}/document/create-by-text instead.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentCreateByText', + path: '/datasets/{dataset_id}/document/create_by_text', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentCreateByText2Body, + params: zPostDatasetsByDatasetIdDocumentCreateByText2Path, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentCreateByText2Response) + +export const createByText = { + post: post16, +} + +export const document_ = { + createByFile, + createByText, +} + +/** + * Download selected uploaded documents as a single ZIP archive + */ +export const post17 = oc + .route({ + description: 'Download selected uploaded documents as a single ZIP archive', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsDownloadZip', + path: '/datasets/{dataset_id}/documents/download-zip', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsDownloadZipBody, + params: zPostDatasetsByDatasetIdDocumentsDownloadZipPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsDownloadZipResponse) + +export const downloadZip = { + post: post17, +} + +/** + * Update metadata for multiple documents + * + * Update metadata for multiple documents + */ +export const post18 = oc + .route({ + description: 'Update metadata for multiple documents', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsMetadata', + path: '/datasets/{dataset_id}/documents/metadata', + summary: 'Update metadata for multiple documents', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsMetadataBody, + params: zPostDatasetsByDatasetIdDocumentsMetadataPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsMetadataResponse) + +export const metadata = { + post: post18, +} + +/** + * Batch update document status + * + * Batch update document status + * Args: + * tenant_id: tenant id + * dataset_id: dataset id + * action: action to perform (Literal["enable", "disable", "archive", "un_archive"]) + * + * Returns: + * dict: A dictionary with a key 'result' and a value 'success' + * int: HTTP status code 200 indicating that the operation was successful. + * + * Raises: + * NotFound: If the dataset with the given ID does not exist. + * Forbidden: If the user does not have permission. + * InvalidActionError: If the action is invalid or cannot be performed. + */ +export const patch2 = oc + .route({ + description: + 'Batch update document status\nArgs:\n tenant_id: tenant id\n dataset_id: dataset id\n action: action to perform (Literal["enable", "disable", "archive", "un_archive"])\n\nReturns:\n dict: A dictionary with a key \'result\' and a value \'success\'\n int: HTTP status code 200 indicating that the operation was successful.\n\nRaises:\n NotFound: If the dataset with the given ID does not exist.\n Forbidden: If the user does not have permission.\n InvalidActionError: If the action is invalid or cannot be performed.', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetIdDocumentsStatusByAction', + path: '/datasets/{dataset_id}/documents/status/{action}', + summary: 'Batch update document status', + tags: ['service_api'], + }) + .input(z.object({ params: zPatchDatasetsByDatasetIdDocumentsStatusByActionPath })) + .output(zPatchDatasetsByDatasetIdDocumentsStatusByActionResponse) + +export const byAction2 = { + patch: patch2, +} + +export const status2 = { + byAction: byAction2, +} + +/** + * Get indexing status for documents in a batch + */ +export const get8 = oc + .route({ + description: 'Get indexing status for documents in a batch', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByBatchIndexingStatus', + path: '/datasets/{dataset_id}/documents/{batch}/indexing-status', + tags: ['service_api'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByBatchIndexingStatusPath })) + .output(zGetDatasetsByDatasetIdDocumentsByBatchIndexingStatusResponse) + +export const indexingStatus = { + get: get8, +} + +export const byBatch = { + indexingStatus, +} + +/** + * Get a signed download URL for a document's original uploaded file + */ +export const get9 = oc + .route({ + description: 'Get a signed download URL for a document\'s original uploaded file', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdDownload', + path: '/datasets/{dataset_id}/documents/{document_id}/download', + tags: ['service_api'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByDocumentIdDownloadPath })) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponse) + +export const download = { + get: get9, +} + +/** + * Delete a specific child chunk + */ +export const delete4 = oc + .route({ + description: 'Delete a specific child chunk', + inputStructure: 'detailed', + method: 'DELETE', + operationId: + 'deleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkId', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}', + successStatus: 204, + tags: ['service_api'], + }) + .input( + z.object({ + params: + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdPath, + }), + ) + .output( + zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse, + ) + +/** + * Update a specific child chunk + */ +export const patch3 = oc + .route({ + description: 'Update a specific child chunk', + inputStructure: 'detailed', + method: 'PATCH', + operationId: + 'patchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkId', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdBody, + params: + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdPath, + }), + ) + .output( + zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse, + ) + +export const byChildChunkId = { + delete: delete4, + patch: patch3, +} + +/** + * List child chunks for a segment + */ +export const get10 = oc + .route({ + description: 'List child chunks for a segment', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunks', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks', + tags: ['service_api'], + }) + .input( + z.object({ + params: zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath, + query: + zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksQuery.optional(), + }), + ) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse) + +/** + * Create a new child chunk for a segment + */ +export const post19 = oc + .route({ + description: 'Create a new child chunk for a segment', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunks', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksBody, + params: zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse) + +export const childChunks = { + get: get10, + post: post19, + byChildChunkId, +} + +/** + * Delete a specific segment + */ +export const delete5 = oc + .route({ + description: 'Delete a specific segment', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentId', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}', + successStatus: 204, + tags: ['service_api'], + }) + .input( + z.object({ params: zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath }), + ) + .output(zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse) + +/** + * Get a specific segment by ID + */ +export const get11 = oc + .route({ + description: 'Get a specific segment by ID', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentId', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}', + tags: ['service_api'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath })) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse) + +/** + * Update a specific segment + */ +export const post20 = oc + .route({ + description: 'Update a specific segment', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentId', + path: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdBody, + params: zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse) + +export const bySegmentId = { + delete: delete5, + get: get11, + post: post20, + childChunks, +} + +/** + * List segments in a document + */ +export const get12 = oc + .route({ + description: 'List segments in a document', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentIdSegments', + path: '/datasets/{dataset_id}/documents/{document_id}/segments', + tags: ['service_api'], + }) + .input( + z.object({ + params: zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath, + query: zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsQuery.optional(), + }), + ) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse) + +/** + * Create segments in a document + */ +export const post21 = oc + .route({ + description: 'Create segments in a document', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsByDocumentIdSegments', + path: '/datasets/{dataset_id}/documents/{document_id}/segments', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBody, + params: zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse) + +export const segments = { + get: get12, + post: post21, + bySegmentId, +} + +/** + * Deprecated legacy alias for updating an existing document by uploading a file. Use PATCH /datasets/{dataset_id}/documents/{document_id} instead. + * + * @deprecated + */ +export const post22 = oc + .route({ + deprecated: true, + description: + 'Deprecated legacy alias for updating an existing document by uploading a file. Use PATCH /datasets/{dataset_id}/documents/{document_id} instead.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile', + path: '/datasets/{dataset_id}/documents/{document_id}/update-by-file', + tags: ['service_api'], + }) + .input(z.object({ params: zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFilePath })) + .output(zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFileResponse) + +/** + * Deprecated legacy alias for updating an existing document by uploading a file. Use PATCH /datasets/{dataset_id}/documents/{document_id} instead. + * + * @deprecated + */ +export const post23 = oc + .route({ + deprecated: true, + description: + 'Deprecated legacy alias for updating an existing document by uploading a file. Use PATCH /datasets/{dataset_id}/documents/{document_id} instead.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile', + path: '/datasets/{dataset_id}/documents/{document_id}/update_by_file', + tags: ['service_api'], + }) + .input(z.object({ params: zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Path })) + .output(zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Response) + +export const updateByFile = { + post: post23, +} + +/** + * Update an existing document by providing text content + */ +export const post24 = oc + .route({ + description: 'Update an existing document by providing text content', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText', + path: '/datasets/{dataset_id}/documents/{document_id}/update-by-text', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextBody, + params: zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextPath, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextResponse) + +/** + * Deprecated legacy alias for updating an existing document by providing text content. Use /datasets/{dataset_id}/documents/{document_id}/update-by-text instead. + * + * @deprecated + */ +export const post25 = oc + .route({ + deprecated: true, + description: + 'Deprecated legacy alias for updating an existing document by providing text content. Use /datasets/{dataset_id}/documents/{document_id}/update-by-text instead.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText', + path: '/datasets/{dataset_id}/documents/{document_id}/update_by_text', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Body, + params: zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Path, + }), + ) + .output(zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Response) + +export const updateByText = { + post: post25, +} + +/** + * Delete document + * + * Delete a document + */ +export const delete6 = oc + .route({ + description: 'Delete a document', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsByDatasetIdDocumentsByDocumentId', + path: '/datasets/{dataset_id}/documents/{document_id}', + successStatus: 204, + summary: 'Delete document', + tags: ['service_api'], + }) + .input(z.object({ params: zDeleteDatasetsByDatasetIdDocumentsByDocumentIdPath })) + .output(zDeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse) + +/** + * Get a specific document by ID + */ +export const get13 = oc + .route({ + description: 'Get a specific document by ID', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocumentsByDocumentId', + path: '/datasets/{dataset_id}/documents/{document_id}', + tags: ['service_api'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsByDocumentIdPath })) + .output(zGetDatasetsByDatasetIdDocumentsByDocumentIdResponse) + +/** + * Update an existing document by uploading a file + */ +export const patch4 = oc + .route({ + description: 'Update an existing document by uploading a file', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetIdDocumentsByDocumentId', + path: '/datasets/{dataset_id}/documents/{document_id}', + tags: ['service_api'], + }) + .input(z.object({ params: zPatchDatasetsByDatasetIdDocumentsByDocumentIdPath })) + .output(zPatchDatasetsByDatasetIdDocumentsByDocumentIdResponse) + +export const byDocumentId = { + delete: delete6, + get: get13, + patch: patch4, + download, + segments, + updateByFile, + updateByText, +} + +/** + * List all documents in a dataset + */ +export const get14 = oc + .route({ + description: 'List all documents in a dataset', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdDocuments', + path: '/datasets/{dataset_id}/documents', + tags: ['service_api'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdDocumentsPath })) + .output(zGetDatasetsByDatasetIdDocumentsResponse) + +export const documents = { + get: get14, + downloadZip, + metadata, + status: status2, + byBatch, + byDocumentId, +} + +/** + * Perform hit testing on a dataset + * + * Perform hit testing on a dataset + * Tests retrieval performance for the specified dataset. + */ +export const post26 = oc + .route({ + description: + 'Perform hit testing on a dataset\nTests retrieval performance for the specified dataset.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdHitTesting', + path: '/datasets/{dataset_id}/hit-testing', + summary: 'Perform hit testing on a dataset', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdHitTestingBody, + params: zPostDatasetsByDatasetIdHitTestingPath, + }), + ) + .output(zPostDatasetsByDatasetIdHitTestingResponse) + +export const hitTesting = { + post: post26, +} + +/** + * Enable or disable built-in metadata field + * + * Enable or disable built-in metadata field + */ +export const post27 = oc + .route({ + description: 'Enable or disable built-in metadata field', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdMetadataBuiltInByAction', + path: '/datasets/{dataset_id}/metadata/built-in/{action}', + summary: 'Enable or disable built-in metadata field', + tags: ['service_api'], + }) + .input(z.object({ params: zPostDatasetsByDatasetIdMetadataBuiltInByActionPath })) + .output(zPostDatasetsByDatasetIdMetadataBuiltInByActionResponse) + +export const byAction3 = { + post: post27, +} + +/** + * Get all built-in metadata fields + * + * Get all built-in metadata fields + */ +export const get15 = oc + .route({ + description: 'Get all built-in metadata fields', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdMetadataBuiltIn', + path: '/datasets/{dataset_id}/metadata/built-in', + summary: 'Get all built-in metadata fields', + tags: ['service_api'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdMetadataBuiltInPath })) + .output(zGetDatasetsByDatasetIdMetadataBuiltInResponse) + +export const builtIn = { + get: get15, + byAction: byAction3, +} + +/** + * Delete metadata + * + * Delete metadata + */ +export const delete7 = oc + .route({ + description: 'Delete metadata', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsByDatasetIdMetadataByMetadataId', + path: '/datasets/{dataset_id}/metadata/{metadata_id}', + successStatus: 204, + summary: 'Delete metadata', + tags: ['service_api'], + }) + .input(z.object({ params: zDeleteDatasetsByDatasetIdMetadataByMetadataIdPath })) + .output(zDeleteDatasetsByDatasetIdMetadataByMetadataIdResponse) + +/** + * Update metadata name + * + * Update metadata name + */ +export const patch5 = oc + .route({ + description: 'Update metadata name', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetIdMetadataByMetadataId', + path: '/datasets/{dataset_id}/metadata/{metadata_id}', + summary: 'Update metadata name', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPatchDatasetsByDatasetIdMetadataByMetadataIdBody, + params: zPatchDatasetsByDatasetIdMetadataByMetadataIdPath, + }), + ) + .output(zPatchDatasetsByDatasetIdMetadataByMetadataIdResponse) + +export const byMetadataId = { + delete: delete7, + patch: patch5, +} + +/** + * Get all metadata for a dataset + * + * Get all metadata for a dataset + */ +export const get16 = oc + .route({ + description: 'Get all metadata for a dataset', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdMetadata', + path: '/datasets/{dataset_id}/metadata', + summary: 'Get all metadata for a dataset', + tags: ['service_api'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdMetadataPath })) + .output(zGetDatasetsByDatasetIdMetadataResponse) + +/** + * Create metadata for a dataset + * + * Create metadata for a dataset + */ +export const post28 = oc + .route({ + description: 'Create metadata for a dataset', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdMetadata', + path: '/datasets/{dataset_id}/metadata', + successStatus: 201, + summary: 'Create metadata for a dataset', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdMetadataBody, + params: zPostDatasetsByDatasetIdMetadataPath, + }), + ) + .output(zPostDatasetsByDatasetIdMetadataResponse) + +export const metadata2 = { + get: get16, + post: post28, + builtIn, + byMetadataId, +} + +/** + * Resource for getting datasource plugins + * + * List all datasource plugins for a rag pipeline + */ +export const get17 = oc + .route({ + description: 'List all datasource plugins for a rag pipeline', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdPipelineDatasourcePlugins', + path: '/datasets/{dataset_id}/pipeline/datasource-plugins', + summary: 'Resource for getting datasource plugins', + tags: ['service_api'], + }) + .input( + z.object({ + params: zGetDatasetsByDatasetIdPipelineDatasourcePluginsPath, + query: zGetDatasetsByDatasetIdPipelineDatasourcePluginsQuery.optional(), + }), + ) + .output(zGetDatasetsByDatasetIdPipelineDatasourcePluginsResponse) + +export const datasourcePlugins = { + get: get17, +} + +/** + * Resource for getting datasource plugins + * + * Run a datasource node for a rag pipeline + */ +export const post29 = oc + .route({ + description: 'Run a datasource node for a rag pipeline', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRun', + path: '/datasets/{dataset_id}/pipeline/datasource/nodes/{node_id}/run', + summary: 'Resource for getting datasource plugins', + tags: ['service_api'], + }) + .input(z.object({ params: zPostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunPath })) + .output(zPostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunResponse) + +export const run = { + post: post29, +} + +export const byNodeId = { + run, +} + +export const nodes = { + byNodeId, +} + +export const datasource = { + nodes, +} + +/** + * Resource for running a rag pipeline + * + * Run a datasource node for a rag pipeline + */ +export const post30 = oc + .route({ + description: 'Run a datasource node for a rag pipeline', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdPipelineRun', + path: '/datasets/{dataset_id}/pipeline/run', + summary: 'Resource for running a rag pipeline', + tags: ['service_api'], + }) + .input(z.object({ params: zPostDatasetsByDatasetIdPipelineRunPath })) + .output(zPostDatasetsByDatasetIdPipelineRunResponse) + +export const run2 = { + post: post30, +} + +export const pipeline2 = { + datasourcePlugins, + datasource, + run: run2, +} + +/** + * Perform hit testing on a dataset + * + * Perform hit testing on a dataset + * Tests retrieval performance for the specified dataset. + */ +export const post31 = oc + .route({ + description: + 'Perform hit testing on a dataset\nTests retrieval performance for the specified dataset.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasetsByDatasetIdRetrieve', + path: '/datasets/{dataset_id}/retrieve', + summary: 'Perform hit testing on a dataset', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostDatasetsByDatasetIdRetrieveBody, + params: zPostDatasetsByDatasetIdRetrievePath, + }), + ) + .output(zPostDatasetsByDatasetIdRetrieveResponse) + +export const retrieve = { + post: post31, +} + +/** + * Get all knowledge type tags + * + * Get tags bound to a specific dataset + */ +export const get18 = oc + .route({ + description: 'Get tags bound to a specific dataset', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetIdTags', + path: '/datasets/{dataset_id}/tags', + summary: 'Get all knowledge type tags', + tags: ['service_api'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdTagsPath })) + .output(zGetDatasetsByDatasetIdTagsResponse) + +export const tags2 = { + get: get18, +} + +/** + * Deletes a dataset given its ID + * + * Delete a dataset + * Args: + * _: ignore + * dataset_id (UUID): The ID of the dataset to be deleted. + * + * Returns: + * dict: A dictionary with a key 'result' and a value 'success' + * if the dataset was successfully deleted. Omitted in HTTP response. + * int: HTTP status code 204 indicating that the operation was successful. + * + * Raises: + * NotFound: If the dataset with the given ID does not exist. + */ +export const delete8 = oc + .route({ + description: + 'Delete a dataset\nArgs:\n _: ignore\n dataset_id (UUID): The ID of the dataset to be deleted.\n\nReturns:\n dict: A dictionary with a key \'result\' and a value \'success\'\n if the dataset was successfully deleted. Omitted in HTTP response.\n int: HTTP status code 204 indicating that the operation was successful.\n\nRaises:\n NotFound: If the dataset with the given ID does not exist.', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteDatasetsByDatasetId', + path: '/datasets/{dataset_id}', + successStatus: 204, + summary: 'Deletes a dataset given its ID', + tags: ['service_api'], + }) + .input(z.object({ params: zDeleteDatasetsByDatasetIdPath })) + .output(zDeleteDatasetsByDatasetIdResponse) + +/** + * Get a specific dataset by ID + */ +export const get19 = oc + .route({ + description: 'Get a specific dataset by ID', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasetsByDatasetId', + path: '/datasets/{dataset_id}', + tags: ['service_api'], + }) + .input(z.object({ params: zGetDatasetsByDatasetIdPath })) + .output(zGetDatasetsByDatasetIdResponse) + +/** + * Update an existing dataset + */ +export const patch6 = oc + .route({ + description: 'Update an existing dataset', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchDatasetsByDatasetId', + path: '/datasets/{dataset_id}', + tags: ['service_api'], + }) + .input(z.object({ body: zPatchDatasetsByDatasetIdBody, params: zPatchDatasetsByDatasetIdPath })) + .output(zPatchDatasetsByDatasetIdResponse) + +export const byDatasetId = { + delete: delete8, + get: get19, + patch: patch6, + document: document_, + documents, + hitTesting, + metadata: metadata2, + pipeline: pipeline2, + retrieve, + tags: tags2, +} + +/** + * Resource for getting datasets + * + * List all datasets + */ +export const get20 = oc + .route({ + description: 'List all datasets', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getDatasets', + path: '/datasets', + summary: 'Resource for getting datasets', + tags: ['service_api'], + }) + .output(zGetDatasetsResponse) + +/** + * Resource for creating datasets + * + * Create a new dataset + */ +export const post32 = oc + .route({ + description: 'Create a new dataset', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postDatasets', + path: '/datasets', + summary: 'Resource for creating datasets', + tags: ['service_api'], + }) + .input(z.object({ body: zPostDatasetsBody })) + .output(zPostDatasetsResponse) + +export const datasets = { + get: get20, + post: post32, + pipeline, + tags, + byDatasetId, +} + +/** + * Get end user detail + * + * Get an end user by ID + * This endpoint is scoped to the current app token's tenant/app to prevent + * cross-tenant/app access when an end-user ID is known. + */ +export const get21 = oc + .route({ + description: + 'Get an end user by ID\nThis endpoint is scoped to the current app token\'s tenant/app to prevent\ncross-tenant/app access when an end-user ID is known.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getEndUsersByEndUserId', + path: '/end-users/{end_user_id}', + summary: 'Get end user detail', + tags: ['service_api'], + }) + .input(z.object({ params: zGetEndUsersByEndUserIdPath })) + .output(zGetEndUsersByEndUserIdResponse) + +export const byEndUserId = { + get: get21, +} + +export const endUsers = { + byEndUserId, +} + +/** + * Upload a file for use in conversations + * + * Upload a file for use in conversations + * Accepts a single file upload via multipart/form-data. + */ +export const post33 = oc + .route({ + description: + 'Upload a file for use in conversations\nAccepts a single file upload via multipart/form-data.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postFilesUpload', + path: '/files/upload', + successStatus: 201, + summary: 'Upload a file for use in conversations', + tags: ['service_api'], + }) + .output(zPostFilesUploadResponse) + +export const upload = { + post: post33, +} + +/** + * Preview/Download a file that was uploaded via Service API + * + * Preview or download a file uploaded via Service API + * Provides secure file preview/download functionality. + * Files can only be accessed if they belong to messages within the requesting app's context. + */ +export const get22 = oc + .route({ + description: + 'Preview or download a file uploaded via Service API\nProvides secure file preview/download functionality.\nFiles can only be accessed if they belong to messages within the requesting app\'s context.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getFilesByFileIdPreview', + path: '/files/{file_id}/preview', + summary: 'Preview/Download a file that was uploaded via Service API', + tags: ['service_api'], + }) + .input( + z.object({ + params: zGetFilesByFileIdPreviewPath, + query: zGetFilesByFileIdPreviewQuery.optional(), + }), + ) + .output(zGetFilesByFileIdPreviewResponse) + +export const preview = { + get: get22, +} + +export const byFileId = { + preview, +} + +export const files = { + upload, + byFileId, +} + +/** + * Get a paused human input form by token + */ +export const get23 = oc + .route({ + description: 'Get a paused human input form by token', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getFormHumanInputByFormToken', + path: '/form/human_input/{form_token}', + tags: ['service_api'], + }) + .input(z.object({ params: zGetFormHumanInputByFormTokenPath })) + .output(zGetFormHumanInputByFormTokenResponse) + +/** + * Submit a paused human input form by token + */ +export const post34 = oc + .route({ + description: 'Submit a paused human input form by token', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postFormHumanInputByFormToken', + path: '/form/human_input/{form_token}', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostFormHumanInputByFormTokenBody, + params: zPostFormHumanInputByFormTokenPath, + }), + ) + .output(zPostFormHumanInputByFormTokenResponse) + +export const byFormToken = { + get: get23, + post: post34, +} + +export const humanInput = { + byFormToken, +} + +export const form = { + humanInput, +} + +/** + * Get app information + * + * Get basic application information + * Returns basic information about the application including name, description, tags, and mode. + */ +export const get24 = oc + .route({ + description: + 'Get basic application information\nReturns basic information about the application including name, description, tags, and mode.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getInfo', + path: '/info', + summary: 'Get app information', + tags: ['service_api'], + }) + .output(zGetInfoResponse) + +export const info = { + get: get24, +} + +/** + * Submit feedback for a message + * + * Submit feedback for a message + * Allows users to rate messages as like/dislike and provide optional feedback content. + */ +export const post35 = oc + .route({ + description: + 'Submit feedback for a message\nAllows users to rate messages as like/dislike and provide optional feedback content.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postMessagesByMessageIdFeedbacks', + path: '/messages/{message_id}/feedbacks', + summary: 'Submit feedback for a message', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostMessagesByMessageIdFeedbacksBody, + params: zPostMessagesByMessageIdFeedbacksPath, + }), + ) + .output(zPostMessagesByMessageIdFeedbacksResponse) + +export const feedbacks2 = { + post: post35, +} + +/** + * Get suggested follow-up questions for a message + * + * Get suggested follow-up questions for a message + * Returns AI-generated follow-up questions based on the message content. + */ +export const get25 = oc + .route({ + description: + 'Get suggested follow-up questions for a message\nReturns AI-generated follow-up questions based on the message content.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getMessagesByMessageIdSuggested', + path: '/messages/{message_id}/suggested', + summary: 'Get suggested follow-up questions for a message', + tags: ['service_api'], + }) + .input(z.object({ params: zGetMessagesByMessageIdSuggestedPath })) + .output(zGetMessagesByMessageIdSuggestedResponse) + +export const suggested = { + get: get25, +} + +export const byMessageId = { + feedbacks: feedbacks2, + suggested, +} + +/** + * List messages in a conversation + * + * List messages in a conversation + * Retrieves messages with pagination support using first_id. + */ +export const get26 = oc + .route({ + description: + 'List messages in a conversation\nRetrieves messages with pagination support using first_id.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getMessages', + path: '/messages', + summary: 'List messages in a conversation', + tags: ['service_api'], + }) + .input(z.object({ query: zGetMessagesQuery })) + .output(zGetMessagesResponse) + +export const messages = { + get: get26, + byMessageId, +} + +/** + * Get app metadata + * + * Get application metadata + * Returns metadata about the application including configuration and settings. + */ +export const get27 = oc + .route({ + description: + 'Get application metadata\nReturns metadata about the application including configuration and settings.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getMeta', + path: '/meta', + summary: 'Get app metadata', + tags: ['service_api'], + }) + .output(zGetMetaResponse) + +export const meta = { + get: get27, +} + +/** + * Retrieve app parameters + * + * Retrieve application input parameters and configuration + * Returns the input form parameters and configuration for the application. + */ +export const get28 = oc + .route({ + description: + 'Retrieve application input parameters and configuration\nReturns the input form parameters and configuration for the application.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getParameters', + path: '/parameters', + summary: 'Retrieve app parameters', + tags: ['service_api'], + }) + .output(zGetParametersResponse) + +export const parameters = { + get: get28, +} + +/** + * Retrieve app site info + * + * Get application site configuration + * Returns the site configuration for the application including theme, icons, and text. + */ +export const get29 = oc + .route({ + description: + 'Get application site configuration\nReturns the site configuration for the application including theme, icons, and text.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getSite', + path: '/site', + summary: 'Retrieve app site info', + tags: ['service_api'], + }) + .output(zGetSiteResponse) + +export const site = { + get: get29, +} + +/** + * Convert text to audio using text-to-speech + * + * Convert text to audio using text-to-speech + * Converts the provided text to audio using the specified voice. + */ +export const post36 = oc + .route({ + description: + 'Convert text to audio using text-to-speech\nConverts the provided text to audio using the specified voice.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTextToAudio', + path: '/text-to-audio', + summary: 'Convert text to audio using text-to-speech', + tags: ['service_api'], + }) + .input(z.object({ body: zPostTextToAudioBody })) + .output(zPostTextToAudioResponse) + +export const textToAudio = { + post: post36, +} + +/** + * Get workflow execution events stream after resume + */ +export const get30 = oc + .route({ + description: 'Get workflow execution events stream after resume', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkflowByTaskIdEvents', + path: '/workflow/{task_id}/events', + tags: ['service_api'], + }) + .input( + z.object({ + params: zGetWorkflowByTaskIdEventsPath, + query: zGetWorkflowByTaskIdEventsQuery.optional(), + }), + ) + .output(zGetWorkflowByTaskIdEventsResponse) + +export const events = { + get: get30, +} + +export const byTaskId3 = { + events, +} + +export const workflow = { + byTaskId: byTaskId3, +} + +/** + * Get workflow app logs + * + * Get workflow execution logs + * Returns paginated workflow execution logs with filtering options. + */ +export const get31 = oc + .route({ + description: + 'Get workflow execution logs\nReturns paginated workflow execution logs with filtering options.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkflowsLogs', + path: '/workflows/logs', + summary: 'Get workflow app logs', + tags: ['service_api'], + }) + .input(z.object({ query: zGetWorkflowsLogsQuery.optional() })) + .output(zGetWorkflowsLogsResponse) + +export const logs = { + get: get31, +} + +/** + * Get a workflow task running detail + * + * Get workflow run details + * Returns detailed information about a specific workflow run. + */ +export const get32 = oc + .route({ + description: + 'Get workflow run details\nReturns detailed information about a specific workflow run.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkflowsRunByWorkflowRunId', + path: '/workflows/run/{workflow_run_id}', + summary: 'Get a workflow task running detail', + tags: ['service_api'], + }) + .input(z.object({ params: zGetWorkflowsRunByWorkflowRunIdPath })) + .output(zGetWorkflowsRunByWorkflowRunIdResponse) + +export const byWorkflowRunId = { + get: get32, +} + +/** + * Execute a workflow + * + * Execute a workflow + * Runs a workflow with the provided inputs and returns the results. + * Supports both blocking and streaming response modes. + */ +export const post37 = oc + .route({ + description: + 'Execute a workflow\nRuns a workflow with the provided inputs and returns the results.\nSupports both blocking and streaming response modes.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkflowsRun', + path: '/workflows/run', + summary: 'Execute a workflow', + tags: ['service_api'], + }) + .input(z.object({ body: zPostWorkflowsRunBody })) + .output(zPostWorkflowsRunResponse) + +export const run3 = { + post: post37, + byWorkflowRunId, +} + +/** + * Stop a running workflow task + * + * Stop a running workflow task + */ +export const post38 = oc + .route({ + description: 'Stop a running workflow task', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkflowsTasksByTaskIdStop', + path: '/workflows/tasks/{task_id}/stop', + summary: 'Stop a running workflow task', + tags: ['service_api'], + }) + .input(z.object({ params: zPostWorkflowsTasksByTaskIdStopPath })) + .output(zPostWorkflowsTasksByTaskIdStopResponse) + +export const stop3 = { + post: post38, +} + +export const byTaskId4 = { + stop: stop3, +} + +export const tasks = { + byTaskId: byTaskId4, +} + +/** + * Run specific workflow by ID + * + * Execute a specific workflow by ID + * Executes a specific workflow version identified by its ID. + */ +export const post39 = oc + .route({ + description: + 'Execute a specific workflow by ID\nExecutes a specific workflow version identified by its ID.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkflowsByWorkflowIdRun', + path: '/workflows/{workflow_id}/run', + summary: 'Run specific workflow by ID', + tags: ['service_api'], + }) + .input( + z.object({ + body: zPostWorkflowsByWorkflowIdRunBody, + params: zPostWorkflowsByWorkflowIdRunPath, + }), + ) + .output(zPostWorkflowsByWorkflowIdRunResponse) + +export const run4 = { + post: post39, +} + +export const byWorkflowId = { + run: run4, +} + +export const workflows = { + logs, + run: run3, + tasks, + byWorkflowId, +} + +/** + * Get available models by model type + * + * Get available models by model type + * Returns a list of available models for the specified model type. + */ +export const get33 = oc + .route({ + description: + 'Get available models by model type\nReturns a list of available models for the specified model type.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkspacesCurrentModelsModelTypesByModelType', + path: '/workspaces/current/models/model-types/{model_type}', + summary: 'Get available models by model type', + tags: ['service_api'], + }) + .input(z.object({ params: zGetWorkspacesCurrentModelsModelTypesByModelTypePath })) + .output(zGetWorkspacesCurrentModelsModelTypesByModelTypeResponse) + +export const byModelType = { + get: get33, +} + +export const modelTypes = { + byModelType, +} + +export const models = { + modelTypes, +} + +export const current = { + models, +} + +export const workspaces = { + current, +} + +export const contract = { + root, + app, + apps, + audioToText, + chatMessages, + completionMessages, + conversations, + datasets, + endUsers, + files, + form, + info, + messages, + meta, + parameters, + site, + textToAudio, + workflow, + workflows, + workspaces, +} diff --git a/packages/contracts/generated/api/service/types.gen.ts b/packages/contracts/generated/api/service/types.gen.ts new file mode 100644 index 0000000000..e3791e295c --- /dev/null +++ b/packages/contracts/generated/api/service/types.gen.ts @@ -0,0 +1,3155 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/v1` | (string & {}) +} + +export type Annotation = { + content?: string | null + created_at?: number | null + hit_count?: number | null + id: string + question?: string | null +} + +export type AnnotationCreatePayload = { + answer: string + question: string +} + +export type AnnotationList = { + data: Array + has_more: boolean + limit: number + page: number + total: number +} + +export type AnnotationReplyActionPayload = { + embedding_model_name: string + embedding_provider_name: string + score_threshold: number +} + +export type ChatRequestPayload = { + auto_generate_name?: boolean + conversation_id?: string | null + files?: Array<{ + [key: string]: unknown + }> | null + inputs: { + [key: string]: unknown + } + query: string + response_mode?: 'blocking' | 'streaming' | null + retriever_from?: string + workflow_id?: string | null +} + +export type ChildChunkCreatePayload = { + content: string +} + +export type ChildChunkListQuery = { + keyword?: string | null + limit?: number + page?: number +} + +export type ChildChunkUpdatePayload = { + content: string +} + +export type CompletionRequestPayload = { + files?: Array<{ + [key: string]: unknown + }> | null + inputs: { + [key: string]: unknown + } + query?: string + response_mode?: 'blocking' | 'streaming' | null + retriever_from?: string +} + +export type ConversationListQuery = { + last_id?: string | null + limit?: number + sort_by?: 'created_at' | '-created_at' | 'updated_at' | '-updated_at' +} + +export type ConversationRenamePayload = { + auto_generate?: boolean + name?: string | null +} + +export type ConversationVariableInfiniteScrollPaginationResponse = { + data: Array + has_more: boolean + limit: number +} + +export type ConversationVariableResponse = { + created_at?: number | null + description?: string | null + id: string + name: string + updated_at?: number | null + value?: string | null + value_type: string +} + +export type ConversationVariableUpdatePayload = { + value: unknown +} + +export type ConversationVariablesQuery = { + last_id?: string | null + limit?: number + variable_name?: string | null +} + +export type DatasetCreatePayload = { + description?: string + embedding_model?: string | null + embedding_model_provider?: string | null + external_knowledge_api_id?: string | null + external_knowledge_id?: string | null + indexing_technique?: 'high_quality' | 'economy' | null + name: string + permission?: DatasetPermissionEnum + provider?: string + retrieval_model?: RetrievalModel + summary_index_setting?: { + [key: string]: unknown + } | null +} + +export type DatasetUpdatePayload = { + description?: string | null + embedding_model?: string | null + embedding_model_provider?: string | null + external_knowledge_api_id?: string | null + external_knowledge_id?: string | null + external_retrieval_model?: { + [key: string]: unknown + } | null + indexing_technique?: 'high_quality' | 'economy' | null + name?: string | null + partial_member_list?: Array<{ + [key: string]: string + }> | null + permission?: DatasetPermissionEnum + retrieval_model?: RetrievalModel +} + +export type DocumentBatchDownloadZipPayload = { + document_ids: Array +} + +export type DocumentTextCreatePayload = { + doc_form?: string + doc_language?: string + embedding_model?: string | null + embedding_model_provider?: string | null + indexing_technique?: string | null + name: string + original_document_id?: string | null + process_rule?: ProcessRule + retrieval_model?: RetrievalModel + text: string +} + +export type DocumentTextUpdate = { + doc_form?: string + doc_language?: string + name?: string | null + process_rule?: ProcessRule + retrieval_model?: RetrievalModel + text?: string | null +} + +export type FeedbackListQuery = { + limit?: number + page?: number +} + +export type FilePreviewQuery = { + as_attachment?: boolean +} + +export type FileResponse = { + conversation_id?: string | null + created_at?: number | null + created_by?: string | null + extension?: string | null + file_key?: string | null + id: string + mime_type?: string | null + name: string + original_url?: string | null + preview_url?: string | null + size: number + source_url?: string | null + tenant_id?: string | null + user_id?: string | null +} + +export type HitTestingPayload = { + attachment_ids?: Array | null + external_retrieval_model?: { + [key: string]: unknown + } | null + query: string + retrieval_model?: RetrievalModel +} + +export type HumanInputFormSubmitPayload = { + action: string + inputs: { + [key: string]: JsonValue + } +} + +export type MessageFeedbackPayload = { + content?: string | null + rating?: 'like' | 'dislike' | null +} + +export type MessageListQuery = { + conversation_id: string + first_id?: string | null + limit?: number +} + +export type MetadataArgs = { + name: string + type: 'string' | 'number' | 'time' +} + +export type MetadataOperationData = { + operation_data: Array +} + +export type MetadataUpdatePayload = { + name: string +} + +export type SegmentCreatePayload = { + segments?: Array<{ + [key: string]: unknown + }> | null +} + +export type SegmentListQuery = { + keyword?: string | null + status?: Array +} + +export type SegmentUpdatePayload = { + segment: SegmentUpdateArgs +} + +export type TagBindingPayload = { + tag_ids: Array + target_id: string +} + +export type TagCreatePayload = { + name: string +} + +export type TagDeletePayload = { + tag_id: string +} + +export type TagUnbindingPayload = { + tag_id: string + target_id: string +} + +export type TagUpdatePayload = { + name: string + tag_id: string +} + +export type TextToAudioPayload = { + message_id?: string | null + streaming?: boolean | null + text?: string | null + voice?: string | null +} + +export type WorkflowAppLogPaginationResponse = { + data: Array + has_more: boolean + limit: number + page: number + total: number +} + +export type WorkflowLogQuery = { + created_at__after?: string | null + created_at__before?: string | null + created_by_account?: string | null + created_by_end_user_session_id?: string | null + keyword?: string | null + limit?: number + page?: number + status?: 'succeeded' | 'failed' | 'stopped' | null +} + +export type WorkflowRunPayload = { + files?: Array<{ + [key: string]: unknown + }> | null + inputs: { + [key: string]: unknown + } + response_mode?: 'blocking' | 'streaming' | null +} + +export type WorkflowRunResponse = { + created_at?: number | null + elapsed_time?: unknown + error?: string | null + finished_at?: number | null + id: string + inputs?: unknown + outputs?: { + [key: string]: unknown + } + status: string + total_steps?: number | null + total_tokens?: number | null + workflow_id: string +} + +export type Condition = { + comparison_operator: + | 'contains' + | 'not contains' + | 'start with' + | 'end with' + | 'is' + | 'is not' + | 'empty' + | 'not empty' + | 'in' + | 'not in' + | '=' + | '≠' + | '>' + | '<' + | '≥' + | '≤' + | 'before' + | 'after' + name: string + value?: unknown +} + +export type DatasetPermissionEnum = 'only_me' | 'all_team_members' | 'partial_members' + +export type MetadataFilteringCondition = { + conditions?: Array | null + logical_operator?: 'and' | 'or' | null +} + +export type RerankingModel = { + reranking_model_name?: string | null + reranking_provider_name?: string | null +} + +export type RetrievalMethod + = | 'semantic_search' + | 'full_text_search' + | 'hybrid_search' + | 'keyword_search' + +export type RetrievalModel = { + metadata_filtering_conditions?: MetadataFilteringCondition + reranking_enable: boolean + reranking_mode?: string | null + reranking_model?: RerankingModel + score_threshold?: number | null + score_threshold_enabled: boolean + search_method: RetrievalMethod + top_k: number + weights?: WeightModel +} + +export type WeightKeywordSetting = { + keyword_weight: number +} + +export type WeightModel = { + keyword_setting?: WeightKeywordSetting + vector_setting?: WeightVectorSetting + weight_type?: 'semantic_first' | 'keyword_first' | 'customized' | null +} + +export type WeightVectorSetting = { + embedding_model_name: string + embedding_provider_name: string + vector_weight: number +} + +export type PreProcessingRule = { + enabled: boolean + id: string +} + +export type ProcessRule = { + mode: 'automatic' | 'custom' | 'hierarchical' + rules?: Rule +} + +export type Rule = { + parent_mode?: 'full-doc' | 'paragraph' | null + pre_processing_rules?: Array | null + segmentation?: Segmentation + subchunk_segmentation?: Segmentation +} + +export type Segmentation = { + chunk_overlap?: number + max_tokens: number + separator?: string +} + +export type JsonValue = unknown + +export type DocumentMetadataOperation = { + document_id: string + metadata_list: Array + partial_update?: boolean +} + +export type MetadataDetail = { + id: string + name: string + value?: unknown +} + +export type SegmentUpdateArgs = { + answer?: string | null + attachment_ids?: Array | null + content?: string | null + enabled?: boolean | null + keywords?: Array | null + regenerate_child_chunks?: boolean + summary?: string | null +} + +export type SimpleAccount = { + email: string + id: string + name: string +} + +export type SimpleEndUser = { + id: string + is_anonymous: boolean + session_id?: string | null + type: string +} + +export type WorkflowAppLogPartialResponse = { + created_at?: number | null + created_by_account?: SimpleAccount + created_by_end_user?: SimpleEndUser + created_by_role?: string | null + created_from?: string | null + details?: unknown + id: string + workflow_run?: WorkflowRunForLogResponse +} + +export type WorkflowRunForLogResponse = { + created_at?: number | null + elapsed_time?: unknown + error?: string | null + exceptions_count?: number | null + finished_at?: number | null + id: string + status?: string | null + total_steps?: number | null + total_tokens?: number | null + triggered_from?: string | null + version?: string | null +} + +export type GetRootData = { + body?: never + path?: never + query?: never + url: '/' +} + +export type GetRootResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetRootResponse = GetRootResponses[keyof GetRootResponses] + +export type GetAppFeedbacksData = { + body?: never + path?: never + query?: { + limit?: number + page?: number + } + url: '/app/feedbacks' +} + +export type GetAppFeedbacksErrors = { + 401: { + [key: string]: unknown + } +} + +export type GetAppFeedbacksError = GetAppFeedbacksErrors[keyof GetAppFeedbacksErrors] + +export type GetAppFeedbacksResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppFeedbacksResponse = GetAppFeedbacksResponses[keyof GetAppFeedbacksResponses] + +export type PostAppsAnnotationReplyByActionData = { + body: AnnotationReplyActionPayload + path: { + action: string + } + query?: never + url: '/apps/annotation-reply/{action}' +} + +export type PostAppsAnnotationReplyByActionErrors = { + 401: { + [key: string]: unknown + } +} + +export type PostAppsAnnotationReplyByActionError + = PostAppsAnnotationReplyByActionErrors[keyof PostAppsAnnotationReplyByActionErrors] + +export type PostAppsAnnotationReplyByActionResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAppsAnnotationReplyByActionResponse + = PostAppsAnnotationReplyByActionResponses[keyof PostAppsAnnotationReplyByActionResponses] + +export type GetAppsAnnotationReplyByActionStatusByJobIdData = { + body?: never + path: { + action: string + job_id: string + } + query?: never + url: '/apps/annotation-reply/{action}/status/{job_id}' +} + +export type GetAppsAnnotationReplyByActionStatusByJobIdErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetAppsAnnotationReplyByActionStatusByJobIdError + = GetAppsAnnotationReplyByActionStatusByJobIdErrors[keyof GetAppsAnnotationReplyByActionStatusByJobIdErrors] + +export type GetAppsAnnotationReplyByActionStatusByJobIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetAppsAnnotationReplyByActionStatusByJobIdResponse + = GetAppsAnnotationReplyByActionStatusByJobIdResponses[keyof GetAppsAnnotationReplyByActionStatusByJobIdResponses] + +export type GetAppsAnnotationsData = { + body?: never + path?: never + query?: never + url: '/apps/annotations' +} + +export type GetAppsAnnotationsErrors = { + 401: { + [key: string]: unknown + } +} + +export type GetAppsAnnotationsError = GetAppsAnnotationsErrors[keyof GetAppsAnnotationsErrors] + +export type GetAppsAnnotationsResponses = { + 200: AnnotationList +} + +export type GetAppsAnnotationsResponse + = GetAppsAnnotationsResponses[keyof GetAppsAnnotationsResponses] + +export type PostAppsAnnotationsData = { + body: AnnotationCreatePayload + path?: never + query?: never + url: '/apps/annotations' +} + +export type PostAppsAnnotationsErrors = { + 401: { + [key: string]: unknown + } +} + +export type PostAppsAnnotationsError = PostAppsAnnotationsErrors[keyof PostAppsAnnotationsErrors] + +export type PostAppsAnnotationsResponses = { + 201: Annotation +} + +export type PostAppsAnnotationsResponse + = PostAppsAnnotationsResponses[keyof PostAppsAnnotationsResponses] + +export type DeleteAppsAnnotationsByAnnotationIdData = { + body?: never + path: { + annotation_id: string + } + query?: never + url: '/apps/annotations/{annotation_id}' +} + +export type DeleteAppsAnnotationsByAnnotationIdErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type DeleteAppsAnnotationsByAnnotationIdError + = DeleteAppsAnnotationsByAnnotationIdErrors[keyof DeleteAppsAnnotationsByAnnotationIdErrors] + +export type DeleteAppsAnnotationsByAnnotationIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteAppsAnnotationsByAnnotationIdResponse + = DeleteAppsAnnotationsByAnnotationIdResponses[keyof DeleteAppsAnnotationsByAnnotationIdResponses] + +export type PutAppsAnnotationsByAnnotationIdData = { + body: AnnotationCreatePayload + path: { + annotation_id: string + } + query?: never + url: '/apps/annotations/{annotation_id}' +} + +export type PutAppsAnnotationsByAnnotationIdErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PutAppsAnnotationsByAnnotationIdError + = PutAppsAnnotationsByAnnotationIdErrors[keyof PutAppsAnnotationsByAnnotationIdErrors] + +export type PutAppsAnnotationsByAnnotationIdResponses = { + 200: Annotation +} + +export type PutAppsAnnotationsByAnnotationIdResponse + = PutAppsAnnotationsByAnnotationIdResponses[keyof PutAppsAnnotationsByAnnotationIdResponses] + +export type PostAudioToTextData = { + body?: never + path?: never + query?: never + url: '/audio-to-text' +} + +export type PostAudioToTextErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 413: { + [key: string]: unknown + } + 415: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostAudioToTextError = PostAudioToTextErrors[keyof PostAudioToTextErrors] + +export type PostAudioToTextResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAudioToTextResponse = PostAudioToTextResponses[keyof PostAudioToTextResponses] + +export type PostChatMessagesData = { + body: ChatRequestPayload + path?: never + query?: never + url: '/chat-messages' +} + +export type PostChatMessagesErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 429: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostChatMessagesError = PostChatMessagesErrors[keyof PostChatMessagesErrors] + +export type PostChatMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostChatMessagesResponse = PostChatMessagesResponses[keyof PostChatMessagesResponses] + +export type PostChatMessagesByTaskIdStopData = { + body?: never + path: { + task_id: string + } + query?: never + url: '/chat-messages/{task_id}/stop' +} + +export type PostChatMessagesByTaskIdStopErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostChatMessagesByTaskIdStopError + = PostChatMessagesByTaskIdStopErrors[keyof PostChatMessagesByTaskIdStopErrors] + +export type PostChatMessagesByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostChatMessagesByTaskIdStopResponse + = PostChatMessagesByTaskIdStopResponses[keyof PostChatMessagesByTaskIdStopResponses] + +export type PostCompletionMessagesData = { + body: CompletionRequestPayload + path?: never + query?: never + url: '/completion-messages' +} + +export type PostCompletionMessagesErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostCompletionMessagesError + = PostCompletionMessagesErrors[keyof PostCompletionMessagesErrors] + +export type PostCompletionMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostCompletionMessagesResponse + = PostCompletionMessagesResponses[keyof PostCompletionMessagesResponses] + +export type PostCompletionMessagesByTaskIdStopData = { + body?: never + path: { + task_id: string + } + query?: never + url: '/completion-messages/{task_id}/stop' +} + +export type PostCompletionMessagesByTaskIdStopErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostCompletionMessagesByTaskIdStopError + = PostCompletionMessagesByTaskIdStopErrors[keyof PostCompletionMessagesByTaskIdStopErrors] + +export type PostCompletionMessagesByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostCompletionMessagesByTaskIdStopResponse + = PostCompletionMessagesByTaskIdStopResponses[keyof PostCompletionMessagesByTaskIdStopResponses] + +export type GetConversationsData = { + body?: never + path?: never + query?: { + last_id?: string | null + limit?: number + sort_by?: 'created_at' | '-created_at' | 'updated_at' | '-updated_at' + } + url: '/conversations' +} + +export type GetConversationsErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetConversationsError = GetConversationsErrors[keyof GetConversationsErrors] + +export type GetConversationsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetConversationsResponse = GetConversationsResponses[keyof GetConversationsResponses] + +export type DeleteConversationsByCIdData = { + body?: never + path: { + c_id: string + } + query?: never + url: '/conversations/{c_id}' +} + +export type DeleteConversationsByCIdErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type DeleteConversationsByCIdError + = DeleteConversationsByCIdErrors[keyof DeleteConversationsByCIdErrors] + +export type DeleteConversationsByCIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteConversationsByCIdResponse + = DeleteConversationsByCIdResponses[keyof DeleteConversationsByCIdResponses] + +export type PostConversationsByCIdNameData = { + body: ConversationRenamePayload + path: { + c_id: string + } + query?: never + url: '/conversations/{c_id}/name' +} + +export type PostConversationsByCIdNameErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostConversationsByCIdNameError + = PostConversationsByCIdNameErrors[keyof PostConversationsByCIdNameErrors] + +export type PostConversationsByCIdNameResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostConversationsByCIdNameResponse + = PostConversationsByCIdNameResponses[keyof PostConversationsByCIdNameResponses] + +export type GetConversationsByCIdVariablesData = { + body?: never + path: { + c_id: string + } + query?: { + last_id?: string | null + limit?: number + variable_name?: string | null + } + url: '/conversations/{c_id}/variables' +} + +export type GetConversationsByCIdVariablesErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetConversationsByCIdVariablesError + = GetConversationsByCIdVariablesErrors[keyof GetConversationsByCIdVariablesErrors] + +export type GetConversationsByCIdVariablesResponses = { + 200: ConversationVariableInfiniteScrollPaginationResponse +} + +export type GetConversationsByCIdVariablesResponse + = GetConversationsByCIdVariablesResponses[keyof GetConversationsByCIdVariablesResponses] + +export type PutConversationsByCIdVariablesByVariableIdData = { + body: ConversationVariableUpdatePayload + path: { + c_id: string + variable_id: string + } + query?: never + url: '/conversations/{c_id}/variables/{variable_id}' +} + +export type PutConversationsByCIdVariablesByVariableIdErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PutConversationsByCIdVariablesByVariableIdError + = PutConversationsByCIdVariablesByVariableIdErrors[keyof PutConversationsByCIdVariablesByVariableIdErrors] + +export type PutConversationsByCIdVariablesByVariableIdResponses = { + 200: ConversationVariableResponse +} + +export type PutConversationsByCIdVariablesByVariableIdResponse + = PutConversationsByCIdVariablesByVariableIdResponses[keyof PutConversationsByCIdVariablesByVariableIdResponses] + +export type GetDatasetsData = { + body?: never + path?: never + query?: never + url: '/datasets' +} + +export type GetDatasetsErrors = { + 401: { + [key: string]: unknown + } +} + +export type GetDatasetsError = GetDatasetsErrors[keyof GetDatasetsErrors] + +export type GetDatasetsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsResponse = GetDatasetsResponses[keyof GetDatasetsResponses] + +export type PostDatasetsData = { + body: DatasetCreatePayload + path?: never + query?: never + url: '/datasets' +} + +export type PostDatasetsErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } +} + +export type PostDatasetsError = PostDatasetsErrors[keyof PostDatasetsErrors] + +export type PostDatasetsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsResponse = PostDatasetsResponses[keyof PostDatasetsResponses] + +export type PostDatasetsPipelineFileUploadData = { + body?: never + path?: never + query?: never + url: '/datasets/pipeline/file-upload' +} + +export type PostDatasetsPipelineFileUploadErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 413: { + [key: string]: unknown + } + 415: { + [key: string]: unknown + } +} + +export type PostDatasetsPipelineFileUploadError + = PostDatasetsPipelineFileUploadErrors[keyof PostDatasetsPipelineFileUploadErrors] + +export type PostDatasetsPipelineFileUploadResponses = { + 201: { + [key: string]: unknown + } +} + +export type PostDatasetsPipelineFileUploadResponse + = PostDatasetsPipelineFileUploadResponses[keyof PostDatasetsPipelineFileUploadResponses] + +export type DeleteDatasetsTagsData = { + body: TagDeletePayload + path?: never + query?: never + url: '/datasets/tags' +} + +export type DeleteDatasetsTagsErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type DeleteDatasetsTagsError = DeleteDatasetsTagsErrors[keyof DeleteDatasetsTagsErrors] + +export type DeleteDatasetsTagsResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteDatasetsTagsResponse + = DeleteDatasetsTagsResponses[keyof DeleteDatasetsTagsResponses] + +export type GetDatasetsTagsData = { + body?: never + path?: never + query?: never + url: '/datasets/tags' +} + +export type GetDatasetsTagsErrors = { + 401: { + [key: string]: unknown + } +} + +export type GetDatasetsTagsError = GetDatasetsTagsErrors[keyof GetDatasetsTagsErrors] + +export type GetDatasetsTagsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsTagsResponse = GetDatasetsTagsResponses[keyof GetDatasetsTagsResponses] + +export type PatchDatasetsTagsData = { + body: TagUpdatePayload + path?: never + query?: never + url: '/datasets/tags' +} + +export type PatchDatasetsTagsErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type PatchDatasetsTagsError = PatchDatasetsTagsErrors[keyof PatchDatasetsTagsErrors] + +export type PatchDatasetsTagsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsTagsResponse = PatchDatasetsTagsResponses[keyof PatchDatasetsTagsResponses] + +export type PostDatasetsTagsData = { + body: TagCreatePayload + path?: never + query?: never + url: '/datasets/tags' +} + +export type PostDatasetsTagsErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type PostDatasetsTagsError = PostDatasetsTagsErrors[keyof PostDatasetsTagsErrors] + +export type PostDatasetsTagsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsTagsResponse = PostDatasetsTagsResponses[keyof PostDatasetsTagsResponses] + +export type PostDatasetsTagsBindingData = { + body: TagBindingPayload + path?: never + query?: never + url: '/datasets/tags/binding' +} + +export type PostDatasetsTagsBindingErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type PostDatasetsTagsBindingError + = PostDatasetsTagsBindingErrors[keyof PostDatasetsTagsBindingErrors] + +export type PostDatasetsTagsBindingResponses = { + 204: { + [key: string]: unknown + } +} + +export type PostDatasetsTagsBindingResponse + = PostDatasetsTagsBindingResponses[keyof PostDatasetsTagsBindingResponses] + +export type PostDatasetsTagsUnbindingData = { + body: TagUnbindingPayload + path?: never + query?: never + url: '/datasets/tags/unbinding' +} + +export type PostDatasetsTagsUnbindingErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type PostDatasetsTagsUnbindingError + = PostDatasetsTagsUnbindingErrors[keyof PostDatasetsTagsUnbindingErrors] + +export type PostDatasetsTagsUnbindingResponses = { + 204: { + [key: string]: unknown + } +} + +export type PostDatasetsTagsUnbindingResponse + = PostDatasetsTagsUnbindingResponses[keyof PostDatasetsTagsUnbindingResponses] + +export type DeleteDatasetsByDatasetIdData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}' +} + +export type DeleteDatasetsByDatasetIdErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 409: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdError + = DeleteDatasetsByDatasetIdErrors[keyof DeleteDatasetsByDatasetIdErrors] + +export type DeleteDatasetsByDatasetIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdResponse + = DeleteDatasetsByDatasetIdResponses[keyof DeleteDatasetsByDatasetIdResponses] + +export type GetDatasetsByDatasetIdData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}' +} + +export type GetDatasetsByDatasetIdErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdError + = GetDatasetsByDatasetIdErrors[keyof GetDatasetsByDatasetIdErrors] + +export type GetDatasetsByDatasetIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdResponse + = GetDatasetsByDatasetIdResponses[keyof GetDatasetsByDatasetIdResponses] + +export type PatchDatasetsByDatasetIdData = { + body: DatasetUpdatePayload + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}' +} + +export type PatchDatasetsByDatasetIdErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdError + = PatchDatasetsByDatasetIdErrors[keyof PatchDatasetsByDatasetIdErrors] + +export type PatchDatasetsByDatasetIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdResponse + = PatchDatasetsByDatasetIdResponses[keyof PatchDatasetsByDatasetIdResponses] + +export type PostDatasetsByDatasetIdDocumentCreateByFileData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/document/create-by-file' +} + +export type PostDatasetsByDatasetIdDocumentCreateByFileErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentCreateByFileError + = PostDatasetsByDatasetIdDocumentCreateByFileErrors[keyof PostDatasetsByDatasetIdDocumentCreateByFileErrors] + +export type PostDatasetsByDatasetIdDocumentCreateByFileResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentCreateByFileResponse + = PostDatasetsByDatasetIdDocumentCreateByFileResponses[keyof PostDatasetsByDatasetIdDocumentCreateByFileResponses] + +export type PostDatasetsByDatasetIdDocumentCreateByTextData = { + body: DocumentTextCreatePayload + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/document/create-by-text' +} + +export type PostDatasetsByDatasetIdDocumentCreateByTextErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentCreateByTextError + = PostDatasetsByDatasetIdDocumentCreateByTextErrors[keyof PostDatasetsByDatasetIdDocumentCreateByTextErrors] + +export type PostDatasetsByDatasetIdDocumentCreateByTextResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentCreateByTextResponse + = PostDatasetsByDatasetIdDocumentCreateByTextResponses[keyof PostDatasetsByDatasetIdDocumentCreateByTextResponses] + +export type PostDatasetsByDatasetIdDocumentCreateByFile2Data = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/document/create_by_file' +} + +export type PostDatasetsByDatasetIdDocumentCreateByFile2Errors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentCreateByFile2Error + = PostDatasetsByDatasetIdDocumentCreateByFile2Errors[keyof PostDatasetsByDatasetIdDocumentCreateByFile2Errors] + +export type PostDatasetsByDatasetIdDocumentCreateByFile2Responses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentCreateByFile2Response + = PostDatasetsByDatasetIdDocumentCreateByFile2Responses[keyof PostDatasetsByDatasetIdDocumentCreateByFile2Responses] + +export type PostDatasetsByDatasetIdDocumentCreateByText2Data = { + body: DocumentTextCreatePayload + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/document/create_by_text' +} + +export type PostDatasetsByDatasetIdDocumentCreateByText2Errors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentCreateByText2Error + = PostDatasetsByDatasetIdDocumentCreateByText2Errors[keyof PostDatasetsByDatasetIdDocumentCreateByText2Errors] + +export type PostDatasetsByDatasetIdDocumentCreateByText2Responses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentCreateByText2Response + = PostDatasetsByDatasetIdDocumentCreateByText2Responses[keyof PostDatasetsByDatasetIdDocumentCreateByText2Responses] + +export type GetDatasetsByDatasetIdDocumentsData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents' +} + +export type GetDatasetsByDatasetIdDocumentsErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsError + = GetDatasetsByDatasetIdDocumentsErrors[keyof GetDatasetsByDatasetIdDocumentsErrors] + +export type GetDatasetsByDatasetIdDocumentsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsResponse + = GetDatasetsByDatasetIdDocumentsResponses[keyof GetDatasetsByDatasetIdDocumentsResponses] + +export type PostDatasetsByDatasetIdDocumentsDownloadZipData = { + body: DocumentBatchDownloadZipPayload + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/download-zip' +} + +export type PostDatasetsByDatasetIdDocumentsDownloadZipErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsDownloadZipError + = PostDatasetsByDatasetIdDocumentsDownloadZipErrors[keyof PostDatasetsByDatasetIdDocumentsDownloadZipErrors] + +export type PostDatasetsByDatasetIdDocumentsDownloadZipResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsDownloadZipResponse + = PostDatasetsByDatasetIdDocumentsDownloadZipResponses[keyof PostDatasetsByDatasetIdDocumentsDownloadZipResponses] + +export type PostDatasetsByDatasetIdDocumentsMetadataData = { + body: MetadataOperationData + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/metadata' +} + +export type PostDatasetsByDatasetIdDocumentsMetadataErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsMetadataError + = PostDatasetsByDatasetIdDocumentsMetadataErrors[keyof PostDatasetsByDatasetIdDocumentsMetadataErrors] + +export type PostDatasetsByDatasetIdDocumentsMetadataResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsMetadataResponse + = PostDatasetsByDatasetIdDocumentsMetadataResponses[keyof PostDatasetsByDatasetIdDocumentsMetadataResponses] + +export type PatchDatasetsByDatasetIdDocumentsStatusByActionData = { + body?: never + path: { + dataset_id: string + action: string + } + query?: never + url: '/datasets/{dataset_id}/documents/status/{action}' +} + +export type PatchDatasetsByDatasetIdDocumentsStatusByActionErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdDocumentsStatusByActionError + = PatchDatasetsByDatasetIdDocumentsStatusByActionErrors[keyof PatchDatasetsByDatasetIdDocumentsStatusByActionErrors] + +export type PatchDatasetsByDatasetIdDocumentsStatusByActionResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdDocumentsStatusByActionResponse + = PatchDatasetsByDatasetIdDocumentsStatusByActionResponses[keyof PatchDatasetsByDatasetIdDocumentsStatusByActionResponses] + +export type GetDatasetsByDatasetIdDocumentsByBatchIndexingStatusData = { + body?: never + path: { + dataset_id: string + batch: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{batch}/indexing-status' +} + +export type GetDatasetsByDatasetIdDocumentsByBatchIndexingStatusErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByBatchIndexingStatusError + = GetDatasetsByDatasetIdDocumentsByBatchIndexingStatusErrors[keyof GetDatasetsByDatasetIdDocumentsByBatchIndexingStatusErrors] + +export type GetDatasetsByDatasetIdDocumentsByBatchIndexingStatusResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByBatchIndexingStatusResponse + = GetDatasetsByDatasetIdDocumentsByBatchIndexingStatusResponses[keyof GetDatasetsByDatasetIdDocumentsByBatchIndexingStatusResponses] + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}' +} + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdError + = DeleteDatasetsByDatasetIdDocumentsByDocumentIdErrors[keyof DeleteDatasetsByDatasetIdDocumentsByDocumentIdErrors] + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse + = DeleteDatasetsByDatasetIdDocumentsByDocumentIdResponses[keyof DeleteDatasetsByDatasetIdDocumentsByDocumentIdResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdError + = GetDatasetsByDatasetIdDocumentsByDocumentIdErrors[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdErrors] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdResponses] + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}' +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdError + = PatchDatasetsByDatasetIdDocumentsByDocumentIdErrors[keyof PatchDatasetsByDatasetIdDocumentsByDocumentIdErrors] + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdResponse + = PatchDatasetsByDatasetIdDocumentsByDocumentIdResponses[keyof PatchDatasetsByDatasetIdDocumentsByDocumentIdResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/download' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadError + = GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadErrors[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadErrors] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: { + keyword?: string | null + status?: Array + } + url: '/datasets/{dataset_id}/documents/{document_id}/segments' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsError + = GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsErrors[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsErrors] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsData = { + body: SegmentCreatePayload + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments' +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsError + = PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsErrors[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsErrors] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse + = PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponses] + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdData = { + body?: never + path: { + dataset_id: string + document_id: string + segment_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' +} + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdError + = DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdErrors[keyof DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdErrors] + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse + = DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses[keyof DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdData = { + body?: never + path: { + segment_id: string + document_id: string + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdError + = GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdErrors[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdErrors] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdData = { + body: SegmentUpdatePayload + path: { + dataset_id: string + document_id: string + segment_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdError + = PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdErrors[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdErrors] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse + = PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponses] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksData = { + body?: never + path: { + dataset_id: string + document_id: string + segment_id: string + } + query?: { + keyword?: string | null + limit?: number + page?: number + } + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks' +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksError + = GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksErrors[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksErrors] + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse + = GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses[keyof GetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksData = { + body: ChildChunkCreatePayload + path: { + dataset_id: string + document_id: string + segment_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks' +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksError + = PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksErrors[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksErrors] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse + = PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponses] + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdData + = { + body?: never + path: { + dataset_id: string + document_id: string + segment_id: string + child_chunk_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' + } + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdErrors + = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + } + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdError + = DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdErrors[keyof DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdErrors] + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses + = { + 204: { + [key: string]: unknown + } + } + +export type DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse + = DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses[keyof DeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses] + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdData + = { + body: ChildChunkUpdatePayload + path: { + dataset_id: string + document_id: string + segment_id: string + child_chunk_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' + } + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdErrors + = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + } + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdError + = PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdErrors[keyof PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdErrors] + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses + = { + 200: { + [key: string]: unknown + } + } + +export type PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse + = PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses[keyof PatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponses] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFileData = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/update-by-file' +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFileErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFileError + = PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFileErrors[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFileErrors] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFileResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFileResponse + = PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFileResponses[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFileResponses] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextData = { + body: DocumentTextUpdate + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/update-by-text' +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextError + = PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextErrors[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextErrors] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextResponse + = PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextResponses[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextResponses] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Data = { + body?: never + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/update_by_file' +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Errors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Error + = PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Errors[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Errors] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Responses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Response + = PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Responses[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Responses] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Data = { + body: DocumentTextUpdate + path: { + dataset_id: string + document_id: string + } + query?: never + url: '/datasets/{dataset_id}/documents/{document_id}/update_by_text' +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Errors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Error + = PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Errors[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Errors] + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Responses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Response + = PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Responses[keyof PostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Responses] + +export type PostDatasetsByDatasetIdHitTestingData = { + body: HitTestingPayload + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/hit-testing' +} + +export type PostDatasetsByDatasetIdHitTestingErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdHitTestingError + = PostDatasetsByDatasetIdHitTestingErrors[keyof PostDatasetsByDatasetIdHitTestingErrors] + +export type PostDatasetsByDatasetIdHitTestingResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdHitTestingResponse + = PostDatasetsByDatasetIdHitTestingResponses[keyof PostDatasetsByDatasetIdHitTestingResponses] + +export type GetDatasetsByDatasetIdMetadataData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/metadata' +} + +export type GetDatasetsByDatasetIdMetadataErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdMetadataError + = GetDatasetsByDatasetIdMetadataErrors[keyof GetDatasetsByDatasetIdMetadataErrors] + +export type GetDatasetsByDatasetIdMetadataResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdMetadataResponse + = GetDatasetsByDatasetIdMetadataResponses[keyof GetDatasetsByDatasetIdMetadataResponses] + +export type PostDatasetsByDatasetIdMetadataData = { + body: MetadataArgs + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/metadata' +} + +export type PostDatasetsByDatasetIdMetadataErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdMetadataError + = PostDatasetsByDatasetIdMetadataErrors[keyof PostDatasetsByDatasetIdMetadataErrors] + +export type PostDatasetsByDatasetIdMetadataResponses = { + 201: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdMetadataResponse + = PostDatasetsByDatasetIdMetadataResponses[keyof PostDatasetsByDatasetIdMetadataResponses] + +export type GetDatasetsByDatasetIdMetadataBuiltInData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/metadata/built-in' +} + +export type GetDatasetsByDatasetIdMetadataBuiltInErrors = { + 401: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdMetadataBuiltInError + = GetDatasetsByDatasetIdMetadataBuiltInErrors[keyof GetDatasetsByDatasetIdMetadataBuiltInErrors] + +export type GetDatasetsByDatasetIdMetadataBuiltInResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdMetadataBuiltInResponse + = GetDatasetsByDatasetIdMetadataBuiltInResponses[keyof GetDatasetsByDatasetIdMetadataBuiltInResponses] + +export type PostDatasetsByDatasetIdMetadataBuiltInByActionData = { + body?: never + path: { + dataset_id: string + action: string + } + query?: never + url: '/datasets/{dataset_id}/metadata/built-in/{action}' +} + +export type PostDatasetsByDatasetIdMetadataBuiltInByActionErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdMetadataBuiltInByActionError + = PostDatasetsByDatasetIdMetadataBuiltInByActionErrors[keyof PostDatasetsByDatasetIdMetadataBuiltInByActionErrors] + +export type PostDatasetsByDatasetIdMetadataBuiltInByActionResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdMetadataBuiltInByActionResponse + = PostDatasetsByDatasetIdMetadataBuiltInByActionResponses[keyof PostDatasetsByDatasetIdMetadataBuiltInByActionResponses] + +export type DeleteDatasetsByDatasetIdMetadataByMetadataIdData = { + body?: never + path: { + dataset_id: string + metadata_id: string + } + query?: never + url: '/datasets/{dataset_id}/metadata/{metadata_id}' +} + +export type DeleteDatasetsByDatasetIdMetadataByMetadataIdErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdMetadataByMetadataIdError + = DeleteDatasetsByDatasetIdMetadataByMetadataIdErrors[keyof DeleteDatasetsByDatasetIdMetadataByMetadataIdErrors] + +export type DeleteDatasetsByDatasetIdMetadataByMetadataIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteDatasetsByDatasetIdMetadataByMetadataIdResponse + = DeleteDatasetsByDatasetIdMetadataByMetadataIdResponses[keyof DeleteDatasetsByDatasetIdMetadataByMetadataIdResponses] + +export type PatchDatasetsByDatasetIdMetadataByMetadataIdData = { + body: MetadataUpdatePayload + path: { + dataset_id: string + metadata_id: string + } + query?: never + url: '/datasets/{dataset_id}/metadata/{metadata_id}' +} + +export type PatchDatasetsByDatasetIdMetadataByMetadataIdErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdMetadataByMetadataIdError + = PatchDatasetsByDatasetIdMetadataByMetadataIdErrors[keyof PatchDatasetsByDatasetIdMetadataByMetadataIdErrors] + +export type PatchDatasetsByDatasetIdMetadataByMetadataIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchDatasetsByDatasetIdMetadataByMetadataIdResponse + = PatchDatasetsByDatasetIdMetadataByMetadataIdResponses[keyof PatchDatasetsByDatasetIdMetadataByMetadataIdResponses] + +export type GetDatasetsByDatasetIdPipelineDatasourcePluginsData = { + body?: never + path: { + dataset_id: string + } + query?: { + is_published?: string + } + url: '/datasets/{dataset_id}/pipeline/datasource-plugins' +} + +export type GetDatasetsByDatasetIdPipelineDatasourcePluginsErrors = { + 401: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdPipelineDatasourcePluginsError + = GetDatasetsByDatasetIdPipelineDatasourcePluginsErrors[keyof GetDatasetsByDatasetIdPipelineDatasourcePluginsErrors] + +export type GetDatasetsByDatasetIdPipelineDatasourcePluginsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdPipelineDatasourcePluginsResponse + = GetDatasetsByDatasetIdPipelineDatasourcePluginsResponses[keyof GetDatasetsByDatasetIdPipelineDatasourcePluginsResponses] + +export type PostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunData = { + body?: never + path: { + dataset_id: string + node_id: string + } + query?: never + url: '/datasets/{dataset_id}/pipeline/datasource/nodes/{node_id}/run' +} + +export type PostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunErrors = { + 401: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunError + = PostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunErrors[keyof PostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunErrors] + +export type PostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunResponse + = PostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunResponses[keyof PostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunResponses] + +export type PostDatasetsByDatasetIdPipelineRunData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/pipeline/run' +} + +export type PostDatasetsByDatasetIdPipelineRunErrors = { + 401: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdPipelineRunError + = PostDatasetsByDatasetIdPipelineRunErrors[keyof PostDatasetsByDatasetIdPipelineRunErrors] + +export type PostDatasetsByDatasetIdPipelineRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdPipelineRunResponse + = PostDatasetsByDatasetIdPipelineRunResponses[keyof PostDatasetsByDatasetIdPipelineRunResponses] + +export type PostDatasetsByDatasetIdRetrieveData = { + body: HitTestingPayload + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/retrieve' +} + +export type PostDatasetsByDatasetIdRetrieveErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdRetrieveError + = PostDatasetsByDatasetIdRetrieveErrors[keyof PostDatasetsByDatasetIdRetrieveErrors] + +export type PostDatasetsByDatasetIdRetrieveResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostDatasetsByDatasetIdRetrieveResponse + = PostDatasetsByDatasetIdRetrieveResponses[keyof PostDatasetsByDatasetIdRetrieveResponses] + +export type GetDatasetsByDatasetIdTagsData = { + body?: never + path: { + dataset_id: string + } + query?: never + url: '/datasets/{dataset_id}/tags' +} + +export type GetDatasetsByDatasetIdTagsErrors = { + 401: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdTagsError + = GetDatasetsByDatasetIdTagsErrors[keyof GetDatasetsByDatasetIdTagsErrors] + +export type GetDatasetsByDatasetIdTagsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetDatasetsByDatasetIdTagsResponse + = GetDatasetsByDatasetIdTagsResponses[keyof GetDatasetsByDatasetIdTagsResponses] + +export type GetEndUsersByEndUserIdData = { + body?: never + path: { + end_user_id: string + } + query?: never + url: '/end-users/{end_user_id}' +} + +export type GetEndUsersByEndUserIdErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetEndUsersByEndUserIdError + = GetEndUsersByEndUserIdErrors[keyof GetEndUsersByEndUserIdErrors] + +export type GetEndUsersByEndUserIdResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetEndUsersByEndUserIdResponse + = GetEndUsersByEndUserIdResponses[keyof GetEndUsersByEndUserIdResponses] + +export type PostFilesUploadData = { + body?: never + path?: never + query?: never + url: '/files/upload' +} + +export type PostFilesUploadErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 413: { + [key: string]: unknown + } + 415: { + [key: string]: unknown + } +} + +export type PostFilesUploadError = PostFilesUploadErrors[keyof PostFilesUploadErrors] + +export type PostFilesUploadResponses = { + 201: FileResponse +} + +export type PostFilesUploadResponse = PostFilesUploadResponses[keyof PostFilesUploadResponses] + +export type GetFilesByFileIdPreviewData = { + body?: never + path: { + file_id: string + } + query?: { + as_attachment?: boolean + } + url: '/files/{file_id}/preview' +} + +export type GetFilesByFileIdPreviewErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetFilesByFileIdPreviewError + = GetFilesByFileIdPreviewErrors[keyof GetFilesByFileIdPreviewErrors] + +export type GetFilesByFileIdPreviewResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetFilesByFileIdPreviewResponse + = GetFilesByFileIdPreviewResponses[keyof GetFilesByFileIdPreviewResponses] + +export type GetFormHumanInputByFormTokenData = { + body?: never + path: { + form_token: string + } + query?: never + url: '/form/human_input/{form_token}' +} + +export type GetFormHumanInputByFormTokenErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 412: { + [key: string]: unknown + } +} + +export type GetFormHumanInputByFormTokenError + = GetFormHumanInputByFormTokenErrors[keyof GetFormHumanInputByFormTokenErrors] + +export type GetFormHumanInputByFormTokenResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetFormHumanInputByFormTokenResponse + = GetFormHumanInputByFormTokenResponses[keyof GetFormHumanInputByFormTokenResponses] + +export type PostFormHumanInputByFormTokenData = { + body: HumanInputFormSubmitPayload + path: { + form_token: string + } + query?: never + url: '/form/human_input/{form_token}' +} + +export type PostFormHumanInputByFormTokenErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 412: { + [key: string]: unknown + } +} + +export type PostFormHumanInputByFormTokenError + = PostFormHumanInputByFormTokenErrors[keyof PostFormHumanInputByFormTokenErrors] + +export type PostFormHumanInputByFormTokenResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostFormHumanInputByFormTokenResponse + = PostFormHumanInputByFormTokenResponses[keyof PostFormHumanInputByFormTokenResponses] + +export type GetInfoData = { + body?: never + path?: never + query?: never + url: '/info' +} + +export type GetInfoErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetInfoError = GetInfoErrors[keyof GetInfoErrors] + +export type GetInfoResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetInfoResponse = GetInfoResponses[keyof GetInfoResponses] + +export type GetMessagesData = { + body?: never + path?: never + query: { + conversation_id: string + first_id?: string | null + limit?: number + } + url: '/messages' +} + +export type GetMessagesErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetMessagesError = GetMessagesErrors[keyof GetMessagesErrors] + +export type GetMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetMessagesResponse = GetMessagesResponses[keyof GetMessagesResponses] + +export type PostMessagesByMessageIdFeedbacksData = { + body: MessageFeedbackPayload + path: { + message_id: string + } + query?: never + url: '/messages/{message_id}/feedbacks' +} + +export type PostMessagesByMessageIdFeedbacksErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostMessagesByMessageIdFeedbacksError + = PostMessagesByMessageIdFeedbacksErrors[keyof PostMessagesByMessageIdFeedbacksErrors] + +export type PostMessagesByMessageIdFeedbacksResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostMessagesByMessageIdFeedbacksResponse + = PostMessagesByMessageIdFeedbacksResponses[keyof PostMessagesByMessageIdFeedbacksResponses] + +export type GetMessagesByMessageIdSuggestedData = { + body?: never + path: { + message_id: string + } + query?: never + url: '/messages/{message_id}/suggested' +} + +export type GetMessagesByMessageIdSuggestedErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetMessagesByMessageIdSuggestedError + = GetMessagesByMessageIdSuggestedErrors[keyof GetMessagesByMessageIdSuggestedErrors] + +export type GetMessagesByMessageIdSuggestedResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetMessagesByMessageIdSuggestedResponse + = GetMessagesByMessageIdSuggestedResponses[keyof GetMessagesByMessageIdSuggestedResponses] + +export type GetMetaData = { + body?: never + path?: never + query?: never + url: '/meta' +} + +export type GetMetaErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetMetaError = GetMetaErrors[keyof GetMetaErrors] + +export type GetMetaResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetMetaResponse = GetMetaResponses[keyof GetMetaResponses] + +export type GetParametersData = { + body?: never + path?: never + query?: never + url: '/parameters' +} + +export type GetParametersErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetParametersError = GetParametersErrors[keyof GetParametersErrors] + +export type GetParametersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetParametersResponse = GetParametersResponses[keyof GetParametersResponses] + +export type GetSiteData = { + body?: never + path?: never + query?: never + url: '/site' +} + +export type GetSiteErrors = { + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } +} + +export type GetSiteError = GetSiteErrors[keyof GetSiteErrors] + +export type GetSiteResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetSiteResponse = GetSiteResponses[keyof GetSiteResponses] + +export type PostTextToAudioData = { + body: TextToAudioPayload + path?: never + query?: never + url: '/text-to-audio' +} + +export type PostTextToAudioErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostTextToAudioError = PostTextToAudioErrors[keyof PostTextToAudioErrors] + +export type PostTextToAudioResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTextToAudioResponse = PostTextToAudioResponses[keyof PostTextToAudioResponses] + +export type GetWorkflowByTaskIdEventsData = { + body?: never + path: { + task_id: string + } + query?: { + user?: string + include_state_snapshot?: string + continue_on_pause?: string + } + url: '/workflow/{task_id}/events' +} + +export type GetWorkflowByTaskIdEventsErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetWorkflowByTaskIdEventsError + = GetWorkflowByTaskIdEventsErrors[keyof GetWorkflowByTaskIdEventsErrors] + +export type GetWorkflowByTaskIdEventsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkflowByTaskIdEventsResponse + = GetWorkflowByTaskIdEventsResponses[keyof GetWorkflowByTaskIdEventsResponses] + +export type GetWorkflowsLogsData = { + body?: never + path?: never + query?: { + created_at__after?: string | null + created_at__before?: string | null + created_by_account?: string | null + created_by_end_user_session_id?: string | null + keyword?: string | null + limit?: number + page?: number + status?: 'succeeded' | 'failed' | 'stopped' | null + } + url: '/workflows/logs' +} + +export type GetWorkflowsLogsErrors = { + 401: { + [key: string]: unknown + } +} + +export type GetWorkflowsLogsError = GetWorkflowsLogsErrors[keyof GetWorkflowsLogsErrors] + +export type GetWorkflowsLogsResponses = { + 200: WorkflowAppLogPaginationResponse +} + +export type GetWorkflowsLogsResponse = GetWorkflowsLogsResponses[keyof GetWorkflowsLogsResponses] + +export type PostWorkflowsRunData = { + body: WorkflowRunPayload + path?: never + query?: never + url: '/workflows/run' +} + +export type PostWorkflowsRunErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 429: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostWorkflowsRunError = PostWorkflowsRunErrors[keyof PostWorkflowsRunErrors] + +export type PostWorkflowsRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkflowsRunResponse = PostWorkflowsRunResponses[keyof PostWorkflowsRunResponses] + +export type GetWorkflowsRunByWorkflowRunIdData = { + body?: never + path: { + workflow_run_id: string + } + query?: never + url: '/workflows/run/{workflow_run_id}' +} + +export type GetWorkflowsRunByWorkflowRunIdErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetWorkflowsRunByWorkflowRunIdError + = GetWorkflowsRunByWorkflowRunIdErrors[keyof GetWorkflowsRunByWorkflowRunIdErrors] + +export type GetWorkflowsRunByWorkflowRunIdResponses = { + 200: WorkflowRunResponse +} + +export type GetWorkflowsRunByWorkflowRunIdResponse + = GetWorkflowsRunByWorkflowRunIdResponses[keyof GetWorkflowsRunByWorkflowRunIdResponses] + +export type PostWorkflowsTasksByTaskIdStopData = { + body?: never + path: { + task_id: string + } + query?: never + url: '/workflows/tasks/{task_id}/stop' +} + +export type PostWorkflowsTasksByTaskIdStopErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostWorkflowsTasksByTaskIdStopError + = PostWorkflowsTasksByTaskIdStopErrors[keyof PostWorkflowsTasksByTaskIdStopErrors] + +export type PostWorkflowsTasksByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkflowsTasksByTaskIdStopResponse + = PostWorkflowsTasksByTaskIdStopResponses[keyof PostWorkflowsTasksByTaskIdStopResponses] + +export type PostWorkflowsByWorkflowIdRunData = { + body: WorkflowRunPayload + path: { + workflow_id: string + } + query?: never + url: '/workflows/{workflow_id}/run' +} + +export type PostWorkflowsByWorkflowIdRunErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 429: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostWorkflowsByWorkflowIdRunError + = PostWorkflowsByWorkflowIdRunErrors[keyof PostWorkflowsByWorkflowIdRunErrors] + +export type PostWorkflowsByWorkflowIdRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkflowsByWorkflowIdRunResponse + = PostWorkflowsByWorkflowIdRunResponses[keyof PostWorkflowsByWorkflowIdRunResponses] + +export type GetWorkspacesCurrentModelsModelTypesByModelTypeData = { + body?: never + path: { + model_type: string + } + query?: never + url: '/workspaces/current/models/model-types/{model_type}' +} + +export type GetWorkspacesCurrentModelsModelTypesByModelTypeErrors = { + 401: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentModelsModelTypesByModelTypeError + = GetWorkspacesCurrentModelsModelTypesByModelTypeErrors[keyof GetWorkspacesCurrentModelsModelTypesByModelTypeErrors] + +export type GetWorkspacesCurrentModelsModelTypesByModelTypeResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkspacesCurrentModelsModelTypesByModelTypeResponse + = GetWorkspacesCurrentModelsModelTypesByModelTypeResponses[keyof GetWorkspacesCurrentModelsModelTypesByModelTypeResponses] diff --git a/packages/contracts/generated/api/service/zod.gen.ts b/packages/contracts/generated/api/service/zod.gen.ts new file mode 100644 index 0000000000..6feacbdead --- /dev/null +++ b/packages/contracts/generated/api/service/zod.gen.ts @@ -0,0 +1,1599 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * Annotation + */ +export const zAnnotation = z.object({ + content: z.string().nullish(), + created_at: z.int().nullish(), + hit_count: z.int().nullish(), + id: z.string(), + question: z.string().nullish(), +}) + +/** + * AnnotationCreatePayload + */ +export const zAnnotationCreatePayload = z.object({ + answer: z.string(), + question: z.string(), +}) + +/** + * AnnotationList + */ +export const zAnnotationList = z.object({ + data: z.array(zAnnotation), + has_more: z.boolean(), + limit: z.int(), + page: z.int(), + total: z.int(), +}) + +/** + * AnnotationReplyActionPayload + */ +export const zAnnotationReplyActionPayload = z.object({ + embedding_model_name: z.string(), + embedding_provider_name: z.string(), + score_threshold: z.number(), +}) + +/** + * ChatRequestPayload + */ +export const zChatRequestPayload = z.object({ + auto_generate_name: z.boolean().optional().default(true), + conversation_id: z.string().nullish(), + files: z.array(z.record(z.string(), z.unknown())).nullish(), + inputs: z.record(z.string(), z.unknown()), + query: z.string(), + response_mode: z.enum(['blocking', 'streaming']).nullish(), + retriever_from: z.string().optional().default('dev'), + workflow_id: z.string().nullish(), +}) + +/** + * ChildChunkCreatePayload + */ +export const zChildChunkCreatePayload = z.object({ + content: z.string(), +}) + +/** + * ChildChunkListQuery + */ +export const zChildChunkListQuery = z.object({ + keyword: z.string().nullish(), + limit: z.int().gte(1).optional().default(20), + page: z.int().gte(1).optional().default(1), +}) + +/** + * ChildChunkUpdatePayload + */ +export const zChildChunkUpdatePayload = z.object({ + content: z.string(), +}) + +/** + * CompletionRequestPayload + */ +export const zCompletionRequestPayload = z.object({ + files: z.array(z.record(z.string(), z.unknown())).nullish(), + inputs: z.record(z.string(), z.unknown()), + query: z.string().optional().default(''), + response_mode: z.enum(['blocking', 'streaming']).nullish(), + retriever_from: z.string().optional().default('dev'), +}) + +/** + * ConversationListQuery + */ +export const zConversationListQuery = z.object({ + last_id: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), + sort_by: z + .enum(['created_at', '-created_at', 'updated_at', '-updated_at']) + .optional() + .default('-updated_at'), +}) + +/** + * ConversationRenamePayload + */ +export const zConversationRenamePayload = z.object({ + auto_generate: z.boolean().optional().default(false), + name: z.string().nullish(), +}) + +/** + * ConversationVariableResponse + */ +export const zConversationVariableResponse = z.object({ + created_at: z.int().nullish(), + description: z.string().nullish(), + id: z.string(), + name: z.string(), + updated_at: z.int().nullish(), + value: z.string().nullish(), + value_type: z.string(), +}) + +/** + * ConversationVariableInfiniteScrollPaginationResponse + */ +export const zConversationVariableInfiniteScrollPaginationResponse = z.object({ + data: z.array(zConversationVariableResponse), + has_more: z.boolean(), + limit: z.int(), +}) + +/** + * ConversationVariableUpdatePayload + */ +export const zConversationVariableUpdatePayload = z.object({ + value: z.unknown(), +}) + +/** + * ConversationVariablesQuery + */ +export const zConversationVariablesQuery = z.object({ + last_id: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), + variable_name: z.string().min(1).max(255).nullish(), +}) + +/** + * DocumentBatchDownloadZipPayload + * + * Request payload for bulk downloading documents as a zip archive. + */ +export const zDocumentBatchDownloadZipPayload = z.object({ + document_ids: z.array(z.uuid()).min(1).max(100), +}) + +/** + * FeedbackListQuery + */ +export const zFeedbackListQuery = z.object({ + limit: z.int().gte(1).lte(101).optional().default(20), + page: z.int().gte(1).optional().default(1), +}) + +/** + * FilePreviewQuery + */ +export const zFilePreviewQuery = z.object({ + as_attachment: z.boolean().optional().default(false), +}) + +/** + * FileResponse + */ +export const zFileResponse = z.object({ + conversation_id: z.string().nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + extension: z.string().nullish(), + file_key: z.string().nullish(), + id: z.string(), + mime_type: z.string().nullish(), + name: z.string(), + original_url: z.string().nullish(), + preview_url: z.string().nullish(), + size: z.int(), + source_url: z.string().nullish(), + tenant_id: z.string().nullish(), + user_id: z.string().nullish(), +}) + +/** + * MessageFeedbackPayload + */ +export const zMessageFeedbackPayload = z.object({ + content: z.string().nullish(), + rating: z.enum(['like', 'dislike']).nullish(), +}) + +/** + * MessageListQuery + */ +export const zMessageListQuery = z.object({ + conversation_id: z.string(), + first_id: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), +}) + +/** + * MetadataArgs + */ +export const zMetadataArgs = z.object({ + name: z.string(), + type: z.enum(['string', 'number', 'time']), +}) + +/** + * MetadataUpdatePayload + */ +export const zMetadataUpdatePayload = z.object({ + name: z.string(), +}) + +/** + * SegmentCreatePayload + */ +export const zSegmentCreatePayload = z.object({ + segments: z.array(z.record(z.string(), z.unknown())).nullish(), +}) + +/** + * SegmentListQuery + */ +export const zSegmentListQuery = z.object({ + keyword: z.string().nullish(), + status: z.array(z.string()).optional(), +}) + +/** + * TagBindingPayload + */ +export const zTagBindingPayload = z.object({ + tag_ids: z.array(z.string()), + target_id: z.string(), +}) + +/** + * TagCreatePayload + */ +export const zTagCreatePayload = z.object({ + name: z.string().min(1).max(50), +}) + +/** + * TagDeletePayload + */ +export const zTagDeletePayload = z.object({ + tag_id: z.string(), +}) + +/** + * TagUnbindingPayload + */ +export const zTagUnbindingPayload = z.object({ + tag_id: z.string(), + target_id: z.string(), +}) + +/** + * TagUpdatePayload + */ +export const zTagUpdatePayload = z.object({ + name: z.string().min(1).max(50), + tag_id: z.string(), +}) + +/** + * TextToAudioPayload + */ +export const zTextToAudioPayload = z.object({ + message_id: z.string().nullish(), + streaming: z.boolean().nullish(), + text: z.string().nullish(), + voice: z.string().nullish(), +}) + +/** + * WorkflowLogQuery + */ +export const zWorkflowLogQuery = z.object({ + created_at__after: z.string().nullish(), + created_at__before: z.string().nullish(), + created_by_account: z.string().nullish(), + created_by_end_user_session_id: z.string().nullish(), + keyword: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), + page: z.int().gte(1).lte(99999).optional().default(1), + status: z.enum(['succeeded', 'failed', 'stopped']).nullish(), +}) + +/** + * WorkflowRunPayload + */ +export const zWorkflowRunPayload = z.object({ + files: z.array(z.record(z.string(), z.unknown())).nullish(), + inputs: z.record(z.string(), z.unknown()), + response_mode: z.enum(['blocking', 'streaming']).nullish(), +}) + +/** + * WorkflowRunResponse + */ +export const zWorkflowRunResponse = z.object({ + created_at: z.int().nullish(), + elapsed_time: z.unknown().optional(), + error: z.string().nullish(), + finished_at: z.int().nullish(), + id: z.string(), + inputs: z.unknown().optional(), + outputs: z.record(z.string(), z.unknown()).optional(), + status: z.string(), + total_steps: z.int().nullish(), + total_tokens: z.int().nullish(), + workflow_id: z.string(), +}) + +/** + * Condition + * + * Condition detail + */ +export const zCondition = z.object({ + comparison_operator: z.enum([ + 'contains', + 'not contains', + 'start with', + 'end with', + 'is', + 'is not', + 'empty', + 'not empty', + 'in', + 'not in', + '=', + '≠', + '>', + '<', + '≥', + '≤', + 'before', + 'after', + ]), + name: z.string(), + value: z.unknown().optional(), +}) + +/** + * DatasetPermissionEnum + */ +export const zDatasetPermissionEnum = z.enum(['only_me', 'all_team_members', 'partial_members']) + +/** + * MetadataFilteringCondition + * + * Metadata Filtering Condition. + */ +export const zMetadataFilteringCondition = z.object({ + conditions: z.array(zCondition).nullish(), + logical_operator: z.enum(['and', 'or']).nullish().default('and'), +}) + +/** + * RerankingModel + */ +export const zRerankingModel = z.object({ + reranking_model_name: z.string().nullish(), + reranking_provider_name: z.string().nullish(), +}) + +/** + * RetrievalMethod + */ +export const zRetrievalMethod = z.enum([ + 'semantic_search', + 'full_text_search', + 'hybrid_search', + 'keyword_search', +]) + +/** + * WeightKeywordSetting + */ +export const zWeightKeywordSetting = z.object({ + keyword_weight: z.number(), +}) + +/** + * WeightVectorSetting + */ +export const zWeightVectorSetting = z.object({ + embedding_model_name: z.string(), + embedding_provider_name: z.string(), + vector_weight: z.number(), +}) + +/** + * WeightModel + */ +export const zWeightModel = z.object({ + keyword_setting: zWeightKeywordSetting.optional(), + vector_setting: zWeightVectorSetting.optional(), + weight_type: z.enum(['semantic_first', 'keyword_first', 'customized']).nullish(), +}) + +/** + * RetrievalModel + */ +export const zRetrievalModel = z.object({ + metadata_filtering_conditions: zMetadataFilteringCondition.optional(), + reranking_enable: z.boolean(), + reranking_mode: z.string().nullish(), + reranking_model: zRerankingModel.optional(), + score_threshold: z.number().nullish(), + score_threshold_enabled: z.boolean(), + search_method: zRetrievalMethod, + top_k: z.int(), + weights: zWeightModel.optional(), +}) + +/** + * DatasetCreatePayload + */ +export const zDatasetCreatePayload = z.object({ + description: z.string().max(400).optional().default(''), + embedding_model: z.string().nullish(), + embedding_model_provider: z.string().nullish(), + external_knowledge_api_id: z.string().nullish(), + external_knowledge_id: z.string().nullish(), + indexing_technique: z.enum(['high_quality', 'economy']).nullish(), + name: z.string().min(1).max(40), + permission: zDatasetPermissionEnum.optional(), + provider: z.string().optional().default('vendor'), + retrieval_model: zRetrievalModel.optional(), + summary_index_setting: z.record(z.string(), z.unknown()).nullish(), +}) + +/** + * DatasetUpdatePayload + */ +export const zDatasetUpdatePayload = z.object({ + description: z.string().max(400).nullish(), + embedding_model: z.string().nullish(), + embedding_model_provider: z.string().nullish(), + external_knowledge_api_id: z.string().nullish(), + external_knowledge_id: z.string().nullish(), + external_retrieval_model: z.record(z.string(), z.unknown()).nullish(), + indexing_technique: z.enum(['high_quality', 'economy']).nullish(), + name: z.string().min(1).max(40).nullish(), + partial_member_list: z.array(z.record(z.string(), z.string())).nullish(), + permission: zDatasetPermissionEnum.optional(), + retrieval_model: zRetrievalModel.optional(), +}) + +/** + * HitTestingPayload + */ +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(), +}) + +/** + * PreProcessingRule + */ +export const zPreProcessingRule = z.object({ + enabled: z.boolean(), + id: z.string(), +}) + +/** + * Segmentation + */ +export const zSegmentation = z.object({ + chunk_overlap: z.int().optional().default(0), + max_tokens: z.int(), + separator: z.string().optional().default('\n'), +}) + +/** + * Rule + */ +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(), +}) + +/** + * ProcessRule + */ +export const zProcessRule = z.object({ + mode: z.enum(['automatic', 'custom', 'hierarchical']), + rules: zRule.optional(), +}) + +/** + * DocumentTextCreatePayload + */ +export const zDocumentTextCreatePayload = z.object({ + doc_form: z.string().optional().default('text_model'), + doc_language: z.string().optional().default('English'), + embedding_model: z.string().nullish(), + embedding_model_provider: z.string().nullish(), + indexing_technique: z.string().nullish(), + name: z.string(), + original_document_id: z.string().nullish(), + process_rule: zProcessRule.optional(), + retrieval_model: zRetrievalModel.optional(), + text: z.string(), +}) + +/** + * DocumentTextUpdate + */ +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(), + text: z.string().nullish(), +}) + +export const zJsonValue = z.unknown() + +/** + * HumanInputFormSubmitPayload + */ +export const zHumanInputFormSubmitPayload = z.object({ + action: z.string(), + inputs: z.record(z.string(), zJsonValue), +}) + +/** + * MetadataDetail + */ +export const zMetadataDetail = z.object({ + id: z.string(), + name: z.string(), + value: z.unknown().optional(), +}) + +/** + * DocumentMetadataOperation + */ +export const zDocumentMetadataOperation = z.object({ + document_id: z.string(), + metadata_list: z.array(zMetadataDetail), + partial_update: z.boolean().optional().default(false), +}) + +/** + * MetadataOperationData + * + * Metadata operation data + */ +export const zMetadataOperationData = z.object({ + operation_data: z.array(zDocumentMetadataOperation), +}) + +/** + * SegmentUpdateArgs + */ +export const zSegmentUpdateArgs = z.object({ + answer: z.string().nullish(), + attachment_ids: z.array(z.string()).nullish(), + content: z.string().nullish(), + enabled: z.boolean().nullish(), + keywords: z.array(z.string()).nullish(), + regenerate_child_chunks: z.boolean().optional().default(false), + summary: z.string().nullish(), +}) + +/** + * SegmentUpdatePayload + */ +export const zSegmentUpdatePayload = z.object({ + segment: zSegmentUpdateArgs, +}) + +/** + * SimpleAccount + */ +export const zSimpleAccount = z.object({ + email: z.string(), + id: z.string(), + name: z.string(), +}) + +/** + * SimpleEndUser + */ +export const zSimpleEndUser = z.object({ + id: z.string(), + is_anonymous: z.boolean(), + session_id: z.string().nullish(), + type: z.string(), +}) + +/** + * WorkflowRunForLogResponse + */ +export const zWorkflowRunForLogResponse = z.object({ + created_at: z.int().nullish(), + elapsed_time: z.unknown().optional(), + error: z.string().nullish(), + exceptions_count: z.int().nullish(), + finished_at: z.int().nullish(), + id: z.string(), + status: z.string().nullish(), + total_steps: z.int().nullish(), + total_tokens: z.int().nullish(), + triggered_from: z.string().nullish(), + version: z.string().nullish(), +}) + +/** + * WorkflowAppLogPartialResponse + */ +export const zWorkflowAppLogPartialResponse = z.object({ + created_at: z.int().nullish(), + created_by_account: zSimpleAccount.optional(), + created_by_end_user: zSimpleEndUser.optional(), + created_by_role: z.string().nullish(), + created_from: z.string().nullish(), + details: z.unknown().optional(), + id: z.string(), + workflow_run: zWorkflowRunForLogResponse.optional(), +}) + +/** + * WorkflowAppLogPaginationResponse + */ +export const zWorkflowAppLogPaginationResponse = z.object({ + data: z.array(zWorkflowAppLogPartialResponse), + has_more: z.boolean(), + limit: z.int(), + page: z.int(), + total: z.int(), +}) + +/** + * Success + */ +export const zGetRootResponse = z.record(z.string(), z.unknown()) + +export const zGetAppFeedbacksQuery = z.object({ + limit: z.int().gte(1).lte(101).optional().default(20), + page: z.int().gte(1).optional().default(1), +}) + +/** + * Feedbacks retrieved successfully + */ +export const zGetAppFeedbacksResponse = z.record(z.string(), z.unknown()) + +export const zPostAppsAnnotationReplyByActionBody = zAnnotationReplyActionPayload + +export const zPostAppsAnnotationReplyByActionPath = z.object({ + action: z.string(), +}) + +/** + * Action completed successfully + */ +export const zPostAppsAnnotationReplyByActionResponse = z.record(z.string(), z.unknown()) + +export const zGetAppsAnnotationReplyByActionStatusByJobIdPath = z.object({ + action: z.string(), + job_id: z.string(), +}) + +/** + * Job status retrieved successfully + */ +export const zGetAppsAnnotationReplyByActionStatusByJobIdResponse = z.record( + z.string(), + z.unknown(), +) + +/** + * Annotations retrieved successfully + */ +export const zGetAppsAnnotationsResponse = zAnnotationList + +export const zPostAppsAnnotationsBody = zAnnotationCreatePayload + +/** + * Annotation created successfully + */ +export const zPostAppsAnnotationsResponse = zAnnotation + +export const zDeleteAppsAnnotationsByAnnotationIdPath = z.object({ + annotation_id: z.string(), +}) + +/** + * Annotation deleted successfully + */ +export const zDeleteAppsAnnotationsByAnnotationIdResponse = z.record(z.string(), z.unknown()) + +export const zPutAppsAnnotationsByAnnotationIdBody = zAnnotationCreatePayload + +export const zPutAppsAnnotationsByAnnotationIdPath = z.object({ + annotation_id: z.string(), +}) + +/** + * Annotation updated successfully + */ +export const zPutAppsAnnotationsByAnnotationIdResponse = zAnnotation + +/** + * Audio successfully transcribed + */ +export const zPostAudioToTextResponse = z.record(z.string(), z.unknown()) + +export const zPostChatMessagesBody = zChatRequestPayload + +/** + * Message sent successfully + */ +export const zPostChatMessagesResponse = z.record(z.string(), z.unknown()) + +export const zPostChatMessagesByTaskIdStopPath = z.object({ + task_id: z.string(), +}) + +/** + * Task stopped successfully + */ +export const zPostChatMessagesByTaskIdStopResponse = z.record(z.string(), z.unknown()) + +export const zPostCompletionMessagesBody = zCompletionRequestPayload + +/** + * Completion created successfully + */ +export const zPostCompletionMessagesResponse = z.record(z.string(), z.unknown()) + +export const zPostCompletionMessagesByTaskIdStopPath = z.object({ + task_id: z.string(), +}) + +/** + * Task stopped successfully + */ +export const zPostCompletionMessagesByTaskIdStopResponse = z.record(z.string(), z.unknown()) + +export const zGetConversationsQuery = z.object({ + last_id: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), + sort_by: z + .enum(['created_at', '-created_at', 'updated_at', '-updated_at']) + .optional() + .default('-updated_at'), +}) + +/** + * Conversations retrieved successfully + */ +export const zGetConversationsResponse = z.record(z.string(), z.unknown()) + +export const zDeleteConversationsByCIdPath = z.object({ + c_id: z.string(), +}) + +/** + * Conversation deleted successfully + */ +export const zDeleteConversationsByCIdResponse = z.record(z.string(), z.unknown()) + +export const zPostConversationsByCIdNameBody = zConversationRenamePayload + +export const zPostConversationsByCIdNamePath = z.object({ + c_id: z.string(), +}) + +/** + * Conversation renamed successfully + */ +export const zPostConversationsByCIdNameResponse = z.record(z.string(), z.unknown()) + +export const zGetConversationsByCIdVariablesPath = z.object({ + c_id: z.string(), +}) + +export const zGetConversationsByCIdVariablesQuery = z.object({ + last_id: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), + variable_name: z.string().min(1).max(255).nullish(), +}) + +/** + * Variables retrieved successfully + */ +export const zGetConversationsByCIdVariablesResponse + = zConversationVariableInfiniteScrollPaginationResponse + +export const zPutConversationsByCIdVariablesByVariableIdBody = zConversationVariableUpdatePayload + +export const zPutConversationsByCIdVariablesByVariableIdPath = z.object({ + c_id: z.string(), + variable_id: z.string(), +}) + +/** + * Variable updated successfully + */ +export const zPutConversationsByCIdVariablesByVariableIdResponse = zConversationVariableResponse + +/** + * Datasets retrieved successfully + */ +export const zGetDatasetsResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsBody = zDatasetCreatePayload + +/** + * Dataset created successfully + */ +export const zPostDatasetsResponse = z.record(z.string(), z.unknown()) + +/** + * File uploaded successfully + */ +export const zPostDatasetsPipelineFileUploadResponse = z.record(z.string(), z.unknown()) + +export const zDeleteDatasetsTagsBody = zTagDeletePayload + +/** + * Tag deleted successfully + */ +export const zDeleteDatasetsTagsResponse = z.record(z.string(), z.unknown()) + +/** + * Tags retrieved successfully + */ +export const zGetDatasetsTagsResponse = z.record(z.string(), z.unknown()) + +export const zPatchDatasetsTagsBody = zTagUpdatePayload + +/** + * Tag updated successfully + */ +export const zPatchDatasetsTagsResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsTagsBody = zTagCreatePayload + +/** + * Tag created successfully + */ +export const zPostDatasetsTagsResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsTagsBindingBody = zTagBindingPayload + +/** + * Tags bound successfully + */ +export const zPostDatasetsTagsBindingResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsTagsUnbindingBody = zTagUnbindingPayload + +/** + * Tag unbound successfully + */ +export const zPostDatasetsTagsUnbindingResponse = z.record(z.string(), z.unknown()) + +export const zDeleteDatasetsByDatasetIdPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Dataset deleted successfully + */ +export const zDeleteDatasetsByDatasetIdResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Dataset retrieved successfully + */ +export const zGetDatasetsByDatasetIdResponse = z.record(z.string(), z.unknown()) + +export const zPatchDatasetsByDatasetIdBody = zDatasetUpdatePayload + +export const zPatchDatasetsByDatasetIdPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Dataset updated successfully + */ +export const zPatchDatasetsByDatasetIdResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdDocumentCreateByFilePath = z.object({ + dataset_id: z.string(), +}) + +/** + * Document created successfully + */ +export const zPostDatasetsByDatasetIdDocumentCreateByFileResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentCreateByTextBody = zDocumentTextCreatePayload + +export const zPostDatasetsByDatasetIdDocumentCreateByTextPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Document created successfully + */ +export const zPostDatasetsByDatasetIdDocumentCreateByTextResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentCreateByFile2Path = z.object({ + dataset_id: z.string(), +}) + +/** + * Document created successfully + */ +export const zPostDatasetsByDatasetIdDocumentCreateByFile2Response = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentCreateByText2Body = zDocumentTextCreatePayload + +export const zPostDatasetsByDatasetIdDocumentCreateByText2Path = z.object({ + dataset_id: z.string(), +}) + +/** + * Document created successfully + */ +export const zPostDatasetsByDatasetIdDocumentCreateByText2Response = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Documents retrieved successfully + */ +export const zGetDatasetsByDatasetIdDocumentsResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdDocumentsDownloadZipBody = zDocumentBatchDownloadZipPayload + +export const zPostDatasetsByDatasetIdDocumentsDownloadZipPath = z.object({ + dataset_id: z.string(), +}) + +/** + * ZIP archive generated successfully + */ +export const zPostDatasetsByDatasetIdDocumentsDownloadZipResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentsMetadataBody = zMetadataOperationData + +export const zPostDatasetsByDatasetIdDocumentsMetadataPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Documents metadata updated successfully + */ +export const zPostDatasetsByDatasetIdDocumentsMetadataResponse = z.record(z.string(), z.unknown()) + +export const zPatchDatasetsByDatasetIdDocumentsStatusByActionPath = z.object({ + dataset_id: z.string(), + action: z.string(), +}) + +/** + * Document status updated successfully + */ +export const zPatchDatasetsByDatasetIdDocumentsStatusByActionResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByBatchIndexingStatusPath = z.object({ + dataset_id: z.string(), + batch: z.string(), +}) + +/** + * Indexing status retrieved successfully + */ +export const zGetDatasetsByDatasetIdDocumentsByBatchIndexingStatusResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Document deleted successfully + */ +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Document retrieved successfully + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Document updated successfully + */ +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdDownloadPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Download URL generated successfully + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdDownloadResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsQuery = z.object({ + keyword: z.string().nullish(), + status: z.array(z.string()).optional(), +}) + +/** + * Segments retrieved successfully + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBody = zSegmentCreatePayload + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Segments created successfully + */ +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), +}) + +/** + * Segment deleted successfully + */ +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath = z.object({ + segment_id: z.string(), + document_id: z.string(), + dataset_id: z.string(), +}) + +/** + * Segment retrieved successfully + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdBody + = zSegmentUpdatePayload + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), +}) + +/** + * Segment updated successfully + */ +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath + = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), + }) + +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksQuery + = z.object({ + keyword: z.string().nullish(), + limit: z.int().gte(1).optional().default(20), + page: z.int().gte(1).optional().default(1), + }) + +/** + * Child chunks retrieved successfully + */ +export const zGetDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse + = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksBody + = zChildChunkCreatePayload + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksPath + = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), + }) + +/** + * Child chunk created successfully + */ +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksResponse + = z.record(z.string(), z.unknown()) + +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdPath + = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), + child_chunk_id: z.string(), + }) + +/** + * Child chunk deleted successfully + */ +export const zDeleteDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse + = z.record(z.string(), z.unknown()) + +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdBody + = zChildChunkUpdatePayload + +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdPath + = z.object({ + dataset_id: z.string(), + document_id: z.string(), + segment_id: z.string(), + child_chunk_id: z.string(), + }) + +/** + * Child chunk updated successfully + */ +export const zPatchDatasetsByDatasetIdDocumentsByDocumentIdSegmentsBySegmentIdChildChunksByChildChunkIdResponse + = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFilePath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Document updated successfully + */ +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFileResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextBody = zDocumentTextUpdate + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextPath = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Document updated successfully + */ +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByTextResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Path = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Document updated successfully + */ +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByFile2Response = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Body = zDocumentTextUpdate + +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Path = z.object({ + dataset_id: z.string(), + document_id: z.string(), +}) + +/** + * Document updated successfully + */ +export const zPostDatasetsByDatasetIdDocumentsByDocumentIdUpdateByText2Response = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdHitTestingBody = zHitTestingPayload + +export const zPostDatasetsByDatasetIdHitTestingPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Hit testing results + */ +export const zPostDatasetsByDatasetIdHitTestingResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdMetadataPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Metadata retrieved successfully + */ +export const zGetDatasetsByDatasetIdMetadataResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdMetadataBody = zMetadataArgs + +export const zPostDatasetsByDatasetIdMetadataPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Metadata created successfully + */ +export const zPostDatasetsByDatasetIdMetadataResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdMetadataBuiltInPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Built-in fields retrieved successfully + */ +export const zGetDatasetsByDatasetIdMetadataBuiltInResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdMetadataBuiltInByActionPath = z.object({ + dataset_id: z.string(), + action: z.string(), +}) + +/** + * Action completed successfully + */ +export const zPostDatasetsByDatasetIdMetadataBuiltInByActionResponse = z.record( + z.string(), + z.unknown(), +) + +export const zDeleteDatasetsByDatasetIdMetadataByMetadataIdPath = z.object({ + dataset_id: z.string(), + metadata_id: z.string(), +}) + +/** + * Metadata deleted successfully + */ +export const zDeleteDatasetsByDatasetIdMetadataByMetadataIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPatchDatasetsByDatasetIdMetadataByMetadataIdBody = zMetadataUpdatePayload + +export const zPatchDatasetsByDatasetIdMetadataByMetadataIdPath = z.object({ + dataset_id: z.string(), + metadata_id: z.string(), +}) + +/** + * Metadata updated successfully + */ +export const zPatchDatasetsByDatasetIdMetadataByMetadataIdResponse = z.record( + z.string(), + z.unknown(), +) + +export const zGetDatasetsByDatasetIdPipelineDatasourcePluginsPath = z.object({ + dataset_id: z.string(), +}) + +export const zGetDatasetsByDatasetIdPipelineDatasourcePluginsQuery = z.object({ + is_published: z.string().optional(), +}) + +/** + * Datasource plugins retrieved successfully + */ +export const zGetDatasetsByDatasetIdPipelineDatasourcePluginsResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunPath = z.object({ + dataset_id: z.string(), + node_id: z.string(), +}) + +/** + * Datasource node run successfully + */ +export const zPostDatasetsByDatasetIdPipelineDatasourceNodesByNodeIdRunResponse = z.record( + z.string(), + z.unknown(), +) + +export const zPostDatasetsByDatasetIdPipelineRunPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Pipeline run successfully + */ +export const zPostDatasetsByDatasetIdPipelineRunResponse = z.record(z.string(), z.unknown()) + +export const zPostDatasetsByDatasetIdRetrieveBody = zHitTestingPayload + +export const zPostDatasetsByDatasetIdRetrievePath = z.object({ + dataset_id: z.string(), +}) + +/** + * Hit testing results + */ +export const zPostDatasetsByDatasetIdRetrieveResponse = z.record(z.string(), z.unknown()) + +export const zGetDatasetsByDatasetIdTagsPath = z.object({ + dataset_id: z.string(), +}) + +/** + * Tags retrieved successfully + */ +export const zGetDatasetsByDatasetIdTagsResponse = z.record(z.string(), z.unknown()) + +export const zGetEndUsersByEndUserIdPath = z.object({ + end_user_id: z.string(), +}) + +/** + * End user retrieved successfully + */ +export const zGetEndUsersByEndUserIdResponse = z.record(z.string(), z.unknown()) + +/** + * File uploaded successfully + */ +export const zPostFilesUploadResponse = zFileResponse + +export const zGetFilesByFileIdPreviewPath = z.object({ + file_id: z.string(), +}) + +export const zGetFilesByFileIdPreviewQuery = z.object({ + as_attachment: z.boolean().optional().default(false), +}) + +/** + * File retrieved successfully + */ +export const zGetFilesByFileIdPreviewResponse = z.record(z.string(), z.unknown()) + +export const zGetFormHumanInputByFormTokenPath = z.object({ + form_token: z.string(), +}) + +/** + * Form retrieved successfully + */ +export const zGetFormHumanInputByFormTokenResponse = z.record(z.string(), z.unknown()) + +export const zPostFormHumanInputByFormTokenBody = zHumanInputFormSubmitPayload + +export const zPostFormHumanInputByFormTokenPath = z.object({ + form_token: z.string(), +}) + +/** + * Form submitted successfully + */ +export const zPostFormHumanInputByFormTokenResponse = z.record(z.string(), z.unknown()) + +/** + * Application info retrieved successfully + */ +export const zGetInfoResponse = z.record(z.string(), z.unknown()) + +export const zGetMessagesQuery = z.object({ + conversation_id: z.string(), + first_id: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), +}) + +/** + * Messages retrieved successfully + */ +export const zGetMessagesResponse = z.record(z.string(), z.unknown()) + +export const zPostMessagesByMessageIdFeedbacksBody = zMessageFeedbackPayload + +export const zPostMessagesByMessageIdFeedbacksPath = z.object({ + message_id: z.string(), +}) + +/** + * Feedback submitted successfully + */ +export const zPostMessagesByMessageIdFeedbacksResponse = z.record(z.string(), z.unknown()) + +export const zGetMessagesByMessageIdSuggestedPath = z.object({ + message_id: z.string(), +}) + +/** + * Suggested questions retrieved successfully + */ +export const zGetMessagesByMessageIdSuggestedResponse = z.record(z.string(), z.unknown()) + +/** + * Metadata retrieved successfully + */ +export const zGetMetaResponse = z.record(z.string(), z.unknown()) + +/** + * Parameters retrieved successfully + */ +export const zGetParametersResponse = z.record(z.string(), z.unknown()) + +/** + * Site configuration retrieved successfully + */ +export const zGetSiteResponse = z.record(z.string(), z.unknown()) + +export const zPostTextToAudioBody = zTextToAudioPayload + +/** + * Text successfully converted to audio + */ +export const zPostTextToAudioResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkflowByTaskIdEventsPath = z.object({ + task_id: z.string(), +}) + +export const zGetWorkflowByTaskIdEventsQuery = z.object({ + user: z.string().optional(), + include_state_snapshot: z.string().optional(), + continue_on_pause: z.string().optional(), +}) + +/** + * SSE event stream + */ +export const zGetWorkflowByTaskIdEventsResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkflowsLogsQuery = z.object({ + created_at__after: z.string().nullish(), + created_at__before: z.string().nullish(), + created_by_account: z.string().nullish(), + created_by_end_user_session_id: z.string().nullish(), + keyword: z.string().nullish(), + limit: z.int().gte(1).lte(100).optional().default(20), + page: z.int().gte(1).lte(99999).optional().default(1), + status: z.enum(['succeeded', 'failed', 'stopped']).nullish(), +}) + +/** + * Logs retrieved successfully + */ +export const zGetWorkflowsLogsResponse = zWorkflowAppLogPaginationResponse + +export const zPostWorkflowsRunBody = zWorkflowRunPayload + +/** + * Workflow executed successfully + */ +export const zPostWorkflowsRunResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkflowsRunByWorkflowRunIdPath = z.object({ + workflow_run_id: z.string(), +}) + +/** + * Workflow run details retrieved successfully + */ +export const zGetWorkflowsRunByWorkflowRunIdResponse = zWorkflowRunResponse + +export const zPostWorkflowsTasksByTaskIdStopPath = z.object({ + task_id: z.string(), +}) + +/** + * Task stopped successfully + */ +export const zPostWorkflowsTasksByTaskIdStopResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkflowsByWorkflowIdRunBody = zWorkflowRunPayload + +export const zPostWorkflowsByWorkflowIdRunPath = z.object({ + workflow_id: z.string(), +}) + +/** + * Workflow executed successfully + */ +export const zPostWorkflowsByWorkflowIdRunResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkspacesCurrentModelsModelTypesByModelTypePath = z.object({ + model_type: z.string(), +}) + +/** + * Models retrieved successfully + */ +export const zGetWorkspacesCurrentModelsModelTypesByModelTypeResponse = z.record( + z.string(), + z.unknown(), +) diff --git a/packages/contracts/generated/api/web/orpc.gen.ts b/packages/contracts/generated/api/web/orpc.gen.ts new file mode 100644 index 0000000000..459d556145 --- /dev/null +++ b/packages/contracts/generated/api/web/orpc.gen.ts @@ -0,0 +1,1085 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zDeleteConversationsByCIdPath, + zDeleteConversationsByCIdResponse, + zDeleteSavedMessagesByMessageIdPath, + zDeleteSavedMessagesByMessageIdResponse, + zGetConversationsQuery, + zGetConversationsResponse, + zGetFormHumanInputByFormTokenPath, + zGetFormHumanInputByFormTokenResponse, + zGetLoginStatusResponse, + zGetMessagesByMessageIdMoreLikeThisPath, + zGetMessagesByMessageIdMoreLikeThisQuery, + zGetMessagesByMessageIdMoreLikeThisResponse, + zGetMessagesByMessageIdSuggestedQuestionsPath, + zGetMessagesByMessageIdSuggestedQuestionsResponse, + zGetMessagesQuery, + zGetMessagesResponse, + zGetMetaResponse, + zGetParametersResponse, + zGetPassportResponse, + zGetRemoteFilesByUrlPath, + zGetRemoteFilesByUrlResponse, + zGetSavedMessagesQuery, + zGetSavedMessagesResponse, + zGetSiteResponse, + zGetSystemFeaturesResponse, + zGetWebappAccessModeQuery, + zGetWebappAccessModeResponse, + zGetWebappPermissionQuery, + zGetWebappPermissionResponse, + zGetWorkflowByTaskIdEventsPath, + zGetWorkflowByTaskIdEventsResponse, + zPatchConversationsByCIdPinPath, + zPatchConversationsByCIdPinResponse, + zPatchConversationsByCIdUnpinPath, + zPatchConversationsByCIdUnpinResponse, + zPostAudioToTextResponse, + zPostChatMessagesBody, + zPostChatMessagesByTaskIdStopPath, + zPostChatMessagesByTaskIdStopResponse, + zPostChatMessagesResponse, + zPostCompletionMessagesBody, + zPostCompletionMessagesByTaskIdStopPath, + zPostCompletionMessagesByTaskIdStopResponse, + zPostCompletionMessagesResponse, + zPostConversationsByCIdNamePath, + zPostConversationsByCIdNameQuery, + zPostConversationsByCIdNameResponse, + zPostEmailCodeLoginBody, + zPostEmailCodeLoginResponse, + zPostEmailCodeLoginValidityBody, + zPostEmailCodeLoginValidityResponse, + zPostFilesUploadResponse, + zPostForgotPasswordBody, + zPostForgotPasswordResetsBody, + zPostForgotPasswordResetsResponse, + zPostForgotPasswordResponse, + zPostForgotPasswordValidityBody, + zPostForgotPasswordValidityResponse, + zPostFormHumanInputByFormTokenPath, + zPostFormHumanInputByFormTokenResponse, + zPostLoginBody, + zPostLoginResponse, + zPostLogoutResponse, + zPostMessagesByMessageIdFeedbacksPath, + zPostMessagesByMessageIdFeedbacksQuery, + zPostMessagesByMessageIdFeedbacksResponse, + zPostRemoteFilesUploadResponse, + zPostSavedMessagesQuery, + zPostSavedMessagesResponse, + zPostTextToAudioBody, + zPostTextToAudioResponse, + zPostWorkflowsRunBody, + zPostWorkflowsRunResponse, + zPostWorkflowsTasksByTaskIdStopPath, + zPostWorkflowsTasksByTaskIdStopResponse, +} from './zod.gen' + +/** + * Convert audio to text + * + * Convert audio file to text using speech-to-text service. + */ +export const post = oc + .route({ + description: 'Convert audio file to text using speech-to-text service.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postAudioToText', + path: '/audio-to-text', + summary: 'Convert audio to text', + tags: ['web'], + }) + .output(zPostAudioToTextResponse) + +export const audioToText = { + post, +} + +/** + * Stop a running chat message task. + */ +export const post2 = oc + .route({ + description: 'Stop a running chat message task.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postChatMessagesByTaskIdStop', + path: '/chat-messages/{task_id}/stop', + tags: ['web'], + }) + .input(z.object({ params: zPostChatMessagesByTaskIdStopPath })) + .output(zPostChatMessagesByTaskIdStopResponse) + +export const stop = { + post: post2, +} + +export const byTaskId = { + stop, +} + +/** + * Create a chat message for conversational applications. + */ +export const post3 = oc + .route({ + description: 'Create a chat message for conversational applications.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postChatMessages', + path: '/chat-messages', + tags: ['web'], + }) + .input(z.object({ body: zPostChatMessagesBody })) + .output(zPostChatMessagesResponse) + +export const chatMessages = { + post: post3, + byTaskId, +} + +/** + * Stop a running completion message task. + */ +export const post4 = oc + .route({ + description: 'Stop a running completion message task.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postCompletionMessagesByTaskIdStop', + path: '/completion-messages/{task_id}/stop', + tags: ['web'], + }) + .input(z.object({ params: zPostCompletionMessagesByTaskIdStopPath })) + .output(zPostCompletionMessagesByTaskIdStopResponse) + +export const stop2 = { + post: post4, +} + +export const byTaskId2 = { + stop: stop2, +} + +/** + * Create a completion message for text generation applications. + */ +export const post5 = oc + .route({ + description: 'Create a completion message for text generation applications.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postCompletionMessages', + path: '/completion-messages', + tags: ['web'], + }) + .input(z.object({ body: zPostCompletionMessagesBody })) + .output(zPostCompletionMessagesResponse) + +export const completionMessages = { + post: post5, + byTaskId: byTaskId2, +} + +/** + * Rename a specific conversation with a custom name or auto-generate one. + */ +export const post6 = oc + .route({ + description: 'Rename a specific conversation with a custom name or auto-generate one.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postConversationsByCIdName', + path: '/conversations/{c_id}/name', + tags: ['web'], + }) + .input( + z.object({ + params: zPostConversationsByCIdNamePath, + query: zPostConversationsByCIdNameQuery.optional(), + }), + ) + .output(zPostConversationsByCIdNameResponse) + +export const name = { + post: post6, +} + +/** + * Pin a specific conversation to keep it at the top of the list. + */ +export const patch = oc + .route({ + description: 'Pin a specific conversation to keep it at the top of the list.', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchConversationsByCIdPin', + path: '/conversations/{c_id}/pin', + tags: ['web'], + }) + .input(z.object({ params: zPatchConversationsByCIdPinPath })) + .output(zPatchConversationsByCIdPinResponse) + +export const pin = { + patch, +} + +/** + * Unpin a specific conversation to remove it from the top of the list. + */ +export const patch2 = oc + .route({ + description: 'Unpin a specific conversation to remove it from the top of the list.', + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'patchConversationsByCIdUnpin', + path: '/conversations/{c_id}/unpin', + tags: ['web'], + }) + .input(z.object({ params: zPatchConversationsByCIdUnpinPath })) + .output(zPatchConversationsByCIdUnpinResponse) + +export const unpin = { + patch: patch2, +} + +/** + * Delete a specific conversation. + */ +export const delete_ = oc + .route({ + description: 'Delete a specific conversation.', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteConversationsByCId', + path: '/conversations/{c_id}', + successStatus: 204, + tags: ['web'], + }) + .input(z.object({ params: zDeleteConversationsByCIdPath })) + .output(zDeleteConversationsByCIdResponse) + +export const byCId = { + delete: delete_, + name, + pin, + unpin, +} + +/** + * Retrieve paginated list of conversations for a chat application. + */ +export const get = oc + .route({ + description: 'Retrieve paginated list of conversations for a chat application.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getConversations', + path: '/conversations', + tags: ['web'], + }) + .input(z.object({ query: zGetConversationsQuery.optional() })) + .output(zGetConversationsResponse) + +export const conversations = { + get, + byCId, +} + +/** + * Verify email code and complete login + */ +export const post7 = oc + .route({ + description: 'Verify email code and complete login', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postEmailCodeLoginValidity', + path: '/email-code-login/validity', + tags: ['web'], + }) + .input(z.object({ body: zPostEmailCodeLoginValidityBody })) + .output(zPostEmailCodeLoginValidityResponse) + +export const validity = { + post: post7, +} + +/** + * Send email verification code for login + */ +export const post8 = oc + .route({ + description: 'Send email verification code for login', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postEmailCodeLogin', + path: '/email-code-login', + tags: ['web'], + }) + .input(z.object({ body: zPostEmailCodeLoginBody })) + .output(zPostEmailCodeLoginResponse) + +export const emailCodeLogin = { + post: post8, + validity, +} + +/** + * Upload a file for use in web applications + * + * Upload a file for use in web applications + * Accepts file uploads for use within web applications, supporting + * multiple file types with automatic validation and storage. + * + * Args: + * app_model: The associated application model + * end_user: The end user uploading the file + * + * Form Parameters: + * file: The file to upload (required) + * source: Optional source type (datasets or None) + * + * Returns: + * dict: File information including ID, URL, and metadata + * int: HTTP status code 201 for success + * + * Raises: + * NoFileUploadedError: No file provided in request + * TooManyFilesError: Multiple files provided (only one allowed) + * FilenameNotExistsError: File has no filename + * FileTooLargeError: File exceeds size limit + * UnsupportedFileTypeError: File type not supported + */ +export const post9 = oc + .route({ + description: + 'Upload a file for use in web applications\nAccepts file uploads for use within web applications, supporting\nmultiple file types with automatic validation and storage.\n\nArgs:\n app_model: The associated application model\n end_user: The end user uploading the file\n\nForm Parameters:\n file: The file to upload (required)\n source: Optional source type (datasets or None)\n\nReturns:\n dict: File information including ID, URL, and metadata\n int: HTTP status code 201 for success\n\nRaises:\n NoFileUploadedError: No file provided in request\n TooManyFilesError: Multiple files provided (only one allowed)\n FilenameNotExistsError: File has no filename\n FileTooLargeError: File exceeds size limit\n UnsupportedFileTypeError: File type not supported', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postFilesUpload', + path: '/files/upload', + successStatus: 201, + summary: 'Upload a file for use in web applications', + tags: ['web'], + }) + .output(zPostFilesUploadResponse) + +export const upload = { + post: post9, +} + +export const files = { + upload, +} + +/** + * Reset user password with verification token + */ +export const post10 = oc + .route({ + description: 'Reset user password with verification token', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postForgotPasswordResets', + path: '/forgot-password/resets', + tags: ['web'], + }) + .input(z.object({ body: zPostForgotPasswordResetsBody })) + .output(zPostForgotPasswordResetsResponse) + +export const resets = { + post: post10, +} + +/** + * Verify password reset token validity + */ +export const post11 = oc + .route({ + description: 'Verify password reset token validity', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postForgotPasswordValidity', + path: '/forgot-password/validity', + tags: ['web'], + }) + .input(z.object({ body: zPostForgotPasswordValidityBody })) + .output(zPostForgotPasswordValidityResponse) + +export const validity2 = { + post: post11, +} + +/** + * Send password reset email + */ +export const post12 = oc + .route({ + description: 'Send password reset email', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postForgotPassword', + path: '/forgot-password', + tags: ['web'], + }) + .input(z.object({ body: zPostForgotPasswordBody })) + .output(zPostForgotPasswordResponse) + +export const forgotPassword = { + post: post12, + resets, + validity: validity2, +} + +/** + * Get human input form definition by token + * + * GET /api/form/human_input/ + */ +export const get2 = oc + .route({ + description: 'GET /api/form/human_input/', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getFormHumanInputByFormToken', + path: '/form/human_input/{form_token}', + summary: 'Get human input form definition by token', + tags: ['web'], + }) + .input(z.object({ params: zGetFormHumanInputByFormTokenPath })) + .output(zGetFormHumanInputByFormTokenResponse) + +/** + * Submit human input form by token + * + * POST /api/form/human_input/ + * + * Request body: + * { + * "inputs": { + * "content": "User input content" + * }, + * "action": "Approve" + * } + */ +export const post13 = oc + .route({ + description: + 'POST /api/form/human_input/\n\nRequest body:\n{\n "inputs": {\n "content": "User input content"\n },\n "action": "Approve"\n}', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postFormHumanInputByFormToken', + path: '/form/human_input/{form_token}', + summary: 'Submit human input form by token', + tags: ['web'], + }) + .input(z.object({ params: zPostFormHumanInputByFormTokenPath })) + .output(zPostFormHumanInputByFormTokenResponse) + +export const byFormToken = { + get: get2, + post: post13, +} + +export const humanInput = { + byFormToken, +} + +export const form = { + humanInput, +} + +/** + * Check login status + */ +export const get3 = oc + .route({ + description: 'Check login status', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getLoginStatus', + path: '/login/status', + tags: ['web'], + }) + .output(zGetLoginStatusResponse) + +export const status = { + get: get3, +} + +/** + * Authenticate user and login + * + * Authenticate user for web application access + */ +export const post14 = oc + .route({ + description: 'Authenticate user for web application access', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postLogin', + path: '/login', + summary: 'Authenticate user and login', + tags: ['web'], + }) + .input(z.object({ body: zPostLoginBody })) + .output(zPostLoginResponse) + +export const login = { + post: post14, + status, +} + +/** + * Logout user from web application + */ +export const post15 = oc + .route({ + description: 'Logout user from web application', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postLogout', + path: '/logout', + tags: ['web'], + }) + .output(zPostLogoutResponse) + +export const logout = { + post: post15, +} + +/** + * Submit feedback (like/dislike) for a specific message. + */ +export const post16 = oc + .route({ + description: 'Submit feedback (like/dislike) for a specific message.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postMessagesByMessageIdFeedbacks', + path: '/messages/{message_id}/feedbacks', + tags: ['web'], + }) + .input( + z.object({ + params: zPostMessagesByMessageIdFeedbacksPath, + query: zPostMessagesByMessageIdFeedbacksQuery.optional(), + }), + ) + .output(zPostMessagesByMessageIdFeedbacksResponse) + +export const feedbacks = { + post: post16, +} + +/** + * Generate a new completion similar to an existing message (completion apps only). + */ +export const get4 = oc + .route({ + description: 'Generate a new completion similar to an existing message (completion apps only).', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getMessagesByMessageIdMoreLikeThis', + path: '/messages/{message_id}/more-like-this', + tags: ['web'], + }) + .input( + z.object({ + params: zGetMessagesByMessageIdMoreLikeThisPath, + query: zGetMessagesByMessageIdMoreLikeThisQuery, + }), + ) + .output(zGetMessagesByMessageIdMoreLikeThisResponse) + +export const moreLikeThis = { + get: get4, +} + +/** + * Get suggested follow-up questions after a message (chat apps only). + */ +export const get5 = oc + .route({ + description: 'Get suggested follow-up questions after a message (chat apps only).', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getMessagesByMessageIdSuggestedQuestions', + path: '/messages/{message_id}/suggested-questions', + tags: ['web'], + }) + .input(z.object({ params: zGetMessagesByMessageIdSuggestedQuestionsPath })) + .output(zGetMessagesByMessageIdSuggestedQuestionsResponse) + +export const suggestedQuestions = { + get: get5, +} + +export const byMessageId = { + feedbacks, + moreLikeThis, + suggestedQuestions, +} + +/** + * Retrieve paginated list of messages from a conversation in a chat application. + */ +export const get6 = oc + .route({ + description: 'Retrieve paginated list of messages from a conversation in a chat application.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getMessages', + path: '/messages', + tags: ['web'], + }) + .input(z.object({ query: zGetMessagesQuery })) + .output(zGetMessagesResponse) + +export const messages = { + get: get6, + byMessageId, +} + +/** + * Get app meta + * + * Retrieve the metadata for a specific app. + */ +export const get7 = oc + .route({ + description: 'Retrieve the metadata for a specific app.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getMeta', + path: '/meta', + summary: 'Get app meta', + tags: ['web'], + }) + .output(zGetMetaResponse) + +export const meta = { + get: get7, +} + +/** + * Retrieve app parameters + * + * Retrieve the parameters for a specific app. + */ +export const get8 = oc + .route({ + description: 'Retrieve the parameters for a specific app.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getParameters', + path: '/parameters', + summary: 'Retrieve app parameters', + tags: ['web'], + }) + .output(zGetParametersResponse) + +export const parameters = { + get: get8, +} + +/** + * Get authentication passport for web application access + */ +export const get9 = oc + .route({ + description: 'Get authentication passport for web application access', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getPassport', + path: '/passport', + tags: ['web'], + }) + .output(zGetPassportResponse) + +export const passport = { + get: get9, +} + +/** + * Upload a file from a remote URL + * + * Upload a file from a remote URL + * Downloads a file from the provided remote URL and uploads it + * to the platform storage for use in web applications. + * + * Args: + * app_model: The associated application model + * end_user: The end user making the request + * + * JSON Parameters: + * url: The remote URL to download the file from (required) + * + * Returns: + * dict: File information including ID, signed URL, and metadata + * int: HTTP status code 201 for success + * + * Raises: + * RemoteFileUploadError: Failed to fetch file from remote URL + * FileTooLargeError: File exceeds size limit + * UnsupportedFileTypeError: File type not supported + */ +export const post17 = oc + .route({ + description: + 'Upload a file from a remote URL\nDownloads a file from the provided remote URL and uploads it\nto the platform storage for use in web applications.\n\nArgs:\n app_model: The associated application model\n end_user: The end user making the request\n\nJSON Parameters:\n url: The remote URL to download the file from (required)\n\nReturns:\n dict: File information including ID, signed URL, and metadata\n int: HTTP status code 201 for success\n\nRaises:\n RemoteFileUploadError: Failed to fetch file from remote URL\n FileTooLargeError: File exceeds size limit\n UnsupportedFileTypeError: File type not supported', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postRemoteFilesUpload', + path: '/remote-files/upload', + successStatus: 201, + summary: 'Upload a file from a remote URL', + tags: ['web'], + }) + .output(zPostRemoteFilesUploadResponse) + +export const upload2 = { + post: post17, +} + +/** + * Get information about a remote file + * + * Get information about a remote file + * Retrieves basic information about a file located at a remote URL, + * including content type and content length. + * + * Args: + * app_model: The associated application model + * end_user: The end user making the request + * url: URL-encoded path to the remote file + * + * Returns: + * dict: Remote file information including type and length + * + * Raises: + * HTTPException: If the remote file cannot be accessed + */ +export const get10 = oc + .route({ + description: + 'Get information about a remote file\nRetrieves basic information about a file located at a remote URL,\nincluding content type and content length.\n\nArgs:\n app_model: The associated application model\n end_user: The end user making the request\n url: URL-encoded path to the remote file\n\nReturns:\n dict: Remote file information including type and length\n\nRaises:\n HTTPException: If the remote file cannot be accessed', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getRemoteFilesByUrl', + path: '/remote-files/{url}', + summary: 'Get information about a remote file', + tags: ['web'], + }) + .input(z.object({ params: zGetRemoteFilesByUrlPath })) + .output(zGetRemoteFilesByUrlResponse) + +export const byUrl = { + get: get10, +} + +export const remoteFiles = { + upload: upload2, + byUrl, +} + +/** + * Remove a message from saved messages. + */ +export const delete2 = oc + .route({ + description: 'Remove a message from saved messages.', + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'deleteSavedMessagesByMessageId', + path: '/saved-messages/{message_id}', + successStatus: 204, + tags: ['web'], + }) + .input(z.object({ params: zDeleteSavedMessagesByMessageIdPath })) + .output(zDeleteSavedMessagesByMessageIdResponse) + +export const byMessageId2 = { + delete: delete2, +} + +/** + * Retrieve paginated list of saved messages for a completion application. + */ +export const get11 = oc + .route({ + description: 'Retrieve paginated list of saved messages for a completion application.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getSavedMessages', + path: '/saved-messages', + tags: ['web'], + }) + .input(z.object({ query: zGetSavedMessagesQuery.optional() })) + .output(zGetSavedMessagesResponse) + +/** + * Save a specific message for later reference. + */ +export const post18 = oc + .route({ + description: 'Save a specific message for later reference.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postSavedMessages', + path: '/saved-messages', + tags: ['web'], + }) + .input(z.object({ query: zPostSavedMessagesQuery })) + .output(zPostSavedMessagesResponse) + +export const savedMessages = { + get: get11, + post: post18, + byMessageId: byMessageId2, +} + +/** + * Retrieve app site info + * + * Retrieve app site information and configuration. + */ +export const get12 = oc + .route({ + description: 'Retrieve app site information and configuration.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getSite', + path: '/site', + summary: 'Retrieve app site info', + tags: ['web'], + }) + .output(zGetSiteResponse) + +export const site = { + get: get12, +} + +/** + * Get system feature flags and configuration + * + * Get system feature flags and configuration + * Returns the current system feature flags and configuration + * that control various functionalities across the platform. + * + * Returns: + * dict: System feature configuration object + * + * This endpoint is akin to the `SystemFeatureApi` endpoint in api/controllers/console/feature.py, + * except it is intended for use by the web app, instead of the console dashboard. + * + * NOTE: This endpoint is unauthenticated by design, as it provides system features + * data required for webapp initialization. + * + * Authentication would create circular dependency (can't authenticate without webapp loading). + * + * Only non-sensitive configuration data should be returned by this endpoint. + */ +export const get13 = oc + .route({ + description: + 'Get system feature flags and configuration\nReturns the current system feature flags and configuration\nthat control various functionalities across the platform.\n\nReturns:\n dict: System feature configuration object\n\nThis endpoint is akin to the `SystemFeatureApi` endpoint in api/controllers/console/feature.py,\nexcept it is intended for use by the web app, instead of the console dashboard.\n\nNOTE: This endpoint is unauthenticated by design, as it provides system features\ndata required for webapp initialization.\n\nAuthentication would create circular dependency (can\'t authenticate without webapp loading).\n\nOnly non-sensitive configuration data should be returned by this endpoint.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getSystemFeatures', + path: '/system-features', + summary: 'Get system feature flags and configuration', + tags: ['web'], + }) + .output(zGetSystemFeaturesResponse) + +export const systemFeatures = { + get: get13, +} + +/** + * Convert text to audio + * + * Convert text to audio using text-to-speech service. + */ +export const post19 = oc + .route({ + description: 'Convert text to audio using text-to-speech service.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postTextToAudio', + path: '/text-to-audio', + summary: 'Convert text to audio', + tags: ['web'], + }) + .input(z.object({ body: zPostTextToAudioBody })) + .output(zPostTextToAudioResponse) + +export const textToAudio = { + post: post19, +} + +/** + * Retrieve the access mode for a web application (public or restricted). + */ +export const get14 = oc + .route({ + description: 'Retrieve the access mode for a web application (public or restricted).', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWebappAccessMode', + path: '/webapp/access-mode', + tags: ['web'], + }) + .input(z.object({ query: zGetWebappAccessModeQuery.optional() })) + .output(zGetWebappAccessModeResponse) + +export const accessMode = { + get: get14, +} + +/** + * Check if user has permission to access a web application. + */ +export const get15 = oc + .route({ + description: 'Check if user has permission to access a web application.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWebappPermission', + path: '/webapp/permission', + tags: ['web'], + }) + .input(z.object({ query: zGetWebappPermissionQuery })) + .output(zGetWebappPermissionResponse) + +export const permission = { + get: get15, +} + +export const webapp = { + accessMode, + permission, +} + +/** + * Get workflow execution events stream after resume + * + * GET /api/workflow//events + * + * Returns Server-Sent Events stream. + */ +export const get16 = oc + .route({ + description: 'GET /api/workflow//events\n\nReturns Server-Sent Events stream.', + inputStructure: 'detailed', + method: 'GET', + operationId: 'getWorkflowByTaskIdEvents', + path: '/workflow/{task_id}/events', + summary: 'Get workflow execution events stream after resume', + tags: ['default'], + }) + .input(z.object({ params: zGetWorkflowByTaskIdEventsPath })) + .output(zGetWorkflowByTaskIdEventsResponse) + +export const events = { + get: get16, +} + +export const byTaskId3 = { + events, +} + +export const workflow = { + byTaskId: byTaskId3, +} + +/** + * Run workflow + * + * Execute a workflow with provided inputs and files. + */ +export const post20 = oc + .route({ + description: 'Execute a workflow with provided inputs and files.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkflowsRun', + path: '/workflows/run', + summary: 'Run workflow', + tags: ['web'], + }) + .input(z.object({ body: zPostWorkflowsRunBody })) + .output(zPostWorkflowsRunResponse) + +export const run = { + post: post20, +} + +/** + * Stop workflow task + * + * Stop a running workflow task. + */ +export const post21 = oc + .route({ + description: 'Stop a running workflow task.', + inputStructure: 'detailed', + method: 'POST', + operationId: 'postWorkflowsTasksByTaskIdStop', + path: '/workflows/tasks/{task_id}/stop', + summary: 'Stop workflow task', + tags: ['web'], + }) + .input(z.object({ params: zPostWorkflowsTasksByTaskIdStopPath })) + .output(zPostWorkflowsTasksByTaskIdStopResponse) + +export const stop3 = { + post: post21, +} + +export const byTaskId4 = { + stop: stop3, +} + +export const tasks = { + byTaskId: byTaskId4, +} + +export const workflows = { + run, + tasks, +} + +export const contract = { + audioToText, + chatMessages, + completionMessages, + conversations, + emailCodeLogin, + files, + forgotPassword, + form, + login, + logout, + messages, + meta, + parameters, + passport, + remoteFiles, + savedMessages, + site, + systemFeatures, + textToAudio, + webapp, + workflow, + workflows, +} diff --git a/packages/contracts/generated/api/web/types.gen.ts b/packages/contracts/generated/api/web/types.gen.ts new file mode 100644 index 0000000000..f2009b966b --- /dev/null +++ b/packages/contracts/generated/api/web/types.gen.ts @@ -0,0 +1,1461 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}/api` | (string & {}) +} + +export type ChatMessagePayload = { + conversation_id?: string | null + files?: Array<{ + [key: string]: unknown + }> | null + inputs: { + [key: string]: unknown + } + parent_message_id?: string | null + query: string + response_mode?: 'blocking' | 'streaming' | null + retriever_from?: string +} + +export type CompletionMessagePayload = { + files?: Array<{ + [key: string]: unknown + }> | null + inputs: { + [key: string]: unknown + } + query?: string + response_mode?: 'blocking' | 'streaming' | null + retriever_from?: string +} + +export type EmailCodeLoginSendPayload = { + email: string + language?: string | null +} + +export type EmailCodeLoginVerifyPayload = { + code: string + email: string + token: string +} + +export type FileResponse = { + conversation_id?: string | null + created_at?: number | null + created_by?: string | null + extension?: string | null + file_key?: string | null + id: string + mime_type?: string | null + name: string + original_url?: string | null + preview_url?: string | null + size: number + source_url?: string | null + tenant_id?: string | null + user_id?: string | null +} + +export type FileWithSignedUrl = { + created_at?: number | null + created_by?: string | null + extension?: string | null + id: string + mime_type?: string | null + name: string + size: number + url?: string | null +} + +export type ForgotPasswordCheckPayload = { + code: string + email: string + token: string +} + +export type ForgotPasswordResetPayload = { + new_password: string + password_confirm: string + token: string +} + +export type ForgotPasswordSendPayload = { + email: string + language?: string | null +} + +export type LoginPayload = { + email: string + password: string +} + +export type MessageMoreLikeThisQuery = { + response_mode: 'blocking' | 'streaming' +} + +export type RemoteFileInfo = { + file_length: number + file_type: string +} + +export type TextToAudioPayload = { + message_id?: string | null + streaming?: boolean | null + text?: string | null + voice?: string | null +} + +export type WorkflowRunPayload = { + files?: Array<{ + [key: string]: unknown + }> | null + inputs: { + [key: string]: unknown + } +} + +export type PostAudioToTextData = { + body?: never + path?: never + query?: never + url: '/audio-to-text' +} + +export type PostAudioToTextErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 413: { + [key: string]: unknown + } + 415: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostAudioToTextError = PostAudioToTextErrors[keyof PostAudioToTextErrors] + +export type PostAudioToTextResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostAudioToTextResponse = PostAudioToTextResponses[keyof PostAudioToTextResponses] + +export type PostChatMessagesData = { + body: ChatMessagePayload + path?: never + query?: never + url: '/chat-messages' +} + +export type PostChatMessagesErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostChatMessagesError = PostChatMessagesErrors[keyof PostChatMessagesErrors] + +export type PostChatMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostChatMessagesResponse = PostChatMessagesResponses[keyof PostChatMessagesResponses] + +export type PostChatMessagesByTaskIdStopData = { + body?: never + path: { + task_id: string + } + query?: never + url: '/chat-messages/{task_id}/stop' +} + +export type PostChatMessagesByTaskIdStopErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostChatMessagesByTaskIdStopError + = PostChatMessagesByTaskIdStopErrors[keyof PostChatMessagesByTaskIdStopErrors] + +export type PostChatMessagesByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostChatMessagesByTaskIdStopResponse + = PostChatMessagesByTaskIdStopResponses[keyof PostChatMessagesByTaskIdStopResponses] + +export type PostCompletionMessagesData = { + body: CompletionMessagePayload + path?: never + query?: never + url: '/completion-messages' +} + +export type PostCompletionMessagesErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostCompletionMessagesError + = PostCompletionMessagesErrors[keyof PostCompletionMessagesErrors] + +export type PostCompletionMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostCompletionMessagesResponse + = PostCompletionMessagesResponses[keyof PostCompletionMessagesResponses] + +export type PostCompletionMessagesByTaskIdStopData = { + body?: never + path: { + task_id: string + } + query?: never + url: '/completion-messages/{task_id}/stop' +} + +export type PostCompletionMessagesByTaskIdStopErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostCompletionMessagesByTaskIdStopError + = PostCompletionMessagesByTaskIdStopErrors[keyof PostCompletionMessagesByTaskIdStopErrors] + +export type PostCompletionMessagesByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostCompletionMessagesByTaskIdStopResponse + = PostCompletionMessagesByTaskIdStopResponses[keyof PostCompletionMessagesByTaskIdStopResponses] + +export type GetConversationsData = { + body?: never + path?: never + query?: { + last_id?: string + limit?: number + pinned?: 'true' | 'false' + sort_by?: 'created_at' | '-created_at' | 'updated_at' | '-updated_at' + } + url: '/conversations' +} + +export type GetConversationsErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetConversationsError = GetConversationsErrors[keyof GetConversationsErrors] + +export type GetConversationsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetConversationsResponse = GetConversationsResponses[keyof GetConversationsResponses] + +export type DeleteConversationsByCIdData = { + body?: never + path: { + c_id: string + } + query?: never + url: '/conversations/{c_id}' +} + +export type DeleteConversationsByCIdErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type DeleteConversationsByCIdError + = DeleteConversationsByCIdErrors[keyof DeleteConversationsByCIdErrors] + +export type DeleteConversationsByCIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteConversationsByCIdResponse + = DeleteConversationsByCIdResponses[keyof DeleteConversationsByCIdResponses] + +export type PostConversationsByCIdNameData = { + body?: never + path: { + c_id: string + } + query?: { + name?: string + auto_generate?: boolean + } + url: '/conversations/{c_id}/name' +} + +export type PostConversationsByCIdNameErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostConversationsByCIdNameError + = PostConversationsByCIdNameErrors[keyof PostConversationsByCIdNameErrors] + +export type PostConversationsByCIdNameResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostConversationsByCIdNameResponse + = PostConversationsByCIdNameResponses[keyof PostConversationsByCIdNameResponses] + +export type PatchConversationsByCIdPinData = { + body?: never + path: { + c_id: string + } + query?: never + url: '/conversations/{c_id}/pin' +} + +export type PatchConversationsByCIdPinErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PatchConversationsByCIdPinError + = PatchConversationsByCIdPinErrors[keyof PatchConversationsByCIdPinErrors] + +export type PatchConversationsByCIdPinResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchConversationsByCIdPinResponse + = PatchConversationsByCIdPinResponses[keyof PatchConversationsByCIdPinResponses] + +export type PatchConversationsByCIdUnpinData = { + body?: never + path: { + c_id: string + } + query?: never + url: '/conversations/{c_id}/unpin' +} + +export type PatchConversationsByCIdUnpinErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PatchConversationsByCIdUnpinError + = PatchConversationsByCIdUnpinErrors[keyof PatchConversationsByCIdUnpinErrors] + +export type PatchConversationsByCIdUnpinResponses = { + 200: { + [key: string]: unknown + } +} + +export type PatchConversationsByCIdUnpinResponse + = PatchConversationsByCIdUnpinResponses[keyof PatchConversationsByCIdUnpinResponses] + +export type PostEmailCodeLoginData = { + body: EmailCodeLoginSendPayload + path?: never + query?: never + url: '/email-code-login' +} + +export type PostEmailCodeLoginErrors = { + 400: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostEmailCodeLoginError = PostEmailCodeLoginErrors[keyof PostEmailCodeLoginErrors] + +export type PostEmailCodeLoginResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostEmailCodeLoginResponse + = PostEmailCodeLoginResponses[keyof PostEmailCodeLoginResponses] + +export type PostEmailCodeLoginValidityData = { + body: EmailCodeLoginVerifyPayload + path?: never + query?: never + url: '/email-code-login/validity' +} + +export type PostEmailCodeLoginValidityErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostEmailCodeLoginValidityError + = PostEmailCodeLoginValidityErrors[keyof PostEmailCodeLoginValidityErrors] + +export type PostEmailCodeLoginValidityResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostEmailCodeLoginValidityResponse + = PostEmailCodeLoginValidityResponses[keyof PostEmailCodeLoginValidityResponses] + +export type PostFilesUploadData = { + body?: never + path?: never + query?: never + url: '/files/upload' +} + +export type PostFilesUploadErrors = { + 400: { + [key: string]: unknown + } + 413: { + [key: string]: unknown + } + 415: { + [key: string]: unknown + } +} + +export type PostFilesUploadError = PostFilesUploadErrors[keyof PostFilesUploadErrors] + +export type PostFilesUploadResponses = { + 201: FileResponse +} + +export type PostFilesUploadResponse = PostFilesUploadResponses[keyof PostFilesUploadResponses] + +export type PostForgotPasswordData = { + body: ForgotPasswordSendPayload + path?: never + query?: never + url: '/forgot-password' +} + +export type PostForgotPasswordErrors = { + 400: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 429: { + [key: string]: unknown + } +} + +export type PostForgotPasswordError = PostForgotPasswordErrors[keyof PostForgotPasswordErrors] + +export type PostForgotPasswordResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostForgotPasswordResponse + = PostForgotPasswordResponses[keyof PostForgotPasswordResponses] + +export type PostForgotPasswordResetsData = { + body: ForgotPasswordResetPayload + path?: never + query?: never + url: '/forgot-password/resets' +} + +export type PostForgotPasswordResetsErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostForgotPasswordResetsError + = PostForgotPasswordResetsErrors[keyof PostForgotPasswordResetsErrors] + +export type PostForgotPasswordResetsResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostForgotPasswordResetsResponse + = PostForgotPasswordResetsResponses[keyof PostForgotPasswordResetsResponses] + +export type PostForgotPasswordValidityData = { + body: ForgotPasswordCheckPayload + path?: never + query?: never + url: '/forgot-password/validity' +} + +export type PostForgotPasswordValidityErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } +} + +export type PostForgotPasswordValidityError + = PostForgotPasswordValidityErrors[keyof PostForgotPasswordValidityErrors] + +export type PostForgotPasswordValidityResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostForgotPasswordValidityResponse + = PostForgotPasswordValidityResponses[keyof PostForgotPasswordValidityResponses] + +export type GetFormHumanInputByFormTokenData = { + body?: never + path: { + form_token: string + } + query?: never + url: '/form/human_input/{form_token}' +} + +export type GetFormHumanInputByFormTokenResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetFormHumanInputByFormTokenResponse + = GetFormHumanInputByFormTokenResponses[keyof GetFormHumanInputByFormTokenResponses] + +export type PostFormHumanInputByFormTokenData = { + body?: never + path: { + form_token: string + } + query?: never + url: '/form/human_input/{form_token}' +} + +export type PostFormHumanInputByFormTokenResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostFormHumanInputByFormTokenResponse + = PostFormHumanInputByFormTokenResponses[keyof PostFormHumanInputByFormTokenResponses] + +export type PostLoginData = { + body: LoginPayload + path?: never + query?: never + url: '/login' +} + +export type PostLoginErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type PostLoginError = PostLoginErrors[keyof PostLoginErrors] + +export type PostLoginResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostLoginResponse = PostLoginResponses[keyof PostLoginResponses] + +export type GetLoginStatusData = { + body?: never + path?: never + query?: never + url: '/login/status' +} + +export type GetLoginStatusErrors = { + 401: { + [key: string]: unknown + } +} + +export type GetLoginStatusError = GetLoginStatusErrors[keyof GetLoginStatusErrors] + +export type GetLoginStatusResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetLoginStatusResponse = GetLoginStatusResponses[keyof GetLoginStatusResponses] + +export type PostLogoutData = { + body?: never + path?: never + query?: never + url: '/logout' +} + +export type PostLogoutResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostLogoutResponse = PostLogoutResponses[keyof PostLogoutResponses] + +export type GetMessagesData = { + body?: never + path?: never + query: { + conversation_id: string + first_id?: string + limit?: number + } + url: '/messages' +} + +export type GetMessagesErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetMessagesError = GetMessagesErrors[keyof GetMessagesErrors] + +export type GetMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetMessagesResponse = GetMessagesResponses[keyof GetMessagesResponses] + +export type PostMessagesByMessageIdFeedbacksData = { + body?: never + path: { + message_id: string + } + query?: { + rating?: 'like' | 'dislike' + content?: string + } + url: '/messages/{message_id}/feedbacks' +} + +export type PostMessagesByMessageIdFeedbacksErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostMessagesByMessageIdFeedbacksError + = PostMessagesByMessageIdFeedbacksErrors[keyof PostMessagesByMessageIdFeedbacksErrors] + +export type PostMessagesByMessageIdFeedbacksResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostMessagesByMessageIdFeedbacksResponse + = PostMessagesByMessageIdFeedbacksResponses[keyof PostMessagesByMessageIdFeedbacksResponses] + +export type GetMessagesByMessageIdMoreLikeThisData = { + body?: never + path: { + message_id: string + } + query: { + response_mode: 'blocking' | 'streaming' + } + url: '/messages/{message_id}/more-like-this' +} + +export type GetMessagesByMessageIdMoreLikeThisErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetMessagesByMessageIdMoreLikeThisError + = GetMessagesByMessageIdMoreLikeThisErrors[keyof GetMessagesByMessageIdMoreLikeThisErrors] + +export type GetMessagesByMessageIdMoreLikeThisResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetMessagesByMessageIdMoreLikeThisResponse + = GetMessagesByMessageIdMoreLikeThisResponses[keyof GetMessagesByMessageIdMoreLikeThisResponses] + +export type GetMessagesByMessageIdSuggestedQuestionsData = { + body?: never + path: { + message_id: string + } + query?: never + url: '/messages/{message_id}/suggested-questions' +} + +export type GetMessagesByMessageIdSuggestedQuestionsErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetMessagesByMessageIdSuggestedQuestionsError + = GetMessagesByMessageIdSuggestedQuestionsErrors[keyof GetMessagesByMessageIdSuggestedQuestionsErrors] + +export type GetMessagesByMessageIdSuggestedQuestionsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetMessagesByMessageIdSuggestedQuestionsResponse + = GetMessagesByMessageIdSuggestedQuestionsResponses[keyof GetMessagesByMessageIdSuggestedQuestionsResponses] + +export type GetMetaData = { + body?: never + path?: never + query?: never + url: '/meta' +} + +export type GetMetaErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetMetaError = GetMetaErrors[keyof GetMetaErrors] + +export type GetMetaResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetMetaResponse = GetMetaResponses[keyof GetMetaResponses] + +export type GetParametersData = { + body?: never + path?: never + query?: never + url: '/parameters' +} + +export type GetParametersErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetParametersError = GetParametersErrors[keyof GetParametersErrors] + +export type GetParametersResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetParametersResponse = GetParametersResponses[keyof GetParametersResponses] + +export type GetPassportData = { + body?: never + path?: never + query?: never + url: '/passport' +} + +export type GetPassportErrors = { + 401: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } +} + +export type GetPassportError = GetPassportErrors[keyof GetPassportErrors] + +export type GetPassportResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetPassportResponse = GetPassportResponses[keyof GetPassportResponses] + +export type PostRemoteFilesUploadData = { + body?: never + path?: never + query?: never + url: '/remote-files/upload' +} + +export type PostRemoteFilesUploadErrors = { + 400: { + [key: string]: unknown + } + 413: { + [key: string]: unknown + } + 415: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostRemoteFilesUploadError + = PostRemoteFilesUploadErrors[keyof PostRemoteFilesUploadErrors] + +export type PostRemoteFilesUploadResponses = { + 201: FileWithSignedUrl +} + +export type PostRemoteFilesUploadResponse + = PostRemoteFilesUploadResponses[keyof PostRemoteFilesUploadResponses] + +export type GetRemoteFilesByUrlData = { + body?: never + path: { + url: string + } + query?: never + url: '/remote-files/{url}' +} + +export type GetRemoteFilesByUrlErrors = { + 400: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetRemoteFilesByUrlError = GetRemoteFilesByUrlErrors[keyof GetRemoteFilesByUrlErrors] + +export type GetRemoteFilesByUrlResponses = { + 200: RemoteFileInfo +} + +export type GetRemoteFilesByUrlResponse + = GetRemoteFilesByUrlResponses[keyof GetRemoteFilesByUrlResponses] + +export type GetSavedMessagesData = { + body?: never + path?: never + query?: { + last_id?: string + limit?: number + } + url: '/saved-messages' +} + +export type GetSavedMessagesErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetSavedMessagesError = GetSavedMessagesErrors[keyof GetSavedMessagesErrors] + +export type GetSavedMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetSavedMessagesResponse = GetSavedMessagesResponses[keyof GetSavedMessagesResponses] + +export type PostSavedMessagesData = { + body?: never + path?: never + query: { + message_id: string + } + url: '/saved-messages' +} + +export type PostSavedMessagesErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostSavedMessagesError = PostSavedMessagesErrors[keyof PostSavedMessagesErrors] + +export type PostSavedMessagesResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostSavedMessagesResponse = PostSavedMessagesResponses[keyof PostSavedMessagesResponses] + +export type DeleteSavedMessagesByMessageIdData = { + body?: never + path: { + message_id: string + } + query?: never + url: '/saved-messages/{message_id}' +} + +export type DeleteSavedMessagesByMessageIdErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type DeleteSavedMessagesByMessageIdError + = DeleteSavedMessagesByMessageIdErrors[keyof DeleteSavedMessagesByMessageIdErrors] + +export type DeleteSavedMessagesByMessageIdResponses = { + 204: { + [key: string]: unknown + } +} + +export type DeleteSavedMessagesByMessageIdResponse + = DeleteSavedMessagesByMessageIdResponses[keyof DeleteSavedMessagesByMessageIdResponses] + +export type GetSiteData = { + body?: never + path?: never + query?: never + url: '/site' +} + +export type GetSiteErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetSiteError = GetSiteErrors[keyof GetSiteErrors] + +export type GetSiteResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetSiteResponse = GetSiteResponses[keyof GetSiteResponses] + +export type GetSystemFeaturesData = { + body?: never + path?: never + query?: never + url: '/system-features' +} + +export type GetSystemFeaturesErrors = { + 500: { + [key: string]: unknown + } +} + +export type GetSystemFeaturesError = GetSystemFeaturesErrors[keyof GetSystemFeaturesErrors] + +export type GetSystemFeaturesResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetSystemFeaturesResponse = GetSystemFeaturesResponses[keyof GetSystemFeaturesResponses] + +export type PostTextToAudioData = { + body: TextToAudioPayload + path?: never + query?: never + url: '/text-to-audio' +} + +export type PostTextToAudioErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostTextToAudioError = PostTextToAudioErrors[keyof PostTextToAudioErrors] + +export type PostTextToAudioResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostTextToAudioResponse = PostTextToAudioResponses[keyof PostTextToAudioResponses] + +export type GetWebappAccessModeData = { + body?: never + path?: never + query?: { + appId?: string + appCode?: string + } + url: '/webapp/access-mode' +} + +export type GetWebappAccessModeErrors = { + 400: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetWebappAccessModeError = GetWebappAccessModeErrors[keyof GetWebappAccessModeErrors] + +export type GetWebappAccessModeResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWebappAccessModeResponse + = GetWebappAccessModeResponses[keyof GetWebappAccessModeResponses] + +export type GetWebappPermissionData = { + body?: never + path?: never + query: { + appId: string + } + url: '/webapp/permission' +} + +export type GetWebappPermissionErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type GetWebappPermissionError = GetWebappPermissionErrors[keyof GetWebappPermissionErrors] + +export type GetWebappPermissionResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWebappPermissionResponse + = GetWebappPermissionResponses[keyof GetWebappPermissionResponses] + +export type GetWorkflowByTaskIdEventsData = { + body?: never + path: { + task_id: string + } + query?: never + url: '/workflow/{task_id}/events' +} + +export type GetWorkflowByTaskIdEventsResponses = { + 200: { + [key: string]: unknown + } +} + +export type GetWorkflowByTaskIdEventsResponse + = GetWorkflowByTaskIdEventsResponses[keyof GetWorkflowByTaskIdEventsResponses] + +export type PostWorkflowsRunData = { + body: WorkflowRunPayload + path?: never + query?: never + url: '/workflows/run' +} + +export type PostWorkflowsRunErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostWorkflowsRunError = PostWorkflowsRunErrors[keyof PostWorkflowsRunErrors] + +export type PostWorkflowsRunResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkflowsRunResponse = PostWorkflowsRunResponses[keyof PostWorkflowsRunResponses] + +export type PostWorkflowsTasksByTaskIdStopData = { + body?: never + path: { + task_id: string + } + query?: never + url: '/workflows/tasks/{task_id}/stop' +} + +export type PostWorkflowsTasksByTaskIdStopErrors = { + 400: { + [key: string]: unknown + } + 401: { + [key: string]: unknown + } + 403: { + [key: string]: unknown + } + 404: { + [key: string]: unknown + } + 500: { + [key: string]: unknown + } +} + +export type PostWorkflowsTasksByTaskIdStopError + = PostWorkflowsTasksByTaskIdStopErrors[keyof PostWorkflowsTasksByTaskIdStopErrors] + +export type PostWorkflowsTasksByTaskIdStopResponses = { + 200: { + [key: string]: unknown + } +} + +export type PostWorkflowsTasksByTaskIdStopResponse + = PostWorkflowsTasksByTaskIdStopResponses[keyof PostWorkflowsTasksByTaskIdStopResponses] diff --git a/packages/contracts/generated/api/web/zod.gen.ts b/packages/contracts/generated/api/web/zod.gen.ts new file mode 100644 index 0000000000..ec4bd19aff --- /dev/null +++ b/packages/contracts/generated/api/web/zod.gen.ts @@ -0,0 +1,478 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * ChatMessagePayload + */ +export const zChatMessagePayload = z.object({ + conversation_id: z.string().nullish(), + files: z.array(z.record(z.string(), z.unknown())).nullish(), + inputs: z.record(z.string(), z.unknown()), + parent_message_id: z.string().nullish(), + query: z.string(), + response_mode: z.enum(['blocking', 'streaming']).nullish(), + retriever_from: z.string().optional().default('web_app'), +}) + +/** + * CompletionMessagePayload + */ +export const zCompletionMessagePayload = z.object({ + files: z.array(z.record(z.string(), z.unknown())).nullish(), + inputs: z.record(z.string(), z.unknown()), + query: z.string().optional().default(''), + response_mode: z.enum(['blocking', 'streaming']).nullish(), + retriever_from: z.string().optional().default('web_app'), +}) + +/** + * EmailCodeLoginSendPayload + */ +export const zEmailCodeLoginSendPayload = z.object({ + email: z.string(), + language: z.string().nullish(), +}) + +/** + * EmailCodeLoginVerifyPayload + */ +export const zEmailCodeLoginVerifyPayload = z.object({ + code: z.string(), + email: z.string(), + token: z.string().min(1), +}) + +/** + * FileResponse + */ +export const zFileResponse = z.object({ + conversation_id: z.string().nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + extension: z.string().nullish(), + file_key: z.string().nullish(), + id: z.string(), + mime_type: z.string().nullish(), + name: z.string(), + original_url: z.string().nullish(), + preview_url: z.string().nullish(), + size: z.int(), + source_url: z.string().nullish(), + tenant_id: z.string().nullish(), + user_id: z.string().nullish(), +}) + +/** + * FileWithSignedUrl + */ +export const zFileWithSignedUrl = z.object({ + created_at: z.int().nullish(), + created_by: z.string().nullish(), + extension: z.string().nullish(), + id: z.string(), + mime_type: z.string().nullish(), + name: z.string(), + size: z.int(), + url: z.string().nullish(), +}) + +/** + * ForgotPasswordCheckPayload + */ +export const zForgotPasswordCheckPayload = z.object({ + code: z.string(), + email: z.string(), + token: z.string().min(1), +}) + +/** + * ForgotPasswordResetPayload + */ +export const zForgotPasswordResetPayload = z.object({ + new_password: z.string(), + password_confirm: z.string(), + token: z.string().min(1), +}) + +/** + * ForgotPasswordSendPayload + */ +export const zForgotPasswordSendPayload = z.object({ + email: z.string(), + language: z.string().nullish(), +}) + +/** + * LoginPayload + */ +export const zLoginPayload = z.object({ + email: z.string(), + password: z.string(), +}) + +/** + * MessageMoreLikeThisQuery + */ +export const zMessageMoreLikeThisQuery = z.object({ + response_mode: z.enum(['blocking', 'streaming']), +}) + +/** + * RemoteFileInfo + */ +export const zRemoteFileInfo = z.object({ + file_length: z.int(), + file_type: z.string(), +}) + +/** + * TextToAudioPayload + */ +export const zTextToAudioPayload = z.object({ + message_id: z.string().nullish(), + streaming: z.boolean().nullish(), + text: z.string().nullish(), + voice: z.string().nullish(), +}) + +/** + * WorkflowRunPayload + */ +export const zWorkflowRunPayload = z.object({ + files: z.array(z.record(z.string(), z.unknown())).nullish(), + inputs: z.record(z.string(), z.unknown()), +}) + +/** + * Success + */ +export const zPostAudioToTextResponse = z.record(z.string(), z.unknown()) + +export const zPostChatMessagesBody = zChatMessagePayload + +/** + * Success + */ +export const zPostChatMessagesResponse = z.record(z.string(), z.unknown()) + +export const zPostChatMessagesByTaskIdStopPath = z.object({ + task_id: z.string(), +}) + +/** + * Success + */ +export const zPostChatMessagesByTaskIdStopResponse = z.record(z.string(), z.unknown()) + +export const zPostCompletionMessagesBody = zCompletionMessagePayload + +/** + * Success + */ +export const zPostCompletionMessagesResponse = z.record(z.string(), z.unknown()) + +export const zPostCompletionMessagesByTaskIdStopPath = z.object({ + task_id: z.string(), +}) + +/** + * Success + */ +export const zPostCompletionMessagesByTaskIdStopResponse = z.record(z.string(), z.unknown()) + +export const zGetConversationsQuery = z.object({ + last_id: z.string().optional(), + limit: z.int().optional().default(20), + pinned: z.enum(['true', 'false']).optional(), + sort_by: z + .enum(['created_at', '-created_at', 'updated_at', '-updated_at']) + .optional() + .default('-updated_at'), +}) + +/** + * Success + */ +export const zGetConversationsResponse = z.record(z.string(), z.unknown()) + +export const zDeleteConversationsByCIdPath = z.object({ + c_id: z.string(), +}) + +/** + * Conversation deleted successfully + */ +export const zDeleteConversationsByCIdResponse = z.record(z.string(), z.unknown()) + +export const zPostConversationsByCIdNamePath = z.object({ + c_id: z.string(), +}) + +export const zPostConversationsByCIdNameQuery = z.object({ + name: z.string().optional(), + auto_generate: z.boolean().optional().default(false), +}) + +/** + * Conversation renamed successfully + */ +export const zPostConversationsByCIdNameResponse = z.record(z.string(), z.unknown()) + +export const zPatchConversationsByCIdPinPath = z.object({ + c_id: z.string(), +}) + +/** + * Conversation pinned successfully + */ +export const zPatchConversationsByCIdPinResponse = z.record(z.string(), z.unknown()) + +export const zPatchConversationsByCIdUnpinPath = z.object({ + c_id: z.string(), +}) + +/** + * Conversation unpinned successfully + */ +export const zPatchConversationsByCIdUnpinResponse = z.record(z.string(), z.unknown()) + +export const zPostEmailCodeLoginBody = zEmailCodeLoginSendPayload + +/** + * Email code sent successfully + */ +export const zPostEmailCodeLoginResponse = z.record(z.string(), z.unknown()) + +export const zPostEmailCodeLoginValidityBody = zEmailCodeLoginVerifyPayload + +/** + * Email code verified and login successful + */ +export const zPostEmailCodeLoginValidityResponse = z.record(z.string(), z.unknown()) + +/** + * File uploaded successfully + */ +export const zPostFilesUploadResponse = zFileResponse + +export const zPostForgotPasswordBody = zForgotPasswordSendPayload + +/** + * Password reset email sent successfully + */ +export const zPostForgotPasswordResponse = z.record(z.string(), z.unknown()) + +export const zPostForgotPasswordResetsBody = zForgotPasswordResetPayload + +/** + * Password reset successfully + */ +export const zPostForgotPasswordResetsResponse = z.record(z.string(), z.unknown()) + +export const zPostForgotPasswordValidityBody = zForgotPasswordCheckPayload + +/** + * Token is valid + */ +export const zPostForgotPasswordValidityResponse = z.record(z.string(), z.unknown()) + +export const zGetFormHumanInputByFormTokenPath = z.object({ + form_token: z.string(), +}) + +/** + * Success + */ +export const zGetFormHumanInputByFormTokenResponse = z.record(z.string(), z.unknown()) + +export const zPostFormHumanInputByFormTokenPath = z.object({ + form_token: z.string(), +}) + +/** + * Success + */ +export const zPostFormHumanInputByFormTokenResponse = z.record(z.string(), z.unknown()) + +export const zPostLoginBody = zLoginPayload + +/** + * Authentication successful + */ +export const zPostLoginResponse = z.record(z.string(), z.unknown()) + +/** + * Login status + */ +export const zGetLoginStatusResponse = z.record(z.string(), z.unknown()) + +/** + * Logout successful + */ +export const zPostLogoutResponse = z.record(z.string(), z.unknown()) + +export const zGetMessagesQuery = z.object({ + conversation_id: z.string(), + first_id: z.string().optional(), + limit: z.int().optional().default(20), +}) + +/** + * Success + */ +export const zGetMessagesResponse = z.record(z.string(), z.unknown()) + +export const zPostMessagesByMessageIdFeedbacksPath = z.object({ + message_id: z.string(), +}) + +export const zPostMessagesByMessageIdFeedbacksQuery = z.object({ + rating: z.enum(['like', 'dislike']).optional(), + content: z.string().optional(), +}) + +/** + * Feedback submitted successfully + */ +export const zPostMessagesByMessageIdFeedbacksResponse = z.record(z.string(), z.unknown()) + +export const zGetMessagesByMessageIdMoreLikeThisPath = z.object({ + message_id: z.string(), +}) + +export const zGetMessagesByMessageIdMoreLikeThisQuery = z.object({ + response_mode: z.enum(['blocking', 'streaming']), +}) + +/** + * Success + */ +export const zGetMessagesByMessageIdMoreLikeThisResponse = z.record(z.string(), z.unknown()) + +export const zGetMessagesByMessageIdSuggestedQuestionsPath = z.object({ + message_id: z.string(), +}) + +/** + * Success + */ +export const zGetMessagesByMessageIdSuggestedQuestionsResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetMetaResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetParametersResponse = z.record(z.string(), z.unknown()) + +/** + * Passport retrieved successfully + */ +export const zGetPassportResponse = z.record(z.string(), z.unknown()) + +/** + * Remote file uploaded successfully + */ +export const zPostRemoteFilesUploadResponse = zFileWithSignedUrl + +export const zGetRemoteFilesByUrlPath = z.object({ + url: z.string(), +}) + +/** + * Remote file information retrieved successfully + */ +export const zGetRemoteFilesByUrlResponse = zRemoteFileInfo + +export const zGetSavedMessagesQuery = z.object({ + last_id: z.string().optional(), + limit: z.int().optional().default(20), +}) + +/** + * Success + */ +export const zGetSavedMessagesResponse = z.record(z.string(), z.unknown()) + +export const zPostSavedMessagesQuery = z.object({ + message_id: z.string(), +}) + +/** + * Message saved successfully + */ +export const zPostSavedMessagesResponse = z.record(z.string(), z.unknown()) + +export const zDeleteSavedMessagesByMessageIdPath = z.object({ + message_id: z.string(), +}) + +/** + * Message removed successfully + */ +export const zDeleteSavedMessagesByMessageIdResponse = z.record(z.string(), z.unknown()) + +/** + * Success + */ +export const zGetSiteResponse = z.record(z.string(), z.unknown()) + +/** + * System features retrieved successfully + */ +export const zGetSystemFeaturesResponse = z.record(z.string(), z.unknown()) + +export const zPostTextToAudioBody = zTextToAudioPayload + +/** + * Success + */ +export const zPostTextToAudioResponse = z.record(z.string(), z.unknown()) + +export const zGetWebappAccessModeQuery = z.object({ + appId: z.string().optional(), + appCode: z.string().optional(), +}) + +/** + * Success + */ +export const zGetWebappAccessModeResponse = z.record(z.string(), z.unknown()) + +export const zGetWebappPermissionQuery = z.object({ + appId: z.string(), +}) + +/** + * Success + */ +export const zGetWebappPermissionResponse = z.record(z.string(), z.unknown()) + +export const zGetWorkflowByTaskIdEventsPath = z.object({ + task_id: z.string(), +}) + +/** + * Success + */ +export const zGetWorkflowByTaskIdEventsResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkflowsRunBody = zWorkflowRunPayload + +/** + * Success + */ +export const zPostWorkflowsRunResponse = z.record(z.string(), z.unknown()) + +export const zPostWorkflowsTasksByTaskIdStopPath = z.object({ + task_id: z.string(), +}) + +/** + * Success + */ +export const zPostWorkflowsTasksByTaskIdStopResponse = z.record(z.string(), z.unknown()) diff --git a/packages/contracts/generated/enterprise/orpc.gen.ts b/packages/contracts/generated/enterprise/orpc.gen.ts new file mode 100644 index 0000000000..73eb850001 --- /dev/null +++ b/packages/contracts/generated/enterprise/orpc.gen.ts @@ -0,0 +1,534 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zConsoleSsoOAuth2LoginResponse, + zConsoleSsoOidcLoginResponse, + zConsoleSsoSamlLoginResponse, + zEnterpriseAppDeployConsoleCancelRuntimeDeploymentBody, + zEnterpriseAppDeployConsoleCancelRuntimeDeploymentPath, + zEnterpriseAppDeployConsoleCancelRuntimeDeploymentResponse, + zEnterpriseAppDeployConsoleCreateAppInstanceBody, + zEnterpriseAppDeployConsoleCreateAppInstanceResponse, + zEnterpriseAppDeployConsoleCreateDeploymentBody, + zEnterpriseAppDeployConsoleCreateDeploymentPath, + zEnterpriseAppDeployConsoleCreateDeploymentResponse, + zEnterpriseAppDeployConsoleCreateDeveloperApiKeyBody, + zEnterpriseAppDeployConsoleCreateDeveloperApiKeyPath, + zEnterpriseAppDeployConsoleCreateDeveloperApiKeyResponse, + zEnterpriseAppDeployConsoleCreateReleaseBody, + zEnterpriseAppDeployConsoleCreateReleasePath, + zEnterpriseAppDeployConsoleCreateReleaseResponse, + zEnterpriseAppDeployConsoleDeleteAppInstancePath, + zEnterpriseAppDeployConsoleDeleteAppInstanceResponse, + zEnterpriseAppDeployConsoleDeleteDeveloperApiKeyPath, + zEnterpriseAppDeployConsoleDeleteDeveloperApiKeyResponse, + zEnterpriseAppDeployConsoleGetAppInstanceAccessPath, + zEnterpriseAppDeployConsoleGetAppInstanceAccessResponse, + zEnterpriseAppDeployConsoleGetAppInstanceOverviewPath, + zEnterpriseAppDeployConsoleGetAppInstanceOverviewResponse, + zEnterpriseAppDeployConsoleGetAppInstanceSettingsPath, + zEnterpriseAppDeployConsoleGetAppInstanceSettingsResponse, + zEnterpriseAppDeployConsoleGetEnvironmentAccessPolicyPath, + zEnterpriseAppDeployConsoleGetEnvironmentAccessPolicyResponse, + zEnterpriseAppDeployConsoleListAppInstancesQuery, + zEnterpriseAppDeployConsoleListAppInstancesResponse, + zEnterpriseAppDeployConsoleListDeploymentBindingOptionsPath, + zEnterpriseAppDeployConsoleListDeploymentBindingOptionsResponse, + zEnterpriseAppDeployConsoleListDeploymentEnvironmentOptionsResponse, + zEnterpriseAppDeployConsoleListReleasesPath, + zEnterpriseAppDeployConsoleListReleasesQuery, + zEnterpriseAppDeployConsoleListReleasesResponse, + zEnterpriseAppDeployConsoleListRuntimeInstancesPath, + zEnterpriseAppDeployConsoleListRuntimeInstancesResponse, + zEnterpriseAppDeployConsolePreviewReleaseBody, + zEnterpriseAppDeployConsolePreviewReleasePath, + zEnterpriseAppDeployConsolePreviewReleaseResponse, + zEnterpriseAppDeployConsoleSearchAccessSubjectsPath, + zEnterpriseAppDeployConsoleSearchAccessSubjectsQuery, + zEnterpriseAppDeployConsoleSearchAccessSubjectsResponse, + zEnterpriseAppDeployConsoleUndeployRuntimeInstanceBody, + zEnterpriseAppDeployConsoleUndeployRuntimeInstancePath, + zEnterpriseAppDeployConsoleUndeployRuntimeInstanceResponse, + zEnterpriseAppDeployConsoleUpdateAccessChannelsBody, + zEnterpriseAppDeployConsoleUpdateAccessChannelsPath, + zEnterpriseAppDeployConsoleUpdateAccessChannelsResponse, + zEnterpriseAppDeployConsoleUpdateAppInstanceBody, + zEnterpriseAppDeployConsoleUpdateAppInstancePath, + zEnterpriseAppDeployConsoleUpdateAppInstanceResponse, + zEnterpriseAppDeployConsoleUpdateDeveloperApiBody, + zEnterpriseAppDeployConsoleUpdateDeveloperApiPath, + zEnterpriseAppDeployConsoleUpdateDeveloperApiResponse, + zEnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyBody, + zEnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyPath, + zEnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyResponse, + zWebAppAuthGetGroupSubjectsQuery, + zWebAppAuthGetGroupSubjectsResponse, + zWebAppAuthGetWebAppAccessModeQuery, + zWebAppAuthGetWebAppAccessModeResponse, + zWebAppAuthGetWebAppWhitelistSubjectsQuery, + zWebAppAuthGetWebAppWhitelistSubjectsResponse, + zWebAppAuthIsUserAllowedToAccessWebAppQuery, + zWebAppAuthIsUserAllowedToAccessWebAppResponse, + zWebAppAuthSearchForWhilteListCandidatesQuery, + zWebAppAuthSearchForWhilteListCandidatesResponse, + zWebAppAuthUpdateWebAppWhitelistSubjectsBody, + zWebAppAuthUpdateWebAppWhitelistSubjectsResponse, +} from './zod.gen' + +export const listAppInstances = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'EnterpriseAppDeployConsole_ListAppInstances', + path: '/enterprise/app-instances', + tags: ['EnterpriseAppDeployConsole'], + }) + .input(z.object({ query: zEnterpriseAppDeployConsoleListAppInstancesQuery.optional() })) + .output(zEnterpriseAppDeployConsoleListAppInstancesResponse) + +export const createAppInstance = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'EnterpriseAppDeployConsole_CreateAppInstance', + path: '/enterprise/app-instances', + tags: ['EnterpriseAppDeployConsole'], + }) + .input(z.object({ body: zEnterpriseAppDeployConsoleCreateAppInstanceBody })) + .output(zEnterpriseAppDeployConsoleCreateAppInstanceResponse) + +export const deleteAppInstance = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'EnterpriseAppDeployConsole_DeleteAppInstance', + path: '/enterprise/app-instances/{appInstanceId}', + tags: ['EnterpriseAppDeployConsole'], + }) + .input(z.object({ params: zEnterpriseAppDeployConsoleDeleteAppInstancePath })) + .output(zEnterpriseAppDeployConsoleDeleteAppInstanceResponse) + +export const updateAppInstance = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'EnterpriseAppDeployConsole_UpdateAppInstance', + path: '/enterprise/app-instances/{appInstanceId}', + tags: ['EnterpriseAppDeployConsole'], + }) + .input( + z.object({ + body: zEnterpriseAppDeployConsoleUpdateAppInstanceBody, + params: zEnterpriseAppDeployConsoleUpdateAppInstancePath, + }), + ) + .output(zEnterpriseAppDeployConsoleUpdateAppInstanceResponse) + +export const getAppInstanceAccess = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'EnterpriseAppDeployConsole_GetAppInstanceAccess', + path: '/enterprise/app-instances/{appInstanceId}/access', + tags: ['EnterpriseAppDeployConsole'], + }) + .input(z.object({ params: zEnterpriseAppDeployConsoleGetAppInstanceAccessPath })) + .output(zEnterpriseAppDeployConsoleGetAppInstanceAccessResponse) + +export const updateAccessChannels = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'EnterpriseAppDeployConsole_UpdateAccessChannels', + path: '/enterprise/app-instances/{appInstanceId}/access-channels', + tags: ['EnterpriseAppDeployConsole'], + }) + .input( + z.object({ + body: zEnterpriseAppDeployConsoleUpdateAccessChannelsBody, + params: zEnterpriseAppDeployConsoleUpdateAccessChannelsPath, + }), + ) + .output(zEnterpriseAppDeployConsoleUpdateAccessChannelsResponse) + +export const searchAccessSubjects = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'EnterpriseAppDeployConsole_SearchAccessSubjects', + path: '/enterprise/app-instances/{appInstanceId}/access-subjects:search', + tags: ['EnterpriseAppDeployConsole'], + }) + .input( + z.object({ + params: zEnterpriseAppDeployConsoleSearchAccessSubjectsPath, + query: zEnterpriseAppDeployConsoleSearchAccessSubjectsQuery.optional(), + }), + ) + .output(zEnterpriseAppDeployConsoleSearchAccessSubjectsResponse) + +export const createDeveloperApiKey = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'EnterpriseAppDeployConsole_CreateDeveloperApiKey', + path: '/enterprise/app-instances/{appInstanceId}/api-keys', + tags: ['EnterpriseAppDeployConsole'], + }) + .input( + z.object({ + body: zEnterpriseAppDeployConsoleCreateDeveloperApiKeyBody, + params: zEnterpriseAppDeployConsoleCreateDeveloperApiKeyPath, + }), + ) + .output(zEnterpriseAppDeployConsoleCreateDeveloperApiKeyResponse) + +export const deleteDeveloperApiKey = oc + .route({ + inputStructure: 'detailed', + method: 'DELETE', + operationId: 'EnterpriseAppDeployConsole_DeleteDeveloperApiKey', + path: '/enterprise/app-instances/{appInstanceId}/api-keys/{apiKeyId}', + tags: ['EnterpriseAppDeployConsole'], + }) + .input(z.object({ params: zEnterpriseAppDeployConsoleDeleteDeveloperApiKeyPath })) + .output(zEnterpriseAppDeployConsoleDeleteDeveloperApiKeyResponse) + +export const listDeploymentBindingOptions = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'EnterpriseAppDeployConsole_ListDeploymentBindingOptions', + path: '/enterprise/app-instances/{appInstanceId}/deployment-binding-options', + tags: ['EnterpriseAppDeployConsole'], + }) + .input(z.object({ params: zEnterpriseAppDeployConsoleListDeploymentBindingOptionsPath })) + .output(zEnterpriseAppDeployConsoleListDeploymentBindingOptionsResponse) + +export const createDeployment = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'EnterpriseAppDeployConsole_CreateDeployment', + path: '/enterprise/app-instances/{appInstanceId}/deployments', + tags: ['EnterpriseAppDeployConsole'], + }) + .input( + z.object({ + body: zEnterpriseAppDeployConsoleCreateDeploymentBody, + params: zEnterpriseAppDeployConsoleCreateDeploymentPath, + }), + ) + .output(zEnterpriseAppDeployConsoleCreateDeploymentResponse) + +export const updateDeveloperApi = oc + .route({ + inputStructure: 'detailed', + method: 'PATCH', + operationId: 'EnterpriseAppDeployConsole_UpdateDeveloperApi', + path: '/enterprise/app-instances/{appInstanceId}/developer-api', + tags: ['EnterpriseAppDeployConsole'], + }) + .input( + z.object({ + body: zEnterpriseAppDeployConsoleUpdateDeveloperApiBody, + params: zEnterpriseAppDeployConsoleUpdateDeveloperApiPath, + }), + ) + .output(zEnterpriseAppDeployConsoleUpdateDeveloperApiResponse) + +export const getEnvironmentAccessPolicy = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'EnterpriseAppDeployConsole_GetEnvironmentAccessPolicy', + path: '/enterprise/app-instances/{appInstanceId}/environments/{environmentId}/access-policy', + tags: ['EnterpriseAppDeployConsole'], + }) + .input(z.object({ params: zEnterpriseAppDeployConsoleGetEnvironmentAccessPolicyPath })) + .output(zEnterpriseAppDeployConsoleGetEnvironmentAccessPolicyResponse) + +export const updateEnvironmentAccessPolicy = oc + .route({ + inputStructure: 'detailed', + method: 'PUT', + operationId: 'EnterpriseAppDeployConsole_UpdateEnvironmentAccessPolicy', + path: '/enterprise/app-instances/{appInstanceId}/environments/{environmentId}/access-policy', + tags: ['EnterpriseAppDeployConsole'], + }) + .input( + z.object({ + body: zEnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyBody, + params: zEnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyPath, + }), + ) + .output(zEnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyResponse) + +export const getAppInstanceOverview = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'EnterpriseAppDeployConsole_GetAppInstanceOverview', + path: '/enterprise/app-instances/{appInstanceId}/overview', + tags: ['EnterpriseAppDeployConsole'], + }) + .input(z.object({ params: zEnterpriseAppDeployConsoleGetAppInstanceOverviewPath })) + .output(zEnterpriseAppDeployConsoleGetAppInstanceOverviewResponse) + +export const listReleases = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'EnterpriseAppDeployConsole_ListReleases', + path: '/enterprise/app-instances/{appInstanceId}/releases', + tags: ['EnterpriseAppDeployConsole'], + }) + .input( + z.object({ + params: zEnterpriseAppDeployConsoleListReleasesPath, + query: zEnterpriseAppDeployConsoleListReleasesQuery.optional(), + }), + ) + .output(zEnterpriseAppDeployConsoleListReleasesResponse) + +export const createRelease = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'EnterpriseAppDeployConsole_CreateRelease', + path: '/enterprise/app-instances/{appInstanceId}/releases', + tags: ['EnterpriseAppDeployConsole'], + }) + .input( + z.object({ + body: zEnterpriseAppDeployConsoleCreateReleaseBody, + params: zEnterpriseAppDeployConsoleCreateReleasePath, + }), + ) + .output(zEnterpriseAppDeployConsoleCreateReleaseResponse) + +export const previewRelease = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'EnterpriseAppDeployConsole_PreviewRelease', + path: '/enterprise/app-instances/{appInstanceId}/releases:preview', + tags: ['EnterpriseAppDeployConsole'], + }) + .input( + z.object({ + body: zEnterpriseAppDeployConsolePreviewReleaseBody, + params: zEnterpriseAppDeployConsolePreviewReleasePath, + }), + ) + .output(zEnterpriseAppDeployConsolePreviewReleaseResponse) + +export const listRuntimeInstances = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'EnterpriseAppDeployConsole_ListRuntimeInstances', + path: '/enterprise/app-instances/{appInstanceId}/runtime-instances', + tags: ['EnterpriseAppDeployConsole'], + }) + .input(z.object({ params: zEnterpriseAppDeployConsoleListRuntimeInstancesPath })) + .output(zEnterpriseAppDeployConsoleListRuntimeInstancesResponse) + +export const cancelRuntimeDeployment = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'EnterpriseAppDeployConsole_CancelRuntimeDeployment', + path: '/enterprise/app-instances/{appInstanceId}/runtime-instances/{runtimeInstanceId}/deployment:cancel', + tags: ['EnterpriseAppDeployConsole'], + }) + .input( + z.object({ + body: zEnterpriseAppDeployConsoleCancelRuntimeDeploymentBody, + params: zEnterpriseAppDeployConsoleCancelRuntimeDeploymentPath, + }), + ) + .output(zEnterpriseAppDeployConsoleCancelRuntimeDeploymentResponse) + +export const undeployRuntimeInstance = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'EnterpriseAppDeployConsole_UndeployRuntimeInstance', + path: '/enterprise/app-instances/{appInstanceId}/runtime-instances/{runtimeInstanceId}:undeploy', + tags: ['EnterpriseAppDeployConsole'], + }) + .input( + z.object({ + body: zEnterpriseAppDeployConsoleUndeployRuntimeInstanceBody, + params: zEnterpriseAppDeployConsoleUndeployRuntimeInstancePath, + }), + ) + .output(zEnterpriseAppDeployConsoleUndeployRuntimeInstanceResponse) + +export const getAppInstanceSettings = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'EnterpriseAppDeployConsole_GetAppInstanceSettings', + path: '/enterprise/app-instances/{appInstanceId}/settings', + tags: ['EnterpriseAppDeployConsole'], + }) + .input(z.object({ params: zEnterpriseAppDeployConsoleGetAppInstanceSettingsPath })) + .output(zEnterpriseAppDeployConsoleGetAppInstanceSettingsResponse) + +export const listDeploymentEnvironmentOptions = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'EnterpriseAppDeployConsole_ListDeploymentEnvironmentOptions', + path: '/enterprise/deployment-environment-options', + tags: ['EnterpriseAppDeployConsole'], + }) + .output(zEnterpriseAppDeployConsoleListDeploymentEnvironmentOptionsResponse) + +export const enterpriseAppDeployConsole = { + listAppInstances, + createAppInstance, + deleteAppInstance, + updateAppInstance, + getAppInstanceAccess, + updateAccessChannels, + searchAccessSubjects, + createDeveloperApiKey, + deleteDeveloperApiKey, + listDeploymentBindingOptions, + createDeployment, + updateDeveloperApi, + getEnvironmentAccessPolicy, + updateEnvironmentAccessPolicy, + getAppInstanceOverview, + listReleases, + createRelease, + previewRelease, + listRuntimeInstances, + cancelRuntimeDeployment, + undeployRuntimeInstance, + getAppInstanceSettings, + listDeploymentEnvironmentOptions, +} + +export const oAuth2Login = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'ConsoleSSO_OAuth2Login', + path: '/enterprise/sso/oauth2/login', + tags: ['ConsoleSSO'], + }) + .output(zConsoleSsoOAuth2LoginResponse) + +export const oidcLogin = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'ConsoleSSO_OIDCLogin', + path: '/enterprise/sso/oidc/login', + tags: ['ConsoleSSO'], + }) + .output(zConsoleSsoOidcLoginResponse) + +export const samlLogin = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'ConsoleSSO_SAMLLogin', + path: '/enterprise/sso/saml/login', + tags: ['ConsoleSSO'], + }) + .output(zConsoleSsoSamlLoginResponse) + +export const consoleSso = { + oAuth2Login, + oidcLogin, + samlLogin, +} + +export const getWebAppAccessMode = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'WebAppAuth_GetWebAppAccessMode', + path: '/enterprise/webapp/app/access-mode', + tags: ['WebAppAuth'], + }) + .input(z.object({ query: zWebAppAuthGetWebAppAccessModeQuery.optional() })) + .output(zWebAppAuthGetWebAppAccessModeResponse) + +export const updateWebAppWhitelistSubjects = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'WebAppAuth_UpdateWebAppWhitelistSubjects', + path: '/enterprise/webapp/app/access-mode', + tags: ['WebAppAuth'], + }) + .input(z.object({ body: zWebAppAuthUpdateWebAppWhitelistSubjectsBody })) + .output(zWebAppAuthUpdateWebAppWhitelistSubjectsResponse) + +export const searchForWhilteListCandidates = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'WebAppAuth_SearchForWhilteListCandidates', + path: '/enterprise/webapp/app/subject/search', + tags: ['WebAppAuth'], + }) + .input(z.object({ query: zWebAppAuthSearchForWhilteListCandidatesQuery.optional() })) + .output(zWebAppAuthSearchForWhilteListCandidatesResponse) + +export const getWebAppWhitelistSubjects = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'WebAppAuth_GetWebAppWhitelistSubjects', + path: '/enterprise/webapp/app/subjects', + tags: ['WebAppAuth'], + }) + .input(z.object({ query: zWebAppAuthGetWebAppWhitelistSubjectsQuery.optional() })) + .output(zWebAppAuthGetWebAppWhitelistSubjectsResponse) + +export const getGroupSubjects = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'WebAppAuth_GetGroupSubjects', + path: '/enterprise/webapp/group/subjects', + tags: ['WebAppAuth'], + }) + .input(z.object({ query: zWebAppAuthGetGroupSubjectsQuery.optional() })) + .output(zWebAppAuthGetGroupSubjectsResponse) + +export const isUserAllowedToAccessWebApp = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'WebAppAuth_IsUserAllowedToAccessWebApp', + path: '/enterprise/webapp/permission', + tags: ['WebAppAuth'], + }) + .input(z.object({ query: zWebAppAuthIsUserAllowedToAccessWebAppQuery.optional() })) + .output(zWebAppAuthIsUserAllowedToAccessWebAppResponse) + +export const webAppAuth = { + getWebAppAccessMode, + updateWebAppWhitelistSubjects, + searchForWhilteListCandidates, + getWebAppWhitelistSubjects, + getGroupSubjects, + isUserAllowedToAccessWebApp, +} + +export const contract = { + enterpriseAppDeployConsole, + consoleSso, + webAppAuth, +} diff --git a/packages/contracts/generated/enterprise/types.gen.ts b/packages/contracts/generated/enterprise/types.gen.ts new file mode 100644 index 0000000000..56228f2738 --- /dev/null +++ b/packages/contracts/generated/enterprise/types.gen.ts @@ -0,0 +1,1978 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}` | (string & {}) +} + +export type AccessChannels = { + enabled?: boolean + webappRows?: Array + cli?: CliAccess +} + +export type AccessModeOption = { + mode?: string + label?: string + disabled?: boolean + selected?: boolean +} + +export type AccessPolicyDetail = { + accessMode?: string + subjects?: Array + options?: Array +} + +export type AccessStatus = { + accessChannelsEnabled?: boolean + webappUrl?: string + cliUrl?: string + developerApiEnabled?: boolean + apiKeyCount?: number +} + +export type AccessSubject = { + subjectId?: string + subjectType?: string +} + +export type AccessSubjectDisplay = { + id?: string + subjectType?: string + name?: string + avatarUrl?: string + memberCount?: string +} + +export type Account = { + id?: string + email?: string + name?: string +} + +export type AccountDetail = { + account?: Account + status?: string + createdAt?: string + lastActiveAt?: string + workspaces?: Array + groups?: Array +} + +export type AccountDetailGroup = { + id?: string + name?: string +} + +export type AccountInWorkspace = { + workspaceId?: string + workspaceName?: string + role?: string +} + +export type AckDeploymentReply = { + accepted?: boolean + newVersion?: string +} + +export type AckDeploymentReq = { + deploymentId?: string + instanceId?: string + expectedVersion?: string + status?: string + observedReleaseId?: string + lastError?: LastError +} + +export type AppInstanceBasicInfo = { + id?: string + name?: string + description?: string + sourceAppId?: string + sourceAppName?: string + mode?: string + createdAt?: string +} + +export type AppInstanceCard = { + id?: string + name?: string + icon?: string + mode?: string + sourceAppName?: string + statuses?: Array + lastDeployedAt?: string +} + +export type AppRunnerBatchRuntimeArtifactReply = { + results?: Array +} + +export type AppRunnerBatchRuntimeArtifactRequest = { + artifacts?: Array +} + +export type AppRunnerBootstrapAssignment = { + appId?: string + environmentId?: string + workflowId?: string + instanceId?: string + workspaceId?: string + instanceVersion?: string + bindingSnapshotVersion?: string + executionTokenVersion?: string + executionToken?: string + releaseId?: string +} + +export type AppRunnerBootstrapReply = { + runnerId?: string + assignmentRevision?: string + assignments?: Array +} + +export type AppRunnerBootstrapRequest = { + runner?: AppRunnerRunnerInfo +} + +export type AppRunnerRunnerInfo = { + hostname?: string +} + +export type AppRunnerRuntimeArtifactReply = { + dslYaml?: string + bindingSnapshotVersion?: string + bindingSnapshot?: { + [key: string]: unknown + } +} + +export type AppRunnerRuntimeArtifactRequest = { + instanceId?: string + releaseId?: string + bindingSnapshotVersion?: string +} + +export type AppRunnerRuntimeArtifactResult = { + instanceId?: string + releaseId?: string + artifact?: AppRunnerRuntimeArtifactReply + errorCode?: string + errorMessage?: string +} + +export type AppRunnerTokenExchangeReply = { + accessToken?: string + expiresAt?: string +} + +export type AppRunnerTokenExchangeRequest = { + joinToken?: string +} + +export type AuthSettingsReply = { + userSsoSettings?: SsoSettings + webSsoSettings?: SsoSettings + dashboardSsoSettings?: SsoSettings + userSsoSamlAcsUrl?: string + userSsoOidcCallbackUrl?: string + userSsoOauth2CallbackUrl?: string + webSsoSamlAcsUrl?: string + webSsoOidcCallbackUrl?: string + webSsoOauth2CallbackUrl?: string + webSsoMembersSamlAcsUrl?: string + webSsoMembersOidcCallbackUrl?: string + webSsoMembersOauth2CallbackUrl?: string + dashboardSsoSamlAcsUrl?: string + dashboardSsoOidcCallbackUrl?: string + dashboardSsoOauth2CallbackUrl?: string +} + +export type AuthSettingsReq = { + ssoType?: string + ssoSettings?: SsoSettings +} + +export type BootstrapProgress = { + currentStep?: string + completedSteps?: Array + attemptCount?: number + lastAttemptAt?: string + lastErrorCode?: string + lastErrorMessage?: string +} + +export type BrandingInfo = { + enabled?: boolean + applicationTitle?: string + loginPageLogo?: string + workspaceLogo?: string + favicon?: string +} + +export type CancelRuntimeDeploymentReply = { + status?: string +} + +export type CancelRuntimeDeploymentReq = { + appInstanceId?: string + runtimeInstanceId?: string +} + +export type CheckPasswordStatusReply = { + requirePasswordChange?: boolean + changeReason?: number + daysToExpire?: number + message?: string +} + +export type ClearDefaultWorkspaceReply = { + [key: string]: unknown +} + +export type CliAccess = { + url?: string +} + +export type ConsoleEnvironment = { + id?: string + name?: string + runtime?: string + type?: string + status?: string +} + +export type ConsoleRelease = { + id?: string + name?: string + shortCommitId?: string + createdAt?: string +} + +export type ConsoleUser = { + id?: string + name?: string +} + +export type CreateAppInstanceReply = { + appInstanceId?: string + initialRelease?: ConsoleRelease +} + +export type CreateAppInstanceReq = { + sourceAppId?: string + name?: string + description?: string +} + +export type CreateBearerTokenResponse = { + token?: string +} + +export type CreateDeploymentReply = { + runtimeInstanceId?: string + deploymentId?: string + status?: string +} + +export type CreateDeploymentReq = { + appInstanceId?: string + environmentId?: string + releaseId?: string + bindings?: Array +} + +export type CreateDeveloperApiKeyReply = { + apiKey?: DeveloperApiKeyRow + token?: string +} + +export type CreateDeveloperApiKeyReq = { + appInstanceId?: string + environmentId?: string + name?: string +} + +export type CreateEnvironmentReply = { + environment?: Environment +} + +export type CreateEnvironmentReq = { + name?: string + description?: string + mode?: number + backend?: number + k8s?: K8sEnvironmentConfig + host?: HostEnvironmentConfig +} + +export type CreateMemberReply = { + id?: string + password?: string +} + +export type CreateMemberReq = { + name?: string + email?: string + status?: string +} + +export type CreateNewGroupsReq = { + groups?: Array +} + +export type CreateNewGroupsReqGroup = { + name?: string +} + +export type CreateNewGroupsRes = { + groups?: Array +} + +export type CreateReleaseReply = { + release?: ConsoleRelease +} + +export type CreateReleaseReq = { + appInstanceId?: string + name?: string + description?: string +} + +export type CreateSecretKeyReply = { + id?: string + name?: string + secretKey?: string + createdAt?: string + lastActive?: string +} + +export type CreateSecretKeyReq = { + name?: string +} + +export type CreateUserReply = { + id?: string + password?: string +} + +export type CreateUserReq = { + name?: string + email?: string + status?: string +} + +export type CreateWorkspaceReply = { + workspace?: Workspace +} + +export type CreateWorkspaceReq = { + name?: string + email?: string + status?: string +} + +export type CurrentUserReply = { + id?: string + name?: string + email?: string + interfaceLanguage?: string + timezone?: string +} + +export type DashboardSsooidcLoginReply = { + url?: string + state?: string +} + +export type DashboardSsoOauth2LoginReply = { + url?: string + state?: string +} + +export type DashboardSsosamlLoginReply = { + url?: string +} + +export type DeleteAppInstanceReply = { + [key: string]: unknown +} + +export type DeleteDeveloperApiKeyReply = { + [key: string]: unknown +} + +export type DeleteEnvironmentReply = { + [key: string]: unknown +} + +export type DeleteGroupsRes = { + message?: string +} + +export type DeleteGuard = { + canDelete?: boolean + disabledReason?: string +} + +export type DeleteMemberReply = { + account?: Account +} + +export type DeleteSecretKeyReply = { + message?: string +} + +export type DeleteUserReply = { + account?: Account +} + +export type DeleteWorkspaceReply = { + [key: string]: unknown +} + +export type DeployedEnvironment = { + environmentId?: string + environmentName?: string +} + +export type DeploymentBindingOptionSlot = { + slot?: string + kind?: string + label?: string + required?: boolean + candidates?: Array + envVarCandidates?: Array +} + +export type DeploymentCredentialOption = { + credentialId?: string + displayName?: string + pluginId?: string + pluginName?: string + pluginVersion?: string +} + +export type DeploymentEnvVarOption = { + envVarId?: string + name?: string + valueType?: string + displayValue?: string +} + +export type DeploymentEnvironmentOption = { + id?: string + name?: string + type?: string + backend?: string + status?: string + managedBy?: string + deployable?: boolean + disabledReason?: string +} + +export type DeploymentRuntimeBinding = { + slot?: string + credentialId?: string + envVarId?: string +} + +export type DeploymentStatusRow = { + environment?: ConsoleEnvironment + release?: ConsoleRelease + status?: string +} + +export type DeveloperApiAccess = { + enabled?: boolean + apiKeys?: Array +} + +export type DeveloperApiKeyRow = { + id?: string + name?: string + environment?: ConsoleEnvironment + maskedKey?: string +} + +export type EndpointReply = { + mode?: number + metricsEndpoint?: OtelExporterEndpoint + tracesEndpoint?: OtelExporterEndpoint +} + +export type EnterpriseSystemUserSettingReply = { + ssoEnforcedForSignin?: boolean + ssoEnforcedForSigninProtocol?: string + enableEmailPasswordLogin?: boolean +} + +export type Environment = { + id?: string + name?: string + description?: string + mode?: number + namespace?: string + apiServer?: string + status?: number + statusMessage?: string + bootstrapProgress?: BootstrapProgress + managedBy?: string + createdAt?: string + updatedAt?: string + backend?: number + host?: string +} + +export type EnvironmentAccessRow = { + environment?: ConsoleEnvironment + currentRelease?: ConsoleRelease + accessMode?: string + accessModeLabel?: string + hint?: string +} + +export type EnvironmentFilter = { + id?: string + name?: string + kind?: string +} + +export type GetAppInstanceAccessReply = { + permissions?: Array + accessChannels?: AccessChannels + developerApi?: DeveloperApiAccess +} + +export type GetAppInstanceOverviewReply = { + instance?: AppInstanceBasicInfo + deployments?: Array + access?: AccessStatus +} + +export type GetAppInstanceSettingsReply = { + name?: string + description?: string + deleteGuard?: DeleteGuard +} + +export type GetBearerTokenResponse = { + maskedToken?: string +} + +export type GetClusterInfoReply = { + mode?: string + clusterId?: string + verifyMode?: string +} + +export type GetDefaultWorkspaceReply = { + workspaceId?: string + workspace?: Workspace +} + +export type GetEnvironmentAccessPolicyReply = { + policy?: AccessPolicyDetail +} + +export type GetEnvironmentReply = { + environment?: Environment +} + +export type GetGroupSubjectsRes = { + subjects?: Array +} + +export type GetGroupsRes = { + groups?: Array +} + +export type GetInstanceReply = { + instanceId?: string + status?: string + desiredReleaseId?: string + observedReleaseId?: string + currentDeploymentId?: string + version?: string +} + +export type GetJoinedGroupsRes = { + groups?: Array +} + +export type GetLicenseReply = { + license?: LicenseInfo +} + +export type GetLicenseStatusReply = { + status?: string +} + +export type GetMfaInfoReply = { + userEnabled?: boolean + userSetup?: boolean + globalEnabled?: boolean +} + +export type GetMemberReply = { + account?: AccountDetail +} + +export type GetUserReply = { + account?: AccountDetail +} + +export type GetWebAppAccessModeRes = { + accessMode?: string +} + +export type GetWebAppAuthInfoRes = { + allowSso?: boolean + allowEmailCodeLogin?: boolean + allowEmailPasswordLogin?: boolean +} + +export type GetWebAppWhitelistSubjectsRes = { + groups?: Array + members?: Array +} + +export type GetWebAppWhitelistSubjectsResMember = { + id?: string + name?: string + email?: string + avatar?: string +} + +export type GetWorkspacePermissionReply = { + permission?: WorkspacePermission +} + +export type GetWorkspaceReply = { + workspace?: Workspace +} + +export type HealthzReply = { + message?: string + status?: string +} + +export type HostEnvironmentConfig = { + machineId?: string + joinTokenHash?: string +} + +export type InfoConfigReply = { + SSOEnforcedForSignin?: boolean + SSOEnforcedForSigninProtocol?: string + SSOEnforcedForWeb?: boolean + SSOEnforcedForWebProtocol?: string + EnableEmailCodeLogin?: boolean + EnableEmailPasswordLogin?: boolean + IsAllowRegister?: boolean + IsAllowCreateWorkspace?: boolean + License?: LicenseStatus + Branding?: BrandingInfo + WebAppAuth?: WebAppAuthInfo + PluginInstallationPermission?: PluginInstallationPermissionInfo +} + +export type InnerBatchGetWebAppAccessModesByIdReq = { + appIds?: Array +} + +export type InnerBatchGetWebAppAccessModesByIdRes = { + accessModes?: { + [key: string]: string + } +} + +export type InnerBatchIsUserAllowedToAccessWebAppReq = { + userId?: string + appIds?: Array +} + +export type InnerBatchIsUserAllowedToAccessWebAppRes = { + permissions?: { + [key: string]: boolean + } +} + +export type InnerCheckAppDeployAccessReply = { + allowed?: boolean + matchedPolicyId?: string + matchedScopeType?: string + reason?: string + cacheTtlSeconds?: number +} + +export type InnerCheckAppDeployAccessReq = { + appInstanceId?: string + environmentId?: string + principalType?: string + principalId?: string +} + +export type InnerCleanAppRes = { + message?: string +} + +export type InnerGetTokenRouteReply = { + environmentId?: string + namespace?: string + serviceName?: string + servicePort?: number + environmentStatus?: string + appId?: string + tenantId?: string + instanceId?: string + observedReleaseId?: string + instanceStatus?: string +} + +export type InnerGetTokenRouteReq = { + token?: string +} + +export type InnerGetWebAppAccessModeByCodeRes = { + accessMode?: string +} + +export type InnerGetWebAppAccessModeByIdRes = { + accessMode?: string +} + +export type InnerIsUserAllowedToAccessWebAppRes = { + result?: boolean +} + +export type InnerTryAddAccountToDefaultWorkspaceReply = { + workspaceId?: string + joined?: boolean + message?: string +} + +export type InnerTryAddAccountToDefaultWorkspaceReq = { + accountId?: string +} + +export type IsUserAllowedToAccessWebAppRes = { + result?: boolean +} + +export type JoinWorkspaceReply = { + message?: string +} + +export type JoinWorkspaceReq = { + id?: string + email?: string + role?: string +} + +export type K8sEnvironmentConfig = { + namespace?: string + apiServer?: string + caBundle?: string + bearerToken?: string +} + +export type LastError = { + phase?: string + code?: string + message?: string + releaseId?: string +} + +export type LicenseInfo = { + uuid?: string + expiredAt?: string + clusterId?: string + product?: string + limits?: LimitFields +} + +export type LicenseStatus = { + status?: string + expiredAt?: string + workspaces?: ResourceQuota +} + +export type LimitFields = { + workspaceMembers?: number + workspaces?: ResourceQuota +} + +export type ListAppInstancesReply = { + filters?: Array + data?: Array + pagination?: Pagination +} + +export type ListDeploymentBindingOptionsReply = { + slots?: Array +} + +export type ListDeploymentEnvironmentOptionsReply = { + environments?: Array +} + +export type ListEnvironmentsReply = { + data?: Array + pagination?: Pagination +} + +export type ListMembersReply = { + data?: Array + pagination?: Pagination +} + +export type ListReleasesReply = { + data?: Array + pagination?: Pagination +} + +export type ListRuntimeInstancesReply = { + data?: Array +} + +export type ListSecretKeysReply = { + data?: Array + pagination?: Pagination +} + +export type ListUsersReply = { + data?: Array + pagination?: Pagination +} + +export type ListWorkspacesReply = { + data?: Array + pagination?: Pagination +} + +export type LoginTypesReply = { + enabledEmailCodeLogin?: boolean + enableEmailPasswordLogin?: boolean + isAllowRegister?: boolean + isAllowCreateWorkspace?: boolean +} + +export type LoginTypesReq = { + enabledEmailCodeLogin?: boolean + enableEmailPasswordLogin?: boolean + isAllowRegister?: boolean + isAllowCreateWorkspace?: boolean +} + +export type MfaBackupCodesRes = { + codes?: Array + validCounts?: number + createdAt?: string +} + +export type MfaDeleteBackupCodesRes = { + message?: string +} + +export type MfaDeleteRes = { + token?: string +} + +export type MfaDownloadBackupCodesSummaryRes = { + content?: string +} + +export type MfaEnrollReq = { + code?: string +} + +export type MfaEnrollRes = { + token?: string +} + +export type MfaGetEnrollInfoRes = { + qrCode?: string + secret?: string +} + +export type MfaModifyRes = { + message?: string +} + +export type OAuth2Config = { + clientId?: string + clientSecret?: string + authUrl?: string + tokenUrl?: string + userinfoUrl?: string + scopes?: string + enablePkce?: boolean +} + +export type OAuth2LoginReply = { + url?: string + state?: string +} + +export type OidcConfig = { + issuerUrl?: string + clientId?: string + clientSecret?: string + enablePkce?: boolean +} + +export type OidcReply = { + url?: string + state?: string +} + +export type OtelExporterEndpoint = { + endpoint?: string + compression?: string + protocol?: number + timeout?: string + headers?: { + [key: string]: string + } + tlsCaPem?: string + tlsInsecure?: boolean + tlsClientCertPem?: string + tlsClientKeyPem?: string + enabled?: boolean + tlsInsecureSkipVerify?: boolean +} + +export type OtelExporterStatusReply = { + connectedAt?: string + bytesPushed?: string + itemsInQueue?: string + logs?: string + status?: number +} + +export type PasswordPolicyConfig = { + minLength?: number + requireDigit?: boolean + requireLowercase?: boolean + requireUppercase?: boolean + requireSpecial?: boolean + forbidRepeated?: boolean + forbidSequential?: boolean + expiryEnabled?: boolean + expiryDays?: number +} + +export type PasswordStrengthReply = { + level?: number +} + +export type PasswordStrengthReq = { + password?: string +} + +export type PluginInstallationPermissionInfo = { + pluginInstallationScope?: string + restrictToMarketplaceOnly?: boolean +} + +export type PluginInstallationSettingsReply = { + pluginInstallationScope?: number + restrictToMarketplaceOnly?: boolean +} + +export type PreviewReleaseReply = { + release?: ConsoleRelease + bindings?: Array +} + +export type PreviewReleaseReq = { + appInstanceId?: string + releaseId?: string +} + +export type ReleaseRow = { + id?: string + name?: string + createdAt?: string + createdBy?: ConsoleUser + deployedTo?: Array +} + +export type ReleaseRuntimeBinding = { + kind?: string + label?: string + displayValue?: string + valueType?: string +} + +export type ResetMemberPasswordReply = { + id?: string + password?: string +} + +export type ResetMemberPasswordReq = { + id?: string +} + +export type ResetPasswordReply = { + message?: string +} + +export type ResetPasswordReq = { + currentPassword?: string + newPassword?: string + confirmPassword?: string +} + +export type ResetUserPasswordReply = { + id?: string + password?: string +} + +export type ResetUserPasswordReq = { + id?: string +} + +export type ResolveCredentialsReply = { + resolved?: Array +} + +export type ResolveCredentialsReq = { + instanceId?: string + deploymentId?: string + slots?: Array +} + +export type ResolvedCredential = { + slot?: string + credentialId?: string + envVarId?: string + value?: string +} + +export type ResourceQuota = { + used?: number + limit?: number + enabled?: boolean +} + +export type RetryEnvironmentReply = { + environment?: Environment +} + +export type RetryEnvironmentReq = { + id?: string +} + +export type RuntimeEndpoints = { + run?: string + health?: string +} + +export type RuntimeInstanceDetail = { + deploymentName?: string + replicas?: number + runtimeMode?: string + runtimeNote?: string + endpoints?: RuntimeEndpoints + bindings?: Array +} + +export type RuntimeInstanceRow = { + id?: string + environment?: ConsoleEnvironment + status?: string + currentRelease?: ConsoleRelease + detail?: RuntimeInstanceDetail +} + +export type SamlConfig = { + idpSsoUrl?: string + certificate?: string +} + +export type SamlLoginReply = { + url?: string +} + +export type SsoIdPProvider = { + protocol?: string + provider?: string + samlConfig?: SamlConfig + oidcConfig?: OidcConfig + oauth2Config?: OAuth2Config +} + +export type SsoSettings = { + ssoEnforced?: boolean + sessionTimeout?: number + ssoIdpProvider?: SsoIdPProvider +} + +export type SsoSettingsReply = { + enabled?: boolean +} + +export type ScimSettings = { + enabled?: boolean + lastSyncTime?: string +} + +export type SearchAccessSubjectsReply = { + data?: Array +} + +export type SearchForWhilteListCandidatesRes = { + subjects?: Array + currPage?: number + hasMore?: boolean +} + +export type SecretKey = { + id?: string + name?: string + secretKeyMasked?: string + createdAt?: string + lastActive?: string +} + +export type SetDefaultWorkspaceReply = { + workspaceId?: string +} + +export type SetDefaultWorkspaceReq = { + id?: string +} + +export type StatusCount = { + status?: string + count?: number +} + +export type Subject = { + subjectId?: string + subjectType?: string + accountData?: SubjectAccountData + groupData?: SubjectGroupData +} + +export type SubjectAccountData = { + id?: string + name?: string + email?: string + avatar?: string +} + +export type SubjectGroupData = { + id?: string + name?: string + groupSize?: number +} + +export type SystemUserSettingReply = { + isAllowRegister?: boolean + enableEmailPasswordLogin?: boolean +} + +export type SystemUserSettingReq = { + isAllowRegister?: boolean + enableEmailPasswordLogin?: boolean +} + +export type TestConnectionReply = { + success?: boolean + error?: string +} + +export type TestEnvironmentConnectionReply = { + ok?: boolean + reachableServerVersion?: string + namespaceExists?: boolean + missingPermissions?: Array + error?: string + probedAt?: string +} + +export type TestEnvironmentConnectionReq = { + id?: string +} + +export type ToggleEndpointRequest = { + enabled?: boolean +} + +export type UndeployRuntimeInstanceReply = { + deploymentId?: string + status?: string +} + +export type UndeployRuntimeInstanceReq = { + appInstanceId?: string + runtimeInstanceId?: string +} + +export type UpdateAccessChannelsReply = { + accessChannels?: AccessChannels +} + +export type UpdateAccessChannelsReq = { + appInstanceId?: string + enabled?: boolean +} + +export type UpdateAccessModeReq = { + appId?: string + accessMode?: string +} + +export type UpdateAccessModeRes = { + message?: string +} + +export type UpdateAppInstanceReply = { + appInstanceId?: string +} + +export type UpdateAppInstanceReq = { + appInstanceId?: string + name?: string + description?: string +} + +export type UpdateBrandingInfoReq = { + enabled?: boolean + applicationTitle?: string + loginPageLogo?: string + workspaceLogo?: string + favicon?: string +} + +export type UpdateDeveloperApiReply = { + developerApi?: DeveloperApiAccess +} + +export type UpdateDeveloperApiReq = { + appInstanceId?: string + enabled?: boolean +} + +export type UpdateEnvironmentAccessPolicyReply = { + permission?: EnvironmentAccessRow +} + +export type UpdateEnvironmentAccessPolicyReq = { + appInstanceId?: string + environmentId?: string + accessMode?: string + subjects?: Array +} + +export type UpdateEnvironmentReply = { + environment?: Environment +} + +export type UpdateEnvironmentReq = { + id?: string + name?: string + description?: string +} + +export type UpdateGroupSubjectsReq = { + groupId?: string + subjects?: Array +} + +export type UpdateGroupSubjectsRes = { + message?: string +} + +export type UpdateGroupsReq = { + groups?: Array +} + +export type UpdateGroupsReqGroup = { + id?: string + name?: string +} + +export type UpdateGroupsRes = { + groups?: Array +} + +export type UpdateJoinedGroupsReq = { + accountId?: string + groupIds?: Array +} + +export type UpdateJoinedGroupsRes = { + message?: string +} + +export type UpdateLicenseReply = { + message?: string +} + +export type UpdateLicenseReq = { + licenseId?: string +} + +export type UpdateMfaStatusReq = { + enabled?: boolean +} + +export type UpdateMfaStatusRes = { + message?: string +} + +export type UpdateMemberReply = { + account?: Account +} + +export type UpdateMemberReq = { + id?: string + name?: string + email?: string + status?: string +} + +export type UpdateMembersInGroupsReq = { + groupId?: string + accountIds?: Array +} + +export type UpdateMembersInGroupsRes = { + message?: string +} + +export type UpdateOfflineLicenseReply = { + message?: string +} + +export type UpdateOfflineLicenseReq = { + offlineCode?: string +} + +export type UpdatePluginInstallationSettingsRequest = { + pluginInstallationScope?: number + restrictToMarketplaceOnly?: boolean +} + +export type UpdateUserReply = { + account?: AccountDetail +} + +export type UpdateUserReq = { + id?: string + name?: string + email?: string + status?: string +} + +export type UpdateWebAppAuthInfoReq = { + allowSso?: boolean + allowEmailCodeLogin?: boolean + allowEmailPasswordLogin?: boolean +} + +export type UpdateWebAppAuthInfoRes = { + message?: string +} + +export type UpdateWebAppWhitelistSubjectsReq = { + appId?: string + subjects?: Array + accessMode?: string +} + +export type UpdateWebAppWhitelistSubjectsRes = { + message?: string +} + +export type UpdateWorkspacePermissionReply = { + message?: string + permission?: WorkspacePermission +} + +export type UpdateWorkspacePermissionReq = { + id?: string + permission?: WorkspacePermission +} + +export type UpdateWorkspaceReply = { + workspace?: Workspace +} + +export type UpdateWorkspaceReq = { + id?: string + name?: string + email?: string + status?: string +} + +export type WebAppAccessRow = { + environment?: ConsoleEnvironment + url?: string +} + +export type WebAppAuthInfo = { + allowSso?: boolean + allowEmailCodeLogin?: boolean + allowEmailPasswordLogin?: boolean +} + +export type WebOAuth2LoginReply = { + url?: string + state?: string +} + +export type WebOidcLoginReply = { + url?: string +} + +export type WebSamlLoginReply = { + url?: string +} + +export type Workspace = { + id?: string + name?: string + status?: string + createdAt?: string + owner?: Account +} + +export type WorkspaceInfoReply = { + WorkspaceMembers?: ResourceQuota +} + +export type WorkspacePermission = { + workspaceId?: string + allowMemberInvite?: boolean + allowOwnerTransfer?: boolean +} + +export type Pagination = { + totalCount?: number + perPage?: number + currentPage?: number + totalPages?: number +} + +export type EnterpriseAppDeployConsoleListAppInstancesData = { + body?: never + path?: never + query?: { + environmentId?: string + notDeployed?: boolean + query?: string + pageNumber?: number + resultsPerPage?: number + } + url: '/enterprise/app-instances' +} + +export type EnterpriseAppDeployConsoleListAppInstancesResponses = { + 200: ListAppInstancesReply +} + +export type EnterpriseAppDeployConsoleListAppInstancesResponse + = EnterpriseAppDeployConsoleListAppInstancesResponses[keyof EnterpriseAppDeployConsoleListAppInstancesResponses] + +export type EnterpriseAppDeployConsoleCreateAppInstanceData = { + body: CreateAppInstanceReq + path?: never + query?: never + url: '/enterprise/app-instances' +} + +export type EnterpriseAppDeployConsoleCreateAppInstanceResponses = { + 200: CreateAppInstanceReply +} + +export type EnterpriseAppDeployConsoleCreateAppInstanceResponse + = EnterpriseAppDeployConsoleCreateAppInstanceResponses[keyof EnterpriseAppDeployConsoleCreateAppInstanceResponses] + +export type EnterpriseAppDeployConsoleDeleteAppInstanceData = { + body?: never + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}' +} + +export type EnterpriseAppDeployConsoleDeleteAppInstanceResponses = { + 200: DeleteAppInstanceReply +} + +export type EnterpriseAppDeployConsoleDeleteAppInstanceResponse + = EnterpriseAppDeployConsoleDeleteAppInstanceResponses[keyof EnterpriseAppDeployConsoleDeleteAppInstanceResponses] + +export type EnterpriseAppDeployConsoleUpdateAppInstanceData = { + body: UpdateAppInstanceReq + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}' +} + +export type EnterpriseAppDeployConsoleUpdateAppInstanceResponses = { + 200: UpdateAppInstanceReply +} + +export type EnterpriseAppDeployConsoleUpdateAppInstanceResponse + = EnterpriseAppDeployConsoleUpdateAppInstanceResponses[keyof EnterpriseAppDeployConsoleUpdateAppInstanceResponses] + +export type EnterpriseAppDeployConsoleGetAppInstanceAccessData = { + body?: never + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/access' +} + +export type EnterpriseAppDeployConsoleGetAppInstanceAccessResponses = { + 200: GetAppInstanceAccessReply +} + +export type EnterpriseAppDeployConsoleGetAppInstanceAccessResponse + = EnterpriseAppDeployConsoleGetAppInstanceAccessResponses[keyof EnterpriseAppDeployConsoleGetAppInstanceAccessResponses] + +export type EnterpriseAppDeployConsoleUpdateAccessChannelsData = { + body: UpdateAccessChannelsReq + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/access-channels' +} + +export type EnterpriseAppDeployConsoleUpdateAccessChannelsResponses = { + 200: UpdateAccessChannelsReply +} + +export type EnterpriseAppDeployConsoleUpdateAccessChannelsResponse + = EnterpriseAppDeployConsoleUpdateAccessChannelsResponses[keyof EnterpriseAppDeployConsoleUpdateAccessChannelsResponses] + +export type EnterpriseAppDeployConsoleSearchAccessSubjectsData = { + body?: never + path: { + appInstanceId: string + } + query?: { + keyword?: string + subjectTypes?: Array + } + url: '/enterprise/app-instances/{appInstanceId}/access-subjects:search' +} + +export type EnterpriseAppDeployConsoleSearchAccessSubjectsResponses = { + 200: SearchAccessSubjectsReply +} + +export type EnterpriseAppDeployConsoleSearchAccessSubjectsResponse + = EnterpriseAppDeployConsoleSearchAccessSubjectsResponses[keyof EnterpriseAppDeployConsoleSearchAccessSubjectsResponses] + +export type EnterpriseAppDeployConsoleCreateDeveloperApiKeyData = { + body: CreateDeveloperApiKeyReq + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/api-keys' +} + +export type EnterpriseAppDeployConsoleCreateDeveloperApiKeyResponses = { + 200: CreateDeveloperApiKeyReply +} + +export type EnterpriseAppDeployConsoleCreateDeveloperApiKeyResponse + = EnterpriseAppDeployConsoleCreateDeveloperApiKeyResponses[keyof EnterpriseAppDeployConsoleCreateDeveloperApiKeyResponses] + +export type EnterpriseAppDeployConsoleDeleteDeveloperApiKeyData = { + body?: never + path: { + appInstanceId: string + apiKeyId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/api-keys/{apiKeyId}' +} + +export type EnterpriseAppDeployConsoleDeleteDeveloperApiKeyResponses = { + 200: DeleteDeveloperApiKeyReply +} + +export type EnterpriseAppDeployConsoleDeleteDeveloperApiKeyResponse + = EnterpriseAppDeployConsoleDeleteDeveloperApiKeyResponses[keyof EnterpriseAppDeployConsoleDeleteDeveloperApiKeyResponses] + +export type EnterpriseAppDeployConsoleListDeploymentBindingOptionsData = { + body?: never + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/deployment-binding-options' +} + +export type EnterpriseAppDeployConsoleListDeploymentBindingOptionsResponses = { + 200: ListDeploymentBindingOptionsReply +} + +export type EnterpriseAppDeployConsoleListDeploymentBindingOptionsResponse + = EnterpriseAppDeployConsoleListDeploymentBindingOptionsResponses[keyof EnterpriseAppDeployConsoleListDeploymentBindingOptionsResponses] + +export type EnterpriseAppDeployConsoleCreateDeploymentData = { + body: CreateDeploymentReq + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/deployments' +} + +export type EnterpriseAppDeployConsoleCreateDeploymentResponses = { + 200: CreateDeploymentReply +} + +export type EnterpriseAppDeployConsoleCreateDeploymentResponse + = EnterpriseAppDeployConsoleCreateDeploymentResponses[keyof EnterpriseAppDeployConsoleCreateDeploymentResponses] + +export type EnterpriseAppDeployConsoleUpdateDeveloperApiData = { + body: UpdateDeveloperApiReq + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/developer-api' +} + +export type EnterpriseAppDeployConsoleUpdateDeveloperApiResponses = { + 200: UpdateDeveloperApiReply +} + +export type EnterpriseAppDeployConsoleUpdateDeveloperApiResponse + = EnterpriseAppDeployConsoleUpdateDeveloperApiResponses[keyof EnterpriseAppDeployConsoleUpdateDeveloperApiResponses] + +export type EnterpriseAppDeployConsoleGetEnvironmentAccessPolicyData = { + body?: never + path: { + appInstanceId: string + environmentId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/environments/{environmentId}/access-policy' +} + +export type EnterpriseAppDeployConsoleGetEnvironmentAccessPolicyResponses = { + 200: GetEnvironmentAccessPolicyReply +} + +export type EnterpriseAppDeployConsoleGetEnvironmentAccessPolicyResponse + = EnterpriseAppDeployConsoleGetEnvironmentAccessPolicyResponses[keyof EnterpriseAppDeployConsoleGetEnvironmentAccessPolicyResponses] + +export type EnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyData = { + body: UpdateEnvironmentAccessPolicyReq + path: { + appInstanceId: string + environmentId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/environments/{environmentId}/access-policy' +} + +export type EnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyResponses = { + 200: UpdateEnvironmentAccessPolicyReply +} + +export type EnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyResponse + = EnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyResponses[keyof EnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyResponses] + +export type EnterpriseAppDeployConsoleGetAppInstanceOverviewData = { + body?: never + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/overview' +} + +export type EnterpriseAppDeployConsoleGetAppInstanceOverviewResponses = { + 200: GetAppInstanceOverviewReply +} + +export type EnterpriseAppDeployConsoleGetAppInstanceOverviewResponse + = EnterpriseAppDeployConsoleGetAppInstanceOverviewResponses[keyof EnterpriseAppDeployConsoleGetAppInstanceOverviewResponses] + +export type EnterpriseAppDeployConsoleListReleasesData = { + body?: never + path: { + appInstanceId: string + } + query?: { + pageNumber?: number + resultsPerPage?: number + } + url: '/enterprise/app-instances/{appInstanceId}/releases' +} + +export type EnterpriseAppDeployConsoleListReleasesResponses = { + 200: ListReleasesReply +} + +export type EnterpriseAppDeployConsoleListReleasesResponse + = EnterpriseAppDeployConsoleListReleasesResponses[keyof EnterpriseAppDeployConsoleListReleasesResponses] + +export type EnterpriseAppDeployConsoleCreateReleaseData = { + body: CreateReleaseReq + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/releases' +} + +export type EnterpriseAppDeployConsoleCreateReleaseResponses = { + 200: CreateReleaseReply +} + +export type EnterpriseAppDeployConsoleCreateReleaseResponse + = EnterpriseAppDeployConsoleCreateReleaseResponses[keyof EnterpriseAppDeployConsoleCreateReleaseResponses] + +export type EnterpriseAppDeployConsolePreviewReleaseData = { + body: PreviewReleaseReq + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/releases:preview' +} + +export type EnterpriseAppDeployConsolePreviewReleaseResponses = { + 200: PreviewReleaseReply +} + +export type EnterpriseAppDeployConsolePreviewReleaseResponse + = EnterpriseAppDeployConsolePreviewReleaseResponses[keyof EnterpriseAppDeployConsolePreviewReleaseResponses] + +export type EnterpriseAppDeployConsoleListRuntimeInstancesData = { + body?: never + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/runtime-instances' +} + +export type EnterpriseAppDeployConsoleListRuntimeInstancesResponses = { + 200: ListRuntimeInstancesReply +} + +export type EnterpriseAppDeployConsoleListRuntimeInstancesResponse + = EnterpriseAppDeployConsoleListRuntimeInstancesResponses[keyof EnterpriseAppDeployConsoleListRuntimeInstancesResponses] + +export type EnterpriseAppDeployConsoleCancelRuntimeDeploymentData = { + body: CancelRuntimeDeploymentReq + path: { + appInstanceId: string + runtimeInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/runtime-instances/{runtimeInstanceId}/deployment:cancel' +} + +export type EnterpriseAppDeployConsoleCancelRuntimeDeploymentResponses = { + 200: CancelRuntimeDeploymentReply +} + +export type EnterpriseAppDeployConsoleCancelRuntimeDeploymentResponse + = EnterpriseAppDeployConsoleCancelRuntimeDeploymentResponses[keyof EnterpriseAppDeployConsoleCancelRuntimeDeploymentResponses] + +export type EnterpriseAppDeployConsoleUndeployRuntimeInstanceData = { + body: UndeployRuntimeInstanceReq + path: { + appInstanceId: string + runtimeInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/runtime-instances/{runtimeInstanceId}:undeploy' +} + +export type EnterpriseAppDeployConsoleUndeployRuntimeInstanceResponses = { + 200: UndeployRuntimeInstanceReply +} + +export type EnterpriseAppDeployConsoleUndeployRuntimeInstanceResponse + = EnterpriseAppDeployConsoleUndeployRuntimeInstanceResponses[keyof EnterpriseAppDeployConsoleUndeployRuntimeInstanceResponses] + +export type EnterpriseAppDeployConsoleGetAppInstanceSettingsData = { + body?: never + path: { + appInstanceId: string + } + query?: never + url: '/enterprise/app-instances/{appInstanceId}/settings' +} + +export type EnterpriseAppDeployConsoleGetAppInstanceSettingsResponses = { + 200: GetAppInstanceSettingsReply +} + +export type EnterpriseAppDeployConsoleGetAppInstanceSettingsResponse + = EnterpriseAppDeployConsoleGetAppInstanceSettingsResponses[keyof EnterpriseAppDeployConsoleGetAppInstanceSettingsResponses] + +export type EnterpriseAppDeployConsoleListDeploymentEnvironmentOptionsData = { + body?: never + path?: never + query?: never + url: '/enterprise/deployment-environment-options' +} + +export type EnterpriseAppDeployConsoleListDeploymentEnvironmentOptionsResponses = { + 200: ListDeploymentEnvironmentOptionsReply +} + +export type EnterpriseAppDeployConsoleListDeploymentEnvironmentOptionsResponse + = EnterpriseAppDeployConsoleListDeploymentEnvironmentOptionsResponses[keyof EnterpriseAppDeployConsoleListDeploymentEnvironmentOptionsResponses] + +export type ConsoleSsoOAuth2LoginData = { + body?: never + path?: never + query?: never + url: '/enterprise/sso/oauth2/login' +} + +export type ConsoleSsoOAuth2LoginResponses = { + 200: OAuth2LoginReply +} + +export type ConsoleSsoOAuth2LoginResponse + = ConsoleSsoOAuth2LoginResponses[keyof ConsoleSsoOAuth2LoginResponses] + +export type ConsoleSsoOidcLoginData = { + body?: never + path?: never + query?: never + url: '/enterprise/sso/oidc/login' +} + +export type ConsoleSsoOidcLoginResponses = { + 200: OidcReply +} + +export type ConsoleSsoOidcLoginResponse + = ConsoleSsoOidcLoginResponses[keyof ConsoleSsoOidcLoginResponses] + +export type ConsoleSsoSamlLoginData = { + body?: never + path?: never + query?: never + url: '/enterprise/sso/saml/login' +} + +export type ConsoleSsoSamlLoginResponses = { + 200: SamlLoginReply +} + +export type ConsoleSsoSamlLoginResponse + = ConsoleSsoSamlLoginResponses[keyof ConsoleSsoSamlLoginResponses] + +export type WebAppAuthGetWebAppAccessModeData = { + body?: never + path?: never + query?: { + appId?: string + } + url: '/enterprise/webapp/app/access-mode' +} + +export type WebAppAuthGetWebAppAccessModeResponses = { + 200: GetWebAppAccessModeRes +} + +export type WebAppAuthGetWebAppAccessModeResponse + = WebAppAuthGetWebAppAccessModeResponses[keyof WebAppAuthGetWebAppAccessModeResponses] + +export type WebAppAuthUpdateWebAppWhitelistSubjectsData = { + body: UpdateWebAppWhitelistSubjectsReq + path?: never + query?: never + url: '/enterprise/webapp/app/access-mode' +} + +export type WebAppAuthUpdateWebAppWhitelistSubjectsResponses = { + 200: UpdateWebAppWhitelistSubjectsRes +} + +export type WebAppAuthUpdateWebAppWhitelistSubjectsResponse + = WebAppAuthUpdateWebAppWhitelistSubjectsResponses[keyof WebAppAuthUpdateWebAppWhitelistSubjectsResponses] + +export type WebAppAuthSearchForWhilteListCandidatesData = { + body?: never + path?: never + query?: { + keyword?: string + pageNumber?: number + resultsPerPage?: number + groupId?: string + } + url: '/enterprise/webapp/app/subject/search' +} + +export type WebAppAuthSearchForWhilteListCandidatesResponses = { + 200: SearchForWhilteListCandidatesRes +} + +export type WebAppAuthSearchForWhilteListCandidatesResponse + = WebAppAuthSearchForWhilteListCandidatesResponses[keyof WebAppAuthSearchForWhilteListCandidatesResponses] + +export type WebAppAuthGetWebAppWhitelistSubjectsData = { + body?: never + path?: never + query?: { + appId?: string + } + url: '/enterprise/webapp/app/subjects' +} + +export type WebAppAuthGetWebAppWhitelistSubjectsResponses = { + 200: GetWebAppWhitelistSubjectsRes +} + +export type WebAppAuthGetWebAppWhitelistSubjectsResponse + = WebAppAuthGetWebAppWhitelistSubjectsResponses[keyof WebAppAuthGetWebAppWhitelistSubjectsResponses] + +export type WebAppAuthGetGroupSubjectsData = { + body?: never + path?: never + query?: { + groupId?: string + } + url: '/enterprise/webapp/group/subjects' +} + +export type WebAppAuthGetGroupSubjectsResponses = { + 200: GetGroupSubjectsRes +} + +export type WebAppAuthGetGroupSubjectsResponse + = WebAppAuthGetGroupSubjectsResponses[keyof WebAppAuthGetGroupSubjectsResponses] + +export type WebAppAuthIsUserAllowedToAccessWebAppData = { + body?: never + path?: never + query?: { + appId?: string + } + url: '/enterprise/webapp/permission' +} + +export type WebAppAuthIsUserAllowedToAccessWebAppResponses = { + 200: IsUserAllowedToAccessWebAppRes +} + +export type WebAppAuthIsUserAllowedToAccessWebAppResponse + = WebAppAuthIsUserAllowedToAccessWebAppResponses[keyof WebAppAuthIsUserAllowedToAccessWebAppResponses] diff --git a/packages/contracts/generated/enterprise/zod.gen.ts b/packages/contracts/generated/enterprise/zod.gen.ts new file mode 100644 index 0000000000..1e7e3d44ae --- /dev/null +++ b/packages/contracts/generated/enterprise/zod.gen.ts @@ -0,0 +1,1952 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +export const zAccessModeOption = z.object({ + mode: z.string().optional(), + label: z.string().optional(), + disabled: z.boolean().optional(), + selected: z.boolean().optional(), +}) + +export const zAccessStatus = z.object({ + accessChannelsEnabled: z.boolean().optional(), + webappUrl: z.string().optional(), + cliUrl: z.string().optional(), + developerApiEnabled: z.boolean().optional(), + apiKeyCount: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), +}) + +export const zAccessSubject = z.object({ + subjectId: z.string().optional(), + subjectType: z.string().optional(), +}) + +export const zAccessSubjectDisplay = z.object({ + id: z.string().optional(), + subjectType: z.string().optional(), + name: z.string().optional(), + avatarUrl: z.string().optional(), + memberCount: z.string().optional(), +}) + +export const zAccessPolicyDetail = z.object({ + accessMode: z.string().optional(), + subjects: z.array(zAccessSubjectDisplay).optional(), + options: z.array(zAccessModeOption).optional(), +}) + +/** + * Account represents a basic user account + */ +export const zAccount = z.object({ + id: z.string().optional(), + email: z.string().optional(), + name: z.string().optional(), +}) + +export const zAccountDetailGroup = z.object({ + id: z.string().optional(), + name: z.string().optional(), +}) + +/** + * AccountInWorkspace represents account's role in a workspace + */ +export const zAccountInWorkspace = z.object({ + workspaceId: z.string().optional(), + workspaceName: z.string().optional(), + role: z.string().optional(), +}) + +/** + * AccountDetail contains detailed account information + */ +export const zAccountDetail = z.object({ + account: zAccount.optional(), + status: z.string().optional(), + createdAt: z.iso.datetime().optional(), + lastActiveAt: z.iso.datetime().optional(), + workspaces: z.array(zAccountInWorkspace).optional(), + groups: z.array(zAccountDetailGroup).optional(), +}) + +export const zAckDeploymentReply = z.object({ + accepted: z.boolean().optional(), + newVersion: z.string().optional(), +}) + +export const zAppInstanceBasicInfo = z.object({ + id: z.string().optional(), + name: z.string().optional(), + description: z.string().optional(), + sourceAppId: z.string().optional(), + sourceAppName: z.string().optional(), + mode: z.string().optional(), + createdAt: z.iso.datetime().optional(), +}) + +export const zAppRunnerBootstrapAssignment = z.object({ + appId: z.string().optional(), + environmentId: z.string().optional(), + workflowId: z.string().optional(), + instanceId: z.string().optional(), + workspaceId: z.string().optional(), + instanceVersion: z.string().optional(), + bindingSnapshotVersion: z.string().optional(), + executionTokenVersion: z.string().optional(), + executionToken: z.string().optional(), + releaseId: z.string().optional(), +}) + +export const zAppRunnerBootstrapReply = z.object({ + runnerId: z.string().optional(), + assignmentRevision: z.string().optional(), + assignments: z.array(zAppRunnerBootstrapAssignment).optional(), +}) + +export const zAppRunnerRunnerInfo = z.object({ + hostname: z.string().optional(), +}) + +export const zAppRunnerBootstrapRequest = z.object({ + runner: zAppRunnerRunnerInfo.optional(), +}) + +export const zAppRunnerRuntimeArtifactReply = z.object({ + dslYaml: z.string().optional(), + bindingSnapshotVersion: z.string().optional(), + bindingSnapshot: z.record(z.string(), z.unknown()).optional(), +}) + +export const zAppRunnerRuntimeArtifactRequest = z.object({ + instanceId: z.string().optional(), + releaseId: z.string().optional(), + bindingSnapshotVersion: z.string().optional(), +}) + +export const zAppRunnerBatchRuntimeArtifactRequest = z.object({ + artifacts: z.array(zAppRunnerRuntimeArtifactRequest).optional(), +}) + +export const zAppRunnerRuntimeArtifactResult = z.object({ + instanceId: z.string().optional(), + releaseId: z.string().optional(), + artifact: zAppRunnerRuntimeArtifactReply.optional(), + errorCode: z.string().optional(), + errorMessage: z.string().optional(), +}) + +export const zAppRunnerBatchRuntimeArtifactReply = z.object({ + results: z.array(zAppRunnerRuntimeArtifactResult).optional(), +}) + +export const zAppRunnerTokenExchangeReply = z.object({ + accessToken: z.string().optional(), + expiresAt: z.iso.datetime().optional(), +}) + +export const zAppRunnerTokenExchangeRequest = z.object({ + joinToken: z.string().optional(), +}) + +/** + * BootstrapProgress is step-list-agnostic. Reconcilers emit step names as + * strings owned by each executor (e.g. "connectivity", "namespace"), so adding + * or removing steps does not break the API. + */ +export const zBootstrapProgress = z.object({ + currentStep: z.string().optional(), + completedSteps: z.array(z.string()).optional(), + attemptCount: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + lastAttemptAt: z.iso.datetime().optional(), + lastErrorCode: z.string().optional(), + lastErrorMessage: z.string().optional(), +}) + +export const zBrandingInfo = z.object({ + enabled: z.boolean().optional(), + applicationTitle: z.string().optional(), + loginPageLogo: z.string().optional(), + workspaceLogo: z.string().optional(), + favicon: z.string().optional(), +}) + +export const zCancelRuntimeDeploymentReply = z.object({ + status: z.string().optional(), +}) + +export const zCancelRuntimeDeploymentReq = z.object({ + appInstanceId: z.string().optional(), + runtimeInstanceId: z.string().optional(), +}) + +export const zCheckPasswordStatusReply = z.object({ + requirePasswordChange: z.boolean().optional(), + changeReason: z.int().optional(), + daysToExpire: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + message: z.string().optional(), +}) + +export const zClearDefaultWorkspaceReply = z.record(z.string(), z.unknown()) + +export const zCliAccess = z.object({ + url: z.string().optional(), +}) + +export const zConsoleEnvironment = z.object({ + id: z.string().optional(), + name: z.string().optional(), + runtime: z.string().optional(), + type: z.string().optional(), + status: z.string().optional(), +}) + +export const zConsoleRelease = z.object({ + id: z.string().optional(), + name: z.string().optional(), + shortCommitId: z.string().optional(), + createdAt: z.iso.datetime().optional(), +}) + +export const zConsoleUser = z.object({ + id: z.string().optional(), + name: z.string().optional(), +}) + +export const zCreateAppInstanceReply = z.object({ + appInstanceId: z.string().optional(), + initialRelease: zConsoleRelease.optional(), +}) + +export const zCreateAppInstanceReq = z.object({ + sourceAppId: z.string().optional(), + name: z.string().optional(), + description: z.string().optional(), +}) + +export const zCreateBearerTokenResponse = z.object({ + token: z.string().optional(), +}) + +export const zCreateDeploymentReply = z.object({ + runtimeInstanceId: z.string().optional(), + deploymentId: z.string().optional(), + status: z.string().optional(), +}) + +export const zCreateDeveloperApiKeyReq = z.object({ + appInstanceId: z.string().optional(), + environmentId: z.string().optional(), + name: z.string().optional(), +}) + +export const zCreateMemberReply = z.object({ + id: z.string().optional(), + password: z.string().optional(), +}) + +/** + * Create member messages + */ +export const zCreateMemberReq = z.object({ + name: z.string().optional(), + email: z.string().optional(), + status: z.string().optional(), +}) + +export const zCreateNewGroupsReqGroup = z.object({ + name: z.string().optional(), +}) + +export const zCreateNewGroupsReq = z.object({ + groups: z.array(zCreateNewGroupsReqGroup).optional(), +}) + +export const zCreateReleaseReply = z.object({ + release: zConsoleRelease.optional(), +}) + +export const zCreateReleaseReq = z.object({ + appInstanceId: z.string().optional(), + name: z.string().optional(), + description: z.string().optional(), +}) + +export const zCreateSecretKeyReply = z.object({ + id: z.string().optional(), + name: z.string().optional(), + secretKey: z.string().optional(), + createdAt: z.iso.datetime().optional(), + lastActive: z.iso.datetime().optional(), +}) + +export const zCreateSecretKeyReq = z.object({ + name: z.string().optional(), +}) + +export const zCreateUserReply = z.object({ + id: z.string().optional(), + password: z.string().optional(), +}) + +export const zCreateUserReq = z.object({ + name: z.string().optional(), + email: z.string().optional(), + status: z.string().optional(), +}) + +/** + * Create workspace messages + */ +export const zCreateWorkspaceReq = z.object({ + name: z.string().optional(), + email: z.string().optional(), + status: z.string().optional(), +}) + +export const zCurrentUserReply = z.object({ + id: z.string().optional(), + name: z.string().optional(), + email: z.string().optional(), + interfaceLanguage: z.string().optional(), + timezone: z.string().optional(), +}) + +export const zDashboardSsooidcLoginReply = z.object({ + url: z.string().optional(), + state: z.string().optional(), +}) + +export const zDashboardSsoOauth2LoginReply = z.object({ + url: z.string().optional(), + state: z.string().optional(), +}) + +/** + * Dashboard SSO Login messages + */ +export const zDashboardSsosamlLoginReply = z.object({ + url: z.string().optional(), +}) + +export const zDeleteAppInstanceReply = z.record(z.string(), z.unknown()) + +export const zDeleteDeveloperApiKeyReply = z.record(z.string(), z.unknown()) + +export const zDeleteEnvironmentReply = z.record(z.string(), z.unknown()) + +export const zDeleteGroupsRes = z.object({ + message: z.string().optional(), +}) + +export const zDeleteGuard = z.object({ + canDelete: z.boolean().optional(), + disabledReason: z.string().optional(), +}) + +export const zDeleteMemberReply = z.object({ + account: zAccount.optional(), +}) + +export const zDeleteSecretKeyReply = z.object({ + message: z.string().optional(), +}) + +export const zDeleteUserReply = z.object({ + account: zAccount.optional(), +}) + +export const zDeleteWorkspaceReply = z.record(z.string(), z.unknown()) + +export const zDeployedEnvironment = z.object({ + environmentId: z.string().optional(), + environmentName: z.string().optional(), +}) + +export const zDeploymentCredentialOption = z.object({ + credentialId: z.string().optional(), + displayName: z.string().optional(), + pluginId: z.string().optional(), + pluginName: z.string().optional(), + pluginVersion: z.string().optional(), +}) + +export const zDeploymentEnvVarOption = z.object({ + envVarId: z.string().optional(), + name: z.string().optional(), + valueType: z.string().optional(), + displayValue: z.string().optional(), +}) + +export const zDeploymentBindingOptionSlot = z.object({ + slot: z.string().optional(), + kind: z.string().optional(), + label: z.string().optional(), + required: z.boolean().optional(), + candidates: z.array(zDeploymentCredentialOption).optional(), + envVarCandidates: z.array(zDeploymentEnvVarOption).optional(), +}) + +export const zDeploymentEnvironmentOption = z.object({ + id: z.string().optional(), + name: z.string().optional(), + type: z.string().optional(), + backend: z.string().optional(), + status: z.string().optional(), + managedBy: z.string().optional(), + deployable: z.boolean().optional(), + disabledReason: z.string().optional(), +}) + +export const zDeploymentRuntimeBinding = z.object({ + slot: z.string().optional(), + credentialId: z.string().optional(), + envVarId: z.string().optional(), +}) + +export const zCreateDeploymentReq = z.object({ + appInstanceId: z.string().optional(), + environmentId: z.string().optional(), + releaseId: z.string().optional(), + bindings: z.array(zDeploymentRuntimeBinding).optional(), +}) + +export const zDeploymentStatusRow = z.object({ + environment: zConsoleEnvironment.optional(), + release: zConsoleRelease.optional(), + status: z.string().optional(), +}) + +export const zDeveloperApiKeyRow = z.object({ + id: z.string().optional(), + name: z.string().optional(), + environment: zConsoleEnvironment.optional(), + maskedKey: z.string().optional(), +}) + +export const zCreateDeveloperApiKeyReply = z.object({ + apiKey: zDeveloperApiKeyRow.optional(), + token: z.string().optional(), +}) + +export const zDeveloperApiAccess = z.object({ + enabled: z.boolean().optional(), + apiKeys: z.array(zDeveloperApiKeyRow).optional(), +}) + +/** + * System user setting messages + */ +export const zEnterpriseSystemUserSettingReply = z.object({ + ssoEnforcedForSignin: z.boolean().optional(), + ssoEnforcedForSigninProtocol: z.string().optional(), + enableEmailPasswordLogin: z.boolean().optional(), +}) + +export const zEnvironment = z.object({ + id: z.string().optional(), + name: z.string().optional(), + description: z.string().optional(), + mode: z.int().optional(), + namespace: z.string().optional(), + apiServer: z.string().optional(), + status: z.int().optional(), + statusMessage: z.string().optional(), + bootstrapProgress: zBootstrapProgress.optional(), + managedBy: z.string().optional(), + createdAt: z.iso.datetime().optional(), + updatedAt: z.iso.datetime().optional(), + backend: z.int().optional(), + host: z.string().optional(), +}) + +export const zCreateEnvironmentReply = z.object({ + environment: zEnvironment.optional(), +}) + +export const zEnvironmentAccessRow = z.object({ + environment: zConsoleEnvironment.optional(), + currentRelease: zConsoleRelease.optional(), + accessMode: z.string().optional(), + accessModeLabel: z.string().optional(), + hint: z.string().optional(), +}) + +export const zEnvironmentFilter = z.object({ + id: z.string().optional(), + name: z.string().optional(), + kind: z.string().optional(), +}) + +export const zGetAppInstanceOverviewReply = z.object({ + instance: zAppInstanceBasicInfo.optional(), + deployments: z.array(zDeploymentStatusRow).optional(), + access: zAccessStatus.optional(), +}) + +export const zGetAppInstanceSettingsReply = z.object({ + name: z.string().optional(), + description: z.string().optional(), + deleteGuard: zDeleteGuard.optional(), +}) + +export const zGetBearerTokenResponse = z.object({ + maskedToken: z.string().optional(), +}) + +export const zGetClusterInfoReply = z.object({ + mode: z.string().optional(), + clusterId: z.string().optional(), + verifyMode: z.string().optional(), +}) + +export const zGetEnvironmentAccessPolicyReply = z.object({ + policy: zAccessPolicyDetail.optional(), +}) + +export const zGetEnvironmentReply = z.object({ + environment: zEnvironment.optional(), +}) + +export const zGetInstanceReply = z.object({ + instanceId: z.string().optional(), + status: z.string().optional(), + desiredReleaseId: z.string().optional(), + observedReleaseId: z.string().optional(), + currentDeploymentId: z.string().optional(), + version: z.string().optional(), +}) + +export const zGetLicenseStatusReply = z.object({ + status: z.string().optional(), +}) + +export const zGetMfaInfoReply = z.object({ + userEnabled: z.boolean().optional(), + userSetup: z.boolean().optional(), + globalEnabled: z.boolean().optional(), +}) + +export const zGetMemberReply = z.object({ + account: zAccountDetail.optional(), +}) + +export const zGetUserReply = z.object({ + account: zAccountDetail.optional(), +}) + +export const zGetWebAppAccessModeRes = z.object({ + accessMode: z.string().optional(), +}) + +export const zGetWebAppAuthInfoRes = z.object({ + allowSso: z.boolean().optional(), + allowEmailCodeLogin: z.boolean().optional(), + allowEmailPasswordLogin: z.boolean().optional(), +}) + +export const zGetWebAppWhitelistSubjectsResMember = z.object({ + id: z.string().optional(), + name: z.string().optional(), + email: z.string().optional(), + avatar: z.string().optional(), +}) + +export const zHealthzReply = z.object({ + message: z.string().optional(), + status: z.string().optional(), +}) + +export const zHostEnvironmentConfig = z.object({ + machineId: z.string().optional(), + joinTokenHash: z.string().optional(), +}) + +export const zInnerBatchGetWebAppAccessModesByIdReq = z.object({ + appIds: z.array(z.string()).optional(), +}) + +export const zInnerBatchGetWebAppAccessModesByIdRes = z.object({ + accessModes: z.record(z.string(), z.string()).optional(), +}) + +export const zInnerBatchIsUserAllowedToAccessWebAppReq = z.object({ + userId: z.string().optional(), + appIds: z.array(z.string()).optional(), +}) + +export const zInnerBatchIsUserAllowedToAccessWebAppRes = z.object({ + permissions: z.record(z.string(), z.boolean()).optional(), +}) + +export const zInnerCheckAppDeployAccessReply = z.object({ + allowed: z.boolean().optional(), + matchedPolicyId: z.string().optional(), + matchedScopeType: z.string().optional(), + reason: z.string().optional(), + cacheTtlSeconds: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), +}) + +export const zInnerCheckAppDeployAccessReq = z.object({ + appInstanceId: z.string().optional(), + environmentId: z.string().optional(), + principalType: z.string().optional(), + principalId: z.string().optional(), +}) + +export const zInnerCleanAppRes = z.object({ + message: z.string().optional(), +}) + +export const zInnerGetTokenRouteReply = z.object({ + environmentId: z.string().optional(), + namespace: z.string().optional(), + serviceName: z.string().optional(), + servicePort: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + environmentStatus: z.string().optional(), + appId: z.string().optional(), + tenantId: z.string().optional(), + instanceId: z.string().optional(), + observedReleaseId: z.string().optional(), + instanceStatus: z.string().optional(), +}) + +export const zInnerGetTokenRouteReq = z.object({ + token: z.string().optional(), +}) + +export const zInnerGetWebAppAccessModeByCodeRes = z.object({ + accessMode: z.string().optional(), +}) + +export const zInnerGetWebAppAccessModeByIdRes = z.object({ + accessMode: z.string().optional(), +}) + +export const zInnerIsUserAllowedToAccessWebAppRes = z.object({ + result: z.boolean().optional(), +}) + +export const zInnerTryAddAccountToDefaultWorkspaceReply = z.object({ + workspaceId: z.string().optional(), + joined: z.boolean().optional(), + message: z.string().optional(), +}) + +/** + * Inner API messages + */ +export const zInnerTryAddAccountToDefaultWorkspaceReq = z.object({ + accountId: z.string().optional(), +}) + +export const zIsUserAllowedToAccessWebAppRes = z.object({ + result: z.boolean().optional(), +}) + +export const zJoinWorkspaceReply = z.object({ + message: z.string().optional(), +}) + +/** + * Join workspace messages + */ +export const zJoinWorkspaceReq = z.object({ + id: z.string().optional(), + email: z.string().optional(), + role: z.string().optional(), +}) + +export const zK8sEnvironmentConfig = z.object({ + namespace: z.string().optional(), + apiServer: z.string().optional(), + caBundle: z.string().optional(), + bearerToken: z.string().optional(), +}) + +/** + * Field-level validation only; target (api_server) and RBAC validation happen + * in the bootstrap reconciler. + */ +export const zCreateEnvironmentReq = z.object({ + name: z.string().optional(), + description: z.string().optional(), + mode: z.int().optional(), + backend: z.int().optional(), + k8s: zK8sEnvironmentConfig.optional(), + host: zHostEnvironmentConfig.optional(), +}) + +export const zLastError = z.object({ + phase: z.string().optional(), + code: z.string().optional(), + message: z.string().optional(), + releaseId: z.string().optional(), +}) + +export const zAckDeploymentReq = z.object({ + deploymentId: z.string().optional(), + instanceId: z.string().optional(), + expectedVersion: z.string().optional(), + status: z.string().optional(), + observedReleaseId: z.string().optional(), + lastError: zLastError.optional(), +}) + +export const zListDeploymentBindingOptionsReply = z.object({ + slots: z.array(zDeploymentBindingOptionSlot).optional(), +}) + +export const zListDeploymentEnvironmentOptionsReply = z.object({ + environments: z.array(zDeploymentEnvironmentOption).optional(), +}) + +export const zLoginTypesReply = z.object({ + enabledEmailCodeLogin: z.boolean().optional(), + enableEmailPasswordLogin: z.boolean().optional(), + isAllowRegister: z.boolean().optional(), + isAllowCreateWorkspace: z.boolean().optional(), +}) + +export const zLoginTypesReq = z.object({ + enabledEmailCodeLogin: z.boolean().optional(), + enableEmailPasswordLogin: z.boolean().optional(), + isAllowRegister: z.boolean().optional(), + isAllowCreateWorkspace: z.boolean().optional(), +}) + +export const zMfaBackupCodesRes = z.object({ + codes: z.array(z.string()).optional(), + validCounts: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + createdAt: z.iso.datetime().optional(), +}) + +export const zMfaDeleteBackupCodesRes = z.object({ + message: z.string().optional(), +}) + +export const zMfaDeleteRes = z.object({ + token: z.string().optional(), +}) + +export const zMfaDownloadBackupCodesSummaryRes = z.object({ + content: z.string().optional(), +}) + +export const zMfaEnrollReq = z.object({ + code: z.string().optional(), +}) + +export const zMfaEnrollRes = z.object({ + token: z.string().optional(), +}) + +export const zMfaGetEnrollInfoRes = z.object({ + qrCode: z.string().optional(), + secret: z.string().optional(), +}) + +export const zMfaModifyRes = z.object({ + message: z.string().optional(), +}) + +export const zOAuth2Config = z.object({ + clientId: z.string().optional(), + clientSecret: z.string().optional(), + authUrl: z.string().optional(), + tokenUrl: z.string().optional(), + userinfoUrl: z.string().optional(), + scopes: z.string().optional(), + enablePkce: z.boolean().optional(), +}) + +export const zOAuth2LoginReply = z.object({ + url: z.string().optional(), + state: z.string().optional(), +}) + +export const zOidcConfig = z.object({ + issuerUrl: z.string().optional(), + clientId: z.string().optional(), + clientSecret: z.string().optional(), + enablePkce: z.boolean().optional(), +}) + +export const zOidcReply = z.object({ + url: z.string().optional(), + state: z.string().optional(), +}) + +export const zOtelExporterEndpoint = z.object({ + endpoint: z.string().optional(), + compression: z.string().optional(), + protocol: z.int().optional(), + timeout: z + .string() + .regex(/^-?(?:0|[1-9]\d{0,11})(?:\.\d{1,9})?s$/) + .optional(), + headers: z.record(z.string(), z.string()).optional(), + tlsCaPem: z.string().optional(), + tlsInsecure: z.boolean().optional(), + tlsClientCertPem: z.string().optional(), + tlsClientKeyPem: z.string().optional(), + enabled: z.boolean().optional(), + tlsInsecureSkipVerify: z.boolean().optional(), +}) + +export const zEndpointReply = z.object({ + mode: z.int().optional(), + metricsEndpoint: zOtelExporterEndpoint.optional(), + tracesEndpoint: zOtelExporterEndpoint.optional(), +}) + +export const zOtelExporterStatusReply = z.object({ + connectedAt: z.iso.datetime().optional(), + bytesPushed: z.string().optional(), + itemsInQueue: z.string().optional(), + logs: z.string().optional(), + status: z.int().optional(), +}) + +export const zPasswordPolicyConfig = z.object({ + minLength: z + .int() + .min(0, { error: 'Invalid value: Expected uint32 to be >= 0' }) + .max(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + .optional(), + requireDigit: z.boolean().optional(), + requireLowercase: z.boolean().optional(), + requireUppercase: z.boolean().optional(), + requireSpecial: z.boolean().optional(), + forbidRepeated: z.boolean().optional(), + forbidSequential: z.boolean().optional(), + expiryEnabled: z.boolean().optional(), + expiryDays: z + .int() + .min(0, { error: 'Invalid value: Expected uint32 to be >= 0' }) + .max(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + .optional(), +}) + +export const zPasswordStrengthReply = z.object({ + level: z.int().optional(), +}) + +export const zPasswordStrengthReq = z.object({ + password: z.string().optional(), +}) + +export const zPluginInstallationPermissionInfo = z.object({ + pluginInstallationScope: z.string().optional(), + restrictToMarketplaceOnly: z.boolean().optional(), +}) + +export const zPluginInstallationSettingsReply = z.object({ + pluginInstallationScope: z.int().optional(), + restrictToMarketplaceOnly: z.boolean().optional(), +}) + +export const zPreviewReleaseReq = z.object({ + appInstanceId: z.string().optional(), + releaseId: z.string().optional(), +}) + +export const zReleaseRow = z.object({ + id: z.string().optional(), + name: z.string().optional(), + createdAt: z.iso.datetime().optional(), + createdBy: zConsoleUser.optional(), + deployedTo: z.array(zDeployedEnvironment).optional(), +}) + +export const zReleaseRuntimeBinding = z.object({ + kind: z.string().optional(), + label: z.string().optional(), + displayValue: z.string().optional(), + valueType: z.string().optional(), +}) + +export const zPreviewReleaseReply = z.object({ + release: zConsoleRelease.optional(), + bindings: z.array(zReleaseRuntimeBinding).optional(), +}) + +export const zResetMemberPasswordReply = z.object({ + id: z.string().optional(), + password: z.string().optional(), +}) + +/** + * Reset member password messages + */ +export const zResetMemberPasswordReq = z.object({ + id: z.string().optional(), +}) + +export const zResetPasswordReply = z.object({ + message: z.string().optional(), +}) + +/** + * Password reset messages + */ +export const zResetPasswordReq = z.object({ + currentPassword: z.string().optional(), + newPassword: z.string().optional(), + confirmPassword: z.string().optional(), +}) + +export const zResetUserPasswordReply = z.object({ + id: z.string().optional(), + password: z.string().optional(), +}) + +export const zResetUserPasswordReq = z.object({ + id: z.string().optional(), +}) + +export const zResolveCredentialsReq = z.object({ + instanceId: z.string().optional(), + deploymentId: z.string().optional(), + slots: z.array(z.string()).optional(), +}) + +/** + * Exactly one of credential_id / env_var_id is populated; model/plugin slots + * carry credential_id (pool A), env_var slots carry env_var_id (pool B). + * See design §4.1. + */ +export const zResolvedCredential = z.object({ + slot: z.string().optional(), + credentialId: z.string().optional(), + envVarId: z.string().optional(), + value: z.string().optional(), +}) + +export const zResolveCredentialsReply = z.object({ + resolved: z.array(zResolvedCredential).optional(), +}) + +/** + * ResourceQuota represents usage quota for a resource + */ +export const zResourceQuota = z.object({ + used: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + limit: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + enabled: z.boolean().optional(), +}) + +export const zLicenseStatus = z.object({ + status: z.string().optional(), + expiredAt: z.string().optional(), + workspaces: zResourceQuota.optional(), +}) + +export const zLimitFields = z.object({ + workspaceMembers: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + workspaces: zResourceQuota.optional(), +}) + +/** + * License information + */ +export const zLicenseInfo = z.object({ + uuid: z.string().optional(), + expiredAt: z.iso.datetime().optional(), + clusterId: z.string().optional(), + product: z.string().optional(), + limits: zLimitFields.optional(), +}) + +/** + * License RPC messages + */ +export const zGetLicenseReply = z.object({ + license: zLicenseInfo.optional(), +}) + +export const zRetryEnvironmentReply = z.object({ + environment: zEnvironment.optional(), +}) + +export const zRetryEnvironmentReq = z.object({ + id: z.string().optional(), +}) + +export const zRuntimeEndpoints = z.object({ + run: z.string().optional(), + health: z.string().optional(), +}) + +export const zRuntimeInstanceDetail = z.object({ + deploymentName: z.string().optional(), + replicas: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + runtimeMode: z.string().optional(), + runtimeNote: z.string().optional(), + endpoints: zRuntimeEndpoints.optional(), + bindings: z.array(zReleaseRuntimeBinding).optional(), +}) + +export const zRuntimeInstanceRow = z.object({ + id: z.string().optional(), + environment: zConsoleEnvironment.optional(), + status: z.string().optional(), + currentRelease: zConsoleRelease.optional(), + detail: zRuntimeInstanceDetail.optional(), +}) + +export const zListRuntimeInstancesReply = z.object({ + data: z.array(zRuntimeInstanceRow).optional(), +}) + +/** + * SSO Configuration messages + */ +export const zSamlConfig = z.object({ + idpSsoUrl: z.string().optional(), + certificate: z.string().optional(), +}) + +export const zSamlLoginReply = z.object({ + url: z.string().optional(), +}) + +export const zSsoIdPProvider = z.object({ + protocol: z.string().optional(), + provider: z.string().optional(), + samlConfig: zSamlConfig.optional(), + oidcConfig: zOidcConfig.optional(), + oauth2Config: zOAuth2Config.optional(), +}) + +export const zSsoSettings = z.object({ + ssoEnforced: z.boolean().optional(), + sessionTimeout: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + ssoIdpProvider: zSsoIdPProvider.optional(), +}) + +export const zAuthSettingsReply = z.object({ + userSsoSettings: zSsoSettings.optional(), + webSsoSettings: zSsoSettings.optional(), + dashboardSsoSettings: zSsoSettings.optional(), + userSsoSamlAcsUrl: z.string().optional(), + userSsoOidcCallbackUrl: z.string().optional(), + userSsoOauth2CallbackUrl: z.string().optional(), + webSsoSamlAcsUrl: z.string().optional(), + webSsoOidcCallbackUrl: z.string().optional(), + webSsoOauth2CallbackUrl: z.string().optional(), + webSsoMembersSamlAcsUrl: z.string().optional(), + webSsoMembersOidcCallbackUrl: z.string().optional(), + webSsoMembersOauth2CallbackUrl: z.string().optional(), + dashboardSsoSamlAcsUrl: z.string().optional(), + dashboardSsoOidcCallbackUrl: z.string().optional(), + dashboardSsoOauth2CallbackUrl: z.string().optional(), +}) + +export const zAuthSettingsReq = z.object({ + ssoType: z.string().optional(), + ssoSettings: zSsoSettings.optional(), +}) + +export const zSsoSettingsReply = z.object({ + enabled: z.boolean().optional(), +}) + +export const zScimSettings = z.object({ + enabled: z.boolean().optional(), + lastSyncTime: z.iso.datetime().optional(), +}) + +export const zSearchAccessSubjectsReply = z.object({ + data: z.array(zAccessSubjectDisplay).optional(), +}) + +export const zSecretKey = z.object({ + id: z.string().optional(), + name: z.string().optional(), + secretKeyMasked: z.string().optional(), + createdAt: z.iso.datetime().optional(), + lastActive: z.iso.datetime().optional(), +}) + +export const zSetDefaultWorkspaceReply = z.object({ + workspaceId: z.string().optional(), +}) + +export const zSetDefaultWorkspaceReq = z.object({ + id: z.string().optional(), +}) + +export const zStatusCount = z.object({ + status: z.string().optional(), + count: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), +}) + +export const zAppInstanceCard = z.object({ + id: z.string().optional(), + name: z.string().optional(), + icon: z.string().optional(), + mode: z.string().optional(), + sourceAppName: z.string().optional(), + statuses: z.array(zStatusCount).optional(), + lastDeployedAt: z.iso.datetime().optional(), +}) + +export const zSubjectAccountData = z.object({ + id: z.string().optional(), + name: z.string().optional(), + email: z.string().optional(), + avatar: z.string().optional(), +}) + +export const zSubjectGroupData = z.object({ + id: z.string().optional(), + name: z.string().optional(), + groupSize: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), +}) + +export const zCreateNewGroupsRes = z.object({ + groups: z.array(zSubjectGroupData).optional(), +}) + +export const zGetGroupsRes = z.object({ + groups: z.array(zSubjectGroupData).optional(), +}) + +export const zGetJoinedGroupsRes = z.object({ + groups: z.array(zSubjectGroupData).optional(), +}) + +export const zGetWebAppWhitelistSubjectsRes = z.object({ + groups: z.array(zSubjectGroupData).optional(), + members: z.array(zGetWebAppWhitelistSubjectsResMember).optional(), +}) + +/** + * Subject represents a subject (user or group) in access control + */ +export const zSubject = z.object({ + subjectId: z.string().optional(), + subjectType: z.string().optional(), + accountData: zSubjectAccountData.optional(), + groupData: zSubjectGroupData.optional(), +}) + +export const zGetGroupSubjectsRes = z.object({ + subjects: z.array(zSubject).optional(), +}) + +export const zSearchForWhilteListCandidatesRes = z.object({ + subjects: z.array(zSubject).optional(), + currPage: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + hasMore: z.boolean().optional(), +}) + +export const zSystemUserSettingReply = z.object({ + isAllowRegister: z.boolean().optional(), + enableEmailPasswordLogin: z.boolean().optional(), +}) + +export const zSystemUserSettingReq = z.object({ + isAllowRegister: z.boolean().optional(), + enableEmailPasswordLogin: z.boolean().optional(), +}) + +export const zTestConnectionReply = z.object({ + success: z.boolean().optional(), + error: z.string().optional(), +}) + +export const zTestEnvironmentConnectionReply = z.object({ + ok: z.boolean().optional(), + reachableServerVersion: z.string().optional(), + namespaceExists: z.boolean().optional(), + missingPermissions: z.array(z.string()).optional(), + error: z.string().optional(), + probedAt: z.iso.datetime().optional(), +}) + +export const zTestEnvironmentConnectionReq = z.object({ + id: z.string().optional(), +}) + +export const zToggleEndpointRequest = z.object({ + enabled: z.boolean().optional(), +}) + +export const zUndeployRuntimeInstanceReply = z.object({ + deploymentId: z.string().optional(), + status: z.string().optional(), +}) + +export const zUndeployRuntimeInstanceReq = z.object({ + appInstanceId: z.string().optional(), + runtimeInstanceId: z.string().optional(), +}) + +export const zUpdateAccessChannelsReq = z.object({ + appInstanceId: z.string().optional(), + enabled: z.boolean().optional(), +}) + +export const zUpdateAccessModeReq = z.object({ + appId: z.string().optional(), + accessMode: z.string().optional(), +}) + +export const zUpdateAccessModeRes = z.object({ + message: z.string().optional(), +}) + +export const zUpdateAppInstanceReply = z.object({ + appInstanceId: z.string().optional(), +}) + +export const zUpdateAppInstanceReq = z.object({ + appInstanceId: z.string().optional(), + name: z.string().optional(), + description: z.string().optional(), +}) + +export const zUpdateBrandingInfoReq = z.object({ + enabled: z.boolean().optional(), + applicationTitle: z.string().optional(), + loginPageLogo: z.string().optional(), + workspaceLogo: z.string().optional(), + favicon: z.string().optional(), +}) + +export const zUpdateDeveloperApiReply = z.object({ + developerApi: zDeveloperApiAccess.optional(), +}) + +export const zUpdateDeveloperApiReq = z.object({ + appInstanceId: z.string().optional(), + enabled: z.boolean().optional(), +}) + +export const zUpdateEnvironmentAccessPolicyReply = z.object({ + permission: zEnvironmentAccessRow.optional(), +}) + +export const zUpdateEnvironmentAccessPolicyReq = z.object({ + appInstanceId: z.string().optional(), + environmentId: z.string().optional(), + accessMode: z.string().optional(), + subjects: z.array(zAccessSubject).optional(), +}) + +export const zUpdateEnvironmentReply = z.object({ + environment: zEnvironment.optional(), +}) + +export const zUpdateEnvironmentReq = z.object({ + id: z.string().optional(), + name: z.string().optional(), + description: z.string().optional(), +}) + +export const zUpdateGroupSubjectsReq = z.object({ + groupId: z.string().optional(), + subjects: z.array(zSubject).optional(), +}) + +export const zUpdateGroupSubjectsRes = z.object({ + message: z.string().optional(), +}) + +export const zUpdateGroupsReqGroup = z.object({ + id: z.string().optional(), + name: z.string().optional(), +}) + +export const zUpdateGroupsReq = z.object({ + groups: z.array(zUpdateGroupsReqGroup).optional(), +}) + +export const zUpdateGroupsRes = z.object({ + groups: z.array(zSubjectGroupData).optional(), +}) + +export const zUpdateJoinedGroupsReq = z.object({ + accountId: z.string().optional(), + groupIds: z.array(z.string()).optional(), +}) + +export const zUpdateJoinedGroupsRes = z.object({ + message: z.string().optional(), +}) + +export const zUpdateLicenseReply = z.object({ + message: z.string().optional(), +}) + +export const zUpdateLicenseReq = z.object({ + licenseId: z.string().optional(), +}) + +export const zUpdateMfaStatusReq = z.object({ + enabled: z.boolean().optional(), +}) + +export const zUpdateMfaStatusRes = z.object({ + message: z.string().optional(), +}) + +export const zUpdateMemberReply = z.object({ + account: zAccount.optional(), +}) + +/** + * Update member messages + */ +export const zUpdateMemberReq = z.object({ + id: z.string().optional(), + name: z.string().optional(), + email: z.string().optional(), + status: z.string().optional(), +}) + +export const zUpdateMembersInGroupsReq = z.object({ + groupId: z.string().optional(), + accountIds: z.array(z.string()).optional(), +}) + +export const zUpdateMembersInGroupsRes = z.object({ + message: z.string().optional(), +}) + +export const zUpdateOfflineLicenseReply = z.object({ + message: z.string().optional(), +}) + +export const zUpdateOfflineLicenseReq = z.object({ + offlineCode: z.string().optional(), +}) + +export const zUpdatePluginInstallationSettingsRequest = z.object({ + pluginInstallationScope: z.int().optional(), + restrictToMarketplaceOnly: z.boolean().optional(), +}) + +export const zUpdateUserReply = z.object({ + account: zAccountDetail.optional(), +}) + +export const zUpdateUserReq = z.object({ + id: z.string().optional(), + name: z.string().optional(), + email: z.string().optional(), + status: z.string().optional(), +}) + +/** + * Web app auth info messages + */ +export const zUpdateWebAppAuthInfoReq = z.object({ + allowSso: z.boolean().optional(), + allowEmailCodeLogin: z.boolean().optional(), + allowEmailPasswordLogin: z.boolean().optional(), +}) + +export const zUpdateWebAppAuthInfoRes = z.object({ + message: z.string().optional(), +}) + +export const zUpdateWebAppWhitelistSubjectsReq = z.object({ + appId: z.string().optional(), + subjects: z.array(zSubject).optional(), + accessMode: z.string().optional(), +}) + +export const zUpdateWebAppWhitelistSubjectsRes = z.object({ + message: z.string().optional(), +}) + +/** + * Update workspace messages + */ +export const zUpdateWorkspaceReq = z.object({ + id: z.string().optional(), + name: z.string().optional(), + email: z.string().optional(), + status: z.string().optional(), +}) + +export const zWebAppAccessRow = z.object({ + environment: zConsoleEnvironment.optional(), + url: z.string().optional(), +}) + +export const zAccessChannels = z.object({ + enabled: z.boolean().optional(), + webappRows: z.array(zWebAppAccessRow).optional(), + cli: zCliAccess.optional(), +}) + +export const zGetAppInstanceAccessReply = z.object({ + permissions: z.array(zEnvironmentAccessRow).optional(), + accessChannels: zAccessChannels.optional(), + developerApi: zDeveloperApiAccess.optional(), +}) + +export const zUpdateAccessChannelsReply = z.object({ + accessChannels: zAccessChannels.optional(), +}) + +export const zWebAppAuthInfo = z.object({ + allowSso: z.boolean().optional(), + allowEmailCodeLogin: z.boolean().optional(), + allowEmailPasswordLogin: z.boolean().optional(), +}) + +/** + * Info configuration messages + */ +export const zInfoConfigReply = z.object({ + SSOEnforcedForSignin: z.boolean().optional(), + SSOEnforcedForSigninProtocol: z.string().optional(), + SSOEnforcedForWeb: z.boolean().optional(), + SSOEnforcedForWebProtocol: z.string().optional(), + EnableEmailCodeLogin: z.boolean().optional(), + EnableEmailPasswordLogin: z.boolean().optional(), + IsAllowRegister: z.boolean().optional(), + IsAllowCreateWorkspace: z.boolean().optional(), + License: zLicenseStatus.optional(), + Branding: zBrandingInfo.optional(), + WebAppAuth: zWebAppAuthInfo.optional(), + PluginInstallationPermission: zPluginInstallationPermissionInfo.optional(), +}) + +export const zWebOAuth2LoginReply = z.object({ + url: z.string().optional(), + state: z.string().optional(), +}) + +export const zWebOidcLoginReply = z.object({ + url: z.string().optional(), +}) + +export const zWebSamlLoginReply = z.object({ + url: z.string().optional(), +}) + +/** + * Workspace represents a workspace entity + */ +export const zWorkspace = z.object({ + id: z.string().optional(), + name: z.string().optional(), + status: z.string().optional(), + createdAt: z.iso.datetime().optional(), + owner: zAccount.optional(), +}) + +export const zCreateWorkspaceReply = z.object({ + workspace: zWorkspace.optional(), +}) + +export const zGetDefaultWorkspaceReply = z.object({ + workspaceId: z.string().optional(), + workspace: zWorkspace.optional(), +}) + +export const zGetWorkspaceReply = z.object({ + workspace: zWorkspace.optional(), +}) + +export const zUpdateWorkspaceReply = z.object({ + workspace: zWorkspace.optional(), +}) + +export const zWorkspaceInfoReply = z.object({ + WorkspaceMembers: zResourceQuota.optional(), +}) + +/** + * Workspace permission + */ +export const zWorkspacePermission = z.object({ + workspaceId: z.string().optional(), + allowMemberInvite: z.boolean().optional(), + allowOwnerTransfer: z.boolean().optional(), +}) + +export const zGetWorkspacePermissionReply = z.object({ + permission: zWorkspacePermission.optional(), +}) + +export const zUpdateWorkspacePermissionReply = z.object({ + message: z.string().optional(), + permission: zWorkspacePermission.optional(), +}) + +/** + * Update workspace permission messages + */ +export const zUpdateWorkspacePermissionReq = z.object({ + id: z.string().optional(), + permission: zWorkspacePermission.optional(), +}) + +/** + * Pagination : Just for pagination by page + */ +export const zPagination = z.object({ + totalCount: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + perPage: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + currentPage: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + totalPages: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), +}) + +export const zListAppInstancesReply = z.object({ + filters: z.array(zEnvironmentFilter).optional(), + data: z.array(zAppInstanceCard).optional(), + pagination: zPagination.optional(), +}) + +export const zListEnvironmentsReply = z.object({ + data: z.array(zEnvironment).optional(), + pagination: zPagination.optional(), +}) + +export const zListMembersReply = z.object({ + data: z.array(zAccountDetail).optional(), + pagination: zPagination.optional(), +}) + +export const zListReleasesReply = z.object({ + data: z.array(zReleaseRow).optional(), + pagination: zPagination.optional(), +}) + +export const zListSecretKeysReply = z.object({ + data: z.array(zSecretKey).optional(), + pagination: zPagination.optional(), +}) + +export const zListUsersReply = z.object({ + data: z.array(zAccountDetail).optional(), + pagination: zPagination.optional(), +}) + +export const zListWorkspacesReply = z.object({ + data: z.array(zWorkspace).optional(), + pagination: zPagination.optional(), +}) + +export const zEnterpriseAppDeployConsoleListAppInstancesQuery = z.object({ + environmentId: z.string().optional(), + notDeployed: z.boolean().optional(), + query: z.string().optional(), + pageNumber: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + resultsPerPage: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleListAppInstancesResponse = zListAppInstancesReply + +export const zEnterpriseAppDeployConsoleCreateAppInstanceBody = zCreateAppInstanceReq + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleCreateAppInstanceResponse = zCreateAppInstanceReply + +export const zEnterpriseAppDeployConsoleDeleteAppInstancePath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleDeleteAppInstanceResponse = zDeleteAppInstanceReply + +export const zEnterpriseAppDeployConsoleUpdateAppInstanceBody = zUpdateAppInstanceReq + +export const zEnterpriseAppDeployConsoleUpdateAppInstancePath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleUpdateAppInstanceResponse = zUpdateAppInstanceReply + +export const zEnterpriseAppDeployConsoleGetAppInstanceAccessPath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleGetAppInstanceAccessResponse = zGetAppInstanceAccessReply + +export const zEnterpriseAppDeployConsoleUpdateAccessChannelsBody = zUpdateAccessChannelsReq + +export const zEnterpriseAppDeployConsoleUpdateAccessChannelsPath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleUpdateAccessChannelsResponse = zUpdateAccessChannelsReply + +export const zEnterpriseAppDeployConsoleSearchAccessSubjectsPath = z.object({ + appInstanceId: z.string(), +}) + +export const zEnterpriseAppDeployConsoleSearchAccessSubjectsQuery = z.object({ + keyword: z.string().optional(), + subjectTypes: z.array(z.string()).optional(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleSearchAccessSubjectsResponse = zSearchAccessSubjectsReply + +export const zEnterpriseAppDeployConsoleCreateDeveloperApiKeyBody = zCreateDeveloperApiKeyReq + +export const zEnterpriseAppDeployConsoleCreateDeveloperApiKeyPath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleCreateDeveloperApiKeyResponse = zCreateDeveloperApiKeyReply + +export const zEnterpriseAppDeployConsoleDeleteDeveloperApiKeyPath = z.object({ + appInstanceId: z.string(), + apiKeyId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleDeleteDeveloperApiKeyResponse = zDeleteDeveloperApiKeyReply + +export const zEnterpriseAppDeployConsoleListDeploymentBindingOptionsPath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleListDeploymentBindingOptionsResponse + = zListDeploymentBindingOptionsReply + +export const zEnterpriseAppDeployConsoleCreateDeploymentBody = zCreateDeploymentReq + +export const zEnterpriseAppDeployConsoleCreateDeploymentPath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleCreateDeploymentResponse = zCreateDeploymentReply + +export const zEnterpriseAppDeployConsoleUpdateDeveloperApiBody = zUpdateDeveloperApiReq + +export const zEnterpriseAppDeployConsoleUpdateDeveloperApiPath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleUpdateDeveloperApiResponse = zUpdateDeveloperApiReply + +export const zEnterpriseAppDeployConsoleGetEnvironmentAccessPolicyPath = z.object({ + appInstanceId: z.string(), + environmentId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleGetEnvironmentAccessPolicyResponse + = zGetEnvironmentAccessPolicyReply + +export const zEnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyBody + = zUpdateEnvironmentAccessPolicyReq + +export const zEnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyPath = z.object({ + appInstanceId: z.string(), + environmentId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleUpdateEnvironmentAccessPolicyResponse + = zUpdateEnvironmentAccessPolicyReply + +export const zEnterpriseAppDeployConsoleGetAppInstanceOverviewPath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleGetAppInstanceOverviewResponse + = zGetAppInstanceOverviewReply + +export const zEnterpriseAppDeployConsoleListReleasesPath = z.object({ + appInstanceId: z.string(), +}) + +export const zEnterpriseAppDeployConsoleListReleasesQuery = z.object({ + pageNumber: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + resultsPerPage: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleListReleasesResponse = zListReleasesReply + +export const zEnterpriseAppDeployConsoleCreateReleaseBody = zCreateReleaseReq + +export const zEnterpriseAppDeployConsoleCreateReleasePath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleCreateReleaseResponse = zCreateReleaseReply + +export const zEnterpriseAppDeployConsolePreviewReleaseBody = zPreviewReleaseReq + +export const zEnterpriseAppDeployConsolePreviewReleasePath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsolePreviewReleaseResponse = zPreviewReleaseReply + +export const zEnterpriseAppDeployConsoleListRuntimeInstancesPath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleListRuntimeInstancesResponse = zListRuntimeInstancesReply + +export const zEnterpriseAppDeployConsoleCancelRuntimeDeploymentBody = zCancelRuntimeDeploymentReq + +export const zEnterpriseAppDeployConsoleCancelRuntimeDeploymentPath = z.object({ + appInstanceId: z.string(), + runtimeInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleCancelRuntimeDeploymentResponse + = zCancelRuntimeDeploymentReply + +export const zEnterpriseAppDeployConsoleUndeployRuntimeInstanceBody = zUndeployRuntimeInstanceReq + +export const zEnterpriseAppDeployConsoleUndeployRuntimeInstancePath = z.object({ + appInstanceId: z.string(), + runtimeInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleUndeployRuntimeInstanceResponse + = zUndeployRuntimeInstanceReply + +export const zEnterpriseAppDeployConsoleGetAppInstanceSettingsPath = z.object({ + appInstanceId: z.string(), +}) + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleGetAppInstanceSettingsResponse + = zGetAppInstanceSettingsReply + +/** + * OK + */ +export const zEnterpriseAppDeployConsoleListDeploymentEnvironmentOptionsResponse + = zListDeploymentEnvironmentOptionsReply + +/** + * OK + */ +export const zConsoleSsoOAuth2LoginResponse = zOAuth2LoginReply + +/** + * OK + */ +export const zConsoleSsoOidcLoginResponse = zOidcReply + +/** + * OK + */ +export const zConsoleSsoSamlLoginResponse = zSamlLoginReply + +export const zWebAppAuthGetWebAppAccessModeQuery = z.object({ + appId: z.string().optional(), +}) + +/** + * OK + */ +export const zWebAppAuthGetWebAppAccessModeResponse = zGetWebAppAccessModeRes + +export const zWebAppAuthUpdateWebAppWhitelistSubjectsBody = zUpdateWebAppWhitelistSubjectsReq + +/** + * OK + */ +export const zWebAppAuthUpdateWebAppWhitelistSubjectsResponse = zUpdateWebAppWhitelistSubjectsRes + +export const zWebAppAuthSearchForWhilteListCandidatesQuery = z.object({ + keyword: z.string().optional(), + pageNumber: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + resultsPerPage: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + groupId: z.string().optional(), +}) + +/** + * OK + */ +export const zWebAppAuthSearchForWhilteListCandidatesResponse = zSearchForWhilteListCandidatesRes + +export const zWebAppAuthGetWebAppWhitelistSubjectsQuery = z.object({ + appId: z.string().optional(), +}) + +/** + * OK + */ +export const zWebAppAuthGetWebAppWhitelistSubjectsResponse = zGetWebAppWhitelistSubjectsRes + +export const zWebAppAuthGetGroupSubjectsQuery = z.object({ + groupId: z.string().optional(), +}) + +/** + * OK + */ +export const zWebAppAuthGetGroupSubjectsResponse = zGetGroupSubjectsRes + +export const zWebAppAuthIsUserAllowedToAccessWebAppQuery = z.object({ + appId: z.string().optional(), +}) + +/** + * OK + */ +export const zWebAppAuthIsUserAllowedToAccessWebAppResponse = zIsUserAllowedToAccessWebAppRes diff --git a/packages/contracts/openapi-ts.api.config.ts b/packages/contracts/openapi-ts.api.config.ts new file mode 100644 index 0000000000..79c8ec8322 --- /dev/null +++ b/packages/contracts/openapi-ts.api.config.ts @@ -0,0 +1,610 @@ +import type { UserConfig } from '@hey-api/openapi-ts' +import fs from 'node:fs' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import { defineConfig } from '@hey-api/openapi-ts' + +type JsonObject = Record + +type SwaggerSchema = JsonObject & { + '$defs'?: Record + '$ref'?: string + 'x-nullable'?: boolean + 'additionalProperties'?: unknown + 'anyOf'?: SwaggerSchema[] + 'const'?: unknown + 'default'?: unknown + 'definitions'?: Record + 'description'?: string + 'enum'?: unknown[] + 'format'?: string + 'items'?: SwaggerSchema + 'properties'?: Record + 'required'?: string[] + 'type'?: string +} + +type SwaggerParameter = JsonObject & { + in?: string + name?: string + required?: boolean + schema?: SwaggerSchema + type?: string +} + +type SwaggerResponse = JsonObject & { + description?: string + schema?: SwaggerSchema +} + +type SwaggerOperation = JsonObject & { + operationId?: string + parameters?: SwaggerParameter[] + responses?: Record +} + +type SwaggerDocument = JsonObject & { + definitions?: Record + paths?: Record> +} + +type ApiSpec = { + filename: string + name: string +} + +type ApiJob = { + document: SwaggerDocument + outputPath: string +} + +type ApiContractOperation = { + method: string + path: string +} + +const currentDir = path.dirname(fileURLToPath(import.meta.url)) +const apiOpenApiDir = path.resolve(currentDir, 'openapi') + +const operationMethods = new Set(['delete', 'get', 'patch', 'post', 'put']) + +const apiSpecs: ApiSpec[] = [ + { filename: 'console-swagger.json', name: 'console' }, + { filename: 'web-swagger.json', name: 'web' }, + { filename: 'service-swagger.json', name: 'service' }, +] + +const isObject = (value: unknown): value is JsonObject => { + return !!value && typeof value === 'object' && !Array.isArray(value) +} + +const unknownObjectSchema = (): SwaggerSchema => ({ + additionalProperties: true, + type: 'object', +}) + +const toWords = (value: string) => { + return value + .replace(/[{}]/g, '') + .replace(/([a-z0-9])([A-Z])/g, '$1 $2') + .split(/[^a-z0-9]+/i) + .filter(Boolean) +} + +const toPascalCase = (words: string[]) => { + return words.map(word => `${word.charAt(0).toUpperCase()}${word.slice(1)}`).join('') +} + +const toCamelCase = (words: string[]) => { + const pascal = toPascalCase(words) + return `${pascal.charAt(0).toLowerCase()}${pascal.slice(1)}` +} + +const toKebabCase = (value: string) => { + return toWords(value).join('-').toLowerCase() +} + +const segmentWords = (segment: string) => { + if (segment.startsWith('{') && segment.endsWith('}')) + return ['by', ...toWords(segment)] + + return toWords(segment) +} + +const routeWords = (routePath: string) => { + return routePath + .split('/') + .filter(Boolean) + .flatMap(segmentWords) +} + +const operationId = (method: string, routePath: string) => { + return toCamelCase([method, ...(routeWords(routePath).length > 0 ? routeWords(routePath) : ['root'])]) +} + +const contractPathSegments = (operation: ApiContractOperation) => { + const segments = operation.path + .split('/') + .filter(Boolean) + .map(segment => toCamelCase(segmentWords(segment))) + + return [...(segments.length > 0 ? segments : ['root']), operation.method.toLowerCase()] +} + +const readApiSwagger = (filename: string): SwaggerDocument => { + const specPath = path.join(apiOpenApiDir, filename) + + if (!fs.existsSync(specPath)) { + throw new Error( + `Missing API OpenAPI spec: ${specPath}. Run "pnpm gen-api-openapi" from packages/contracts/ first.`, + ) + } + + const rawSpec = JSON.parse(fs.readFileSync(specPath, 'utf8')) + if (!isObject(rawSpec) || !isObject(rawSpec.paths)) + throw new Error(`Invalid API OpenAPI spec: ${specPath}`) + + return rawSpec as SwaggerDocument +} + +const clone = (value: T): T => { + return JSON.parse(JSON.stringify(value)) as T +} + +const collectDefinitionRefs = (value: unknown, refs: Set, visited = new WeakSet()) => { + if (!value || typeof value !== 'object') + return + + if (visited.has(value)) + return + + visited.add(value) + + if (Array.isArray(value)) { + value.forEach(item => collectDefinitionRefs(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()) => { + if (!value || typeof value !== 'object' || visited.has(value)) + return + + visited.add(value) + + if (Array.isArray(value)) { + value.forEach(item => removeNullDefaults(item, visited)) + return + } + + const schema = value as SwaggerSchema + if (schema.default === null) + delete schema.default + + Object.values(schema).forEach(item => removeNullDefaults(item, visited)) +} + +const isNullSchema = (schema: SwaggerSchema) => { + return schema.type === 'null' +} + +const normalizeNullableAnyOf = (value: unknown, visited = new WeakSet()) => { + 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) => { + const visited = new WeakSet() + + 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() + collectDefinitionRefs(document, refs) + + for (const refName of refs) + definitions[refName] ??= unknownObjectSchema() +} + +const resolveDefinitionRef = ( + schema: SwaggerSchema | undefined, + definitions: Record, +): SwaggerSchema | undefined => { + const ref = schema?.$ref + + if (!ref?.startsWith('#/definitions/')) + return schema + + return definitions[ref.slice('#/definitions/'.length)] ?? schema +} + +const withoutNullableWrapper = (schema: SwaggerSchema | undefined): SwaggerSchema => { + if (!schema) + return {} + + const nonNullSchema = schema.anyOf?.find(item => item.type !== 'null') + if (!nonNullSchema) + return schema + + const { anyOf: _anyOf, ...rest } = schema + return { + ...rest, + ...nonNullSchema, + } +} + +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, + required: boolean, +): SwaggerParameter => { + const querySchema = withoutNullableWrapper(schema) + const parameter: SwaggerParameter = { + in: 'query', + name, + required, + } + + 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 +} + +const mergeQueryParameter = ( + parameters: SwaggerParameter[], + queryParameter: SwaggerParameter, +) => { + const existingIndex = parameters.findIndex((parameter) => { + return parameter.in === 'query' && parameter.name === queryParameter.name + }) + + if (existingIndex === -1) { + parameters.push(queryParameter) + return + } + + const existingParameter = parameters[existingIndex] + if (!existingParameter) { + parameters.push(queryParameter) + return + } + + parameters[existingIndex] = { + ...existingParameter, + ...queryParameter, + description: queryParameter.description ?? existingParameter.description, + required: Boolean(existingParameter.required) || Boolean(queryParameter.required), + } +} + +const normalizeGetBodyParameters = ( + operation: SwaggerOperation, + definitions: Record, +) => { + if (!Array.isArray(operation.parameters)) + return + + const bodyParameters: SwaggerParameter[] = [] + const normalizedParameters: SwaggerParameter[] = [] + + for (const parameter of operation.parameters) { + if (parameter.in === 'body') { + bodyParameters.push(parameter) + continue + } + + normalizedParameters.push(parameter) + } + + for (const parameter of bodyParameters) { + const schema = resolveDefinitionRef(parameter.schema, definitions) + const properties = schema?.properties ?? {} + const required = new Set(schema?.required ?? []) + + for (const [name, propertySchema] of Object.entries(properties)) { + mergeQueryParameter( + normalizedParameters, + queryParameterFromSchema(name, propertySchema, required.has(name)), + ) + } + } + + operation.parameters = normalizedParameters +} + +const normalizeResponses = (operation: SwaggerOperation) => { + const responses = operation.responses ??= {} + + for (const response of Object.values(responses)) { + if (!response.schema) + response.schema = unknownObjectSchema() + } + + if (!Object.keys(responses).some(status => /^2\d\d$/.test(status))) { + responses['200'] = { + description: 'Success', + schema: unknownObjectSchema(), + } + } +} + +const normalizeOperations = (document: SwaggerDocument) => { + const definitions = document.definitions ??= {} + + for (const [routePath, pathItem] of Object.entries(document.paths ?? {})) { + for (const [method, operation] of Object.entries(pathItem)) { + if (!operationMethods.has(method) || !isObject(operation)) + continue + + const swaggerOperation = operation as SwaggerOperation + swaggerOperation.operationId = operationId(method, routePath) + + normalizeResponses(swaggerOperation) + + if (method === 'get') + normalizeGetBodyParameters(swaggerOperation, definitions) + } + } +} + +const normalizeApiSwagger = (document: SwaggerDocument) => { + 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) + + return document +} + +const topLevelPathSegment = (routePath: string) => { + return routePath.split('/').filter(Boolean)[0] ?? 'root' +} + +const selectReferencedDefinitions = ( + definitions: Record, + paths: Record>, +) => { + const selectedDefinitions: Record = {} + const pendingRefs = new Set() + collectDefinitionRefs(paths, pendingRefs) + + while (pendingRefs.size > 0) { + const refName = pendingRefs.values().next().value + if (!refName) + break + + pendingRefs.delete(refName) + + if (selectedDefinitions[refName]) + continue + + selectedDefinitions[refName] = definitions[refName] ?? unknownObjectSchema() + + const nestedRefs = new Set() + collectDefinitionRefs(selectedDefinitions[refName], nestedRefs) + for (const nestedRef of nestedRefs) { + if (!selectedDefinitions[nestedRef]) + pendingRefs.add(nestedRef) + } + } + + return selectedDefinitions +} + +const cloneDocumentWithPaths = ( + document: SwaggerDocument, + paths: Record>, +) => { + const { definitions: _definitions, paths: _paths, ...metadata } = document + const clonedPaths = clone(paths) + + return { + ...clone(metadata), + definitions: selectReferencedDefinitions(document.definitions ?? {}, clonedPaths), + paths: clonedPaths, + } satisfies SwaggerDocument +} + +const splitConsoleDocument = (document: SwaggerDocument) => { + const pathsBySegment = new Map>>() + + for (const [routePath, pathItem] of Object.entries(document.paths ?? {})) { + const segment = topLevelPathSegment(routePath) + const paths = pathsBySegment.get(segment) ?? {} + paths[routePath] = pathItem + pathsBySegment.set(segment, paths) + } + + return [...pathsBySegment.entries()] + .sort(([left], [right]) => left.localeCompare(right)) + .map(([segment, paths]): ApiJob => ({ + document: cloneDocumentWithPaths(document, paths), + outputPath: `generated/api/console/${toKebabCase(segment)}`, + })) +} + +const createApiJobs = (spec: ApiSpec): ApiJob[] => { + const document = normalizeApiSwagger(readApiSwagger(spec.filename)) + + if (spec.name === 'console') + return splitConsoleDocument(document) + + return [ + { + document, + outputPath: `generated/api/${spec.name}`, + }, + ] +} + +const createApiConfig = (job: ApiJob): UserConfig => ({ + input: job.document, + logs: { + file: false, + }, + output: { + entryFile: false, + fileName: { + suffix: '.gen', + }, + path: job.outputPath, + postProcess: [ + { + args: ['fmt', '{{path}}'], + command: 'vp', + }, + { + args: ['--fix', '{{path}}/*.ts'], + command: 'eslint', + }, + ], + }, + plugins: [ + { + 'comments': false, + 'name': '@hey-api/typescript', + '~resolvers': { + enum: markNullableEnumSchema, + }, + }, + { + 'name': 'zod', + '~resolvers': { + enum: markNullableEnumSchema, + }, + }, + { + contracts: { + contractName: { + casing: 'camelCase', + name: '{{name}}', + }, + nesting: contractPathSegments, + segmentName: { + casing: 'camelCase', + name: '{{name}}', + }, + strategy: 'single', + }, + name: 'orpc', + validator: 'zod', + }, + ], +}) + +export default defineConfig(apiSpecs.flatMap(createApiJobs).map(createApiConfig)) diff --git a/packages/contracts/openapi-ts.enterprise.config.ts b/packages/contracts/openapi-ts.enterprise.config.ts new file mode 100644 index 0000000000..3c9bc903ab --- /dev/null +++ b/packages/contracts/openapi-ts.enterprise.config.ts @@ -0,0 +1,119 @@ +import fs from 'node:fs' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import { defineConfig } from '@hey-api/openapi-ts' +import yaml from 'js-yaml' + +type JsonObject = Record + +type OpenApiDocument = JsonObject & { + paths?: Record +} + +type ContractOperation = { + id: string + operationId?: string + tags?: readonly string[] +} + +const currentDir = path.dirname(fileURLToPath(import.meta.url)) +const enterpriseServerDir = process.env.DIFY_ENTERPRISE_SERVER + ? path.resolve(process.env.DIFY_ENTERPRISE_SERVER) + : path.resolve(currentDir, '../../../dify-enterprise/server') +const enterpriseOpenApiPath = path.join(enterpriseServerDir, 'pkg/apis/enterprise/openapi.yaml') + +const isConsoleApiPath = (routePath: string) => routePath.startsWith('/console/api/') + +const stripConsoleApiPrefix = (routePath: string) => { + if (isConsoleApiPath(routePath)) + return routePath.replace('/console/api', '') + + return routePath +} + +const stripSchemaNamePrefix = (schemaName: string) => { + return schemaName + .replace(/^dify\.enterprise\.api\.enterprise\./, '') + .replace(/^pagination\./, '') +} + +const contractNameSegments = (operation: ContractOperation) => { + const operationId = operation.operationId || operation.id + const tag = operation.tags?.[0] + const tagPrefixPattern = tag ? new RegExp(`^${tag}[._/-]`) : undefined + const name = tagPrefixPattern ? operationId.replace(tagPrefixPattern, '') : operationId + const segments = name.split(/[._/-]+/).filter(Boolean) + + return segments.length > 0 ? segments : [operationId] +} + +const contractPathSegments = (operation: ContractOperation) => { + return [operation.tags?.[0] || 'default', ...contractNameSegments(operation)] +} + +const normalizeEnterpriseOpenApi = () => { + const openApi = yaml.load(fs.readFileSync(enterpriseOpenApiPath, 'utf8')) + + if (!openApi || typeof openApi !== 'object' || Array.isArray(openApi)) + throw new Error(`Invalid enterprise OpenAPI document: ${enterpriseOpenApiPath}`) + + const document = openApi as OpenApiDocument + const paths = document.paths ?? {} + + document.paths = Object.fromEntries( + Object.entries(paths) + .filter(([routePath]) => isConsoleApiPath(routePath)) + .map(([routePath, pathItem]) => [stripConsoleApiPrefix(routePath), pathItem]), + ) + + return document +} + +export default defineConfig({ + input: normalizeEnterpriseOpenApi(), + output: { + entryFile: false, + path: 'generated/enterprise', + fileName: { + suffix: '.gen', + }, + postProcess: [ + { + command: 'vp', + args: ['fmt', '{{path}}'], + }, + { + command: 'eslint', + args: ['--fix', '{{path}}/*.ts'], + }, + ], + }, + parser: { + transforms: { + schemaName: stripSchemaNamePrefix, + }, + }, + plugins: [ + { + name: '@hey-api/typescript', + comments: false, + }, + 'zod', + { + name: 'orpc', + contracts: { + strategy: 'single', + contractName: { + name: '{{name}}', + casing: 'camelCase', + }, + nesting: contractPathSegments, + segmentName: { + name: '{{name}}', + casing: 'camelCase', + }, + }, + validator: 'zod', + }, + ], +}) diff --git a/packages/contracts/package.json b/packages/contracts/package.json new file mode 100644 index 0000000000..5e9af5e0f1 --- /dev/null +++ b/packages/contracts/package.json @@ -0,0 +1,37 @@ +{ + "name": "@dify/contracts", + "type": "module", + "version": "0.0.0-private", + "private": true, + "exports": { + "./api/*": { + "types": "./generated/api/*.ts", + "import": "./generated/api/*.ts" + }, + "./enterprise/*": { + "types": "./generated/enterprise/*.ts", + "import": "./generated/enterprise/*.ts" + } + }, + "scripts": { + "gen-api-contract": "pnpm gen-api-openapi && node -e \"fs.rmSync('generated/api', { recursive: true, force: true })\" && openapi-ts -f openapi-ts.api.config.ts", + "gen-api-openapi": "uv run --project ../../api ../../api/dev/generate_swagger_specs.py --output-dir openapi", + "gen-enterprise-contract": "openapi-ts -f openapi-ts.enterprise.config.ts", + "type-check": "tsgo" + }, + "dependencies": { + "@orpc/contract": "catalog:", + "zod": "catalog:" + }, + "devDependencies": { + "@dify/tsconfig": "workspace:*", + "@hey-api/openapi-ts": "catalog:", + "@types/js-yaml": "catalog:", + "@types/node": "catalog:", + "@typescript/native-preview": "catalog:", + "eslint": "catalog:", + "js-yaml": "catalog:", + "typescript": "catalog:", + "vite-plus": "catalog:" + } +} diff --git a/packages/contracts/tsconfig.json b/packages/contracts/tsconfig.json new file mode 100644 index 0000000000..4ebf36d2d3 --- /dev/null +++ b/packages/contracts/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "@dify/tsconfig/node.json", + "include": [ + "*.ts", + "generated/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/packages/dev-proxy/README.md b/packages/dev-proxy/README.md new file mode 100644 index 0000000000..6b9d7298c4 --- /dev/null +++ b/packages/dev-proxy/README.md @@ -0,0 +1,196 @@ +# @langgenius/dev-proxy + +Generic Hono-based development proxy for frontend projects. The package does not ship any product-specific routes, cookie names, or environment variable conventions. Every proxied path and upstream target is declared in a local config file. + +## Installation + +```bash +pnpm add -D @langgenius/dev-proxy +``` + +Add a script in your frontend project: + +```json +{ + "scripts": { + "dev:proxy": "dev-proxy --config ./dev-proxy.config.ts --env-file ./.env" + } +} +``` + +Run it with: + +```bash +pnpm dev:proxy +``` + +## CLI + +```bash +dev-proxy --config ./dev-proxy.config.ts +``` + +Supported options: + +- `--config`, `-c`: config file path. Defaults to `dev-proxy.config.ts`. +- `--env-file`: load environment variables before evaluating the config file. +- `--host`: override `server.host` from config. +- `--port`: override `server.port` from config. +- `--help`, `-h`: print help. + +`--target` is not supported. Put targets in the config file so routes and upstreams stay explicit. + +## Config Shape + +```ts +import { defineDevProxyConfig } from '@langgenius/dev-proxy' + +export default defineDevProxyConfig({ + server: { + host: '127.0.0.1', + port: 5001, + }, + routes: [ + { + paths: '/api', + target: 'https://example.com', + }, + ], + cors: { + allowedOrigins: 'local', + }, +}) +``` + +Config files can be `.ts`, `.mts`, `.js`, or `.mjs`. + +`routes` are matched in declaration order. The first matching route wins. Each configured path matches both the exact path and all child paths, so `paths: '/api'` matches `/api`, `/api/apps`, and `/api/apps/123`. + +By default, credentialed CORS is allowed for local development origins such as `localhost`, `127.0.0.1`, and `::1`. To restrict it to specific origins: + +``` +cors: { + allowedOrigins: ['http://localhost:3000'], +} +``` + +## Scenario 1: Proxy One Local Route Group To An Online Backend + +Use this when a local frontend should call an online backend through one proxy server. For example, the frontend calls `http://127.0.0.1:5001/api/apps`, and the proxy forwards it to `https://cloud.example.com/api/apps`. + +```ts +import { defineDevProxyConfig } from '@langgenius/dev-proxy' + +const target = process.env.DEV_PROXY_TARGET || 'https://cloud.example.com' + +export default defineDevProxyConfig({ + server: { + host: process.env.DEV_PROXY_HOST || '127.0.0.1', + port: Number(process.env.DEV_PROXY_PORT || 5001), + }, + routes: [ + { + paths: '/api', + target, + }, + ], +}) +``` + +Optional `.env`: + +```env +DEV_PROXY_TARGET=https://cloud.example.com +DEV_PROXY_HOST=127.0.0.1 +DEV_PROXY_PORT=5001 +``` + +Command: + +```bash +dev-proxy --config ./dev-proxy.config.ts --env-file ./.env +``` + +## Scenario 2: Proxy Two Route Groups To Two Local Backends + +Use this when one frontend needs to talk to two different local services. For example: + +- `/console/api/*` goes to a local console backend at `http://127.0.0.1:5001` +- `/api/*` goes to a local public API backend at `http://127.0.0.1:5002` + +```ts +import { defineDevProxyConfig } from '@langgenius/dev-proxy' + +const consoleApiTarget = process.env.DEV_PROXY_CONSOLE_API_TARGET || 'http://127.0.0.1:5001' +const publicApiTarget = process.env.DEV_PROXY_PUBLIC_API_TARGET || 'http://127.0.0.1:5002' + +export default defineDevProxyConfig({ + server: { + host: process.env.DEV_PROXY_HOST || '127.0.0.1', + port: Number(process.env.DEV_PROXY_PORT || 8082), + }, + routes: [ + { + paths: '/console/api', + target: consoleApiTarget, + }, + { + paths: '/api', + target: publicApiTarget, + }, + ], +}) +``` + +Optional `.env`: + +```env +DEV_PROXY_CONSOLE_API_TARGET=http://127.0.0.1:5001 +DEV_PROXY_PUBLIC_API_TARGET=http://127.0.0.1:5002 +DEV_PROXY_HOST=127.0.0.1 +DEV_PROXY_PORT=8082 +``` + +When two route groups overlap, put the more specific one first: + +```ts +routes: [ + { paths: '/api/enterprise', target: 'http://127.0.0.1:5003' }, + { paths: '/api', target: 'http://127.0.0.1:5002' }, +] +``` + +## Cookie Rewrite + +Cookie rewriting is opt-in and config-driven. The package does not know any application cookie names. + +Use `cookieRewrite` when an upstream uses secure cookie prefixes such as `__Host-` or `__Secure-`, but local development needs cookies to work over `http://localhost`. + +```ts +import type { CookieRewriteOptions } from '@langgenius/dev-proxy' +import { defineDevProxyConfig } from '@langgenius/dev-proxy' + +const cookieRewrite: CookieRewriteOptions = { + hostPrefixCookies: ['access_token', 'refresh_token', /^passport-/], +} + +export default defineDevProxyConfig({ + routes: [ + { + paths: '/api', + target: 'https://cloud.example.com', + cookieRewrite, + }, + ], +}) +``` + +Set `cookieRewrite: false` to disable cookie rewriting for a route. + +## Behavior + +- The proxy preserves the matched path prefix when forwarding requests. +- Request bodies are forwarded as streams. +- Hop-by-hop headers are removed before forwarding. +- Local credentialed CORS and preflight requests are handled by the proxy. +- Route matching is explicit and order-sensitive. diff --git a/packages/dev-proxy/bin/dev-proxy.js b/packages/dev-proxy/bin/dev-proxy.js new file mode 100755 index 0000000000..02e37f3525 --- /dev/null +++ b/packages/dev-proxy/bin/dev-proxy.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +import '../dist/cli.mjs' diff --git a/packages/dev-proxy/package.json b/packages/dev-proxy/package.json new file mode 100644 index 0000000000..d5524290eb --- /dev/null +++ b/packages/dev-proxy/package.json @@ -0,0 +1,43 @@ +{ + "name": "@langgenius/dev-proxy", + "type": "module", + "version": "0.0.5", + "exports": { + ".": { + "types": "./dist/index.d.mts", + "import": "./dist/index.mjs" + } + }, + "types": "./dist/index.d.mts", + "bin": { + "dev-proxy": "./bin/dev-proxy.js" + }, + "files": [ + "bin", + "dist", + "src" + ], + "engines": { + "node": "^22.22.1" + }, + "scripts": { + "build": "vp pack", + "prepare": "pnpm run build", + "test": "vp test", + "type-check": "tsgo", + "prepublish": "pnpm run build" + }, + "dependencies": { + "@hono/node-server": "catalog:", + "c12": "catalog:", + "hono": "catalog:" + }, + "devDependencies": { + "@dify/tsconfig": "workspace:*", + "@types/node": "catalog:", + "@typescript/native-preview": "catalog:", + "vite": "catalog:", + "vite-plus": "catalog:", + "vitest": "catalog:" + } +} diff --git a/packages/dev-proxy/src/cli.spec.ts b/packages/dev-proxy/src/cli.spec.ts new file mode 100644 index 0000000000..e8a87a0588 --- /dev/null +++ b/packages/dev-proxy/src/cli.spec.ts @@ -0,0 +1,158 @@ +/** + * @vitest-environment node + */ +import type { ChildProcessByStdio } from 'node:child_process' +import type { Readable } from 'node:stream' +import { spawn } from 'node:child_process' +import { once } from 'node:events' +import fs from 'node:fs/promises' +import net from 'node:net' +import os from 'node:os' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import { afterEach, describe, expect, it } from 'vitest' + +const tempDirs: string[] = [] +type DevProxyCliProcess = ChildProcessByStdio + +const childProcesses: DevProxyCliProcess[] = [] +const binPath = fileURLToPath(new URL('../bin/dev-proxy.js', import.meta.url)) + +const createTempDir = async () => { + const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'dev-proxy-cli-test-')) + tempDirs.push(tempDir) + return tempDir +} + +const getFreePort = async () => { + const server = net.createServer() + await new Promise((resolve, reject) => { + server.once('error', reject) + server.listen(0, '127.0.0.1', resolve) + }) + + const address = server.address() + if (!address || typeof address === 'string') + throw new Error('Failed to allocate a test port.') + + const { port } = address + await new Promise((resolve, reject) => { + server.close((error) => { + if (error) + reject(error) + else + resolve() + }) + }) + + return port +} + +const waitForOutput = ( + child: DevProxyCliProcess, + output: () => string, + expectedOutput: string, +) => new Promise((resolve, reject) => { + let timeout: ReturnType + + function cleanup() { + clearTimeout(timeout) + child.stdout.off('data', onData) + child.stderr.off('data', onData) + child.off('exit', onExit) + } + + function onData() { + if (!output().includes(expectedOutput)) + return + + cleanup() + resolve() + } + + function onExit(code: number | null, signal: NodeJS.Signals | null) { + cleanup() + reject(new Error(`dev-proxy exited before writing "${expectedOutput}" with code ${code} and signal ${signal}. Output:\n${output()}`)) + } + + timeout = setTimeout(() => { + cleanup() + reject(new Error(`Timed out waiting for "${expectedOutput}". Output:\n${output()}`)) + }, 3000) + + child.stdout.on('data', onData) + child.stderr.on('data', onData) + child.once('exit', onExit) + onData() +}) + +const spawnCli = (args: readonly string[], cwd: string) => { + const child = spawn(process.execPath, [binPath, ...args], { + cwd, + env: { + ...process.env, + FORCE_COLOR: '0', + }, + stdio: ['ignore', 'pipe', 'pipe'], + }) + childProcesses.push(child) + return child +} + +const stopChildProcess = async (child: DevProxyCliProcess) => { + if (child.exitCode !== null || child.signalCode !== null) + return + + child.kill('SIGTERM') + await once(child, 'exit') +} + +describe('dev proxy CLI', () => { + afterEach(async () => { + await Promise.all(childProcesses.splice(0).map(stopChildProcess)) + await Promise.all(tempDirs.splice(0).map(tempDir => fs.rm(tempDir, { + force: true, + recursive: true, + }))) + }) + + // Scenario: help output should still be a normal short-lived command. + it('should print help and exit', async () => { + // Arrange + const tempDir = await createTempDir() + const child = spawnCli(['--help'], tempDir) + + // Act + const [code] = await once(child, 'exit') + + // Assert + expect(code).toBe(0) + }) + + // Scenario: successful server startup should keep the CLI process alive. + it('should keep running after starting the proxy server', async () => { + // Arrange + const tempDir = await createTempDir() + const port = await getFreePort() + await fs.writeFile(path.join(tempDir, 'dev-proxy.config.ts'), ` + export default { + routes: [{ paths: '/api', target: 'https://api.example.com' }], + } + `) + + let output = '' + const child = spawnCli(['--config', './dev-proxy.config.ts', '--host', '127.0.0.1', '--port', String(port)], tempDir) + child.stdout.on('data', chunk => output += chunk.toString()) + child.stderr.on('data', chunk => output += chunk.toString()) + + // Act + await waitForOutput(child, () => output, `[dev-proxy] listening on http://127.0.0.1:${port}`) + await new Promise(resolve => setTimeout(resolve, 100)) + const response = await fetch(`http://127.0.0.1:${port}/not-proxied`) + + // Assert + expect(child.exitCode).toBeNull() + expect(child.signalCode).toBeNull() + expect(response.status).toBe(404) + }) +}) diff --git a/packages/dev-proxy/src/cli.ts b/packages/dev-proxy/src/cli.ts new file mode 100644 index 0000000000..05234cb359 --- /dev/null +++ b/packages/dev-proxy/src/cli.ts @@ -0,0 +1,56 @@ +import process from 'node:process' +import { serve } from '@hono/node-server' +import { loadDevProxyConfig, parseDevProxyCliArgs, resolveDevProxyServerOptions } from './config' +import { createDevProxyApp } from './server' + +function printUsage() { + console.log(`Usage: + dev-proxy --config [options] + +Options: + --config, -c Path to a dev proxy config file. Defaults to dev-proxy.config.ts. + --env-file Load environment variables before evaluating the config file. + --host Override the configured host. + --port Override the configured port. + --help, -h Show this help message.`) +} + +async function flushStandardStreams() { + await Promise.all([ + new Promise(resolve => process.stdout.write('', () => resolve())), + new Promise(resolve => process.stderr.write('', () => resolve())), + ]) +} + +async function main() { + const cliOptions = parseDevProxyCliArgs(process.argv.slice(2)) + + if (cliOptions.help) { + printUsage() + return + } + + const config = await loadDevProxyConfig(cliOptions.config, process.cwd(), { + envFile: cliOptions.envFile, + }) + const { host, port } = resolveDevProxyServerOptions(config.server, cliOptions) + const app = createDevProxyApp(config) + + serve({ + fetch: app.fetch, + hostname: host, + port, + }) + + console.log(`[dev-proxy] listening on http://${host}:${port}`) +} + +try { + await main() + await flushStandardStreams() +} +catch (error) { + console.error(error instanceof Error ? error.message : error) + await flushStandardStreams() + process.exit(1) +} diff --git a/packages/dev-proxy/src/config.spec.ts b/packages/dev-proxy/src/config.spec.ts new file mode 100644 index 0000000000..6f681bcbae --- /dev/null +++ b/packages/dev-proxy/src/config.spec.ts @@ -0,0 +1,145 @@ +/** + * @vitest-environment node + */ +import fs from 'node:fs/promises' +import os from 'node:os' +import path from 'node:path' +import { afterEach, describe, expect, it } from 'vitest' +import { loadDevProxyConfig, parseDevProxyCliArgs, resolveDevProxyServerOptions } from './config' + +const tempDirs: string[] = [] + +const createTempDir = async () => { + const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'dev-proxy-test-')) + tempDirs.push(tempDir) + return tempDir +} + +describe('dev proxy config', () => { + afterEach(async () => { + delete process.env.DEV_PROXY_TEST_PORT + delete process.env.DEV_PROXY_TEST_TARGET + + await Promise.all(tempDirs.splice(0).map(tempDir => fs.rm(tempDir, { + force: true, + recursive: true, + }))) + }) + + // Scenario: CLI options should support both inline and separated values. + it('should parse proxy CLI options', () => { + // Act + const options = parseDevProxyCliArgs([ + '--config=./dev-proxy.config.ts', + '--env-file', + './.env.proxy', + '--host', + '0.0.0.0', + '--port', + '8083', + ]) + + // Assert + expect(options).toEqual({ + config: './dev-proxy.config.ts', + envFile: './.env.proxy', + host: '0.0.0.0', + port: '8083', + }) + }) + + // Scenario: removed target shortcuts should fail instead of silently doing the wrong thing. + it('should reject unsupported target shortcuts', () => { + // Assert + expect(() => parseDevProxyCliArgs(['--target', 'enterprise'])).toThrow('Unsupported dev proxy option') + }) + + // Scenario: package manager argument separators should not be treated as proxy options. + it('should ignore package manager argument separators', () => { + // Act + const options = parseDevProxyCliArgs(['--config', './dev-proxy.config.ts', '--', '--help']) + + // Assert + expect(options).toEqual({ + config: './dev-proxy.config.ts', + help: true, + }) + }) + + // Scenario: CLI host and port should override config defaults. + it('should resolve server options with CLI overrides', () => { + // Act + const options = resolveDevProxyServerOptions({ + host: '127.0.0.1', + port: 5001, + }, { + host: '0.0.0.0', + port: '9002', + }) + + // Assert + expect(options).toEqual({ + host: '0.0.0.0', + port: 9002, + }) + }) + + // Scenario: TS config files should load through c12. + it('should load a TypeScript config file', async () => { + // Arrange + const tempDir = await createTempDir() + await fs.writeFile(path.join(tempDir, 'dev-proxy.config.ts'), ` + export default { + server: { host: '127.0.0.1', port: 7777 }, + routes: [{ paths: ['/api', '/files'], target: 'https://api.example.com' }], + } + `) + + // Act + const config = await loadDevProxyConfig('dev-proxy.config.ts', tempDir) + + // Assert + expect(config.server).toEqual({ + host: '127.0.0.1', + port: 7777, + }) + expect(config.routes).toEqual([ + { + paths: ['/api', '/files'], + target: 'https://api.example.com', + }, + ]) + }) + + // Scenario: env files should be loaded before the TypeScript config is evaluated. + it('should load a TypeScript config file with env file values', async () => { + // Arrange + const tempDir = await createTempDir() + await fs.writeFile(path.join(tempDir, '.env.proxy'), [ + 'DEV_PROXY_TEST_PORT=7788', + 'DEV_PROXY_TEST_TARGET=https://env.example.com', + ].join('\n')) + await fs.writeFile(path.join(tempDir, 'dev-proxy.config.ts'), ` + export default { + server: { port: Number(process.env.DEV_PROXY_TEST_PORT) }, + routes: [{ paths: '/api', target: process.env.DEV_PROXY_TEST_TARGET }], + } + `) + + // Act + const config = await loadDevProxyConfig('dev-proxy.config.ts', tempDir, { + envFile: '.env.proxy', + }) + + // Assert + expect(config.server).toEqual({ + port: 7788, + }) + expect(config.routes).toEqual([ + { + paths: '/api', + target: 'https://env.example.com', + }, + ]) + }) +}) diff --git a/packages/dev-proxy/src/config.ts b/packages/dev-proxy/src/config.ts new file mode 100644 index 0000000000..b23cb0a152 --- /dev/null +++ b/packages/dev-proxy/src/config.ts @@ -0,0 +1,129 @@ +import type { DotenvOptions } from 'c12' +import type { DevProxyCliOptions, DevProxyConfig, DevProxyConfigLoadOptions, DevProxyServerConfig, ResolvedDevProxyServerOptions } from './types' +import path from 'node:path' +import { loadConfig } from 'c12' + +const DEFAULT_CONFIG_FILE = 'dev-proxy.config.ts' +const DEFAULT_PROXY_HOST = '127.0.0.1' +const DEFAULT_PROXY_PORT = 5001 + +const OPTION_NAME_TO_KEY = { + '--config': 'config', + '-c': 'config', + '--env-file': 'envFile', + '--host': 'host', + '--port': 'port', +} as const + +type OptionName = keyof typeof OPTION_NAME_TO_KEY + +const isOptionName = (value: string): value is OptionName => value in OPTION_NAME_TO_KEY + +const requireOptionValue = (name: string, value?: string) => { + if (!value || value.startsWith('-')) + throw new Error(`Missing value for ${name}.`) + + return value +} + +export const parseDevProxyCliArgs = (argv: readonly string[]): DevProxyCliOptions => { + const options: DevProxyCliOptions = {} + + for (let index = 0; index < argv.length; index += 1) { + const arg = argv[index]! + + if (arg === '--') + continue + + if (arg === '--help' || arg === '-h') { + options.help = true + continue + } + + const [rawName, inlineValue] = arg.split('=', 2) + const name = rawName ?? '' + + if (!name.startsWith('-')) + continue + + if (!isOptionName(name)) + throw new Error(`Unsupported dev proxy option "${name}".`) + + const key = OPTION_NAME_TO_KEY[name] + options[key] = inlineValue ?? requireOptionValue(name, argv[index + 1]) + + if (inlineValue === undefined) + index += 1 + } + + return options +} + +const resolvePort = (rawPort: string | number) => { + const port = Number(rawPort) + if (!Number.isInteger(port) || port < 1 || port > 65535) + throw new Error(`Invalid proxy port "${rawPort}". Expected an integer between 1 and 65535.`) + + return port +} + +export const resolveDevProxyServerOptions = ( + serverConfig: DevProxyServerConfig = {}, + cliOptions: DevProxyCliOptions = {}, +): ResolvedDevProxyServerOptions => { + const configuredPort = cliOptions.port ?? serverConfig.port ?? DEFAULT_PROXY_PORT + + return { + host: cliOptions.host || serverConfig.host || DEFAULT_PROXY_HOST, + port: resolvePort(configuredPort), + } +} + +const isRecord = (value: unknown): value is Record => + typeof value === 'object' && value !== null + +export function assertDevProxyConfig(config: unknown): asserts config is DevProxyConfig { + if (!isRecord(config)) + throw new Error('Dev proxy config must export an object.') + + if (!Array.isArray(config.routes)) + throw new Error('Dev proxy config must include a routes array.') +} + +const resolveDotenvOptions = ( + envFile: DevProxyConfigLoadOptions['envFile'], + cwd: string, +): DotenvOptions | false => { + if (!envFile) + return false + + const resolvedEnvFilePath = path.resolve(cwd, envFile) + return { + cwd: path.dirname(resolvedEnvFilePath), + fileName: path.basename(resolvedEnvFilePath), + interpolate: true, + } +} + +export const loadDevProxyConfig = async ( + configPath = DEFAULT_CONFIG_FILE, + cwd = process.cwd(), + options: DevProxyConfigLoadOptions = {}, +): Promise => { + const resolvedConfigPath = path.resolve(cwd, configPath) + const parsedPath = path.parse(resolvedConfigPath) + const { config: loadedConfig } = await loadConfig({ + configFile: parsedPath.name, + cwd: parsedPath.dir, + dotenv: resolveDotenvOptions(options.envFile, cwd), + envName: false, + globalRc: false, + packageJson: false, + rcFile: false, + }) + + assertDevProxyConfig(loadedConfig) + return loadedConfig +} + +export const defineDevProxyConfig = (config: DevProxyConfig) => config diff --git a/packages/dev-proxy/src/cookies.spec.ts b/packages/dev-proxy/src/cookies.spec.ts new file mode 100644 index 0000000000..4a1b614eeb --- /dev/null +++ b/packages/dev-proxy/src/cookies.spec.ts @@ -0,0 +1,44 @@ +/** + * @vitest-environment node + */ +import { describe, expect, it } from 'vitest' +import { rewriteCookieHeaderForUpstream, rewriteSetCookieHeadersForLocal } from './cookies' + +describe('dev proxy cookies', () => { + // Scenario: cookie names should only receive secure host prefixes when configured. + it('should rewrite configured cookie names for HTTPS upstream requests', () => { + // Act + const cookieHeader = rewriteCookieHeaderForUpstream('access_token=abc; theme=dark; passport-app=def', { + hostPrefixCookies: ['access_token', /^passport-/], + useHostPrefix: true, + }) + + // Assert + expect(cookieHeader).toBe('__Host-access_token=abc; theme=dark; __Host-passport-app=def') + }) + + // Scenario: HTTP upstreams should keep local cookie names even when rewrite config exists. + it('should keep local cookie names for HTTP upstream requests', () => { + // Act + const cookieHeader = rewriteCookieHeaderForUpstream('access_token=abc; refresh_token=def', { + hostPrefixCookies: ['access_token', 'refresh_token'], + useHostPrefix: false, + }) + + // Assert + expect(cookieHeader).toBe('access_token=abc; refresh_token=def') + }) + + // Scenario: upstream set-cookie headers should be converted into localhost-safe cookies. + it('should rewrite upstream set-cookie headers for local development', () => { + // Act + const cookies = rewriteSetCookieHeadersForLocal([ + '__Host-access_token=abc; Path=/console/api; Domain=cloud.example.com; Secure; SameSite=None; Partitioned', + ]) + + // Assert + expect(cookies).toEqual([ + 'access_token=abc; Path=/; SameSite=Lax', + ]) + }) +}) diff --git a/web/plugins/dev-proxy/cookies.ts b/packages/dev-proxy/src/cookies.ts similarity index 58% rename from web/plugins/dev-proxy/cookies.ts rename to packages/dev-proxy/src/cookies.ts index c606322e96..61fdb6abd4 100644 --- a/web/plugins/dev-proxy/cookies.ts +++ b/packages/dev-proxy/src/cookies.ts @@ -1,4 +1,4 @@ -const DEFAULT_PROXY_TARGET = 'https://cloud.dify.ai' +import type { CookieRewriteOptions } from './types' const SECURE_COOKIE_PREFIX_PATTERN = /^__(Host|Secure)-/ const SAME_SITE_NONE_PATTERN = /^samesite=none$/i @@ -7,39 +7,43 @@ const COOKIE_DOMAIN_PATTERN = /^domain=/i const COOKIE_SECURE_PATTERN = /^secure$/i const COOKIE_PARTITIONED_PATTERN = /^partitioned$/i -const HOST_PREFIX_COOKIE_NAMES = new Set([ - 'access_token', - 'csrf_token', - 'refresh_token', - 'webapp_access_token', -]) +const stripSecureCookiePrefix = (cookieName: string) => cookieName.replace(SECURE_COOKIE_PREFIX_PATTERN, '') -const isPassportCookie = (cookieName: string) => cookieName.startsWith('passport-') +const matchesCookieName = (cookieName: string, matcher: string | RegExp) => + typeof matcher === 'string' + ? matcher === cookieName + : matcher.test(cookieName) -const shouldUseHostPrefix = (cookieName: string) => { - const normalizedCookieName = cookieName.replace(SECURE_COOKIE_PREFIX_PATTERN, '') - return HOST_PREFIX_COOKIE_NAMES.has(normalizedCookieName) || isPassportCookie(normalizedCookieName) +const shouldUseHostPrefix = (cookieName: string, options: CookieRewriteOptions) => { + const normalizedCookieName = stripSecureCookiePrefix(cookieName) + + return options.hostPrefixCookies?.some(matcher => matchesCookieName(normalizedCookieName, matcher)) || false } -const toUpstreamCookieName = (cookieName: string) => { +const toUpstreamCookieName = (cookieName: string, options: CookieRewriteOptions) => { if (cookieName.startsWith('__Host-')) return cookieName if (cookieName.startsWith('__Secure-')) - return `__Host-${cookieName.replace(SECURE_COOKIE_PREFIX_PATTERN, '')}` + return `__Host-${stripSecureCookiePrefix(cookieName)}` - if (!shouldUseHostPrefix(cookieName)) + if (!shouldUseHostPrefix(cookieName, options)) return cookieName return `__Host-${cookieName}` } -const toLocalCookieName = (cookieName: string) => cookieName.replace(SECURE_COOKIE_PREFIX_PATTERN, '') +export const toLocalCookieName = (cookieName: string) => stripSecureCookiePrefix(cookieName) -export const rewriteCookieHeaderForUpstream = (cookieHeader?: string) => { +export const rewriteCookieHeaderForUpstream = ( + cookieHeader: string | undefined, + options: CookieRewriteOptions & { useHostPrefix?: boolean }, +) => { if (!cookieHeader) return cookieHeader + const { useHostPrefix = true } = options + return cookieHeader .split(/;\s*/) .filter(Boolean) @@ -50,7 +54,11 @@ export const rewriteCookieHeaderForUpstream = (cookieHeader?: string) => { const cookieName = cookie.slice(0, separatorIndex).trim() const cookieValue = cookie.slice(separatorIndex + 1) - return `${toUpstreamCookieName(cookieName)}=${cookieValue}` + const upstreamCookieName = useHostPrefix + ? toUpstreamCookieName(cookieName, options) + : cookieName + + return `${upstreamCookieName}=${cookieValue}` }) .join('; ') } @@ -84,15 +92,5 @@ const rewriteSetCookieValueForLocal = (setCookieValue: string) => { return [`${toLocalCookieName(cookieName)}=${cookieValue}`, ...rewrittenAttributes].join('; ') } -export const rewriteSetCookieHeadersForLocal = (setCookieHeaders?: string | string[]): string[] | undefined => { - if (!setCookieHeaders) - return undefined - - const normalizedHeaders = Array.isArray(setCookieHeaders) - ? setCookieHeaders - : [setCookieHeaders] - - return normalizedHeaders.map(rewriteSetCookieValueForLocal) -} - -export { DEFAULT_PROXY_TARGET } +export const rewriteSetCookieHeadersForLocal = (setCookieHeaders: readonly string[]) => + setCookieHeaders.map(rewriteSetCookieValueForLocal) diff --git a/packages/dev-proxy/src/index.ts b/packages/dev-proxy/src/index.ts new file mode 100644 index 0000000000..e35893b98f --- /dev/null +++ b/packages/dev-proxy/src/index.ts @@ -0,0 +1,22 @@ +export { + assertDevProxyConfig, + defineDevProxyConfig, + loadDevProxyConfig, + parseDevProxyCliArgs, + resolveDevProxyServerOptions, +} from './config' +export { rewriteCookieHeaderForUpstream, rewriteSetCookieHeadersForLocal, toLocalCookieName } from './cookies' +export { buildUpstreamUrl, createDevProxyApp, isAllowedDevOrigin, isAllowedLocalDevOrigin } from './server' +export type { + CookieNameMatcher, + CookieRewriteOptions, + CreateDevProxyAppOptions, + DevProxyCliOptions, + DevProxyConfig, + DevProxyConfigLoadOptions, + DevProxyCorsAllowedOrigins, + DevProxyCorsConfig, + DevProxyRoute, + DevProxyServerConfig, + ResolvedDevProxyServerOptions, +} from './types' diff --git a/packages/dev-proxy/src/server.spec.ts b/packages/dev-proxy/src/server.spec.ts new file mode 100644 index 0000000000..32c16a1807 --- /dev/null +++ b/packages/dev-proxy/src/server.spec.ts @@ -0,0 +1,242 @@ +/** + * @vitest-environment node + */ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { buildUpstreamUrl, createDevProxyApp, isAllowedDevOrigin } from './server' + +describe('dev proxy server', () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + // Scenario: target paths should not be duplicated when the incoming route already includes them. + it('should preserve prefixed targets when building upstream URLs', () => { + // Act + const url = buildUpstreamUrl('https://api.example.com/console/api', '/console/api/apps', '?page=1') + + // Assert + expect(url.href).toBe('https://api.example.com/console/api/apps?page=1') + }) + + // Scenario: only localhost dev origins should be reflected for credentialed CORS by default. + it('should only allow local development origins by default', () => { + // Assert + expect(isAllowedDevOrigin('http://localhost:3000')).toBe(true) + expect(isAllowedDevOrigin('http://127.0.0.1:3000')).toBe(true) + expect(isAllowedDevOrigin('https://example.com')).toBe(false) + }) + + // Scenario: explicit CORS origins should support non-local development hosts. + it('should allow explicitly configured origins', () => { + // Assert + expect(isAllowedDevOrigin('https://app.example.com', ['https://app.example.com'])).toBe(true) + expect(isAllowedDevOrigin('https://other.example.com', ['https://app.example.com'])).toBe(false) + }) + + // Scenario: proxy requests should rewrite cookies and surface credentialed CORS headers when configured. + it('should proxy api requests with configured local cookie rewriting', async () => { + // Arrange + const fetchImpl = vi.fn().mockResolvedValue(new Response('ok', { + status: 200, + headers: [ + ['content-encoding', 'br'], + ['content-length', '123'], + ['set-cookie', '__Host-access_token=abc; Path=/console/api; Domain=cloud.example.com; Secure; SameSite=None'], + ['transfer-encoding', 'chunked'], + ], + })) + const app = createDevProxyApp({ + routes: [ + { + paths: '/console/api', + target: 'https://cloud.example.com', + cookieRewrite: { + hostPrefixCookies: ['access_token'], + }, + }, + ], + fetchImpl, + }) + + // Act + const response = await app.request('http://127.0.0.1:5001/console/api/apps?page=1', { + headers: { + 'Origin': 'http://localhost:3000', + 'Cookie': 'access_token=abc; theme=dark', + 'Accept-Encoding': 'zstd, br, gzip', + }, + }) + + // Assert + expect(fetchImpl).toHaveBeenCalledTimes(1) + expect(fetchImpl).toHaveBeenCalledWith( + new URL('https://cloud.example.com/console/api/apps?page=1'), + expect.objectContaining({ + method: 'GET', + headers: expect.any(Headers), + }), + ) + + const requestHeaders = fetchImpl.mock.calls[0]?.[1]?.headers + if (!(requestHeaders instanceof Headers)) + throw new Error('Expected proxy request headers to be Headers') + + expect(requestHeaders.get('cookie')).toBe('__Host-access_token=abc; theme=dark') + expect(requestHeaders.get('origin')).toBe('https://cloud.example.com') + expect(requestHeaders.get('accept-encoding')).toBe('identity') + expect(response.headers.get('access-control-allow-origin')).toBe('http://localhost:3000') + expect(response.headers.get('access-control-allow-credentials')).toBe('true') + expect(response.headers.get('content-encoding')).toBeNull() + expect(response.headers.get('content-length')).toBeNull() + expect(response.headers.get('transfer-encoding')).toBeNull() + expect(response.headers.getSetCookie()).toEqual([ + 'access_token=abc; Path=/; SameSite=Lax', + ]) + }) + + // Scenario: generic proxy routes should not know Dify cookie names by default. + it('should not rewrite cookie names when cookie rewriting is not configured', async () => { + // Arrange + const fetchImpl = vi.fn().mockResolvedValue(new Response('ok')) + const app = createDevProxyApp({ + routes: [ + { + paths: '/api', + target: 'https://api.example.com', + }, + ], + fetchImpl, + }) + + // Act + await app.request('http://127.0.0.1:5001/api/messages', { + headers: { + Cookie: 'access_token=abc; refresh_token=def', + }, + }) + + // Assert + const requestHeaders = fetchImpl.mock.calls[0]?.[1]?.headers + if (!(requestHeaders instanceof Headers)) + throw new Error('Expected proxy request headers to be Headers') + + expect(requestHeaders.get('cookie')).toBe('access_token=abc; refresh_token=def') + }) + + // Scenario: local HTTP upstreams expect local cookie names even when cookie rewriting is configured. + it('should keep local cookie names for HTTP upstream targets', async () => { + // Arrange + const fetchImpl = vi.fn().mockResolvedValue(new Response('ok')) + const app = createDevProxyApp({ + routes: [ + { + paths: '/console/api', + target: 'http://127.0.0.1:5001', + cookieRewrite: { + hostPrefixCookies: ['access_token', 'refresh_token'], + }, + }, + ], + fetchImpl, + }) + + // Act + await app.request('http://127.0.0.1:5010/console/api/account/profile', { + headers: { + Cookie: 'access_token=abc; refresh_token=def', + }, + }) + + // Assert + const requestHeaders = fetchImpl.mock.calls[0]?.[1]?.headers + if (!(requestHeaders instanceof Headers)) + throw new Error('Expected proxy request headers to be Headers') + + expect(requestHeaders.get('cookie')).toBe('access_token=abc; refresh_token=def') + }) + + // Scenario: custom route paths should support independent upstream targets. + it('should proxy custom route paths to their configured targets', async () => { + // Arrange + const fetchImpl = vi.fn().mockResolvedValue(new Response('ok')) + const app = createDevProxyApp({ + routes: [ + { + paths: '/api', + target: 'https://api.example.com', + }, + { + paths: '/files', + target: 'https://files.example.com/assets', + }, + ], + fetchImpl, + }) + + // Act + await app.request('http://127.0.0.1:5001/api/messages') + await app.request('http://127.0.0.1:5001/files/logo.png?size=small') + + // Assert + expect(fetchImpl.mock.calls.map(([url]) => url.toString())).toEqual([ + 'https://api.example.com/api/messages', + 'https://files.example.com/assets/files/logo.png?size=small', + ]) + }) + + // Scenario: routes are matched in config order so callers can put specific routes first. + it('should prefer earlier route entries', async () => { + // Arrange + const fetchImpl = vi.fn().mockResolvedValue(new Response('ok')) + const app = createDevProxyApp({ + routes: [ + { + paths: '/api/enterprise', + target: 'https://enterprise.example.com', + }, + { + paths: '/api', + target: 'https://api.example.com', + }, + ], + fetchImpl, + }) + + // Act + await app.request('http://127.0.0.1:5001/api/enterprise/sso/login') + + // Assert + expect(fetchImpl.mock.calls.map(([url]) => url.toString())).toEqual([ + 'https://enterprise.example.com/api/enterprise/sso/login', + ]) + }) + + // Scenario: preflight requests should advertise allowed headers for credentialed cross-origin calls. + it('should answer CORS preflight requests', async () => { + // Arrange + const app = createDevProxyApp({ + routes: [ + { + paths: '/api', + target: 'https://api.example.com', + }, + ], + fetchImpl: vi.fn(), + }) + + // Act + const response = await app.request('http://127.0.0.1:5001/api/messages', { + method: 'OPTIONS', + headers: { + 'Origin': 'http://localhost:3000', + 'Access-Control-Request-Headers': 'authorization,content-type,x-csrf-token', + }, + }) + + // Assert + expect(response.status).toBe(204) + expect(response.headers.get('access-control-allow-origin')).toBe('http://localhost:3000') + expect(response.headers.get('access-control-allow-credentials')).toBe('true') + expect(response.headers.get('access-control-allow-headers')).toBe('authorization,content-type,x-csrf-token') + }) +}) diff --git a/packages/dev-proxy/src/server.ts b/packages/dev-proxy/src/server.ts new file mode 100644 index 0000000000..79654750da --- /dev/null +++ b/packages/dev-proxy/src/server.ts @@ -0,0 +1,254 @@ +import type { Context, Hono } from 'hono' +import type { CookieRewriteOptions, CreateDevProxyAppOptions, DevProxyCorsAllowedOrigins, DevProxyRoute } from './types' +import { Hono as HonoApp } from 'hono' +import { rewriteCookieHeaderForUpstream, rewriteSetCookieHeadersForLocal } from './cookies' + +const LOCAL_DEV_HOSTS = new Set(['localhost', '127.0.0.1', '[::1]', '::1']) +const ALLOW_METHODS = 'GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS' +const DEFAULT_ALLOW_HEADERS = 'Authorization, Content-Type, X-CSRF-Token' +const UPSTREAM_ACCEPT_ENCODING = 'identity' +const RESPONSE_HEADERS_TO_DROP = [ + 'connection', + 'content-encoding', + 'content-length', + 'keep-alive', + 'proxy-authenticate', + 'proxy-authorization', + 'te', + 'trailer', + 'transfer-encoding', + 'upgrade', +] as const + +const appendHeaderValue = (headers: Headers, name: string, value: string) => { + const currentValue = headers.get(name) + if (!currentValue) { + headers.set(name, value) + return + } + + if (currentValue.split(',').map(item => item.trim()).includes(value)) + return + + headers.set(name, `${currentValue}, ${value}`) +} + +export const isAllowedLocalDevOrigin = (origin?: string | null) => { + if (!origin) + return false + + try { + const url = new URL(origin) + return LOCAL_DEV_HOSTS.has(url.hostname) + } + catch { + return false + } +} + +export const isAllowedDevOrigin = ( + origin?: string | null, + allowedOrigins: DevProxyCorsAllowedOrigins = 'local', +) => { + if (!origin) + return false + + if (allowedOrigins === 'local') + return isAllowedLocalDevOrigin(origin) + + return allowedOrigins.includes(origin) +} + +const applyCorsHeaders = ( + headers: Headers, + origin: string | undefined | null, + allowedOrigins: DevProxyCorsAllowedOrigins = 'local', +) => { + if (!isAllowedDevOrigin(origin, allowedOrigins)) + return + + headers.set('Access-Control-Allow-Origin', origin!) + headers.set('Access-Control-Allow-Credentials', 'true') + appendHeaderValue(headers, 'Vary', 'Origin') +} + +export const buildUpstreamUrl = (target: string, requestPath: string, search = '') => { + const targetUrl = new URL(target) + const normalizedTargetPath = targetUrl.pathname === '/' ? '' : targetUrl.pathname.replace(/\/$/, '') + const normalizedRequestPath = requestPath.startsWith('/') ? requestPath : `/${requestPath}` + const hasTargetPrefix = normalizedTargetPath + && (normalizedRequestPath === normalizedTargetPath || normalizedRequestPath.startsWith(`${normalizedTargetPath}/`)) + + targetUrl.pathname = hasTargetPrefix + ? normalizedRequestPath + : `${normalizedTargetPath}${normalizedRequestPath}` + targetUrl.search = search + + return targetUrl +} + +const createProxyRequestHeaders = ( + request: Request, + targetUrl: URL, + cookieRewrite: CookieRewriteOptions | false | undefined, +) => { + const headers = new Headers(request.headers) + headers.delete('host') + headers.set('accept-encoding', UPSTREAM_ACCEPT_ENCODING) + + if (headers.has('origin')) + headers.set('origin', targetUrl.origin) + + if (cookieRewrite) { + const rewrittenCookieHeader = rewriteCookieHeaderForUpstream(headers.get('cookie') || undefined, { + ...cookieRewrite, + useHostPrefix: targetUrl.protocol === 'https:', + }) + if (rewrittenCookieHeader) + headers.set('cookie', rewrittenCookieHeader) + } + + return headers +} + +const getSetCookieHeaders = (headers: Headers) => { + const headersWithGetSetCookie = headers as Headers & { getSetCookie?: () => string[] } + const setCookieHeaders = headersWithGetSetCookie.getSetCookie?.() + if (setCookieHeaders?.length) + return setCookieHeaders + + const setCookie = headers.get('set-cookie') + return setCookie ? [setCookie] : [] +} + +const createUpstreamResponseHeaders = ( + response: Response, + requestOrigin: string | undefined | null, + allowedOrigins: DevProxyCorsAllowedOrigins, + cookieRewrite: CookieRewriteOptions | false | undefined, +) => { + const headers = new Headers(response.headers) + RESPONSE_HEADERS_TO_DROP.forEach(header => headers.delete(header)) + headers.delete('set-cookie') + + const setCookieHeaders = getSetCookieHeaders(response.headers) + const responseSetCookieHeaders = cookieRewrite + ? rewriteSetCookieHeadersForLocal(setCookieHeaders) + : setCookieHeaders + + responseSetCookieHeaders.forEach((cookie) => { + headers.append('set-cookie', cookie) + }) + + applyCorsHeaders(headers, requestOrigin, allowedOrigins) + return headers +} + +const proxyRequest = async ( + context: Context, + route: DevProxyRoute, + fetchImpl: typeof globalThis.fetch, + allowedOrigins: DevProxyCorsAllowedOrigins, +) => { + const requestUrl = new URL(context.req.url) + const targetUrl = buildUpstreamUrl(route.target, requestUrl.pathname, requestUrl.search) + const requestHeaders = createProxyRequestHeaders(context.req.raw, targetUrl, route.cookieRewrite) + const requestInit: RequestInit & { duplex?: 'half' } = { + method: context.req.method, + headers: requestHeaders, + redirect: 'manual', + } + + if (context.req.method !== 'GET' && context.req.method !== 'HEAD') { + requestInit.body = context.req.raw.body + requestInit.duplex = 'half' + } + + const upstreamResponse = await fetchImpl(targetUrl, requestInit) + const responseHeaders = createUpstreamResponseHeaders( + upstreamResponse, + context.req.header('origin'), + allowedOrigins, + route.cookieRewrite, + ) + + return new Response(upstreamResponse.body, { + status: upstreamResponse.status, + statusText: upstreamResponse.statusText, + headers: responseHeaders, + }) +} + +const normalizeRoutePaths = (paths: DevProxyRoute['paths']) => Array.isArray(paths) ? paths : [paths] + +const registerProxyRoute = ( + app: Hono, + route: DevProxyRoute, + path: string, + fetchImpl: typeof globalThis.fetch, + allowedOrigins: DevProxyCorsAllowedOrigins, +) => { + if (!path.startsWith('/')) + throw new Error(`Invalid dev proxy route path "${path}". Paths must start with "/".`) + + app.all(path, context => proxyRequest(context, route, fetchImpl, allowedOrigins)) + app.all(`${path}/*`, context => proxyRequest(context, route, fetchImpl, allowedOrigins)) +} + +const registerProxyRoutes = ( + app: Hono, + routes: readonly DevProxyRoute[], + fetchImpl: typeof globalThis.fetch, + allowedOrigins: DevProxyCorsAllowedOrigins, +) => { + routes.forEach((route) => { + normalizeRoutePaths(route.paths).forEach((path) => { + registerProxyRoute(app, route, path, fetchImpl, allowedOrigins) + }) + }) +} + +export const createDevProxyApp = (options: CreateDevProxyAppOptions) => { + const app = new HonoApp() + const fetchImpl = options.fetchImpl || globalThis.fetch + const logger = options.logger || console + const allowedOrigins = options.cors?.allowedOrigins || 'local' + + app.onError((error, context) => { + logger.error('[dev-proxy]', error) + + const headers = new Headers() + applyCorsHeaders(headers, context.req.header('origin'), allowedOrigins) + + return new Response('Upstream proxy request failed.', { + status: 502, + headers, + }) + }) + + app.use('*', async (context, next) => { + if (context.req.method === 'OPTIONS') { + const headers = new Headers() + applyCorsHeaders(headers, context.req.header('origin'), allowedOrigins) + headers.set('Access-Control-Allow-Methods', ALLOW_METHODS) + headers.set( + 'Access-Control-Allow-Headers', + context.req.header('Access-Control-Request-Headers') || DEFAULT_ALLOW_HEADERS, + ) + if (context.req.header('Access-Control-Request-Private-Network') === 'true') + headers.set('Access-Control-Allow-Private-Network', 'true') + + return new Response(null, { + status: 204, + headers, + }) + } + + await next() + applyCorsHeaders(context.res.headers, context.req.header('origin'), allowedOrigins) + }) + + registerProxyRoutes(app, options.routes, fetchImpl, allowedOrigins) + + return app +} diff --git a/packages/dev-proxy/src/types.ts b/packages/dev-proxy/src/types.ts new file mode 100644 index 0000000000..2c42b2f7fb --- /dev/null +++ b/packages/dev-proxy/src/types.ts @@ -0,0 +1,50 @@ +export type DevProxyServerConfig = { + host?: string + port?: number +} + +export type DevProxyCorsAllowedOrigins = 'local' | readonly string[] + +export type DevProxyCorsConfig = { + allowedOrigins?: DevProxyCorsAllowedOrigins +} + +export type CookieNameMatcher = string | RegExp + +export type CookieRewriteOptions = { + hostPrefixCookies?: readonly CookieNameMatcher[] +} + +export type DevProxyRoute = { + paths: string | readonly string[] + target: string + cookieRewrite?: CookieRewriteOptions | false +} + +export type DevProxyConfig = { + server?: DevProxyServerConfig + routes: readonly DevProxyRoute[] + cors?: DevProxyCorsConfig +} + +export type DevProxyCliOptions = { + config?: string + envFile?: string + host?: string + port?: string + help?: boolean +} + +export type DevProxyConfigLoadOptions = { + envFile?: string | false +} + +export type ResolvedDevProxyServerOptions = { + host: string + port: number +} + +export type CreateDevProxyAppOptions = Pick & { + fetchImpl?: typeof globalThis.fetch + logger?: Pick +} diff --git a/packages/dev-proxy/tsconfig.json b/packages/dev-proxy/tsconfig.json new file mode 100644 index 0000000000..813a9bd8a3 --- /dev/null +++ b/packages/dev-proxy/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "@dify/tsconfig/node.json", + "compilerOptions": { + "types": [ + "node", + "vitest/globals" + ] + }, + "include": [ + "src/**/*.ts", + "vite.config.ts" + ], + "exclude": [ + "node_modules", + "dist" + ] +} diff --git a/packages/dev-proxy/vite.config.ts b/packages/dev-proxy/vite.config.ts new file mode 100644 index 0000000000..d060ae036e --- /dev/null +++ b/packages/dev-proxy/vite.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vite-plus' + +export default defineConfig({ + pack: { + clean: true, + deps: { + neverBundle: [ + '@hono/node-server', + 'c12', + 'hono', + ], + }, + entry: [ + 'src/index.ts', + 'src/cli.ts', + ], + format: ['esm'], + outDir: 'dist', + platform: 'node', + sourcemap: true, + target: 'node22', + treeshake: true, + }, + test: { + environment: 'node', + }, +}) diff --git a/packages/dify-ui/.storybook/storybook.css b/packages/dify-ui/.storybook/storybook.css index e9796fd046..ca76cd2968 100644 --- a/packages/dify-ui/.storybook/storybook.css +++ b/packages/dify-ui/.storybook/storybook.css @@ -1,6 +1,9 @@ @import 'tailwindcss'; -@config '../tailwind.config.ts'; +@plugin '../src/plugins/icons.ts'; + +@source '../src'; +@source '../.storybook'; @import '../src/styles/styles.css'; diff --git a/packages/dify-ui/AGENTS.md b/packages/dify-ui/AGENTS.md index 4a7fe2f22a..bdc2160702 100644 --- a/packages/dify-ui/AGENTS.md +++ b/packages/dify-ui/AGENTS.md @@ -1,6 +1,6 @@ # @langgenius/dify-ui -Shared design tokens, the `cn()` utility, a Tailwind CSS preset, and headless primitive components consumed by `web/`. +Shared design tokens, the `cn()` utility, CSS-first Tailwind styles, and headless primitive components consumed by `web/`. ## Component Authoring Rules @@ -51,9 +51,33 @@ The Figma design system uses `--radius/*` tokens whose scale is **offset by one ### Rules -- **Do not** add custom `borderRadius` values to `tailwind-preset.ts`. We use Tailwind v4 defaults and arbitrary values (`rounded-[Npx]`) for sizes without a standard equivalent. +- **Do not** add custom `borderRadius` theme values. We use Tailwind v4 defaults and arbitrary values (`rounded-[Npx]`) for sizes without a standard equivalent. - **Do not** use `radius-*` as CSS class names. The old `@utility radius-*` definitions have been removed. - When the Figma MCP returns `rounded-[var(--radius/sm, 6px)]`, convert it to the standard Tailwind class from the table above (e.g. `rounded-md`). - For values without a standard Tailwind equivalent (10px, 20px, 28px), use arbitrary values like `rounded-[10px]`. +## Search / Picker Primitive Selection: Autocomplete vs Combobox vs Select + +Pick by whether the user is entering free-form text, choosing a remembered value, or selecting from a closed list. + +Base UI decision rules: + +- [Autocomplete docs]: use `Combobox` instead of `Autocomplete` if the selection should be remembered and the input value cannot be custom. +- [Combobox docs]: do not use `Combobox` for simple search widgets that require unrestricted text entry; use `Autocomplete` instead. + +Apply this split in Dify UI: + +- `Autocomplete` — free-form text input with optional suggestions or completions. The input value may be custom and does not necessarily become a selected option. Use for search boxes, command-style suggestions, tag suggestions, and async text completion. +- `Combobox` — searchable picker whose value is one or more selected items from a collection. The chosen value is remembered by the root, and free-form text is not the final value. Use for model pickers, user pickers, dataset/document pickers, and multi-select chips. +- `Select` — closed-list picker without text entry. Use when the option set is small or already scannable and filtering is unnecessary. + +Composition rules: + +- Keep Base UI primitive semantics visible in the public API. Export compound parts such as `ComboboxInputGroup`, `ComboboxInput`, `ComboboxContent`, `ComboboxList`, `ComboboxItem`, and `ComboboxItemIndicator` instead of wrapping them into one business component. +- For `Combobox` multiple selection, follow the official chips pattern: `ComboboxInputGroup` contains `ComboboxChips`, `ComboboxValue` renders `ComboboxChip` items, and `ComboboxInput` remains inside the chips row. Chips should wrap and let the input group grow vertically instead of forcing horizontal overflow. +- Content primitives must own their Base UI `Portal` and use `z-1002` on `Positioner`, matching the overlay contract in `README.md`. +- Use `w-(--anchor-width)` with viewport-aware max-width for `Autocomplete` and `Combobox` popups. Do not add `min-w-(--anchor-width)` when it would defeat available-width clamping. + +[Autocomplete docs]: https://base-ui.com/react/components/autocomplete.md#usage-guidelines +[Combobox docs]: https://base-ui.com/react/components/combobox.md#usage-guidelines [docs]: https://base-ui.com/react/components/tooltip#infotips diff --git a/packages/dify-ui/README.md b/packages/dify-ui/README.md index cd9485c400..bdeeec33cb 100644 --- a/packages/dify-ui/README.md +++ b/packages/dify-ui/README.md @@ -1,6 +1,6 @@ # @langgenius/dify-ui -Shared UI primitives, design tokens, Tailwind preset, and the `cn()` utility consumed by Dify's `web/` app. +Shared UI primitives, design tokens, CSS-first Tailwind styles, and the `cn()` utility consumed by Dify's `web/` app. The primitives are thin, opinionated wrappers around [Base UI] headless components, styled with `cva` + `cn` and Dify design tokens. @@ -36,22 +36,36 @@ Importing from `@langgenius/dify-ui` (no subpath) is intentionally not supported ## Primitives -| Category | Subpath | Notes | -| -------- | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------- | -| Overlay | `./alert-dialog`, `./context-menu`, `./dialog`, `./dropdown-menu`, `./popover`, `./select`, `./toast`, `./tooltip` | Portalled. See [Overlay & portal contract] below. | -| Form | `./number-field`, `./slider`, `./switch` | Controlled / uncontrolled per Base UI defaults. | -| Layout | `./scroll-area` | Custom-styled scrollbar over the host viewport. | -| Media | `./avatar`, `./button` | Button exposes `cva` variants. | +| Category | Subpath | Notes | +| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | +| Overlay | `./alert-dialog`, `./autocomplete`, `./combobox`, `./context-menu`, `./dialog`, `./dropdown-menu`, `./popover`, `./select`, `./toast`, `./tooltip` | Portalled. See [Overlay & portal contract] below. | +| Form | `./autocomplete`, `./combobox`, `./number-field`, `./slider`, `./switch` | Controlled / uncontrolled per Base UI defaults. | +| Layout | `./scroll-area` | Custom-styled scrollbar over the host viewport. | +| Media | `./avatar`, `./button` | Button exposes `cva` variants. | Utilities: - `./cn` — `clsx` + `tailwind-merge` wrapper. Use this for conditional class composition. -- `./tailwind-preset` — Tailwind v4 preset with Dify tokens. Apps extend it from their own `tailwind.config.ts`. -- `./styles.css` — the one CSS entry that ships the design tokens, theme variables, and base reset. Import it once from the app root. +- `./styles.css` — the one CSS entry that ships the design tokens, theme variables, and project utilities/components. Import it once from the app root. + +## Tailwind CSS v4 integration + +This package uses Tailwind CSS v4's CSS-first configuration model. Consumers should import Tailwind from their own root stylesheet, then import this package's CSS entry: + +```css +@import 'tailwindcss'; +@import '@langgenius/dify-ui/styles.css'; +``` + +If a consumer uses Dify UI source files through the workspace, add an explicit source so Tailwind can detect utility classes: + +```css +@source '../packages/dify-ui/src'; +``` ## Overlay & portal contract -All overlay primitives (`dialog`, `alert-dialog`, `popover`, `dropdown-menu`, `context-menu`, `select`, `tooltip`, `toast`) render their content inside a [Base UI Portal] attached to `document.body`. This is the Base UI default — see the upstream [Portals][Base UI Portal] docs for the underlying behavior. Consumers **do not** need to wrap anything in a portal manually. +All overlay primitives (`dialog`, `alert-dialog`, `autocomplete`, `combobox`, `popover`, `dropdown-menu`, `context-menu`, `select`, `tooltip`, `toast`) render their content inside a [Base UI Portal] attached to `document.body`. This is the Base UI default — see the upstream [Portals][Base UI Portal] docs for the underlying behavior. Consumers **do not** need to wrap anything in a portal manually. ### Root isolation requirement @@ -69,14 +83,14 @@ Equivalent: any root element with `isolation: isolate` in CSS. Without it, overl Every overlay primitive uses a single, shared z-index. Do **not** override it at call sites. -| Layer | z-index | Where | -| ----------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------- | -| Overlays (Dialog, AlertDialog, Popover, DropdownMenu, ContextMenu, Select, Tooltip) | `z-1002` | Positioner / Backdrop | -| Toast viewport | `z-1003` | One layer above overlays so notifications are never hidden under a dialog. | +| Layer | z-index | Where | +| ----------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------- | +| Overlays (Dialog, AlertDialog, Autocomplete, Combobox, Popover, DropdownMenu, ContextMenu, Select, Tooltip) | `z-1002` | Positioner / Backdrop | +| Toast viewport | `z-1003` | One layer above overlays so notifications are never hidden under a dialog. | -Rationale: during Dify's migration from legacy `portal-to-follow-elem` / `base/modal` / `base/dialog` overlays to this package, new and old overlays coexist in the DOM. `z-1002` sits above any common legacy layer, eliminating per-call-site z-index hacks. Among themselves, new primitives share the same z-index and **rely on DOM order** for stacking — the portal mounted later wins. +Rationale: during Dify's migration from legacy `base/modal` / `base/dialog` overlays to this package, new and old overlays coexist in the DOM. `z-1002` sits above any common legacy layer, eliminating per-call-site z-index hacks. Among themselves, new primitives share the same z-index and **rely on DOM order** for stacking — the portal mounted later wins. -See `[web/docs/overlay-migration.md](../../web/docs/overlay-migration.md)` for the Dify-web migration history and the remaining legacy allowlist. Once the legacy overlays are gone, the values in this table can drop back to `z-50` / `z-51`. +See `[web/docs/overlay-migration.md](../../web/docs/overlay-migration.md)` for the Dify-web migration history. Once the legacy overlays are gone, the values in this table can drop back to `z-50` / `z-51`. ### Rules diff --git a/packages/dify-ui/package.json b/packages/dify-ui/package.json index 483db46986..20e94c7dee 100644 --- a/packages/dify-ui/package.json +++ b/packages/dify-ui/package.json @@ -5,10 +5,6 @@ "private": true, "exports": { "./styles.css": "./src/styles/styles.css", - "./tailwind-preset": { - "types": "./src/tailwind-preset.ts", - "import": "./src/tailwind-preset.ts" - }, "./cn": { "types": "./src/cn.ts", "import": "./src/cn.ts" @@ -17,6 +13,10 @@ "types": "./src/alert-dialog/index.tsx", "import": "./src/alert-dialog/index.tsx" }, + "./autocomplete": { + "types": "./src/autocomplete/index.tsx", + "import": "./src/autocomplete/index.tsx" + }, "./avatar": { "types": "./src/avatar/index.tsx", "import": "./src/avatar/index.tsx" @@ -25,6 +25,10 @@ "types": "./src/button/index.tsx", "import": "./src/button/index.tsx" }, + "./combobox": { + "types": "./src/combobox/index.tsx", + "import": "./src/combobox/index.tsx" + }, "./context-menu": { "types": "./src/context-menu/index.tsx", "import": "./src/context-menu/index.tsx" @@ -107,6 +111,7 @@ "@storybook/addon-themes": "catalog:", "@storybook/react-vite": "catalog:", "@tailwindcss/vite": "catalog:", + "@tanstack/react-virtual": "catalog:", "@types/react": "catalog:", "@types/react-dom": "catalog:", "@typescript/native-preview": "catalog:", diff --git a/packages/dify-ui/src/autocomplete/__tests__/index.spec.tsx b/packages/dify-ui/src/autocomplete/__tests__/index.spec.tsx new file mode 100644 index 0000000000..a7031c5b12 --- /dev/null +++ b/packages/dify-ui/src/autocomplete/__tests__/index.spec.tsx @@ -0,0 +1,252 @@ +import type { ReactNode } from 'react' +import { render } from 'vitest-browser-react' +import { + Autocomplete, + AutocompleteClear, + AutocompleteContent, + AutocompleteEmpty, + AutocompleteGroup, + AutocompleteInput, + AutocompleteInputGroup, + AutocompleteItem, + AutocompleteItemIndicator, + AutocompleteItemText, + AutocompleteLabel, + AutocompleteList, + AutocompleteSeparator, + AutocompleteStatus, + AutocompleteTrigger, +} from '../index' + +const renderWithSafeViewport = (ui: ReactNode) => render( +
+ {ui} +
, +) + +const asHTMLElement = (element: HTMLElement | SVGElement) => element as HTMLElement + +const renderAutocomplete = ({ + children, + open = false, + defaultValue = 'workflow', +}: { + children?: ReactNode + open?: boolean + defaultValue?: string +} = {}) => renderWithSafeViewport( + + {children ?? ( + <> + + + + + + + 2 suggestions + + + Workflow + + + + Dataset + + + No suggestions + + + )} + , +) + +describe('Autocomplete wrappers', () => { + describe('Input group and input', () => { + it('should apply medium input group and input classes by default', async () => { + const screen = await renderAutocomplete() + + await expect.element(screen.getByTestId('input-group')).toHaveClass('rounded-lg') + await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toHaveClass('px-3') + await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toHaveClass('system-sm-regular') + }) + + it('should apply large input group and input classes when large size is provided', async () => { + const screen = await renderAutocomplete({ + children: ( + + + + ), + }) + + await expect.element(screen.getByTestId('input-group')).toHaveClass('rounded-[10px]') + await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toHaveClass('px-4') + await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toHaveClass('system-md-regular') + }) + + it('should set input defaults and forward passthrough props', async () => { + const screen = await renderAutocomplete({ + children: ( + + + + ), + }) + + await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toHaveAttribute('autocomplete', 'off') + await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toHaveAttribute('type', 'text') + await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toHaveAttribute('placeholder', 'Find a resource') + await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toBeRequired() + await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toHaveClass('custom-input') + }) + }) + + describe('Controls', () => { + it('should provide fallback aria labels and decorative icons when labels are omitted', async () => { + const screen = await renderAutocomplete() + + await expect.element(screen.getByRole('button', { name: 'Clear autocomplete' })).toHaveAttribute('type', 'button') + await expect.element(screen.getByRole('button', { name: 'Open autocomplete suggestions' })).toHaveAttribute('type', 'button') + expect(screen.getByRole('button', { name: 'Clear autocomplete' }).element().querySelector('.i-ri-close-line')).toHaveAttribute('aria-hidden', 'true') + expect(screen.getByRole('button', { name: 'Open autocomplete suggestions' }).element().querySelector('.i-ri-arrow-down-s-line')).toHaveAttribute('aria-hidden', 'true') + }) + + it('should preserve explicit labels and custom children', async () => { + const screen = await renderAutocomplete({ + children: ( + + + + reset + + + open + + + ), + }) + + expect(screen.getByRole('button', { name: 'Reset search' }).element()).toContainElement(screen.getByTestId('custom-clear').element()) + expect(screen.getByRole('button', { name: 'Show suggestions' }).element()).toContainElement(screen.getByTestId('custom-trigger').element()) + expect(screen.getByRole('button', { name: 'Reset search' }).element().querySelector('.i-ri-close-line')).not.toBeInTheDocument() + expect(screen.getByRole('button', { name: 'Show suggestions' }).element().querySelector('.i-ri-arrow-down-s-line')).not.toBeInTheDocument() + }) + + it('should rely on aria-labelledby when provided instead of injecting fallback labels', async () => { + const screen = await renderAutocomplete({ + children: ( + <> + Clear from label + Trigger from label + + + + + + + ), + }) + + await expect.element(screen.getByRole('button', { name: 'Clear from label' })).not.toHaveAttribute('aria-label') + await expect.element(screen.getByRole('button', { name: 'Trigger from label' })).not.toHaveAttribute('aria-label') + }) + }) + + describe('Content and options', () => { + it('should use default overlay placement and Dify popup classes', async () => { + const screen = await renderAutocomplete({ open: true }) + + await expect.element(screen.getByRole('group', { name: 'autocomplete positioner' })).toHaveAttribute('data-side', 'bottom') + await expect.element(screen.getByRole('group', { name: 'autocomplete positioner' })).toHaveAttribute('data-align', 'start') + await expect.element(screen.getByRole('group', { name: 'autocomplete positioner' })).toHaveClass('z-1002') + await expect.element(screen.getByRole('dialog', { name: 'autocomplete popup' })).toHaveClass('rounded-xl') + await expect.element(screen.getByRole('dialog', { name: 'autocomplete popup' })).toHaveClass('w-(--anchor-width)') + await expect.element(screen.getByRole('listbox', { name: 'autocomplete list' })).toHaveClass('scroll-py-1') + }) + + it('should apply custom placement side and passthrough popup props', async () => { + const onPopupClick = vi.fn() + const screen = await renderWithSafeViewport( + + + + + + + + Workflow + + + + , + ) + + asHTMLElement(screen.getByRole('dialog', { name: 'autocomplete popup' }).element()).click() + + await expect.element(screen.getByRole('group', { name: 'autocomplete positioner' })).toHaveAttribute('data-side', 'top') + expect(onPopupClick).toHaveBeenCalledTimes(1) + }) + + it('should render item text indicator status and empty wrappers with design classes', async () => { + const screen = await renderAutocomplete({ open: true }) + + await expect.element(screen.getByText('Workflow')).toHaveClass('system-sm-medium') + await expect.element(screen.getByTestId('status')).toHaveClass('text-text-tertiary') + await expect.element(screen.getByTestId('empty')).toHaveClass('system-sm-regular') + expect(screen.getByText('Workflow').element().parentElement?.querySelector('.i-ri-arrow-right-line')).toHaveAttribute('aria-hidden', 'true') + }) + + it('should forward custom classes to label separator item text and indicator', async () => { + const screen = await renderWithSafeViewport( + + + + + + + + Resources + + + Workflow + + + + + + , + ) + + await expect.element(screen.getByText('Resources')).toHaveClass('custom-label') + await expect.element(screen.getByTestId('separator')).toHaveClass('custom-separator') + await expect.element(screen.getByRole('option', { name: 'Workflow' })).toHaveClass('custom-item') + await expect.element(screen.getByText('Workflow')).toHaveClass('custom-text') + await expect.element(screen.getByTestId('indicator')).toHaveClass('custom-indicator') + }) + }) +}) diff --git a/packages/dify-ui/src/autocomplete/index.stories.tsx b/packages/dify-ui/src/autocomplete/index.stories.tsx new file mode 100644 index 0000000000..71c7c6607d --- /dev/null +++ b/packages/dify-ui/src/autocomplete/index.stories.tsx @@ -0,0 +1,721 @@ +import type { Meta, StoryObj } from '@storybook/react-vite' +import type { Virtualizer } from '@tanstack/react-virtual' +import type { RefObject } from 'react' +import { useVirtualizer } from '@tanstack/react-virtual' +import { useEffect, useMemo, useRef, useState } from 'react' +import { + Autocomplete, + AutocompleteClear, + AutocompleteCollection, + AutocompleteContent, + AutocompleteEmpty, + AutocompleteGroup, + AutocompleteInput, + AutocompleteInputGroup, + AutocompleteItem, + AutocompleteItemText, + AutocompleteLabel, + AutocompleteList, + AutocompleteSeparator, + AutocompleteStatus, + AutocompleteTrigger, + useAutocompleteFilter, + useAutocompleteFilteredItems, +} from '.' +import { cn } from '../cn' + +type Suggestion = { + value: string + label: string + description?: string + icon?: string + meta?: string +} + +type SuggestionGroup = { + label: string + items: Suggestion[] +} + +const inputWidth = 'w-80' + +type StoryVirtualizer = Virtualizer + +const scrollHighlightedVirtualItem = ( + item: unknown, + { + reason, + index, + }: { + reason: 'keyboard' | 'pointer' | 'none' + index: number + }, + virtualizer: StoryVirtualizer | null, +) => { + if (!item || !virtualizer) + return + + const isStart = index === 0 + const isEnd = index === virtualizer.options.count - 1 + const shouldScroll = reason === 'none' || (reason === 'keyboard' && (isStart || isEnd)) + + if (shouldScroll) { + queueMicrotask(() => { + virtualizer.scrollToIndex(index, { align: isEnd ? 'start' : 'end' }) + }) + } +} + +const tagSuggestions: Suggestion[] = [ + { value: 'feature', label: 'feature', description: 'Product work and launch notes' }, + { value: 'fix', label: 'fix', description: 'Bug fixes and regressions' }, + { value: 'docs', label: 'docs', description: 'Documentation updates' }, + { value: 'internal', label: 'internal', description: 'Workspace-only notes' }, + { value: 'mobile', label: 'mobile', description: 'Mobile app issues' }, + { value: 'component: autocomplete', label: 'component: autocomplete', description: 'Base UI primitive wrapper' }, + { value: 'component: combobox', label: 'component: combobox', description: 'Filterable predefined selection' }, + { value: 'component: select', label: 'component: select', description: 'Compact predefined selection' }, +] + +const promptCompletions: Suggestion[] = [ + { value: 'summarize this conversation', label: 'summarize this conversation' }, + { value: 'summarize this dataset with citations', label: 'summarize this dataset with citations' }, + { value: 'summarize this workflow run for an operator', label: 'summarize this workflow run for an operator' }, + { value: 'summarize this support ticket in 3 bullets', label: 'summarize this support ticket in 3 bullets' }, +] + +const workflowSuggestions: Suggestion[] = [ + { value: 'http-request', label: 'HTTP Request', description: 'Call an external API', icon: 'i-ri-global-line', meta: 'Tool' }, + { value: 'knowledge-retrieval', label: 'Knowledge Retrieval', description: 'Search configured datasets', icon: 'i-ri-database-2-line', meta: 'Tool' }, + { value: 'code-execution', label: 'Code Execution', description: 'Run sandboxed snippets', icon: 'i-ri-code-s-slash-line', meta: 'Tool' }, + { value: 'template-transform', label: 'Template Transform', description: 'Compose variables into output', icon: 'i-ri-braces-line', meta: 'Tool' }, + { value: 'question-classifier', label: 'Question Classifier', description: 'Route by intent', icon: 'i-ri-git-branch-line', meta: 'Tool' }, + { value: 'parameter-extractor', label: 'Parameter Extractor', description: 'Extract typed values', icon: 'i-ri-list-check-3', meta: 'Tool' }, + { value: 'answer-node', label: 'Answer Node', description: 'Return a final assistant answer', icon: 'i-ri-message-3-line', meta: 'Node' }, + { value: 'iteration-node', label: 'Iteration Node', description: 'Run a loop over array items', icon: 'i-ri-repeat-line', meta: 'Node' }, + { value: 'variable-assigner', label: 'Variable Assigner', description: 'Persist intermediate state', icon: 'i-ri-pencil-ruler-2-line', meta: 'Node' }, +] + +const groupedSuggestions: SuggestionGroup[] = [ + { + label: 'Tags', + items: tagSuggestions.slice(0, 5), + }, + { + label: 'Workflow Suggestions', + items: workflowSuggestions.slice(0, 5), + }, + { + label: 'Prompt Starters', + items: promptCompletions.slice(0, 3), + }, +] + +const commandGroups: SuggestionGroup[] = [ + { + label: 'App', + items: [ + { value: '/run', label: 'Run workflow', description: 'Execute the current draft', icon: 'i-ri-play-circle-line' }, + { value: '/publish', label: 'Publish app', description: 'Ship the current configuration', icon: 'i-ri-upload-cloud-2-line' }, + { value: '/trace', label: 'Open trace', description: 'Inspect the latest workflow run', icon: 'i-ri-route-line' }, + ], + }, + { + label: 'Workspace', + items: [ + { value: '/dataset', label: 'Search datasets', description: 'Find knowledge attached to this app', icon: 'i-ri-database-line' }, + { value: '/members', label: 'Invite members', description: 'Open workspace access settings', icon: 'i-ri-user-add-line' }, + { value: '/usage', label: 'View usage', description: 'Open model and workflow usage', icon: 'i-ri-bar-chart-line' }, + ], + }, +] + +const remoteSuggestions: Suggestion[] = [ + { value: 'agent-builder', label: 'Agent Builder', description: 'Workspace app' }, + { value: 'agent-observability', label: 'Agent Observability', description: 'Dataset' }, + { value: 'agent-routing-dataset', label: 'Agent Routing Dataset', description: 'Knowledge source' }, +] + +const virtualizedSuggestions: Suggestion[] = Array.from({ length: 1000 }, (_, index) => { + const family = ['workflow', 'dataset', 'prompt', 'tool'][index % 4]! + const number = new Intl.NumberFormat('en-US', { + minimumIntegerDigits: 4, + }).format(index + 1) + + return { + value: `${family}-${index + 1}`, + label: `${family} suggestion ${number}`, + description: `Free-form autocomplete result from ${family} search`, + icon: family === 'dataset' + ? 'i-ri-database-2-line' + : family === 'prompt' + ? 'i-ri-text-snippet' + : family === 'tool' + ? 'i-ri-tools-line' + : 'i-ri-flow-chart', + meta: family, + } +}) + +const getSuggestionLabel = (item: Suggestion) => item.label + +const SuggestionItem = ({ + item, + index, + dense, +}: { + item: Suggestion + index?: number + dense?: boolean +}) => ( + + {item.icon && +) + +const TagSuggestionItem = ({ + item, + index, +}: { + item: Suggestion + index?: number +}) => ( + + {item.label} + {item.description && {item.description}} + +) + +const BasicTagAutocomplete = ({ + size = 'medium', +}: { + size?: 'small' | 'medium' | 'large' +}) => ( + + + + + + {(item: Suggestion, index: number) => ( + + )} + + No tag suggestion. Keep the typed value. + + +) + +const GroupedSuggestionList = () => { + const groups = useAutocompleteFilteredItems() + + return ( + + {groups.map((group, groupIndex) => ( + + {groupIndex > 0 && } + {group.label} + + {(item: Suggestion) => ( + + )} + + + ))} + + ) +} + +const CommandPaletteList = () => { + const groups = useAutocompleteFilteredItems() + + return ( + + {groups.map((group, groupIndex) => ( + + {groupIndex > 0 && } + {group.label} + + {(item: Suggestion) => ( + + + {item.icon && + + Enter + + + )} + + + ))} + + ) +} + +const LimitedStatus = ({ + total, +}: { + total: number +}) => { + const items = useAutocompleteFilteredItems() + const hidden = Math.max(0, total - items.length) + + return hidden > 0 + ? `${hidden} more suggestions hidden. Refine the query to narrow results.` + : `${items.length} suggestions available.` +} + +const AsyncSearchDemo = () => { + const [value, setValue] = useState('agent') + const [loading, setLoading] = useState(false) + const [items, setItems] = useState(remoteSuggestions) + + useEffect(() => { + setLoading(true) + const timeout = window.setTimeout(() => { + setItems( + value.trim() + ? remoteSuggestions.filter(item => item.label.toLowerCase().includes(value.trim().toLowerCase())) + : remoteSuggestions, + ) + setLoading(false) + }, 500) + + return () => window.clearTimeout(timeout) + }, [value]) + + return ( +
+ + + + + + {loading ? 'Loading suggestions…' : `${items.length} remote suggestions`} + + + {(item: Suggestion, index: number) => ( + + )} + + No remote suggestion. Keep the typed query. + + +
+ ) +} + +const VirtualizedSuggestionList = ({ + virtualizerRef, +}: { + virtualizerRef: RefObject +}) => { + const scrollRef = useRef(null) + const filteredItems = useAutocompleteFilteredItems() + const virtualizer = useVirtualizer({ + count: filteredItems.length, + getScrollElement: () => scrollRef.current, + estimateSize: () => 44, + overscan: 6, + }) + + useEffect(() => { + virtualizerRef.current = virtualizer + + return () => { + virtualizerRef.current = null + } + }, [virtualizer, virtualizerRef]) + + return ( +
+ + {virtualizer.getVirtualItems().map((virtualItem) => { + const item = filteredItems[virtualItem.index] + + if (!item) + return null + + return ( +
+ +
+ ) + })} +
+
+ ) +} + +const VirtualizedStatus = () => { + const filteredItems = useAutocompleteFilteredItems() + + return ( + + {filteredItems.length} + {' '} + matching suggestions. Selecting one only replaces the input text. + + ) +} + +const FuzzyHighlight = ({ + text, + query, +}: { + text: string + query: string +}) => { + const parts = useMemo(() => { + const trimmed = query.trim() + + if (!trimmed) + return [text] + + const escaped = trimmed.slice(0, 80).replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + return text.split(new RegExp(`(${escaped})`, 'i')) + }, [query, text]) + + return ( + <> + {parts.map((part, index) => ( + part.toLowerCase() === query.trim().toLowerCase() + ? {part} + : part + ))} + + ) +} + +const FuzzyMatchingDemo = () => { + const [value, setValue] = useState('retr') + const { contains } = useAutocompleteFilter({ sensitivity: 'base' }) + + return ( +
+ + + + + + {(item: Suggestion, index: number) => ( + + {item.icon && + )} + + No workflow suggestion. Keep typing freely. + + +
+ ) +} + +const meta = { + title: 'Base/UI/Autocomplete', + component: Autocomplete, + parameters: { + layout: 'centered', + docs: { + description: { + component: 'Compound autocomplete built on Base UI Autocomplete. Use it for free-form inputs where suggestions can replace or complete the typed text, but selection is not persistent state.', + }, + }, + }, + tags: ['autodocs'], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const SearchTags: Story = { + render: () => ( +
+ +
+ ), +} + +export const Sizes: Story = { + render: () => ( +
+ {(['small', 'medium', 'large'] as const).map(size => ( +
+ +
+ ))} +
+ ), +} + +export const InlineAutocomplete: Story = { + render: () => ( +
+ + + + + + {(item: Suggestion, index: number) => ( + + )} + + No inline completion. Continue typing freely. + + +
+ ), +} + +export const GroupedSuggestions: Story = { + render: () => ( +
+ + + + + + No suggestion. Use the text as entered. + + +
+ ), +} + +export const FuzzyMatching: Story = { + render: () => , +} + +export const LimitResults: Story = { + render: () => ( +
+ + + + + + + + + {(item: Suggestion, index: number) => ( + + )} + + No suggestion. Submit the typed text instead. + + +
+ ), +} + +export const CommandPalette: Story = { + render: () => ( +
+ + + + + +
+ ), +} + +const VirtualizedLongSuggestionsDemo = () => { + const virtualizerRef = useRef(null) + + return ( +
+ { + scrollHighlightedVirtualItem(item, details, virtualizerRef.current) + }} + > + + + + + + No suggestion. Free-form text is still valid. + + +
+ ) +} + +export const VirtualizedLongSuggestions: Story = { + render: () => , +} + +export const AsyncSearch: Story = { + render: () => , +} + +export const Empty: Story = { + render: () => ( +
+ + + + + + {(item: Suggestion, index: number) => ( + + )} + + No tag suggestion. The custom text remains valid. + + +
+ ), +} + +export const DisabledAndReadOnly: Story = { + render: () => ( +
+ + + + + + + + + {(item: Suggestion, index: number) => ( + + )} + + + + + + + + + + + + {(item: Suggestion, index: number) => ( + + )} + + + +
+ ), +} diff --git a/packages/dify-ui/src/autocomplete/index.tsx b/packages/dify-ui/src/autocomplete/index.tsx new file mode 100644 index 0000000000..16c4b19673 --- /dev/null +++ b/packages/dify-ui/src/autocomplete/index.tsx @@ -0,0 +1,381 @@ +'use client' + +import type { VariantProps } from 'class-variance-authority' +import type { HTMLAttributes, ReactNode } from 'react' +import type { Placement } from '../placement' +import { Autocomplete as BaseAutocomplete } from '@base-ui/react/autocomplete' +import { cva } from 'class-variance-authority' +import { cn } from '../cn' +import { + overlayIndicatorClassName, + overlayLabelClassName, + overlayPopupAnimationClassName, + overlaySeparatorClassName, +} from '../overlay-shared' +import { parsePlacement } from '../placement' + +export type { Placement } + +export const Autocomplete = BaseAutocomplete.Root +export const AutocompleteValue = BaseAutocomplete.Value +export const AutocompleteGroup = BaseAutocomplete.Group +export const AutocompleteCollection = BaseAutocomplete.Collection +export const AutocompleteRow = BaseAutocomplete.Row +export const useAutocompleteFilter = BaseAutocomplete.useFilter +export const useAutocompleteFilteredItems = BaseAutocomplete.useFilteredItems + +export type AutocompleteRootProps = BaseAutocomplete.Root.Props +export type AutocompleteRootChangeEventDetails = BaseAutocomplete.Root.ChangeEventDetails +export type AutocompleteRootHighlightEventDetails = BaseAutocomplete.Root.HighlightEventDetails + +const autocompletePopupClassName = [ + 'w-(--anchor-width) max-w-[min(28rem,var(--available-width))] overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg outline-hidden', + 'data-side-top:origin-bottom data-side-bottom:origin-top data-side-left:origin-right data-side-right:origin-left', +] + +const autocompleteListClassName = [ + 'max-h-[min(20rem,var(--available-height))] overflow-y-auto overflow-x-hidden overscroll-contain p-1 outline-hidden scroll-py-1', + 'data-empty:max-h-none data-empty:p-0', +] + +const autocompleteItemClassName = [ + 'mx-1 flex min-h-8 cursor-pointer select-none items-center gap-2 rounded-lg px-2 py-1.5 text-text-secondary outline-hidden transition-colors', + 'hover:bg-state-base-hover-alt hover:text-text-primary', + 'data-highlighted:bg-state-base-hover data-highlighted:text-text-primary', + 'data-disabled:cursor-not-allowed data-disabled:opacity-30 data-disabled:hover:bg-transparent data-disabled:hover:text-text-secondary', + 'motion-reduce:transition-none', +] + +const autocompleteInputGroupVariants = cva( + [ + 'group/autocomplete flex w-full min-w-0 items-center border border-transparent bg-components-input-bg-normal text-components-input-text-filled shadow-none outline-hidden transition-[background-color,border-color,box-shadow]', + 'hover:border-components-input-border-hover hover:bg-components-input-bg-hover', + 'focus-within:border-components-input-border-active focus-within:bg-components-input-bg-active focus-within:shadow-xs', + 'data-focused:border-components-input-border-active data-focused:bg-components-input-bg-active data-focused:shadow-xs', + 'data-disabled:cursor-not-allowed data-disabled:border-transparent data-disabled:bg-components-input-bg-disabled data-disabled:text-components-input-text-filled-disabled', + 'data-disabled:hover:border-transparent data-disabled:hover:bg-components-input-bg-disabled', + 'data-readonly:shadow-none data-readonly:hover:border-transparent data-readonly:hover:bg-components-input-bg-normal', + 'motion-reduce:transition-none', + ], + { + variants: { + size: { + small: 'h-6 rounded-md', + medium: 'h-8 rounded-lg', + large: 'h-9 rounded-[10px]', + }, + }, + defaultVariants: { + size: 'medium', + }, + }, +) + +export type AutocompleteSize = NonNullable['size']> + +export type AutocompleteInputGroupProps + = BaseAutocomplete.InputGroup.Props + & VariantProps + +export function AutocompleteInputGroup({ + className, + size = 'medium', + ...props +}: AutocompleteInputGroupProps) { + return ( + + ) +} + +const autocompleteInputVariants = cva( + [ + 'w-0 min-w-0 flex-1 appearance-none border-0 bg-transparent text-components-input-text-filled caret-primary-600 outline-hidden', + 'placeholder:text-components-input-text-placeholder', + 'disabled:cursor-not-allowed disabled:text-components-input-text-filled-disabled disabled:placeholder:text-components-input-text-disabled', + 'data-readonly:cursor-default', + ], + { + variants: { + size: { + small: 'px-2 py-1 system-xs-regular', + medium: 'px-3 py-[7px] system-sm-regular', + large: 'px-4 py-2 system-md-regular', + }, + }, + defaultVariants: { + size: 'medium', + }, + }, +) + +export type AutocompleteInputProps + = Omit + & VariantProps + +export function AutocompleteInput({ + className, + size = 'medium', + type = 'text', + autoComplete = 'off', + ...props +}: AutocompleteInputProps) { + return ( + + ) +} + +const autocompleteControlVariants = cva( + [ + 'flex shrink-0 touch-manipulation items-center justify-center rounded-md text-text-tertiary outline-hidden transition-colors', + 'hover:bg-components-input-bg-hover hover:text-text-secondary focus-visible:bg-components-input-bg-hover focus-visible:text-text-secondary', + 'focus-visible:ring-1 focus-visible:ring-components-input-border-active focus-visible:ring-inset', + 'disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-text-tertiary disabled:focus-visible:bg-transparent disabled:focus-visible:ring-0', + 'group-data-disabled/autocomplete:cursor-not-allowed group-data-disabled/autocomplete:hover:bg-transparent group-data-disabled/autocomplete:focus-visible:bg-transparent group-data-disabled/autocomplete:focus-visible:ring-0', + 'group-data-readonly/autocomplete:hidden', + 'motion-reduce:transition-none', + ], + { + variants: { + size: { + small: 'mr-1 size-4', + medium: 'mr-1.5 size-5', + large: 'mr-2 size-5', + }, + }, + defaultVariants: { + size: 'medium', + }, + }, +) + +export type AutocompleteControlProps + = Omit + & VariantProps + & { className?: string } + +export function AutocompleteTrigger({ + className, + children, + size = 'medium', + type = 'button', + ...props +}: AutocompleteControlProps) { + return ( + + {children ?? + ) +} + +export type AutocompleteClearProps + = Omit + & VariantProps + & { className?: string } + +export function AutocompleteClear({ + className, + children, + size = 'medium', + type = 'button', + ...props +}: AutocompleteClearProps) { + return ( + + {children ?? + ) +} + +export function AutocompleteIcon({ + className, + children, + ...props +}: BaseAutocomplete.Icon.Props) { + return ( + + {children ?? + ) +} + +type AutocompleteContentProps = { + children: ReactNode + placement?: Placement + sideOffset?: number + alignOffset?: number + className?: string + popupClassName?: string + portalProps?: Omit + positionerProps?: Omit< + BaseAutocomplete.Positioner.Props, + 'children' | 'className' | 'side' | 'align' | 'sideOffset' | 'alignOffset' + > + popupProps?: Omit< + BaseAutocomplete.Popup.Props, + 'children' | 'className' + > +} + +export function AutocompleteContent({ + children, + placement = 'bottom-start', + sideOffset = 4, + alignOffset = 0, + className, + popupClassName, + portalProps, + positionerProps, + popupProps, +}: AutocompleteContentProps) { + const { side, align } = parsePlacement(placement) + + return ( + + + + {children} + + + + ) +} + +export function AutocompleteList({ + className, + ...props +}: BaseAutocomplete.List.Props) { + return ( + + ) +} + +export function AutocompleteItem({ + className, + ...props +}: BaseAutocomplete.Item.Props) { + return ( + + ) +} + +export type AutocompleteItemTextProps = HTMLAttributes + +export function AutocompleteItemText({ + className, + ...props +}: AutocompleteItemTextProps) { + return ( + + ) +} + +export function AutocompleteLabel({ + className, + ...props +}: BaseAutocomplete.GroupLabel.Props) { + return ( + + ) +} + +export function AutocompleteSeparator({ + className, + ...props +}: BaseAutocomplete.Separator.Props) { + return ( + + ) +} + +export function AutocompleteEmpty({ + className, + ...props +}: BaseAutocomplete.Empty.Props) { + return ( + + ) +} + +export function AutocompleteStatus({ + className, + ...props +}: BaseAutocomplete.Status.Props) { + return ( + + ) +} + +export function AutocompleteItemIndicator({ + className, + children, + ...props +}: HTMLAttributes) { + return ( + + {children ?? + ) +} diff --git a/packages/dify-ui/src/combobox/__tests__/index.spec.tsx b/packages/dify-ui/src/combobox/__tests__/index.spec.tsx new file mode 100644 index 0000000000..705ebe9601 --- /dev/null +++ b/packages/dify-ui/src/combobox/__tests__/index.spec.tsx @@ -0,0 +1,363 @@ +import type { ReactNode } from 'react' +import { render } from 'vitest-browser-react' +import { + Combobox, + ComboboxChip, + ComboboxChipRemove, + ComboboxChips, + ComboboxClear, + ComboboxContent, + ComboboxEmpty, + ComboboxGroup, + ComboboxGroupLabel, + ComboboxInput, + ComboboxInputGroup, + ComboboxInputTrigger, + ComboboxItem, + ComboboxItemIndicator, + ComboboxItemText, + ComboboxLabel, + ComboboxList, + ComboboxSeparator, + ComboboxStatus, + ComboboxTrigger, + ComboboxValue, +} from '../index' + +const renderWithSafeViewport = (ui: ReactNode) => render( +
+ {ui} +
, +) + +const asHTMLElement = (element: HTMLElement | SVGElement) => element as HTMLElement + +const renderSelectLikeCombobox = ({ + children, + open = false, +}: { + children?: ReactNode + open?: boolean +} = {}) => renderWithSafeViewport( + + {children ?? ( + <> + Resource type + + + + + 2 options + + + Workflow + + + + Dataset + + + No options + + + )} + , +) + +const renderInputCombobox = ({ + children, + open = false, +}: { + children?: ReactNode + open?: boolean +} = {}) => renderWithSafeViewport( + + {children ?? ( + <> + + + + + + + + + Workflow + + + + + + )} + , +) + +describe('Combobox wrappers', () => { + describe('Select-like trigger', () => { + it('should render label and apply medium trigger classes by default', async () => { + const screen = await renderSelectLikeCombobox() + + await expect.element(screen.getByText('Resource type')).toHaveClass('system-sm-medium') + await expect.element(screen.getByRole('combobox', { name: 'Resource type' })).toHaveClass('rounded-lg') + await expect.element(screen.getByRole('combobox', { name: 'Resource type' })).toHaveClass('system-sm-regular') + }) + + it('should apply small and large trigger size variants', async () => { + const smallScreen = await renderSelectLikeCombobox({ + children: ( + + + + ), + }) + + await expect.element(smallScreen.getByRole('combobox', { name: 'Small resource type' })).toHaveClass('rounded-md') + await expect.element(smallScreen.getByRole('combobox', { name: 'Small resource type' })).toHaveClass('system-xs-regular') + + const largeScreen = await renderSelectLikeCombobox({ + children: ( + + + + ), + }) + + await expect.element(largeScreen.getByRole('combobox', { name: 'Large resource type' })).toHaveClass('rounded-[10px]') + await expect.element(largeScreen.getByRole('combobox', { name: 'Large resource type' })).toHaveClass('system-md-regular') + }) + + it('should render default trigger icon and support hiding it', async () => { + const withIcon = await renderSelectLikeCombobox() + + expect(withIcon.getByTestId('trigger').element().querySelector('.i-ri-arrow-down-s-line')).toHaveAttribute('aria-hidden', 'true') + + const withoutIcon = await renderSelectLikeCombobox({ + children: ( + + + + ), + }) + + expect(withoutIcon.getByRole('combobox', { name: 'Resource type without icon' }).element().querySelector('.i-ri-arrow-down-s-line')).not.toBeInTheDocument() + }) + }) + + describe('Input group and controls', () => { + it('should apply medium input group and input classes by default', async () => { + const screen = await renderInputCombobox() + + await expect.element(screen.getByTestId('input-group')).toHaveClass('rounded-lg') + await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toHaveClass('px-3') + await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toHaveClass('system-sm-regular') + }) + + it('should apply large input group and input classes when large size is provided', async () => { + const screen = await renderInputCombobox({ + children: ( + + + + ), + }) + + await expect.element(screen.getByTestId('input-group')).toHaveClass('rounded-[10px]') + await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toHaveClass('px-4') + await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toHaveClass('system-md-regular') + }) + + it('should set input defaults and forward passthrough props', async () => { + const screen = await renderInputCombobox({ + children: ( + + + + ), + }) + + await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toHaveAttribute('autocomplete', 'off') + await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toHaveAttribute('type', 'text') + await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toHaveAttribute('placeholder', 'Find a resource') + await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toBeRequired() + await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toHaveClass('custom-input') + }) + + it('should provide fallback aria labels and decorative icons for input controls', async () => { + const screen = await renderInputCombobox() + + await expect.element(screen.getByRole('button', { name: 'Clear combobox' })).toHaveAttribute('type', 'button') + await expect.element(screen.getByRole('button', { name: 'Open combobox options' })).toHaveAttribute('type', 'button') + expect(screen.getByRole('button', { name: 'Clear combobox' }).element().querySelector('.i-ri-close-line')).toHaveAttribute('aria-hidden', 'true') + expect(screen.getByRole('button', { name: 'Open combobox options' }).element().querySelector('.i-ri-arrow-down-s-line')).toHaveAttribute('aria-hidden', 'true') + }) + + it('should rely on aria-labelledby when provided instead of injecting fallback labels', async () => { + const screen = await renderInputCombobox({ + children: ( + <> + Clear from label + Trigger from label + + + + + + + ), + }) + + await expect.element(screen.getByRole('button', { name: 'Clear from label' })).not.toHaveAttribute('aria-label') + await expect.element(screen.getByRole('button', { name: 'Trigger from label' })).not.toHaveAttribute('aria-label') + }) + }) + + describe('Content and options', () => { + it('should use default overlay placement and Dify popup classes', async () => { + const screen = await renderSelectLikeCombobox({ open: true }) + + await expect.element(screen.getByRole('group', { name: 'combobox positioner' })).toHaveAttribute('data-side', 'bottom') + await expect.element(screen.getByRole('group', { name: 'combobox positioner' })).toHaveAttribute('data-align', 'start') + await expect.element(screen.getByRole('group', { name: 'combobox positioner' })).toHaveClass('z-1002') + await expect.element(screen.getByRole('dialog', { name: 'combobox popup' })).toHaveClass('rounded-xl') + await expect.element(screen.getByRole('dialog', { name: 'combobox popup' })).toHaveClass('w-(--anchor-width)') + await expect.element(screen.getByRole('listbox', { name: 'combobox list' })).toHaveClass('scroll-py-1') + }) + + it('should apply custom placement side and passthrough popup props', async () => { + const onPopupClick = vi.fn() + const screen = await renderWithSafeViewport( + + + + + + + + Workflow + + + + , + ) + + asHTMLElement(screen.getByRole('dialog', { name: 'combobox popup' }).element()).click() + + await expect.element(screen.getByRole('group', { name: 'combobox positioner' })).toHaveAttribute('data-side', 'top') + expect(onPopupClick).toHaveBeenCalledTimes(1) + }) + + it('should render item text indicator status and empty wrappers with design classes', async () => { + const screen = await renderSelectLikeCombobox({ open: true }) + + await expect.element(screen.getByTestId('list').getByText('Workflow')).toHaveClass('system-sm-medium') + await expect.element(screen.getByTestId('status')).toHaveClass('text-text-tertiary') + await expect.element(screen.getByTestId('empty')).toHaveClass('system-sm-regular') + expect(screen.getByTestId('list').getByText('Workflow').element().parentElement?.querySelector('.i-ri-check-line')).toHaveAttribute('aria-hidden', 'true') + }) + + it('should forward custom classes to group label separator item text and indicator', async () => { + const screen = await renderWithSafeViewport( + + + + + + + + Resources + + + Workflow + + + + + + , + ) + + await expect.element(screen.getByText('Resources')).toHaveClass('custom-label') + await expect.element(screen.getByTestId('separator')).toHaveClass('custom-separator') + await expect.element(screen.getByRole('option', { name: 'Workflow' })).toHaveClass('custom-item') + await expect.element(screen.getByTestId('custom-list').getByText('Workflow')).toHaveClass('custom-text') + await expect.element(screen.getByTestId('indicator')).toHaveClass('custom-indicator') + }) + }) + + describe('Multiple selection chips', () => { + it('should render chip wrappers and default remove button label', async () => { + const screen = await renderWithSafeViewport( + + + + {(selectedValue: string[]) => ( + + {selectedValue.map(item => ( + + {item} + + + ))} + + )} + + + + , + ) + + await expect.element(screen.getByTestId('chips')).toHaveClass('custom-chips') + await expect.element(screen.getByText('maya').element().parentElement!).toHaveClass('custom-chip') + await expect.element(screen.getByRole('button', { name: 'Remove selected item' })).toHaveAttribute('type', 'button') + expect(screen.getByTestId('remove-chip').element().querySelector('.i-ri-close-line')).toHaveAttribute('aria-hidden', 'true') + }) + + it('should preserve chip remove aria-labelledby over fallback label', async () => { + const screen = await renderWithSafeViewport( + + + + {(selectedValue: string[]) => ( + + {selectedValue.map(item => ( + + Remove Maya + + + ))} + + )} + + + + , + ) + + await expect.element(screen.getByRole('button', { name: 'Remove Maya' })).not.toHaveAttribute('aria-label') + }) + }) +}) diff --git a/packages/dify-ui/src/combobox/index.stories.tsx b/packages/dify-ui/src/combobox/index.stories.tsx new file mode 100644 index 0000000000..f2b5f4d4c6 --- /dev/null +++ b/packages/dify-ui/src/combobox/index.stories.tsx @@ -0,0 +1,618 @@ +import type { Meta, StoryObj } from '@storybook/react-vite' +import type { Virtualizer } from '@tanstack/react-virtual' +import type { RefObject } from 'react' +import { useVirtualizer } from '@tanstack/react-virtual' +import { useEffect, useRef, useState } from 'react' +import { + Combobox, + ComboboxChip, + ComboboxChipRemove, + ComboboxChips, + ComboboxClear, + ComboboxCollection, + ComboboxContent, + ComboboxEmpty, + ComboboxGroup, + ComboboxGroupLabel, + ComboboxInput, + ComboboxInputGroup, + ComboboxInputTrigger, + ComboboxItem, + ComboboxItemIndicator, + ComboboxItemText, + ComboboxLabel, + ComboboxList, + ComboboxSeparator, + ComboboxStatus, + ComboboxTrigger, + ComboboxValue, + useComboboxFilteredItems, +} from '.' +import { cn } from '../cn' + +type Option = { + value: string + label: string + meta?: string + icon?: string + disabled?: boolean +} + +type OptionGroup = { + label: string + items: Option[] +} + +const fieldWidth = 'w-80' +const wideFieldWidth = 'w-[520px]' +const nativeFieldLabelClassName = 'mb-1 block text-text-secondary system-sm-medium' + +type StoryVirtualizer = Virtualizer + +const scrollHighlightedVirtualItem = ( + item: unknown, + { + reason, + index, + }: { + reason: 'keyboard' | 'pointer' | 'none' + index: number + }, + virtualizer: StoryVirtualizer | null, +) => { + if (!item || !virtualizer) + return + + const isStart = index === 0 + const isEnd = index === virtualizer.options.count - 1 + const shouldScroll = reason === 'none' || (reason === 'keyboard' && (isStart || isEnd)) + + if (shouldScroll) { + queueMicrotask(() => { + virtualizer.scrollToIndex(index, { align: isEnd ? 'start' : 'end' }) + }) + } +} + +const providerOptions: Option[] = [ + { value: 'openai', label: 'OpenAI', meta: 'GPT-5, GPT-4.1', icon: 'i-ri-openai-fill' }, + { value: 'anthropic', label: 'Anthropic', meta: 'Claude Opus, Sonnet', icon: 'i-ri-sparkling-2-line' }, + { value: 'google', label: 'Google', meta: 'Gemini 2.5', icon: 'i-ri-google-fill' }, + { value: 'azure-openai', label: 'Azure OpenAI', meta: 'Enterprise workspace', icon: 'i-ri-microsoft-fill' }, + { value: 'localai', label: 'LocalAI', meta: 'Self-hosted endpoint', icon: 'i-ri-server-line', disabled: true }, +] + +const dataSourceOptions: Option[] = [ + { value: 'knowledge-base', label: 'Knowledge Base', meta: 'Vector index', icon: 'i-ri-database-2-line' }, + { value: 'notion', label: 'Notion', meta: 'Synced pages', icon: 'i-ri-notion-fill' }, + { value: 'website', label: 'Website crawler', meta: 'Public URLs', icon: 'i-ri-global-line' }, + { value: 's3', label: 'S3 bucket', meta: 'Private files', icon: 'i-ri-cloud-line' }, + { value: 'slack', label: 'Slack', meta: 'Channel history', icon: 'i-ri-slack-fill' }, +] + +const reviewerOptions: Option[] = [ + { value: 'maya', label: 'Maya Chen', meta: 'Product owner' }, + { value: 'liam', label: 'Liam Brooks', meta: 'Prompt engineer' }, + { value: 'nora', label: 'Nora Park', meta: 'Data steward' }, + { value: 'owen', label: 'Owen Reed', meta: 'Security reviewer' }, + { value: 'yuki', label: 'Yuki Tanaka', meta: 'ML engineer' }, +] + +const toolGroups: OptionGroup[] = [ + { + label: 'Retrieval', + items: [ + { value: 'dataset-search', label: 'Dataset search', meta: 'Search workspace knowledge', icon: 'i-ri-search-eye-line' }, + { value: 'web-scraper', label: 'Web scraper', meta: 'Fetch public pages', icon: 'i-ri-global-line' }, + ], + }, + { + label: 'Actions', + items: [ + { value: 'http-request', label: 'HTTP request', meta: 'Call external APIs', icon: 'i-ri-terminal-box-line' }, + { value: 'code-runner', label: 'Code runner', meta: 'Execute sandboxed scripts', icon: 'i-ri-code-s-slash-line' }, + ], + }, + { + label: 'Operations', + items: [ + { value: 'human-review', label: 'Human review', meta: 'Assign approval task', icon: 'i-ri-user-voice-line' }, + { value: 'audit-log', label: 'Audit log', meta: 'Record workflow events', icon: 'i-ri-file-list-3-line' }, + ], + }, +] + +const tagOptions: Option[] = [ + { value: 'rag', label: 'RAG' }, + { value: 'agent', label: 'Agent' }, + { value: 'production', label: 'Production' }, + { value: 'evaluation', label: 'Evaluation' }, + { value: 'finance', label: 'Finance' }, + { value: 'support', label: 'Support' }, +] + +const directoryOptions: Option[] = [ + { value: 'maya-chen', label: 'Maya Chen', meta: 'Product owner · maya@example.com', icon: 'i-ri-user-3-line' }, + { value: 'liam-brooks', label: 'Liam Brooks', meta: 'Prompt engineer · liam@example.com', icon: 'i-ri-user-3-line' }, + { value: 'nora-park', label: 'Nora Park', meta: 'Data steward · nora@example.com', icon: 'i-ri-user-3-line' }, + { value: 'owen-reed', label: 'Owen Reed', meta: 'Security reviewer · owen@example.com', icon: 'i-ri-shield-user-line' }, + { value: 'yuki-tanaka', label: 'Yuki Tanaka', meta: 'ML engineer · yuki@example.com', icon: 'i-ri-user-3-line' }, + { value: 'ava-martin', label: 'Ava Martin', meta: 'Support lead · ava@example.com', icon: 'i-ri-customer-service-2-line' }, +] + +const emptyOptions: Option[] = [ + { value: 'billing', label: 'Billing connector' }, + { value: 'zendesk', label: 'Zendesk' }, + { value: 'github', label: 'GitHub issues' }, +] + +const modelCatalogOptions: Option[] = Array.from({ length: 1000 }, (_, index) => { + const provider = ['OpenAI', 'Anthropic', 'Google', 'Mistral', 'DeepSeek'][index % 5]! + const family = ['chat', 'reasoning', 'vision', 'embedding'][index % 4]! + const number = new Intl.NumberFormat('en-US', { + minimumIntegerDigits: 4, + }).format(index + 1) + + return { + value: `model-${index + 1}`, + label: `${provider} ${family} ${number}`, + meta: `${provider} provider · ${family}`, + icon: family === 'embedding' + ? 'i-ri-vector-triangle' + : family === 'vision' + ? 'i-ri-image-circle-line' + : family === 'reasoning' + ? 'i-ri-brain-line' + : 'i-ri-chat-1-line', + } +}) + +const sizeOptions: Option[] = providerOptions.slice(0, 3) +const defaultProvider = providerOptions[0]! +const disabledProvider = providerOptions[1]! +const defaultDataSource = dataSourceOptions[0]! +const defaultPopupDataSource = dataSourceOptions[1]! +const readOnlyDataSource = dataSourceOptions[2]! +const defaultTool = toolGroups[0]!.items[0]! +const defaultReviewers = [reviewerOptions[0]!, reviewerOptions[2]!] +const defaultTag = tagOptions[2]! + +const renderOptionItem = (option: Option, index?: number) => ( + + + {option.icon && } + + {option.label} + {option.meta && {option.meta}} + + + + +) + +const renderSimpleOptionItem = (option: Option, index?: number) => ( + + {option.label} + + +) + +const PopupSearchInput = ({ + label, + placeholder, +}: { + label: string + placeholder: string +}) => ( + + + + + +) + +const GroupedToolList = () => { + const groups = useComboboxFilteredItems() + + return ( + + {groups.map((group, groupIndex) => ( + + {groupIndex > 0 && } + {group.label} + + {(option: Option) => renderOptionItem(option)} + + + ))} + + ) +} + +const VirtualizedModelList = ({ + virtualizerRef, +}: { + virtualizerRef: RefObject +}) => { + const scrollRef = useRef(null) + const filteredItems = useComboboxFilteredItems