diff --git a/api/controllers/console/app/message.py b/api/controllers/console/app/message.py index 195a41f2888..f987ecca745 100644 --- a/api/controllers/console/app/message.py +++ b/api/controllers/console/app/message.py @@ -167,12 +167,16 @@ register_schema_models( ChatMessagesQuery, MessageFeedbackPayload, FeedbackExportQuery, +) +register_response_schema_models( + console_ns, AnnotationCountResponse, SuggestedQuestionsResponse, MessageDetailResponse, MessageInfiniteScrollPaginationResponse, + SimpleResultResponse, + TextFileResponse, ) -register_response_schema_models(console_ns, SimpleResultResponse, TextFileResponse) @console_ns.route("/apps//chat-messages") diff --git a/api/controllers/console/explore/trial.py b/api/controllers/console/explore/trial.py index 6aef9129780..fd614ece87f 100644 --- a/api/controllers/console/explore/trial.py +++ b/api/controllers/console/explore/trial.py @@ -1,28 +1,24 @@ import logging -from typing import Any, Literal, cast +from typing import Literal from flask import request -from flask_restx import Resource, fields, marshal, marshal_with +from flask_restx import Resource from pydantic import BaseModel, Field from sqlalchemy import select from werkzeug.exceptions import Forbidden, InternalServerError, NotFound import services -from controllers.common.fields import ( - AudioBinaryResponse, - AudioTranscriptResponse, - GeneratedAppResponse, - SimpleResultResponse, -) +from controllers.common.fields import AudioBinaryResponse, AudioTranscriptResponse, SimpleResultResponse from controllers.common.fields import Parameters as ParametersResponse from controllers.common.fields import Site as SiteResponse from controllers.common.schema import ( - get_or_create_model, query_params_from_model, + query_params_from_request, register_response_schema_models, register_schema_models, ) from controllers.console import console_ns +from controllers.console.app.app import AppDetailWithSite from controllers.console.app.error import ( AppUnavailableError, AudioTooLargeError, @@ -36,6 +32,7 @@ from controllers.console.app.error import ( ProviderQuotaExceededError, UnsupportedAudioTypeError, ) +from controllers.console.app.workflow import WorkflowResponse from controllers.console.app.wraps import get_app_model_with_trial from controllers.console.explore.error import ( AppSuggestedQuestionsAfterAnswerDisabledError, @@ -56,26 +53,13 @@ from core.errors.error import ( ) from extensions.ext_database import db from extensions.ext_redis import redis_client -from fields.app_fields import ( - app_detail_fields_with_site, - deleted_tool_fields, - model_config_fields, - site_fields, - tag_fields, -) -from fields.dataset_fields import dataset_fields -from fields.member_fields import simple_account_fields +from fields.base import ResponseModel +from fields.dataset_fields import DatasetDetailResponse from fields.message_fields import SuggestedQuestionsResponse -from fields.workflow_fields import ( - conversation_variable_fields, - pipeline_variable_fields, - workflow_fields, - workflow_partial_fields, -) from graphon.graph_engine.manager import GraphEngineManager from graphon.model_runtime.errors.invoke import InvokeError from libs import helper -from libs.helper import uuid_value +from libs.helper import dump_response, uuid_value from models import Account from models.account import TenantStatus from models.model import AppMode, Site @@ -102,57 +86,42 @@ from services.recommended_app_service import RecommendedAppService logger = logging.getLogger(__name__) -model_config_model = get_or_create_model("TrialAppModelConfig", model_config_fields) -workflow_partial_model = get_or_create_model("TrialWorkflowPartial", workflow_partial_fields) -deleted_tool_model = get_or_create_model("TrialDeletedTool", deleted_tool_fields) -tag_model = get_or_create_model("TrialTag", tag_fields) -site_model = get_or_create_model("TrialSite", site_fields) +class TrialDatasetListItemResponse(DatasetDetailResponse): + pass -app_detail_fields_with_site_copy = app_detail_fields_with_site.copy() -app_detail_fields_with_site_copy["model_config"] = fields.Nested( - model_config_model, attribute="app_model_config", allow_null=True -) -app_detail_fields_with_site_copy["workflow"] = fields.Nested(workflow_partial_model, allow_null=True) -app_detail_fields_with_site_copy["deleted_tools"] = fields.List(fields.Nested(deleted_tool_model)) -app_detail_fields_with_site_copy["tags"] = fields.List(fields.Nested(tag_model)) -app_detail_fields_with_site_copy["site"] = fields.Nested(site_model) -app_detail_with_site_model = get_or_create_model("TrialAppDetailWithSite", app_detail_fields_with_site_copy) -simple_account_model = get_or_create_model("TrialSimpleAccount", simple_account_fields) -conversation_variable_model = get_or_create_model("TrialConversationVariable", conversation_variable_fields) -pipeline_variable_model = get_or_create_model("TrialPipelineVariable", pipeline_variable_fields) +class TrialDatasetListResponse(ResponseModel): + data: list[TrialDatasetListItemResponse] + has_more: bool + limit: int + total: int + page: int -workflow_fields_copy = workflow_fields.copy() -workflow_fields_copy["created_by"] = fields.Nested(simple_account_model, attribute="created_by_account") -workflow_fields_copy["updated_by"] = fields.Nested( - simple_account_model, attribute="updated_by_account", allow_null=True -) -workflow_fields_copy["conversation_variables"] = fields.List(fields.Nested(conversation_variable_model)) -workflow_fields_copy["rag_pipeline_variables"] = fields.List(fields.Nested(pipeline_variable_model)) -workflow_model = get_or_create_model("TrialWorkflow", workflow_fields_copy) -dataset_model = get_or_create_model("TrialDataset", dataset_fields) -dataset_list_model = get_or_create_model( - "TrialDatasetList", - { - "data": fields.List(fields.Nested(dataset_model)), - "has_more": fields.Boolean, - "limit": fields.Integer, - "total": fields.Integer, - "page": fields.Integer, - }, +register_response_schema_models( + console_ns, + ParametersResponse, + AppDetailWithSite, + AudioBinaryResponse, + AudioTranscriptResponse, + SimpleResultResponse, + SiteResponse, + SuggestedQuestionsResponse, + TrialDatasetListItemResponse, + TrialDatasetListResponse, + WorkflowResponse, ) class WorkflowRunRequest(BaseModel): inputs: dict - files: list | None = Field(default=None) + files: list | None = None class ChatRequest(BaseModel): inputs: dict query: str - files: list | None = Field(default=None) + files: list | None = None conversation_id: str | None = None parent_message_id: str | None = None retriever_from: str = "explore_app" @@ -168,7 +137,7 @@ class TextToSpeechRequest(BaseModel): class CompletionRequest(BaseModel): inputs: dict query: str = "" - files: list | None = Field(default=None) + files: list | None = None response_mode: Literal["blocking", "streaming"] | None = None retriever_from: str = "explore_app" @@ -187,23 +156,13 @@ register_schema_models( CompletionRequest, TrialDatasetListQuery, ) -register_response_schema_models( - console_ns, - ParametersResponse, - AudioBinaryResponse, - AudioTranscriptResponse, - GeneratedAppResponse, - SimpleResultResponse, - SiteResponse, - SuggestedQuestionsResponse, -) class TrialAppWorkflowRunApi(TrialAppResource): @trial_feature_enable - @console_ns.expect(console_ns.models[WorkflowRunRequest.__name__]) - @console_ns.response(200, "Success", console_ns.models[GeneratedAppResponse.__name__]) @with_current_user + @console_ns.expect(console_ns.models[WorkflowRunRequest.__name__]) + @console_ns.response(200, "Success") def post(self, current_user: Account, trial_app): """ Run workflow @@ -224,6 +183,7 @@ class TrialAppWorkflowRunApi(TrialAppResource): app_model=app_model, user=current_user, args=args, invoke_from=InvokeFrom.EXPLORE, streaming=True ) RecommendedAppService.add_trial_app_record(db.session, app_id, user_id) + # response-contract:ignore compact_generate_response return helper.compact_generate_response(response) except ProviderTokenNotInitError as ex: raise ProviderNotInitializeError(ex.description) @@ -263,12 +223,12 @@ class TrialAppWorkflowTaskStopApi(TrialAppResource): # New graph engine command channel mechanism GraphEngineManager(redis_client).send_stop_command(task_id) - return {"result": "success"} + return SimpleResultResponse(result="success").model_dump(mode="json") class TrialChatApi(TrialAppResource): @console_ns.expect(console_ns.models[ChatRequest.__name__]) - @console_ns.response(200, "Success", console_ns.models[GeneratedAppResponse.__name__]) + @console_ns.response(200, "Success") @trial_feature_enable @with_current_user def post(self, current_user: Account, trial_app): @@ -297,6 +257,7 @@ class TrialChatApi(TrialAppResource): app_model=app_model, user=current_user, args=args, invoke_from=InvokeFrom.EXPLORE, streaming=True ) RecommendedAppService.add_trial_app_record(db.session, app_id, user_id) + # response-contract:ignore compact_generate_response return helper.compact_generate_response(response) except services.errors.conversation.ConversationNotExistsError: raise NotFound("Conversation Not Exists.") @@ -355,7 +316,7 @@ class TrialMessageSuggestedQuestionApi(TrialAppResource): logger.exception("internal server error.") raise InternalServerError() - return {"data": questions} + return dump_response(SuggestedQuestionsResponse, {"data": questions}) class TrialChatAudioApi(TrialAppResource): @@ -374,7 +335,7 @@ class TrialChatAudioApi(TrialAppResource): response = AudioService.transcript_asr(app_model=app_model, file=file, end_user=None) RecommendedAppService.add_trial_app_record(db.session, app_id, user_id) - return response + return dump_response(AudioTranscriptResponse, response) except services.errors.app_model_config.AppModelConfigBrokenError: logger.exception("App model config broken.") raise AppUnavailableError() @@ -427,6 +388,7 @@ class TrialChatTextApi(TrialAppResource): message_id=message_id, ) RecommendedAppService.add_trial_app_record(db.session, app_id, user_id) + # response-contract:ignore binary response return response except services.errors.app_model_config.AppModelConfigBrokenError: logger.exception("App model config broken.") @@ -456,7 +418,7 @@ class TrialChatTextApi(TrialAppResource): class TrialCompletionApi(TrialAppResource): @console_ns.expect(console_ns.models[CompletionRequest.__name__]) - @console_ns.response(200, "Success", console_ns.models[GeneratedAppResponse.__name__]) + @console_ns.response(200, "Success") @trial_feature_enable @with_current_user def post(self, current_user: Account, trial_app): @@ -480,6 +442,7 @@ class TrialCompletionApi(TrialAppResource): ) RecommendedAppService.add_trial_app_record(db.session, app_id, user_id) + # response-contract:ignore compact_generate_response return helper.compact_generate_response(response) except services.errors.conversation.ConversationNotExistsError: raise NotFound("Conversation Not Exists.") @@ -557,50 +520,49 @@ class TrialAppParameterApi(Resource): class AppApi(Resource): - @console_ns.response(200, "Success", app_detail_with_site_model) @get_app_model_with_trial(None) - @marshal_with(app_detail_with_site_model) + @console_ns.response(200, "App detail retrieved successfully", console_ns.models[AppDetailWithSite.__name__]) def get(self, app_model): """Get app detail""" app_service = AppService() app_model = app_service.get_app(app_model) - return app_model + return dump_response(AppDetailWithSite, app_model) class AppWorkflowApi(Resource): - @console_ns.response(200, "Success", workflow_model) @get_app_model_with_trial(None) - @marshal_with(workflow_model) + @console_ns.response(200, "Workflow detail retrieved successfully", console_ns.models[WorkflowResponse.__name__]) def get(self, app_model): """Get workflow detail""" if not app_model.workflow_id: raise AppUnavailableError() workflow = db.session.get(Workflow, app_model.workflow_id) - return workflow + return dump_response(WorkflowResponse, workflow) class DatasetListApi(Resource): @console_ns.doc(params=query_params_from_model(TrialDatasetListQuery)) - @console_ns.response(200, "Success", dataset_list_model) + @console_ns.response(200, "Success", console_ns.models[TrialDatasetListResponse.__name__]) @get_app_model_with_trial(None) def get(self, app_model): - page = request.args.get("page", default=1, type=int) - limit = request.args.get("limit", default=20, type=int) - ids = request.args.getlist("ids") + query = query_params_from_request( + TrialDatasetListQuery, + list_fields=("ids",), + use_defaults_for_malformed_ints=True, + ) tenant_id = app_model.tenant_id - if ids: - datasets, total = DatasetService.get_datasets_by_ids(ids, tenant_id) + if query.ids: + datasets, total = DatasetService.get_datasets_by_ids(query.ids, tenant_id) else: raise NeedAddIdsError() - data = cast(list[dict[str, Any]], marshal(datasets, dataset_fields)) - - response = {"data": data, "has_more": len(datasets) == limit, "limit": limit, "total": total, "page": page} - return response + return TrialDatasetListResponse( + data=datasets, has_more=len(datasets) == query.limit, limit=query.limit, total=total or 0, page=query.page + ).model_dump(mode="json") console_ns.add_resource(TrialChatApi, "/trial-apps//chat-messages", endpoint="trial_app_chat_completion") diff --git a/api/controllers/console/workspace/account.py b/api/controllers/console/workspace/account.py index c13c8aa162f..e2aae8eee5e 100644 --- a/api/controllers/console/workspace/account.py +++ b/api/controllers/console/workspace/account.py @@ -1,12 +1,12 @@ from __future__ import annotations from datetime import datetime -from typing import Any, Literal +from typing import Literal import pytz from flask import request from flask_restx import Resource -from pydantic import BaseModel, Field, RootModel, field_validator, model_validator +from pydantic import BaseModel, Field, field_validator, model_validator from sqlalchemy import select from werkzeug.exceptions import NotFound @@ -47,7 +47,7 @@ from controllers.console.wraps import ( ) from extensions.ext_database import db from fields.base import ResponseModel -from fields.member_fields import Account as AccountResponse +from fields.member_fields import AccountResponse from graphon.file import helpers as file_helpers from libs.datetime_utils import naive_utc_now from libs.helper import EmailStr, dump_response, extract_remote_ip, timezone, to_timestamp @@ -194,10 +194,6 @@ register_schema_models( ) -def _serialize_account(account) -> dict[str, Any]: - return AccountResponse.model_validate(account, from_attributes=True).model_dump(mode="json") - - class AccountIntegrateResponse(ResponseModel): provider: str created_at: int | None = None @@ -236,23 +232,15 @@ class EducationAutocompleteResponse(ResponseModel): has_next: bool | None = None -class EducationActivateResponse(RootModel[dict[str, Any]]): - root: dict[str, Any] - - -register_schema_models( - console_ns, - AccountIntegrateResponse, - AccountIntegrateListResponse, - EducationVerifyResponse, - EducationStatusResponse, - EducationAutocompleteResponse, -) register_response_schema_models( console_ns, AccountResponse, + AccountIntegrateResponse, + AccountIntegrateListResponse, AvatarUrlResponse, - EducationActivateResponse, + EducationVerifyResponse, + EducationStatusResponse, + EducationAutocompleteResponse, SimpleResultDataResponse, SimpleResultResponse, VerificationTokenResponse, @@ -302,7 +290,7 @@ class AccountInitApi(Resource): account.initialized_at = naive_utc_now() db.session.commit() - return {"result": "success"} + return SimpleResultResponse(result="success").model_dump(mode="json") @console_ns.route("/account/profile") @@ -314,7 +302,7 @@ class AccountProfileApi(Resource): @enterprise_license_required @with_current_user def get(self, current_user: Account): - return _serialize_account(current_user) + return dump_response(AccountResponse, current_user) @console_ns.route("/account/name") @@ -330,7 +318,7 @@ class AccountNameApi(Resource): args = AccountNamePayload.model_validate(payload) updated_account = AccountService.update_account(current_user, session=db.session, name=args.name) - return _serialize_account(updated_account) + return dump_response(AccountResponse, updated_account) @console_ns.route("/account/avatar") @@ -349,7 +337,7 @@ class AccountAvatarApi(Resource): avatar = args.avatar if avatar.startswith(("http://", "https://")): - return dump_response(AvatarUrlResponse, {"avatar_url": avatar}) + return AvatarUrlResponse(avatar_url=avatar).model_dump(mode="json") upload_file = db.session.scalar(select(UploadFile).where(UploadFile.id == avatar).limit(1)) if upload_file is None: @@ -362,7 +350,7 @@ class AccountAvatarApi(Resource): raise NotFound("Avatar file not found") avatar_url = file_helpers.get_signed_file_url(upload_file_id=upload_file.id) - return dump_response(AvatarUrlResponse, {"avatar_url": avatar_url}) + return AvatarUrlResponse(avatar_url=avatar_url).model_dump(mode="json") @console_ns.expect(console_ns.models[AccountAvatarPayload.__name__]) @setup_required @@ -376,7 +364,7 @@ class AccountAvatarApi(Resource): updated_account = AccountService.update_account(current_user, session=db.session, avatar=args.avatar) - return _serialize_account(updated_account) + return dump_response(AccountResponse, updated_account) @console_ns.route("/account/interface-language") @@ -395,7 +383,7 @@ class AccountInterfaceLanguageApi(Resource): current_user, session=db.session, interface_language=args.interface_language ) - return _serialize_account(updated_account) + return dump_response(AccountResponse, updated_account) @console_ns.route("/account/interface-theme") @@ -414,7 +402,7 @@ class AccountInterfaceThemeApi(Resource): current_user, session=db.session, interface_theme=args.interface_theme ) - return _serialize_account(updated_account) + return dump_response(AccountResponse, updated_account) @console_ns.route("/account/timezone") @@ -431,7 +419,7 @@ class AccountTimezoneApi(Resource): updated_account = AccountService.update_account(current_user, session=db.session, timezone=args.timezone) - return _serialize_account(updated_account) + return dump_response(AccountResponse, updated_account) @console_ns.route("/account/password") @@ -452,7 +440,7 @@ class AccountPasswordApi(Resource): except ServiceCurrentPasswordIncorrectError: raise CurrentPasswordIncorrectError() - return _serialize_account(current_user) + return dump_response(AccountResponse, current_user) @console_ns.route("/account/integrates") @@ -471,33 +459,29 @@ class AccountIntegrateApi(Resource): oauth_base_path = "/console/api/oauth/login" providers = ["github", "google"] - integrate_data = [] + integrate_data: list[AccountIntegrateResponse] = [] for provider in providers: existing_integrate = next((ai for ai in account_integrates if ai.provider == provider), None) if existing_integrate: integrate_data.append( - { - "id": existing_integrate.id, - "provider": provider, - "created_at": existing_integrate.created_at, - "is_bound": True, - "link": None, - } + AccountIntegrateResponse( + provider=provider, + created_at=to_timestamp(existing_integrate.created_at), + is_bound=True, + link=None, + ) ) else: integrate_data.append( - { - "id": None, - "provider": provider, - "created_at": None, - "is_bound": False, - "link": f"{base_url}{oauth_base_path}/{provider}", - } + AccountIntegrateResponse( + provider=provider, + created_at=None, + is_bound=False, + link=f"{base_url}{oauth_base_path}/{provider}", + ) ) - return AccountIntegrateListResponse( - data=[AccountIntegrateResponse.model_validate(item) for item in integrate_data] - ).model_dump(mode="json") + return AccountIntegrateListResponse(data=integrate_data).model_dump(mode="json") @console_ns.route("/account/delete/verify") @@ -511,7 +495,7 @@ class AccountDeleteVerifyApi(Resource): token, code = AccountService.generate_account_deletion_verification_code(account) AccountService.send_account_deletion_verification_email(account, code) - return {"result": "success", "data": token} + return SimpleResultDataResponse(result="success", data=token).model_dump(mode="json") @console_ns.route("/account/delete") @@ -531,7 +515,7 @@ class AccountDeleteApi(Resource): AccountService.delete_account(account) - return {"result": "success"} + return SimpleResultResponse(result="success").model_dump(mode="json") @console_ns.route("/account/delete/feedback") @@ -545,7 +529,7 @@ class AccountDeleteUpdateFeedbackApi(Resource): BillingService.update_account_deletion_feedback(args.email, args.feedback) - return {"result": "success"} + return SimpleResultResponse(result="success").model_dump(mode="json") @console_ns.route("/account/education/verify") @@ -558,15 +542,16 @@ class EducationVerifyApi(Resource): @console_ns.response(200, "Success", console_ns.models[EducationVerifyResponse.__name__]) @with_current_user def get(self, account: Account): - return EducationVerifyResponse.model_validate( - BillingService.EducationIdentity.verify(account.id, account.email) or {} - ).model_dump(mode="json") + return dump_response( + EducationVerifyResponse, BillingService.EducationIdentity.verify(account.id, account.email) or {} + ) @console_ns.route("/account/education") class EducationApi(Resource): @console_ns.expect(console_ns.models[EducationActivatePayload.__name__]) - @console_ns.response(200, "Success", console_ns.models[EducationActivateResponse.__name__]) + # response-contract:ignore billing-service activation payload; TODO: model education activation result. + @console_ns.response(200, "Success") @setup_required @login_required @account_initialization_required @@ -577,7 +562,8 @@ class EducationApi(Resource): payload = console_ns.payload or {} args = EducationActivatePayload.model_validate(payload) - return BillingService.EducationIdentity.activate(account, args.token, args.institution, args.role) + result = BillingService.EducationIdentity.activate(account, args.token, args.institution, args.role) + return result @setup_required @login_required @@ -591,7 +577,7 @@ class EducationApi(Resource): # convert expire_at to UTC timestamp from isoformat if res and "expire_at" in res: res["expire_at"] = datetime.fromisoformat(res["expire_at"]).astimezone(pytz.utc) - return EducationStatusResponse.model_validate(res).model_dump(mode="json") + return dump_response(EducationStatusResponse, res) @console_ns.route("/account/education/autocomplete") @@ -607,9 +593,10 @@ class EducationAutoCompleteApi(Resource): payload = request.args.to_dict(flat=True) args = EducationAutocompleteQuery.model_validate(payload) - return EducationAutocompleteResponse.model_validate( - BillingService.EducationIdentity.autocomplete(args.keywords, args.page, args.limit) or {} - ).model_dump(mode="json") + return dump_response( + EducationAutocompleteResponse, + BillingService.EducationIdentity.autocomplete(args.keywords, args.page, args.limit) or {}, + ) @console_ns.route("/account/change-email") @@ -669,7 +656,7 @@ class ChangeEmailSendEmailApi(Resource): language=language, phase=send_phase, ) - return {"result": "success", "data": token} + return SimpleResultDataResponse(result="success", data=token).model_dump(mode="json") @console_ns.route("/account/change-email/validity") @@ -716,7 +703,9 @@ class ChangeEmailCheckApi(Resource): new_token = AccountService.generate_change_email_token(refreshed_token_data, current_user) AccountService.reset_change_email_error_rate_limit(user_email) - return {"is_valid": True, "email": normalized_token_email, "token": new_token} + return VerificationTokenResponse(is_valid=True, email=normalized_token_email, token=new_token).model_dump( + mode="json" + ) @console_ns.route("/account/change-email/reset") @@ -768,7 +757,7 @@ class ChangeEmailResetApi(Resource): email=normalized_new_email, ) - return _serialize_account(updated_account) + return dump_response(AccountResponse, updated_account) @console_ns.route("/account/change-email/check-email-unique") @@ -784,4 +773,4 @@ class CheckEmailUnique(Resource): raise AccountInFreezeError() if not AccountService.check_email_unique(normalized_email, session=db.session): raise EmailAlreadyInUseError() - return {"result": "success"} + return SimpleResultResponse(result="success").model_dump(mode="json") diff --git a/api/controllers/console/workspace/endpoint.py b/api/controllers/console/workspace/endpoint.py index ddb0f7045d9..c55186ab984 100644 --- a/api/controllers/console/workspace/endpoint.py +++ b/api/controllers/console/workspace/endpoint.py @@ -12,7 +12,8 @@ from flask import request from flask_restx import Resource from pydantic import BaseModel, Field -from controllers.common.schema import query_params_from_model, register_schema_models +from controllers.common.fields import SuccessResponse +from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models from controllers.console import console_ns from controllers.console.wraps import ( RBACPermission, @@ -24,8 +25,9 @@ from controllers.console.wraps import ( with_current_tenant_id, with_current_user_id, ) +from core.plugin.entities.endpoint import EndpointEntityWithInstance from core.plugin.impl.exc import PluginPermissionDeniedError -from graphon.model_runtime.utils.encoders import jsonable_encoder +from fields.base import ResponseModel from libs.login import login_required from services.plugin.endpoint_service import EndpointService @@ -40,14 +42,17 @@ class EndpointIdPayload(BaseModel): endpoint_id: str -class EndpointUpdatePayload(BaseModel): +class EndpointSettingsPayload(BaseModel): settings: dict[str, Any] name: str = Field(min_length=1) -class LegacyEndpointUpdatePayload(EndpointIdPayload): - settings: dict[str, Any] - name: str = Field(min_length=1) +class EndpointUpdatePayload(EndpointSettingsPayload): + pass + + +class LegacyEndpointUpdatePayload(EndpointIdPayload, EndpointSettingsPayload): + pass class EndpointListQuery(BaseModel): @@ -59,98 +64,85 @@ class EndpointListForPluginQuery(EndpointListQuery): plugin_id: str -class EndpointCreateResponse(BaseModel): - success: bool = Field(description="Operation success") - - -class EndpointListResponse(BaseModel): - endpoints: list[dict[str, Any]] = Field( - description="Endpoint information", - ) - - -class PluginEndpointListResponse(BaseModel): - endpoints: list[dict[str, Any]] = Field( - description="Endpoint information", - ) - - -class EndpointDeleteResponse(BaseModel): - success: bool = Field(description="Operation success") - - -class EndpointUpdateResponse(BaseModel): - success: bool = Field(description="Operation success") - - -class EndpointEnableResponse(BaseModel): - success: bool = Field(description="Operation success") - - -class EndpointDisableResponse(BaseModel): - success: bool = Field(description="Operation success") +class EndpointListResponse(ResponseModel): + endpoints: list[EndpointEntityWithInstance] = Field(description="Endpoint information") register_schema_models( console_ns, EndpointCreatePayload, EndpointIdPayload, + EndpointSettingsPayload, EndpointUpdatePayload, LegacyEndpointUpdatePayload, EndpointListQuery, EndpointListForPluginQuery, - EndpointCreateResponse, +) +register_response_schema_models( + console_ns, + SuccessResponse, EndpointListResponse, - PluginEndpointListResponse, - EndpointDeleteResponse, - EndpointUpdateResponse, - EndpointEnableResponse, - EndpointDisableResponse, ) -def _create_endpoint(tenant_id: str, user_id: str) -> dict[str, bool]: +def _create_endpoint(tenant_id: str, user_id: str) -> bool: """Create a plugin endpoint for the injected workspace and user.""" args = EndpointCreatePayload.model_validate(console_ns.payload) try: - return { - "success": EndpointService.create_endpoint( - tenant_id=tenant_id, - user_id=user_id, - plugin_unique_identifier=args.plugin_unique_identifier, - name=args.name, - settings=args.settings, - ) - } + return EndpointService.create_endpoint( + tenant_id=tenant_id, + user_id=user_id, + plugin_unique_identifier=args.plugin_unique_identifier, + name=args.name, + settings=args.settings, + ) except PluginPermissionDeniedError as e: raise ValueError(e.description) from e -def _update_endpoint(tenant_id: str, user_id: str, endpoint_id: str) -> dict[str, bool]: +def _update_endpoint(tenant_id: str, user_id: str, endpoint_id: str) -> bool: """Update a plugin endpoint identified by the canonical path parameter.""" args = EndpointUpdatePayload.model_validate(console_ns.payload) - return { - "success": EndpointService.update_endpoint( - tenant_id=tenant_id, - user_id=user_id, - endpoint_id=endpoint_id, - name=args.name, - settings=args.settings, - ) - } + return EndpointService.update_endpoint( + tenant_id=tenant_id, + user_id=user_id, + endpoint_id=endpoint_id, + name=args.name, + settings=args.settings, + ) -def _delete_endpoint(tenant_id: str, user_id: str, endpoint_id: str) -> dict[str, bool]: +def _legacy_update_endpoint(tenant_id: str, user_id: str) -> bool: + args = LegacyEndpointUpdatePayload.model_validate(console_ns.payload) + return EndpointService.update_endpoint( + tenant_id=tenant_id, + user_id=user_id, + endpoint_id=args.endpoint_id, + name=args.name, + settings=args.settings, + ) + + +def _delete_endpoint(tenant_id: str, user_id: str, endpoint_id: str) -> bool: """Delete a plugin endpoint identified by the canonical path parameter.""" - return { - "success": EndpointService.delete_endpoint( - tenant_id=tenant_id, - user_id=user_id, - endpoint_id=endpoint_id, - ) - } + return EndpointService.delete_endpoint( + tenant_id=tenant_id, + user_id=user_id, + endpoint_id=endpoint_id, + ) + + +def _delete_endpoint_from_payload(tenant_id: str, user_id: str) -> bool: + args = EndpointIdPayload.model_validate(console_ns.payload) + return _delete_endpoint(tenant_id=tenant_id, user_id=user_id, endpoint_id=args.endpoint_id) + + +def _set_endpoint_enabled(tenant_id: str, user_id: str, *, enabled: bool) -> bool: + args = EndpointIdPayload.model_validate(console_ns.payload) + action = EndpointService.enable_endpoint if enabled else EndpointService.disable_endpoint + return action(tenant_id=tenant_id, user_id=user_id, endpoint_id=args.endpoint_id) @console_ns.route("/workspaces/current/endpoints") @@ -163,7 +155,7 @@ class EndpointCollectionApi(Resource): @console_ns.response( 200, "Endpoint created successfully", - console_ns.models[EndpointCreateResponse.__name__], + console_ns.models[SuccessResponse.__name__], ) @console_ns.response(403, "Admin privileges required") @setup_required @@ -174,7 +166,7 @@ class EndpointCollectionApi(Resource): @with_current_user_id @with_current_tenant_id def post(self, tenant_id: str, user_id: str): - return _create_endpoint(tenant_id=tenant_id, user_id=user_id) + return SuccessResponse(success=_create_endpoint(tenant_id=tenant_id, user_id=user_id)).model_dump(mode="json") @console_ns.route("/workspaces/current/endpoints/create") @@ -192,7 +184,7 @@ class DeprecatedEndpointCreateApi(Resource): @console_ns.response( 200, "Endpoint created successfully", - console_ns.models[EndpointCreateResponse.__name__], + console_ns.models[SuccessResponse.__name__], ) @console_ns.response(403, "Admin privileges required") @setup_required @@ -203,7 +195,7 @@ class DeprecatedEndpointCreateApi(Resource): @with_current_user_id @with_current_tenant_id def post(self, tenant_id: str, user_id: str): - return _create_endpoint(tenant_id=tenant_id, user_id=user_id) + return SuccessResponse(success=_create_endpoint(tenant_id=tenant_id, user_id=user_id)).model_dump(mode="json") @console_ns.route("/workspaces/current/endpoints/list") @@ -224,19 +216,14 @@ class EndpointListApi(Resource): def get(self, tenant_id: str, user_id: str): args = EndpointListQuery.model_validate(request.args.to_dict(flat=True)) - page = args.page - page_size = args.page_size - - return jsonable_encoder( - { - "endpoints": EndpointService.list_endpoints( - tenant_id=tenant_id, - user_id=user_id, - page=page, - page_size=page_size, - ) - } - ) + return EndpointListResponse( + endpoints=EndpointService.list_endpoints( + tenant_id=tenant_id, + user_id=user_id, + page=args.page, + page_size=args.page_size, + ) + ).model_dump(mode="json") @console_ns.route("/workspaces/current/endpoints/list/plugin") @@ -247,7 +234,7 @@ class EndpointListForSinglePluginApi(Resource): @console_ns.response( 200, "Success", - console_ns.models[PluginEndpointListResponse.__name__], + console_ns.models[EndpointListResponse.__name__], ) @setup_required @login_required @@ -257,21 +244,15 @@ class EndpointListForSinglePluginApi(Resource): def get(self, tenant_id: str, user_id: str): args = EndpointListForPluginQuery.model_validate(request.args.to_dict(flat=True)) - page = args.page - page_size = args.page_size - plugin_id = args.plugin_id - - return jsonable_encoder( - { - "endpoints": EndpointService.list_endpoints_for_single_plugin( - tenant_id=tenant_id, - user_id=user_id, - plugin_id=plugin_id, - page=page, - page_size=page_size, - ) - } - ) + return EndpointListResponse( + endpoints=EndpointService.list_endpoints_for_single_plugin( + tenant_id=tenant_id, + user_id=user_id, + plugin_id=args.plugin_id, + page=args.page, + page_size=args.page_size, + ) + ).model_dump(mode="json") @console_ns.route("/workspaces/current/endpoints/") @@ -284,7 +265,7 @@ class EndpointItemApi(Resource): @console_ns.response( 200, "Endpoint deleted successfully", - console_ns.models[EndpointDeleteResponse.__name__], + console_ns.models[SuccessResponse.__name__], ) @console_ns.response(403, "Admin privileges required") @setup_required @@ -295,7 +276,9 @@ class EndpointItemApi(Resource): @with_current_user_id @with_current_tenant_id def delete(self, tenant_id: str, user_id: str, id: str): - return _delete_endpoint(tenant_id=tenant_id, user_id=user_id, endpoint_id=id) + return SuccessResponse( + success=_delete_endpoint(tenant_id=tenant_id, user_id=user_id, endpoint_id=id) + ).model_dump(mode="json") @console_ns.doc("update_endpoint") @console_ns.doc(description="Update a plugin endpoint") @@ -304,7 +287,7 @@ class EndpointItemApi(Resource): @console_ns.response( 200, "Endpoint updated successfully", - console_ns.models[EndpointUpdateResponse.__name__], + console_ns.models[SuccessResponse.__name__], ) @console_ns.response(403, "Admin privileges required") @setup_required @@ -315,7 +298,9 @@ class EndpointItemApi(Resource): @with_current_user_id @with_current_tenant_id def patch(self, tenant_id: str, user_id: str, id: str): - return _update_endpoint(tenant_id=tenant_id, user_id=user_id, endpoint_id=id) + return SuccessResponse( + success=_update_endpoint(tenant_id=tenant_id, user_id=user_id, endpoint_id=id) + ).model_dump(mode="json") @console_ns.route("/workspaces/current/endpoints/delete") @@ -334,7 +319,7 @@ class DeprecatedEndpointDeleteApi(Resource): @console_ns.response( 200, "Endpoint deleted successfully", - console_ns.models[EndpointDeleteResponse.__name__], + console_ns.models[SuccessResponse.__name__], ) @console_ns.response(403, "Admin privileges required") @setup_required @@ -345,8 +330,9 @@ class DeprecatedEndpointDeleteApi(Resource): @with_current_user_id @with_current_tenant_id def post(self, tenant_id: str, user_id: str): - args = EndpointIdPayload.model_validate(console_ns.payload) - return _delete_endpoint(tenant_id=tenant_id, user_id=user_id, endpoint_id=args.endpoint_id) + return SuccessResponse( # + success=_delete_endpoint_from_payload(tenant_id=tenant_id, user_id=user_id) + ).model_dump(mode="json") @console_ns.route("/workspaces/current/endpoints/update") @@ -365,7 +351,7 @@ class DeprecatedEndpointUpdateApi(Resource): @console_ns.response( 200, "Endpoint updated successfully", - console_ns.models[EndpointUpdateResponse.__name__], + console_ns.models[SuccessResponse.__name__], ) @console_ns.response(403, "Admin privileges required") @setup_required @@ -376,8 +362,9 @@ class DeprecatedEndpointUpdateApi(Resource): @with_current_user_id @with_current_tenant_id def post(self, tenant_id: str, user_id: str): - args = LegacyEndpointUpdatePayload.model_validate(console_ns.payload) - return _update_endpoint(tenant_id=tenant_id, user_id=user_id, endpoint_id=args.endpoint_id) + return SuccessResponse( # + success=_legacy_update_endpoint(tenant_id=tenant_id, user_id=user_id) + ).model_dump(mode="json") @console_ns.route("/workspaces/current/endpoints/enable") @@ -388,7 +375,7 @@ class EndpointEnableApi(Resource): @console_ns.response( 200, "Endpoint enabled successfully", - console_ns.models[EndpointEnableResponse.__name__], + console_ns.models[SuccessResponse.__name__], ) @console_ns.response(403, "Admin privileges required") @setup_required @@ -399,13 +386,9 @@ class EndpointEnableApi(Resource): @with_current_user_id @with_current_tenant_id def post(self, tenant_id: str, user_id: str): - args = EndpointIdPayload.model_validate(console_ns.payload) - - return { - "success": EndpointService.enable_endpoint( - tenant_id=tenant_id, user_id=user_id, endpoint_id=args.endpoint_id - ) - } + return SuccessResponse( + success=_set_endpoint_enabled(tenant_id=tenant_id, user_id=user_id, enabled=True) + ).model_dump(mode="json") @console_ns.route("/workspaces/current/endpoints/disable") @@ -416,7 +399,7 @@ class EndpointDisableApi(Resource): @console_ns.response( 200, "Endpoint disabled successfully", - console_ns.models[EndpointDisableResponse.__name__], + console_ns.models[SuccessResponse.__name__], ) @console_ns.response(403, "Admin privileges required") @setup_required @@ -427,10 +410,6 @@ class EndpointDisableApi(Resource): @with_current_user_id @with_current_tenant_id def post(self, tenant_id: str, user_id: str): - args = EndpointIdPayload.model_validate(console_ns.payload) - - return { - "success": EndpointService.disable_endpoint( - tenant_id=tenant_id, user_id=user_id, endpoint_id=args.endpoint_id - ) - } + return SuccessResponse( + success=_set_endpoint_enabled(tenant_id=tenant_id, user_id=user_id, enabled=False) + ).model_dump(mode="json") diff --git a/api/controllers/console/workspace/members.py b/api/controllers/console/workspace/members.py index 3a2e3c92359..cb25180fb03 100644 --- a/api/controllers/console/workspace/members.py +++ b/api/controllers/console/workspace/members.py @@ -3,7 +3,7 @@ from uuid import UUID from flask import abort, request from flask_restx import Resource -from pydantic import BaseModel, Field, TypeAdapter +from pydantic import BaseModel, Field from sqlalchemy import func, select import services @@ -30,8 +30,8 @@ from controllers.console.wraps import ( from extensions.ext_database import db from extensions.ext_redis import redis_client from fields.base import ResponseModel -from fields.member_fields import AccountWithRole, AccountWithRoleList -from libs.helper import extract_remote_ip +from fields.member_fields import AccountWithRoleListResponse, AccountWithRoleResponse +from libs.helper import dump_response, extract_remote_ip from libs.login import current_account_with_tenant, login_required from models.account import Account, TenantAccountJoin, TenantAccountRole from services.account_service import AccountService, RegisterService, TenantService @@ -70,22 +70,20 @@ class MemberInviteResultResponse(ResponseModel): message: str | None = None +class MemberActionResponse(ResponseModel): + result: str + tenant_id: str = "" + + class MemberInviteResponse(ResponseModel): result: str invitation_results: list[MemberInviteResultResponse] tenant_id: str -class MemberActionTenantResponse(ResponseModel): - result: str - tenant_id: str - - register_enum_models(console_ns, TenantAccountRole) register_schema_models( console_ns, - AccountWithRole, - AccountWithRoleList, MemberInvitePayload, MemberRoleUpdatePayload, OwnerTransferEmailPayload, @@ -94,11 +92,14 @@ register_schema_models( ) register_response_schema_models( console_ns, + AccountWithRoleResponse, + AccountWithRoleListResponse, + MemberActionResponse, + MemberInviteResponse, + MemberInviteResultResponse, SimpleResultDataResponse, SimpleResultResponse, VerificationTokenResponse, - MemberInviteResponse, - MemberActionTenantResponse, ) @@ -179,7 +180,7 @@ class MemberListApi(Resource): @setup_required @login_required @account_initialization_required - @console_ns.response(200, "Success", console_ns.models[AccountWithRoleList.__name__]) + @console_ns.response(200, "Success", console_ns.models[AccountWithRoleListResponse.__name__]) @with_current_user def get(self, current_user: Account | None = None): if current_user is None: @@ -216,9 +217,7 @@ class MemberListApi(Resource): } ) - member_models = TypeAdapter(list[AccountWithRole]).validate_python(serialized_members) - response = AccountWithRoleList(accounts=member_models) - return response.model_dump(mode="json"), 200 + return dump_response(AccountWithRoleListResponse, {"accounts": serialized_members}), 200 @console_ns.route("/workspaces/current/members/invite-email") @@ -254,7 +253,7 @@ class MemberInviteEmailApi(Resource): check_workspace_member_invite_permission(inviter.current_tenant.id) - invitation_results = [] + invitation_results: list[MemberInviteResultResponse] = [] console_web_url = dify_config.CONSOLE_WEB_URL tenant_id = inviter.current_tenant.id @@ -277,38 +276,40 @@ class MemberInviteEmailApi(Resource): ) encoded_invitee_email = parse.quote(invitee_email) invitation_results.append( - { - "status": "success", - "email": invitee_email, - "url": f"{console_web_url}/activate?email={encoded_invitee_email}&token={token}", - } + MemberInviteResultResponse( + status="success", + email=invitee_email, + url=f"{console_web_url}/activate?email={encoded_invitee_email}&token={token}", + ) ) except AccountAlreadyInTenantError: invitation_results.append( - { - "status": "already_member", - "email": invitee_email, - "message": "Account already in workspace.", - } + MemberInviteResultResponse( + status="already_member", + email=invitee_email, + message="Account already in workspace.", + ) ) except Exception as e: - invitation_results.append({"status": "failed", "email": invitee_email, "message": str(e)}) + invitation_results.append( + MemberInviteResultResponse(status="failed", email=invitee_email, message=str(e)) + ) - return { - "result": "success", - "invitation_results": invitation_results, - "tenant_id": str(inviter.current_tenant.id) if inviter.current_tenant else "", - }, 201 + return MemberInviteResponse( + result="success", + invitation_results=invitation_results, + tenant_id=inviter.current_tenant.id if inviter.current_tenant else "", + ).model_dump(mode="json"), 201 @console_ns.route("/workspaces/current/members/") class MemberCancelInviteApi(Resource): """Cancel an invitation by member id.""" - @console_ns.response(200, "Success", console_ns.models[MemberActionTenantResponse.__name__]) @setup_required @login_required @account_initialization_required + @console_ns.response(200, "Success", console_ns.models[MemberActionResponse.__name__]) @with_current_user def delete(self, current_user: Account, member_id: UUID): if not current_user.current_tenant: @@ -330,10 +331,10 @@ class MemberCancelInviteApi(Resource): except Exception as e: raise ValueError(str(e)) - return { - "result": "success", - "tenant_id": str(current_user.current_tenant.id) if current_user.current_tenant else "", - }, 200 + return MemberActionResponse( + result="success", + tenant_id=current_user.current_tenant.id if current_user.current_tenant else "", + ).model_dump(mode="json"), 200 @console_ns.route("/workspaces/current/members//update-role") @@ -377,7 +378,7 @@ class MemberUpdateRoleApi(Resource): except Exception as e: raise ValueError(str(e)) - return {"result": "success"} + return SimpleResultResponse(result="success").model_dump(mode="json") @console_ns.route("/workspaces/current/dataset-operators") @@ -387,15 +388,13 @@ class DatasetOperatorMemberListApi(Resource): @setup_required @login_required @account_initialization_required - @console_ns.response(200, "Success", console_ns.models[AccountWithRoleList.__name__]) + @console_ns.response(200, "Success", console_ns.models[AccountWithRoleListResponse.__name__]) @with_current_user def get(self, current_user: Account): if not current_user.current_tenant: raise ValueError("No current tenant") members = TenantService.get_dataset_operator_members(current_user.current_tenant, session=db.session) - member_models = TypeAdapter(list[AccountWithRole]).validate_python(members, from_attributes=True) - response = AccountWithRoleList(accounts=member_models) - return response.model_dump(mode="json"), 200 + return dump_response(AccountWithRoleListResponse, {"accounts": members}), 200 @console_ns.route("/workspaces/current/members/send-owner-transfer-confirm-email") @@ -435,7 +434,7 @@ class SendOwnerTransferEmailApi(Resource): workspace_name=current_user.current_tenant.name if current_user.current_tenant else "", ) - return {"result": "success", "data": token} + return SimpleResultDataResponse(result="success", data=token).model_dump(mode="json") @console_ns.route("/workspaces/current/members/owner-transfer-check") @@ -480,7 +479,7 @@ class OwnerTransferCheckApi(Resource): _, new_token = AccountService.generate_owner_transfer_token(user_email, code=args.code, additional_data={}) AccountService.reset_owner_transfer_error_rate_limit(user_email) - return {"is_valid": True, "email": token_data.get("email"), "token": new_token} + return VerificationTokenResponse(is_valid=True, email=user_email, token=new_token).model_dump(mode="json") @console_ns.route("/workspaces/current/members//owner-transfer") @@ -546,4 +545,4 @@ class OwnerTransfer(Resource): except Exception as e: raise ValueError(str(e)) - return {"result": "success"} + return SimpleResultResponse(result="success").model_dump(mode="json") diff --git a/api/controllers/console/workspace/snippets.py b/api/controllers/console/workspace/snippets.py index e8f0b228c8b..6e7c79f85ae 100644 --- a/api/controllers/console/workspace/snippets.py +++ b/api/controllers/console/workspace/snippets.py @@ -1,16 +1,13 @@ import logging import re -from typing import Any from urllib.parse import quote from flask import Response, request -from flask_restx import Resource, marshal -from pydantic import RootModel +from flask_restx import Resource from sqlalchemy.orm import Session, sessionmaker from werkzeug.datastructures import MultiDict from werkzeug.exceptions import NotFound -from controllers.common.fields import TextFileResponse from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models from controllers.console import console_ns from controllers.console.snippets.payloads import ( @@ -32,12 +29,13 @@ from controllers.console.wraps import ( ) from extensions.ext_database import db from fields.base import ResponseModel -from fields.snippet_fields import snippet_fields, snippet_list_fields, snippet_pagination_fields +from fields.snippet_fields import SnippetPaginationResponse, SnippetResponse +from libs.helper import dump_response from libs.login import login_required from models import Account from models.snippet import SnippetType from services.app_dsl_service import ImportStatus -from services.snippet_dsl_service import SnippetDslService +from services.snippet_dsl_service import CheckDependenciesResult, SnippetDslService, SnippetImportInfo from services.snippet_service import SnippetService logger = logging.getLogger(__name__) @@ -45,15 +43,7 @@ _TAG_IDS_BRACKET_PATTERN = re.compile(r"^tag_ids\[(\d+)\]$") _CREATOR_IDS_BRACKET_PATTERN = re.compile(r"^creator_ids\[(\d+)\]$") -class SnippetImportResponse(RootModel[dict[str, Any]]): - root: dict[str, Any] - - -class SnippetDependencyCheckResponse(RootModel[dict[str, Any]]): - root: dict[str, Any] - - -class SnippetUseCountResponse(ResponseModel): +class SnippetUseCountIncrementResponse(ResponseModel): result: str use_count: int @@ -100,30 +90,22 @@ register_schema_models( IncludeSecretQuery, ) register_response_schema_models( - console_ns, - TextFileResponse, - SnippetImportResponse, - SnippetDependencyCheckResponse, - SnippetUseCountResponse, + console_ns, SnippetResponse, SnippetPaginationResponse, SnippetUseCountIncrementResponse, SnippetImportInfo ) -# Create namespace models for marshaling -snippet_model = console_ns.model("Snippet", snippet_fields) -snippet_list_model = console_ns.model("SnippetList", snippet_list_fields) -snippet_pagination_model = console_ns.model("SnippetPagination", snippet_pagination_fields) - @console_ns.route("/workspaces/current/customized-snippets") class CustomizedSnippetsApi(Resource): @console_ns.doc("list_customized_snippets") @console_ns.doc(params=query_params_from_model(SnippetListQuery)) - @console_ns.response(200, "Snippets retrieved successfully", snippet_pagination_model) + @console_ns.response(200, "Snippets retrieved successfully", console_ns.models[SnippetPaginationResponse.__name__]) @setup_required @login_required @account_initialization_required @with_current_tenant_id def get(self, current_tenant_id: str): """List customized snippets with pagination and search.""" + query = SnippetListQuery.model_validate(_normalize_snippet_list_query_args(request.args)) snippet_service = _snippet_service() @@ -138,17 +120,20 @@ class CustomizedSnippetsApi(Resource): tag_ids=query.tag_ids, ) - return { - "data": marshal(snippets, snippet_list_fields), - "page": query.page, - "limit": query.limit, - "total": total, - "has_more": has_more, - }, 200 + return dump_response( + SnippetPaginationResponse, + { + "data": snippets, + "page": query.page, + "limit": query.limit, + "total": total, + "has_more": has_more, + }, + ), 200 @console_ns.doc("create_customized_snippet") @console_ns.expect(console_ns.models.get(CreateSnippetPayload.__name__)) - @console_ns.response(201, "Snippet created successfully", snippet_model) + @console_ns.response(201, "Snippet created successfully", console_ns.models[SnippetResponse.__name__]) @console_ns.response(400, "Invalid request") @setup_required @login_required @@ -161,6 +146,7 @@ class CustomizedSnippetsApi(Resource): @with_current_tenant_id def post(self, current_tenant_id: str, current_user: Account): """Create a new customized snippet.""" + payload = CreateSnippetPayload.model_validate(console_ns.payload or {}) try: @@ -185,13 +171,13 @@ class CustomizedSnippetsApi(Resource): except ValueError as e: return {"message": str(e)}, 400 - return marshal(snippet, snippet_fields), 201 + return dump_response(SnippetResponse, snippet), 201 @console_ns.route("/workspaces/current/customized-snippets/") class CustomizedSnippetDetailApi(Resource): @console_ns.doc("get_customized_snippet") - @console_ns.response(200, "Snippet retrieved successfully", snippet_model) + @console_ns.response(200, "Snippet retrieved successfully", console_ns.models[SnippetResponse.__name__]) @console_ns.response(404, "Snippet not found") @setup_required @login_required @@ -199,20 +185,21 @@ class CustomizedSnippetDetailApi(Resource): @with_current_tenant_id def get(self, current_tenant_id: str, snippet_id: str): """Get customized snippet details.""" + snippet_service = _snippet_service() snippet = snippet_service.get_snippet_by_id( - snippet_id=str(snippet_id), + snippet_id=snippet_id, tenant_id=current_tenant_id, ) if not snippet: raise NotFound("Snippet not found") - return marshal(snippet, snippet_fields), 200 + return dump_response(SnippetResponse, snippet), 200 @console_ns.doc("update_customized_snippet") @console_ns.expect(console_ns.models.get(UpdateSnippetPayload.__name__)) - @console_ns.response(200, "Snippet updated successfully", snippet_model) + @console_ns.response(200, "Snippet updated successfully", console_ns.models[SnippetResponse.__name__]) @console_ns.response(400, "Invalid request") @console_ns.response(404, "Snippet not found") @setup_required @@ -226,9 +213,10 @@ class CustomizedSnippetDetailApi(Resource): @with_current_tenant_id def patch(self, current_tenant_id: str, current_user: Account, snippet_id: str): """Update customized snippet.""" + snippet_service = _snippet_service() snippet = snippet_service.get_snippet_by_id( - snippet_id=str(snippet_id), + snippet_id=snippet_id, tenant_id=current_tenant_id, ) @@ -257,7 +245,7 @@ class CustomizedSnippetDetailApi(Resource): except ValueError as e: return {"message": str(e)}, 400 - return marshal(snippet, snippet_fields), 200 + return dump_response(SnippetResponse, snippet), 200 @console_ns.doc("delete_customized_snippet") @console_ns.response(204, "Snippet deleted successfully") @@ -270,9 +258,10 @@ class CustomizedSnippetDetailApi(Resource): @with_current_tenant_id def delete(self, current_tenant_id: str, snippet_id: str): """Delete customized snippet.""" + snippet_service = _snippet_service() snippet = snippet_service.get_snippet_by_id( - snippet_id=str(snippet_id), + snippet_id=snippet_id, tenant_id=current_tenant_id, ) @@ -296,7 +285,7 @@ class CustomizedSnippetExportApi(Resource): @console_ns.doc(description="Export snippet configuration as DSL") @console_ns.doc(params={"snippet_id": "Snippet ID to export"}) @console_ns.doc(params=query_params_from_model(IncludeSecretQuery)) - @console_ns.response(200, "Snippet exported successfully", console_ns.models[TextFileResponse.__name__]) + @console_ns.response(200, "Snippet exported successfully") @console_ns.response(404, "Snippet not found") @setup_required @login_required @@ -308,9 +297,10 @@ class CustomizedSnippetExportApi(Resource): @with_current_tenant_id def get(self, current_tenant_id: str, snippet_id: str): """Export snippet as DSL.""" + snippet_service = _snippet_service() snippet = snippet_service.get_snippet_by_id( - snippet_id=str(snippet_id), + snippet_id=snippet_id, tenant_id=current_tenant_id, ) @@ -343,8 +333,8 @@ class CustomizedSnippetImportApi(Resource): @console_ns.doc("import_customized_snippet") @console_ns.doc(description="Import snippet from DSL") @console_ns.expect(console_ns.models.get(SnippetImportPayload.__name__)) - @console_ns.response(200, "Snippet imported successfully", console_ns.models[SnippetImportResponse.__name__]) - @console_ns.response(202, "Import pending confirmation", console_ns.models[SnippetImportResponse.__name__]) + @console_ns.response(200, "Snippet imported successfully", console_ns.models[SnippetImportInfo.__name__]) + @console_ns.response(202, "Import pending confirmation", console_ns.models[SnippetImportInfo.__name__]) @console_ns.response(400, "Import failed") @setup_required @login_required @@ -385,7 +375,7 @@ class CustomizedSnippetImportConfirmApi(Resource): @console_ns.doc("confirm_snippet_import") @console_ns.doc(description="Confirm a pending snippet import") @console_ns.doc(params={"import_id": "Import ID to confirm"}) - @console_ns.response(200, "Import confirmed successfully", console_ns.models[SnippetImportResponse.__name__]) + @console_ns.response(200, "Import confirmed successfully", console_ns.models[SnippetImportInfo.__name__]) @console_ns.response(400, "Import failed") @setup_required @login_required @@ -412,11 +402,7 @@ class CustomizedSnippetCheckDependenciesApi(Resource): @console_ns.doc("check_snippet_dependencies") @console_ns.doc(description="Check dependencies for a snippet") @console_ns.doc(params={"snippet_id": "Snippet ID"}) - @console_ns.response( - 200, - "Dependencies checked successfully", - console_ns.models[SnippetDependencyCheckResponse.__name__], - ) + @console_ns.response(200, "Dependencies checked successfully", console_ns.models[CheckDependenciesResult.__name__]) @console_ns.response(404, "Snippet not found") @setup_required @login_required @@ -430,7 +416,7 @@ class CustomizedSnippetCheckDependenciesApi(Resource): """Check dependencies for a snippet.""" snippet_service = _snippet_service() snippet = snippet_service.get_snippet_by_id( - snippet_id=str(snippet_id), + snippet_id=snippet_id, tenant_id=current_tenant_id, ) @@ -449,7 +435,11 @@ class CustomizedSnippetUseCountIncrementApi(Resource): @console_ns.doc("increment_snippet_use_count") @console_ns.doc(description="Increment snippet use count by 1") @console_ns.doc(params={"snippet_id": "Snippet ID"}) - @console_ns.response(200, "Use count incremented successfully", console_ns.models[SnippetUseCountResponse.__name__]) + @console_ns.response( + 200, + "Use count incremented successfully", + console_ns.models[SnippetUseCountIncrementResponse.__name__], + ) @console_ns.response(404, "Snippet not found") @setup_required @login_required @@ -461,9 +451,10 @@ class CustomizedSnippetUseCountIncrementApi(Resource): @with_current_tenant_id def post(self, current_tenant_id: str, snippet_id: str): """Increment snippet use count when it is inserted into a workflow.""" + snippet_service = _snippet_service() snippet = snippet_service.get_snippet_by_id( - snippet_id=str(snippet_id), + snippet_id=snippet_id, tenant_id=current_tenant_id, ) @@ -476,4 +467,6 @@ class CustomizedSnippetUseCountIncrementApi(Resource): session.commit() session.refresh(snippet) - return {"result": "success", "use_count": snippet.use_count}, 200 + return SnippetUseCountIncrementResponse(result="success", use_count=snippet.use_count).model_dump( + mode="json" + ), 200 diff --git a/api/controllers/console/workspace/workspace.py b/api/controllers/console/workspace/workspace.py index 0afd7e06bf7..2644229d3e6 100644 --- a/api/controllers/console/workspace/workspace.py +++ b/api/controllers/console/workspace/workspace.py @@ -2,7 +2,7 @@ import logging from datetime import datetime from flask import request -from flask_restx import Resource, fields, marshal +from flask_restx import Resource from pydantic import BaseModel, Field, field_validator from sqlalchemy import select from werkzeug.exceptions import Unauthorized @@ -16,7 +16,12 @@ from controllers.common.errors import ( TooManyFilesError, UnsupportedFileTypeError, ) -from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models +from controllers.common.schema import ( + query_params_from_model, + query_params_from_request, + register_response_schema_models, + register_schema_models, +) from controllers.console import console_ns from controllers.console.admin import admin_required from controllers.console.error import AccountNotLinkTenantError @@ -31,7 +36,7 @@ from controllers.console.wraps import ( from enums.cloud_plan import CloudPlan from extensions.ext_database import db from fields.base import ResponseModel -from libs.helper import OptionalTimestampField, TimestampField, dump_response, to_timestamp +from libs.helper import dump_response, to_timestamp from libs.login import login_required from models.account import Account, Tenant, TenantAccountJoin, TenantCustomConfigDict, TenantStatus from services.account_service import TenantService @@ -102,6 +107,7 @@ class TenantListItemResponse(ResponseModel): plan: str | None = None status: str | None = None created_at: int | None = None + last_opened_at: int | None = None current: bool @field_validator("plan", "status", mode="before") @@ -113,9 +119,9 @@ class TenantListItemResponse(ResponseModel): return value return str(getattr(value, "value", value)) - @field_validator("created_at", mode="before") + @field_validator("created_at", "last_opened_at", mode="before") @classmethod - def _normalize_created_at(cls, value: datetime | int | None): + def _normalize_timestamp(cls, value: datetime | int | None): return to_timestamp(value) @@ -131,7 +137,7 @@ class WorkspaceListItemResponse(ResponseModel): @field_validator("status", mode="before") @classmethod - def _normalize_status(cls, value): + def _normalize_enum_like(cls, value): if value is None: return None if isinstance(value, str): @@ -144,7 +150,7 @@ class WorkspaceListItemResponse(ResponseModel): return to_timestamp(value) -class WorkspaceListResponse(ResponseModel): +class WorkspacePaginationResponse(ResponseModel): data: list[WorkspaceListItemResponse] has_more: bool limit: int @@ -157,7 +163,7 @@ class SwitchWorkspaceResponse(ResponseModel): new_tenant: TenantInfoResponse -class WorkspaceMutationResponse(ResponseModel): +class WorkspaceTenantResultResponse(ResponseModel): result: str tenant: TenantInfoResponse @@ -172,6 +178,16 @@ class WorkspacePermissionResponse(ResponseModel): allow_owner_transfer: bool +WORKSPACE_LOGO_UPLOAD_PARAMS = { + "file": { + "in": "formData", + "type": "file", + "required": True, + "description": "Workspace web app logo file. Only SVG and PNG files are supported.", + } +} + + register_schema_models( console_ns, WorkspaceListQuery, @@ -182,49 +198,17 @@ register_schema_models( register_response_schema_models( console_ns, TenantInfoResponse, + TenantListItemResponse, TenantListResponse, - WorkspaceListResponse, - SwitchWorkspaceResponse, - WorkspaceMutationResponse, - WorkspaceLogoUploadResponse, WorkspaceCustomConfigResponse, + WorkspaceListItemResponse, + WorkspacePaginationResponse, + SwitchWorkspaceResponse, + WorkspaceTenantResultResponse, + WorkspaceLogoUploadResponse, WorkspacePermissionResponse, ) -provider_fields = { - "provider_name": fields.String, - "provider_type": fields.String, - "is_valid": fields.Boolean, - "token_is_set": fields.Boolean, -} - -tenant_fields = { - "id": fields.String, - "name": fields.String, - "plan": fields.String, - "status": fields.String, - "created_at": TimestampField, - "role": fields.String, - "in_trial": fields.Boolean, - "trial_end_reason": fields.String, - "custom_config": fields.Raw(attribute="custom_config"), - "trial_credits": fields.Integer, - "trial_credits_used": fields.Integer, - "next_credit_reset_date": fields.Integer, -} - -tenants_fields = { - "id": fields.String, - "name": fields.String, - "plan": fields.String, - "status": fields.String, - "created_at": TimestampField, - "last_opened_at": OptionalTimestampField, - "current": fields.Boolean, -} - -workspace_fields = {"id": fields.String, "name": fields.String, "status": fields.String, "created_at": TimestampField} - @console_ns.route("/workspaces") class TenantListApi(Resource): @@ -279,18 +263,17 @@ class TenantListApi(Resource): tenant_dicts.append(tenant_dict) - return {"workspaces": marshal(tenant_dicts, tenants_fields)}, 200 + return dump_response(TenantListResponse, {"workspaces": tenant_dicts}), 200 @console_ns.route("/all-workspaces") class WorkspaceListApi(Resource): @console_ns.doc(params=query_params_from_model(WorkspaceListQuery)) - @console_ns.response(200, "Success", console_ns.models[WorkspaceListResponse.__name__]) + @console_ns.response(200, "Success", console_ns.models[WorkspacePaginationResponse.__name__]) @setup_required @admin_required def get(self): - payload = request.args.to_dict(flat=True) - args = WorkspaceListQuery.model_validate(payload) + args = query_params_from_request(WorkspaceListQuery) stmt = select(Tenant).order_by(Tenant.created_at.desc()) tenants = db.paginate(select=stmt, page=args.page, per_page=args.limit, error_out=False) @@ -299,13 +282,9 @@ class WorkspaceListApi(Resource): if tenants.has_next: has_more = True - return { - "data": marshal(tenants.items, workspace_fields), - "has_more": has_more, - "limit": args.limit, - "page": args.page, - "total": tenants.total, - }, 200 + return WorkspacePaginationResponse( + data=tenants.items, has_more=has_more, limit=args.limit, page=args.page, total=tenants.total or 0 + ).model_dump(mode="json"), 200 @console_ns.route("/workspaces/current", endpoint="workspaces_current") @@ -359,13 +338,15 @@ class SwitchWorkspaceApi(Resource): if new_tenant is None: raise ValueError("Tenant not found") - return {"result": "success", "new_tenant": marshal(WorkspaceService.get_tenant_info(new_tenant), tenant_fields)} + return SwitchWorkspaceResponse( + result="success", new_tenant=WorkspaceService.get_tenant_info(new_tenant) + ).model_dump(mode="json") @console_ns.route("/workspaces/custom-config") class CustomConfigWorkspaceApi(Resource): @console_ns.expect(console_ns.models[WorkspaceCustomConfigPayload.__name__]) - @console_ns.response(200, "Success", console_ns.models[WorkspaceMutationResponse.__name__]) + @console_ns.response(200, "Success", console_ns.models[WorkspaceTenantResultResponse.__name__]) @setup_required @login_required @account_initialization_required @@ -388,11 +369,14 @@ class CustomConfigWorkspaceApi(Resource): tenant.custom_config_dict = custom_config_dict db.session.commit() - return {"result": "success", "tenant": marshal(WorkspaceService.get_tenant_info(tenant), tenant_fields)} + return WorkspaceTenantResultResponse( + result="success", tenant=WorkspaceService.get_tenant_info(tenant) + ).model_dump(mode="json") @console_ns.route("/workspaces/custom-config/webapp-logo/upload") class WebappLogoWorkspaceApi(Resource): + @console_ns.doc(consumes=["multipart/form-data"], params=WORKSPACE_LOGO_UPLOAD_PARAMS) @console_ns.response(201, "Logo uploaded", console_ns.models[WorkspaceLogoUploadResponse.__name__]) @setup_required @login_required @@ -429,13 +413,13 @@ class WebappLogoWorkspaceApi(Resource): except services.errors.file.UnsupportedFileTypeError: raise UnsupportedFileTypeError() - return {"id": upload_file.id}, 201 + return WorkspaceLogoUploadResponse(id=upload_file.id).model_dump(mode="json"), 201 @console_ns.route("/workspaces/info") class WorkspaceInfoApi(Resource): @console_ns.expect(console_ns.models[WorkspaceInfoPayload.__name__]) - @console_ns.response(200, "Success", console_ns.models[WorkspaceMutationResponse.__name__]) + @console_ns.response(200, "Success", console_ns.models[WorkspaceTenantResultResponse.__name__]) @setup_required @login_required @account_initialization_required @@ -451,7 +435,9 @@ class WorkspaceInfoApi(Resource): tenant.name = args.name db.session.commit() - return {"result": "success", "tenant": marshal(WorkspaceService.get_tenant_info(tenant), tenant_fields)} + return WorkspaceTenantResultResponse( + result="success", tenant=WorkspaceService.get_tenant_info(tenant) + ).model_dump(mode="json") @console_ns.route("/workspaces/current/permission") @@ -475,8 +461,8 @@ class WorkspacePermissionApi(Resource): # Get workspace permissions from enterprise service permission = EnterpriseService.WorkspacePermissionService.get_permission(current_tenant_id) - return { - "workspace_id": permission.workspace_id, - "allow_member_invite": permission.allow_member_invite, - "allow_owner_transfer": permission.allow_owner_transfer, - }, 200 + return WorkspacePermissionResponse( + workspace_id=permission.workspace_id, + allow_member_invite=permission.allow_member_invite, + allow_owner_transfer=permission.allow_owner_transfer, + ).model_dump(mode="json"), 200 diff --git a/api/fields/app_fields.py b/api/fields/app_fields.py deleted file mode 100644 index 96d8fbdf34c..00000000000 --- a/api/fields/app_fields.py +++ /dev/null @@ -1,271 +0,0 @@ -import json -from typing import override - -from flask_restx import fields - -from fields.workflow_fields import workflow_partial_fields -from libs.helper import AppIconUrlField, TimestampField - - -class JsonStringField(fields.Raw): - @override - def format(self, value): - if isinstance(value, str): - try: - return json.loads(value) - except (json.JSONDecodeError, TypeError): - return value - return value - - -class OpaqueRawField(fields.Raw): - @override - def schema(self) -> dict[str, object]: - return {"type": "object"} - - -class StringListRawField(fields.Raw): - @override - def schema(self) -> dict[str, object]: - return {"type": "array", "items": {"type": "string"}} - - -class ObjectListRawField(fields.Raw): - @override - def schema(self) -> dict[str, object]: - return {"type": "array", "items": {"type": "object"}} - - -app_detail_kernel_fields = { - "id": fields.String, - "name": fields.String, - "description": fields.String, - "mode": fields.String(attribute="mode_compatible_with_agent"), - "icon_type": fields.String, - "icon": fields.String, - "icon_background": fields.String, - "icon_url": AppIconUrlField, -} - -related_app_list = { - "data": fields.List(fields.Nested(app_detail_kernel_fields)), - "total": fields.Integer, -} - -model_config_fields = { - "opening_statement": fields.String, - "suggested_questions": StringListRawField(attribute="suggested_questions_list"), - "suggested_questions_after_answer": OpaqueRawField(attribute="suggested_questions_after_answer_dict"), - "speech_to_text": OpaqueRawField(attribute="speech_to_text_dict"), - "text_to_speech": OpaqueRawField(attribute="text_to_speech_dict"), - "retriever_resource": OpaqueRawField(attribute="retriever_resource_dict"), - "annotation_reply": OpaqueRawField(attribute="annotation_reply_dict"), - "more_like_this": OpaqueRawField(attribute="more_like_this_dict"), - "sensitive_word_avoidance": OpaqueRawField(attribute="sensitive_word_avoidance_dict"), - "external_data_tools": ObjectListRawField(attribute="external_data_tools_list"), - "model": OpaqueRawField(attribute="model_dict"), - "user_input_form": ObjectListRawField(attribute="user_input_form_list"), - "dataset_query_variable": fields.String, - "pre_prompt": fields.String, - "agent_mode": OpaqueRawField(attribute="agent_mode_dict"), - "prompt_type": fields.String, - "chat_prompt_config": OpaqueRawField(attribute="chat_prompt_config_dict"), - "completion_prompt_config": OpaqueRawField(attribute="completion_prompt_config_dict"), - "dataset_configs": OpaqueRawField(attribute="dataset_configs_dict"), - "file_upload": OpaqueRawField(attribute="file_upload_dict"), - "created_by": fields.String, - "created_at": TimestampField, - "updated_by": fields.String, - "updated_at": TimestampField, -} - -tag_fields = {"id": fields.String, "name": fields.String, "type": fields.String} - -app_detail_fields = { - "id": fields.String, - "name": fields.String, - "description": fields.String, - "mode": fields.String(attribute="mode_compatible_with_agent"), - "icon": fields.String, - "icon_background": fields.String, - "enable_site": fields.Boolean, - "enable_api": fields.Boolean, - "model_config": fields.Nested(model_config_fields, attribute="app_model_config", allow_null=True), - "workflow": fields.Nested(workflow_partial_fields, allow_null=True), - "tracing": OpaqueRawField, - "use_icon_as_answer_icon": fields.Boolean, - "created_by": fields.String, - "created_at": TimestampField, - "updated_by": fields.String, - "updated_at": TimestampField, - "access_mode": fields.String, - "tags": fields.List(fields.Nested(tag_fields)), - "permission_keys": fields.List(fields.String()), -} - -prompt_config_fields = { - "prompt_template": fields.String, -} - -model_config_partial_fields = { - "model": OpaqueRawField(attribute="model_dict"), - "pre_prompt": fields.String, - "created_by": fields.String, - "created_at": TimestampField, - "updated_by": fields.String, - "updated_at": TimestampField, -} - -app_partial_fields = { - "id": fields.String, - "name": fields.String, - "max_active_requests": OpaqueRawField(), - "description": fields.String(attribute="desc_or_prompt"), - "mode": fields.String(attribute="mode_compatible_with_agent"), - "icon_type": fields.String, - "icon": fields.String, - "icon_background": fields.String, - "icon_url": AppIconUrlField, - "model_config": fields.Nested(model_config_partial_fields, attribute="app_model_config", allow_null=True), - "workflow": fields.Nested(workflow_partial_fields, allow_null=True), - "use_icon_as_answer_icon": fields.Boolean, - "created_by": fields.String, - "created_at": TimestampField, - "updated_by": fields.String, - "updated_at": TimestampField, - "tags": fields.List(fields.Nested(tag_fields)), - "access_mode": fields.String, - "create_user_name": fields.String, - "author_name": fields.String, - "has_draft_trigger": fields.Boolean, - "permission_keys": fields.List(fields.String()), -} - - -app_pagination_fields = { - "page": fields.Integer, - "limit": fields.Integer(attribute="per_page"), - "total": fields.Integer, - "has_more": fields.Boolean(attribute="has_next"), - "data": fields.List(fields.Nested(app_partial_fields), attribute="items"), -} - -template_fields = { - "name": fields.String, - "icon": fields.String, - "icon_background": fields.String, - "description": fields.String, - "mode": fields.String, - "model_config": fields.Nested(model_config_fields), -} - -template_list_fields = { - "data": fields.List(fields.Nested(template_fields)), -} - -site_fields = { - "access_token": fields.String(attribute="code"), - "code": fields.String, - "title": fields.String, - "icon_type": fields.String, - "icon": fields.String, - "icon_background": fields.String, - "icon_url": AppIconUrlField, - "description": fields.String, - "default_language": fields.String, - "chat_color_theme": fields.String, - "chat_color_theme_inverted": fields.Boolean, - "customize_domain": fields.String, - "copyright": fields.String, - "privacy_policy": fields.String, - "custom_disclaimer": fields.String, - "customize_token_strategy": fields.String, - "prompt_public": fields.Boolean, - "app_base_url": fields.String, - "show_workflow_steps": fields.Boolean, - "use_icon_as_answer_icon": fields.Boolean, - "created_by": fields.String, - "created_at": TimestampField, - "updated_by": fields.String, - "updated_at": TimestampField, -} - -deleted_tool_fields = { - "type": fields.String, - "tool_name": fields.String, - "provider_id": fields.String, -} - -app_detail_fields_with_site = { - "id": fields.String, - "name": fields.String, - "description": fields.String, - "mode": fields.String(attribute="mode_compatible_with_agent"), - "icon_type": fields.String, - "icon": fields.String, - "icon_background": fields.String, - "icon_url": AppIconUrlField, - "enable_site": fields.Boolean, - "enable_api": fields.Boolean, - "model_config": fields.Nested(model_config_fields, attribute="app_model_config", allow_null=True), - "workflow": fields.Nested(workflow_partial_fields, allow_null=True), - "api_base_url": fields.String, - "use_icon_as_answer_icon": fields.Boolean, - "max_active_requests": fields.Integer, - "created_by": fields.String, - "created_at": TimestampField, - "updated_by": fields.String, - "updated_at": TimestampField, - "deleted_tools": fields.List(fields.Nested(deleted_tool_fields)), - "access_mode": fields.String, - "tags": fields.List(fields.Nested(tag_fields)), - "permission_keys": fields.List(fields.String()), - "site": fields.Nested(site_fields), -} - - -app_site_fields = { - "app_id": fields.String, - "access_token": fields.String(attribute="code"), - "code": fields.String, - "title": fields.String, - "icon": fields.String, - "icon_background": fields.String, - "description": fields.String, - "default_language": fields.String, - "customize_domain": fields.String, - "copyright": fields.String, - "privacy_policy": fields.String, - "custom_disclaimer": fields.String, - "customize_token_strategy": fields.String, - "prompt_public": fields.Boolean, - "show_workflow_steps": fields.Boolean, - "use_icon_as_answer_icon": fields.Boolean, -} - -leaked_dependency_fields = {"type": fields.String, "value": OpaqueRawField, "current_identifier": fields.String} - -app_import_fields = { - "id": fields.String, - "status": fields.String, - "app_id": fields.String, - "app_mode": fields.String, - "current_dsl_version": fields.String, - "imported_dsl_version": fields.String, - "error": fields.String, -} - -app_import_check_dependencies_fields = { - "leaked_dependencies": fields.List(fields.Nested(leaked_dependency_fields)), -} - -app_server_fields = { - "id": fields.String, - "name": fields.String, - "server_code": fields.String, - "description": fields.String, - "status": fields.String, - "parameters": JsonStringField, - "created_at": TimestampField, - "updated_at": TimestampField, -} diff --git a/api/fields/member_fields.py b/api/fields/member_fields.py index 9bbcbef8429..5108522af01 100644 --- a/api/fields/member_fields.py +++ b/api/fields/member_fields.py @@ -2,26 +2,19 @@ from __future__ import annotations from datetime import datetime -from flask_restx import fields from pydantic import Field, computed_field, field_validator from fields.base import ResponseModel from libs.helper import build_avatar_url, to_timestamp -simple_account_fields = { - "id": fields.String, - "name": fields.String, - "email": fields.String, -} - -class SimpleAccount(ResponseModel): +class SimpleAccountResponse(ResponseModel): id: str name: str email: str -class _AccountAvatar(ResponseModel): +class _AccountAvatarResponseMixin(ResponseModel): avatar: str | None = None @computed_field(return_type=str | None) # type: ignore[prop-decorator] @@ -30,7 +23,7 @@ class _AccountAvatar(ResponseModel): return build_avatar_url(self.avatar) -class Account(_AccountAvatar): +class AccountResponse(_AccountAvatarResponseMixin): id: str name: str email: str @@ -48,7 +41,7 @@ class Account(_AccountAvatar): return to_timestamp(value) -class AccountWithRole(_AccountAvatar): +class AccountWithRoleResponse(_AccountAvatarResponseMixin): id: str name: str email: str @@ -65,5 +58,11 @@ class AccountWithRole(_AccountAvatar): return to_timestamp(value) -class AccountWithRoleList(ResponseModel): - accounts: list[AccountWithRole] +class AccountWithRoleListResponse(ResponseModel): + accounts: list[AccountWithRoleResponse] + + +SimpleAccount = SimpleAccountResponse +Account = AccountResponse +AccountWithRole = AccountWithRoleResponse +AccountWithRoleList = AccountWithRoleListResponse diff --git a/api/fields/snippet_fields.py b/api/fields/snippet_fields.py index 699a3687ac1..9d12b600722 100644 --- a/api/fields/snippet_fields.py +++ b/api/fields/snippet_fields.py @@ -1,61 +1,67 @@ -from typing import override +from datetime import datetime +from typing import Any -from flask_restx import fields +from pydantic import Field, field_validator -from fields.member_fields import simple_account_fields -from libs.helper import TimestampField +from fields.base import ResponseModel +from fields.member_fields import SimpleAccountResponse +from libs.helper import to_timestamp -class OpaqueRawField(fields.Raw): - @override - def schema(self) -> dict[str, object]: - return {"type": "object"} +class SnippetTagResponse(ResponseModel): + id: str + name: str + type: str -tag_fields = {"id": fields.String, "name": fields.String, "type": fields.String} +class SnippetListItemResponse(ResponseModel): + id: str + name: str + description: str | None = None + type: str + version: int + use_count: int + is_published: bool + icon_info: dict[str, Any] | None = None + tags: list[SnippetTagResponse] = Field(default_factory=list) + created_by: str | None = None + author_name: str | None = None + created_at: int | None = None + updated_by: str | None = None + updated_at: int | None = None -# Snippet list item fields (lightweight for list display) -snippet_list_fields = { - "id": fields.String, - "name": fields.String, - "description": fields.String, - "type": fields.String, - "version": fields.Integer, - "use_count": fields.Integer, - "is_published": fields.Boolean, - "icon_info": OpaqueRawField, - "tags": fields.List(fields.Nested(tag_fields)), - "created_by": fields.String, - "author_name": fields.String, - "created_at": TimestampField, - "updated_by": fields.String, - "updated_at": TimestampField, -} + @field_validator("created_at", "updated_at", mode="before") + @classmethod + def _normalize_timestamp(cls, value: datetime | int | None) -> int | None: + return to_timestamp(value) -# Full snippet fields (includes creator info and graph data) -snippet_fields = { - "id": fields.String, - "name": fields.String, - "description": fields.String, - "type": fields.String, - "version": fields.Integer, - "use_count": fields.Integer, - "is_published": fields.Boolean, - "icon_info": OpaqueRawField, - "graph": OpaqueRawField(attribute="graph_dict"), - "input_fields": OpaqueRawField(attribute="input_fields_list"), - "tags": fields.List(fields.Nested(tag_fields)), - "created_by": fields.Nested(simple_account_fields, attribute="created_by_account", allow_null=True), - "created_at": TimestampField, - "updated_by": fields.Nested(simple_account_fields, attribute="updated_by_account", allow_null=True), - "updated_at": TimestampField, -} -# Pagination response fields -snippet_pagination_fields = { - "data": fields.List(fields.Nested(snippet_list_fields)), - "page": fields.Integer, - "limit": fields.Integer, - "total": fields.Integer, - "has_more": fields.Boolean, -} +class SnippetResponse(ResponseModel): + id: str + name: str + description: str | None = None + type: str + version: int + use_count: int + is_published: bool + icon_info: dict[str, Any] | None = None + graph: dict[str, Any] | None = Field(default=None, validation_alias="graph_dict") + input_fields: list[dict[str, Any]] | None = Field(default=None, validation_alias="input_fields_list") + tags: list[SnippetTagResponse] = Field(default_factory=list) + created_by: SimpleAccountResponse | None = Field(default=None, validation_alias="created_by_account") + created_at: int | None = None + updated_by: SimpleAccountResponse | None = Field(default=None, validation_alias="updated_by_account") + updated_at: int | None = None + + @field_validator("created_at", "updated_at", mode="before") + @classmethod + def _normalize_timestamp(cls, value: datetime | int | None) -> int | None: + return to_timestamp(value) + + +class SnippetPaginationResponse(ResponseModel): + data: list[SnippetListItemResponse] + page: int + limit: int + total: int + has_more: bool diff --git a/api/fields/workflow_fields.py b/api/fields/workflow_fields.py deleted file mode 100644 index 2d0d8f9f546..00000000000 --- a/api/fields/workflow_fields.py +++ /dev/null @@ -1,129 +0,0 @@ -from typing import override - -from flask_restx import fields - -from core.helper import encrypter -from fields.member_fields import simple_account_fields -from graphon.variables import SecretVariable, SegmentType, VariableBase -from libs.helper import TimestampField - -from ._value_type_serializer import serialize_value_type - -ENVIRONMENT_VARIABLE_SUPPORTED_TYPES = (SegmentType.STRING, SegmentType.NUMBER, SegmentType.SECRET) - - -class OpaqueRawField(fields.Raw): - @override - def schema(self) -> dict[str, object]: - return {"type": "object"} - - -class JsonValueRawField(fields.Raw): - @override - def schema(self) -> dict[str, object]: - return { - "anyOf": [ - {"type": "string"}, - {"type": "integer"}, - {"type": "number"}, - {"type": "boolean"}, - {"type": "object", "additionalProperties": True}, - {"type": "array", "items": {}}, - {"type": "null"}, - ] - } - - -class EnvironmentVariableField(fields.Raw): - @override - def schema(self) -> dict[str, object]: - return {"type": "object"} - - @override - def format(self, value): - # Mask secret variables values in environment_variables - if isinstance(value, SecretVariable): - return { - "id": value.id, - "name": value.name, - "value": encrypter.full_mask_token(), - "value_type": value.value_type.value, - "description": value.description, - } - if isinstance(value, VariableBase): - return { - "id": value.id, - "name": value.name, - "value": value.value, - "value_type": str(value.value_type.exposed_type()), - "description": value.description, - } - if isinstance(value, dict): - value_type_str = value.get("value_type") - if not isinstance(value_type_str, str): - raise TypeError( - f"unexpected type for value_type field, value={value_type_str}, type={type(value_type_str)}" - ) - value_type = SegmentType(value_type_str).exposed_type() - if value_type not in ENVIRONMENT_VARIABLE_SUPPORTED_TYPES: - raise ValueError(f"Unsupported environment variable value type: {value_type}") - return value - - -conversation_variable_fields = { - "id": fields.String, - "name": fields.String, - "value_type": fields.String(attribute=serialize_value_type), - "value": JsonValueRawField, - "description": fields.String, -} - -pipeline_variable_fields = { - "label": fields.String, - "variable": fields.String, - "type": fields.String, - "belong_to_node_id": fields.String, - "max_length": fields.Integer, - "required": fields.Boolean, - "unit": fields.String, - "default_value": JsonValueRawField, - "options": fields.List(fields.String), - "placeholder": fields.String, - "tooltips": fields.String, - "allowed_file_types": fields.List(fields.String), - "allow_file_extension": fields.List(fields.String), - "allow_file_upload_methods": fields.List(fields.String), -} - -workflow_fields = { - "id": fields.String, - "graph": OpaqueRawField(attribute="graph_dict"), - "features": OpaqueRawField(attribute="features_dict"), - "hash": fields.String(attribute="unique_hash"), - "version": fields.String, - "marked_name": fields.String, - "marked_comment": fields.String, - "created_by": fields.Nested(simple_account_fields, attribute="created_by_account"), - "created_at": TimestampField, - "updated_by": fields.Nested(simple_account_fields, attribute="updated_by_account", allow_null=True), - "updated_at": TimestampField, - "tool_published": fields.Boolean, - "environment_variables": fields.List(EnvironmentVariableField()), - "conversation_variables": fields.List(fields.Nested(conversation_variable_fields)), - "rag_pipeline_variables": fields.List(fields.Nested(pipeline_variable_fields)), -} - -workflow_partial_fields = { - "id": fields.String, - "created_by": fields.String, - "created_at": TimestampField, - "updated_by": fields.String, - "updated_at": TimestampField, -} - -workflow_pagination_fields = { - "items": fields.List(fields.Nested(workflow_fields), attribute="items"), - "page": fields.Integer, - "limit": fields.Integer(attribute="limit"), - "has_more": fields.Boolean(attribute="has_more"), -} diff --git a/api/openapi/markdown/console-openapi.md b/api/openapi/markdown/console-openapi.md index b3a0b8a6a71..35d52c61d60 100644 --- a/api/openapi/markdown/console-openapi.md +++ b/api/openapi/markdown/console-openapi.md @@ -38,7 +38,7 @@ Get account avatar url | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [Account](#account)
| +| 200 | Success | **application/json**: [AccountResponse](#accountresponse)
| ### [POST] /account/change-email #### Request Body @@ -77,7 +77,7 @@ Get account avatar url | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [Account](#account)
| +| 200 | Success | **application/json**: [AccountResponse](#accountresponse)
| ### [POST] /account/change-email/validity #### Request Body @@ -141,9 +141,9 @@ Get account avatar url #### Responses -| Code | Description | Schema | -| ---- | ----------- | ------ | -| 200 | Success | **application/json**: [EducationActivateResponse](#educationactivateresponse)
| +| Code | Description | +| ---- | ----------- | +| 200 | Success | ### [GET] /account/education/autocomplete #### Parameters @@ -198,7 +198,7 @@ Get account avatar url | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [Account](#account)
| +| 200 | Success | **application/json**: [AccountResponse](#accountresponse)
| ### [POST] /account/interface-theme #### Request Body @@ -211,7 +211,7 @@ Get account avatar url | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [Account](#account)
| +| 200 | Success | **application/json**: [AccountResponse](#accountresponse)
| ### [POST] /account/name #### Request Body @@ -224,7 +224,7 @@ Get account avatar url | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [Account](#account)
| +| 200 | Success | **application/json**: [AccountResponse](#accountresponse)
| ### [POST] /account/password #### Request Body @@ -237,14 +237,14 @@ Get account avatar url | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [Account](#account)
| +| 200 | Success | **application/json**: [AccountResponse](#accountresponse)
| ### [GET] /account/profile #### Responses | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [Account](#account)
| +| 200 | Success | **application/json**: [AccountResponse](#accountresponse)
| ### [POST] /account/timezone #### Request Body @@ -257,7 +257,7 @@ Get account avatar url | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [Account](#account)
| +| 200 | Success | **application/json**: [AccountResponse](#accountresponse)
| ### [POST] /activate Activate account with invitation token @@ -1050,7 +1050,7 @@ Infer CLI tool + ENV suggestions from a standardized Agent App skill | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [WorkspaceListResponse](#workspacelistresponse)
| +| 200 | Success | **application/json**: [WorkspacePaginationResponse](#workspacepaginationresponse)
| ### [GET] /api-based-extension Get all API-based extensions for current tenant @@ -8760,7 +8760,7 @@ Bedrock retrieval test (internal use only) | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [TrialAppDetailWithSite](#trialappdetailwithsite)
| +| 200 | App detail retrieved successfully | **application/json**: [AppDetailWithSite](#appdetailwithsite)
| ### [POST] /trial-apps/{app_id}/audio-to-text #### Parameters @@ -8790,9 +8790,9 @@ Bedrock retrieval test (internal use only) #### Responses -| Code | Description | Schema | -| ---- | ----------- | ------ | -| 200 | Success | **application/json**: [GeneratedAppResponse](#generatedappresponse)
| +| Code | Description | +| ---- | ----------- | +| 200 | Success | ### [POST] /trial-apps/{app_id}/completion-messages #### Parameters @@ -8809,9 +8809,9 @@ Bedrock retrieval test (internal use only) #### Responses -| Code | Description | Schema | -| ---- | ----------- | ------ | -| 200 | Success | **application/json**: [GeneratedAppResponse](#generatedappresponse)
| +| Code | Description | +| ---- | ----------- | +| 200 | Success | ### [GET] /trial-apps/{app_id}/datasets #### Parameters @@ -8827,7 +8827,7 @@ Bedrock retrieval test (internal use only) | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [TrialDatasetList](#trialdatasetlist)
| +| 200 | Success | **application/json**: [TrialDatasetListResponse](#trialdatasetlistresponse)
| ### [GET] /trial-apps/{app_id}/messages/{message_id}/suggested-questions #### Parameters @@ -8907,7 +8907,7 @@ Returns the site configuration for the application including theme, icons, and t | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [TrialWorkflow](#trialworkflow)
| +| 200 | Workflow detail retrieved successfully | **application/json**: [WorkflowResponse](#workflowresponse)
| ### [POST] /trial-apps/{app_id}/workflows/run **Run workflow** @@ -8926,9 +8926,9 @@ Returns the site configuration for the application including theme, icons, and t #### Responses -| Code | Description | Schema | -| ---- | ----------- | ------ | -| 200 | Success | **application/json**: [GeneratedAppResponse](#generatedappresponse)
| +| Code | Description | +| ---- | ----------- | +| 200 | Success | ### [POST] /trial-apps/{app_id}/workflows/tasks/{task_id}/stop **Stop workflow task** @@ -9104,7 +9104,7 @@ Get list of available agent providers | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Snippets retrieved successfully | **application/json**: [SnippetPagination](#snippetpagination)
| +| 200 | Snippets retrieved successfully | **application/json**: [SnippetPaginationResponse](#snippetpaginationresponse)
| ### [POST] /workspaces/current/customized-snippets **Create a new customized snippet** @@ -9119,7 +9119,7 @@ Get list of available agent providers | Code | Description | Schema | | ---- | ----------- | ------ | -| 201 | Snippet created successfully | **application/json**: [Snippet](#snippet)
| +| 201 | Snippet created successfully | **application/json**: [SnippetResponse](#snippetresponse)
| | 400 | Invalid request | | ### [POST] /workspaces/current/customized-snippets/imports @@ -9135,8 +9135,8 @@ Get list of available agent providers | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Snippet imported successfully | **application/json**: [SnippetImportResponse](#snippetimportresponse)
| -| 202 | Import pending confirmation | **application/json**: [SnippetImportResponse](#snippetimportresponse)
| +| 200 | Snippet imported successfully | **application/json**: [SnippetImportInfo](#snippetimportinfo)
| +| 202 | Import pending confirmation | **application/json**: [SnippetImportInfo](#snippetimportinfo)
| | 400 | Import failed | | ### [POST] /workspaces/current/customized-snippets/imports/{import_id}/confirm @@ -9152,7 +9152,7 @@ Get list of available agent providers | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Import confirmed successfully | **application/json**: [SnippetImportResponse](#snippetimportresponse)
| +| 200 | Import confirmed successfully | **application/json**: [SnippetImportInfo](#snippetimportinfo)
| | 400 | Import failed | | ### [DELETE] /workspaces/current/customized-snippets/{snippet_id} @@ -9184,7 +9184,7 @@ Get list of available agent providers | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Snippet retrieved successfully | **application/json**: [Snippet](#snippet)
| +| 200 | Snippet retrieved successfully | **application/json**: [SnippetResponse](#snippetresponse)
| | 404 | Snippet not found | | ### [PATCH] /workspaces/current/customized-snippets/{snippet_id} @@ -9206,7 +9206,7 @@ Get list of available agent providers | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Snippet updated successfully | **application/json**: [Snippet](#snippet)
| +| 200 | Snippet updated successfully | **application/json**: [SnippetResponse](#snippetresponse)
| | 400 | Invalid request | | | 404 | Snippet not found | | @@ -9223,7 +9223,7 @@ Get list of available agent providers | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Dependencies checked successfully | **application/json**: [SnippetDependencyCheckResponse](#snippetdependencycheckresponse)
| +| 200 | Dependencies checked successfully | **application/json**: [CheckDependenciesResult](#checkdependenciesresult)
| | 404 | Snippet not found | | ### [GET] /workspaces/current/customized-snippets/{snippet_id}/export @@ -9240,10 +9240,10 @@ Export snippet configuration as DSL #### Responses -| Code | Description | Schema | -| ---- | ----------- | ------ | -| 200 | Snippet exported successfully | **application/json**: [TextFileResponse](#textfileresponse)
| -| 404 | Snippet not found | | +| Code | Description | +| ---- | ----------- | +| 200 | Snippet exported successfully | +| 404 | Snippet not found | ### [POST] /workspaces/current/customized-snippets/{snippet_id}/use-count/increment **Increment snippet use count when it is inserted into a workflow** @@ -9260,7 +9260,7 @@ Increment snippet use count by 1 | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Use count incremented successfully | **application/json**: [SnippetUseCountResponse](#snippetusecountresponse)
| +| 200 | Use count incremented successfully | **application/json**: [SnippetUseCountIncrementResponse](#snippetusecountincrementresponse)
| | 404 | Snippet not found | | ### [GET] /workspaces/current/dataset-operators @@ -9268,7 +9268,7 @@ Increment snippet use count by 1 | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [AccountWithRoleList](#accountwithrolelist)
| +| 200 | Success | **application/json**: [AccountWithRoleListResponse](#accountwithrolelistresponse)
| ### [GET] /workspaces/current/default-model #### Parameters @@ -9309,7 +9309,7 @@ Create a new plugin endpoint | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Endpoint created successfully | **application/json**: [EndpointCreateResponse](#endpointcreateresponse)
| +| 200 | Endpoint created successfully | **application/json**: [SuccessResponse](#successresponse)
| | 403 | Admin privileges required | | ### ~~[POST] /workspaces/current/endpoints/create~~ @@ -9328,7 +9328,7 @@ Deprecated legacy alias for creating a plugin endpoint. Use POST /workspaces/cur | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Endpoint created successfully | **application/json**: [EndpointCreateResponse](#endpointcreateresponse)
| +| 200 | Endpoint created successfully | **application/json**: [SuccessResponse](#successresponse)
| | 403 | Admin privileges required | | ### ~~[POST] /workspaces/current/endpoints/delete~~ @@ -9347,7 +9347,7 @@ Deprecated legacy alias for deleting a plugin endpoint. Use DELETE /workspaces/c | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Endpoint deleted successfully | **application/json**: [EndpointDeleteResponse](#endpointdeleteresponse)
| +| 200 | Endpoint deleted successfully | **application/json**: [SuccessResponse](#successresponse)
| | 403 | Admin privileges required | | ### [POST] /workspaces/current/endpoints/disable @@ -9363,7 +9363,7 @@ Disable a plugin endpoint | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Endpoint disabled successfully | **application/json**: [EndpointDisableResponse](#endpointdisableresponse)
| +| 200 | Endpoint disabled successfully | **application/json**: [SuccessResponse](#successresponse)
| | 403 | Admin privileges required | | ### [POST] /workspaces/current/endpoints/enable @@ -9379,7 +9379,7 @@ Enable a plugin endpoint | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Endpoint enabled successfully | **application/json**: [EndpointEnableResponse](#endpointenableresponse)
| +| 200 | Endpoint enabled successfully | **application/json**: [SuccessResponse](#successresponse)
| | 403 | Admin privileges required | | ### [GET] /workspaces/current/endpoints/list @@ -9413,7 +9413,7 @@ List endpoints for a specific plugin | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [PluginEndpointListResponse](#pluginendpointlistresponse)
| +| 200 | Success | **application/json**: [EndpointListResponse](#endpointlistresponse)
| ### ~~[POST] /workspaces/current/endpoints/update~~ @@ -9431,7 +9431,7 @@ Deprecated legacy alias for updating a plugin endpoint. Use PATCH /workspaces/cu | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Endpoint updated successfully | **application/json**: [EndpointUpdateResponse](#endpointupdateresponse)
| +| 200 | Endpoint updated successfully | **application/json**: [SuccessResponse](#successresponse)
| | 403 | Admin privileges required | | ### [DELETE] /workspaces/current/endpoints/{id} @@ -9447,7 +9447,7 @@ Delete a plugin endpoint | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Endpoint deleted successfully | **application/json**: [EndpointDeleteResponse](#endpointdeleteresponse)
| +| 200 | Endpoint deleted successfully | **application/json**: [SuccessResponse](#successresponse)
| | 403 | Admin privileges required | | ### [PATCH] /workspaces/current/endpoints/{id} @@ -9469,7 +9469,7 @@ Update a plugin endpoint | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Endpoint updated successfully | **application/json**: [EndpointUpdateResponse](#endpointupdateresponse)
| +| 200 | Endpoint updated successfully | **application/json**: [SuccessResponse](#successresponse)
| | 403 | Admin privileges required | | ### [GET] /workspaces/current/members @@ -9477,7 +9477,7 @@ Update a plugin endpoint | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [AccountWithRoleList](#accountwithrolelist)
| +| 200 | Success | **application/json**: [AccountWithRoleListResponse](#accountwithrolelistresponse)
| ### [POST] /workspaces/current/members/invite-email #### Request Body @@ -9529,7 +9529,7 @@ Update a plugin endpoint | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [MemberActionTenantResponse](#memberactiontenantresponse)
| +| 200 | Success | **application/json**: [MemberActionResponse](#memberactionresponse)
| ### [POST] /workspaces/current/members/{member_id}/owner-transfer #### Parameters @@ -11739,9 +11739,15 @@ Returns permission flags that control workspace features like member invitations | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [WorkspaceMutationResponse](#workspacemutationresponse)
| +| 200 | Success | **application/json**: [WorkspaceTenantResultResponse](#workspacetenantresultresponse)
| ### [POST] /workspaces/custom-config/webapp-logo/upload +#### Request Body + +| Required | Schema | +| -------- | ------ | +| Yes | **multipart/form-data**: { **"file"**: binary }
| + #### Responses | Code | Description | Schema | @@ -11759,7 +11765,7 @@ Returns permission flags that control workspace features like member invitations | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Success | **application/json**: [WorkspaceMutationResponse](#workspacemutationresponse)
| +| 200 | Success | **application/json**: [WorkspaceTenantResultResponse](#workspacetenantresultresponse)
| ### [POST] /workspaces/switch #### Request Body @@ -11928,23 +11934,6 @@ Default namespace | role_name | string | | No | | tenant_id | string | | No | -#### Account - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| avatar | string | | No | -| avatar_url | string | | Yes | -| created_at | integer | | No | -| email | string | | Yes | -| id | string | | Yes | -| interface_language | string | | No | -| interface_theme | string | | No | -| is_password_set | boolean | | Yes | -| last_login_at | integer | | No | -| last_login_ip | string | | No | -| name | string | | Yes | -| timezone | string | | No | - #### AccountAvatarPayload | Name | Type | Description | Required | @@ -12020,17 +12009,41 @@ Default namespace | password | string | | No | | repeat_new_password | string | | Yes | +#### AccountResponse + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| avatar | string | | No | +| avatar_url | string | | Yes | +| created_at | integer | | No | +| email | string | | Yes | +| id | string | | Yes | +| interface_language | string | | No | +| interface_theme | string | | No | +| is_password_set | boolean | | Yes | +| last_login_at | integer | | No | +| last_login_ip | string | | No | +| name | string | | Yes | +| timezone | string | | No | + #### AccountTimezonePayload | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | timezone | string | | Yes | -#### AccountWithRole +#### AccountWithRoleListResponse + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| accounts | [ [AccountWithRoleResponse](#accountwithroleresponse) ] | | Yes | + +#### AccountWithRoleResponse | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | avatar | string | | No | +| avatar_url | string | | Yes | | created_at | integer | | No | | email | string | | Yes | | id | string | | Yes | @@ -12041,12 +12054,6 @@ Default namespace | roles | [ object ] | | No | | status | string | | Yes | -#### AccountWithRoleList - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| accounts | [ [AccountWithRole](#accountwithrole) ] | | Yes | - #### ActivateCheckQuery | Name | Type | Description | Required | @@ -12095,7 +12102,7 @@ Default namespace | ---- | ---- | ----------- | -------- | | conversation_id | string | | No | | created_at | integer | | No | -| created_by_account | [SimpleAccount](#simpleaccount) | | No | +| created_by_account | [SimpleAccountResponse](#simpleaccountresponse) | | No | | elapsed_time | number | | No | | exceptions_count | integer | | No | | finished_at | integer | | No | @@ -13429,7 +13436,6 @@ Soft lifecycle state for Agent records. | created_at | integer | | No | | files | [ string ] | | Yes | | id | string | | Yes | -| message_chain_id | string | | No | | message_id | string | | Yes | | observation | string | | No | | position | integer | | Yes | @@ -13909,6 +13915,12 @@ AppMCPServer Status Enum | use_icon_as_answer_icon | boolean | | No | | workflow | [WorkflowPartial](#workflowpartial) | | No | +#### AppSelectorScope + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| AppSelectorScope | string | | | + #### AppSiteResponse | Name | Type | Description | Required | @@ -14540,8 +14552,8 @@ Enum class for configurate method of provider model. | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | annotation_create_account | [SimpleAccount](#simpleaccount) | | No | +| annotation_id | string | | Yes | | created_at | integer | | No | -| id | string | | Yes | #### ConversationDetail @@ -15782,12 +15794,6 @@ Request payload for bulk downloading documents as a zip archive. | role | string | | Yes | | token | string | | Yes | -#### EducationActivateResponse - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| EducationActivateResponse | object | | | - #### EducationAutocompleteQuery | Name | Type | Description | Required | @@ -15897,29 +15903,32 @@ Request payload for bulk downloading documents as a zip archive. | plugin_unique_identifier | string | | Yes | | settings | object | | Yes | -#### EndpointCreateResponse +#### EndpointDeclaration + +declaration of an endpoint | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | -| success | boolean | Operation success | Yes | +| hidden | boolean | | No | +| method | string | | Yes | +| path | string | | Yes | -#### EndpointDeleteResponse +#### EndpointEntityWithInstance | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | -| success | boolean | Operation success | Yes | - -#### EndpointDisableResponse - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| success | boolean | Operation success | Yes | - -#### EndpointEnableResponse - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| success | boolean | Operation success | Yes | +| created_at | dateTime | | Yes | +| declaration | [EndpointProviderDeclaration](#endpointproviderdeclaration) | | No | +| enabled | boolean | | Yes | +| expired_at | dateTime | | Yes | +| hook_id | string | | Yes | +| id | string | | Yes | +| name | string | | Yes | +| plugin_id | string | | Yes | +| settings | object | | Yes | +| tenant_id | string | | Yes | +| updated_at | dateTime | | Yes | +| url | string | | Yes | #### EndpointIdPayload @@ -15946,7 +15955,23 @@ Request payload for bulk downloading documents as a zip archive. | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | -| endpoints | [ object ] | Endpoint information | Yes | +| endpoints | [ [EndpointEntityWithInstance](#endpointentitywithinstance) ] | Endpoint information | Yes | + +#### EndpointProviderDeclaration + +declaration of an endpoint group + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| endpoints | [ [EndpointDeclaration](#endpointdeclaration) ] | | No | +| settings | [ [ProviderConfig](#providerconfig) ] | | No | + +#### EndpointSettingsPayload + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| name | string | | Yes | +| settings | object | | Yes | #### EndpointUpdatePayload @@ -15955,12 +15980,6 @@ Request payload for bulk downloading documents as a zip archive. | name | string | | Yes | | settings | object | | Yes | -#### EndpointUpdateResponse - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| success | boolean | Operation success | Yes | - #### EnvSuggestion | Name | Type | Description | Required | @@ -16986,12 +17005,12 @@ Enum class for large language model mode. | marketplace_plugin_unique_identifier | string | | Yes | | version | string | | No | -#### MemberActionTenantResponse +#### MemberActionResponse | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | result | string | | Yes | -| tenant_id | string | | Yes | +| tenant_id | string | | No | #### MemberBindingsResponse @@ -17079,6 +17098,7 @@ Enum class for large language model mode. | agent_thoughts | [ [AgentThought](#agentthought) ] | | No | | annotation | [ConversationAnnotation](#conversationannotation) | | No | | annotation_hit_history | [ConversationAnnotationHitHistory](#conversationannotationhithistory) | | No | +| answer | string | | Yes | | answer_tokens | integer | | No | | conversation_id | string | | Yes | | created_at | integer | | No | @@ -17092,12 +17112,11 @@ Enum class for large language model mode. | inputs | object | | Yes | | message | [JSONValue](#jsonvalue) | | No | | message_files | [ [MessageFile](#messagefile) ] | | No | -| message_metadata_dict | [JSONValue](#jsonvalue) | | No | | message_tokens | integer | | No | +| metadata | [JSONValue](#jsonvalue) | | No | | parent_message_id | string | | No | | provider_response_latency | number | | No | | query | string | | Yes | -| re_sign_file_url_answer | string | | Yes | | status | string | | Yes | | workflow_run_id | string | | No | @@ -17181,10 +17200,30 @@ Metadata operation data | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | -| completion_params | object | | No | -| mode | [LLMMode](#llmmode) | | Yes | -| name | string | | Yes | -| provider | string | | Yes | +| agent_mode | [JSONValue](#jsonvalue) | | No | +| annotation_reply | [JSONValue](#jsonvalue) | | No | +| chat_prompt_config | [JSONValue](#jsonvalue) | | No | +| completion_prompt_config | [JSONValue](#jsonvalue) | | No | +| created_at | integer | | No | +| created_by | string | | No | +| dataset_configs | [JSONValue](#jsonvalue) | | No | +| dataset_query_variable | string | | No | +| external_data_tools | [JSONValue](#jsonvalue) | | No | +| file_upload | [JSONValue](#jsonvalue) | | No | +| model | [JSONValue](#jsonvalue) | | No | +| more_like_this | [JSONValue](#jsonvalue) | | No | +| opening_statement | string | | No | +| pre_prompt | string | | No | +| prompt_type | string | | No | +| retriever_resource | [JSONValue](#jsonvalue) | | No | +| sensitive_word_avoidance | [JSONValue](#jsonvalue) | | No | +| speech_to_text | [JSONValue](#jsonvalue) | | No | +| suggested_questions | [JSONValue](#jsonvalue) | | No | +| suggested_questions_after_answer | [JSONValue](#jsonvalue) | | No | +| text_to_speech | [JSONValue](#jsonvalue) | | No | +| updated_at | integer | | No | +| updated_by | string | | No | +| user_input_form | [JSONValue](#jsonvalue) | | No | #### ModelConfigPartial @@ -17281,6 +17320,12 @@ Enum class for model property key. | ---- | ---- | ----------- | -------- | | payment_link | string | | Yes | +#### ModelSelectorScope + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| ModelSelectorScope | string | | | + #### ModelStatus Enum class for model status. @@ -17588,6 +17633,13 @@ Coarse node-level status used by Inspector to pick a banner. | ---- | ---- | ----------- | -------- | | OpaqueObjectResponse | object | | | +#### Option + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| label | [I18nObject](#i18nobject) | The label of the option | Yes | +| value | string | The value of the option | Yes | + #### OutputErrorStrategy Per-output failure handling strategy. @@ -18287,12 +18339,6 @@ Shared permission levels for resources (datasets, credentials, etc.) | ---- | ---- | ----------- | -------- | | options | | | Yes | -#### PluginEndpointListResponse - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| endpoints | [ object ] | Endpoint information | Yes | - #### PluginInstallationPermissionModel | Name | Type | Description | Required | @@ -18429,6 +18475,24 @@ Dataset Process Rule Mode | ---- | ---- | ----------- | -------- | | ProcessRuleMode | string | Dataset Process Rule Mode | | +#### ProviderConfig + +Model class for common provider settings like credentials + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| default | integer
string
number
boolean | | No | +| help | [I18nObject](#i18nobject) | | No | +| label | [I18nObject](#i18nobject) | | No | +| multiple | boolean | | No | +| name | string | The name of the credentials | Yes | +| options | [ [Option](#option) ] | | No | +| placeholder | [I18nObject](#i18nobject) | | No | +| required | boolean | | No | +| scope | [AppSelectorScope](#appselectorscope)
[ModelSelectorScope](#modelselectorscope)
[ToolSelectorScope](#toolselectorscope) | | No | +| type | [Type](#type) | The type of the credentials | Yes | +| url | string | | No | + #### ProviderCredentialResponse | Name | Type | Description | Required | @@ -19151,6 +19215,14 @@ Model class for provider quota configuration. | id | string | | Yes | | name | string | | Yes | +#### SimpleAccountResponse + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| email | string | | Yes | +| id | string | | Yes | +| name | string | | Yes | + #### SimpleConversation | Name | Type | Description | Required | @@ -19288,32 +19360,6 @@ Validated metadata extracted from a Skill package. | inferable | boolean | | Yes | | reason | string | | No | -#### Snippet - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| created_at | long | | No | -| created_by | [_AnonymousInlineModel_b0fd3f86d9d5](#_anonymousinlinemodel_b0fd3f86d9d5) | | No | -| description | string | | No | -| graph | object | | No | -| icon_info | object | | No | -| id | string | | No | -| input_fields | object | | No | -| is_published | boolean | | No | -| name | string | | No | -| tags | [ [_AnonymousInlineModel_7b8b49ca164e](#_anonymousinlinemodel_7b8b49ca164e) ] | | No | -| type | string | | No | -| updated_at | long | | No | -| updated_by | [_AnonymousInlineModel_b0fd3f86d9d5](#_anonymousinlinemodel_b0fd3f86d9d5) | | No | -| use_count | integer | | No | -| version | integer | | No | - -#### SnippetDependencyCheckResponse - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| SnippetDependencyCheckResponse | object | | | - #### SnippetDraftConfigResponse | Name | Type | Description | Required | @@ -19350,6 +19396,17 @@ Payload for syncing snippet draft workflow. | hash | string | | No | | input_fields | [ object ] | | No | +#### SnippetImportInfo + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| current_dsl_version | string,
**Default:** 0.1.0 | | No | +| error | string | | No | +| id | string | | Yes | +| imported_dsl_version | string | | No | +| snippet_id | string | | No | +| status | [ImportStatus](#importstatus) | | Yes | + #### SnippetImportPayload Payload for importing snippet from DSL. @@ -19363,12 +19420,6 @@ Payload for importing snippet from DSL. | yaml_content | string | YAML content (required for yaml-content mode) | No | | yaml_url | string | YAML URL (required for yaml-url mode) | No | -#### SnippetImportResponse - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| SnippetImportResponse | object | | | - #### SnippetIterationNodeRunPayload Payload for running an iteration node in snippet draft workflow. @@ -19377,24 +19428,24 @@ Payload for running an iteration node in snippet draft workflow. | ---- | ---- | ----------- | -------- | | inputs | object | | No | -#### SnippetList +#### SnippetListItemResponse | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | author_name | string | | No | -| created_at | long | | No | +| created_at | integer | | No | | created_by | string | | No | | description | string | | No | | icon_info | object | | No | -| id | string | | No | -| is_published | boolean | | No | -| name | string | | No | -| tags | [ [_AnonymousInlineModel_7b8b49ca164e](#_anonymousinlinemodel_7b8b49ca164e) ] | | No | -| type | string | | No | -| updated_at | long | | No | +| id | string | | Yes | +| is_published | boolean | | Yes | +| name | string | | Yes | +| tags | [ [SnippetTagResponse](#snippettagresponse) ] | | No | +| type | string | | Yes | +| updated_at | integer | | No | | updated_by | string | | No | -| use_count | integer | | No | -| version | integer | | No | +| use_count | integer | | Yes | +| version | integer | | Yes | #### SnippetListQuery @@ -19417,17 +19468,45 @@ Payload for running a loop node in snippet draft workflow. | ---- | ---- | ----------- | -------- | | inputs | object | | No | -#### SnippetPagination +#### SnippetPaginationResponse | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | -| data | [ [_AnonymousInlineModel_744ff9cc03e6](#_anonymousinlinemodel_744ff9cc03e6) ] | | No | -| has_more | boolean | | No | -| limit | integer | | No | -| page | integer | | No | -| total | integer | | No | +| data | [ [SnippetListItemResponse](#snippetlistitemresponse) ] | | Yes | +| has_more | boolean | | Yes | +| limit | integer | | Yes | +| page | integer | | Yes | +| total | integer | | Yes | -#### SnippetUseCountResponse +#### SnippetResponse + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| created_at | integer | | No | +| created_by | [SimpleAccountResponse](#simpleaccountresponse) | | No | +| description | string | | No | +| graph | object | | No | +| icon_info | object | | No | +| id | string | | Yes | +| input_fields | [ object ] | | No | +| is_published | boolean | | Yes | +| name | string | | Yes | +| tags | [ [SnippetTagResponse](#snippettagresponse) ] | | No | +| type | string | | Yes | +| updated_at | integer | | No | +| updated_by | [SimpleAccountResponse](#simpleaccountresponse) | | No | +| use_count | integer | | Yes | +| version | integer | | Yes | + +#### SnippetTagResponse + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| id | string | | Yes | +| name | string | | Yes | +| type | string | | Yes | + +#### SnippetUseCountIncrementResponse | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | @@ -19458,7 +19537,7 @@ Query parameters for listing snippet published workflows. | ---- | ---- | ----------- | -------- | | conversation_variables | [ [WorkflowConversationVariableResponse](#workflowconversationvariableresponse) ] | | Yes | | created_at | integer | | Yes | -| created_by | [SimpleAccount](#simpleaccount) | | No | +| created_by | [SimpleAccountResponse](#simpleaccountresponse) | | No | | environment_variables | [ [WorkflowEnvironmentVariableResponse](#workflowenvironmentvariableresponse) ] | | Yes | | features | object | | Yes | | graph | object | | Yes | @@ -19470,7 +19549,7 @@ Query parameters for listing snippet published workflows. | rag_pipeline_variables | [ [PipelineVariableResponse](#pipelinevariableresponse) ] | | Yes | | tool_published | boolean | | Yes | | updated_at | integer | | Yes | -| updated_by | [SimpleAccount](#simpleaccount) | | No | +| updated_by | [SimpleAccountResponse](#simpleaccountresponse) | | No | | version | string | | Yes | #### StarredAppListQuery @@ -19722,6 +19801,7 @@ Tag type | created_at | integer | | No | | current | boolean | | Yes | | id | string | | Yes | +| last_opened_at | integer | | No | | name | string | | No | | plan | string | | No | | status | string | | No | @@ -19841,6 +19921,12 @@ Enum class for tool provider | ---- | ---- | ----------- | -------- | | ToolProviderType | string | Enum class for tool provider | | +#### ToolSelectorScope + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| ToolSelectorScope | string | | | + #### TraceAppConfigResponse | Name | Type | Description | Required | @@ -19869,97 +19955,47 @@ Enum class for tool provider | ---- | ---- | ----------- | -------- | | tracing_provider | string | Tracing provider name | Yes | -#### TrialAppDetailWithSite +#### TrialDatasetListItemResponse | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | -| access_mode | string | | No | -| api_base_url | string | | No | -| created_at | long | | No | -| created_by | string | | No | -| deleted_tools | [ [TrialDeletedTool](#trialdeletedtool) ] | | No | -| description | string | | No | -| enable_api | boolean | | No | -| enable_site | boolean | | No | -| icon | string | | No | -| icon_background | string | | No | -| icon_type | string | | No | -| icon_url | string | | No | -| id | string | | No | -| max_active_requests | integer | | No | -| mode | string | | No | -| model_config | [TrialAppModelConfig](#trialappmodelconfig) | | No | -| name | string | | No | +| app_count | integer | | Yes | +| author_name | string | | Yes | +| built_in_field_enabled | boolean | | Yes | +| chunk_structure | string | | Yes | +| created_at | integer | | Yes | +| created_by | string | | Yes | +| data_source_type | string | | Yes | +| description | string | | Yes | +| doc_form | string | | Yes | +| doc_metadata | [ [DatasetDocMetadataResponse](#datasetdocmetadataresponse) ] | | Yes | +| document_count | integer | | Yes | +| embedding_available | boolean | | No | +| embedding_model | string | | Yes | +| embedding_model_provider | string | | Yes | +| enable_api | boolean | | Yes | +| external_knowledge_info | [DatasetExternalKnowledgeInfoResponse](#datasetexternalknowledgeinforesponse) | | No | +| external_retrieval_model | [DatasetExternalRetrievalModelResponse](#datasetexternalretrievalmodelresponse) | | Yes | +| icon_info | [DatasetIconInfoResponse](#dataseticoninforesponse) | | No | +| id | string | | Yes | +| indexing_technique | string | | Yes | +| is_multimodal | boolean | | Yes | +| is_published | boolean | | Yes | +| maintainer | string | | No | +| name | string | | Yes | +| permission | string | | Yes | | permission_keys | [ string ] | | No | -| site | [TrialSite](#trialsite) | | No | -| tags | [ [TrialTag](#trialtag) ] | | No | -| updated_at | long | | No | -| updated_by | string | | No | -| use_icon_as_answer_icon | boolean | | No | -| workflow | [TrialWorkflowPartial](#trialworkflowpartial) | | No | - -#### TrialAppModelConfig - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| agent_mode | object | | No | -| annotation_reply | object | | No | -| chat_prompt_config | object | | No | -| completion_prompt_config | object | | No | -| created_at | long | | No | -| created_by | string | | No | -| dataset_configs | object | | No | -| dataset_query_variable | string | | No | -| external_data_tools | [ object ] | | No | -| file_upload | object | | No | -| model | object | | No | -| more_like_this | object | | No | -| opening_statement | string | | No | -| pre_prompt | string | | No | -| prompt_type | string | | No | -| retriever_resource | object | | No | -| sensitive_word_avoidance | object | | No | -| speech_to_text | object | | No | -| suggested_questions | [ string ] | | No | -| suggested_questions_after_answer | object | | No | -| text_to_speech | object | | No | -| updated_at | long | | No | -| updated_by | string | | No | -| user_input_form | [ object ] | | No | - -#### TrialConversationVariable - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| description | string | | No | -| id | string | | No | -| name | string | | No | -| value | string
integer
number
boolean
object
[ object ] | | No | -| value_type | string | | No | - -#### TrialDataset - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| created_at | long | | No | -| created_by | string | | No | -| data_source_type | string | | No | -| description | string | | No | -| id | string | | No | -| indexing_technique | string | | No | -| name | string | | No | -| permission | string | | No | -| permission_keys | [ string ] | | No | - -#### TrialDatasetList - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| data | [ [TrialDataset](#trialdataset) ] | | No | -| has_more | boolean | | No | -| limit | integer | | No | -| page | integer | | No | -| total | integer | | No | +| pipeline_id | string | | Yes | +| provider | string | | Yes | +| retrieval_model_dict | [DatasetRetrievalModelResponse](#datasetretrievalmodelresponse) | | Yes | +| runtime_mode | string | | Yes | +| summary_index_setting | [DatasetSummaryIndexSettingResponse](#datasetsummaryindexsettingresponse) | | No | +| tags | [ [DatasetTagResponse](#datasettagresponse) ] | | Yes | +| total_available_documents | integer | | Yes | +| total_documents | integer | | Yes | +| updated_at | integer | | Yes | +| updated_by | string | | Yes | +| word_count | integer | | Yes | #### TrialDatasetListQuery @@ -19969,13 +20005,15 @@ Enum class for tool provider | limit | integer,
**Default:** 20 | Number of items per page | No | | page | integer,
**Default:** 1 | Page number | No | -#### TrialDeletedTool +#### TrialDatasetListResponse | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | -| provider_id | string | | No | -| tool_name | string | | No | -| type | string | | No | +| data | [ [TrialDatasetListItemResponse](#trialdatasetlistitemresponse) ] | | Yes | +| has_more | boolean | | Yes | +| limit | integer | | Yes | +| page | integer | | Yes | +| total | integer | | Yes | #### TrialModelsResponse @@ -19983,100 +20021,6 @@ Enum class for tool provider | ---- | ---- | ----------- | -------- | | trial_models | [ string ] | | Yes | -#### TrialPipelineVariable - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| allow_file_extension | [ string ] | | No | -| allow_file_upload_methods | [ string ] | | No | -| allowed_file_types | [ string ] | | No | -| belong_to_node_id | string | | No | -| default_value | string
integer
number
boolean
object
[ object ] | | No | -| label | string | | No | -| max_length | integer | | No | -| options | [ string ] | | No | -| placeholder | string | | No | -| required | boolean | | No | -| tooltips | string | | No | -| type | string | | No | -| unit | string | | No | -| variable | string | | No | - -#### TrialSimpleAccount - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| email | string | | No | -| id | string | | No | -| name | string | | No | - -#### TrialSite - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| access_token | string | | No | -| app_base_url | string | | No | -| chat_color_theme | string | | No | -| chat_color_theme_inverted | boolean | | No | -| code | string | | No | -| copyright | string | | No | -| created_at | long | | No | -| created_by | string | | No | -| custom_disclaimer | string | | No | -| customize_domain | string | | No | -| customize_token_strategy | string | | No | -| default_language | string | | No | -| description | string | | No | -| icon | string | | No | -| icon_background | string | | No | -| icon_type | string | | No | -| icon_url | string | | No | -| privacy_policy | string | | No | -| prompt_public | boolean | | No | -| show_workflow_steps | boolean | | No | -| title | string | | No | -| updated_at | long | | No | -| updated_by | string | | No | -| use_icon_as_answer_icon | boolean | | No | - -#### TrialTag - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| id | string | | No | -| name | string | | No | -| type | string | | No | - -#### TrialWorkflow - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| conversation_variables | [ [TrialConversationVariable](#trialconversationvariable) ] | | No | -| created_at | long | | No | -| created_by | [TrialSimpleAccount](#trialsimpleaccount) | | No | -| environment_variables | [ object ] | | No | -| features | object | | No | -| graph | object | | No | -| hash | string | | No | -| id | string | | No | -| marked_comment | string | | No | -| marked_name | string | | No | -| rag_pipeline_variables | [ [TrialPipelineVariable](#trialpipelinevariable) ] | | No | -| tool_published | boolean | | No | -| updated_at | long | | No | -| updated_by | [TrialSimpleAccount](#trialsimpleaccount) | | No | -| version | string | | No | - -#### TrialWorkflowPartial - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| created_at | long | | No | -| created_by | string | | No | -| id | string | | No | -| updated_at | long | | No | -| updated_by | string | | No | - #### TriggerOAuthAuthorizeResponse | Name | Type | Description | Required | @@ -20390,7 +20334,7 @@ How a workflow node is bound to an Agent. | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | created_at | integer | | No | -| created_by_account | [SimpleAccount](#simpleaccount) | | No | +| created_by_account | [SimpleAccountResponse](#simpleaccountresponse) | | No | | created_by_end_user | [SimpleEndUser](#simpleenduser) | | No | | created_by_role | string | | No | | created_from | string | | No | @@ -20427,7 +20371,7 @@ How a workflow node is bound to an Agent. | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | created_at | integer | | No | -| created_by_account | [SimpleAccount](#simpleaccount) | | No | +| created_by_account | [SimpleAccountResponse](#simpleaccountresponse) | | No | | created_by_end_user | [SimpleEndUser](#simpleenduser) | | No | | id | string | | Yes | | trigger_metadata | | | No | @@ -20528,7 +20472,7 @@ How a workflow node is bound to an Agent. | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | -| users | [ [AccountWithRole](#accountwithrole) ] | | Yes | +| users | [ [AccountWithRoleResponse](#accountwithroleresponse) ] | | Yes | #### WorkflowCommentReply @@ -20877,7 +20821,7 @@ can reuse its existing handler. | ---- | ---- | ----------- | -------- | | conversation_variables | [ [WorkflowConversationVariableResponse](#workflowconversationvariableresponse) ] | | Yes | | created_at | integer | | Yes | -| created_by | [SimpleAccount](#simpleaccount) | | No | +| created_by | [SimpleAccountResponse](#simpleaccountresponse) | | No | | environment_variables | [ [WorkflowEnvironmentVariableResponse](#workflowenvironmentvariableresponse) ] | | Yes | | features | object | | Yes | | graph | object | | Yes | @@ -20888,7 +20832,7 @@ can reuse its existing handler. | rag_pipeline_variables | [ [PipelineVariableResponse](#pipelinevariableresponse) ] | | Yes | | tool_published | boolean | | Yes | | updated_at | integer | | Yes | -| updated_by | [SimpleAccount](#simpleaccount) | | No | +| updated_by | [SimpleAccountResponse](#simpleaccountresponse) | | No | | version | string | | Yes | #### WorkflowRestoreResponse @@ -20923,7 +20867,7 @@ can reuse its existing handler. | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | created_at | integer | | No | -| created_by_account | [SimpleAccount](#simpleaccount) | | No | +| created_by_account | [SimpleAccountResponse](#simpleaccountresponse) | | No | | created_by_end_user | [SimpleEndUser](#simpleenduser) | | No | | created_by_role | string | | No | | elapsed_time | number | | No | @@ -20962,7 +20906,7 @@ can reuse its existing handler. | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | created_at | integer | | No | -| created_by_account | [SimpleAccount](#simpleaccount) | | No | +| created_by_account | [SimpleAccountResponse](#simpleaccountresponse) | | No | | elapsed_time | number | | No | | exceptions_count | integer | | No | | finished_at | integer | | No | @@ -21009,7 +20953,7 @@ can reuse its existing handler. | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | created_at | integer | | No | -| created_by_account | [SimpleAccount](#simpleaccount) | | No | +| created_by_account | [SimpleAccountResponse](#simpleaccountresponse) | | No | | created_by_end_user | [SimpleEndUser](#simpleenduser) | | No | | created_by_role | string | | No | | elapsed_time | number | | No | @@ -21202,7 +21146,13 @@ Workflow tool configuration | limit | integer,
**Default:** 20 | | No | | page | integer,
**Default:** 1 | | No | -#### WorkspaceListResponse +#### WorkspaceLogoUploadResponse + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| id | string | | Yes | + +#### WorkspacePaginationResponse | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | @@ -21212,19 +21162,6 @@ Workflow tool configuration | page | integer | | Yes | | total | integer | | Yes | -#### WorkspaceLogoUploadResponse - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| id | string | | Yes | - -#### WorkspaceMutationResponse - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| result | string | | Yes | -| tenant | [TenantInfoResponse](#tenantinforesponse) | | Yes | - #### WorkspacePermissionResponse | Name | Type | Description | Required | @@ -21239,6 +21176,13 @@ Workflow tool configuration | ---- | ---- | ----------- | -------- | | permission_keys | [ string ] | | No | +#### WorkspaceTenantResultResponse + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| result | string | | Yes | +| tenant | [TenantInfoResponse](#tenantinforesponse) | | Yes | + #### _AccessPolicyList | Name | Type | Description | Required | @@ -21246,41 +21190,6 @@ Workflow tool configuration | data | [ [AccessPolicy](#accesspolicy) ] | | No | | pagination | [Pagination](#pagination) | | No | -#### _AnonymousInlineModel_744ff9cc03e6 - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| author_name | string | | No | -| created_at | long | | No | -| created_by | string | | No | -| description | string | | No | -| icon_info | object | | No | -| id | string | | No | -| is_published | boolean | | No | -| name | string | | No | -| tags | [ [_AnonymousInlineModel_7b8b49ca164e](#_anonymousinlinemodel_7b8b49ca164e) ] | | No | -| type | string | | No | -| updated_at | long | | No | -| updated_by | string | | No | -| use_count | integer | | No | -| version | integer | | No | - -#### _AnonymousInlineModel_7b8b49ca164e - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| id | string | | No | -| name | string | | No | -| type | string | | No | - -#### _AnonymousInlineModel_b0fd3f86d9d5 - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| email | string | | No | -| id | string | | No | -| name | string | | No | - #### _AnonymousInlineModel_b1954337d565 | Name | Type | Description | Required | diff --git a/api/openapi/markdown/service-openapi.md b/api/openapi/markdown/service-openapi.md index 8fc5e75e3cf..5c30aefead1 100644 --- a/api/openapi/markdown/service-openapi.md +++ b/api/openapi/markdown/service-openapi.md @@ -3937,7 +3937,7 @@ Model class for provider with models response. | output_variable_name | string | | Yes | | type | string | | No | -#### SimpleAccount +#### SimpleAccountResponse | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | @@ -4147,7 +4147,7 @@ in form definiton, or a variable while the workflow is running. | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | created_at | integer | | No | -| created_by_account | [SimpleAccount](#simpleaccount) | | No | +| created_by_account | [SimpleAccountResponse](#simpleaccountresponse) | | No | | created_by_end_user | [SimpleEndUser](#simpleenduser) | | No | | created_by_role | string | | No | | created_from | string | | No | 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 be68a3beed6..2ac9fc978d8 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_trial.py +++ b/api/tests/unit_tests/controllers/console/explore/test_trial.py @@ -1,4 +1,4 @@ -from inspect import unwrap as inspect_unwrap +from inspect import unwrap from io import BytesIO from typing import Any from unittest.mock import MagicMock, patch @@ -35,24 +35,16 @@ from models.model import AppMode from services.errors.conversation import ConversationNotExistsError from services.errors.llm import InvokeRateLimitError -unwrap: Any = inspect_unwrap - @pytest.fixture -def account() -> Account: - acc = Account(name="User", email="user@example.com") +def account(): + acc = MagicMock(spec=Account) acc.id = "u1" return acc -def _file_data() -> Any: - file_data: Any = BytesIO(b"fake audio data") - file_data.filename = "test.wav" - return file_data - - @pytest.fixture -def trial_app_chat() -> MagicMock: +def trial_app_chat(): app = MagicMock() app.id = "a-chat" app.mode = AppMode.CHAT @@ -60,7 +52,7 @@ def trial_app_chat() -> MagicMock: @pytest.fixture -def trial_app_completion() -> MagicMock: +def trial_app_completion(): app = MagicMock() app.id = "a-comp" app.mode = AppMode.COMPLETION @@ -68,7 +60,7 @@ def trial_app_completion() -> MagicMock: @pytest.fixture -def trial_app_workflow() -> MagicMock: +def trial_app_workflow(): app = MagicMock() app.id = "a-workflow" app.mode = AppMode.WORKFLOW @@ -76,7 +68,7 @@ def trial_app_workflow() -> MagicMock: @pytest.fixture -def valid_parameters() -> dict[str, object]: +def valid_parameters(): return { "user_input_form": [], "system_parameters": {}, @@ -92,13 +84,54 @@ def valid_parameters() -> dict[str, object]: } -def test_trial_workflow_uses_trial_scoped_simple_account_model() -> None: - assert module.simple_account_model.name == "TrialSimpleAccount" - assert hasattr(module.simple_account_model, "items") +def test_trial_workflow_registers_normalized_simple_account_response_model(): + assert "SimpleAccountResponse" in module.console_ns.models + + +def _response_model_name(entry: object) -> str: + assert isinstance(entry, tuple) + assert len(entry) >= 2 + model = entry[1] + name = getattr(model, "name", None) + assert isinstance(name, str) + return name + + +def test_trial_endpoints_keep_response_and_query_docs(): + untyped_generated_response_views = [ + module.TrialAppWorkflowRunApi.post, + module.TrialChatApi.post, + module.TrialCompletionApi.post, + ] + for view in untyped_generated_response_views: + apidoc = getattr(view, "__apidoc__", {}) + assert apidoc.get("responses", {})["200"] == ("Success", None, {}) + + cases = [ + (module.TrialMessageSuggestedQuestionApi.get, module.SuggestedQuestionsResponse.__name__), + (module.TrialChatAudioApi.post, module.AudioTranscriptResponse.__name__), + (module.TrialChatTextApi.post, module.AudioBinaryResponse.__name__), + (module.TrialSitApi.get, module.SiteResponse.__name__), + (module.TrialAppParameterApi.get, module.ParametersResponse.__name__), + (module.AppApi.get, module.AppDetailWithSite.__name__), + (module.AppWorkflowApi.get, module.WorkflowResponse.__name__), + (module.DatasetListApi.get, module.TrialDatasetListResponse.__name__), + ] + + for view, model_name in cases: + apidoc = getattr(view, "__apidoc__", {}) + responses = apidoc.get("responses", {}) + assert _response_model_name(responses["200"]) == model_name + + dataset_params = module.DatasetListApi.get.__apidoc__["params"] + assert dataset_params["ids"]["in"] == "query" + assert dataset_params["ids"]["type"] == "array" + assert dataset_params["page"]["default"] == 1 + assert dataset_params["limit"]["default"] == 20 class TestTrialAppWorkflowRunApi: - def test_not_workflow_app(self, app: Flask, account: Account) -> None: + def test_not_workflow_app(self, app: Flask, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -106,7 +139,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(NotWorkflowAppError): method(api, account, MagicMock(mode=AppMode.CHAT)) - def test_success(self, app: Flask, trial_app_workflow: MagicMock, account: Account) -> None: + def test_success(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -119,7 +152,7 @@ class TestTrialAppWorkflowRunApi: assert result is not None - def test_workflow_provider_not_init(self, app: Flask, trial_app_workflow: MagicMock, account: Account) -> None: + def test_workflow_provider_not_init(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -134,7 +167,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(ProviderNotInitializeError): method(api, account, trial_app_workflow) - def test_workflow_quota_exceeded(self, app: Flask, trial_app_workflow: MagicMock, account: Account) -> None: + def test_workflow_quota_exceeded(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -149,7 +182,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(ProviderQuotaExceededError): method(api, account, trial_app_workflow) - def test_workflow_model_not_support(self, app: Flask, trial_app_workflow: MagicMock, account: Account) -> None: + def test_workflow_model_not_support(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -164,7 +197,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(ProviderModelCurrentlyNotSupportError): method(api, account, trial_app_workflow) - def test_workflow_invoke_error(self, app: Flask, trial_app_workflow: MagicMock, account: Account) -> None: + def test_workflow_invoke_error(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -179,7 +212,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(CompletionRequestError): method(api, account, trial_app_workflow) - def test_workflow_rate_limit_error(self, app: Flask, trial_app_workflow: MagicMock, account: Account) -> None: + def test_workflow_rate_limit_error(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -194,7 +227,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(InvokeRateLimitHttpError): method(api, account, trial_app_workflow) - def test_workflow_value_error(self, app: Flask, trial_app_workflow: MagicMock, account: Account) -> None: + def test_workflow_value_error(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -209,7 +242,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(ValueError): method(api, account, trial_app_workflow) - def test_workflow_generic_exception(self, app: Flask, trial_app_workflow: MagicMock, account: Account) -> None: + def test_workflow_generic_exception(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -226,7 +259,7 @@ class TestTrialAppWorkflowRunApi: class TestTrialChatApi: - def test_not_chat_app(self, app: Flask, account: Account) -> None: + def test_not_chat_app(self, app: Flask, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -234,7 +267,7 @@ class TestTrialChatApi: with pytest.raises(NotChatAppError): method(api, account, MagicMock(mode="completion")) - def test_success(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_success(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -247,7 +280,7 @@ class TestTrialChatApi: assert result is not None - def test_chat_conversation_not_exists(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_chat_conversation_not_exists(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -262,7 +295,7 @@ class TestTrialChatApi: with pytest.raises(NotFound): method(api, account, trial_app_chat) - def test_chat_conversation_completed(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_chat_conversation_completed(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -277,7 +310,7 @@ class TestTrialChatApi: with pytest.raises(ConversationCompletedError): method(api, account, trial_app_chat) - def test_chat_app_config_broken(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_chat_app_config_broken(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -292,7 +325,7 @@ class TestTrialChatApi: with pytest.raises(AppUnavailableError): method(api, account, trial_app_chat) - def test_chat_provider_not_init(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_chat_provider_not_init(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -307,7 +340,7 @@ class TestTrialChatApi: with pytest.raises(ProviderNotInitializeError): method(api, account, trial_app_chat) - def test_chat_quota_exceeded(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_chat_quota_exceeded(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -322,7 +355,7 @@ class TestTrialChatApi: with pytest.raises(ProviderQuotaExceededError): method(api, account, trial_app_chat) - def test_chat_model_not_support(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_chat_model_not_support(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -337,7 +370,7 @@ class TestTrialChatApi: with pytest.raises(ProviderModelCurrentlyNotSupportError): method(api, account, trial_app_chat) - def test_chat_invoke_error(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_chat_invoke_error(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -352,7 +385,7 @@ class TestTrialChatApi: with pytest.raises(CompletionRequestError): method(api, account, trial_app_chat) - def test_chat_rate_limit_error(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_chat_rate_limit_error(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -367,7 +400,7 @@ class TestTrialChatApi: with pytest.raises(InvokeRateLimitHttpError): method(api, account, trial_app_chat) - def test_chat_value_error(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_chat_value_error(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -382,7 +415,7 @@ class TestTrialChatApi: with pytest.raises(ValueError): method(api, account, trial_app_chat) - def test_chat_generic_exception(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_chat_generic_exception(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -399,7 +432,7 @@ class TestTrialChatApi: class TestTrialCompletionApi: - def test_not_completion_app(self, app: Flask, account: Account) -> None: + def test_not_completion_app(self, app: Flask, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -407,7 +440,7 @@ class TestTrialCompletionApi: with pytest.raises(NotCompletionAppError): method(api, account, MagicMock(mode=AppMode.CHAT)) - def test_success(self, app: Flask, trial_app_completion: MagicMock, account: Account) -> None: + def test_success(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -420,7 +453,7 @@ class TestTrialCompletionApi: assert result is not None - def test_completion_app_config_broken(self, app: Flask, trial_app_completion: MagicMock, account: Account) -> None: + def test_completion_app_config_broken(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -435,7 +468,7 @@ class TestTrialCompletionApi: with pytest.raises(AppUnavailableError): method(api, account, trial_app_completion) - def test_completion_provider_not_init(self, app: Flask, trial_app_completion: MagicMock, account: Account) -> None: + def test_completion_provider_not_init(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -450,7 +483,7 @@ class TestTrialCompletionApi: with pytest.raises(ProviderNotInitializeError): method(api, account, trial_app_completion) - def test_completion_quota_exceeded(self, app: Flask, trial_app_completion: MagicMock, account: Account) -> None: + def test_completion_quota_exceeded(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -465,7 +498,7 @@ class TestTrialCompletionApi: with pytest.raises(ProviderQuotaExceededError): method(api, account, trial_app_completion) - def test_completion_model_not_support(self, app: Flask, trial_app_completion: MagicMock, account: Account) -> None: + def test_completion_model_not_support(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -480,7 +513,7 @@ class TestTrialCompletionApi: with pytest.raises(ProviderModelCurrentlyNotSupportError): method(api, account, trial_app_completion) - def test_completion_invoke_error(self, app: Flask, trial_app_completion: MagicMock, account: Account) -> None: + def test_completion_invoke_error(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -495,7 +528,7 @@ class TestTrialCompletionApi: with pytest.raises(CompletionRequestError): method(api, account, trial_app_completion) - def test_completion_rate_limit_error(self, app: Flask, trial_app_completion: MagicMock, account: Account) -> None: + def test_completion_rate_limit_error(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -510,7 +543,7 @@ class TestTrialCompletionApi: with pytest.raises(InternalServerError): method(api, account, trial_app_completion) - def test_completion_value_error(self, app: Flask, trial_app_completion: MagicMock, account: Account) -> None: + def test_completion_value_error(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -525,7 +558,7 @@ class TestTrialCompletionApi: with pytest.raises(ValueError): method(api, account, trial_app_completion) - def test_completion_generic_exception(self, app: Flask, trial_app_completion: MagicMock, account: Account) -> None: + def test_completion_generic_exception(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -542,7 +575,7 @@ class TestTrialCompletionApi: class TestTrialMessageSuggestedQuestionApi: - def test_not_chat_app(self, app: Flask, account: Account) -> None: + def test_not_chat_app(self, app: Flask, account): api = module.TrialMessageSuggestedQuestionApi() method = unwrap(api.get) @@ -550,7 +583,7 @@ class TestTrialMessageSuggestedQuestionApi: with pytest.raises(NotChatAppError): method(api, account, MagicMock(mode="completion"), str(uuid4())) - def test_success(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_success(self, app: Flask, trial_app_chat, account): api = module.TrialMessageSuggestedQuestionApi() method = unwrap(api.get) @@ -566,7 +599,7 @@ class TestTrialMessageSuggestedQuestionApi: assert result == {"data": ["q1", "q2"]} - def test_conversation_not_exists(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_conversation_not_exists(self, app: Flask, trial_app_chat, account): api = module.TrialMessageSuggestedQuestionApi() method = unwrap(api.get) @@ -583,14 +616,14 @@ class TestTrialMessageSuggestedQuestionApi: class TestTrialAppParameterApi: - def test_app_unavailable(self) -> None: + def test_app_unavailable(self): api = module.TrialAppParameterApi() method = unwrap(api.get) with pytest.raises(AppUnavailableError): method(api, None) - def test_success_non_workflow(self, valid_parameters: dict[str, object]) -> None: + def test_success_non_workflow(self, valid_parameters): api = module.TrialAppParameterApi() method = unwrap(api.get) @@ -617,11 +650,12 @@ class TestTrialAppParameterApi: class TestTrialChatAudioApi: - def test_success(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_success(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) - file_data = _file_data() + file_data: Any = BytesIO(b"fake audio data") + file_data.filename = "test.wav" with ( app.test_request_context( @@ -634,11 +668,12 @@ class TestTrialChatAudioApi: assert result == {"text": "hello"} - def test_app_config_broken(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_app_config_broken(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) - file_data = _file_data() + file_data: Any = BytesIO(b"fake audio data") + file_data.filename = "test.wav" with ( app.test_request_context( @@ -653,11 +688,12 @@ class TestTrialChatAudioApi: with pytest.raises(module.AppUnavailableError): method(api, account, trial_app_chat) - def test_no_audio_uploaded(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_no_audio_uploaded(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) - file_data = _file_data() + file_data: Any = BytesIO(b"fake audio data") + file_data.filename = "test.wav" with ( app.test_request_context( @@ -672,11 +708,12 @@ class TestTrialChatAudioApi: with pytest.raises(module.NoAudioUploadedError): method(api, account, trial_app_chat) - def test_audio_too_large(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_audio_too_large(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) - file_data = _file_data() + file_data: Any = BytesIO(b"fake audio data") + file_data.filename = "test.wav" with ( app.test_request_context( @@ -691,11 +728,12 @@ class TestTrialChatAudioApi: with pytest.raises(module.AudioTooLargeError): method(api, account, trial_app_chat) - def test_unsupported_audio_type(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_unsupported_audio_type(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) - file_data = _file_data() + file_data: Any = BytesIO(b"fake audio data") + file_data.filename = "test.wav" with ( app.test_request_context( @@ -710,11 +748,12 @@ class TestTrialChatAudioApi: with pytest.raises(module.UnsupportedAudioTypeError): method(api, account, trial_app_chat) - def test_provider_not_support_tts(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_provider_not_support_tts(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) - file_data = _file_data() + file_data: Any = BytesIO(b"fake audio data") + file_data.filename = "test.wav" with ( app.test_request_context( @@ -729,11 +768,12 @@ class TestTrialChatAudioApi: with pytest.raises(module.ProviderNotSupportSpeechToTextError): method(api, account, trial_app_chat) - def test_provider_not_init(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_provider_not_init(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) - file_data = _file_data() + file_data: Any = BytesIO(b"fake audio data") + file_data.filename = "test.wav" with ( app.test_request_context( @@ -744,11 +784,12 @@ class TestTrialChatAudioApi: with pytest.raises(ProviderNotInitializeError): method(api, account, trial_app_chat) - def test_quota_exceeded(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_quota_exceeded(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) - file_data = _file_data() + file_data: Any = BytesIO(b"fake audio data") + file_data.filename = "test.wav" with ( app.test_request_context( @@ -761,7 +802,7 @@ class TestTrialChatAudioApi: class TestTrialChatTextApi: - def test_success(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_success(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -774,7 +815,7 @@ class TestTrialChatTextApi: assert result == {"audio": "base64_data"} - def test_app_config_broken(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_app_config_broken(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -789,7 +830,7 @@ class TestTrialChatTextApi: with pytest.raises(module.AppUnavailableError): method(api, account, trial_app_chat) - def test_provider_not_support(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_provider_not_support(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -804,7 +845,7 @@ class TestTrialChatTextApi: with pytest.raises(module.ProviderNotSupportSpeechToTextError): method(api, account, trial_app_chat) - def test_audio_too_large(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_audio_too_large(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -819,7 +860,7 @@ class TestTrialChatTextApi: with pytest.raises(module.AudioTooLargeError): method(api, account, trial_app_chat) - def test_no_audio_uploaded(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_no_audio_uploaded(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -834,7 +875,7 @@ class TestTrialChatTextApi: with pytest.raises(module.NoAudioUploadedError): method(api, account, trial_app_chat) - def test_provider_not_init(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_provider_not_init(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -845,7 +886,7 @@ class TestTrialChatTextApi: with pytest.raises(ProviderNotInitializeError): method(api, account, trial_app_chat) - def test_quota_exceeded(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_quota_exceeded(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -856,7 +897,7 @@ class TestTrialChatTextApi: with pytest.raises(ProviderQuotaExceededError): method(api, account, trial_app_chat) - def test_model_not_support(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_model_not_support(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -867,7 +908,7 @@ class TestTrialChatTextApi: with pytest.raises(ProviderModelCurrentlyNotSupportError): method(api, account, trial_app_chat) - def test_invoke_error(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_invoke_error(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -880,7 +921,7 @@ class TestTrialChatTextApi: class TestTrialAppWorkflowTaskStopApi: - def test_not_workflow_app(self, app: Flask, trial_app_chat: MagicMock) -> None: + def test_not_workflow_app(self, app: Flask, trial_app_chat): api = module.TrialAppWorkflowTaskStopApi() method = unwrap(api.post) @@ -888,7 +929,7 @@ class TestTrialAppWorkflowTaskStopApi: with pytest.raises(NotWorkflowAppError): method(api, trial_app_chat, str(uuid4())) - def test_success(self, app: Flask, trial_app_workflow: MagicMock) -> None: + def test_success(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowTaskStopApi() method = unwrap(api.post) @@ -906,7 +947,7 @@ class TestTrialAppWorkflowTaskStopApi: class TestTrialSitApi: - def test_no_site(self, app: Flask) -> None: + def test_no_site(self, app: Flask): api = module.TrialSitApi() method = unwrap(api.get) app_model = MagicMock() @@ -917,7 +958,7 @@ class TestTrialSitApi: with pytest.raises(Forbidden): method(api, app_model) - def test_archived_tenant(self, app: Flask) -> None: + def test_archived_tenant(self, app: Flask): api = module.TrialSitApi() method = unwrap(api.get) @@ -932,7 +973,7 @@ class TestTrialSitApi: with pytest.raises(Forbidden): method(api, app_model) - def test_success(self, app: Flask) -> None: + def test_success(self, app: Flask): api = module.TrialSitApi() method = unwrap(api.get) @@ -957,11 +998,12 @@ class TestTrialSitApi: class TestTrialChatAudioApiExceptionHandlers: - def test_provider_not_init(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_provider_not_init(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) - file_data = _file_data() + file_data: Any = BytesIO(b"fake audio data") + file_data.filename = "test.wav" with ( app.test_request_context( @@ -976,11 +1018,12 @@ class TestTrialChatAudioApiExceptionHandlers: with pytest.raises(ProviderNotInitializeError): method(api, account, trial_app_chat) - def test_quota_exceeded(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_quota_exceeded(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) - file_data = _file_data() + file_data: Any = BytesIO(b"fake audio data") + file_data.filename = "test.wav" with ( app.test_request_context( @@ -995,11 +1038,12 @@ class TestTrialChatAudioApiExceptionHandlers: with pytest.raises(ProviderQuotaExceededError): method(api, account, trial_app_chat) - def test_invoke_error(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_invoke_error(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) - file_data = _file_data() + file_data: Any = BytesIO(b"fake audio data") + file_data.filename = "test.wav" with ( app.test_request_context( @@ -1016,7 +1060,7 @@ class TestTrialChatAudioApiExceptionHandlers: class TestTrialChatTextApiExceptionHandlers: - def test_app_config_broken(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_app_config_broken(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -1031,7 +1075,7 @@ class TestTrialChatTextApiExceptionHandlers: with pytest.raises(module.AppUnavailableError): method(api, account, trial_app_chat) - def test_unsupported_audio_type(self, app: Flask, trial_app_chat: MagicMock, account: Account) -> None: + def test_unsupported_audio_type(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) 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 abd9b4facb9..8db3a295376 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_endpoint.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_endpoint.py @@ -1,4 +1,5 @@ import inspect +from datetime import UTC, datetime from unittest.mock import patch import pytest @@ -16,9 +17,32 @@ from controllers.console.workspace.endpoint import ( EndpointListApi, EndpointListForSinglePluginApi, ) +from core.plugin.entities.endpoint import EndpointEntityWithInstance from core.plugin.impl.exc import PluginPermissionDeniedError +def _endpoint_entity() -> EndpointEntityWithInstance: + now = datetime(2026, 1, 1, tzinfo=UTC) + return EndpointEntityWithInstance( + id="e1", + created_at=now, + updated_at=now, + tenant_id="t1", + plugin_id="p1", + settings={ + "secret": "value", + "enabled": True, + "ids": ["a", "b"], + "nested": {"limit": 3}, + }, + expired_at=now, + name="endpoint", + enabled=True, + url="https://example.test/hook-1", + hook_id="hook-1", + ) + + class TestEndpointCollectionApi: def test_create_success(self, app: Flask): api = EndpointCollectionApi() @@ -102,12 +126,34 @@ class TestEndpointListApi: with ( app.test_request_context("/?page=1&page_size=10"), - patch("controllers.console.workspace.endpoint.EndpointService.list_endpoints", return_value=[{"id": "e1"}]), + patch( + "controllers.console.workspace.endpoint.EndpointService.list_endpoints", + return_value=[_endpoint_entity()], + ), ): result = method(api, "t1", "u1") - assert "endpoints" in result - assert len(result["endpoints"]) == 1 + assert result["endpoints"] == [ + { + "id": "e1", + "created_at": "2026-01-01T00:00:00Z", + "updated_at": "2026-01-01T00:00:00Z", + "settings": { + "secret": "value", + "enabled": True, + "ids": ["a", "b"], + "nested": {"limit": 3}, + }, + "tenant_id": "t1", + "plugin_id": "p1", + "expired_at": "2026-01-01T00:00:00Z", + "declaration": {"settings": [], "endpoints": []}, + "name": "endpoint", + "enabled": True, + "url": "https://example.test/hook-1", + "hook_id": "hook-1", + } + ] def test_list_invalid_query(self, app: Flask): api = EndpointListApi() @@ -129,12 +175,13 @@ class TestEndpointListForSinglePluginApi: app.test_request_context("/?page=1&page_size=10&plugin_id=p1"), patch( "controllers.console.workspace.endpoint.EndpointService.list_endpoints_for_single_plugin", - return_value=[{"id": "e1"}], + return_value=[_endpoint_entity()], ), ): result = method(api, "t1", "u1") - assert "endpoints" in result + assert result["endpoints"][0]["id"] == "e1" + assert result["endpoints"][0]["settings"]["nested"] == {"limit": 3} def test_list_for_plugin_missing_param(self, app: Flask): api = EndpointListForSinglePluginApi() diff --git a/api/tests/unit_tests/controllers/console/workspace/test_snippets.py b/api/tests/unit_tests/controllers/console/workspace/test_snippets.py index e8e005a1b83..55eee935606 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_snippets.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_snippets.py @@ -1,3 +1,4 @@ +from datetime import datetime from inspect import unwrap from types import SimpleNamespace from unittest.mock import ANY, Mock @@ -46,12 +47,73 @@ def _snippet(**overrides) -> CustomizedSnippet: "name": "Snippet", "description": "Description", "type": snippets_module.SnippetType.NODE, + "version": 3, + "use_count": 7, + "is_published": True, + "icon_info": {"icon": "star", "icon_background": "#101828", "icon_type": "emoji"}, + "input_fields": '[{"label": "Question", "variable": "query", "type": "text-input"}]', "created_by": "account-1", + "created_at": datetime(2024, 1, 2, 3, 4, 5), + "updated_by": None, + "updated_at": datetime(2024, 1, 3, 4, 5, 6), } data.update(overrides) return CustomizedSnippet(**data) +def _patch_snippet_response_properties(monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setattr( + CustomizedSnippet, + "tags", + property(lambda _snippet: [{"id": "tag-1", "name": "Search", "type": "snippet"}]), + ) + monkeypatch.setattr(CustomizedSnippet, "created_by_account", property(lambda _snippet: _account("account-1"))) + monkeypatch.setattr(CustomizedSnippet, "updated_by_account", property(lambda _snippet: None)) + + +def _expected_snippet_list_item(snippet: CustomizedSnippet) -> dict: + return { + "id": snippet.id, + "name": snippet.name, + "description": snippet.description, + "type": snippet.type, + "version": snippet.version, + "use_count": snippet.use_count, + "is_published": snippet.is_published, + "icon_info": snippet.icon_info, + "tags": [{"id": "tag-1", "name": "Search", "type": "snippet"}], + "created_by": snippet.created_by, + "author_name": "Test User", + "created_at": int(snippet.created_at.timestamp()), + "updated_by": snippet.updated_by, + "updated_at": int(snippet.updated_at.timestamp()), + } + + +def _expected_snippet_response(snippet: CustomizedSnippet) -> dict: + return { + "id": snippet.id, + "name": snippet.name, + "description": snippet.description, + "type": snippet.type, + "version": snippet.version, + "use_count": snippet.use_count, + "is_published": snippet.is_published, + "icon_info": snippet.icon_info, + "graph": {}, + "input_fields": [{"label": "Question", "variable": "query", "type": "text-input"}], + "tags": [{"id": "tag-1", "name": "Search", "type": "snippet"}], + "created_by": { + "id": "account-1", + "name": "Test User", + "email": "account-1@example.com", + }, + "created_at": int(snippet.created_at.timestamp()), + "updated_by": None, + "updated_at": int(snippet.updated_at.timestamp()), + } + + def test_normalize_snippet_list_query_args_sorts_indexed_values(): query_args = snippets_module.MultiDict( [ @@ -75,7 +137,7 @@ def test_list_snippets_returns_pagination(app: Flask, monkeypatch: pytest.Monkey tag_id = "11111111-1111-1111-1111-111111111111" get_snippets = Mock(return_value=(snippets, 1, False)) monkeypatch.setattr(snippets_module.SnippetService, "get_snippets", get_snippets) - monkeypatch.setattr(snippets_module, "marshal", Mock(return_value=[{"id": "snippet-1"}])) + _patch_snippet_response_properties(monkeypatch) api = snippets_module.CustomizedSnippetsApi() handler = unwrap(api.get) @@ -87,7 +149,7 @@ def test_list_snippets_returns_pagination(app: Flask, monkeypatch: pytest.Monkey assert status_code == 200 assert response == { - "data": [{"id": "snippet-1"}], + "data": [_expected_snippet_list_item(snippets[0])], "page": 2, "limit": 10, "total": 1, @@ -110,6 +172,7 @@ def test_create_snippet_defaults_unknown_type_and_returns_created(app: Flask, mo snippet = _snippet() create_snippet = Mock(return_value=snippet) monkeypatch.setattr(snippets_module.SnippetService, "create_snippet", create_snippet) + _patch_snippet_response_properties(monkeypatch) monkeypatch.setattr( snippets_module.CreateSnippetPayload, "model_validate", @@ -124,7 +187,6 @@ def test_create_snippet_defaults_unknown_type_and_returns_created(app: Flask, mo ) ), ) - monkeypatch.setattr(snippets_module, "marshal", Mock(return_value={"id": "snippet-1"})) api = snippets_module.CustomizedSnippetsApi() handler = unwrap(api.post) @@ -137,7 +199,7 @@ def test_create_snippet_defaults_unknown_type_and_returns_created(app: Flask, mo response, status_code = handler(api, "tenant-1", user) assert status_code == 201 - assert response == {"id": "snippet-1"} + assert response == _expected_snippet_response(snippet) assert create_snippet.call_args.kwargs["snippet_type"] == snippets_module.SnippetType.NODE @@ -184,7 +246,7 @@ def test_get_snippet_detail_raises_when_missing(app: Flask, monkeypatch: pytest. def test_get_snippet_detail_returns_snippet(app: Flask, monkeypatch: pytest.MonkeyPatch): snippet = _snippet() monkeypatch.setattr(snippets_module.SnippetService, "get_snippet_by_id", Mock(return_value=snippet)) - monkeypatch.setattr(snippets_module, "marshal", Mock(return_value={"id": "snippet-1"})) + _patch_snippet_response_properties(monkeypatch) api = snippets_module.CustomizedSnippetDetailApi() handler = unwrap(api.get) @@ -193,7 +255,7 @@ def test_get_snippet_detail_returns_snippet(app: Flask, monkeypatch: pytest.Monk response, status_code = handler(api, "tenant-1", snippet_id="snippet-1") assert status_code == 200 - assert response == {"id": "snippet-1"} + assert response == _expected_snippet_response(snippet) def test_patch_snippet_returns_400_for_empty_payload(app: Flask, monkeypatch: pytest.MonkeyPatch): @@ -230,7 +292,7 @@ def test_patch_snippet_updates_and_commits(app: Flask, monkeypatch: pytest.Monke monkeypatch.setattr(snippets_module.SnippetService, "update_snippet", update_snippet) monkeypatch.setattr(snippets_module, "Session", SessionContext) monkeypatch.setattr(snippets_module, "db", SimpleNamespace(engine=object())) - monkeypatch.setattr(snippets_module, "marshal", Mock(return_value={"id": "snippet-1", "name": "New"})) + _patch_snippet_response_properties(monkeypatch) api = snippets_module.CustomizedSnippetDetailApi() handler = unwrap(api.patch) @@ -243,7 +305,7 @@ def test_patch_snippet_updates_and_commits(app: Flask, monkeypatch: pytest.Monke response, status_code = handler(api, "tenant-1", user, snippet_id="snippet-1") assert status_code == 200 - assert response == {"id": "snippet-1", "name": "New"} + assert response == _expected_snippet_response(updated_snippet) update_snippet.assert_called_once() assert update_snippet.call_args.kwargs["data"] == { "name": "New", 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 47e9f51fb27..e9cd3410cb9 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_workspace.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_workspace.py @@ -26,7 +26,9 @@ from controllers.console.workspace.workspace import ( WebappLogoWorkspaceApi, WorkspaceInfoApi, WorkspaceListApi, + WorkspaceLogoUploadResponse, WorkspacePermissionApi, + WorkspacePermissionResponse, ) from enums.cloud_plan import CloudPlan from libs.datetime_utils import naive_utc_now @@ -587,7 +589,8 @@ class TestWebappLogoWorkspaceApi: result, status = method(api, user) assert status == 201 - assert result["id"] == "file1" + assert result == {"id": "file1"} + assert WorkspaceLogoUploadResponse.model_validate(result).model_dump(mode="json") == {"id": "file1"} def test_filename_missing(self, app: Flask): api = WebappLogoWorkspaceApi() @@ -676,7 +679,7 @@ class TestWorkspaceInfoApi: patch("controllers.console.workspace.workspace.db.session.commit"), patch( "controllers.console.workspace.workspace.WorkspaceService.get_tenant_info", - return_value={"name": "New Name"}, + return_value={"id": "t1", "name": "New Name"}, ), ): result = method(api, "t1") @@ -717,7 +720,13 @@ class TestWorkspacePermissionApi: result, status = method(api, "t1") assert status == 200 - assert result["workspace_id"] == "t1" + expected = { + "workspace_id": "t1", + "allow_member_invite": True, + "allow_owner_transfer": False, + } + assert result == expected + assert WorkspacePermissionResponse.model_validate(result).model_dump(mode="json") == expected def test_no_current_tenant(self, app: Flask): api = WorkspacePermissionApi() diff --git a/api/tests/unit_tests/fields/test_snippet_fields.py b/api/tests/unit_tests/fields/test_snippet_fields.py index ad8ee6e8f0b..233c4e5da90 100644 --- a/api/tests/unit_tests/fields/test_snippet_fields.py +++ b/api/tests/unit_tests/fields/test_snippet_fields.py @@ -1,8 +1,7 @@ from types import SimpleNamespace -from flask_restx import marshal - -from fields.snippet_fields import snippet_list_fields +from fields.snippet_fields import SnippetListItemResponse +from libs.helper import dump_response def test_snippet_list_fields_include_author_name() -> None: @@ -23,6 +22,6 @@ def test_snippet_list_fields_include_author_name() -> None: updated_at=None, ) - result = marshal(snippet, snippet_list_fields) + result = dump_response(SnippetListItemResponse, snippet) assert result["author_name"] == "Alice" diff --git a/packages/contracts/generated/api/console/account/orpc.gen.ts b/packages/contracts/generated/api/console/account/orpc.gen.ts index a9261036675..e719bbfabd0 100644 --- a/packages/contracts/generated/api/console/account/orpc.gen.ts +++ b/packages/contracts/generated/api/console/account/orpc.gen.ts @@ -27,8 +27,6 @@ import { zPostAccountDeleteFeedbackBody, zPostAccountDeleteFeedbackResponse, zPostAccountDeleteResponse, - zPostAccountEducationBody, - zPostAccountEducationResponse, zPostAccountInitBody, zPostAccountInitResponse, zPostAccountInterfaceLanguageBody, @@ -222,25 +220,13 @@ export const get5 = oc }) .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 +export const post8 = oc .route({ inputStructure: 'detailed', method: 'POST', @@ -252,7 +238,7 @@ export const post9 = oc .output(zPostAccountInitResponse) export const init = { - post: post9, + post: post8, } export const get6 = oc @@ -269,7 +255,7 @@ export const integrates = { get: get6, } -export const post10 = oc +export const post9 = oc .route({ inputStructure: 'detailed', method: 'POST', @@ -281,10 +267,10 @@ export const post10 = oc .output(zPostAccountInterfaceLanguageResponse) export const interfaceLanguage = { - post: post10, + post: post9, } -export const post11 = oc +export const post10 = oc .route({ inputStructure: 'detailed', method: 'POST', @@ -296,10 +282,10 @@ export const post11 = oc .output(zPostAccountInterfaceThemeResponse) export const interfaceTheme = { - post: post11, + post: post10, } -export const post12 = oc +export const post11 = oc .route({ inputStructure: 'detailed', method: 'POST', @@ -311,10 +297,10 @@ export const post12 = oc .output(zPostAccountNameResponse) export const name = { - post: post12, + post: post11, } -export const post13 = oc +export const post12 = oc .route({ inputStructure: 'detailed', method: 'POST', @@ -326,7 +312,7 @@ export const post13 = oc .output(zPostAccountPasswordResponse) export const password = { - post: post13, + post: post12, } export const get7 = oc @@ -343,7 +329,7 @@ export const profile = { get: get7, } -export const post14 = oc +export const post13 = oc .route({ inputStructure: 'detailed', method: 'POST', @@ -355,7 +341,7 @@ export const post14 = oc .output(zPostAccountTimezoneResponse) export const timezone = { - post: post14, + post: post13, } export const account = { diff --git a/packages/contracts/generated/api/console/account/types.gen.ts b/packages/contracts/generated/api/console/account/types.gen.ts index cdd45925fb2..390e7caeffa 100644 --- a/packages/contracts/generated/api/console/account/types.gen.ts +++ b/packages/contracts/generated/api/console/account/types.gen.ts @@ -12,7 +12,7 @@ export type AccountAvatarPayload = { avatar: string } -export type Account = { +export type AccountResponse = { avatar?: string | null readonly avatar_url: string | null created_at?: number | null @@ -81,16 +81,6 @@ export type EducationStatusResponse = { result?: boolean | null } -export type EducationActivatePayload = { - institution: string - role: string - token: string -} - -export type EducationActivateResponse = { - [key: string]: unknown -} - export type EducationAutocompleteResponse = { curr_page?: number | null data?: Array @@ -140,7 +130,7 @@ export type AccountIntegrateResponse = { provider: string } -export type AccountWritable = { +export type AccountResponseWritable = { avatar?: string | null created_at?: number | null email: string @@ -177,7 +167,7 @@ export type PostAccountAvatarData = { } export type PostAccountAvatarResponses = { - 200: Account + 200: AccountResponse } export type PostAccountAvatarResponse = PostAccountAvatarResponses[keyof PostAccountAvatarResponses] @@ -218,7 +208,7 @@ export type PostAccountChangeEmailResetData = { } export type PostAccountChangeEmailResetResponses = { - 200: Account + 200: AccountResponse } export type PostAccountChangeEmailResetResponse @@ -293,20 +283,6 @@ export type GetAccountEducationResponses = { export type GetAccountEducationResponse = GetAccountEducationResponses[keyof GetAccountEducationResponses] -export type PostAccountEducationData = { - body: EducationActivatePayload - path?: never - query?: never - url: '/account/education' -} - -export type PostAccountEducationResponses = { - 200: EducationActivateResponse -} - -export type PostAccountEducationResponse - = PostAccountEducationResponses[keyof PostAccountEducationResponses] - export type GetAccountEducationAutocompleteData = { body?: never path?: never @@ -374,7 +350,7 @@ export type PostAccountInterfaceLanguageData = { } export type PostAccountInterfaceLanguageResponses = { - 200: Account + 200: AccountResponse } export type PostAccountInterfaceLanguageResponse @@ -388,7 +364,7 @@ export type PostAccountInterfaceThemeData = { } export type PostAccountInterfaceThemeResponses = { - 200: Account + 200: AccountResponse } export type PostAccountInterfaceThemeResponse @@ -402,7 +378,7 @@ export type PostAccountNameData = { } export type PostAccountNameResponses = { - 200: Account + 200: AccountResponse } export type PostAccountNameResponse = PostAccountNameResponses[keyof PostAccountNameResponses] @@ -415,7 +391,7 @@ export type PostAccountPasswordData = { } export type PostAccountPasswordResponses = { - 200: Account + 200: AccountResponse } export type PostAccountPasswordResponse @@ -429,7 +405,7 @@ export type GetAccountProfileData = { } export type GetAccountProfileResponses = { - 200: Account + 200: AccountResponse } export type GetAccountProfileResponse = GetAccountProfileResponses[keyof GetAccountProfileResponses] @@ -442,7 +418,7 @@ export type PostAccountTimezoneData = { } export type PostAccountTimezoneResponses = { - 200: Account + 200: AccountResponse } export type PostAccountTimezoneResponse diff --git a/packages/contracts/generated/api/console/account/zod.gen.ts b/packages/contracts/generated/api/console/account/zod.gen.ts index 9951efc8d9f..feb3a45d78b 100644 --- a/packages/contracts/generated/api/console/account/zod.gen.ts +++ b/packages/contracts/generated/api/console/account/zod.gen.ts @@ -17,9 +17,9 @@ export const zAccountAvatarPayload = z.object({ }) /** - * Account + * AccountResponse */ -export const zAccount = z.object({ +export const zAccountResponse = z.object({ avatar: z.string().nullish(), avatar_url: z.string().nullable(), created_at: z.int().nullish(), @@ -118,20 +118,6 @@ export const zEducationStatusResponse = z.object({ result: z.boolean().nullish(), }) -/** - * EducationActivatePayload - */ -export const zEducationActivatePayload = z.object({ - institution: z.string(), - role: z.string(), - token: z.string(), -}) - -/** - * EducationActivateResponse - */ -export const zEducationActivateResponse = z.record(z.string(), z.unknown()) - /** * EducationAutocompleteResponse */ @@ -212,9 +198,9 @@ export const zAccountIntegrateListResponse = z.object({ }) /** - * Account + * AccountResponse */ -export const zAccountWritable = z.object({ +export const zAccountResponseWritable = z.object({ avatar: z.string().nullish(), created_at: z.int().nullish(), email: z.string(), @@ -242,7 +228,7 @@ export const zPostAccountAvatarBody = zAccountAvatarPayload /** * Success */ -export const zPostAccountAvatarResponse = zAccount +export const zPostAccountAvatarResponse = zAccountResponse export const zPostAccountChangeEmailBody = zChangeEmailSendPayload @@ -263,7 +249,7 @@ export const zPostAccountChangeEmailResetBody = zChangeEmailResetPayload /** * Success */ -export const zPostAccountChangeEmailResetResponse = zAccount +export const zPostAccountChangeEmailResetResponse = zAccountResponse export const zPostAccountChangeEmailValidityBody = zChangeEmailValidityPayload @@ -296,13 +282,6 @@ export const zGetAccountDeleteVerifyResponse = zSimpleResultDataResponse */ export const zGetAccountEducationResponse = zEducationStatusResponse -export const zPostAccountEducationBody = zEducationActivatePayload - -/** - * Success - */ -export const zPostAccountEducationResponse = zEducationActivateResponse - export const zGetAccountEducationAutocompleteQuery = z.object({ keywords: z.string(), limit: z.int().optional().default(20), @@ -336,37 +315,37 @@ export const zPostAccountInterfaceLanguageBody = zAccountInterfaceLanguagePayloa /** * Success */ -export const zPostAccountInterfaceLanguageResponse = zAccount +export const zPostAccountInterfaceLanguageResponse = zAccountResponse export const zPostAccountInterfaceThemeBody = zAccountInterfaceThemePayload /** * Success */ -export const zPostAccountInterfaceThemeResponse = zAccount +export const zPostAccountInterfaceThemeResponse = zAccountResponse export const zPostAccountNameBody = zAccountNamePayload /** * Success */ -export const zPostAccountNameResponse = zAccount +export const zPostAccountNameResponse = zAccountResponse export const zPostAccountPasswordBody = zAccountPasswordPayload /** * Success */ -export const zPostAccountPasswordResponse = zAccount +export const zPostAccountPasswordResponse = zAccountResponse /** * Success */ -export const zGetAccountProfileResponse = zAccount +export const zGetAccountProfileResponse = zAccountResponse export const zPostAccountTimezoneBody = zAccountTimezonePayload /** * Success */ -export const zPostAccountTimezoneResponse = zAccount +export const zPostAccountTimezoneResponse = zAccountResponse diff --git a/packages/contracts/generated/api/console/agent/types.gen.ts b/packages/contracts/generated/api/console/agent/types.gen.ts index 43119c4f1f4..c5ef43f6360 100644 --- a/packages/contracts/generated/api/console/agent/types.gen.ts +++ b/packages/contracts/generated/api/console/agent/types.gen.ts @@ -269,6 +269,7 @@ export type MessageDetailResponse = { agent_thoughts?: Array annotation?: ConversationAnnotation | null annotation_hit_history?: ConversationAnnotationHitHistory | null + answer: string answer_tokens?: number | null conversation_id: string created_at?: number | null @@ -284,12 +285,11 @@ export type MessageDetailResponse = { } message?: JsonValue | null message_files?: Array - message_metadata_dict?: JsonValue | null message_tokens?: number | null + metadata?: JsonValue | 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 } @@ -405,12 +405,30 @@ export type DeletedTool = { } export type ModelConfig = { - completion_params?: { - [key: string]: unknown - } - mode: LlmMode - name: string - provider: string + agent_mode?: JsonValue | null + annotation_reply?: JsonValue | null + chat_prompt_config?: JsonValue | null + completion_prompt_config?: JsonValue | null + created_at?: number | null + created_by?: string | null + dataset_configs?: JsonValue | null + dataset_query_variable?: string | null + external_data_tools?: JsonValue | null + file_upload?: JsonValue | null + model?: JsonValue | null + more_like_this?: JsonValue | null + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource?: JsonValue | null + sensitive_word_avoidance?: JsonValue | null + speech_to_text?: JsonValue | null + suggested_questions?: JsonValue | null + suggested_questions_after_answer?: JsonValue | null + text_to_speech?: JsonValue | null + updated_at?: number | null + updated_by?: string | null + user_input_form?: JsonValue | null } export type Site = { @@ -723,7 +741,6 @@ export type AgentThought = { created_at?: number | null files: Array id: string - message_chain_id?: string | null message_id: string observation?: string | null position: number @@ -743,8 +760,8 @@ export type ConversationAnnotation = { export type ConversationAnnotationHitHistory = { annotation_create_account?: SimpleAccount | null + annotation_id: string created_at?: number | null - id: string } export type HumanInputContent = { @@ -879,8 +896,6 @@ export type AgentAppPublishedReferenceResponse = { app_name: string } -export type LlmMode = 'chat' | 'completion' - export type AgentKind = 'dify_agent' export type AgentPublishedReferenceResponse = { diff --git a/packages/contracts/generated/api/console/agent/zod.gen.ts b/packages/contracts/generated/api/console/agent/zod.gen.ts index d7f5681ffc4..634ab4af2d5 100644 --- a/packages/contracts/generated/api/console/agent/zod.gen.ts +++ b/packages/contracts/generated/api/console/agent/zod.gen.ts @@ -229,6 +229,36 @@ export const zJsonValue = z ]) .nullable() +/** + * ModelConfig + */ +export const zModelConfig = z.object({ + agent_mode: zJsonValue.nullish(), + annotation_reply: zJsonValue.nullish(), + chat_prompt_config: zJsonValue.nullish(), + completion_prompt_config: zJsonValue.nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs: zJsonValue.nullish(), + dataset_query_variable: z.string().nullish(), + external_data_tools: zJsonValue.nullish(), + file_upload: zJsonValue.nullish(), + model: zJsonValue.nullish(), + more_like_this: zJsonValue.nullish(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource: zJsonValue.nullish(), + sensitive_word_avoidance: zJsonValue.nullish(), + speech_to_text: zJsonValue.nullish(), + suggested_questions: zJsonValue.nullish(), + suggested_questions_after_answer: zJsonValue.nullish(), + text_to_speech: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form: zJsonValue.nullish(), +}) + /** * WorkflowPartial */ @@ -240,6 +270,43 @@ export const zWorkflowPartial = z.object({ updated_by: z.string().nullish(), }) +/** + * AgentAppDetailWithSite + */ +export const zAgentAppDetailWithSite = z.object({ + access_mode: z.string().nullish(), + active_config_is_published: z.boolean().optional().default(false), + api_base_url: z.string().nullish(), + app_id: z.string().nullish(), + bound_agent_id: z.string().nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + debug_conversation_id: 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(), + icon_url: z.string().nullable(), + id: z.string(), + maintainer: z.string().nullish(), + max_active_requests: z.int().nullish(), + mode: z.string(), + model_config: zModelConfig.nullish(), + name: z.string(), + permission_keys: z.array(z.string()).optional(), + role: z.string().nullish(), + site: zSite.nullish(), + tags: z.array(zTag).optional(), + tracing: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + use_icon_as_answer_icon: z.boolean().nullish(), + workflow: zWorkflowPartial.nullish(), +}) + /** * AgentConfigSnapshotSummaryResponse */ @@ -570,7 +637,6 @@ export const zAgentThought = z.object({ 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(), @@ -773,60 +839,6 @@ export const zAgentAppPagination = z.object({ total: z.int(), }) -/** - * LLMMode - * - * Enum class for large language model mode. - */ -export const zLlmMode = z.enum(['chat', 'completion']) - -/** - * ModelConfig - */ -export const zModelConfig = z.object({ - completion_params: z.record(z.string(), z.unknown()).optional(), - mode: zLlmMode, - name: z.string(), - provider: z.string(), -}) - -/** - * AgentAppDetailWithSite - */ -export const zAgentAppDetailWithSite = z.object({ - access_mode: z.string().nullish(), - active_config_is_published: z.boolean().optional().default(false), - api_base_url: z.string().nullish(), - app_id: z.string().nullish(), - bound_agent_id: z.string().nullish(), - created_at: z.int().nullish(), - created_by: z.string().nullish(), - debug_conversation_id: 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(), - icon_url: z.string().nullable(), - id: z.string(), - maintainer: z.string().nullish(), - max_active_requests: z.int().nullish(), - mode: z.string(), - model_config: zModelConfig.nullish(), - name: z.string(), - permission_keys: z.array(z.string()).optional(), - role: z.string().nullish(), - site: zSite.nullish(), - tags: z.array(zTag).optional(), - tracing: zJsonValue.nullish(), - updated_at: z.int().nullish(), - updated_by: z.string().nullish(), - use_icon_as_answer_icon: z.boolean().nullish(), - workflow: zWorkflowPartial.nullish(), -}) - /** * AgentKind * @@ -1056,8 +1068,8 @@ export const zConversationAnnotation = z.object({ */ export const zConversationAnnotationHitHistory = z.object({ annotation_create_account: zSimpleAccount.nullish(), + annotation_id: z.string(), created_at: z.int().nullish(), - id: z.string(), }) /** @@ -2035,6 +2047,7 @@ export const zMessageDetailResponse = z.object({ agent_thoughts: z.array(zAgentThought).optional(), annotation: zConversationAnnotation.nullish(), annotation_hit_history: zConversationAnnotationHitHistory.nullish(), + answer: z.string(), answer_tokens: z.int().nullish(), conversation_id: z.string(), created_at: z.int().nullish(), @@ -2048,12 +2061,11 @@ export const zMessageDetailResponse = z.object({ inputs: z.record(z.string(), zJsonValue), message: zJsonValue.nullish(), message_files: z.array(zMessageFile).optional(), - message_metadata_dict: zJsonValue.nullish(), message_tokens: z.int().nullish(), + metadata: zJsonValue.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(), }) diff --git a/packages/contracts/generated/api/console/all-workspaces/types.gen.ts b/packages/contracts/generated/api/console/all-workspaces/types.gen.ts index 4683b2d9921..b4c9fa0349a 100644 --- a/packages/contracts/generated/api/console/all-workspaces/types.gen.ts +++ b/packages/contracts/generated/api/console/all-workspaces/types.gen.ts @@ -4,7 +4,7 @@ export type ClientOptions = { baseUrl: `${string}://${string}/console/api` | (string & {}) } -export type WorkspaceListResponse = { +export type WorkspacePaginationResponse = { data: Array has_more: boolean limit: number @@ -30,7 +30,7 @@ export type GetAllWorkspacesData = { } export type GetAllWorkspacesResponses = { - 200: WorkspaceListResponse + 200: WorkspacePaginationResponse } 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 index f63bd0e396f..c9cdda11681 100644 --- a/packages/contracts/generated/api/console/all-workspaces/zod.gen.ts +++ b/packages/contracts/generated/api/console/all-workspaces/zod.gen.ts @@ -13,9 +13,9 @@ export const zWorkspaceListItemResponse = z.object({ }) /** - * WorkspaceListResponse + * WorkspacePaginationResponse */ -export const zWorkspaceListResponse = z.object({ +export const zWorkspacePaginationResponse = z.object({ data: z.array(zWorkspaceListItemResponse), has_more: z.boolean(), limit: z.int(), @@ -31,4 +31,4 @@ export const zGetAllWorkspacesQuery = z.object({ /** * Success */ -export const zGetAllWorkspacesResponse = zWorkspaceListResponse +export const zGetAllWorkspacesResponse = zWorkspacePaginationResponse diff --git a/packages/contracts/generated/api/console/apps/types.gen.ts b/packages/contracts/generated/api/console/apps/types.gen.ts index 9e79518f3cd..ed30656edda 100644 --- a/packages/contracts/generated/api/console/apps/types.gen.ts +++ b/packages/contracts/generated/api/console/apps/types.gen.ts @@ -472,6 +472,7 @@ export type MessageDetailResponse = { agent_thoughts?: Array annotation?: ConversationAnnotation | null annotation_hit_history?: ConversationAnnotationHitHistory | null + answer: string answer_tokens?: number | null conversation_id: string created_at?: number | null @@ -487,12 +488,11 @@ export type MessageDetailResponse = { } message?: JsonValue | null message_files?: Array - message_metadata_dict?: JsonValue | null message_tokens?: number | null + metadata?: JsonValue | 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 } @@ -731,7 +731,7 @@ export type WorkflowRunPaginationResponse = { export type WorkflowRunDetailResponse = { created_at?: number | null - created_by_account?: SimpleAccount | null + created_by_account?: SimpleAccountResponse | null created_by_end_user?: SimpleEndUser | null created_by_role?: string | null elapsed_time?: number | null @@ -799,7 +799,7 @@ export type WorkflowCommentCreate = { } export type WorkflowCommentMentionUsersPayload = { - users: Array + users: Array } export type WorkflowCommentDetail = { @@ -887,7 +887,7 @@ export type DefaultBlockConfigResponse = { export type WorkflowResponse = { conversation_variables: Array created_at: number - created_by?: SimpleAccount | null + created_by?: SimpleAccountResponse | null environment_variables: Array features: { [key: string]: unknown @@ -902,7 +902,7 @@ export type WorkflowResponse = { rag_pipeline_variables: Array tool_published: boolean updated_at: number - updated_by?: SimpleAccount | null + updated_by?: SimpleAccountResponse | null version: string } @@ -1029,7 +1029,7 @@ export type AgentComposerValidateResponse = { export type WorkflowRunNodeExecutionResponse = { created_at?: number | null - created_by_account?: SimpleAccount | null + created_by_account?: SimpleAccountResponse | null created_by_end_user?: SimpleEndUser | null created_by_role?: string | null elapsed_time?: number | null @@ -1223,12 +1223,30 @@ export type DeletedTool = { } export type ModelConfig = { - completion_params?: { - [key: string]: unknown - } - mode: LlmMode - name: string - provider: string + agent_mode?: JsonValue | null + annotation_reply?: JsonValue | null + chat_prompt_config?: JsonValue | null + completion_prompt_config?: JsonValue | null + created_at?: number | null + created_by?: string | null + dataset_configs?: JsonValue | null + dataset_query_variable?: string | null + external_data_tools?: JsonValue | null + file_upload?: JsonValue | null + model?: JsonValue | null + more_like_this?: JsonValue | null + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource?: JsonValue | null + sensitive_word_avoidance?: JsonValue | null + speech_to_text?: JsonValue | null + suggested_questions?: JsonValue | null + suggested_questions_after_answer?: JsonValue | null + text_to_speech?: JsonValue | null + updated_at?: number | null + updated_by?: string | null + user_input_form?: JsonValue | null } export type Site = { @@ -1289,7 +1307,7 @@ export type WorkflowOnlineUsersByApp = { export type AdvancedChatWorkflowRunForListResponse = { conversation_id?: string | null created_at?: number | null - created_by_account?: SimpleAccount | null + created_by_account?: SimpleAccountResponse | null elapsed_time?: number | null exceptions_count?: number | null finished_at?: number | null @@ -1498,7 +1516,6 @@ export type AgentThought = { created_at?: number | null files: Array id: string - message_chain_id?: string | null message_id: string observation?: string | null position: number @@ -1518,8 +1535,8 @@ export type ConversationAnnotation = { export type ConversationAnnotationHitHistory = { annotation_create_account?: SimpleAccount | null + annotation_id: string created_at?: number | null - id: string } export type HumanInputContent = { @@ -1596,7 +1613,7 @@ export type UserSatisfactionRateStatisticItem = { export type WorkflowAppLogPartialResponse = { created_at?: number | null - created_by_account?: SimpleAccount | null + created_by_account?: SimpleAccountResponse | null created_by_end_user?: SimpleEndUser | null created_by_role?: string | null created_from?: string | null @@ -1607,7 +1624,7 @@ export type WorkflowAppLogPartialResponse = { export type WorkflowArchivedLogPartialResponse = { created_at?: number | null - created_by_account?: SimpleAccount | null + created_by_account?: SimpleAccountResponse | null created_by_end_user?: SimpleEndUser | null id: string trigger_metadata?: unknown @@ -1616,7 +1633,7 @@ export type WorkflowArchivedLogPartialResponse = { export type WorkflowRunForListResponse = { created_at?: number | null - created_by_account?: SimpleAccount | null + created_by_account?: SimpleAccountResponse | null elapsed_time?: number | null exceptions_count?: number | null finished_at?: number | null @@ -1628,7 +1645,7 @@ export type WorkflowRunForListResponse = { version?: string | null } -export type SimpleAccount = { +export type SimpleAccountResponse = { email: string id: string name: string @@ -1671,8 +1688,9 @@ export type WorkflowCommentBasic = { updated_at?: number | null } -export type AccountWithRole = { +export type AccountWithRoleResponse = { avatar?: string | null + readonly avatar_url: string | null created_at?: number | null email: string id: string @@ -1982,9 +2000,14 @@ export type ModelConfigPartial = { updated_by?: string | null } -export type LlmMode = 'chat' | 'completion' - -export type Type = 'github' | 'marketplace' | 'package' +export type Type + = | 'app-selector' + | 'array[tools]' + | 'boolean' + | 'model-selector' + | 'secret-input' + | 'select' + | 'text-input' export type Github = { github_plugin_unique_identifier: string @@ -2054,6 +2077,12 @@ export type SimpleMessageDetail = { query: string } +export type SimpleAccount = { + email: string + id: string + name: string +} + export type HumanInputFormDefinition = { actions?: Array display_in_ui?: boolean @@ -2637,6 +2666,10 @@ export type WorkflowCommentBasicListWritable = { data: Array } +export type WorkflowCommentMentionUsersPayloadWritable = { + users: Array +} + export type WorkflowCommentDetailWritable = { content: string created_at?: number | null @@ -2716,6 +2749,21 @@ export type WorkflowCommentBasicWritable = { updated_at?: number | null } +export type AccountWithRoleResponseWritable = { + 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 + roles?: Array<{ + [key: string]: string + }> + status: string +} + export type WorkflowCommentAccountWritable = { email: string id: string diff --git a/packages/contracts/generated/api/console/apps/zod.gen.ts b/packages/contracts/generated/api/console/apps/zod.gen.ts index 9b86fda0a62..ab8a2081c85 100644 --- a/packages/contracts/generated/api/console/apps/zod.gen.ts +++ b/packages/contracts/generated/api/console/apps/zod.gen.ts @@ -889,6 +889,36 @@ export const zJsonValue = z */ export const zGeneratedAppResponse = zJsonValue +/** + * ModelConfig + */ +export const zModelConfig = z.object({ + agent_mode: zJsonValue.nullish(), + annotation_reply: zJsonValue.nullish(), + chat_prompt_config: zJsonValue.nullish(), + completion_prompt_config: zJsonValue.nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs: zJsonValue.nullish(), + dataset_query_variable: z.string().nullish(), + external_data_tools: zJsonValue.nullish(), + file_upload: zJsonValue.nullish(), + model: zJsonValue.nullish(), + more_like_this: zJsonValue.nullish(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource: zJsonValue.nullish(), + sensitive_word_avoidance: zJsonValue.nullish(), + speech_to_text: zJsonValue.nullish(), + suggested_questions: zJsonValue.nullish(), + suggested_questions_after_answer: zJsonValue.nullish(), + text_to_speech: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form: zJsonValue.nullish(), +}) + /** * WorkflowPartial */ @@ -900,6 +930,66 @@ export const zWorkflowPartial = z.object({ updated_by: z.string().nullish(), }) +/** + * AppDetailWithSite + */ +export const zAppDetailWithSite = z.object({ + access_mode: z.string().nullish(), + api_base_url: z.string().nullish(), + app_id: z.string().nullish(), + bound_agent_id: z.string().nullish(), + 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(), + icon_url: z.string().nullable(), + id: z.string(), + maintainer: z.string().nullish(), + max_active_requests: z.int().nullish(), + mode: z.string(), + model_config: zModelConfig.nullish(), + name: z.string(), + permission_keys: z.array(z.string()).optional(), + site: zSite.nullish(), + tags: z.array(zTag).optional(), + tracing: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + use_icon_as_answer_icon: z.boolean().nullish(), + workflow: zWorkflowPartial.nullish(), +}) + +/** + * AppDetail + */ +export const zAppDetail = z.object({ + access_mode: z.string().nullish(), + app_model_config: zModelConfig.nullish(), + 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(), + maintainer: z.string().nullish(), + mode_compatible_with_agent: z.string(), + name: z.string(), + permission_keys: z.array(z.string()).optional(), + tags: z.array(zTag).optional(), + tracing: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + use_icon_as_answer_icon: z.boolean().nullish(), + workflow: zWorkflowPartial.nullish(), +}) + /** * ImportStatus */ @@ -1118,6 +1208,25 @@ export const zFeedbackStat = z.object({ like: z.int(), }) +/** + * ConversationDetail + */ +export const zConversationDetail = z.object({ + admin_feedback_stats: zFeedbackStat.nullish(), + 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.nullish(), + status: z.string(), + updated_at: z.int().nullish(), + user_feedback_stats: zFeedbackStat.nullish(), +}) + /** * ConversationVariableResponse */ @@ -1150,7 +1259,6 @@ export const zAgentThought = z.object({ 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(), @@ -1319,9 +1427,9 @@ export const zUserSatisfactionRateStatisticResponse = z.object({ }) /** - * SimpleAccount + * SimpleAccountResponse */ -export const zSimpleAccount = z.object({ +export const zSimpleAccountResponse = z.object({ email: z.string(), id: z.string(), name: z.string(), @@ -1333,7 +1441,7 @@ export const zSimpleAccount = z.object({ export const zAdvancedChatWorkflowRunForListResponse = z.object({ conversation_id: z.string().nullish(), created_at: z.int().nullish(), - created_by_account: zSimpleAccount.nullish(), + created_by_account: zSimpleAccountResponse.nullish(), elapsed_time: z.number().nullish(), exceptions_count: z.int().nullish(), finished_at: z.int().nullish(), @@ -1355,72 +1463,12 @@ export const zAdvancedChatWorkflowRunPaginationResponse = z.object({ limit: z.int(), }) -/** - * ConversationAnnotation - */ -export const zConversationAnnotation = z.object({ - account: zSimpleAccount.nullish(), - content: z.string(), - created_at: z.int().nullish(), - id: z.string(), - question: z.string().nullish(), -}) - -/** - * ConversationAnnotationHitHistory - */ -export const zConversationAnnotationHitHistory = z.object({ - annotation_create_account: zSimpleAccount.nullish(), - created_at: z.int().nullish(), - id: z.string(), -}) - -/** - * Feedback - */ -export const zFeedback = z.object({ - content: z.string().nullish(), - from_account: zSimpleAccount.nullish(), - 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.nullish(), - annotation_hit_history: zConversationAnnotationHitHistory.nullish(), - 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(), -}) - /** * WorkflowRunForListResponse */ export const zWorkflowRunForListResponse = z.object({ created_at: z.int().nullish(), - created_by_account: zSimpleAccount.nullish(), + created_by_account: zSimpleAccountResponse.nullish(), elapsed_time: z.number().nullish(), exceptions_count: z.int().nullish(), finished_at: z.int().nullish(), @@ -1456,7 +1504,7 @@ export const zSimpleEndUser = z.object({ */ export const zWorkflowRunDetailResponse = z.object({ created_at: z.int().nullish(), - created_by_account: zSimpleAccount.nullish(), + created_by_account: zSimpleAccountResponse.nullish(), created_by_end_user: zSimpleEndUser.nullish(), created_by_role: z.string().nullish(), elapsed_time: z.number().nullish(), @@ -1478,7 +1526,7 @@ export const zWorkflowRunDetailResponse = z.object({ */ export const zWorkflowRunNodeExecutionResponse = z.object({ created_at: z.int().nullish(), - created_by_account: zSimpleAccount.nullish(), + created_by_account: zSimpleAccountResponse.nullish(), created_by_end_user: zSimpleEndUser.nullish(), created_by_role: z.string().nullish(), elapsed_time: z.number().nullish(), @@ -1544,10 +1592,11 @@ export const zSandboxUploadResponse = z.object({ }) /** - * AccountWithRole + * AccountWithRoleResponse */ -export const zAccountWithRole = z.object({ +export const zAccountWithRoleResponse = z.object({ avatar: z.string().nullish(), + avatar_url: z.string().nullable(), created_at: z.int().nullish(), email: z.string(), id: z.string(), @@ -1563,7 +1612,7 @@ export const zAccountWithRole = z.object({ * WorkflowCommentMentionUsersPayload */ export const zWorkflowCommentMentionUsersPayload = z.object({ - users: z.array(zAccountWithRole), + users: z.array(zAccountWithRoleResponse), }) /** @@ -1752,7 +1801,7 @@ export const zPipelineVariableResponse = z.object({ export const zWorkflowResponse = z.object({ conversation_variables: z.array(zWorkflowConversationVariableResponse), created_at: z.int(), - created_by: zSimpleAccount.nullish(), + created_by: zSimpleAccountResponse.nullish(), environment_variables: z.array(zWorkflowEnvironmentVariableResponse), features: z.record(z.string(), z.unknown()), graph: z.record(z.string(), z.unknown()), @@ -1763,7 +1812,7 @@ export const zWorkflowResponse = z.object({ rag_pipeline_variables: z.array(zPipelineVariableResponse), tool_published: z.boolean(), updated_at: z.int(), - updated_by: zSimpleAccount.nullish(), + updated_by: zSimpleAccountResponse.nullish(), version: z.string(), }) @@ -2056,120 +2105,18 @@ export const zAppPagination = z.object({ total: z.int(), }) -/** - * LLMMode - * - * Enum class for large language model mode. - */ -export const zLlmMode = z.enum(['chat', 'completion']) - -/** - * ModelConfig - */ -export const zModelConfig = z.object({ - completion_params: z.record(z.string(), z.unknown()).optional(), - mode: zLlmMode, - name: z.string(), - provider: z.string(), -}) - -/** - * AppDetailWithSite - */ -export const zAppDetailWithSite = z.object({ - access_mode: z.string().nullish(), - api_base_url: z.string().nullish(), - app_id: z.string().nullish(), - bound_agent_id: z.string().nullish(), - 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(), - icon_url: z.string().nullable(), - id: z.string(), - maintainer: z.string().nullish(), - max_active_requests: z.int().nullish(), - mode: z.string(), - model_config: zModelConfig.nullish(), - name: z.string(), - permission_keys: z.array(z.string()).optional(), - site: zSite.nullish(), - tags: z.array(zTag).optional(), - tracing: zJsonValue.nullish(), - updated_at: z.int().nullish(), - updated_by: z.string().nullish(), - use_icon_as_answer_icon: z.boolean().nullish(), - workflow: zWorkflowPartial.nullish(), -}) - -/** - * AppDetail - */ -export const zAppDetail = z.object({ - access_mode: z.string().nullish(), - app_model_config: zModelConfig.nullish(), - 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(), - maintainer: z.string().nullish(), - mode_compatible_with_agent: z.string(), - name: z.string(), - permission_keys: z.array(z.string()).optional(), - tags: z.array(zTag).optional(), - tracing: zJsonValue.nullish(), - updated_at: z.int().nullish(), - updated_by: z.string().nullish(), - use_icon_as_answer_icon: z.boolean().nullish(), - workflow: zWorkflowPartial.nullish(), -}) - -/** - * ConversationDetail - */ -export const zConversationDetail = z.object({ - admin_feedback_stats: zFeedbackStat.nullish(), - 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.nullish(), - status: z.string(), - updated_at: z.int().nullish(), - user_feedback_stats: zFeedbackStat.nullish(), -}) - -/** - * ConversationMessageDetail - */ -export const zConversationMessageDetail = z.object({ - created_at: z.int().nullish(), - first_message: zMessageDetail.nullish(), - from_account_id: z.string().nullish(), - from_end_user_id: z.string().nullish(), - from_source: z.string(), - id: z.string(), - model_config: zModelConfig.nullish(), - status: z.string(), -}) - /** * Type */ -export const zType = z.enum(['github', 'marketplace', 'package']) +export const zType = z.enum([ + 'app-selector', + 'array[tools]', + 'boolean', + 'model-selector', + 'secret-input', + 'select', + 'text-input', +]) /** * Github @@ -2366,6 +2313,26 @@ export const zSimpleMessageDetail = z.object({ 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.nullish(), + content: z.string(), + created_at: z.int().nullish(), + id: z.string(), + question: z.string().nullish(), +}) + /** * Conversation */ @@ -2398,6 +2365,69 @@ export const zConversationPagination = z.object({ total: z.int(), }) +/** + * ConversationAnnotationHitHistory + */ +export const zConversationAnnotationHitHistory = z.object({ + annotation_create_account: zSimpleAccount.nullish(), + annotation_id: z.string(), + created_at: z.int().nullish(), +}) + +/** + * Feedback + */ +export const zFeedback = z.object({ + content: z.string().nullish(), + from_account: zSimpleAccount.nullish(), + 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.nullish(), + annotation_hit_history: zConversationAnnotationHitHistory.nullish(), + 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.nullish(), + from_account_id: z.string().nullish(), + from_end_user_id: z.string().nullish(), + from_source: z.string(), + id: z.string(), + model_config: zModelConfig.nullish(), + status: z.string(), +}) + /** * ExecutionContentType */ @@ -2425,7 +2455,7 @@ export const zWorkflowRunForLogResponse = z.object({ */ export const zWorkflowAppLogPartialResponse = z.object({ created_at: z.int().nullish(), - created_by_account: zSimpleAccount.nullish(), + created_by_account: zSimpleAccountResponse.nullish(), created_by_end_user: zSimpleEndUser.nullish(), created_by_role: z.string().nullish(), created_from: z.string().nullish(), @@ -2461,7 +2491,7 @@ export const zWorkflowRunForArchivedLogResponse = z.object({ */ export const zWorkflowArchivedLogPartialResponse = z.object({ created_at: z.int().nullish(), - created_by_account: zSimpleAccount.nullish(), + created_by_account: zSimpleAccountResponse.nullish(), created_by_end_user: zSimpleEndUser.nullish(), id: z.string(), trigger_metadata: z.unknown().optional(), @@ -3455,6 +3485,7 @@ export const zMessageDetailResponse = z.object({ agent_thoughts: z.array(zAgentThought).optional(), annotation: zConversationAnnotation.nullish(), annotation_hit_history: zConversationAnnotationHitHistory.nullish(), + answer: z.string(), answer_tokens: z.int().nullish(), conversation_id: z.string(), created_at: z.int().nullish(), @@ -3468,12 +3499,11 @@ export const zMessageDetailResponse = z.object({ inputs: z.record(z.string(), zJsonValue), message: zJsonValue.nullish(), message_files: z.array(zMessageFile).optional(), - message_metadata_dict: zJsonValue.nullish(), message_tokens: z.int().nullish(), + metadata: zJsonValue.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(), }) @@ -3586,6 +3616,29 @@ export const zAppDetailWithSiteWritable = z.object({ workflow: zWorkflowPartial.nullish(), }) +/** + * AccountWithRoleResponse + */ +export const zAccountWithRoleResponseWritable = 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(), + roles: z.array(z.record(z.string(), z.string())).optional(), + status: z.string(), +}) + +/** + * WorkflowCommentMentionUsersPayload + */ +export const zWorkflowCommentMentionUsersPayloadWritable = z.object({ + users: z.array(zAccountWithRoleResponseWritable), +}) + /** * WorkflowCommentAccount */ diff --git a/packages/contracts/generated/api/console/installed-apps/types.gen.ts b/packages/contracts/generated/api/console/installed-apps/types.gen.ts index f9a5eb01edc..61b1303d5b5 100644 --- a/packages/contracts/generated/api/console/installed-apps/types.gen.ts +++ b/packages/contracts/generated/api/console/installed-apps/types.gen.ts @@ -246,7 +246,6 @@ export type AgentThought = { created_at?: number | null files: Array id: string - message_chain_id?: string | null message_id: string observation?: string | null position: number diff --git a/packages/contracts/generated/api/console/installed-apps/zod.gen.ts b/packages/contracts/generated/api/console/installed-apps/zod.gen.ts index a4556058506..53439d132c8 100644 --- a/packages/contracts/generated/api/console/installed-apps/zod.gen.ts +++ b/packages/contracts/generated/api/console/installed-apps/zod.gen.ts @@ -266,7 +266,6 @@ export const zAgentThought = z.object({ 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(), diff --git a/packages/contracts/generated/api/console/instruction-generate/types.gen.ts b/packages/contracts/generated/api/console/instruction-generate/types.gen.ts index 82a9bee0864..08dc7f85248 100644 --- a/packages/contracts/generated/api/console/instruction-generate/types.gen.ts +++ b/packages/contracts/generated/api/console/instruction-generate/types.gen.ts @@ -25,15 +25,42 @@ export type SimpleDataResponse = { } export type ModelConfig = { - completion_params?: { - [key: string]: unknown - } - mode: LlmMode - name: string - provider: string + agent_mode?: JsonValue | null + annotation_reply?: JsonValue | null + chat_prompt_config?: JsonValue | null + completion_prompt_config?: JsonValue | null + created_at?: number | null + created_by?: string | null + dataset_configs?: JsonValue | null + dataset_query_variable?: string | null + external_data_tools?: JsonValue | null + file_upload?: JsonValue | null + model?: JsonValue | null + more_like_this?: JsonValue | null + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource?: JsonValue | null + sensitive_word_avoidance?: JsonValue | null + speech_to_text?: JsonValue | null + suggested_questions?: JsonValue | null + suggested_questions_after_answer?: JsonValue | null + text_to_speech?: JsonValue | null + updated_at?: number | null + updated_by?: string | null + user_input_form?: JsonValue | null } -export type LlmMode = 'chat' | 'completion' +export type JsonValue + = | string + | number + | number + | boolean + | { + [key: string]: unknown + } + | Array + | null export type PostInstructionGenerateData = { body: InstructionGeneratePayload diff --git a/packages/contracts/generated/api/console/instruction-generate/zod.gen.ts b/packages/contracts/generated/api/console/instruction-generate/zod.gen.ts index 2d89050e2a0..cbffd4478f7 100644 --- a/packages/contracts/generated/api/console/instruction-generate/zod.gen.ts +++ b/packages/contracts/generated/api/console/instruction-generate/zod.gen.ts @@ -21,21 +21,45 @@ export const zSimpleDataResponse = z.object({ data: z.string(), }) -/** - * LLMMode - * - * Enum class for large language model mode. - */ -export const zLlmMode = z.enum(['chat', 'completion']) +export const zJsonValue = z + .union([ + z.string(), + z.int(), + z.number(), + z.boolean(), + z.record(z.string(), z.unknown()), + z.array(z.unknown()), + ]) + .nullable() /** * ModelConfig */ export const zModelConfig = z.object({ - completion_params: z.record(z.string(), z.unknown()).optional(), - mode: zLlmMode, - name: z.string(), - provider: z.string(), + agent_mode: zJsonValue.nullish(), + annotation_reply: zJsonValue.nullish(), + chat_prompt_config: zJsonValue.nullish(), + completion_prompt_config: zJsonValue.nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs: zJsonValue.nullish(), + dataset_query_variable: z.string().nullish(), + external_data_tools: zJsonValue.nullish(), + file_upload: zJsonValue.nullish(), + model: zJsonValue.nullish(), + more_like_this: zJsonValue.nullish(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource: zJsonValue.nullish(), + sensitive_word_avoidance: zJsonValue.nullish(), + speech_to_text: zJsonValue.nullish(), + suggested_questions: zJsonValue.nullish(), + suggested_questions_after_answer: zJsonValue.nullish(), + text_to_speech: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form: zJsonValue.nullish(), }) /** diff --git a/packages/contracts/generated/api/console/rag/types.gen.ts b/packages/contracts/generated/api/console/rag/types.gen.ts index b9862a8d1e8..b49f5d522d4 100644 --- a/packages/contracts/generated/api/console/rag/types.gen.ts +++ b/packages/contracts/generated/api/console/rag/types.gen.ts @@ -119,7 +119,7 @@ export type SimpleResultResponse = { export type WorkflowRunDetailResponse = { created_at?: number | null - created_by_account?: SimpleAccount | null + created_by_account?: SimpleAccountResponse | null created_by_end_user?: SimpleEndUser | null created_by_role?: string | null elapsed_time?: number | null @@ -158,7 +158,7 @@ export type DefaultBlockConfigResponse = { export type WorkflowResponse = { conversation_variables: Array created_at: number - created_by?: SimpleAccount | null + created_by?: SimpleAccountResponse | null environment_variables: Array features: { [key: string]: unknown @@ -173,7 +173,7 @@ export type WorkflowResponse = { rag_pipeline_variables: Array tool_published: boolean updated_at: number - updated_by?: SimpleAccount | null + updated_by?: SimpleAccountResponse | null version: string } @@ -221,7 +221,7 @@ export type DatasourceVariablesPayload = { export type WorkflowRunNodeExecutionResponse = { created_at?: number | null - created_by_account?: SimpleAccount | null + created_by_account?: SimpleAccountResponse | null created_by_end_user?: SimpleEndUser | null created_by_role?: string | null elapsed_time?: number | null @@ -421,7 +421,7 @@ export type PluginDependency = { export type WorkflowRunForListResponse = { created_at?: number | null - created_by_account?: SimpleAccount | null + created_by_account?: SimpleAccountResponse | null elapsed_time?: number | null exceptions_count?: number | null finished_at?: number | null @@ -433,7 +433,7 @@ export type WorkflowRunForListResponse = { version?: string | null } -export type SimpleAccount = { +export type SimpleAccountResponse = { email: string id: string name: string @@ -515,7 +515,14 @@ export type DatasetWeightedScoreResponse = { weight_type?: string | null } -export type Type = 'github' | 'marketplace' | 'package' +export type Type + = | 'app-selector' + | 'array[tools]' + | 'boolean' + | 'model-selector' + | 'secret-input' + | 'select' + | 'text-input' export type Github = { github_plugin_unique_identifier: string diff --git a/packages/contracts/generated/api/console/rag/zod.gen.ts b/packages/contracts/generated/api/console/rag/zod.gen.ts index 717db30baa7..60d70850ef4 100644 --- a/packages/contracts/generated/api/console/rag/zod.gen.ts +++ b/packages/contracts/generated/api/console/rag/zod.gen.ts @@ -322,9 +322,9 @@ export const zPipelineTemplateListResponse = z.object({ }) /** - * SimpleAccount + * SimpleAccountResponse */ -export const zSimpleAccount = z.object({ +export const zSimpleAccountResponse = z.object({ email: z.string(), id: z.string(), name: z.string(), @@ -335,7 +335,7 @@ export const zSimpleAccount = z.object({ */ export const zWorkflowRunForListResponse = z.object({ created_at: z.int().nullish(), - created_by_account: zSimpleAccount.nullish(), + created_by_account: zSimpleAccountResponse.nullish(), elapsed_time: z.number().nullish(), exceptions_count: z.int().nullish(), finished_at: z.int().nullish(), @@ -371,7 +371,7 @@ export const zSimpleEndUser = z.object({ */ export const zWorkflowRunDetailResponse = z.object({ created_at: z.int().nullish(), - created_by_account: zSimpleAccount.nullish(), + created_by_account: zSimpleAccountResponse.nullish(), created_by_end_user: zSimpleEndUser.nullish(), created_by_role: z.string().nullish(), elapsed_time: z.number().nullish(), @@ -393,7 +393,7 @@ export const zWorkflowRunDetailResponse = z.object({ */ export const zWorkflowRunNodeExecutionResponse = z.object({ created_at: z.int().nullish(), - created_by_account: zSimpleAccount.nullish(), + created_by_account: zSimpleAccountResponse.nullish(), created_by_end_user: zSimpleEndUser.nullish(), created_by_role: z.string().nullish(), elapsed_time: z.number().nullish(), @@ -471,7 +471,7 @@ export const zPipelineVariableResponse = z.object({ export const zWorkflowResponse = z.object({ conversation_variables: z.array(zWorkflowConversationVariableResponse), created_at: z.int(), - created_by: zSimpleAccount.nullish(), + created_by: zSimpleAccountResponse.nullish(), environment_variables: z.array(zWorkflowEnvironmentVariableResponse), features: z.record(z.string(), z.unknown()), graph: z.record(z.string(), z.unknown()), @@ -482,7 +482,7 @@ export const zWorkflowResponse = z.object({ rag_pipeline_variables: z.array(zPipelineVariableResponse), tool_published: z.boolean(), updated_at: z.int(), - updated_by: zSimpleAccount.nullish(), + updated_by: zSimpleAccountResponse.nullish(), version: z.string(), }) @@ -547,7 +547,15 @@ export const zDatasetRerankingModelResponse = z.object({ /** * Type */ -export const zType = z.enum(['github', 'marketplace', 'package']) +export const zType = z.enum([ + 'app-selector', + 'array[tools]', + 'boolean', + 'model-selector', + 'secret-input', + 'select', + 'text-input', +]) /** * Github 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 index a1165a4f8a2..4883b92063d 100644 --- a/packages/contracts/generated/api/console/rule-code-generate/types.gen.ts +++ b/packages/contracts/generated/api/console/rule-code-generate/types.gen.ts @@ -14,15 +14,42 @@ export type RuleCodeGeneratePayload = { export type GeneratorResponse = unknown export type ModelConfig = { - completion_params?: { - [key: string]: unknown - } - mode: LlmMode - name: string - provider: string + agent_mode?: JsonValue | null + annotation_reply?: JsonValue | null + chat_prompt_config?: JsonValue | null + completion_prompt_config?: JsonValue | null + created_at?: number | null + created_by?: string | null + dataset_configs?: JsonValue | null + dataset_query_variable?: string | null + external_data_tools?: JsonValue | null + file_upload?: JsonValue | null + model?: JsonValue | null + more_like_this?: JsonValue | null + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource?: JsonValue | null + sensitive_word_avoidance?: JsonValue | null + speech_to_text?: JsonValue | null + suggested_questions?: JsonValue | null + suggested_questions_after_answer?: JsonValue | null + text_to_speech?: JsonValue | null + updated_at?: number | null + updated_by?: string | null + user_input_form?: JsonValue | null } -export type LlmMode = 'chat' | 'completion' +export type JsonValue + = | string + | number + | number + | boolean + | { + [key: string]: unknown + } + | Array + | null export type PostRuleCodeGenerateData = { body: RuleCodeGeneratePayload 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 index 97e1b816289..0536774a0c9 100644 --- a/packages/contracts/generated/api/console/rule-code-generate/zod.gen.ts +++ b/packages/contracts/generated/api/console/rule-code-generate/zod.gen.ts @@ -7,21 +7,45 @@ import * as z from 'zod' */ export const zGeneratorResponse = z.unknown() -/** - * LLMMode - * - * Enum class for large language model mode. - */ -export const zLlmMode = z.enum(['chat', 'completion']) +export const zJsonValue = z + .union([ + z.string(), + z.int(), + z.number(), + z.boolean(), + z.record(z.string(), z.unknown()), + z.array(z.unknown()), + ]) + .nullable() /** * ModelConfig */ export const zModelConfig = z.object({ - completion_params: z.record(z.string(), z.unknown()).optional(), - mode: zLlmMode, - name: z.string(), - provider: z.string(), + agent_mode: zJsonValue.nullish(), + annotation_reply: zJsonValue.nullish(), + chat_prompt_config: zJsonValue.nullish(), + completion_prompt_config: zJsonValue.nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs: zJsonValue.nullish(), + dataset_query_variable: z.string().nullish(), + external_data_tools: zJsonValue.nullish(), + file_upload: zJsonValue.nullish(), + model: zJsonValue.nullish(), + more_like_this: zJsonValue.nullish(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource: zJsonValue.nullish(), + sensitive_word_avoidance: zJsonValue.nullish(), + speech_to_text: zJsonValue.nullish(), + suggested_questions: zJsonValue.nullish(), + suggested_questions_after_answer: zJsonValue.nullish(), + text_to_speech: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form: zJsonValue.nullish(), }) /** diff --git a/packages/contracts/generated/api/console/rule-generate/types.gen.ts b/packages/contracts/generated/api/console/rule-generate/types.gen.ts index 4e7c1421461..9a09a91374a 100644 --- a/packages/contracts/generated/api/console/rule-generate/types.gen.ts +++ b/packages/contracts/generated/api/console/rule-generate/types.gen.ts @@ -13,15 +13,42 @@ export type RuleGeneratePayload = { export type GeneratorResponse = unknown export type ModelConfig = { - completion_params?: { - [key: string]: unknown - } - mode: LlmMode - name: string - provider: string + agent_mode?: JsonValue | null + annotation_reply?: JsonValue | null + chat_prompt_config?: JsonValue | null + completion_prompt_config?: JsonValue | null + created_at?: number | null + created_by?: string | null + dataset_configs?: JsonValue | null + dataset_query_variable?: string | null + external_data_tools?: JsonValue | null + file_upload?: JsonValue | null + model?: JsonValue | null + more_like_this?: JsonValue | null + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource?: JsonValue | null + sensitive_word_avoidance?: JsonValue | null + speech_to_text?: JsonValue | null + suggested_questions?: JsonValue | null + suggested_questions_after_answer?: JsonValue | null + text_to_speech?: JsonValue | null + updated_at?: number | null + updated_by?: string | null + user_input_form?: JsonValue | null } -export type LlmMode = 'chat' | 'completion' +export type JsonValue + = | string + | number + | number + | boolean + | { + [key: string]: unknown + } + | Array + | null export type PostRuleGenerateData = { body: RuleGeneratePayload diff --git a/packages/contracts/generated/api/console/rule-generate/zod.gen.ts b/packages/contracts/generated/api/console/rule-generate/zod.gen.ts index 6e539e63f4e..b1f31427366 100644 --- a/packages/contracts/generated/api/console/rule-generate/zod.gen.ts +++ b/packages/contracts/generated/api/console/rule-generate/zod.gen.ts @@ -7,21 +7,45 @@ import * as z from 'zod' */ export const zGeneratorResponse = z.unknown() -/** - * LLMMode - * - * Enum class for large language model mode. - */ -export const zLlmMode = z.enum(['chat', 'completion']) +export const zJsonValue = z + .union([ + z.string(), + z.int(), + z.number(), + z.boolean(), + z.record(z.string(), z.unknown()), + z.array(z.unknown()), + ]) + .nullable() /** * ModelConfig */ export const zModelConfig = z.object({ - completion_params: z.record(z.string(), z.unknown()).optional(), - mode: zLlmMode, - name: z.string(), - provider: z.string(), + agent_mode: zJsonValue.nullish(), + annotation_reply: zJsonValue.nullish(), + chat_prompt_config: zJsonValue.nullish(), + completion_prompt_config: zJsonValue.nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs: zJsonValue.nullish(), + dataset_query_variable: z.string().nullish(), + external_data_tools: zJsonValue.nullish(), + file_upload: zJsonValue.nullish(), + model: zJsonValue.nullish(), + more_like_this: zJsonValue.nullish(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource: zJsonValue.nullish(), + sensitive_word_avoidance: zJsonValue.nullish(), + speech_to_text: zJsonValue.nullish(), + suggested_questions: zJsonValue.nullish(), + suggested_questions_after_answer: zJsonValue.nullish(), + text_to_speech: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form: zJsonValue.nullish(), }) /** 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 index f7da1cd5cc8..c2b459fee56 100644 --- 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 @@ -12,15 +12,42 @@ export type RuleStructuredOutputPayload = { export type GeneratorResponse = unknown export type ModelConfig = { - completion_params?: { - [key: string]: unknown - } - mode: LlmMode - name: string - provider: string + agent_mode?: JsonValue | null + annotation_reply?: JsonValue | null + chat_prompt_config?: JsonValue | null + completion_prompt_config?: JsonValue | null + created_at?: number | null + created_by?: string | null + dataset_configs?: JsonValue | null + dataset_query_variable?: string | null + external_data_tools?: JsonValue | null + file_upload?: JsonValue | null + model?: JsonValue | null + more_like_this?: JsonValue | null + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource?: JsonValue | null + sensitive_word_avoidance?: JsonValue | null + speech_to_text?: JsonValue | null + suggested_questions?: JsonValue | null + suggested_questions_after_answer?: JsonValue | null + text_to_speech?: JsonValue | null + updated_at?: number | null + updated_by?: string | null + user_input_form?: JsonValue | null } -export type LlmMode = 'chat' | 'completion' +export type JsonValue + = | string + | number + | number + | boolean + | { + [key: string]: unknown + } + | Array + | null export type PostRuleStructuredOutputGenerateData = { body: RuleStructuredOutputPayload 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 index 6119b0010d0..0929fccae64 100644 --- 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 @@ -7,21 +7,45 @@ import * as z from 'zod' */ export const zGeneratorResponse = z.unknown() -/** - * LLMMode - * - * Enum class for large language model mode. - */ -export const zLlmMode = z.enum(['chat', 'completion']) +export const zJsonValue = z + .union([ + z.string(), + z.int(), + z.number(), + z.boolean(), + z.record(z.string(), z.unknown()), + z.array(z.unknown()), + ]) + .nullable() /** * ModelConfig */ export const zModelConfig = z.object({ - completion_params: z.record(z.string(), z.unknown()).optional(), - mode: zLlmMode, - name: z.string(), - provider: z.string(), + agent_mode: zJsonValue.nullish(), + annotation_reply: zJsonValue.nullish(), + chat_prompt_config: zJsonValue.nullish(), + completion_prompt_config: zJsonValue.nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs: zJsonValue.nullish(), + dataset_query_variable: z.string().nullish(), + external_data_tools: zJsonValue.nullish(), + file_upload: zJsonValue.nullish(), + model: zJsonValue.nullish(), + more_like_this: zJsonValue.nullish(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource: zJsonValue.nullish(), + sensitive_word_avoidance: zJsonValue.nullish(), + speech_to_text: zJsonValue.nullish(), + suggested_questions: zJsonValue.nullish(), + suggested_questions_after_answer: zJsonValue.nullish(), + text_to_speech: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form: zJsonValue.nullish(), }) /** diff --git a/packages/contracts/generated/api/console/snippets/types.gen.ts b/packages/contracts/generated/api/console/snippets/types.gen.ts index 631da7bace8..2fc256bcbb4 100644 --- a/packages/contracts/generated/api/console/snippets/types.gen.ts +++ b/packages/contracts/generated/api/console/snippets/types.gen.ts @@ -16,7 +16,7 @@ export type SimpleResultResponse = { export type WorkflowRunDetailResponse = { created_at?: number | null - created_by_account?: SimpleAccount | null + created_by_account?: SimpleAccountResponse | null created_by_end_user?: SimpleEndUser | null created_by_role?: string | null elapsed_time?: number | null @@ -51,7 +51,7 @@ export type DefaultBlockConfigsResponse = Array<{ export type SnippetWorkflowResponse = { conversation_variables: Array created_at: number - created_by?: SimpleAccount | null + created_by?: SimpleAccountResponse | null environment_variables: Array features: { [key: string]: unknown @@ -69,7 +69,7 @@ export type SnippetWorkflowResponse = { rag_pipeline_variables: Array tool_published: boolean updated_at: number - updated_by?: SimpleAccount | null + updated_by?: SimpleAccountResponse | null version: string } @@ -120,7 +120,7 @@ export type SnippetLoopNodeRunPayload = { export type WorkflowRunNodeExecutionResponse = { created_at?: number | null - created_by_account?: SimpleAccount | null + created_by_account?: SimpleAccountResponse | null created_by_end_user?: SimpleEndUser | null created_by_role?: string | null elapsed_time?: number | null @@ -210,7 +210,7 @@ export type WorkflowPublishResponse = { export type WorkflowRunForListResponse = { created_at?: number | null - created_by_account?: SimpleAccount | null + created_by_account?: SimpleAccountResponse | null elapsed_time?: number | null exceptions_count?: number | null finished_at?: number | null @@ -222,7 +222,7 @@ export type WorkflowRunForListResponse = { version?: string | null } -export type SimpleAccount = { +export type SimpleAccountResponse = { email: string id: string name: string diff --git a/packages/contracts/generated/api/console/snippets/zod.gen.ts b/packages/contracts/generated/api/console/snippets/zod.gen.ts index 85e5b961547..303fb07c66a 100644 --- a/packages/contracts/generated/api/console/snippets/zod.gen.ts +++ b/packages/contracts/generated/api/console/snippets/zod.gen.ts @@ -134,9 +134,9 @@ export const zWorkflowPublishResponse = z.object({ }) /** - * SimpleAccount + * SimpleAccountResponse */ -export const zSimpleAccount = z.object({ +export const zSimpleAccountResponse = z.object({ email: z.string(), id: z.string(), name: z.string(), @@ -147,7 +147,7 @@ export const zSimpleAccount = z.object({ */ export const zWorkflowRunForListResponse = z.object({ created_at: z.int().nullish(), - created_by_account: zSimpleAccount.nullish(), + created_by_account: zSimpleAccountResponse.nullish(), elapsed_time: z.number().nullish(), exceptions_count: z.int().nullish(), finished_at: z.int().nullish(), @@ -183,7 +183,7 @@ export const zSimpleEndUser = z.object({ */ export const zWorkflowRunDetailResponse = z.object({ created_at: z.int().nullish(), - created_by_account: zSimpleAccount.nullish(), + created_by_account: zSimpleAccountResponse.nullish(), created_by_end_user: zSimpleEndUser.nullish(), created_by_role: z.string().nullish(), elapsed_time: z.number().nullish(), @@ -205,7 +205,7 @@ export const zWorkflowRunDetailResponse = z.object({ */ export const zWorkflowRunNodeExecutionResponse = z.object({ created_at: z.int().nullish(), - created_by_account: zSimpleAccount.nullish(), + created_by_account: zSimpleAccountResponse.nullish(), created_by_end_user: zSimpleEndUser.nullish(), created_by_role: z.string().nullish(), elapsed_time: z.number().nullish(), @@ -283,7 +283,7 @@ export const zPipelineVariableResponse = z.object({ export const zSnippetWorkflowResponse = z.object({ conversation_variables: z.array(zWorkflowConversationVariableResponse), created_at: z.int(), - created_by: zSimpleAccount.nullish(), + created_by: zSimpleAccountResponse.nullish(), environment_variables: z.array(zWorkflowEnvironmentVariableResponse), features: z.record(z.string(), z.unknown()), graph: z.record(z.string(), z.unknown()), @@ -295,7 +295,7 @@ export const zSnippetWorkflowResponse = z.object({ rag_pipeline_variables: z.array(zPipelineVariableResponse), tool_published: z.boolean(), updated_at: z.int(), - updated_by: zSimpleAccount.nullish(), + updated_by: zSimpleAccountResponse.nullish(), version: z.string(), }) diff --git a/packages/contracts/generated/api/console/trial-apps/orpc.gen.ts b/packages/contracts/generated/api/console/trial-apps/orpc.gen.ts index ebc2624fa19..35859bf863e 100644 --- a/packages/contracts/generated/api/console/trial-apps/orpc.gen.ts +++ b/packages/contracts/generated/api/console/trial-apps/orpc.gen.ts @@ -19,18 +19,9 @@ import { zGetTrialAppsByAppIdWorkflowsResponse, zPostTrialAppsByAppIdAudioToTextPath, zPostTrialAppsByAppIdAudioToTextResponse, - zPostTrialAppsByAppIdChatMessagesBody, - zPostTrialAppsByAppIdChatMessagesPath, - zPostTrialAppsByAppIdChatMessagesResponse, - zPostTrialAppsByAppIdCompletionMessagesBody, - zPostTrialAppsByAppIdCompletionMessagesPath, - zPostTrialAppsByAppIdCompletionMessagesResponse, zPostTrialAppsByAppIdTextToAudioBody, zPostTrialAppsByAppIdTextToAudioPath, zPostTrialAppsByAppIdTextToAudioResponse, - zPostTrialAppsByAppIdWorkflowsRunBody, - zPostTrialAppsByAppIdWorkflowsRunPath, - zPostTrialAppsByAppIdWorkflowsRunResponse, zPostTrialAppsByAppIdWorkflowsTasksByTaskIdStopPath, zPostTrialAppsByAppIdWorkflowsTasksByTaskIdStopResponse, } from './zod.gen' @@ -50,46 +41,6 @@ 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', @@ -175,7 +126,7 @@ export const site = { get: get4, } -export const post4 = oc +export const post2 = oc .route({ inputStructure: 'detailed', method: 'POST', @@ -192,37 +143,13 @@ export const post4 = oc .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, + post: post2, } /** * Stop workflow task */ -export const post6 = oc +export const post3 = oc .route({ inputStructure: 'detailed', method: 'POST', @@ -235,7 +162,7 @@ export const post6 = oc .output(zPostTrialAppsByAppIdWorkflowsTasksByTaskIdStopResponse) export const stop = { - post: post6, + post: post3, } export const byTaskId = { @@ -263,7 +190,6 @@ export const get5 = oc export const workflows = { get: get5, - run, tasks, } @@ -285,8 +211,6 @@ export const get6 = oc export const byAppId = { get: get6, audioToText, - chatMessages, - completionMessages, datasets, messages, parameters, diff --git a/packages/contracts/generated/api/console/trial-apps/types.gen.ts b/packages/contracts/generated/api/console/trial-apps/types.gen.ts index 894da1102ee..e6892fbfcf5 100644 --- a/packages/contracts/generated/api/console/trial-apps/types.gen.ts +++ b/packages/contracts/generated/api/console/trial-apps/types.gen.ts @@ -4,66 +4,47 @@ export type ClientOptions = { baseUrl: `${string}://${string}/console/api` | (string & {}) } -export type TrialAppDetailWithSite = { - access_mode?: string - api_base_url?: string - created_at?: number - created_by?: string - deleted_tools?: Array - description?: string - enable_api?: boolean - enable_site?: boolean - icon?: string - icon_background?: string - icon_type?: string - icon_url?: string - id?: string - max_active_requests?: number - mode?: string - model_config?: TrialAppModelConfig - name?: string +export type AppDetailWithSite = { + access_mode?: string | null + api_base_url?: string | null + app_id?: string | null + bound_agent_id?: string | null + 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 + readonly icon_url: string | null + id: string + maintainer?: string | null + max_active_requests?: number | null + mode: string + model_config?: ModelConfig | null + name: string permission_keys?: Array - site?: TrialSite - tags?: Array - updated_at?: number - updated_by?: string - use_icon_as_answer_icon?: boolean - workflow?: TrialWorkflowPartial + site?: Site | null + tags?: Array + tracing?: JsonValue | null + updated_at?: number | null + updated_by?: string | null + use_icon_as_answer_icon?: boolean | null + workflow?: WorkflowPartial | null } export type AudioTranscriptResponse = { text: 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 GeneratedAppResponse = JsonValue - -export type CompletionRequest = { - files?: Array | null - inputs: { - [key: string]: unknown - } - query?: string - response_mode?: 'blocking' | 'streaming' | null - retriever_from?: string -} - -export type TrialDatasetList = { - data?: Array - has_more?: boolean - limit?: number - page?: number - total?: number +export type TrialDatasetListResponse = { + data: Array + has_more: boolean + limit: number + page: number + total: number } export type SuggestedQuestionsResponse = { @@ -111,143 +92,69 @@ export type TextToSpeechRequest = { export type AudioBinaryResponse = Blob | File -export type TrialWorkflow = { - conversation_variables?: Array - created_at?: number - created_by?: TrialSimpleAccount - environment_variables?: Array<{ - [key: string]: unknown - }> - features?: { +export type WorkflowResponse = { + conversation_variables: Array + created_at: number + created_by?: SimpleAccountResponse | null + environment_variables: Array + features: { [key: string]: unknown } - graph?: { - [key: string]: unknown - } - hash?: string - id?: string - marked_comment?: string - marked_name?: string - rag_pipeline_variables?: Array - tool_published?: boolean - updated_at?: number - updated_by?: TrialSimpleAccount - version?: string -} - -export type WorkflowRunRequest = { - files?: Array | null - inputs: { + graph: { [key: string]: unknown } + hash: string + id: string + marked_comment: string + marked_name: string + rag_pipeline_variables: Array + tool_published: boolean + updated_at: number + updated_by?: SimpleAccountResponse | null + version: string } export type SimpleResultResponse = { result: string } -export type TrialDeletedTool = { - provider_id?: string - tool_name?: string - type?: string +export type DeletedTool = { + provider_id: string + tool_name: string + type: string } -export type TrialAppModelConfig = { - agent_mode?: { - [key: string]: unknown - } - annotation_reply?: { - [key: string]: unknown - } - chat_prompt_config?: { - [key: string]: unknown - } - completion_prompt_config?: { - [key: string]: unknown - } - created_at?: number - created_by?: string - dataset_configs?: { - [key: string]: unknown - } - dataset_query_variable?: string - external_data_tools?: Array<{ - [key: string]: unknown - }> - file_upload?: { - [key: string]: unknown - } - model?: { - [key: string]: unknown - } - more_like_this?: { - [key: string]: unknown - } - opening_statement?: string - pre_prompt?: string - prompt_type?: string - retriever_resource?: { - [key: string]: unknown - } - sensitive_word_avoidance?: { - [key: string]: unknown - } - speech_to_text?: { - [key: string]: unknown - } - suggested_questions?: Array - suggested_questions_after_answer?: { - [key: string]: unknown - } - text_to_speech?: { - [key: string]: unknown - } - updated_at?: number - updated_by?: string - user_input_form?: Array<{ - [key: string]: unknown - }> +export type ModelConfig = { + agent_mode?: JsonValue | null + annotation_reply?: JsonValue | null + chat_prompt_config?: JsonValue | null + completion_prompt_config?: JsonValue | null + created_at?: number | null + created_by?: string | null + dataset_configs?: JsonValue | null + dataset_query_variable?: string | null + external_data_tools?: JsonValue | null + file_upload?: JsonValue | null + model?: JsonValue | null + more_like_this?: JsonValue | null + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource?: JsonValue | null + sensitive_word_avoidance?: JsonValue | null + speech_to_text?: JsonValue | null + suggested_questions?: JsonValue | null + suggested_questions_after_answer?: JsonValue | null + text_to_speech?: JsonValue | null + updated_at?: number | null + updated_by?: string | null + user_input_form?: JsonValue | null } -export type TrialSite = { - access_token?: string - app_base_url?: string - chat_color_theme?: string - chat_color_theme_inverted?: boolean - code?: string - copyright?: string - created_at?: number - created_by?: string - custom_disclaimer?: string - customize_domain?: string - customize_token_strategy?: string - default_language?: string - description?: string - icon?: string - icon_background?: string - icon_type?: string - icon_url?: string - privacy_policy?: string - prompt_public?: boolean - show_workflow_steps?: boolean - title?: string - updated_at?: number - updated_by?: string - use_icon_as_answer_icon?: boolean -} - -export type TrialTag = { - id?: string - name?: string - type?: string -} - -export type TrialWorkflowPartial = { - created_at?: number - created_by?: string - id?: string - updated_at?: number - updated_by?: string +export type Tag = { + id: string + name: string + type: string } export type JsonValue @@ -261,16 +168,52 @@ export type JsonValue | Array | null -export type TrialDataset = { - created_at?: number - created_by?: string - data_source_type?: string - description?: string - id?: string - indexing_technique?: string - name?: string - permission?: string +export type WorkflowPartial = { + created_at?: number | null + created_by?: string | null + id: string + updated_at?: number | null + updated_by?: string | null +} + +export type TrialDatasetListItemResponse = { + app_count: number + author_name: string | null + built_in_field_enabled: boolean + chunk_structure: string | null + created_at: number + created_by: string + data_source_type: string | null + description: string | null + doc_form: string | null + doc_metadata: Array + document_count: number + embedding_available?: boolean | null + embedding_model: string | null + embedding_model_provider: string | null + enable_api: boolean + external_knowledge_info?: DatasetExternalKnowledgeInfoResponse + external_retrieval_model: DatasetExternalRetrievalModelResponse | null + icon_info?: DatasetIconInfoResponse + id: string + indexing_technique: string | null + is_multimodal: boolean + is_published: boolean + maintainer?: string | null + name: string + permission: string permission_keys?: Array + pipeline_id: string | null + provider: string + retrieval_model_dict: DatasetRetrievalModelResponse + runtime_mode: string | null + summary_index_setting?: DatasetSummaryIndexSettingResponse + tags: Array + total_available_documents: number + total_documents: number + updated_at: number + updated_by: string | null + word_count: number } export type JsonObject = { @@ -285,56 +228,145 @@ export type SystemParameters = { workflow_file_upload_limit: number } -export type TrialConversationVariable = { - description?: string - id?: string - name?: string - value?: - | string - | number - | number - | boolean - | { - [key: string]: unknown - } - | Array - | null - value_type?: string +export type WorkflowConversationVariableResponse = { + description: string + id: string + name: string + value: unknown + value_type: string } -export type TrialSimpleAccount = { - email?: string - id?: string - name?: string +export type SimpleAccountResponse = { + email: string + id: string + name: string } -export type TrialPipelineVariable = { - allow_file_extension?: Array - allow_file_upload_methods?: Array - allowed_file_types?: Array - belong_to_node_id?: string - default_value?: - | string - | number - | number - | boolean - | { - [key: string]: unknown - } - | Array - | null - label?: string - max_length?: number - options?: Array - placeholder?: string - required?: boolean - tooltips?: string - type?: string - unit?: string - variable?: string +export type WorkflowEnvironmentVariableResponse = { + description: string + id: string + name: string + value: unknown + value_type: string } -export type GeneratedAppResponseWritable = JsonValue +export type PipelineVariableResponse = { + allowed_file_extensions?: Array | null + allowed_file_types?: Array | null + allowed_file_upload_methods?: Array | null + belong_to_node_id: string + default_value?: unknown + label: string + max_length?: number | null + options?: Array | null + placeholder?: string | null + required: boolean + tooltips?: string | null + type: string + unit?: string | null + variable: string +} + +export type DatasetDocMetadataResponse = { + id: string + name: string + type: string +} + +export type DatasetExternalKnowledgeInfoResponse = { + external_knowledge_api_endpoint?: string | null + external_knowledge_api_id?: string | null + external_knowledge_api_name?: string | null + external_knowledge_id?: string | null +} + +export type DatasetExternalRetrievalModelResponse = { + score_threshold?: number | null + score_threshold_enabled?: boolean | null + top_k: number +} + +export type DatasetIconInfoResponse = { + icon?: string | null + icon_background?: string | null + icon_type?: string | null + icon_url?: string | null +} + +export type DatasetRetrievalModelResponse = { + reranking_enable: boolean + reranking_mode?: string | null + reranking_model?: DatasetRerankingModelResponse + score_threshold?: number | null + score_threshold_enabled: boolean + search_method: string + top_k: number + weights?: DatasetWeightedScoreResponse | null +} + +export type DatasetSummaryIndexSettingResponse = { + enable?: boolean | null + model_name?: string | null + model_provider_name?: string | null + summary_prompt?: string | null +} + +export type DatasetTagResponse = { + id: string + name: string + type: string +} + +export type DatasetRerankingModelResponse = { + reranking_model_name?: string | null + reranking_provider_name?: string | null +} + +export type DatasetWeightedScoreResponse = { + keyword_setting?: DatasetKeywordSettingResponse + vector_setting?: DatasetVectorSettingResponse + weight_type?: string | null +} + +export type DatasetKeywordSettingResponse = { + keyword_weight?: number | null +} + +export type DatasetVectorSettingResponse = { + embedding_model_name?: string | null + embedding_provider_name?: string | null + vector_weight?: number | null +} + +export type AppDetailWithSiteWritable = { + access_mode?: string | null + api_base_url?: string | null + app_id?: string | null + bound_agent_id?: string | null + 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 + maintainer?: string | null + max_active_requests?: number | null + mode: string + model_config?: ModelConfig | null + name: string + permission_keys?: Array + site?: SiteWritable | null + tags?: Array + tracing?: JsonValue | null + updated_at?: number | null + updated_by?: string | null + use_icon_as_answer_icon?: boolean | null + workflow?: WorkflowPartial | null +} export type SiteWritable = { chat_color_theme?: string | null @@ -362,7 +394,7 @@ export type GetTrialAppsByAppIdData = { } export type GetTrialAppsByAppIdResponses = { - 200: TrialAppDetailWithSite + 200: AppDetailWithSite } export type GetTrialAppsByAppIdResponse @@ -384,38 +416,6 @@ export type PostTrialAppsByAppIdAudioToTextResponses = { 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: GeneratedAppResponse -} - -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: GeneratedAppResponse -} - -export type PostTrialAppsByAppIdCompletionMessagesResponse - = PostTrialAppsByAppIdCompletionMessagesResponses[keyof PostTrialAppsByAppIdCompletionMessagesResponses] - export type GetTrialAppsByAppIdDatasetsData = { body?: never path: { @@ -430,7 +430,7 @@ export type GetTrialAppsByAppIdDatasetsData = { } export type GetTrialAppsByAppIdDatasetsResponses = { - 200: TrialDatasetList + 200: TrialDatasetListResponse } export type GetTrialAppsByAppIdDatasetsResponse @@ -511,28 +511,12 @@ export type GetTrialAppsByAppIdWorkflowsData = { } export type GetTrialAppsByAppIdWorkflowsResponses = { - 200: TrialWorkflow + 200: WorkflowResponse } 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: GeneratedAppResponse -} - -export type PostTrialAppsByAppIdWorkflowsRunResponse - = PostTrialAppsByAppIdWorkflowsRunResponses[keyof PostTrialAppsByAppIdWorkflowsRunResponses] - export type PostTrialAppsByAppIdWorkflowsTasksByTaskIdStopData = { body?: never path: { diff --git a/packages/contracts/generated/api/console/trial-apps/zod.gen.ts b/packages/contracts/generated/api/console/trial-apps/zod.gen.ts index b8768790ef9..74402a204a1 100644 --- a/packages/contracts/generated/api/console/trial-apps/zod.gen.ts +++ b/packages/contracts/generated/api/console/trial-apps/zod.gen.ts @@ -9,29 +9,6 @@ export const zAudioTranscriptResponse = z.object({ text: z.string(), }) -/** - * 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'), -}) - /** * SuggestedQuestionsResponse */ @@ -74,14 +51,6 @@ export const zTextToSpeechRequest = z.object({ */ export const zAudioBinaryResponse = z.custom() -/** - * WorkflowRunRequest - */ -export const zWorkflowRunRequest = z.object({ - files: z.array(z.unknown()).nullish(), - inputs: z.record(z.string(), z.unknown()), -}) - /** * SimpleResultResponse */ @@ -89,169 +58,22 @@ export const zSimpleResultResponse = z.object({ result: z.string(), }) -export const zTrialDeletedTool = z.object({ - provider_id: z.string().optional(), - tool_name: z.string().optional(), - type: z.string().optional(), +/** + * DeletedTool + */ +export const zDeletedTool = z.object({ + provider_id: z.string(), + tool_name: z.string(), + type: z.string(), }) -export const zTrialAppModelConfig = z.object({ - agent_mode: z.record(z.string(), z.unknown()).optional(), - annotation_reply: z.record(z.string(), z.unknown()).optional(), - chat_prompt_config: z.record(z.string(), z.unknown()).optional(), - completion_prompt_config: z.record(z.string(), z.unknown()).optional(), - created_at: z.coerce - .bigint() - .min(BigInt('-9223372036854775808'), { - error: 'Invalid value: Expected int64 to be >= -9223372036854775808', - }) - .max(BigInt('9223372036854775807'), { - error: 'Invalid value: Expected int64 to be <= 9223372036854775807', - }) - .optional(), - created_by: z.string().optional(), - dataset_configs: z.record(z.string(), z.unknown()).optional(), - dataset_query_variable: z.string().optional(), - external_data_tools: z.array(z.record(z.string(), z.unknown())).optional(), - file_upload: z.record(z.string(), z.unknown()).optional(), - model: z.record(z.string(), z.unknown()).optional(), - more_like_this: z.record(z.string(), z.unknown()).optional(), - opening_statement: z.string().optional(), - pre_prompt: z.string().optional(), - prompt_type: z.string().optional(), - retriever_resource: z.record(z.string(), z.unknown()).optional(), - sensitive_word_avoidance: z.record(z.string(), z.unknown()).optional(), - speech_to_text: z.record(z.string(), z.unknown()).optional(), - suggested_questions: z.array(z.string()).optional(), - suggested_questions_after_answer: z.record(z.string(), z.unknown()).optional(), - text_to_speech: z.record(z.string(), z.unknown()).optional(), - updated_at: z.coerce - .bigint() - .min(BigInt('-9223372036854775808'), { - error: 'Invalid value: Expected int64 to be >= -9223372036854775808', - }) - .max(BigInt('9223372036854775807'), { - error: 'Invalid value: Expected int64 to be <= 9223372036854775807', - }) - .optional(), - updated_by: z.string().optional(), - user_input_form: z.array(z.record(z.string(), z.unknown())).optional(), -}) - -export const zTrialSite = z.object({ - access_token: z.string().optional(), - app_base_url: z.string().optional(), - chat_color_theme: z.string().optional(), - chat_color_theme_inverted: z.boolean().optional(), - code: z.string().optional(), - copyright: z.string().optional(), - created_at: z.coerce - .bigint() - .min(BigInt('-9223372036854775808'), { - error: 'Invalid value: Expected int64 to be >= -9223372036854775808', - }) - .max(BigInt('9223372036854775807'), { - error: 'Invalid value: Expected int64 to be <= 9223372036854775807', - }) - .optional(), - created_by: z.string().optional(), - custom_disclaimer: z.string().optional(), - customize_domain: z.string().optional(), - customize_token_strategy: z.string().optional(), - default_language: z.string().optional(), - description: z.string().optional(), - icon: z.string().optional(), - icon_background: z.string().optional(), - icon_type: z.string().optional(), - icon_url: z.string().optional(), - privacy_policy: z.string().optional(), - prompt_public: z.boolean().optional(), - show_workflow_steps: z.boolean().optional(), - title: z.string().optional(), - updated_at: z.coerce - .bigint() - .min(BigInt('-9223372036854775808'), { - error: 'Invalid value: Expected int64 to be >= -9223372036854775808', - }) - .max(BigInt('9223372036854775807'), { - error: 'Invalid value: Expected int64 to be <= 9223372036854775807', - }) - .optional(), - updated_by: z.string().optional(), - use_icon_as_answer_icon: z.boolean().optional(), -}) - -export const zTrialTag = z.object({ - id: z.string().optional(), - name: z.string().optional(), - type: z.string().optional(), -}) - -export const zTrialWorkflowPartial = z.object({ - created_at: z.coerce - .bigint() - .min(BigInt('-9223372036854775808'), { - error: 'Invalid value: Expected int64 to be >= -9223372036854775808', - }) - .max(BigInt('9223372036854775807'), { - error: 'Invalid value: Expected int64 to be <= 9223372036854775807', - }) - .optional(), - created_by: z.string().optional(), - id: z.string().optional(), - updated_at: z.coerce - .bigint() - .min(BigInt('-9223372036854775808'), { - error: 'Invalid value: Expected int64 to be >= -9223372036854775808', - }) - .max(BigInt('9223372036854775807'), { - error: 'Invalid value: Expected int64 to be <= 9223372036854775807', - }) - .optional(), - updated_by: z.string().optional(), -}) - -export const zTrialAppDetailWithSite = z.object({ - access_mode: z.string().optional(), - api_base_url: z.string().optional(), - created_at: z.coerce - .bigint() - .min(BigInt('-9223372036854775808'), { - error: 'Invalid value: Expected int64 to be >= -9223372036854775808', - }) - .max(BigInt('9223372036854775807'), { - error: 'Invalid value: Expected int64 to be <= 9223372036854775807', - }) - .optional(), - created_by: z.string().optional(), - deleted_tools: z.array(zTrialDeletedTool).optional(), - description: z.string().optional(), - enable_api: z.boolean().optional(), - enable_site: z.boolean().optional(), - icon: z.string().optional(), - icon_background: z.string().optional(), - icon_type: z.string().optional(), - icon_url: z.string().optional(), - id: z.string().optional(), - max_active_requests: z.int().optional(), - mode: z.string().optional(), - model_config: zTrialAppModelConfig.optional(), - name: z.string().optional(), - permission_keys: z.array(z.string()).optional(), - site: zTrialSite.optional(), - tags: z.array(zTrialTag).optional(), - updated_at: z.coerce - .bigint() - .min(BigInt('-9223372036854775808'), { - error: 'Invalid value: Expected int64 to be >= -9223372036854775808', - }) - .max(BigInt('9223372036854775807'), { - error: 'Invalid value: Expected int64 to be <= 9223372036854775807', - }) - .optional(), - updated_by: z.string().optional(), - use_icon_as_answer_icon: z.boolean().optional(), - workflow: zTrialWorkflowPartial.optional(), +/** + * Tag + */ +export const zTag = z.object({ + id: z.string(), + name: z.string(), + type: z.string(), }) export const zJsonValue = z @@ -266,36 +88,78 @@ export const zJsonValue = z .nullable() /** - * GeneratedAppResponse + * ModelConfig */ -export const zGeneratedAppResponse = zJsonValue - -export const zTrialDataset = z.object({ - created_at: z.coerce - .bigint() - .min(BigInt('-9223372036854775808'), { - error: 'Invalid value: Expected int64 to be >= -9223372036854775808', - }) - .max(BigInt('9223372036854775807'), { - error: 'Invalid value: Expected int64 to be <= 9223372036854775807', - }) - .optional(), - created_by: z.string().optional(), - data_source_type: z.string().optional(), - description: z.string().optional(), - id: z.string().optional(), - indexing_technique: z.string().optional(), - name: z.string().optional(), - permission: z.string().optional(), - permission_keys: z.array(z.string()).optional(), +export const zModelConfig = z.object({ + agent_mode: zJsonValue.nullish(), + annotation_reply: zJsonValue.nullish(), + chat_prompt_config: zJsonValue.nullish(), + completion_prompt_config: zJsonValue.nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs: zJsonValue.nullish(), + dataset_query_variable: z.string().nullish(), + external_data_tools: zJsonValue.nullish(), + file_upload: zJsonValue.nullish(), + model: zJsonValue.nullish(), + more_like_this: zJsonValue.nullish(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource: zJsonValue.nullish(), + sensitive_word_avoidance: zJsonValue.nullish(), + speech_to_text: zJsonValue.nullish(), + suggested_questions: zJsonValue.nullish(), + suggested_questions_after_answer: zJsonValue.nullish(), + text_to_speech: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form: zJsonValue.nullish(), }) -export const zTrialDatasetList = z.object({ - data: z.array(zTrialDataset).optional(), - has_more: z.boolean().optional(), - limit: z.int().optional(), - page: z.int().optional(), - total: z.int().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(), +}) + +/** + * AppDetailWithSite + */ +export const zAppDetailWithSite = z.object({ + access_mode: z.string().nullish(), + api_base_url: z.string().nullish(), + app_id: z.string().nullish(), + bound_agent_id: z.string().nullish(), + 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(), + icon_url: z.string().nullable(), + id: z.string(), + maintainer: z.string().nullish(), + max_active_requests: z.int().nullish(), + mode: z.string(), + model_config: zModelConfig.nullish(), + name: z.string(), + permission_keys: z.array(z.string()).optional(), + site: zSite.nullish(), + tags: z.array(zTag).optional(), + tracing: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + use_icon_as_answer_icon: z.boolean().nullish(), + workflow: zWorkflowPartial.nullish(), }) export const zJsonObject = z.record(z.string(), z.unknown()) @@ -329,93 +193,235 @@ export const zParameters = z.object({ user_input_form: z.array(zJsonObject), }) -export const zTrialConversationVariable = z.object({ - description: z.string().optional(), - id: z.string().optional(), - name: z.string().optional(), - value: z - .union([ - z.string(), - z.int(), - z.number(), - z.boolean(), - z.record(z.string(), z.unknown()), - z.array(z.unknown()), - ]) - .nullish(), - value_type: z.string().optional(), -}) - -export const zTrialSimpleAccount = z.object({ - email: z.string().optional(), - id: z.string().optional(), - name: z.string().optional(), -}) - -export const zTrialPipelineVariable = z.object({ - allow_file_extension: z.array(z.string()).optional(), - allow_file_upload_methods: z.array(z.string()).optional(), - allowed_file_types: z.array(z.string()).optional(), - belong_to_node_id: z.string().optional(), - default_value: z - .union([ - z.string(), - z.int(), - z.number(), - z.boolean(), - z.record(z.string(), z.unknown()), - z.array(z.unknown()), - ]) - .nullish(), - label: z.string().optional(), - max_length: z.int().optional(), - options: z.array(z.string()).optional(), - placeholder: z.string().optional(), - required: z.boolean().optional(), - tooltips: z.string().optional(), - type: z.string().optional(), - unit: z.string().optional(), - variable: z.string().optional(), -}) - -export const zTrialWorkflow = z.object({ - conversation_variables: z.array(zTrialConversationVariable).optional(), - created_at: z.coerce - .bigint() - .min(BigInt('-9223372036854775808'), { - error: 'Invalid value: Expected int64 to be >= -9223372036854775808', - }) - .max(BigInt('9223372036854775807'), { - error: 'Invalid value: Expected int64 to be <= 9223372036854775807', - }) - .optional(), - created_by: zTrialSimpleAccount.optional(), - environment_variables: z.array(z.record(z.string(), z.unknown())).optional(), - features: z.record(z.string(), z.unknown()).optional(), - graph: z.record(z.string(), z.unknown()).optional(), - hash: z.string().optional(), - id: z.string().optional(), - marked_comment: z.string().optional(), - marked_name: z.string().optional(), - rag_pipeline_variables: z.array(zTrialPipelineVariable).optional(), - tool_published: z.boolean().optional(), - updated_at: z.coerce - .bigint() - .min(BigInt('-9223372036854775808'), { - error: 'Invalid value: Expected int64 to be >= -9223372036854775808', - }) - .max(BigInt('9223372036854775807'), { - error: 'Invalid value: Expected int64 to be <= 9223372036854775807', - }) - .optional(), - updated_by: zTrialSimpleAccount.optional(), - version: z.string().optional(), +/** + * WorkflowConversationVariableResponse + */ +export const zWorkflowConversationVariableResponse = z.object({ + description: z.string(), + id: z.string(), + name: z.string(), + value: z.unknown(), + value_type: z.string(), }) /** - * GeneratedAppResponse + * SimpleAccountResponse */ -export const zGeneratedAppResponseWritable = zJsonValue +export const zSimpleAccountResponse = z.object({ + email: z.string(), + id: z.string(), + name: z.string(), +}) + +/** + * WorkflowEnvironmentVariableResponse + */ +export const zWorkflowEnvironmentVariableResponse = z.object({ + description: z.string(), + id: z.string(), + name: z.string(), + value: z.unknown(), + value_type: z.string(), +}) + +/** + * PipelineVariableResponse + */ +export const zPipelineVariableResponse = z.object({ + allowed_file_extensions: z.array(z.string()).nullish(), + allowed_file_types: z.array(z.string()).nullish(), + allowed_file_upload_methods: z.array(z.string()).nullish(), + belong_to_node_id: z.string(), + default_value: z.unknown().optional(), + label: z.string(), + max_length: z.int().nullish(), + options: z.array(z.string()).nullish(), + placeholder: z.string().nullish(), + required: z.boolean(), + tooltips: z.string().nullish(), + type: z.string(), + unit: z.string().nullish(), + variable: z.string(), +}) + +/** + * WorkflowResponse + */ +export const zWorkflowResponse = z.object({ + conversation_variables: z.array(zWorkflowConversationVariableResponse), + created_at: z.int(), + created_by: zSimpleAccountResponse.nullish(), + environment_variables: z.array(zWorkflowEnvironmentVariableResponse), + features: z.record(z.string(), z.unknown()), + graph: z.record(z.string(), z.unknown()), + hash: z.string(), + id: z.string(), + marked_comment: z.string(), + marked_name: z.string(), + rag_pipeline_variables: z.array(zPipelineVariableResponse), + tool_published: z.boolean(), + updated_at: z.int(), + updated_by: zSimpleAccountResponse.nullish(), + version: z.string(), +}) + +/** + * DatasetDocMetadataResponse + */ +export const zDatasetDocMetadataResponse = z.object({ + id: z.string(), + name: z.string(), + type: z.string(), +}) + +/** + * DatasetExternalKnowledgeInfoResponse + */ +export const zDatasetExternalKnowledgeInfoResponse = z.object({ + external_knowledge_api_endpoint: z.string().nullish(), + external_knowledge_api_id: z.string().nullish(), + external_knowledge_api_name: z.string().nullish(), + external_knowledge_id: z.string().nullish(), +}) + +/** + * DatasetExternalRetrievalModelResponse + */ +export const zDatasetExternalRetrievalModelResponse = z.object({ + score_threshold: z.number().nullish(), + score_threshold_enabled: z.boolean().nullish(), + top_k: z.int(), +}) + +/** + * DatasetIconInfoResponse + */ +export const zDatasetIconInfoResponse = z.object({ + icon: z.string().nullish(), + icon_background: z.string().nullish(), + icon_type: z.string().nullish(), + icon_url: z.string().nullish(), +}) + +/** + * DatasetSummaryIndexSettingResponse + */ +export const zDatasetSummaryIndexSettingResponse = z.object({ + enable: z.boolean().nullish(), + model_name: z.string().nullish(), + model_provider_name: z.string().nullish(), + summary_prompt: z.string().nullish(), +}) + +/** + * DatasetTagResponse + */ +export const zDatasetTagResponse = z.object({ + id: z.string(), + name: z.string(), + type: z.string(), +}) + +/** + * DatasetRerankingModelResponse + */ +export const zDatasetRerankingModelResponse = z.object({ + reranking_model_name: z.string().nullish(), + reranking_provider_name: z.string().nullish(), +}) + +/** + * DatasetKeywordSettingResponse + */ +export const zDatasetKeywordSettingResponse = z.object({ + keyword_weight: z.number().nullish(), +}) + +/** + * DatasetVectorSettingResponse + */ +export const zDatasetVectorSettingResponse = z.object({ + embedding_model_name: z.string().nullish(), + embedding_provider_name: z.string().nullish(), + vector_weight: z.number().nullish(), +}) + +/** + * DatasetWeightedScoreResponse + */ +export const zDatasetWeightedScoreResponse = z.object({ + keyword_setting: zDatasetKeywordSettingResponse.optional(), + vector_setting: zDatasetVectorSettingResponse.optional(), + weight_type: z.string().nullish(), +}) + +/** + * DatasetRetrievalModelResponse + */ +export const zDatasetRetrievalModelResponse = z.object({ + reranking_enable: z.boolean(), + reranking_mode: z.string().nullish(), + reranking_model: zDatasetRerankingModelResponse.optional(), + score_threshold: z.number().nullish(), + score_threshold_enabled: z.boolean(), + search_method: z.string(), + top_k: z.int(), + weights: zDatasetWeightedScoreResponse.nullish(), +}) + +/** + * TrialDatasetListItemResponse + */ +export const zTrialDatasetListItemResponse = z.object({ + app_count: z.int(), + author_name: z.string().nullable(), + built_in_field_enabled: z.boolean(), + chunk_structure: z.string().nullable(), + created_at: z.int(), + created_by: z.string(), + data_source_type: z.string().nullable(), + description: z.string().nullable(), + doc_form: z.string().nullable(), + doc_metadata: z.array(zDatasetDocMetadataResponse), + document_count: z.int(), + embedding_available: z.boolean().nullish(), + embedding_model: z.string().nullable(), + embedding_model_provider: z.string().nullable(), + enable_api: z.boolean(), + external_knowledge_info: zDatasetExternalKnowledgeInfoResponse.optional(), + external_retrieval_model: zDatasetExternalRetrievalModelResponse.nullable(), + icon_info: zDatasetIconInfoResponse.optional(), + id: z.string(), + indexing_technique: z.string().nullable(), + is_multimodal: z.boolean(), + is_published: z.boolean(), + maintainer: z.string().nullish(), + name: z.string(), + permission: z.string(), + permission_keys: z.array(z.string()).optional(), + pipeline_id: z.string().nullable(), + provider: z.string(), + retrieval_model_dict: zDatasetRetrievalModelResponse, + runtime_mode: z.string().nullable(), + summary_index_setting: zDatasetSummaryIndexSettingResponse.optional(), + tags: z.array(zDatasetTagResponse), + total_available_documents: z.int(), + total_documents: z.int(), + updated_at: z.int(), + updated_by: z.string().nullable(), + word_count: z.int(), +}) + +/** + * TrialDatasetListResponse + */ +export const zTrialDatasetListResponse = z.object({ + data: z.array(zTrialDatasetListItemResponse), + has_more: z.boolean(), + limit: z.int(), + page: z.int(), + total: z.int(), +}) /** * Site @@ -436,14 +442,47 @@ export const zSiteWritable = z.object({ use_icon_as_answer_icon: z.boolean(), }) +/** + * AppDetailWithSite + */ +export const zAppDetailWithSiteWritable = z.object({ + access_mode: z.string().nullish(), + api_base_url: z.string().nullish(), + app_id: z.string().nullish(), + bound_agent_id: z.string().nullish(), + 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(), + maintainer: z.string().nullish(), + max_active_requests: z.int().nullish(), + mode: z.string(), + model_config: zModelConfig.nullish(), + name: z.string(), + permission_keys: z.array(z.string()).optional(), + site: zSiteWritable.nullish(), + tags: z.array(zTag).optional(), + tracing: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + use_icon_as_answer_icon: z.boolean().nullish(), + workflow: zWorkflowPartial.nullish(), +}) + export const zGetTrialAppsByAppIdPath = z.object({ app_id: z.uuid(), }) /** - * Success + * App detail retrieved successfully */ -export const zGetTrialAppsByAppIdResponse = zTrialAppDetailWithSite +export const zGetTrialAppsByAppIdResponse = zAppDetailWithSite export const zPostTrialAppsByAppIdAudioToTextPath = z.object({ app_id: z.uuid(), @@ -454,28 +493,6 @@ export const zPostTrialAppsByAppIdAudioToTextPath = z.object({ */ export const zPostTrialAppsByAppIdAudioToTextResponse = zAudioTranscriptResponse -export const zPostTrialAppsByAppIdChatMessagesBody = zChatRequest - -export const zPostTrialAppsByAppIdChatMessagesPath = z.object({ - app_id: z.uuid(), -}) - -/** - * Success - */ -export const zPostTrialAppsByAppIdChatMessagesResponse = zGeneratedAppResponse - -export const zPostTrialAppsByAppIdCompletionMessagesBody = zCompletionRequest - -export const zPostTrialAppsByAppIdCompletionMessagesPath = z.object({ - app_id: z.uuid(), -}) - -/** - * Success - */ -export const zPostTrialAppsByAppIdCompletionMessagesResponse = zGeneratedAppResponse - export const zGetTrialAppsByAppIdDatasetsPath = z.object({ app_id: z.uuid(), }) @@ -489,7 +506,7 @@ export const zGetTrialAppsByAppIdDatasetsQuery = z.object({ /** * Success */ -export const zGetTrialAppsByAppIdDatasetsResponse = zTrialDatasetList +export const zGetTrialAppsByAppIdDatasetsResponse = zTrialDatasetListResponse export const zGetTrialAppsByAppIdMessagesByMessageIdSuggestedQuestionsPath = z.object({ app_id: z.uuid(), @@ -536,20 +553,9 @@ export const zGetTrialAppsByAppIdWorkflowsPath = z.object({ }) /** - * Success + * Workflow detail retrieved successfully */ -export const zGetTrialAppsByAppIdWorkflowsResponse = zTrialWorkflow - -export const zPostTrialAppsByAppIdWorkflowsRunBody = zWorkflowRunRequest - -export const zPostTrialAppsByAppIdWorkflowsRunPath = z.object({ - app_id: z.uuid(), -}) - -/** - * Success - */ -export const zPostTrialAppsByAppIdWorkflowsRunResponse = zGeneratedAppResponse +export const zGetTrialAppsByAppIdWorkflowsResponse = zWorkflowResponse export const zPostTrialAppsByAppIdWorkflowsTasksByTaskIdStopPath = z.object({ app_id: z.uuid(), diff --git a/packages/contracts/generated/api/console/workflow-generate/types.gen.ts b/packages/contracts/generated/api/console/workflow-generate/types.gen.ts index 7f67a572cb5..7fdaec5f4f0 100644 --- a/packages/contracts/generated/api/console/workflow-generate/types.gen.ts +++ b/packages/contracts/generated/api/console/workflow-generate/types.gen.ts @@ -17,15 +17,42 @@ export type WorkflowGeneratePayload = { export type GeneratorResponse = unknown export type ModelConfig = { - completion_params?: { - [key: string]: unknown - } - mode: LlmMode - name: string - provider: string + agent_mode?: JsonValue | null + annotation_reply?: JsonValue | null + chat_prompt_config?: JsonValue | null + completion_prompt_config?: JsonValue | null + created_at?: number | null + created_by?: string | null + dataset_configs?: JsonValue | null + dataset_query_variable?: string | null + external_data_tools?: JsonValue | null + file_upload?: JsonValue | null + model?: JsonValue | null + more_like_this?: JsonValue | null + opening_statement?: string | null + pre_prompt?: string | null + prompt_type?: string | null + retriever_resource?: JsonValue | null + sensitive_word_avoidance?: JsonValue | null + speech_to_text?: JsonValue | null + suggested_questions?: JsonValue | null + suggested_questions_after_answer?: JsonValue | null + text_to_speech?: JsonValue | null + updated_at?: number | null + updated_by?: string | null + user_input_form?: JsonValue | null } -export type LlmMode = 'chat' | 'completion' +export type JsonValue + = | string + | number + | number + | boolean + | { + [key: string]: unknown + } + | Array + | null export type PostWorkflowGenerateData = { body: WorkflowGeneratePayload diff --git a/packages/contracts/generated/api/console/workflow-generate/zod.gen.ts b/packages/contracts/generated/api/console/workflow-generate/zod.gen.ts index c57f0e31412..3076374073e 100644 --- a/packages/contracts/generated/api/console/workflow-generate/zod.gen.ts +++ b/packages/contracts/generated/api/console/workflow-generate/zod.gen.ts @@ -7,21 +7,45 @@ import * as z from 'zod' */ export const zGeneratorResponse = z.unknown() -/** - * LLMMode - * - * Enum class for large language model mode. - */ -export const zLlmMode = z.enum(['chat', 'completion']) +export const zJsonValue = z + .union([ + z.string(), + z.int(), + z.number(), + z.boolean(), + z.record(z.string(), z.unknown()), + z.array(z.unknown()), + ]) + .nullable() /** * ModelConfig */ export const zModelConfig = z.object({ - completion_params: z.record(z.string(), z.unknown()).optional(), - mode: zLlmMode, - name: z.string(), - provider: z.string(), + agent_mode: zJsonValue.nullish(), + annotation_reply: zJsonValue.nullish(), + chat_prompt_config: zJsonValue.nullish(), + completion_prompt_config: zJsonValue.nullish(), + created_at: z.int().nullish(), + created_by: z.string().nullish(), + dataset_configs: zJsonValue.nullish(), + dataset_query_variable: z.string().nullish(), + external_data_tools: zJsonValue.nullish(), + file_upload: zJsonValue.nullish(), + model: zJsonValue.nullish(), + more_like_this: zJsonValue.nullish(), + opening_statement: z.string().nullish(), + pre_prompt: z.string().nullish(), + prompt_type: z.string().nullish(), + retriever_resource: zJsonValue.nullish(), + sensitive_word_avoidance: zJsonValue.nullish(), + speech_to_text: zJsonValue.nullish(), + suggested_questions: zJsonValue.nullish(), + suggested_questions_after_answer: zJsonValue.nullish(), + text_to_speech: zJsonValue.nullish(), + updated_at: z.int().nullish(), + updated_by: z.string().nullish(), + user_input_form: zJsonValue.nullish(), }) /** diff --git a/packages/contracts/generated/api/console/workspaces/orpc.gen.ts b/packages/contracts/generated/api/console/workspaces/orpc.gen.ts index 7e676564999..f5e49c82a47 100644 --- a/packages/contracts/generated/api/console/workspaces/orpc.gen.ts +++ b/packages/contracts/generated/api/console/workspaces/orpc.gen.ts @@ -40,9 +40,6 @@ import { zGetWorkspacesCurrentAgentProvidersResponse, zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdCheckDependenciesPath, zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdCheckDependenciesResponse, - zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportPath, - zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportQuery, - zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportResponse, zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdPath, zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdResponse, zGetWorkspacesCurrentCustomizedSnippetsQuery, @@ -370,6 +367,7 @@ import { zPostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateResponse, zPostWorkspacesCustomConfigBody, zPostWorkspacesCustomConfigResponse, + zPostWorkspacesCustomConfigWebappLogoUploadBody, zPostWorkspacesCustomConfigWebappLogoUploadResponse, zPostWorkspacesInfoBody, zPostWorkspacesInfoResponse, @@ -524,33 +522,6 @@ export const checkDependencies = { get: get3, } -/** - * Export snippet as DSL - * - * Export snippet configuration as DSL - */ -export const get4 = oc - .route({ - description: 'Export snippet configuration as DSL', - inputStructure: 'detailed', - method: 'GET', - operationId: 'getWorkspacesCurrentCustomizedSnippetsBySnippetIdExport', - path: '/workspaces/current/customized-snippets/{snippet_id}/export', - summary: 'Export snippet as DSL', - tags: ['console'], - }) - .input( - z.object({ - params: zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportPath, - query: zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportQuery.optional(), - }), - ) - .output(zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportResponse) - -export const export_ = { - get: get4, -} - /** * Increment snippet use count when it is inserted into a workflow * @@ -598,7 +569,7 @@ export const delete_ = oc /** * Get customized snippet details */ -export const get5 = oc +export const get4 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -632,17 +603,16 @@ export const patch = oc export const bySnippetId = { delete: delete_, - get: get5, + get: get4, patch, checkDependencies, - export: export_, useCount, } /** * List customized snippets with pagination and search */ -export const get6 = oc +export const get5 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -671,13 +641,13 @@ export const post4 = oc .output(zPostWorkspacesCurrentCustomizedSnippetsResponse) export const customizedSnippets = { - get: get6, + get: get5, post: post4, imports, bySnippetId, } -export const get7 = oc +export const get6 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -688,10 +658,10 @@ export const get7 = oc .output(zGetWorkspacesCurrentDatasetOperatorsResponse) export const datasetOperators = { - get: get7, + get: get6, } -export const get8 = oc +export const get7 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -714,7 +684,7 @@ export const post5 = oc .output(zPostWorkspacesCurrentDefaultModelResponse) export const defaultModel = { - get: get8, + get: get7, post: post5, } @@ -805,7 +775,7 @@ export const enable = { /** * List endpoints for a specific plugin */ -export const get9 = oc +export const get8 = oc .route({ description: 'List endpoints for a specific plugin', inputStructure: 'detailed', @@ -818,13 +788,13 @@ export const get9 = oc .output(zGetWorkspacesCurrentEndpointsListPluginResponse) export const plugin = { - get: get9, + get: get8, } /** * List plugin endpoints with pagination */ -export const get10 = oc +export const get9 = oc .route({ description: 'List plugin endpoints with pagination', inputStructure: 'detailed', @@ -837,7 +807,7 @@ export const get10 = oc .output(zGetWorkspacesCurrentEndpointsListResponse) export const list = { - get: get10, + get: get9, plugin, } @@ -1033,7 +1003,7 @@ export const byMemberId = { updateRole, } -export const get11 = oc +export const get10 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1044,14 +1014,14 @@ export const get11 = oc .output(zGetWorkspacesCurrentMembersResponse) export const members = { - get: get11, + get: get10, inviteEmail, ownerTransferCheck, sendOwnerTransferConfirmEmail, byMemberId, } -export const get12 = oc +export const get11 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1063,7 +1033,7 @@ export const get12 = oc .output(zGetWorkspacesCurrentModelProvidersByProviderCheckoutUrlResponse) export const checkoutUrl = { - get: get12, + get: get11, } export const post16 = oc @@ -1123,7 +1093,7 @@ export const delete5 = oc ) .output(zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponse) -export const get13 = oc +export const get12 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1174,7 +1144,7 @@ export const put2 = oc export const credentials = { delete: delete5, - get: get13, + get: get12, post: post18, put: put2, switch: switch_, @@ -1238,7 +1208,7 @@ export const delete6 = oc ) .output(zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse) -export const get14 = oc +export const get13 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1289,7 +1259,7 @@ export const put3 = oc export const credentials2 = { delete: delete6, - get: get14, + get: get13, post: post21, put: put3, switch: switch2, @@ -1393,7 +1363,7 @@ export const loadBalancingConfigs = { byConfigId, } -export const get15 = oc +export const get14 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1410,7 +1380,7 @@ export const get15 = oc .output(zGetWorkspacesCurrentModelProvidersByProviderModelsParameterRulesResponse) export const parameterRules = { - get: get15, + get: get14, } export const delete7 = oc @@ -1430,7 +1400,7 @@ export const delete7 = oc ) .output(zDeleteWorkspacesCurrentModelProvidersByProviderModelsResponse) -export const get16 = oc +export const get15 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1459,7 +1429,7 @@ export const post24 = oc export const models = { delete: delete7, - get: get16, + get: get15, post: post24, credentials: credentials2, disable: disable2, @@ -1495,7 +1465,7 @@ export const byProvider = { preferredProviderType, } -export const get17 = oc +export const get16 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1507,11 +1477,11 @@ export const get17 = oc .output(zGetWorkspacesCurrentModelProvidersResponse) export const modelProviders = { - get: get17, + get: get16, byProvider, } -export const get18 = oc +export const get17 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1523,7 +1493,7 @@ export const get18 = oc .output(zGetWorkspacesCurrentModelsModelTypesByModelTypeResponse) export const byModelType = { - get: get18, + get: get17, } export const modelTypes = { @@ -1539,7 +1509,7 @@ export const models2 = { * * Returns permission flags that control workspace features like member invitations and owner transfer. */ -export const get19 = oc +export const get18 = oc .route({ description: 'Returns permission flags that control workspace features like member invitations and owner transfer.', @@ -1553,10 +1523,10 @@ export const get19 = oc .output(zGetWorkspacesCurrentPermissionResponse) export const permission = { - get: get19, + get: get18, } -export const get20 = oc +export const get19 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1568,7 +1538,7 @@ export const get20 = oc .output(zGetWorkspacesCurrentPluginAssetResponse) export const asset = { - get: get20, + get: get19, } export const post26 = oc @@ -1601,7 +1571,7 @@ export const exclude = { post: post27, } -export const get21 = oc +export const get20 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1613,7 +1583,7 @@ export const get21 = oc .output(zGetWorkspacesCurrentPluginAutoUpgradeFetchResponse) export const fetch_ = { - get: get21, + get: get20, } export const autoUpgrade = { @@ -1622,7 +1592,7 @@ export const autoUpgrade = { fetch: fetch_, } -export const get22 = oc +export const get21 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1633,10 +1603,10 @@ export const get22 = oc .output(zGetWorkspacesCurrentPluginDebuggingKeyResponse) export const debuggingKey = { - get: get22, + get: get21, } -export const get23 = oc +export const get22 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1648,10 +1618,10 @@ export const get23 = oc .output(zGetWorkspacesCurrentPluginFetchManifestResponse) export const fetchManifest = { - get: get23, + get: get22, } -export const get24 = oc +export const get23 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1663,7 +1633,7 @@ export const get24 = oc .output(zGetWorkspacesCurrentPluginIconResponse) export const icon = { - get: get24, + get: get23, } export const post28 = oc @@ -1751,7 +1721,7 @@ export const latestVersions = { post: post32, } -export const get25 = oc +export const get24 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1763,12 +1733,12 @@ export const get25 = oc .output(zGetWorkspacesCurrentPluginListResponse) export const list2 = { - get: get25, + get: get24, installations, latestVersions, } -export const get26 = oc +export const get25 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1780,14 +1750,14 @@ export const get26 = oc .output(zGetWorkspacesCurrentPluginMarketplacePkgResponse) export const pkg2 = { - get: get26, + get: get25, } export const marketplace2 = { pkg: pkg2, } -export const get27 = oc +export const get26 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1799,7 +1769,7 @@ export const get27 = oc .output(zGetWorkspacesCurrentPluginParametersDynamicOptionsResponse) export const dynamicOptions = { - get: get27, + get: get26, } /** @@ -1843,7 +1813,7 @@ export const change2 = { post: post34, } -export const get28 = oc +export const get27 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1854,7 +1824,7 @@ export const get28 = oc .output(zGetWorkspacesCurrentPluginPermissionFetchResponse) export const fetch2 = { - get: get28, + get: get27, } export const permission2 = { @@ -1862,7 +1832,7 @@ export const permission2 = { fetch: fetch2, } -export const get29 = oc +export const get28 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1874,7 +1844,7 @@ export const get29 = oc .output(zGetWorkspacesCurrentPluginReadmeResponse) export const readme = { - get: get29, + get: get28, } export const post35 = oc @@ -1922,7 +1892,7 @@ export const delete8 = { byIdentifier, } -export const get30 = oc +export const get29 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1934,11 +1904,11 @@ export const get30 = oc .output(zGetWorkspacesCurrentPluginTasksByTaskIdResponse) export const byTaskId = { - get: get30, + get: get29, delete: delete8, } -export const get31 = oc +export const get30 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -1950,7 +1920,7 @@ export const get31 = oc .output(zGetWorkspacesCurrentPluginTasksResponse) export const tasks = { - get: get31, + get: get30, deleteAll, byTaskId, } @@ -2054,7 +2024,7 @@ export const upload = { pkg: pkg3, } -export const get32 = oc +export const get31 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2071,7 +2041,7 @@ export const get32 = oc .output(zGetWorkspacesCurrentPluginByCategoryListResponse) export const list3 = { - get: get32, + get: get31, } export const byCategory = { @@ -2124,7 +2094,7 @@ export const delete9 = oc .input(z.object({ params: zDeleteWorkspacesCurrentRbacAccessPoliciesByPolicyIdPath })) .output(zDeleteWorkspacesCurrentRbacAccessPoliciesByPolicyIdResponse) -export const get33 = oc +export const get32 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2148,12 +2118,12 @@ export const put4 = oc export const byPolicyId = { delete: delete9, - get: get33, + get: get32, put: put4, copy, } -export const get34 = oc +export const get33 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2175,7 +2145,7 @@ export const post45 = oc .output(zPostWorkspacesCurrentRbacAccessPoliciesResponse) export const accessPolicies = { - get: get34, + get: get33, post: post45, byPolicyId, } @@ -2234,7 +2204,7 @@ export const delete10 = oc ) .output(zDeleteWorkspacesCurrentRbacAppsByAppIdAccessPoliciesByPolicyIdMemberBindingsResponse) -export const get35 = oc +export const get34 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2251,10 +2221,10 @@ export const get35 = oc export const memberBindings = { delete: delete10, - get: get35, + get: get34, } -export const get36 = oc +export const get35 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2270,7 +2240,7 @@ export const get36 = oc .output(zGetWorkspacesCurrentRbacAppsByAppIdAccessPoliciesByPolicyIdRoleBindingsResponse) export const roleBindings = { - get: get36, + get: get35, } export const byPolicyId2 = { @@ -2282,7 +2252,7 @@ export const accessPolicies2 = { byPolicyId: byPolicyId2, } -export const get37 = oc +export const get36 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2294,10 +2264,10 @@ export const get37 = oc .output(zGetWorkspacesCurrentRbacAppsByAppIdAccessPolicyResponse) export const accessPolicy = { - get: get37, + get: get36, } -export const get38 = oc +export const get37 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2309,7 +2279,7 @@ export const get38 = oc .output(zGetWorkspacesCurrentRbacAppsByAppIdUserAccessPoliciesResponse) export const userAccessPolicies = { - get: get38, + get: get37, } export const put7 = oc @@ -2339,7 +2309,7 @@ export const users = { byTargetAccountId, } -export const get39 = oc +export const get38 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2362,7 +2332,7 @@ export const put8 = oc .output(zPutWorkspacesCurrentRbacAppsByAppIdWhitelistResponse) export const whitelist = { - get: get39, + get: get38, put: put8, } @@ -2397,7 +2367,7 @@ export const delete11 = oc zDeleteWorkspacesCurrentRbacDatasetsByDatasetIdAccessPoliciesByPolicyIdMemberBindingsResponse, ) -export const get40 = oc +export const get39 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2418,10 +2388,10 @@ export const get40 = oc export const memberBindings2 = { delete: delete11, - get: get40, + get: get39, } -export const get41 = oc +export const get40 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2437,7 +2407,7 @@ export const get41 = oc .output(zGetWorkspacesCurrentRbacDatasetsByDatasetIdAccessPoliciesByPolicyIdRoleBindingsResponse) export const roleBindings2 = { - get: get41, + get: get40, } export const byPolicyId3 = { @@ -2449,7 +2419,7 @@ export const accessPolicies4 = { byPolicyId: byPolicyId3, } -export const get42 = oc +export const get41 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2461,10 +2431,10 @@ export const get42 = oc .output(zGetWorkspacesCurrentRbacDatasetsByDatasetIdAccessPolicyResponse) export const accessPolicy2 = { - get: get42, + get: get41, } -export const get43 = oc +export const get42 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2476,7 +2446,7 @@ export const get43 = oc .output(zGetWorkspacesCurrentRbacDatasetsByDatasetIdUserAccessPoliciesResponse) export const userAccessPolicies2 = { - get: get43, + get: get42, } export const put9 = oc @@ -2506,7 +2476,7 @@ export const users2 = { byTargetAccountId: byTargetAccountId2, } -export const get44 = oc +export const get43 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2529,7 +2499,7 @@ export const put10 = oc .output(zPutWorkspacesCurrentRbacDatasetsByDatasetIdWhitelistResponse) export const whitelist2 = { - get: get44, + get: get43, put: put10, } @@ -2545,7 +2515,7 @@ export const datasets = { byDatasetId, } -export const get45 = oc +export const get44 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2568,7 +2538,7 @@ export const put11 = oc .output(zPutWorkspacesCurrentRbacMembersByMemberIdRbacRolesResponse) export const rbacRoles = { - get: get45, + get: get44, put: put11, } @@ -2580,7 +2550,7 @@ export const members2 = { byMemberId: byMemberId2, } -export const get46 = oc +export const get45 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2591,10 +2561,10 @@ export const get46 = oc .output(zGetWorkspacesCurrentRbacMyPermissionsResponse) export const myPermissions = { - get: get46, + get: get45, } -export const get47 = oc +export const get46 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2605,10 +2575,10 @@ export const get47 = oc .output(zGetWorkspacesCurrentRbacRolePermissionsCatalogAppResponse) export const app = { - get: get47, + get: get46, } -export const get48 = oc +export const get47 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2619,10 +2589,10 @@ export const get48 = oc .output(zGetWorkspacesCurrentRbacRolePermissionsCatalogDatasetResponse) export const dataset = { - get: get48, + get: get47, } -export const get49 = oc +export const get48 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2633,7 +2603,7 @@ export const get49 = oc .output(zGetWorkspacesCurrentRbacRolePermissionsCatalogResponse) export const catalog = { - get: get49, + get: get48, app, dataset, } @@ -2658,7 +2628,7 @@ export const copy2 = { post: post46, } -export const get50 = oc +export const get49 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2670,7 +2640,7 @@ export const get50 = oc .output(zGetWorkspacesCurrentRbacRolesByRoleIdMembersResponse) export const members3 = { - get: get50, + get: get49, } export const delete12 = oc @@ -2684,7 +2654,7 @@ export const delete12 = oc .input(z.object({ params: zDeleteWorkspacesCurrentRbacRolesByRoleIdPath })) .output(zDeleteWorkspacesCurrentRbacRolesByRoleIdResponse) -export const get51 = oc +export const get50 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2708,13 +2678,13 @@ export const put12 = oc export const byRoleId = { delete: delete12, - get: get51, + get: get50, put: put12, copy: copy2, members: members3, } -export const get52 = oc +export const get51 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2736,7 +2706,7 @@ export const post47 = oc .output(zPostWorkspacesCurrentRbacRolesResponse) export const roles = { - get: get52, + get: get51, post: post47, byRoleId, } @@ -2760,7 +2730,7 @@ export const bindings = { put: put13, } -export const get53 = oc +export const get52 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2776,10 +2746,10 @@ export const get53 = oc .output(zGetWorkspacesCurrentRbacWorkspaceAppsAccessPoliciesByPolicyIdMemberBindingsResponse) export const memberBindings3 = { - get: get53, + get: get52, } -export const get54 = oc +export const get53 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2795,7 +2765,7 @@ export const get54 = oc .output(zGetWorkspacesCurrentRbacWorkspaceAppsAccessPoliciesByPolicyIdRoleBindingsResponse) export const roleBindings3 = { - get: get54, + get: get53, } export const byPolicyId4 = { @@ -2808,7 +2778,7 @@ export const accessPolicies6 = { byPolicyId: byPolicyId4, } -export const get55 = oc +export const get54 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2819,7 +2789,7 @@ export const get55 = oc .output(zGetWorkspacesCurrentRbacWorkspaceAppsAccessPolicyResponse) export const accessPolicy3 = { - get: get55, + get: get54, } export const apps2 = { @@ -2846,7 +2816,7 @@ export const bindings2 = { put: put14, } -export const get56 = oc +export const get55 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2862,10 +2832,10 @@ export const get56 = oc .output(zGetWorkspacesCurrentRbacWorkspaceDatasetsAccessPoliciesByPolicyIdMemberBindingsResponse) export const memberBindings4 = { - get: get56, + get: get55, } -export const get57 = oc +export const get56 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2881,7 +2851,7 @@ export const get57 = oc .output(zGetWorkspacesCurrentRbacWorkspaceDatasetsAccessPoliciesByPolicyIdRoleBindingsResponse) export const roleBindings4 = { - get: get57, + get: get56, } export const byPolicyId5 = { @@ -2894,7 +2864,7 @@ export const accessPolicies7 = { byPolicyId: byPolicyId5, } -export const get58 = oc +export const get57 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2905,7 +2875,7 @@ export const get58 = oc .output(zGetWorkspacesCurrentRbacWorkspaceDatasetsAccessPolicyResponse) export const accessPolicy4 = { - get: get58, + get: get57, } export const datasets2 = { @@ -2930,7 +2900,7 @@ export const rbac = { workspace, } -export const get59 = oc +export const get58 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2941,7 +2911,7 @@ export const get59 = oc .output(zGetWorkspacesCurrentToolLabelsResponse) export const toolLabels = { - get: get59, + get: get58, } export const post48 = oc @@ -2974,7 +2944,7 @@ export const delete13 = { post: post49, } -export const get60 = oc +export const get59 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -2985,11 +2955,11 @@ export const get60 = oc .input(z.object({ query: zGetWorkspacesCurrentToolProviderApiGetQuery })) .output(zGetWorkspacesCurrentToolProviderApiGetResponse) -export const get61 = { - get: get60, +export const get60 = { + get: get59, } -export const get62 = oc +export const get61 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3001,7 +2971,7 @@ export const get62 = oc .output(zGetWorkspacesCurrentToolProviderApiRemoteResponse) export const remote = { - get: get62, + get: get61, } export const post50 = oc @@ -3038,7 +3008,7 @@ export const test = { pre, } -export const get63 = oc +export const get62 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3050,7 +3020,7 @@ export const get63 = oc .output(zGetWorkspacesCurrentToolProviderApiToolsResponse) export const tools = { - get: get63, + get: get62, } export const post52 = oc @@ -3071,7 +3041,7 @@ export const update2 = { export const api = { add, delete: delete13, - get: get61, + get: get60, remote, schema, test, @@ -3099,7 +3069,7 @@ export const add2 = { post: post53, } -export const get64 = oc +export const get63 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3116,10 +3086,10 @@ export const get64 = oc .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoResponse) export const info = { - get: get64, + get: get63, } -export const get65 = oc +export const get64 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3139,7 +3109,7 @@ export const get65 = oc ) export const byCredentialType = { - get: get65, + get: get64, } export const schema2 = { @@ -3151,7 +3121,7 @@ export const credential = { schema: schema2, } -export const get66 = oc +export const get65 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3168,7 +3138,7 @@ export const get66 = oc .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsResponse) export const credentials3 = { - get: get66, + get: get65, } export const post54 = oc @@ -3211,7 +3181,7 @@ export const delete14 = { post: post55, } -export const get67 = oc +export const get66 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3223,10 +3193,10 @@ export const get67 = oc .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderIconResponse) export const icon2 = { - get: get67, + get: get66, } -export const get68 = oc +export const get67 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3238,10 +3208,10 @@ export const get68 = oc .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderInfoResponse) export const info2 = { - get: get68, + get: get67, } -export const get69 = oc +export const get68 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3255,7 +3225,7 @@ export const get69 = oc .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaResponse) export const clientSchema = { - get: get69, + get: get68, } export const delete15 = oc @@ -3273,7 +3243,7 @@ export const delete15 = oc ) .output(zDeleteWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse) -export const get70 = oc +export const get69 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3304,7 +3274,7 @@ export const post56 = oc export const customClient = { delete: delete15, - get: get70, + get: get69, post: post56, } @@ -3313,7 +3283,7 @@ export const oauth = { customClient, } -export const get71 = oc +export const get70 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3325,7 +3295,7 @@ export const get71 = oc .output(zGetWorkspacesCurrentToolProviderBuiltinByProviderToolsResponse) export const tools2 = { - get: get71, + get: get70, } export const post57 = oc @@ -3380,7 +3350,7 @@ export const auth = { post: post58, } -export const get72 = oc +export const get71 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3392,14 +3362,14 @@ export const get72 = oc .output(zGetWorkspacesCurrentToolProviderMcpToolsByProviderIdResponse) export const byProviderId = { - get: get72, + get: get71, } export const tools3 = { byProviderId, } -export const get73 = oc +export const get72 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3411,7 +3381,7 @@ export const get73 = oc .output(zGetWorkspacesCurrentToolProviderMcpUpdateByProviderIdResponse) export const byProviderId2 = { - get: get73, + get: get72, } export const update4 = { @@ -3490,7 +3460,7 @@ export const delete17 = { post: post61, } -export const get74 = oc +export const get73 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3501,11 +3471,11 @@ export const get74 = oc .input(z.object({ query: zGetWorkspacesCurrentToolProviderWorkflowGetQuery.optional() })) .output(zGetWorkspacesCurrentToolProviderWorkflowGetResponse) -export const get75 = { - get: get74, +export const get74 = { + get: get73, } -export const get76 = oc +export const get75 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3517,7 +3487,7 @@ export const get76 = oc .output(zGetWorkspacesCurrentToolProviderWorkflowToolsResponse) export const tools4 = { - get: get76, + get: get75, } export const post62 = oc @@ -3538,7 +3508,7 @@ export const update5 = { export const workflow = { create: create2, delete: delete17, - get: get75, + get: get74, tools: tools4, update: update5, } @@ -3550,7 +3520,7 @@ export const toolProvider = { workflow, } -export const get77 = oc +export const get76 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3562,10 +3532,10 @@ export const get77 = oc .output(zGetWorkspacesCurrentToolProvidersResponse) export const toolProviders = { - get: get77, + get: get76, } -export const get78 = oc +export const get77 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3576,10 +3546,10 @@ export const get78 = oc .output(zGetWorkspacesCurrentToolsApiResponse) export const api2 = { - get: get78, + get: get77, } -export const get79 = oc +export const get78 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3590,10 +3560,10 @@ export const get79 = oc .output(zGetWorkspacesCurrentToolsBuiltinResponse) export const builtin2 = { - get: get79, + get: get78, } -export const get80 = oc +export const get79 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3604,10 +3574,10 @@ export const get80 = oc .output(zGetWorkspacesCurrentToolsMcpResponse) export const mcp2 = { - get: get80, + get: get79, } -export const get81 = oc +export const get80 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3618,7 +3588,7 @@ export const get81 = oc .output(zGetWorkspacesCurrentToolsWorkflowResponse) export const workflow2 = { - get: get81, + get: get80, } export const tools5 = { @@ -3628,7 +3598,7 @@ export const tools5 = { workflow: workflow2, } -export const get82 = oc +export const get81 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3640,13 +3610,13 @@ export const get82 = oc .output(zGetWorkspacesCurrentTriggerProviderByProviderIconResponse) export const icon3 = { - get: get82, + get: get81, } /** * Get info for a trigger provider */ -export const get83 = oc +export const get82 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3659,7 +3629,7 @@ export const get83 = oc .output(zGetWorkspacesCurrentTriggerProviderByProviderInfoResponse) export const info3 = { - get: get83, + get: get82, } /** @@ -3680,7 +3650,7 @@ export const delete18 = oc /** * Get OAuth client configuration for a provider */ -export const get84 = oc +export const get83 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3714,7 +3684,7 @@ export const post63 = oc export const client = { delete: delete18, - get: get84, + get: get83, post: post63, } @@ -3781,7 +3751,7 @@ export const create3 = { /** * Get the request logs for a subscription instance for a trigger provider */ -export const get85 = oc +export const get84 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3802,7 +3772,7 @@ export const get85 = oc ) export const bySubscriptionBuilderId2 = { - get: get85, + get: get84, } export const logs = { @@ -3876,7 +3846,7 @@ export const verifyAndUpdate = { /** * Get a subscription instance for a trigger provider */ -export const get86 = oc +export const get85 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3897,7 +3867,7 @@ export const get86 = oc ) export const bySubscriptionBuilderId5 = { - get: get86, + get: get85, } export const builder = { @@ -3912,7 +3882,7 @@ export const builder = { /** * List all trigger subscriptions for the current tenant's provider */ -export const get87 = oc +export const get86 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3925,13 +3895,13 @@ export const get87 = oc .output(zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListResponse) export const list4 = { - get: get87, + get: get86, } /** * Initiate OAuth authorization flow for a trigger provider */ -export const get88 = oc +export const get87 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -3948,7 +3918,7 @@ export const get88 = oc .output(zGetWorkspacesCurrentTriggerProviderByProviderSubscriptionsOauthAuthorizeResponse) export const authorize = { - get: get88, + get: get87, } export const oauth3 = { @@ -4065,7 +4035,7 @@ export const triggerProvider = { /** * List all trigger providers for the current tenant */ -export const get89 = oc +export const get88 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -4077,7 +4047,7 @@ export const get89 = oc .output(zGetWorkspacesCurrentTriggersResponse) export const triggers = { - get: get89, + get: get88, } export const post71 = oc @@ -4121,6 +4091,7 @@ export const post72 = oc successStatus: 201, tags: ['console'], }) + .input(z.object({ body: zPostWorkspacesCustomConfigWebappLogoUploadBody })) .output(zPostWorkspacesCustomConfigWebappLogoUploadResponse) export const upload2 = { @@ -4177,7 +4148,7 @@ export const switch3 = { post: post75, } -export const get90 = oc +export const get89 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -4189,7 +4160,7 @@ export const get90 = oc .output(zGetWorkspacesByTenantIdModelProvidersByProviderByIconTypeByLangResponse) export const byLang = { - get: get90, + get: get89, } export const byIconType = { @@ -4208,7 +4179,7 @@ export const byTenantId = { modelProviders: modelProviders2, } -export const get91 = oc +export const get90 = oc .route({ inputStructure: 'detailed', method: 'GET', @@ -4219,7 +4190,7 @@ export const get91 = oc .output(zGetWorkspacesResponse) export const workspaces = { - get: get91, + get: get90, current, customConfig, info: info4, diff --git a/packages/contracts/generated/api/console/workspaces/types.gen.ts b/packages/contracts/generated/api/console/workspaces/types.gen.ts index 29f23567e95..09bb8132845 100644 --- a/packages/contracts/generated/api/console/workspaces/types.gen.ts +++ b/packages/contracts/generated/api/console/workspaces/types.gen.ts @@ -31,12 +31,12 @@ export type AgentProviderListResponse = Array<{ [key: string]: unknown }> -export type SnippetPagination = { - data?: Array - has_more?: boolean - limit?: number - page?: number - total?: number +export type SnippetPaginationResponse = { + data: Array + has_more: boolean + limit: number + page: number + total: number } export type CreateSnippetPayload = { @@ -50,28 +50,28 @@ export type CreateSnippetPayload = { type?: 'group' | 'node' } -export type Snippet = { - created_at?: number - created_by?: AnonymousInlineModelB0Fd3F86D9D5 - description?: string +export type SnippetResponse = { + created_at?: number | null + created_by?: SimpleAccountResponse | null + description?: string | null graph?: { [key: string]: unknown - } + } | null icon_info?: { [key: string]: unknown - } - id?: string - input_fields?: { + } | null + id: string + input_fields?: Array<{ [key: string]: unknown - } - is_published?: boolean - name?: string - tags?: Array - type?: string - updated_at?: number - updated_by?: AnonymousInlineModelB0Fd3F86D9D5 - use_count?: number - version?: number + }> | null + is_published: boolean + name: string + tags?: Array + type: string + updated_at?: number | null + updated_by?: SimpleAccountResponse | null + use_count: number + version: number } export type SnippetImportPayload = { @@ -83,8 +83,13 @@ export type SnippetImportPayload = { yaml_url?: string | null } -export type SnippetImportResponse = { - [key: string]: unknown +export type SnippetImportInfo = { + current_dsl_version?: string + error?: string + id: string + imported_dsl_version?: string + snippet_id?: string | null + status: ImportStatus } export type UpdateSnippetPayload = { @@ -93,19 +98,17 @@ export type UpdateSnippetPayload = { name?: string | null } -export type SnippetDependencyCheckResponse = { - [key: string]: unknown +export type CheckDependenciesResult = { + leaked_dependencies?: Array } -export type TextFileResponse = string - -export type SnippetUseCountResponse = { +export type SnippetUseCountIncrementResponse = { result: string use_count: number } -export type AccountWithRoleList = { - accounts: Array +export type AccountWithRoleListResponse = { + accounts: Array } export type DefaultModelDataResponse = { @@ -128,7 +131,7 @@ export type EndpointCreatePayload = { } } -export type EndpointCreateResponse = { +export type SuccessResponse = { success: boolean } @@ -136,28 +139,8 @@ 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 - }> + endpoints: Array } export type LegacyEndpointUpdatePayload = { @@ -168,10 +151,6 @@ export type LegacyEndpointUpdatePayload = { } } -export type EndpointUpdateResponse = { - success: boolean -} - export type EndpointUpdatePayload = { name: string settings: { @@ -211,9 +190,9 @@ export type SimpleResultDataResponse = { result: string } -export type MemberActionTenantResponse = { +export type MemberActionResponse = { result: string - tenant_id: string + tenant_id?: string } export type OwnerTransferPayload = { @@ -391,10 +370,6 @@ export type ParserExcludePlugin = { plugin_id: string } -export type SuccessResponse = { - success: boolean -} - export type PluginAutoUpgradeFetchResponse = { auto_upgrade: PluginAutoUpgradeSettingsResponseModel category: PluginCategory @@ -836,7 +811,7 @@ export type WorkspaceCustomConfigPayload = { replace_webapp_logo?: string | null } -export type WorkspaceMutationResponse = { +export type WorkspaceTenantResultResponse = { result: string tenant: TenantInfoResponse } @@ -862,6 +837,7 @@ export type TenantListItemResponse = { created_at?: number | null current: boolean id: string + last_opened_at?: number | null name?: string | null plan?: string | null status?: string | null @@ -872,23 +848,23 @@ export type WorkspaceCustomConfigResponse = { replace_webapp_logo?: string | null } -export type AnonymousInlineModel744Ff9Cc03E6 = { - author_name?: string - created_at?: number - created_by?: string - description?: string +export type SnippetListItemResponse = { + author_name?: string | null + created_at?: number | null + created_by?: string | null + description?: string | null icon_info?: { [key: string]: unknown - } - id?: string - is_published?: boolean - name?: string - tags?: Array - type?: string - updated_at?: number - updated_by?: string - use_count?: number - version?: number + } | null + id: string + is_published: boolean + name: string + tags?: Array + type: string + updated_at?: number | null + updated_by?: string | null + use_count: number + version: number } export type IconInfo = { @@ -909,20 +885,29 @@ export type InputFieldDefinition = { type?: string | null } -export type AnonymousInlineModelB0Fd3F86D9D5 = { - email?: string - id?: string - name?: string +export type SimpleAccountResponse = { + email: string + id: string + name: string } -export type AnonymousInlineModel7B8B49Ca164e = { - id?: string - name?: string - type?: string +export type SnippetTagResponse = { + id: string + name: string + type: string } -export type AccountWithRole = { +export type ImportStatus = 'completed' | 'completed-with-warnings' | 'failed' | 'pending' + +export type PluginDependency = { + current_identifier?: string | null + type: Type + value: Github | Marketplace | Package +} + +export type AccountWithRoleResponse = { avatar?: string | null + readonly avatar_url: string | null created_at?: number | null email: string id: string @@ -948,6 +933,23 @@ export type Inner = { provider?: string | null } +export type EndpointEntityWithInstance = { + created_at: string + declaration?: EndpointProviderDeclaration + enabled: boolean + expired_at: string + hook_id: string + id: string + name: string + plugin_id: string + settings: { + [key: string]: unknown + } + tenant_id: string + updated_at: string + url: string +} + export type MemberInviteResultResponse = { email: string message?: string | null @@ -1198,6 +1200,32 @@ export type WorkflowToolParameterConfiguration = { name: string } +export type Type + = | 'app-selector' + | 'array[tools]' + | 'boolean' + | 'model-selector' + | 'secret-input' + | 'select' + | 'text-input' + +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 SimpleProviderEntityResponse = { icon_small?: I18nObject | null icon_small_dark?: I18nObject | null @@ -1209,6 +1237,11 @@ export type SimpleProviderEntityResponse = { tenant_id: string } +export type EndpointProviderDeclaration = { + endpoints?: Array | null + settings?: Array +} + export type ConfigurateMethod = 'customizable-model' | 'predefined-model' export type CustomConfigurationResponse = { @@ -1419,6 +1452,26 @@ export type AiModelEntityResponse = { pricing?: PriceConfigResponse | null } +export type EndpointDeclaration = { + hidden?: boolean + method: string + path: string +} + +export type ProviderConfig = { + default?: number | string | number | boolean | null + help?: I18nObject | null + label?: I18nObject | null + multiple?: boolean + name: string + options?: Array