This commit is contained in:
chariri 2026-06-25 18:39:42 +00:00 committed by GitHub
commit 258bf100b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
79 changed files with 5326 additions and 6507 deletions

View File

@ -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/<uuid:app_id>/chat-messages")

View File

@ -1,19 +1,19 @@
import json
import logging
from collections.abc import Sequence
from collections.abc import Mapping, Sequence
from datetime import datetime
from typing import Any, NotRequired, TypedDict, cast
from typing import Any, Literal, NotRequired, TypedDict, cast
from flask import abort, request
from flask_restx import Resource, fields
from pydantic import AliasChoices, BaseModel, Field, RootModel, ValidationError, field_validator
from flask_restx import Resource
from pydantic import AliasChoices, BaseModel, Field, ValidationError, field_validator
from sqlalchemy.orm import Session, sessionmaker
from werkzeug.exceptions import BadRequest, Forbidden, InternalServerError, NotFound
import services
from controllers.common.controller_schemas import DefaultBlockConfigQuery, WorkflowListQuery, WorkflowUpdatePayload
from controllers.common.errors import InvalidArgumentError
from controllers.common.fields import GeneratedAppResponse, NewAppResponse, SimpleResultResponse
from controllers.common.fields import NewAppResponse, SimpleResultResponse
from controllers.common.schema import (
query_params_from_model,
register_response_schema_model,
@ -21,11 +21,7 @@ from controllers.common.schema import (
register_schema_models,
)
from controllers.console import console_ns
from controllers.console.app.error import (
ConversationCompletedError,
DraftWorkflowNotExist,
DraftWorkflowNotSync,
)
from controllers.console.app.error import ConversationCompletedError, DraftWorkflowNotExist, DraftWorkflowNotSync
from controllers.console.app.permission_keys import get_app_permission_keys
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
@ -58,7 +54,7 @@ from extensions.ext_database import db
from extensions.ext_redis import redis_client
from factories import file_factory, variable_factory
from fields.base import ResponseModel
from fields.member_fields import SimpleAccount
from fields.member_fields import SimpleAccountResponse
from fields.workflow_run_fields import WorkflowRunNodeExecutionResponse
from graphon.enums import NodeType
from graphon.file import File
@ -69,7 +65,7 @@ from graphon.variables import SecretVariable, SegmentType, VariableBase
from graphon.variables.exc import VariableError
from libs import helper
from libs.datetime_utils import naive_utc_now
from libs.helper import TimestampField, dump_response, to_timestamp, uuid_value
from libs.helper import dump_response, to_timestamp, uuid_value
from libs.login import login_required
from models import Account, App
from models.model import AppMode
@ -103,20 +99,16 @@ class SyncDraftWorkflowPayload(BaseModel):
graph: dict[str, Any]
features: dict[str, Any]
hash: str | None = None
environment_variables: list[dict[str, Any]] = Field(
default_factory=list,
)
conversation_variables: list[dict[str, Any]] = Field(
default_factory=list,
)
environment_variables: list[dict[str, Any]] = Field(default_factory=list)
conversation_variables: list[dict[str, Any]] = Field(default_factory=list)
class BaseWorkflowRunPayload(BaseModel):
files: list[dict[str, Any]] | None = Field(default=None)
files: list[dict[str, Any]] | None = None
class AdvancedChatWorkflowRunPayload(BaseWorkflowRunPayload):
inputs: dict[str, Any] | None = Field(default=None)
inputs: dict[str, Any] | None = None
query: str = ""
conversation_id: str | None = None
parent_message_id: str | None = None
@ -130,11 +122,11 @@ class AdvancedChatWorkflowRunPayload(BaseWorkflowRunPayload):
class IterationNodeRunPayload(BaseModel):
inputs: dict[str, Any] | None = Field(default=None)
inputs: dict[str, Any] | None = None
class LoopNodeRunPayload(BaseModel):
inputs: dict[str, Any] | None = Field(default=None)
inputs: dict[str, Any] | None = None
class DraftWorkflowRunPayload(BaseWorkflowRunPayload):
@ -159,10 +151,7 @@ class ConvertToWorkflowPayload(BaseModel):
class WorkflowFeaturesPayload(BaseModel):
features: dict[str, Any] = Field(
...,
description="Workflow feature configuration",
)
features: dict[str, Any] = Field(..., description="Workflow feature configuration")
class WorkflowOnlineUsersPayload(BaseModel):
@ -197,7 +186,7 @@ class PipelineVariableResponse(ResponseModel):
max_length: int | None = None
required: bool
unit: str | None = None
default_value: Any = Field(default=None)
default_value: Any = None
options: list[str] | None = None
placeholder: str | None = None
tooltips: str | None = None
@ -220,21 +209,17 @@ class WorkflowEnvironmentVariableResponse(ResponseModel):
class WorkflowResponse(ResponseModel):
id: str
graph: dict[str, Any] = Field(
validation_alias=AliasChoices("graph_dict", "graph"),
)
features: dict[str, Any] = Field(
validation_alias=AliasChoices("features_dict", "features"),
)
graph: dict[str, Any] = Field(validation_alias=AliasChoices("graph_dict", "graph"))
features: dict[str, Any] = Field(validation_alias=AliasChoices("features_dict", "features"))
hash: str = Field(validation_alias=AliasChoices("unique_hash", "hash"))
version: str
marked_name: str
marked_comment: str
created_by: SimpleAccount | None = Field(
created_by: SimpleAccountResponse | None = Field(
default=None, validation_alias=AliasChoices("created_by_account", "created_by")
)
created_at: int
updated_by: SimpleAccount | None = Field(
updated_by: SimpleAccountResponse | None = Field(
default=None, validation_alias=AliasChoices("updated_by_account", "updated_by")
)
updated_at: int
@ -267,6 +252,53 @@ class WorkflowPaginationResponse(ResponseModel):
has_more: bool
class SyncDraftWorkflowResponse(ResponseModel):
result: str
hash: str
updated_at: int
class PublishWorkflowResponse(ResponseModel):
result: str
created_at: int
class HumanInputUserActionResponse(ResponseModel):
id: str
title: str
button_style: str = "default"
class HumanInputFormPreviewResponse(ResponseModel):
# Draft previews are shape-compatible with live human_input_required events,
# but they do not persist a form or mint recipient tokens (no expiration_time)
type_: Literal["human_input_required"] = Field(default="human_input_required", alias="TYPE")
form_id: str
form_content: str
inputs: list[Mapping[str, Any]] = Field(default_factory=list)
actions: list[HumanInputUserActionResponse] = Field(default_factory=list)
node_id: str
node_title: str
resolved_default_values: Mapping[str, Any] = Field(default_factory=dict)
display_in_ui: bool = Field(default=False, description="Always false for draft preview responses.")
form_token: str | None = Field(default=None, description="Always null for draft preview responses.")
expiration_time: int | None = Field(default=None, description="Always null for draft preview responses.")
class HumanInputDeliveryTestResponse(ResponseModel):
pass
class TriggerDebugWaitingResponse(ResponseModel):
status: Literal["waiting"]
retry_in: int
class TriggerDebugErrorResponse(ResponseModel):
status: Literal["error"]
error: str | None = None
class WorkflowOnlineUser(ResponseModel):
user_id: str
username: str
@ -282,46 +314,6 @@ class WorkflowOnlineUsersResponse(ResponseModel):
data: list[WorkflowOnlineUsersByApp]
class WorkflowPublishResponse(ResponseModel):
result: str
created_at: int
class WorkflowRestoreResponse(ResponseModel):
result: str
hash: str
updated_at: int
class DefaultBlockConfigsResponse(RootModel[list[dict[str, Any]]]):
root: list[dict[str, Any]]
class DefaultBlockConfigResponse(RootModel[dict[str, Any]]):
root: dict[str, Any]
class HumanInputFormPreviewResponse(ResponseModel):
form_id: str
node_id: str
node_title: str
form_content: str
inputs: list[dict[str, Any]] = Field(default_factory=list)
actions: list[dict[str, Any]] = Field(default_factory=list)
display_in_ui: bool | None = None
form_token: str | None = None
resolved_default_values: dict[str, Any] = Field(default_factory=dict)
expiration_time: int | None = None
class HumanInputFormSubmitResponse(RootModel[dict[str, Any]]):
root: dict[str, Any]
class EmptyObjectResponse(RootModel[dict[str, Any]]):
root: dict[str, Any]
class DraftWorkflowTriggerRunPayload(BaseModel):
node_id: str
@ -356,19 +348,19 @@ register_response_schema_models(
WorkflowEnvironmentVariableResponse,
WorkflowResponse,
WorkflowPaginationResponse,
SyncDraftWorkflowResponse,
PublishWorkflowResponse,
HumanInputUserActionResponse,
HumanInputFormPreviewResponse,
HumanInputDeliveryTestResponse,
TriggerDebugWaitingResponse,
TriggerDebugErrorResponse,
WorkflowOnlineUser,
WorkflowOnlineUsersByApp,
WorkflowOnlineUsersResponse,
WorkflowPublishResponse,
WorkflowRestoreResponse,
DefaultBlockConfigsResponse,
DefaultBlockConfigResponse,
HumanInputFormPreviewResponse,
HumanInputFormSubmitResponse,
EmptyObjectResponse,
GeneratedAppResponse,
NewAppResponse,
SimpleResultResponse,
WorkflowRunNodeExecutionResponse,
)
@ -426,6 +418,14 @@ def _serialize_environment_variable(value: Any) -> EnvironmentVariableResponseDi
return value
def _trigger_debug_waiting_response() -> dict[str, int | str]:
return TriggerDebugWaitingResponse(status="waiting", retry_in=LISTENING_RETRY_IN).model_dump(mode="json")
def _trigger_debug_error_response(error: str | None = None) -> dict[str, str]:
return TriggerDebugErrorResponse(status="error", error=error).model_dump(mode="json", exclude_none=True)
@console_ns.route("/apps/<uuid:app_id>/workflows/draft")
class DraftWorkflowApi(Resource):
@console_ns.doc("get_draft_workflow")
@ -475,14 +475,7 @@ class DraftWorkflowApi(Resource):
@console_ns.response(
200,
"Draft workflow synced successfully",
console_ns.model(
"SyncDraftWorkflowResponse",
{
"result": fields.String,
"hash": fields.String,
"updated_at": fields.String,
},
),
console_ns.models[SyncDraftWorkflowResponse.__name__],
)
@console_ns.response(400, "Invalid workflow configuration")
@console_ns.response(403, "Permission denied")
@ -535,11 +528,11 @@ class DraftWorkflowApi(Resource):
except VariableError as e:
raise InvalidArgumentError(description=str(e))
return {
"result": "success",
"hash": workflow.unique_hash,
"updated_at": TimestampField().format(workflow.updated_at or workflow.created_at),
}
return SyncDraftWorkflowResponse(
result="success",
hash=workflow.unique_hash,
updated_at=to_timestamp(workflow.updated_at or workflow.created_at),
).model_dump(mode="json")
@console_ns.route("/apps/<uuid:app_id>/advanced-chat/workflows/draft/run")
@ -548,7 +541,7 @@ class AdvancedChatDraftWorkflowRunApi(Resource):
@console_ns.doc(description="Run draft workflow for advanced chat application")
@console_ns.doc(params={"app_id": "Application ID"})
@console_ns.expect(console_ns.models[AdvancedChatWorkflowRunPayload.__name__])
@console_ns.response(200, "Workflow run started successfully", console_ns.models[GeneratedAppResponse.__name__])
@console_ns.response(200, "Workflow run started successfully")
@console_ns.response(400, "Invalid request parameters")
@console_ns.response(403, "Permission denied")
@setup_required
@ -574,6 +567,7 @@ class AdvancedChatDraftWorkflowRunApi(Resource):
app_model=app_model, user=current_user, args=args, invoke_from=InvokeFrom.DEBUGGER, streaming=True
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except services.errors.conversation.ConversationNotExistsError:
raise NotFound("Conversation Not Exists.")
@ -594,11 +588,7 @@ class AdvancedChatDraftRunIterationNodeApi(Resource):
@console_ns.doc(description="Run draft workflow iteration node for advanced chat")
@console_ns.doc(params={"app_id": "Application ID", "node_id": "Node ID"})
@console_ns.expect(console_ns.models[IterationNodeRunPayload.__name__])
@console_ns.response(
200,
"Iteration node run started successfully",
console_ns.models[GeneratedAppResponse.__name__],
)
@console_ns.response(200, "Iteration node run started successfully")
@console_ns.response(403, "Permission denied")
@console_ns.response(404, "Node not found")
@setup_required
@ -619,6 +609,7 @@ class AdvancedChatDraftRunIterationNodeApi(Resource):
app_model=app_model, user=current_user, node_id=node_id, args=args, streaming=True
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except services.errors.conversation.ConversationNotExistsError:
raise NotFound("Conversation Not Exists.")
@ -637,11 +628,7 @@ class WorkflowDraftRunIterationNodeApi(Resource):
@console_ns.doc(description="Run draft workflow iteration node")
@console_ns.doc(params={"app_id": "Application ID", "node_id": "Node ID"})
@console_ns.expect(console_ns.models[IterationNodeRunPayload.__name__])
@console_ns.response(
200,
"Workflow iteration node run started successfully",
console_ns.models[GeneratedAppResponse.__name__],
)
@console_ns.response(200, "Workflow iteration node run started successfully")
@console_ns.response(403, "Permission denied")
@console_ns.response(404, "Node not found")
@setup_required
@ -662,6 +649,7 @@ class WorkflowDraftRunIterationNodeApi(Resource):
app_model=app_model, user=current_user, node_id=node_id, args=args, streaming=True
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except services.errors.conversation.ConversationNotExistsError:
raise NotFound("Conversation Not Exists.")
@ -680,7 +668,7 @@ class AdvancedChatDraftRunLoopNodeApi(Resource):
@console_ns.doc(description="Run draft workflow loop node for advanced chat")
@console_ns.doc(params={"app_id": "Application ID", "node_id": "Node ID"})
@console_ns.expect(console_ns.models[LoopNodeRunPayload.__name__])
@console_ns.response(200, "Loop node run started successfully", console_ns.models[GeneratedAppResponse.__name__])
@console_ns.response(200, "Loop node run started successfully")
@console_ns.response(403, "Permission denied")
@console_ns.response(404, "Node not found")
@setup_required
@ -701,6 +689,7 @@ class AdvancedChatDraftRunLoopNodeApi(Resource):
app_model=app_model, user=current_user, node_id=node_id, args=args, streaming=True
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except services.errors.conversation.ConversationNotExistsError:
raise NotFound("Conversation Not Exists.")
@ -719,11 +708,7 @@ class WorkflowDraftRunLoopNodeApi(Resource):
@console_ns.doc(description="Run draft workflow loop node")
@console_ns.doc(params={"app_id": "Application ID", "node_id": "Node ID"})
@console_ns.expect(console_ns.models[LoopNodeRunPayload.__name__])
@console_ns.response(
200,
"Workflow loop node run started successfully",
console_ns.models[GeneratedAppResponse.__name__],
)
@console_ns.response(200, "Workflow loop node run started successfully")
@console_ns.response(403, "Permission denied")
@console_ns.response(404, "Node not found")
@setup_required
@ -744,6 +729,7 @@ class WorkflowDraftRunLoopNodeApi(Resource):
app_model=app_model, user=current_user, node_id=node_id, args=args, streaming=True
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except services.errors.conversation.ConversationNotExistsError:
raise NotFound("Conversation Not Exists.")
@ -764,10 +750,7 @@ class HumanInputFormPreviewPayload(BaseModel):
class HumanInputFormSubmitPayload(BaseModel):
form_inputs: dict[str, Any] = Field(
...,
description="Values the user provides for the form's own fields",
)
form_inputs: dict[str, Any] = Field(..., description="Values the user provides for the form's own fields")
inputs: dict[str, Any] = Field(
...,
description="Values used to fill missing upstream variables referenced in form_content",
@ -797,7 +780,11 @@ class AdvancedChatDraftHumanInputFormPreviewApi(Resource):
@console_ns.doc(description="Get human input form preview for advanced chat workflow")
@console_ns.doc(params={"app_id": "Application ID", "node_id": "Node ID"})
@console_ns.expect(console_ns.models[HumanInputFormPreviewPayload.__name__])
@console_ns.response(200, "Human input form preview", console_ns.models[HumanInputFormPreviewResponse.__name__])
@console_ns.response(
200,
"Human input form preview retrieved",
console_ns.models[HumanInputFormPreviewResponse.__name__],
)
@setup_required
@login_required
@account_initialization_required
@ -819,7 +806,7 @@ class AdvancedChatDraftHumanInputFormPreviewApi(Resource):
node_id=node_id,
inputs=inputs,
)
return jsonable_encoder(preview)
return dump_response(HumanInputFormPreviewResponse, preview)
@console_ns.route("/apps/<uuid:app_id>/advanced-chat/workflows/draft/human-input/nodes/<string:node_id>/form/run")
@ -830,8 +817,7 @@ class AdvancedChatDraftHumanInputFormRunApi(Resource):
@console_ns.expect(console_ns.models[HumanInputFormSubmitPayload.__name__])
@console_ns.response(
200,
"Human input form submission result",
console_ns.models[HumanInputFormSubmitResponse.__name__],
"Human input form submitted",
)
@setup_required
@login_required
@ -854,6 +840,7 @@ class AdvancedChatDraftHumanInputFormRunApi(Resource):
inputs=args.inputs,
action=args.action,
)
# TODO: typing here for result
return jsonable_encoder(result)
@ -863,7 +850,11 @@ class WorkflowDraftHumanInputFormPreviewApi(Resource):
@console_ns.doc(description="Get human input form preview for workflow")
@console_ns.doc(params={"app_id": "Application ID", "node_id": "Node ID"})
@console_ns.expect(console_ns.models[HumanInputFormPreviewPayload.__name__])
@console_ns.response(200, "Human input form preview", console_ns.models[HumanInputFormPreviewResponse.__name__])
@console_ns.response(
200,
"Human input form preview retrieved",
console_ns.models[HumanInputFormPreviewResponse.__name__],
)
@setup_required
@login_required
@account_initialization_required
@ -885,7 +876,7 @@ class WorkflowDraftHumanInputFormPreviewApi(Resource):
node_id=node_id,
inputs=inputs,
)
return jsonable_encoder(preview)
return dump_response(HumanInputFormPreviewResponse, preview)
@console_ns.route("/apps/<uuid:app_id>/workflows/draft/human-input/nodes/<string:node_id>/form/run")
@ -896,8 +887,7 @@ class WorkflowDraftHumanInputFormRunApi(Resource):
@console_ns.expect(console_ns.models[HumanInputFormSubmitPayload.__name__])
@console_ns.response(
200,
"Human input form submission result",
console_ns.models[HumanInputFormSubmitResponse.__name__],
"Human input form submitted",
)
@setup_required
@login_required
@ -920,6 +910,7 @@ class WorkflowDraftHumanInputFormRunApi(Resource):
inputs=args.inputs,
action=args.action,
)
# TODO: typing here
return jsonable_encoder(result)
@ -929,7 +920,11 @@ class WorkflowDraftHumanInputDeliveryTestApi(Resource):
@console_ns.doc(description="Test human input delivery for workflow")
@console_ns.doc(params={"app_id": "Application ID", "node_id": "Node ID"})
@console_ns.expect(console_ns.models[HumanInputDeliveryTestPayload.__name__])
@console_ns.response(200, "Human input delivery test result", console_ns.models[EmptyObjectResponse.__name__])
@console_ns.response(
200,
"Human input delivery tested",
console_ns.models[HumanInputDeliveryTestResponse.__name__],
)
@setup_required
@login_required
@account_initialization_required
@ -950,7 +945,7 @@ class WorkflowDraftHumanInputDeliveryTestApi(Resource):
delivery_method_id=args.delivery_method_id,
inputs=args.inputs,
)
return jsonable_encoder({})
return HumanInputDeliveryTestResponse().model_dump(mode="json")
@console_ns.route("/apps/<uuid:app_id>/workflows/draft/run")
@ -959,11 +954,7 @@ class DraftWorkflowRunApi(Resource):
@console_ns.doc(description="Run draft workflow")
@console_ns.doc(params={"app_id": "Application ID"})
@console_ns.expect(console_ns.models[DraftWorkflowRunPayload.__name__])
@console_ns.response(
200,
"Draft workflow run started successfully",
console_ns.models[GeneratedAppResponse.__name__],
)
@console_ns.response(200, "Draft workflow run started successfully")
@console_ns.response(403, "Permission denied")
@setup_required
@login_required
@ -991,6 +982,7 @@ class DraftWorkflowRunApi(Resource):
streaming=True,
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except InvokeRateLimitError as ex:
raise InvokeRateLimitHttpError(ex.description)
@ -1021,7 +1013,7 @@ class WorkflowTaskStopApi(Resource):
# 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")
@console_ns.route("/apps/<uuid:app_id>/workflows/draft/nodes/<string:node_id>/run")
@ -1109,7 +1101,7 @@ class PublishedWorkflowApi(Resource):
return dump_response(WorkflowResponse, workflow)
@console_ns.expect(console_ns.models[PublishWorkflowPayload.__name__])
@console_ns.response(200, "Workflow published successfully", console_ns.models[WorkflowPublishResponse.__name__])
@console_ns.response(200, "Workflow published successfully", console_ns.models[PublishWorkflowResponse.__name__])
@setup_required
@login_required
@account_initialization_required
@ -1141,12 +1133,9 @@ class PublishedWorkflowApi(Resource):
app_model_in_session.updated_by = current_user.id
app_model_in_session.updated_at = naive_utc_now()
workflow_created_at = TimestampField().format(workflow.created_at)
workflow_created_at = to_timestamp(workflow.created_at)
return {
"result": "success",
"created_at": workflow_created_at,
}
return PublishWorkflowResponse(result="success", created_at=workflow_created_at).model_dump(mode="json")
@console_ns.route("/apps/<uuid:app_id>/workflows/default-workflow-block-configs")
@ -1157,7 +1146,6 @@ class DefaultBlockConfigsApi(Resource):
@console_ns.response(
200,
"Default block configurations retrieved successfully",
console_ns.models[DefaultBlockConfigsResponse.__name__],
)
@setup_required
@login_required
@ -1179,13 +1167,12 @@ class DefaultBlockConfigApi(Resource):
@console_ns.doc("get_default_block_config")
@console_ns.doc(description="Get default block configuration by type")
@console_ns.doc(params={"app_id": "Application ID", "block_type": "Block type"})
@console_ns.doc(params=query_params_from_model(DefaultBlockConfigQuery))
@console_ns.response(
200,
"Default block configuration retrieved successfully",
console_ns.models[DefaultBlockConfigResponse.__name__],
)
@console_ns.response(404, "Block type not found")
@console_ns.doc(params=query_params_from_model(DefaultBlockConfigQuery))
@setup_required
@login_required
@account_initialization_required
@ -1279,15 +1266,14 @@ class WorkflowFeaturesApi(Resource):
workflow_service = WorkflowService()
workflow_service.update_draft_workflow_features(app_model=app_model, features=features, account=current_user)
return {"result": "success"}
return SimpleResultResponse(result="success").model_dump(mode="json")
@console_ns.route("/apps/<uuid:app_id>/workflows")
class PublishedAllWorkflowApi(Resource):
@console_ns.doc(params=query_params_from_model(WorkflowListQuery))
@console_ns.doc("get_all_published_workflows")
@console_ns.doc(description="Get all published workflows for an application")
@console_ns.doc(params={"app_id": "Application ID"})
@console_ns.doc(params={"app_id": "Application ID", **query_params_from_model(WorkflowListQuery)})
@console_ns.response(
200,
"Published workflows retrieved successfully",
@ -1340,7 +1326,11 @@ class DraftWorkflowRestoreApi(Resource):
@console_ns.doc("restore_workflow_to_draft")
@console_ns.doc(description="Restore a published workflow version into the draft workflow")
@console_ns.doc(params={"app_id": "Application ID", "workflow_id": "Published workflow ID"})
@console_ns.response(200, "Workflow restored successfully", console_ns.models[WorkflowRestoreResponse.__name__])
@console_ns.response(
200,
"Workflow restored successfully",
console_ns.models[SyncDraftWorkflowResponse.__name__],
)
@console_ns.response(400, "Source workflow must be published")
@console_ns.response(404, "Workflow not found")
@setup_required
@ -1366,11 +1356,11 @@ class DraftWorkflowRestoreApi(Resource):
except ValueError as exc:
raise BadRequest(str(exc)) from exc
return {
"result": "success",
"hash": workflow.unique_hash,
"updated_at": TimestampField().format(workflow.updated_at or workflow.created_at),
}
return SyncDraftWorkflowResponse(
result="success",
hash=workflow.unique_hash,
updated_at=to_timestamp(workflow.updated_at or workflow.created_at),
).model_dump(mode="json")
@console_ns.route("/apps/<uuid:app_id>/workflows/<string:workflow_id>")
@ -1422,6 +1412,7 @@ class WorkflowByIdApi(Resource):
return dump_response(WorkflowResponse, workflow)
@console_ns.response(204, "Workflow deleted successfully")
@setup_required
@login_required
@account_initialization_required
@ -1480,7 +1471,7 @@ class DraftWorkflowNodeLastRunApi(Resource):
)
if node_exec is None:
raise NotFound("last run not found")
return WorkflowRunNodeExecutionResponse.model_validate(node_exec, from_attributes=True).model_dump(mode="json")
return dump_response(WorkflowRunNodeExecutionResponse, node_exec)
@console_ns.route("/apps/<uuid:app_id>/workflows/draft/trigger/run")
@ -1493,19 +1484,8 @@ class DraftWorkflowTriggerRunApi(Resource):
@console_ns.doc("poll_draft_workflow_trigger_run")
@console_ns.doc(description="Poll for trigger events and execute full workflow when event arrives")
@console_ns.doc(params={"app_id": "Application ID"})
@console_ns.expect(
console_ns.model(
"DraftWorkflowTriggerRunRequest",
{
"node_id": fields.String(required=True, description="Node ID"),
},
)
)
@console_ns.response(
200,
"Trigger event received and workflow executed successfully",
console_ns.models[GeneratedAppResponse.__name__],
)
@console_ns.expect(console_ns.models[DraftWorkflowTriggerRunPayload.__name__])
@console_ns.response(200, "Trigger event received and workflow executed successfully")
@console_ns.response(403, "Permission denied")
@console_ns.response(500, "Internal server error")
@setup_required
@ -1537,10 +1517,11 @@ class DraftWorkflowTriggerRunApi(Resource):
try:
event = poller.poll()
if not event:
return jsonable_encoder({"status": "waiting", "retry_in": LISTENING_RETRY_IN})
return _trigger_debug_waiting_response()
workflow_args = dict(event.workflow_args)
workflow_args[SKIP_PREPARE_USER_INPUTS_KEY] = True
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(
AppGenerateService.generate(
app_model=app_model,
@ -1554,7 +1535,7 @@ class DraftWorkflowTriggerRunApi(Resource):
except InvokeRateLimitError as ex:
raise InvokeRateLimitHttpError(ex.description)
except PluginInvokeError as e:
return jsonable_encoder({"status": "error", "error": e.to_user_friendly_error()}), 400
return _trigger_debug_error_response(e.to_user_friendly_error()), 400
except Exception as e:
logger.exception("Error polling trigger debug event")
raise e
@ -1573,7 +1554,7 @@ class DraftWorkflowTriggerNodeApi(Resource):
@console_ns.response(
200,
"Trigger event received and node executed successfully",
console_ns.models[GeneratedAppResponse.__name__],
console_ns.models[WorkflowRunNodeExecutionResponse.__name__],
)
@console_ns.response(403, "Permission denied")
@console_ns.response(500, "Internal server error")
@ -1617,12 +1598,12 @@ class DraftWorkflowTriggerNodeApi(Resource):
)
event = poller.poll()
except PluginInvokeError as e:
return jsonable_encoder({"status": "error", "error": e.to_user_friendly_error()}), 400
return _trigger_debug_error_response(e.to_user_friendly_error()), 400
except Exception as e:
logger.exception("Error polling trigger debug event")
raise e
if not event:
return jsonable_encoder({"status": "waiting", "retry_in": LISTENING_RETRY_IN})
return _trigger_debug_waiting_response()
raw_files = event.workflow_args.get("files")
files = _parse_file(draft_workflow, raw_files if isinstance(raw_files, list) else None)
@ -1636,12 +1617,10 @@ class DraftWorkflowTriggerNodeApi(Resource):
query="",
files=files,
)
return jsonable_encoder(node_execution)
return dump_response(WorkflowRunNodeExecutionResponse, node_execution)
except Exception as e:
logger.exception("Error running draft workflow trigger node")
return jsonable_encoder(
{"status": "error", "error": "An unexpected error occurred while running the node."}
), 400
return _trigger_debug_error_response("An unexpected error occurred while running the node."), 400
@console_ns.route("/apps/<uuid:app_id>/workflows/draft/trigger/run-all")
@ -1655,7 +1634,7 @@ class DraftWorkflowTriggerRunAllApi(Resource):
@console_ns.doc(description="Full workflow debug when the start node is a trigger")
@console_ns.doc(params={"app_id": "Application ID"})
@console_ns.expect(console_ns.models[DraftWorkflowTriggerRunAllPayload.__name__])
@console_ns.response(200, "Workflow executed successfully", console_ns.models[GeneratedAppResponse.__name__])
@console_ns.response(200, "Workflow executed successfully")
@console_ns.response(403, "Permission denied")
@console_ns.response(500, "Internal server error")
@setup_required
@ -1685,12 +1664,12 @@ class DraftWorkflowTriggerRunAllApi(Resource):
node_ids=node_ids,
)
except PluginInvokeError as e:
return jsonable_encoder({"status": "error", "error": e.to_user_friendly_error()}), 400
return _trigger_debug_error_response(e.to_user_friendly_error()), 400
except Exception as e:
logger.exception("Error polling trigger debug event")
raise e
if trigger_debug_event is None:
return jsonable_encoder({"status": "waiting", "retry_in": LISTENING_RETRY_IN})
return _trigger_debug_waiting_response()
try:
workflow_args = dict(trigger_debug_event.workflow_args)
@ -1704,16 +1683,13 @@ class DraftWorkflowTriggerRunAllApi(Resource):
streaming=True,
root_node_id=trigger_debug_event.node_id,
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except InvokeRateLimitError as ex:
raise InvokeRateLimitHttpError(ex.description)
except Exception:
logger.exception("Error running draft workflow trigger run-all")
return jsonable_encoder(
{
"status": "error",
}
), 400
return _trigger_debug_error_response(), 400
@console_ns.route("/apps/workflows/online-users")
@ -1738,7 +1714,7 @@ class WorkflowOnlineUsersApi(Resource):
raise BadRequest(f"Maximum {MAX_WORKFLOW_ONLINE_USERS_REQUEST_IDS} app_ids are allowed per request.")
if not app_ids:
return {"data": []}
return WorkflowOnlineUsersResponse(data=[]).model_dump(mode="json")
workflow_service = WorkflowService()
accessible_app_ids = workflow_service.get_accessible_app_ids(app_ids, current_tenant_id)

View File

@ -1,19 +1,15 @@
from datetime import datetime
from typing import Any
from uuid import UUID
from flask import request
from flask_restx import Resource, fields, marshal
from pydantic import BaseModel, Field, RootModel
from flask_restx import Resource
from pydantic import AliasChoices, BaseModel, Field, field_validator
from werkzeug.exceptions import Forbidden, InternalServerError, NotFound
import services
from controllers.common.fields import UsageCountResponse
from controllers.common.schema import (
get_or_create_model,
query_params_from_model,
register_response_schema_models,
register_schema_models,
)
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.datasets.error import DatasetNameDuplicateError
from controllers.console.wraps import (
@ -28,19 +24,8 @@ from controllers.console.wraps import (
)
from extensions.ext_database import db
from fields.base import ResponseModel
from fields.dataset_fields import (
dataset_detail_fields,
dataset_retrieval_model_fields,
doc_metadata_fields,
external_knowledge_info_fields,
external_retrieval_model_fields,
icon_info_fields,
keyword_setting_fields,
reranking_model_fields,
tag_fields,
vector_setting_fields,
weighted_score_fields,
)
from fields.dataset_fields import DatasetDetailResponse
from libs.helper import dump_response
from libs.login import login_required
from models import Account
from services.dataset_service import DatasetService
@ -49,50 +34,10 @@ from services.external_knowledge_service import ExternalDatasetService
from services.hit_testing_service import HitTestingService
from services.knowledge_service import BedrockRetrievalSetting, ExternalDatasetTestService
register_response_schema_models(console_ns, UsageCountResponse)
def _build_dataset_detail_model():
keyword_setting_model = get_or_create_model("DatasetKeywordSetting", keyword_setting_fields)
vector_setting_model = get_or_create_model("DatasetVectorSetting", vector_setting_fields)
weighted_score_fields_copy = weighted_score_fields.copy()
weighted_score_fields_copy["keyword_setting"] = fields.Nested(keyword_setting_model)
weighted_score_fields_copy["vector_setting"] = fields.Nested(vector_setting_model)
weighted_score_model = get_or_create_model("DatasetWeightedScore", weighted_score_fields_copy)
reranking_model = get_or_create_model("DatasetRerankingModel", reranking_model_fields)
dataset_retrieval_model_fields_copy = dataset_retrieval_model_fields.copy()
dataset_retrieval_model_fields_copy["reranking_model"] = fields.Nested(reranking_model)
dataset_retrieval_model_fields_copy["weights"] = fields.Nested(weighted_score_model, allow_null=True)
dataset_retrieval_model = get_or_create_model("DatasetRetrievalModel", dataset_retrieval_model_fields_copy)
tag_model = get_or_create_model("Tag", tag_fields)
doc_metadata_model = get_or_create_model("DatasetDocMetadata", doc_metadata_fields)
external_knowledge_info_model = get_or_create_model("ExternalKnowledgeInfo", external_knowledge_info_fields)
external_retrieval_model = get_or_create_model("ExternalRetrievalModel", external_retrieval_model_fields)
icon_info_model = get_or_create_model("DatasetIconInfo", icon_info_fields)
dataset_detail_fields_copy = dataset_detail_fields.copy()
dataset_detail_fields_copy["retrieval_model_dict"] = fields.Nested(dataset_retrieval_model)
dataset_detail_fields_copy["tags"] = fields.List(fields.Nested(tag_model))
dataset_detail_fields_copy["external_knowledge_info"] = fields.Nested(external_knowledge_info_model)
dataset_detail_fields_copy["external_retrieval_model"] = fields.Nested(external_retrieval_model, allow_null=True)
dataset_detail_fields_copy["doc_metadata"] = fields.List(fields.Nested(doc_metadata_model))
dataset_detail_fields_copy["icon_info"] = fields.Nested(icon_info_model)
return get_or_create_model("DatasetDetail", dataset_detail_fields_copy)
try:
dataset_detail_model = console_ns.models["DatasetDetail"]
except KeyError:
dataset_detail_model = _build_dataset_detail_model()
class ExternalKnowledgeApiPayload(BaseModel):
name: str = Field(..., min_length=1, max_length=40)
settings: dict[str, object]
settings: dict[str, Any]
class ExternalDatasetCreatePayload(BaseModel):
@ -100,15 +45,13 @@ class ExternalDatasetCreatePayload(BaseModel):
external_knowledge_id: str
name: str = Field(..., min_length=1, max_length=100)
description: str | None = Field(None, max_length=400)
external_retrieval_model: dict[str, object] | None = Field(default=None)
external_retrieval_model: dict[str, Any] | None = None
class ExternalHitTestingPayload(BaseModel):
query: str
external_retrieval_model: dict[str, object] | None = Field(default=None)
metadata_filtering_conditions: dict[str, object] | None = Field(
default=None,
)
external_retrieval_model: dict[str, Any] | None = None
metadata_filtering_conditions: dict[str, Any] | None = None
class BedrockRetrievalPayload(BaseModel):
@ -123,7 +66,7 @@ class ExternalApiTemplateListQuery(BaseModel):
keyword: str | None = Field(default=None, description="Search keyword")
class ExternalKnowledgeDatasetBindingResponse(ResponseModel):
class ExternalKnowledgeApiBindingResponse(ResponseModel):
id: str
name: str
@ -133,22 +76,52 @@ class ExternalKnowledgeApiResponse(ResponseModel):
tenant_id: str
name: str
description: str
settings: dict[str, Any] | None = Field(default=None)
dataset_bindings: list[ExternalKnowledgeDatasetBindingResponse] = Field(default_factory=list)
settings: dict[str, Any] | None = Field(validation_alias=AliasChoices("settings_dict", "settings"))
dataset_bindings: list[ExternalKnowledgeApiBindingResponse]
created_by: str
created_at: str
@field_validator("created_at", mode="before")
@classmethod
def _normalize_created_at(cls, value: datetime | str) -> str:
if isinstance(value, datetime):
return value.isoformat()
return value
class ExternalKnowledgeApiListResponse(ResponseModel):
data: list[ExternalKnowledgeApiResponse]
has_more: bool
limit: int
total: int
total: int | None
page: int
class ExternalRetrievalTestResponse(RootModel[dict[str, Any] | list[dict[str, Any]]]):
root: dict[str, Any] | list[dict[str, Any]]
class ExternalHitTestingQueryResponse(ResponseModel):
content: str
class ExternalHitTestingRecordResponse(ResponseModel):
content: str | None = None
title: str | None = None
score: float | None = None
metadata: dict[str, Any] | None = None
class ExternalHitTestingResponse(ResponseModel):
query: ExternalHitTestingQueryResponse
records: list[ExternalHitTestingRecordResponse]
class BedrockRetrievalRecordResponse(ResponseModel):
metadata: dict[str, Any] | None = None
score: float
title: str | None = None
content: str | None = None
class BedrockRetrievalResponse(ResponseModel):
records: list[BedrockRetrievalRecordResponse]
register_schema_models(
@ -161,9 +134,16 @@ register_schema_models(
)
register_response_schema_models(
console_ns,
UsageCountResponse,
DatasetDetailResponse,
ExternalKnowledgeApiBindingResponse,
ExternalKnowledgeApiResponse,
ExternalKnowledgeApiListResponse,
ExternalRetrievalTestResponse,
ExternalHitTestingQueryResponse,
ExternalHitTestingRecordResponse,
ExternalHitTestingResponse,
BedrockRetrievalRecordResponse,
BedrockRetrievalResponse,
)
@ -187,24 +167,26 @@ class ExternalApiTemplateListApi(Resource):
external_knowledge_apis, total = ExternalDatasetService.get_external_knowledge_apis(
query.page, query.limit, current_tenant_id, query.keyword
)
response = {
"data": [item.to_dict() for item in external_knowledge_apis],
"has_more": len(external_knowledge_apis) == query.limit,
"limit": query.limit,
"total": total,
"page": query.page,
}
return response, 200
return ExternalKnowledgeApiListResponse(
data=[ExternalKnowledgeApiResponse.model_validate(item) for item in external_knowledge_apis],
has_more=len(external_knowledge_apis) == query.limit,
limit=query.limit,
total=total,
page=query.page,
).model_dump(mode="json"), 200
@setup_required
@login_required
@account_initialization_required
@console_ns.doc("create_external_api_template")
@console_ns.doc(description="Create external knowledge API template")
@console_ns.expect(console_ns.models[ExternalKnowledgeApiPayload.__name__])
@console_ns.response(
201,
"External API template created successfully",
console_ns.models[ExternalKnowledgeApiResponse.__name__],
)
@console_ns.response(403, "Permission denied")
@setup_required
@login_required
@account_initialization_required
@with_current_user
@with_current_tenant_id
def post(self, current_tenant_id: str, current_user: Account):
@ -223,7 +205,7 @@ class ExternalApiTemplateListApi(Resource):
except services.errors.dataset.DatasetNameDuplicateError:
raise DatasetNameDuplicateError()
return external_knowledge_api.to_dict(), 201
return dump_response(ExternalKnowledgeApiResponse, external_knowledge_api), 201
@console_ns.route("/datasets/external-knowledge-api/<uuid:external_knowledge_api_id>")
@ -249,17 +231,21 @@ class ExternalApiTemplateApi(Resource):
if external_knowledge_api is None:
raise NotFound("API template not found.")
return external_knowledge_api.to_dict(), 200
return dump_response(ExternalKnowledgeApiResponse, external_knowledge_api), 200
@console_ns.doc("update_external_api_template")
@console_ns.doc(description="Update external knowledge API template")
@console_ns.doc(params={"external_knowledge_api_id": "External knowledge API ID"})
@console_ns.expect(console_ns.models[ExternalKnowledgeApiPayload.__name__])
@console_ns.response(
200,
"External API template updated successfully",
console_ns.models[ExternalKnowledgeApiResponse.__name__],
)
@console_ns.response(404, "Template not found")
@setup_required
@login_required
@account_initialization_required
@console_ns.expect(console_ns.models[ExternalKnowledgeApiPayload.__name__])
@with_current_user
@with_current_tenant_id
def patch(self, current_tenant_id: str, current_user: Account, external_knowledge_api_id: UUID):
@ -275,7 +261,7 @@ class ExternalApiTemplateApi(Resource):
args=payload.model_dump(),
)
return external_knowledge_api.to_dict(), 200
return dump_response(ExternalKnowledgeApiResponse, external_knowledge_api), 200
@setup_required
@login_required
@ -309,7 +295,7 @@ class ExternalApiUseCheckApi(Resource):
external_knowledge_api_is_using, count = ExternalDatasetService.external_knowledge_api_use_check(
external_knowledge_api_id_str, current_tenant_id
)
return {"is_using": external_knowledge_api_is_using, "count": count}, 200
return UsageCountResponse(is_using=external_knowledge_api_is_using, count=count).model_dump(mode="json"), 200
@console_ns.route("/datasets/external")
@ -317,7 +303,9 @@ class ExternalDatasetCreateApi(Resource):
@console_ns.doc("create_external_dataset")
@console_ns.doc(description="Create external knowledge dataset")
@console_ns.expect(console_ns.models[ExternalDatasetCreatePayload.__name__])
@console_ns.response(201, "External dataset created successfully", dataset_detail_model)
@console_ns.response(
201, "External dataset created successfully", console_ns.models[DatasetDetailResponse.__name__]
)
@console_ns.response(400, "Invalid parameters")
@console_ns.response(403, "Permission denied")
@setup_required
@ -345,16 +333,15 @@ class ExternalDatasetCreateApi(Resource):
except services.errors.dataset.DatasetNameDuplicateError:
raise DatasetNameDuplicateError()
item = marshal(dataset, dataset_detail_fields)
dataset_id_str = item["id"]
dataset_id_str = str(dataset.id)
permission_keys_map = enterprise_rbac_service.RBACService.DatasetPermissions.batch_get(
str(current_tenant_id),
current_user.id,
[dataset_id_str],
)
item["permission_keys"] = permission_keys_map.get(dataset_id_str, [])
return item, 201
data = DatasetDetailResponse.model_validate(dataset).model_dump(mode="json")
data["permission_keys"] = permission_keys_map.get(dataset_id_str, [])
return data, 201
@console_ns.route("/datasets/<uuid:dataset_id>/external-hit-testing")
@ -366,7 +353,7 @@ class ExternalKnowledgeHitTestingApi(Resource):
@console_ns.response(
200,
"External hit testing completed successfully",
console_ns.models[ExternalRetrievalTestResponse.__name__],
console_ns.models[ExternalHitTestingResponse.__name__],
)
@console_ns.response(404, "Dataset not found")
@console_ns.response(400, "Invalid parameters")
@ -399,7 +386,7 @@ class ExternalKnowledgeHitTestingApi(Resource):
metadata_filtering_conditions=payload.metadata_filtering_conditions,
)
return response
return dump_response(ExternalHitTestingResponse, response)
except Exception as e:
raise InternalServerError(str(e))
@ -410,11 +397,7 @@ class BedrockRetrievalApi(Resource):
@console_ns.doc("bedrock_retrieval_test")
@console_ns.doc(description="Bedrock retrieval test (internal use only)")
@console_ns.expect(console_ns.models[BedrockRetrievalPayload.__name__])
@console_ns.response(
200,
"Bedrock retrieval test completed",
console_ns.models[ExternalRetrievalTestResponse.__name__],
)
@console_ns.response(200, "Bedrock retrieval test completed", console_ns.models[BedrockRetrievalResponse.__name__])
def post(self):
payload = BedrockRetrievalPayload.model_validate(console_ns.payload or {})
@ -422,4 +405,4 @@ class BedrockRetrievalApi(Resource):
result = ExternalDatasetTestService.knowledge_retrieval(
payload.retrieval_setting, payload.query, payload.knowledge_id
)
return result, 200
return dump_response(BedrockRetrievalResponse, result), 200

View File

@ -1,5 +1,6 @@
import json
import logging
from collections.abc import Mapping
from typing import Any, Literal, cast
from uuid import UUID
@ -21,8 +22,6 @@ from controllers.console.app.error import (
)
from controllers.console.app.workflow import (
RESTORE_SOURCE_WORKFLOW_MUST_BE_PUBLISHED_MESSAGE,
DefaultBlockConfigResponse,
DefaultBlockConfigsResponse,
WorkflowPaginationResponse,
WorkflowResponse,
)
@ -41,6 +40,7 @@ from controllers.web.error import InvokeRateLimitError as InvokeRateLimitHttpErr
from core.app.apps.base_app_queue_manager import AppQueueManager
from core.app.apps.pipeline.pipeline_generator import PipelineGenerator
from core.app.entities.app_invoke_entities import InvokeFrom
from core.plugin.entities.plugin_daemon import PluginDatasourceProviderEntity
from extensions.ext_database import db
from factories import variable_factory
from fields.base import ResponseModel
@ -50,9 +50,8 @@ from fields.workflow_run_fields import (
WorkflowRunNodeExecutionResponse,
WorkflowRunPaginationResponse,
)
from graphon.model_runtime.utils.encoders import jsonable_encoder
from libs import helper
from libs.helper import TimestampField, UUIDStrOrEmpty, dump_response
from libs.helper import UUIDStrOrEmpty, dump_response, to_timestamp
from libs.login import login_required
from models import Account
from models.dataset import Pipeline
@ -72,14 +71,14 @@ logger = logging.getLogger(__name__)
class DraftWorkflowSyncPayload(BaseModel):
graph: dict[str, Any]
hash: str | None = None
environment_variables: list[dict[str, Any]] | None = Field(default=None)
conversation_variables: list[dict[str, Any]] | None = Field(default=None)
rag_pipeline_variables: list[dict[str, Any]] | None = Field(default=None)
features: dict[str, Any] | None = Field(default=None)
environment_variables: list[dict[str, Any]] | None = None
conversation_variables: list[dict[str, Any]] | None = None
rag_pipeline_variables: list[dict[str, Any]] | None = None
features: dict[str, Any] | None = None
class NodeRunPayload(BaseModel):
inputs: dict[str, Any] | None = Field(default=None)
inputs: dict[str, Any] | None = None
class NodeRunRequiredPayload(BaseModel):
@ -136,14 +135,30 @@ class RagPipelineWorkflowPublishResponse(ResponseModel):
created_at: int
class RagPipelineOpaqueResponse(RootModel[Any]):
root: Any
class RagPipelineStepParametersResponse(ResponseModel):
class RagPipelineVariablesResponse(ResponseModel):
# TODO: Replace Any with a response model that mirrors graphon.variables.variables.RAGPipelineVariable.
variables: Any
class DatasourcePluginListResponse(RootModel[list[PluginDatasourceProviderEntity]]):
pass
class RagPipelineRecommendedPluginResponse(ResponseModel):
installed_recommended_plugins: list[Mapping[str, object]] = Field(
description="Installed tool provider payloads. Shape follows the tool provider serializer."
)
uninstalled_recommended_plugins: list[Mapping[str, object]] = Field(
description="Marketplace plugin manifest payloads returned by the marketplace service."
)
class RagPipelineTransformResponse(ResponseModel):
pipeline_id: str
dataset_id: str
status: str
register_schema_models(
console_ns,
DraftWorkflowSyncPayload,
@ -162,10 +177,10 @@ register_schema_models(
)
register_response_schema_models(
console_ns,
DefaultBlockConfigResponse,
DefaultBlockConfigsResponse,
RagPipelineOpaqueResponse,
RagPipelineStepParametersResponse,
DatasourcePluginListResponse,
RagPipelineRecommendedPluginResponse,
RagPipelineTransformResponse,
RagPipelineVariablesResponse,
RagPipelineWorkflowPublishResponse,
RagPipelineWorkflowSyncResponse,
SimpleResultResponse,
@ -254,17 +269,16 @@ class DraftRagPipelineApi(Resource):
except WorkflowHashNotEqualError:
raise DraftWorkflowNotSync()
return {
"result": "success",
"hash": workflow.unique_hash,
"updated_at": TimestampField().format(workflow.updated_at or workflow.created_at),
}
return RagPipelineWorkflowSyncResponse(
result="success",
hash=workflow.unique_hash,
updated_at=to_timestamp(workflow.updated_at or workflow.created_at),
).model_dump(mode="json")
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/draft/iteration/nodes/<string:node_id>/run")
class RagPipelineDraftRunIterationNodeApi(Resource):
@console_ns.expect(console_ns.models[NodeRunPayload.__name__])
@console_ns.response(200, "Success", console_ns.models[RagPipelineOpaqueResponse.__name__])
@setup_required
@login_required
@account_initialization_required
@ -284,6 +298,7 @@ class RagPipelineDraftRunIterationNodeApi(Resource):
pipeline=pipeline, user=current_user, node_id=node_id, args=args, streaming=True
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except services.errors.conversation.ConversationNotExistsError:
raise NotFound("Conversation Not Exists.")
@ -299,7 +314,6 @@ class RagPipelineDraftRunIterationNodeApi(Resource):
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/draft/loop/nodes/<string:node_id>/run")
class RagPipelineDraftRunLoopNodeApi(Resource):
@console_ns.expect(console_ns.models[NodeRunPayload.__name__])
@console_ns.response(200, "Success", console_ns.models[RagPipelineOpaqueResponse.__name__])
@setup_required
@login_required
@account_initialization_required
@ -319,6 +333,7 @@ class RagPipelineDraftRunLoopNodeApi(Resource):
pipeline=pipeline, user=current_user, node_id=node_id, args=args, streaming=True
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except services.errors.conversation.ConversationNotExistsError:
raise NotFound("Conversation Not Exists.")
@ -334,7 +349,6 @@ class RagPipelineDraftRunLoopNodeApi(Resource):
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/draft/run")
class DraftRagPipelineRunApi(Resource):
@console_ns.expect(console_ns.models[DraftWorkflowRunPayload.__name__])
@console_ns.response(200, "Success", console_ns.models[RagPipelineOpaqueResponse.__name__])
@setup_required
@login_required
@account_initialization_required
@ -358,6 +372,7 @@ class DraftRagPipelineRunApi(Resource):
streaming=True,
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except InvokeRateLimitError as ex:
raise InvokeRateLimitHttpError(ex.description)
@ -366,7 +381,6 @@ class DraftRagPipelineRunApi(Resource):
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/published/run")
class PublishedRagPipelineRunApi(Resource):
@console_ns.expect(console_ns.models[PublishedWorkflowRunPayload.__name__])
@console_ns.response(200, "Success", console_ns.models[RagPipelineOpaqueResponse.__name__])
@setup_required
@login_required
@account_initialization_required
@ -391,6 +405,7 @@ class PublishedRagPipelineRunApi(Resource):
streaming=streaming,
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except InvokeRateLimitError as ex:
raise InvokeRateLimitHttpError(ex.description)
@ -399,7 +414,6 @@ class PublishedRagPipelineRunApi(Resource):
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/published/datasource/nodes/<string:node_id>/run")
class RagPipelinePublishedDatasourceNodeRunApi(Resource):
@console_ns.expect(console_ns.models[DatasourceNodeRunPayload.__name__])
@console_ns.response(200, "Success", console_ns.models[RagPipelineOpaqueResponse.__name__])
@setup_required
@login_required
@account_initialization_required
@ -414,6 +428,7 @@ class RagPipelinePublishedDatasourceNodeRunApi(Resource):
payload = DatasourceNodeRunPayload.model_validate(console_ns.payload or {})
rag_pipeline_service = RagPipelineService()
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(
PipelineGenerator.convert_to_event_stream(
rag_pipeline_service.run_datasource_workflow_node(
@ -432,7 +447,6 @@ class RagPipelinePublishedDatasourceNodeRunApi(Resource):
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/draft/datasource/nodes/<string:node_id>/run")
class RagPipelineDraftDatasourceNodeRunApi(Resource):
@console_ns.expect(console_ns.models[DatasourceNodeRunPayload.__name__])
@console_ns.response(200, "Success", console_ns.models[RagPipelineOpaqueResponse.__name__])
@setup_required
@login_required
@edit_permission_required
@ -447,6 +461,7 @@ class RagPipelineDraftDatasourceNodeRunApi(Resource):
payload = DatasourceNodeRunPayload.model_validate(console_ns.payload or {})
rag_pipeline_service = RagPipelineService()
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(
PipelineGenerator.convert_to_event_stream(
rag_pipeline_service.run_datasource_workflow_node(
@ -492,9 +507,7 @@ class RagPipelineDraftNodeRunApi(Resource):
if workflow_node_execution is None:
raise ValueError("Workflow node execution not found")
return WorkflowRunNodeExecutionResponse.model_validate(
workflow_node_execution, from_attributes=True
).model_dump(mode="json")
return dump_response(WorkflowRunNodeExecutionResponse, workflow_node_execution)
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflow-runs/tasks/<string:task_id>/stop")
@ -513,7 +526,7 @@ class RagPipelineTaskStopApi(Resource):
"""
AppQueueManager.set_stop_flag(task_id, InvokeFrom.DEBUGGER, current_user.id)
return {"result": "success"}
return SimpleResultResponse(result="success").model_dump(mode="json")
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/publish")
@ -567,20 +580,18 @@ class PublishedRagPipelineApi(Resource):
pipeline.is_published = True
pipeline.workflow_id = workflow.id
db.session.commit()
workflow_created_at = TimestampField().format(workflow.created_at)
workflow_created_at = to_timestamp(workflow.created_at)
return {
"result": "success",
"created_at": workflow_created_at,
}
return RagPipelineWorkflowPublishResponse(result="success", created_at=workflow_created_at).model_dump(
mode="json"
)
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/default-workflow-block-configs")
class DefaultRagPipelineBlockConfigsApi(Resource):
@console_ns.response(
200,
"Default block configs retrieved successfully",
console_ns.models[DefaultBlockConfigsResponse.__name__],
"Default workflow block configurations retrieved successfully",
)
@setup_required
@login_required
@ -602,8 +613,7 @@ class DefaultRagPipelineBlockConfigApi(Resource):
@console_ns.doc(params=query_params_from_model(DefaultBlockConfigQuery))
@console_ns.response(
200,
"Default block config retrieved successfully",
console_ns.models[DefaultBlockConfigResponse.__name__],
"Default workflow block configuration retrieved successfully",
)
@setup_required
@login_required
@ -631,13 +641,13 @@ class DefaultRagPipelineBlockConfigApi(Resource):
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows")
class PublishedAllRagPipelineApi(Resource):
@console_ns.doc(params=query_params_from_model(WorkflowListQuery))
@console_ns.response(
200,
"Published workflows retrieved successfully",
console_ns.models[WorkflowPaginationResponse.__name__],
)
@console_ns.response(403, "Permission denied")
@console_ns.doc(params=query_params_from_model(WorkflowListQuery))
@setup_required
@login_required
@account_initialization_required
@ -671,14 +681,15 @@ class PublishedAllRagPipelineApi(Resource):
named_only=named_only,
)
return WorkflowPaginationResponse.model_validate(
return dump_response(
WorkflowPaginationResponse,
{
"items": workflows,
"page": page,
"limit": limit,
"has_more": has_more,
}
).model_dump(mode="json")
},
)
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/<string:workflow_id>/restore")
@ -706,11 +717,11 @@ class RagPipelineDraftWorkflowRestoreApi(Resource):
except WorkflowNotFoundError as exc:
raise NotFound(str(exc)) from exc
return {
"result": "success",
"hash": workflow.unique_hash,
"updated_at": TimestampField().format(workflow.updated_at or workflow.created_at),
}
return RagPipelineWorkflowSyncResponse(
result="success",
hash=workflow.unique_hash,
updated_at=to_timestamp(workflow.updated_at or workflow.created_at),
).model_dump(mode="json")
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/<string:workflow_id>")
@ -784,13 +795,17 @@ class RagPipelineByIdApi(Resource):
except ValueError as e:
raise NotFound(str(e))
return None, 204
return "", 204
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/published/processing/parameters")
class PublishedRagPipelineSecondStepApi(Resource):
@console_ns.doc(params=query_params_from_model(NodeIdQuery))
@console_ns.response(200, "Success", console_ns.models[RagPipelineStepParametersResponse.__name__])
@console_ns.response(
200,
"Second step parameters retrieved successfully",
console_ns.models[RagPipelineVariablesResponse.__name__],
)
@setup_required
@login_required
@account_initialization_required
@ -805,15 +820,17 @@ class PublishedRagPipelineSecondStepApi(Resource):
node_id = query.node_id
rag_pipeline_service = RagPipelineService()
variables = rag_pipeline_service.get_second_step_parameters(pipeline=pipeline, node_id=node_id, is_draft=False)
return {
"variables": variables,
}
return dump_response(RagPipelineVariablesResponse, {"variables": variables})
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/published/pre-processing/parameters")
class PublishedRagPipelineFirstStepApi(Resource):
@console_ns.doc(params=query_params_from_model(NodeIdQuery))
@console_ns.response(200, "Success", console_ns.models[RagPipelineStepParametersResponse.__name__])
@console_ns.response(
200,
"First step parameters retrieved successfully",
console_ns.models[RagPipelineVariablesResponse.__name__],
)
@setup_required
@login_required
@account_initialization_required
@ -828,15 +845,17 @@ class PublishedRagPipelineFirstStepApi(Resource):
node_id = query.node_id
rag_pipeline_service = RagPipelineService()
variables = rag_pipeline_service.get_first_step_parameters(pipeline=pipeline, node_id=node_id, is_draft=False)
return {
"variables": variables,
}
return dump_response(RagPipelineVariablesResponse, {"variables": variables})
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/draft/pre-processing/parameters")
class DraftRagPipelineFirstStepApi(Resource):
@console_ns.doc(params=query_params_from_model(NodeIdQuery))
@console_ns.response(200, "Success", console_ns.models[RagPipelineStepParametersResponse.__name__])
@console_ns.response(
200,
"First step parameters retrieved successfully",
console_ns.models[RagPipelineVariablesResponse.__name__],
)
@setup_required
@login_required
@account_initialization_required
@ -851,15 +870,17 @@ class DraftRagPipelineFirstStepApi(Resource):
node_id = query.node_id
rag_pipeline_service = RagPipelineService()
variables = rag_pipeline_service.get_first_step_parameters(pipeline=pipeline, node_id=node_id, is_draft=True)
return {
"variables": variables,
}
return dump_response(RagPipelineVariablesResponse, {"variables": variables})
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/draft/processing/parameters")
class DraftRagPipelineSecondStepApi(Resource):
@console_ns.doc(params=query_params_from_model(NodeIdQuery))
@console_ns.response(200, "Success", console_ns.models[RagPipelineStepParametersResponse.__name__])
@console_ns.response(
200,
"Second step parameters retrieved successfully",
console_ns.models[RagPipelineVariablesResponse.__name__],
)
@setup_required
@login_required
@account_initialization_required
@ -875,9 +896,7 @@ class DraftRagPipelineSecondStepApi(Resource):
rag_pipeline_service = RagPipelineService()
variables = rag_pipeline_service.get_second_step_parameters(pipeline=pipeline, node_id=node_id, is_draft=True)
return {
"variables": variables,
}
return dump_response(RagPipelineVariablesResponse, {"variables": variables})
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflow-runs")
@ -910,7 +929,7 @@ class RagPipelineWorkflowRunListApi(Resource):
rag_pipeline_service = RagPipelineService()
result = rag_pipeline_service.get_rag_pipeline_paginate_workflow_runs(pipeline=pipeline, args=args)
return WorkflowRunPaginationResponse.model_validate(result, from_attributes=True).model_dump(mode="json")
return dump_response(WorkflowRunPaginationResponse, result)
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflow-runs/<uuid:run_id>")
@ -935,7 +954,7 @@ class RagPipelineWorkflowRunDetailApi(Resource):
if workflow_run is None:
raise NotFound("Workflow run not found")
return WorkflowRunDetailResponse.model_validate(workflow_run, from_attributes=True).model_dump(mode="json")
return dump_response(WorkflowRunDetailResponse, workflow_run)
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflow-runs/<uuid:run_id>/node-executions")
@ -964,20 +983,25 @@ class RagPipelineWorkflowRunNodeExecutionListApi(Resource):
user=user,
)
return WorkflowRunNodeExecutionListResponse.model_validate(
{"data": node_executions}, from_attributes=True
).model_dump(mode="json")
return dump_response(WorkflowRunNodeExecutionListResponse, {"data": node_executions})
@console_ns.route("/rag/pipelines/datasource-plugins")
class DatasourceListApi(Resource):
@console_ns.response(200, "Success", console_ns.models[RagPipelineOpaqueResponse.__name__])
@console_ns.response(
200,
"Datasource plugins retrieved successfully",
console_ns.models[DatasourcePluginListResponse.__name__],
)
@setup_required
@login_required
@account_initialization_required
@with_current_tenant_id
def get(self, current_tenant_id: str):
return jsonable_encoder(RagPipelineManageService.list_rag_pipeline_datasources(current_tenant_id))
return dump_response(
DatasourcePluginListResponse,
RagPipelineManageService.list_rag_pipeline_datasources(current_tenant_id),
)
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/draft/nodes/<string:node_id>/last-run")
@ -1003,12 +1027,16 @@ class RagPipelineWorkflowLastRunApi(Resource):
)
if node_exec is None:
raise NotFound("last run not found")
return WorkflowRunNodeExecutionResponse.model_validate(node_exec, from_attributes=True).model_dump(mode="json")
return dump_response(WorkflowRunNodeExecutionResponse, node_exec)
@console_ns.route("/rag/pipelines/transform/datasets/<uuid:dataset_id>")
class RagPipelineTransformApi(Resource):
@console_ns.response(200, "Success", console_ns.models[RagPipelineOpaqueResponse.__name__])
@console_ns.response(
200,
"Dataset transformed successfully",
console_ns.models[RagPipelineTransformResponse.__name__],
)
@setup_required
@login_required
@account_initialization_required
@ -1020,7 +1048,7 @@ class RagPipelineTransformApi(Resource):
dataset_id_str = str(dataset_id)
rag_pipeline_transform_service = RagPipelineTransformService()
result = rag_pipeline_transform_service.transform_dataset(dataset_id_str, db.session)
return result
return dump_response(RagPipelineTransformResponse, result)
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/draft/datasource/variables-inspect")
@ -1050,15 +1078,17 @@ class RagPipelineDatasourceVariableApi(Resource):
args=args,
current_user=current_user,
)
return WorkflowRunNodeExecutionResponse.model_validate(
workflow_node_execution, from_attributes=True
).model_dump(mode="json")
return dump_response(WorkflowRunNodeExecutionResponse, workflow_node_execution)
@console_ns.route("/rag/pipelines/recommended-plugins")
class RagPipelineRecommendedPluginApi(Resource):
@console_ns.doc(params=query_params_from_model(RagPipelineRecommendedPluginQuery))
@console_ns.response(200, "Success", console_ns.models[RagPipelineOpaqueResponse.__name__])
@console_ns.response(
200,
"Recommended plugins retrieved successfully",
console_ns.models[RagPipelineRecommendedPluginResponse.__name__],
)
@setup_required
@login_required
@account_initialization_required
@ -1069,4 +1099,4 @@ class RagPipelineRecommendedPluginApi(Resource):
rag_pipeline_service = RagPipelineService()
recommended_plugins = rag_pipeline_service.get_recommended_plugins(query.type, current_user, current_tenant_id)
return recommended_plugins
return dump_response(RagPipelineRecommendedPluginResponse, recommended_plugins)

View File

@ -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/<uuid:app_id>/chat-messages", endpoint="trial_app_chat_completion")

View File

@ -8,20 +8,18 @@ from pydantic import BaseModel, Field
from sqlalchemy.orm import Session, sessionmaker
from werkzeug.exceptions import BadRequest, InternalServerError, NotFound
from controllers.common.fields import GeneratedAppResponse, SimpleResultResponse
from controllers.common.fields import EventStreamResponse, SimpleResultResponse
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.app.error import DraftWorkflowNotExist, DraftWorkflowNotSync
from controllers.console.app.workflow import (
RESTORE_SOURCE_WORKFLOW_MUST_BE_PUBLISHED_MESSAGE,
DefaultBlockConfigsResponse,
PublishWorkflowResponse,
SyncDraftWorkflowResponse,
WorkflowPaginationResponse,
WorkflowPublishResponse,
WorkflowResponse,
WorkflowRestoreResponse,
)
from controllers.console.snippets.payloads import (
PublishWorkflowPayload,
SnippetDraftNodeRunPayload,
SnippetDraftRunPayload,
SnippetDraftSyncPayload,
@ -43,6 +41,7 @@ from core.app.apps.base_app_queue_manager import AppQueueManager
from core.app.entities.app_invoke_entities import InvokeFrom
from extensions.ext_database import db
from extensions.ext_redis import redis_client
from fields.base import ResponseModel
from fields.workflow_run_fields import (
WorkflowRunDetailResponse,
WorkflowRunNodeExecutionListResponse,
@ -51,7 +50,7 @@ from fields.workflow_run_fields import (
)
from graphon.graph_engine.manager import GraphEngineManager
from libs import helper
from libs.helper import TimestampField
from libs.helper import dump_response, to_timestamp
from libs.login import current_account_with_tenant, login_required
from models import Account
from models.snippet import CustomizedSnippet
@ -76,7 +75,7 @@ class SnippetWorkflowResponse(WorkflowResponse):
input_fields: list[dict] = Field(default_factory=list)
class SnippetDraftConfigResponse(BaseModel):
class SnippetDraftConfigResponse(ResponseModel):
parallel_depth_limit: int
@ -96,19 +95,17 @@ register_schema_models(
SnippetLoopNodeRunPayload,
SnippetWorkflowListQuery,
WorkflowRunQuery,
PublishWorkflowPayload,
)
register_response_schema_models(
console_ns,
DefaultBlockConfigsResponse,
GeneratedAppResponse,
EventStreamResponse,
SimpleResultResponse,
SnippetDraftConfigResponse,
SnippetWorkflowResponse,
SnippetWorkflowPaginationResponse,
WorkflowPublishResponse,
PublishWorkflowResponse,
WorkflowPaginationResponse,
WorkflowRestoreResponse,
SyncDraftWorkflowResponse,
WorkflowRunPaginationResponse,
WorkflowRunDetailResponse,
WorkflowRunNodeExecutionListResponse,
@ -175,7 +172,7 @@ class SnippetDraftWorkflowApi(Resource):
raise DraftWorkflowNotExist()
workflow.conversation_variables = []
response = SnippetWorkflowResponse.model_validate(workflow, from_attributes=True).model_dump(mode="json")
response = dump_response(SnippetWorkflowResponse, workflow)
response["input_fields"] = snippet.input_fields_list
return response
@ -184,7 +181,7 @@ class SnippetDraftWorkflowApi(Resource):
@console_ns.response(
200,
"Draft workflow synced successfully",
console_ns.models[WorkflowRestoreResponse.__name__],
console_ns.models[SyncDraftWorkflowResponse.__name__],
)
@console_ns.response(400, "Hash mismatch")
@setup_required
@ -214,11 +211,11 @@ class SnippetDraftWorkflowApi(Resource):
except ValueError as e:
return {"message": str(e)}, 400
return {
"result": "success",
"hash": workflow.unique_hash,
"updated_at": TimestampField().format(workflow.updated_at or workflow.created_at),
}
return SyncDraftWorkflowResponse(
result="success",
hash=workflow.unique_hash,
updated_at=to_timestamp(workflow.updated_at or workflow.created_at),
).model_dump(mode="json")
@console_ns.route("/snippets/<uuid:snippet_id>/workflows/draft/config")
@ -237,9 +234,7 @@ class SnippetDraftConfigApi(Resource):
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_MANAGE, resource_required=False)
def get(self, snippet: CustomizedSnippet):
"""Get snippet draft workflow configuration limits."""
return {
"parallel_depth_limit": 3,
}
return SnippetDraftConfigResponse(parallel_depth_limit=3).model_dump(mode="json")
@console_ns.route("/snippets/<uuid:snippet_id>/workflows/publish")
@ -268,13 +263,12 @@ class SnippetPublishedWorkflowApi(Resource):
if not workflow:
return None
response = SnippetWorkflowResponse.model_validate(workflow, from_attributes=True).model_dump(mode="json")
response = dump_response(SnippetWorkflowResponse, workflow)
response["input_fields"] = snippet.input_fields_list
return response
@console_ns.doc("publish_snippet_workflow")
@console_ns.expect(console_ns.models.get(PublishWorkflowPayload.__name__))
@console_ns.response(200, "Workflow published successfully", console_ns.models[WorkflowPublishResponse.__name__])
@console_ns.response(200, "Workflow published successfully", console_ns.models[PublishWorkflowResponse.__name__])
@console_ns.response(400, "No draft workflow found")
@setup_required
@login_required
@ -297,25 +291,18 @@ class SnippetPublishedWorkflowApi(Resource):
snippet=snippet,
account=current_user,
)
workflow_created_at = TimestampField().format(workflow.created_at)
workflow_created_at = to_timestamp(workflow.created_at)
session.commit()
except ValueError as e:
return {"message": str(e)}, 400
return {
"result": "success",
"created_at": workflow_created_at,
}
return PublishWorkflowResponse(result="success", created_at=workflow_created_at).model_dump(mode="json")
@console_ns.route("/snippets/<uuid:snippet_id>/workflows/default-workflow-block-configs")
class SnippetDefaultBlockConfigsApi(Resource):
@console_ns.doc("get_snippet_default_block_configs")
@console_ns.response(
200,
"Default block configs retrieved successfully",
console_ns.models[DefaultBlockConfigsResponse.__name__],
)
@console_ns.response(200, "Default block configs retrieved successfully")
@setup_required
@login_required
@account_initialization_required
@ -377,7 +364,7 @@ class SnippetDraftWorkflowRestoreApi(Resource):
@console_ns.doc("restore_snippet_workflow_to_draft")
@console_ns.doc(description="Restore a published snippet workflow version into the draft workflow")
@console_ns.doc(params={"snippet_id": "Snippet ID", "workflow_id": "Published workflow ID"})
@console_ns.response(200, "Workflow restored successfully", console_ns.models[WorkflowRestoreResponse.__name__])
@console_ns.response(200, "Workflow restored successfully", console_ns.models[SyncDraftWorkflowResponse.__name__])
@console_ns.response(400, "Source workflow must be published")
@console_ns.response(404, "Workflow not found")
@setup_required
@ -406,11 +393,11 @@ class SnippetDraftWorkflowRestoreApi(Resource):
except ValueError as exc:
raise BadRequest(str(exc)) from exc
return {
"result": "success",
"hash": workflow.unique_hash,
"updated_at": TimestampField().format(workflow.updated_at or workflow.created_at),
}
return SyncDraftWorkflowResponse(
result="success",
hash=workflow.unique_hash,
updated_at=to_timestamp(workflow.updated_at or workflow.created_at),
).model_dump(mode="json")
@console_ns.route("/snippets/<uuid:snippet_id>/workflow-runs")
@ -442,7 +429,7 @@ class SnippetWorkflowRunsApi(Resource):
snippet_service = _snippet_service()
result = snippet_service.get_snippet_workflow_runs(snippet=snippet, args=args)
return WorkflowRunPaginationResponse.model_validate(result, from_attributes=True).model_dump(mode="json")
return dump_response(WorkflowRunPaginationResponse, result)
@console_ns.route("/snippets/<uuid:snippet_id>/workflow-runs/<uuid:run_id>")
@ -468,7 +455,7 @@ class SnippetWorkflowRunDetailApi(Resource):
if not workflow_run:
raise NotFound("Workflow run not found")
return WorkflowRunDetailResponse.model_validate(workflow_run, from_attributes=True).model_dump(mode="json")
return dump_response(WorkflowRunDetailResponse, workflow_run)
@console_ns.route("/snippets/<uuid:snippet_id>/workflow-runs/<uuid:run_id>/node-executions")
@ -493,9 +480,7 @@ class SnippetWorkflowRunNodeExecutionsApi(Resource):
run_id=run_id,
)
return WorkflowRunNodeExecutionListResponse.model_validate(
{"data": node_executions}, from_attributes=True
).model_dump(mode="json")
return dump_response(WorkflowRunNodeExecutionListResponse, {"data": node_executions})
@console_ns.route("/snippets/<uuid:snippet_id>/workflows/draft/nodes/<string:node_id>/run")
@ -546,9 +531,7 @@ class SnippetDraftNodeRunApi(Resource):
session_maker=_snippet_session_maker(),
)
return WorkflowRunNodeExecutionResponse.model_validate(
workflow_node_execution, from_attributes=True
).model_dump(mode="json")
return dump_response(WorkflowRunNodeExecutionResponse, workflow_node_execution)
@console_ns.route("/snippets/<uuid:snippet_id>/workflows/draft/nodes/<string:node_id>/last-run")
@ -584,7 +567,7 @@ class SnippetDraftNodeLastRunApi(Resource):
if node_exec is None:
raise NotFound("Node last run not found")
return WorkflowRunNodeExecutionResponse.model_validate(node_exec, from_attributes=True).model_dump(mode="json")
return dump_response(WorkflowRunNodeExecutionResponse, node_exec)
@console_ns.route("/snippets/<uuid:snippet_id>/workflows/draft/iteration/nodes/<string:node_id>/run")
@ -596,7 +579,7 @@ class SnippetDraftRunIterationNodeApi(Resource):
@console_ns.response(
200,
"Iteration node run started successfully (SSE stream)",
console_ns.models[GeneratedAppResponse.__name__],
console_ns.models[EventStreamResponse.__name__],
)
@console_ns.response(404, "Snippet or draft workflow not found")
@setup_required
@ -627,6 +610,7 @@ class SnippetDraftRunIterationNodeApi(Resource):
session_maker=_snippet_session_maker(),
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except ValueError as e:
raise e
@ -644,7 +628,7 @@ class SnippetDraftRunLoopNodeApi(Resource):
@console_ns.response(
200,
"Loop node run started successfully (SSE stream)",
console_ns.models[GeneratedAppResponse.__name__],
console_ns.models[EventStreamResponse.__name__],
)
@console_ns.response(404, "Snippet or draft workflow not found")
@setup_required
@ -675,6 +659,7 @@ class SnippetDraftRunLoopNodeApi(Resource):
session_maker=_snippet_session_maker(),
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except ValueError as e:
raise e
@ -690,7 +675,7 @@ class SnippetDraftWorkflowRunApi(Resource):
@console_ns.response(
200,
"Draft workflow run started successfully (SSE stream)",
console_ns.models[GeneratedAppResponse.__name__],
console_ns.models[EventStreamResponse.__name__],
)
@console_ns.response(404, "Snippet or draft workflow not found")
@setup_required
@ -722,6 +707,7 @@ class SnippetDraftWorkflowRunApi(Resource):
session_maker=_snippet_session_maker(),
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except ValueError as e:
raise e
@ -757,4 +743,4 @@ class SnippetWorkflowTaskStopApi(Resource):
# 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")

View File

@ -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/<uuid:snippet_id>")
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

View File

@ -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

View File

@ -837,7 +837,7 @@ class DocumentStatusApi(DatasetApiResource):
except ValueError as e:
raise InvalidActionError(str(e))
return dump_response(SimpleResultResponse, {"result": "success"}), 200
return SimpleResultResponse(result="success").model_dump(mode="json"), 200
@service_api_ns.route("/datasets/tags")
@ -903,11 +903,8 @@ class DatasetTagsApi(DatasetApiResource):
payload = TagCreatePayload.model_validate(service_api_ns.payload or {})
tag = TagService.save_tags(SaveTagPayload(name=payload.name, type=TagType.KNOWLEDGE), db.session)
response = dump_response(
KnowledgeTagResponse,
{"id": tag.id, "name": tag.name, "type": tag.type, "binding_count": 0},
)
return response, 200
response = KnowledgeTagResponse(id=tag.id, name=tag.name, type=tag.type, binding_count="0")
return response.model_dump(mode="json"), 200
@service_api_ns.doc(
summary="Update Knowledge Tag",
@ -943,11 +940,8 @@ class DatasetTagsApi(DatasetApiResource):
binding_count = TagService.get_tag_binding_count(tag_id, db.session)
response = dump_response(
KnowledgeTagResponse,
{"id": tag.id, "name": tag.name, "type": tag.type, "binding_count": binding_count},
)
return response, 200
response = KnowledgeTagResponse(id=tag.id, name=tag.name, type=tag.type, binding_count=str(binding_count))
return response.model_dump(mode="json"), 200
@service_api_ns.doc(
summary="Delete Knowledge Tag",
@ -1078,5 +1072,8 @@ class DatasetTagsBindingStatusApi(DatasetApiResource):
tags = TagService.get_tags_by_target_id(
"knowledge", current_user.current_tenant_id, str(dataset_id), db.session
)
tags_list = [{"id": tag.id, "name": tag.name} for tag in tags]
return dump_response(DatasetBoundTagListResponse, {"data": tags_list, "total": len(tags)}), 200
response = DatasetBoundTagListResponse(
data=[DatasetBoundTagResponse(id=tag.id, name=tag.name) for tag in tags],
total=len(tags),
)
return response.model_dump(mode="json"), 200

View File

@ -12,6 +12,7 @@ from controllers.common.errors import FilenameNotExistsError, NoFileUploadedErro
from controllers.common.fields import GeneratedAppResponse
from controllers.common.schema import (
query_params_from_model,
query_params_from_request,
register_response_schema_models,
register_schema_model,
register_schema_models,
@ -150,12 +151,11 @@ class DatasourcePluginsApi(DatasetApiResource):
if not dataset:
raise NotFound("Dataset not found.")
# Get query parameter to determine published or draft
is_published: bool = request.args.get("is_published", default=True, type=bool)
query = query_params_from_request(DatasourcePluginsQuery)
rag_pipeline_service: RagPipelineService = RagPipelineService()
datasource_plugins: list[dict[Any, Any]] = rag_pipeline_service.get_datasource_plugins(
tenant_id=tenant_id, dataset_id=dataset_id_str, is_published=is_published
tenant_id=tenant_id, dataset_id=dataset_id_str, is_published=query.is_published
)
return datasource_plugins, 200

View File

@ -2,14 +2,12 @@
Web App Human Input Form APIs.
"""
import json
import logging
from collections.abc import Sequence
from typing import Any, NotRequired, TypedDict
from typing import Self
from flask import Response, request
from flask import request
from flask_restx import Resource
from pydantic import BaseModel, ConfigDict, Field
from sqlalchemy import select
from sqlalchemy.orm import sessionmaker
from werkzeug.exceptions import Forbidden
@ -20,35 +18,58 @@ from controllers.common.human_input import HumanInputFormSubmitPayload, stringif
from controllers.common.schema import register_response_schema_models, register_schema_models
from controllers.web import web_ns
from controllers.web.error import WebFormRateLimitExceededError
from controllers.web.site import serialize_app_site_payload
from controllers.web.site import WebAppSiteResponse
from extensions.ext_database import db
from graphon.nodes.human_input.entities import FormInputConfig
from libs.helper import RateLimiter, extract_remote_ip, to_timestamp
from fields.base import ResponseModel
from graphon.nodes.human_input.entities import FormInputConfig, UserActionConfig
from libs.helper import RateLimiter, dump_response, extract_remote_ip, to_timestamp
from models.account import TenantStatus
from models.model import App, Site
from repositories.factory import DifyAPIRepositoryFactory
from services.feature_service import FeatureService
from services.human_input_file_upload_service import HumanInputFileUploadService
from services.human_input_service import Form, FormNotFoundError, HumanInputService
logger = logging.getLogger(__name__)
class HumanInputUploadTokenResponse(BaseModel):
class HumanInputUploadTokenResponse(ResponseModel):
upload_token: str
expires_at: int
class HumanInputFormDefinitionResponse(BaseModel):
form_content: Any
inputs: Any
class HumanInputFormDefinitionResponse(ResponseModel):
form_content: str
inputs: list[FormInputConfig]
resolved_default_values: dict[str, str]
user_actions: Any
user_actions: list[UserActionConfig]
expiration_time: int
site: dict[str, Any] | None = Field(default=None)
site: WebAppSiteResponse | None = None
@classmethod
def from_form(
cls,
form: Form,
*,
inputs: Sequence[FormInputConfig] = (),
site: WebAppSiteResponse | None = None,
) -> Self:
definition_payload = form.get_definition().model_dump(mode="json")
expiration_time = to_timestamp(form.expiration_time)
if expiration_time is None:
raise ValueError("Human input form expiration_time is required")
return cls(
form_content=definition_payload["rendered_content"],
inputs=list(inputs),
resolved_default_values=stringify_form_default_values(definition_payload["default_values"]),
user_actions=definition_payload["user_actions"],
expiration_time=expiration_time,
site=site,
)
class HumanInputFormSubmitResponse(BaseModel):
model_config = ConfigDict(extra="forbid")
class HumanInputFormSubmitResponse(ResponseModel):
pass
register_schema_models(web_ns, HumanInputFormSubmitPayload)
@ -86,40 +107,26 @@ def _create_upload_service() -> HumanInputFileUploadService:
)
class FormDefinitionPayload(TypedDict):
form_content: Any
inputs: Any
resolved_default_values: dict[str, str]
user_actions: Any
expiration_time: int
site: NotRequired[dict]
def _jsonify_form_definition(
form: Form,
*,
inputs: Sequence[FormInputConfig] = (),
site_payload: dict | None = None,
) -> Response:
"""Return the form payload (optionally with site) as a JSON response."""
definition_payload = form.get_definition().model_dump(mode="json")
payload: FormDefinitionPayload = {
"form_content": definition_payload["rendered_content"],
"inputs": [i.model_dump(mode="json") for i in inputs],
"resolved_default_values": stringify_form_default_values(definition_payload["default_values"]),
"user_actions": definition_payload["user_actions"],
"expiration_time": to_timestamp(form.expiration_time),
}
if site_payload is not None:
payload["site"] = site_payload
return Response(json.dumps(payload, ensure_ascii=False), mimetype="application/json")
@web_ns.route("/form/human_input/<string:form_token>/upload-token")
class HumanInputFormUploadTokenApi(Resource):
"""API for issuing HITL upload tokens for active human input forms."""
@web_ns.response(200, "Success", web_ns.models[HumanInputUploadTokenResponse.__name__])
@web_ns.doc("create_human_input_form_upload_token")
@web_ns.doc(description="Issue an upload token for an active human input form")
@web_ns.doc(params={"form_token": "Human input form token"})
@web_ns.doc(
responses={
200: "Upload token issued successfully",
404: "Form not found",
412: "Form already submitted or expired",
429: "Too many requests",
}
)
@web_ns.response(
200,
"Upload token issued successfully",
web_ns.models[HumanInputUploadTokenResponse.__name__],
)
def post(self, form_token: str):
"""
Issue an upload token for a human input form.
@ -136,11 +143,9 @@ class HumanInputFormUploadTokenApi(Resource):
except FormNotFoundError:
raise NotFoundError("Form not found")
response = HumanInputUploadTokenResponse(
upload_token=token.upload_token,
expires_at=to_timestamp(token.expires_at),
)
return response.model_dump(mode="json"), 200
return HumanInputUploadTokenResponse(
upload_token=token.upload_token, expires_at=to_timestamp(token.expires_at)
).model_dump(mode="json"), 200
@web_ns.route("/form/human_input/<string:form_token>")
@ -150,7 +155,23 @@ class HumanInputFormApi(Resource):
# NOTE(QuantumGhost): this endpoint is unauthenticated on purpose for now.
# def get(self, _app_model: App, _end_user: EndUser, form_token: str):
@web_ns.response(200, "Success", web_ns.models[HumanInputFormDefinitionResponse.__name__])
@web_ns.doc("get_human_input_form")
@web_ns.doc(description="Get a human input form definition by token")
@web_ns.doc(params={"form_token": "Human input form token"})
@web_ns.doc(
responses={
200: "Form retrieved successfully",
403: "Forbidden",
404: "Form not found",
412: "Form already submitted or expired",
429: "Too many requests",
}
)
@web_ns.response(
200,
"Form retrieved successfully",
web_ns.models[HumanInputFormDefinitionResponse.__name__],
)
def get(self, form_token: str):
"""
Get human input form definition by token.
@ -172,17 +193,47 @@ class HumanInputFormApi(Resource):
service.ensure_form_active(form)
app_model, site = _get_app_site_from_form(form)
tenant = app_model.tenant
if tenant is None:
raise Forbidden()
inputs = service.resolve_form_inputs(form)
return _jsonify_form_definition(
form,
inputs=inputs,
site_payload=serialize_app_site_payload(app_model, site, None),
return dump_response(
HumanInputFormDefinitionResponse,
HumanInputFormDefinitionResponse.from_form(
form,
inputs=inputs,
site=WebAppSiteResponse.from_app_site(
tenant=tenant,
app_model=app_model,
site=site,
end_user_id=None,
can_replace_logo=FeatureService.get_features(
app_model.tenant_id, exclude_vector_space=True
).can_replace_logo,
),
),
)
# def post(self, _app_model: App, _end_user: EndUser, form_token: str):
@web_ns.response(200, "Success", web_ns.models[HumanInputFormSubmitResponse.__name__])
@web_ns.expect(web_ns.models[HumanInputFormSubmitPayload.__name__])
@web_ns.doc("submit_human_input_form")
@web_ns.doc(description="Submit a human input form by token")
@web_ns.doc(params={"form_token": "Human input form token"})
@web_ns.doc(
responses={
200: "Form submitted successfully",
400: "Bad request - invalid submission data",
404: "Form not found",
412: "Form already submitted or expired",
429: "Too many requests",
}
)
@web_ns.response(
200,
"Form submitted successfully",
web_ns.models[HumanInputFormSubmitResponse.__name__],
)
def post(self, form_token: str):
"""
Submit human input form by token.
@ -225,7 +276,7 @@ class HumanInputFormApi(Resource):
except FormNotFoundError:
raise NotFoundError("Form not found")
return {}, 200
return HumanInputFormSubmitResponse().model_dump(mode="json"), 200
def _get_app_site_from_form(form: Form) -> tuple[App, Site]:
@ -238,7 +289,7 @@ def _get_app_site_from_form(form: Form) -> tuple[App, Site]:
if site is None:
raise Forbidden()
if app_model.tenant and app_model.tenant.status == TenantStatus.ARCHIVE:
if app_model.tenant is None or app_model.tenant.status == TenantStatus.ARCHIVE:
raise Forbidden()
return app_model, site

View File

@ -1,7 +1,6 @@
from typing import Any, cast
from typing import Any, Self
from flask_restx import fields, marshal, marshal_with
from pydantic import Field
from pydantic import AliasChoices, Field, computed_field
from sqlalchemy import select
from werkzeug.exceptions import Forbidden
@ -11,30 +10,19 @@ from controllers.web import web_ns
from controllers.web.wraps import WebApiResource
from extensions.ext_database import db
from fields.base import ResponseModel
from libs.helper import AppIconUrlField
from models.account import TenantStatus
from libs.helper import build_icon_url
from models.account import Tenant, TenantStatus
from models.model import App, EndUser, Site
from services.feature_service import FeatureService
class AppSiteModelConfigResponse(ResponseModel):
opening_statement: str | None = None
suggested_questions: Any
suggested_questions_after_answer: Any
more_like_this: Any
model: Any
user_input_form: Any
pre_prompt: str | None = None
class AppSiteResponse(ResponseModel):
title: str | None = None
class WebSiteResponse(ResponseModel):
title: str
chat_color_theme: str | None = None
chat_color_theme_inverted: bool | None = None
chat_color_theme_inverted: bool
icon_type: str | None = None
icon: str | None = None
icon_background: str | None = None
icon_url: str | None = None
description: str | None = None
copyright: str | None = None
privacy_policy: str | None = None
@ -44,64 +32,92 @@ class AppSiteResponse(ResponseModel):
show_workflow_steps: bool | None = None
use_icon_as_answer_icon: bool | None = None
@computed_field(return_type=str | None) # type: ignore[prop-decorator]
@property
def icon_url(self) -> str | None:
return build_icon_url(self.icon_type, self.icon)
class AppSiteInfoResponse(ResponseModel):
class WebModelConfigResponse(ResponseModel):
opening_statement: str | None = None
suggested_questions: Any = Field(
default=None,
validation_alias=AliasChoices("suggested_questions_list", "suggested_questions"),
)
suggested_questions_after_answer: Any = Field(
default=None,
validation_alias=AliasChoices("suggested_questions_after_answer_dict", "suggested_questions_after_answer"),
)
more_like_this: Any = Field(
default=None,
validation_alias=AliasChoices("more_like_this_dict", "more_like_this"),
)
model: Any = Field(default=None, validation_alias=AliasChoices("model_dict", "model"))
user_input_form: Any = Field(
default=None,
validation_alias=AliasChoices("user_input_form_list", "user_input_form"),
)
pre_prompt: str | None = None
class WebAppCustomConfigResponse(ResponseModel):
remove_webapp_brand: bool
replace_webapp_logo: str | None = None
class WebAppSiteResponse(ResponseModel):
app_id: str
end_user_id: str | None = None
enable_site: bool
site: AppSiteResponse
model_config_: AppSiteModelConfigResponse | None = Field(default=None, alias="model_config")
plan: str | None = None
site: WebSiteResponse
model_config_: WebModelConfigResponse | None = Field(
default=None, validation_alias="model_config", serialization_alias="model_config"
)
plan: str
can_replace_logo: bool
custom_config: dict[str, Any] | None = Field(default=None)
custom_config: WebAppCustomConfigResponse | None = None
@classmethod
def from_app_site(
cls,
*,
tenant: Tenant,
app_model: App,
site: Site,
end_user_id: str | None,
can_replace_logo: bool,
) -> Self:
custom_config = None
if can_replace_logo:
replace_webapp_logo = (
f"{dify_config.FILES_URL}/files/workspaces/{tenant.id}/webapp-logo"
if tenant.custom_config_dict.get("replace_webapp_logo")
else None
)
custom_config = WebAppCustomConfigResponse(
remove_webapp_brand=tenant.custom_config_dict.get("remove_webapp_brand", False),
replace_webapp_logo=replace_webapp_logo,
)
return cls(
app_id=app_model.id,
end_user_id=end_user_id,
enable_site=app_model.enable_site,
site=WebSiteResponse.model_validate(site, from_attributes=True),
model_config_=None,
plan=tenant.plan,
can_replace_logo=can_replace_logo,
custom_config=custom_config,
)
register_response_schema_models(web_ns, AppSiteInfoResponse)
register_response_schema_models(
web_ns, WebSiteResponse, WebModelConfigResponse, WebAppCustomConfigResponse, WebAppSiteResponse
)
@web_ns.route("/site")
class AppSiteApi(WebApiResource):
"""Resource for app sites."""
model_config_fields = {
"opening_statement": fields.String,
"suggested_questions": fields.Raw(attribute="suggested_questions_list"),
"suggested_questions_after_answer": fields.Raw(attribute="suggested_questions_after_answer_dict"),
"more_like_this": fields.Raw(attribute="more_like_this_dict"),
"model": fields.Raw(attribute="model_dict"),
"user_input_form": fields.Raw(attribute="user_input_form_list"),
"pre_prompt": fields.String,
}
site_fields = {
"title": fields.String,
"chat_color_theme": fields.String,
"chat_color_theme_inverted": fields.Boolean,
"icon_type": fields.String,
"icon": fields.String,
"icon_background": fields.String,
"icon_url": AppIconUrlField,
"description": fields.String,
"copyright": fields.String,
"privacy_policy": fields.String,
"custom_disclaimer": fields.String,
"default_language": fields.String,
"prompt_public": fields.Boolean,
"show_workflow_steps": fields.Boolean,
"use_icon_as_answer_icon": fields.Boolean,
}
app_fields = {
"app_id": fields.String,
"end_user_id": fields.String,
"enable_site": fields.Boolean,
"site": fields.Nested(site_fields),
"model_config": fields.Nested(model_config_fields, allow_null=True),
"plan": fields.String,
"can_replace_logo": fields.Boolean,
"custom_config": fields.Raw(attribute="custom_config"),
}
@web_ns.doc("Get App Site Info")
@web_ns.doc(description="Retrieve app site information and configuration.")
@web_ns.doc(
@ -114,57 +130,25 @@ class AppSiteApi(WebApiResource):
500: "Internal Server Error",
}
)
@web_ns.response(200, "Success", web_ns.models[AppSiteInfoResponse.__name__])
@marshal_with(app_fields)
@web_ns.response(200, "Success", web_ns.models[WebAppSiteResponse.__name__])
def get(self, app_model: App, end_user: EndUser):
"""Retrieve app site info."""
# get site
site = db.session.scalar(select(Site).where(Site.app_id == app_model.id).limit(1))
if not site:
if site is None:
raise Forbidden()
if app_model.tenant and app_model.tenant.status == TenantStatus.ARCHIVE:
tenant = app_model.tenant
if tenant is None or tenant.status == TenantStatus.ARCHIVE:
raise Forbidden()
can_replace_logo = FeatureService.get_features(app_model.tenant_id, exclude_vector_space=True).can_replace_logo
return AppSiteInfo(app_model.tenant, app_model, site, end_user.id, can_replace_logo)
class AppSiteInfo:
"""Class to store site information."""
def __init__(self, tenant, app, site, end_user, can_replace_logo):
"""Initialize AppSiteInfo instance."""
self.app_id = app.id
self.end_user_id = end_user
self.enable_site = app.enable_site
self.site = site
self.model_config = None
self.plan = tenant.plan
self.can_replace_logo = can_replace_logo
if can_replace_logo:
base_url = dify_config.FILES_URL
remove_webapp_brand = tenant.custom_config_dict.get("remove_webapp_brand", False)
replace_webapp_logo = (
f"{base_url}/files/workspaces/{tenant.id}/webapp-logo"
if tenant.custom_config_dict.get("replace_webapp_logo")
else None
)
self.custom_config = {
"remove_webapp_brand": remove_webapp_brand,
"replace_webapp_logo": replace_webapp_logo,
}
def serialize_site(site: Site) -> dict[str, Any]:
"""Serialize Site model using the same schema as AppSiteApi."""
return cast(dict[str, Any], marshal(site, AppSiteApi.site_fields))
def serialize_app_site_payload(app_model: App, site: Site, end_user_id: str | None) -> dict[str, Any]:
can_replace_logo = FeatureService.get_features(app_model.tenant_id, exclude_vector_space=True).can_replace_logo
app_site_info = AppSiteInfo(app_model.tenant, app_model, site, end_user_id, can_replace_logo)
return cast(dict[str, Any], marshal(app_site_info, AppSiteApi.app_fields))
return WebAppSiteResponse.from_app_site(
tenant=tenant,
app_model=app_model,
site=site,
end_user_id=end_user.id,
can_replace_logo=can_replace_logo,
).model_dump(mode="json")

View File

@ -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,
}

View File

@ -3,25 +3,14 @@ from __future__ import annotations
from datetime import datetime
from typing import Any
from flask_restx import fields
from pydantic import field_validator
from fields.base import ResponseModel
from graphon.variables.types import SegmentType
from libs.helper import TimestampField, to_timestamp
from libs.helper import to_timestamp
from ._value_type_serializer import serialize_value_type
conversation_variable_fields = {
"id": fields.String,
"name": fields.String,
"value_type": fields.String(attribute=serialize_value_type),
"value": fields.String,
"description": fields.String,
"created_at": TimestampField,
"updated_at": TimestampField,
}
class ConversationVariableResponse(ResponseModel):
id: str

View File

@ -1,22 +1,9 @@
from datetime import datetime
from flask_restx import fields
from pydantic import Field, field_validator
from fields.base import ResponseModel
from libs.helper import TimestampField, to_timestamp
dataset_fields = {
"id": fields.String,
"name": fields.String,
"description": fields.String,
"permission": fields.String,
"data_source_type": fields.String,
"indexing_technique": fields.String,
"created_by": fields.String,
"created_at": TimestampField,
"permission_keys": fields.List(fields.String()),
}
from libs.helper import to_timestamp
class DatasetMetadataResponse(ResponseModel):
@ -50,104 +37,6 @@ class DatasetMetadataActionResponse(ResponseModel):
result: str
reranking_model_fields = {"reranking_provider_name": fields.String, "reranking_model_name": fields.String}
keyword_setting_fields = {"keyword_weight": fields.Float}
vector_setting_fields = {
"vector_weight": fields.Float,
"embedding_model_name": fields.String,
"embedding_provider_name": fields.String,
}
weighted_score_fields = {
"weight_type": fields.String,
"keyword_setting": fields.Nested(keyword_setting_fields),
"vector_setting": fields.Nested(vector_setting_fields),
}
dataset_retrieval_model_fields = {
"search_method": fields.String,
"reranking_enable": fields.Boolean,
"reranking_mode": fields.String,
"reranking_model": fields.Nested(reranking_model_fields),
"weights": fields.Nested(weighted_score_fields, allow_null=True),
"top_k": fields.Integer,
"score_threshold_enabled": fields.Boolean,
"score_threshold": fields.Float,
}
dataset_summary_index_fields = {
"enable": fields.Boolean,
"model_name": fields.String,
"model_provider_name": fields.String,
"summary_prompt": fields.String,
}
external_retrieval_model_fields = {
"top_k": fields.Integer,
"score_threshold": fields.Float,
"score_threshold_enabled": fields.Boolean,
}
tag_fields = {"id": fields.String, "name": fields.String, "type": fields.String}
external_knowledge_info_fields = {
"external_knowledge_id": fields.String,
"external_knowledge_api_id": fields.String,
"external_knowledge_api_name": fields.String,
"external_knowledge_api_endpoint": fields.String,
}
doc_metadata_fields = {"id": fields.String, "name": fields.String, "type": fields.String}
icon_info_fields = {
"icon_type": fields.String,
"icon": fields.String,
"icon_background": fields.String,
"icon_url": fields.String,
}
dataset_detail_fields = {
"id": fields.String,
"name": fields.String,
"description": fields.String,
"provider": fields.String,
"permission": fields.String,
"data_source_type": fields.String,
"indexing_technique": fields.String,
"app_count": fields.Integer,
"document_count": fields.Integer,
"word_count": fields.Integer,
"created_by": fields.String,
"author_name": fields.String,
"created_at": TimestampField,
"updated_by": fields.String,
"updated_at": TimestampField,
"embedding_model": fields.String,
"embedding_model_provider": fields.String,
"embedding_available": fields.Boolean,
"retrieval_model_dict": fields.Nested(dataset_retrieval_model_fields),
"summary_index_setting": fields.Nested(dataset_summary_index_fields),
"tags": fields.List(fields.Nested(tag_fields)),
"doc_form": fields.String,
"external_knowledge_info": fields.Nested(external_knowledge_info_fields),
"external_retrieval_model": fields.Nested(external_retrieval_model_fields, allow_null=True),
"doc_metadata": fields.List(fields.Nested(doc_metadata_fields)),
"built_in_field_enabled": fields.Boolean,
"pipeline_id": fields.String,
"runtime_mode": fields.String,
"chunk_structure": fields.String,
"icon_info": fields.Nested(icon_info_fields),
"is_published": fields.Boolean,
"total_documents": fields.Integer,
"total_available_documents": fields.Integer,
"enable_api": fields.Boolean,
"is_multimodal": fields.Boolean,
"permission_keys": fields.List(fields.String()),
}
class DatasetRerankingModelResponse(ResponseModel):
reranking_provider_name: str | None = None
reranking_model_name: str | None = None

View File

@ -15,13 +15,13 @@ simple_account_fields = {
}
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 +30,7 @@ class _AccountAvatar(ResponseModel):
return build_avatar_url(self.avatar)
class Account(_AccountAvatar):
class AccountResponse(_AccountAvatarResponseMixin):
id: str
name: str
email: str
@ -48,7 +48,7 @@ class Account(_AccountAvatar):
return to_timestamp(value)
class AccountWithRole(_AccountAvatar):
class AccountWithRoleResponse(_AccountAvatarResponseMixin):
id: str
name: str
email: str
@ -65,5 +65,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

View File

@ -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

View File

@ -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"),
}

View File

@ -1,53 +1,14 @@
"""Workflow run response schemas for console APIs.
Most workflow-run endpoints should document and serialize responses with the
Pydantic models in this module. The remaining Flask-RESTX field dictionaries are
kept only for workflow app-log endpoints that still build legacy log models.
"""
from __future__ import annotations
from datetime import datetime
from typing import Any
from flask_restx import Namespace, fields
from pydantic import AliasChoices, Field, field_validator
from fields.base import ResponseModel
from fields.end_user_fields import SimpleEndUser
from fields.member_fields import SimpleAccount
from libs.helper import TimestampField, to_timestamp
workflow_run_for_log_fields = {
"id": fields.String,
"version": fields.String,
"status": fields.String,
"triggered_from": fields.String,
"error": fields.String,
"elapsed_time": fields.Float,
"total_tokens": fields.Integer,
"total_steps": fields.Integer,
"created_at": TimestampField,
"finished_at": TimestampField,
"exceptions_count": fields.Integer,
}
def build_workflow_run_for_log_model(api_or_ns: Namespace):
return api_or_ns.model("WorkflowRunForLog", workflow_run_for_log_fields)
workflow_run_for_archived_log_fields = {
"id": fields.String,
"status": fields.String,
"triggered_from": fields.String,
"elapsed_time": fields.Float,
"total_tokens": fields.Integer,
}
def build_workflow_run_for_archived_log_model(api_or_ns: Namespace):
return api_or_ns.model("WorkflowRunForArchivedLog", workflow_run_for_archived_log_fields)
from fields.member_fields import SimpleAccountResponse
from libs.helper import to_timestamp
class WorkflowRunForLogResponse(ResponseModel):
@ -98,7 +59,7 @@ class WorkflowRunForListResponse(ResponseModel):
elapsed_time: float | None = None
total_tokens: int | None = None
total_steps: int | None = None
created_by_account: SimpleAccount | None = None
created_by_account: SimpleAccountResponse | None = None
created_at: int | None = None
finished_at: int | None = None
exceptions_count: int | None = None
@ -158,7 +119,7 @@ class WorkflowRunDetailResponse(ResponseModel):
total_tokens: int | None = None
total_steps: int | None = None
created_by_role: str | None = None
created_by_account: SimpleAccount | None = None
created_by_account: SimpleAccountResponse | None = None
created_by_end_user: SimpleEndUser | None = None
created_at: int | None = None
finished_at: int | None = None
@ -194,7 +155,7 @@ class WorkflowRunNodeExecutionResponse(ResponseModel):
extras: Any = None
created_at: int | None = None
created_by_role: str | None = None
created_by_account: SimpleAccount | None = None
created_by_account: SimpleAccountResponse | None = None
created_by_end_user: SimpleEndUser | None = None
finished_at: int | None = None
inputs_truncated: bool | None = None

View File

@ -10,12 +10,11 @@ import uuid
from collections.abc import Callable, Generator, Mapping
from datetime import datetime
from hashlib import sha256
from typing import TYPE_CHECKING, Annotated, Any, Protocol, cast, overload, override
from typing import TYPE_CHECKING, Annotated, Any, Protocol, cast, overload
from uuid import UUID
from zoneinfo import available_timezones
from flask import Request, Response, stream_with_context
from flask_restx import fields
from pydantic import BaseModel, ConfigDict, TypeAdapter, with_config
from pydantic.functional_validators import AfterValidator
from typing_extensions import TypedDict
@ -127,26 +126,6 @@ def run(script):
return subprocess.getstatusoutput("source /root/.bashrc && " + script)
class AppIconUrlField(fields.Raw):
@override
def schema(self) -> dict[str, object]:
return {"type": "string", "nullable": True}
@override
def output(self, key, obj, **kwargs):
if obj is None:
return None
from models.model import App, IconType, Site
if isinstance(obj, dict) and "app" in obj:
obj = obj["app"]
if isinstance(obj, App | Site) and obj.icon_type == IconType.IMAGE:
return build_icon_url(obj.icon_type, obj.icon)
return None
def build_icon_url(icon_type: Any, icon: str | None) -> str | None:
if icon is None or icon_type is None:
return None
@ -167,28 +146,6 @@ def build_avatar_url(avatar: str | None) -> str | None:
return file_helpers.get_signed_file_url(avatar)
class TimestampField(fields.Raw):
@override
def schema(self) -> dict[str, object]:
return {"type": "integer", "format": "int64"}
@override
def format(self, value) -> int:
return int(value.timestamp())
class OptionalTimestampField(fields.Raw):
@override
def schema(self) -> dict[str, object]:
return {"type": "integer", "format": "int64", "nullable": True}
@override
def format(self, value) -> int | None:
if value is None:
return None
return int(value.timestamp())
@overload
def to_timestamp(value: datetime) -> int: ...

File diff suppressed because it is too large Load Diff

View File

@ -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 |

View File

@ -346,23 +346,29 @@ Verify password reset token validity
### [GET] /form/human_input/{form_token}
**Get human input form definition by token**
Get a human input form definition by token
GET /api/form/human_input/<form_token>
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| form_token | path | | Yes | string |
| form_token | path | Human input form token | Yes | string |
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Success | **application/json**: [HumanInputFormDefinitionResponse](#humaninputformdefinitionresponse)<br> |
| 200 | Form retrieved successfully | **application/json**: [HumanInputFormDefinitionResponse](#humaninputformdefinitionresponse)<br> |
| 403 | Forbidden | |
| 404 | Form not found | |
| 412 | Form already submitted or expired | |
| 429 | Too many requests | |
### [POST] /form/human_input/{form_token}
**Submit human input form by token**
Submit a human input form by token
POST /api/form/human_input/<form_token>
Request body:
@ -377,7 +383,7 @@ Request body:
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| form_token | path | | Yes | string |
| form_token | path | Human input form token | Yes | string |
#### Request Body
@ -389,24 +395,32 @@ Request body:
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Success | **application/json**: [HumanInputFormSubmitResponse](#humaninputformsubmitresponse)<br> |
| 200 | Form submitted successfully | **application/json**: [HumanInputFormSubmitResponse](#humaninputformsubmitresponse)<br> |
| 400 | Bad request - invalid submission data | |
| 404 | Form not found | |
| 412 | Form already submitted or expired | |
| 429 | Too many requests | |
### [POST] /form/human_input/{form_token}/upload-token
**Issue an upload token for a human input form**
Issue an upload token for an active human input form
POST /api/form/human_input/<form_token>/upload-token
#### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| form_token | path | | Yes | string |
| form_token | path | Human input form token | Yes | string |
#### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Success | **application/json**: [HumanInputUploadTokenResponse](#humaninputuploadtokenresponse)<br> |
| 200 | Upload token issued successfully | **application/json**: [HumanInputUploadTokenResponse](#humaninputuploadtokenresponse)<br> |
| 404 | Form not found | |
| 412 | Form already submitted or expired | |
| 429 | Too many requests | |
### [POST] /human-input-forms/files
**Upload one local file or remote URL file for a HITL human input form**
@ -752,7 +766,7 @@ Retrieve app site information and configuration.
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Success | **application/json**: [AppSiteInfoResponse](#appsiteinforesponse)<br> |
| 200 | Success | **application/json**: [WebAppSiteResponse](#webappsiteresponse)<br> |
| 400 | Bad Request | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
@ -967,51 +981,6 @@ Returns Server-Sent Events stream.
| ---- | ---- | ----------- | -------- |
| appId | string | Application ID | Yes |
#### AppSiteInfoResponse
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| app_id | string | | Yes |
| can_replace_logo | boolean | | Yes |
| custom_config | object | | No |
| enable_site | boolean | | Yes |
| end_user_id | string | | No |
| model_config | [AppSiteModelConfigResponse](#appsitemodelconfigresponse) | | No |
| plan | string | | No |
| site | [AppSiteResponse](#appsiteresponse) | | Yes |
#### AppSiteModelConfigResponse
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| model | | | Yes |
| more_like_this | | | Yes |
| opening_statement | string | | No |
| pre_prompt | string | | No |
| suggested_questions | | | Yes |
| suggested_questions_after_answer | | | Yes |
| user_input_form | | | Yes |
#### AppSiteResponse
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| chat_color_theme | string | | No |
| chat_color_theme_inverted | boolean | | No |
| copyright | string | | No |
| custom_disclaimer | 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 |
| use_icon_as_answer_icon | boolean | | No |
#### AudioBinaryResponse
| Name | Type | Description | Required |
@ -1260,11 +1229,11 @@ Parsed multipart form fields for HITL uploads.
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| expiration_time | integer | | Yes |
| form_content | | | Yes |
| inputs | | | Yes |
| form_content | string | | Yes |
| inputs | [ [FormInputConfig](#forminputconfig) ] | | Yes |
| resolved_default_values | object | | Yes |
| site | object | | No |
| user_actions | | | Yes |
| site | [WebAppSiteResponse](#webappsiteresponse) | | No |
| user_actions | [ [UserActionConfig](#useractionconfig) ] | | Yes |
#### HumanInputFormSubmissionData
@ -1681,6 +1650,26 @@ in form definiton, or a variable while the workflow is running.
| ---- | ---- | ----------- | -------- |
| protocol | string | | Yes |
#### WebAppCustomConfigResponse
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| remove_webapp_brand | boolean | | Yes |
| replace_webapp_logo | string | | No |
#### WebAppSiteResponse
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| app_id | string | | Yes |
| can_replace_logo | boolean | | Yes |
| custom_config | [WebAppCustomConfigResponse](#webappcustomconfigresponse) | | No |
| enable_site | boolean | | Yes |
| end_user_id | string | | No |
| model_config | [WebModelConfigResponse](#webmodelconfigresponse) | | No |
| plan | string | | Yes |
| site | [WebSiteResponse](#websiteresponse) | | Yes |
#### WebMessageInfiniteScrollPagination
| Name | Type | Description | Required |
@ -1709,6 +1698,38 @@ in form definiton, or a variable while the workflow is running.
| retriever_resources | [ [RetrieverResource](#retrieverresource) ] | | Yes |
| status | string | | Yes |
#### WebModelConfigResponse
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| model | | | No |
| more_like_this | | | No |
| opening_statement | string | | No |
| pre_prompt | string | | No |
| suggested_questions | | | No |
| suggested_questions_after_answer | | | No |
| user_input_form | | | No |
#### WebSiteResponse
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| chat_color_theme | string | | No |
| chat_color_theme_inverted | boolean | | Yes |
| copyright | string | | No |
| custom_disclaimer | string | | No |
| default_language | string | | No |
| description | string | | No |
| icon | string | | No |
| icon_background | string | | No |
| icon_type | string | | No |
| icon_url | string | | Yes |
| privacy_policy | string | | No |
| prompt_public | boolean | | No |
| show_workflow_steps | boolean | | No |
| title | string | | Yes |
| use_icon_as_answer_icon | boolean | | No |
#### WorkflowRunPayload
| Name | Type | Description | Required |

View File

@ -607,7 +607,11 @@ class TestMiscApis:
method = unwrap(api.get)
service = MagicMock()
service.get_recommended_plugins.return_value = [{"id": "p1"}]
recommended_plugins = {
"installed_recommended_plugins": [{"id": "p1"}],
"uninstalled_recommended_plugins": [{"id": "p2"}],
}
service.get_recommended_plugins.return_value = recommended_plugins
user = make_account()
tenant_id = "tenant-1"
@ -619,7 +623,7 @@ class TestMiscApis:
),
):
result = method(api, tenant_id, user)
assert result == [{"id": "p1"}]
assert result == recommended_plugins
service.get_recommended_plugins.assert_called_once_with("all", user, tenant_id)
@ -826,7 +830,7 @@ class TestRagPipelineByIdApi:
result = method(api, pipeline, "old-workflow")
workflow_service.delete_workflow.assert_called_once()
assert result == (None, 204)
assert result == ("", 204)
def test_delete_active_workflow_rejected(self, app: Flask) -> None:
api = RagPipelineByIdApi()

View File

@ -2,21 +2,22 @@
from __future__ import annotations
from types import SimpleNamespace
from unittest.mock import patch
from unittest.mock import MagicMock, patch
import pytest
from flask import Flask
from sqlalchemy.orm import Session
from werkzeug.exceptions import Forbidden
from controllers.web.site import AppSiteApi, AppSiteInfo
from controllers.web.site import AppSiteApi, WebAppSiteResponse, WebModelConfigResponse
from models import Tenant, TenantStatus
from models.model import App, AppMode, CustomizeTokenStrategy, Site
from models.account import TenantCustomConfigDict
from models.model import App, AppMode, AppModelConfig, CustomizeTokenStrategy, EndUser, Site
from services.feature_service import FeatureModel
@pytest.fixture
def app(flask_app_with_containers) -> Flask:
def app(flask_app_with_containers: Flask) -> Flask:
return flask_app_with_containers
@ -41,7 +42,23 @@ def _create_app(db_session: Session, tenant_id: str, *, enable_site: bool = True
def _create_site(db_session: Session, app_id: str) -> Site:
site = Site(
site = _site_model(app_id=app_id)
db_session.add(site)
db_session.commit()
return site
def _end_user(tenant_id: str, app_id: str) -> EndUser:
return EndUser(
tenant_id=tenant_id,
app_id=app_id,
type="browser",
session_id=f"session-{app_id}",
)
def _site_model(*, app_id: str) -> Site:
return Site(
app_id=app_id,
title="Site",
icon_type="emoji",
@ -51,31 +68,30 @@ def _create_site(db_session: Session, app_id: str) -> Site:
default_language="en",
chat_color_theme="light",
chat_color_theme_inverted=False,
custom_disclaimer="",
customize_token_strategy=CustomizeTokenStrategy.NOT_ALLOW,
code=f"code-{app_id[-6:]}",
prompt_public=False,
show_workflow_steps=True,
use_icon_as_answer_icon=False,
)
db_session.add(site)
db_session.commit()
return site
class TestAppSiteApi:
@patch("controllers.web.site.FeatureService.get_features")
def test_happy_path(self, mock_features, app: Flask, db_session_with_containers: Session) -> None:
def test_happy_path(self, mock_features: MagicMock, app: Flask, db_session_with_containers: Session) -> None:
app.config["RESTX_MASK_HEADER"] = "X-Fields"
tenant = _create_tenant(db_session_with_containers)
app_model = _create_app(db_session_with_containers, tenant.id)
_create_site(db_session_with_containers, app_model.id)
end_user = SimpleNamespace(id="eu-1")
mock_features.return_value = SimpleNamespace(can_replace_logo=False)
end_user = _end_user(tenant.id, app_model.id)
mock_features.return_value = FeatureModel(can_replace_logo=False)
with app.test_request_context("/site"):
result = AppSiteApi().get(app_model, end_user)
assert result["app_id"] == app_model.id
assert result["end_user_id"] == end_user.id
assert result["plan"] == "basic"
assert result["enable_site"] is True
@ -83,51 +99,139 @@ class TestAppSiteApi:
app.config["RESTX_MASK_HEADER"] = "X-Fields"
tenant = _create_tenant(db_session_with_containers)
app_model = _create_app(db_session_with_containers, tenant.id)
end_user = SimpleNamespace(id="eu-1")
end_user = _end_user(tenant.id, app_model.id)
with app.test_request_context("/site"):
with pytest.raises(Forbidden):
AppSiteApi().get(app_model, end_user)
@patch("controllers.web.site.FeatureService.get_features")
def test_archived_tenant_raises_forbidden(
self, mock_features, app: Flask, db_session_with_containers: Session
) -> None:
def test_archived_tenant_raises_forbidden(self, app: Flask, db_session_with_containers: Session) -> None:
app.config["RESTX_MASK_HEADER"] = "X-Fields"
tenant = _create_tenant(db_session_with_containers, status=TenantStatus.ARCHIVE)
app_model = _create_app(db_session_with_containers, tenant.id)
_create_site(db_session_with_containers, app_model.id)
end_user = SimpleNamespace(id="eu-1")
mock_features.return_value = SimpleNamespace(can_replace_logo=False)
end_user = _end_user(tenant.id, app_model.id)
with app.test_request_context("/site"):
with pytest.raises(Forbidden):
AppSiteApi().get(app_model, end_user)
class TestAppSiteInfo:
def _tenant_model(*, plan: str = "basic", custom_config: TenantCustomConfigDict | None = None) -> Tenant:
tenant = Tenant(name="test-tenant", plan=plan)
tenant.custom_config_dict = custom_config or {}
return tenant
def _app_model(*, tenant: Tenant, enable_site: bool = True) -> App:
app_model = App(
tenant_id=tenant.id,
mode=AppMode.CHAT,
name="test-app",
enable_site=enable_site,
enable_api=True,
)
app_model.id = "app-test"
return app_model
class TestWebAppSiteResponse:
def test_basic_fields(self) -> None:
tenant = SimpleNamespace(id="tenant-1", plan="basic", custom_config_dict={})
site_obj = SimpleNamespace()
info = AppSiteInfo(tenant, SimpleNamespace(id="app-1", enable_site=True), site_obj, "eu-1", False)
assert info.app_id == "app-1"
assert info.end_user_id == "eu-1"
assert info.enable_site is True
assert info.plan == "basic"
assert info.can_replace_logo is False
assert info.model_config is None
@patch("controllers.web.site.dify_config", SimpleNamespace(FILES_URL="https://files.example.com"))
def test_can_replace_logo_sets_custom_config(self) -> None:
tenant = SimpleNamespace(
id="tenant-1",
plan="pro",
custom_config_dict={"remove_webapp_brand": True, "replace_webapp_logo": True},
tenant = _tenant_model()
app_model = _app_model(tenant=tenant)
response = WebAppSiteResponse.from_app_site(
tenant=tenant,
app_model=app_model,
site=_site_model(app_id=app_model.id),
end_user_id="eu-1",
can_replace_logo=False,
)
site_obj = SimpleNamespace()
info = AppSiteInfo(tenant, SimpleNamespace(id="app-1", enable_site=True), site_obj, "eu-1", True)
assert info.can_replace_logo is True
assert info.custom_config["remove_webapp_brand"] is True
assert "webapp-logo" in info.custom_config["replace_webapp_logo"]
assert response.app_id == app_model.id
assert response.end_user_id == "eu-1"
assert response.enable_site is True
assert response.plan == "basic"
assert response.can_replace_logo is False
assert response.model_config_ is None
assert response.custom_config is None
assert response.site.custom_disclaimer == ""
def test_nullable_site_fields_preserve_none(self) -> None:
tenant = _tenant_model()
app_model = _app_model(tenant=tenant)
site = _site_model(app_id=app_model.id)
site.chat_color_theme = None
site.icon_type = None
site.icon = None
site.icon_background = None
site.description = None
site.copyright = None
site.privacy_policy = None
response = WebAppSiteResponse.from_app_site(
tenant=tenant,
app_model=app_model,
site=site,
end_user_id=None,
can_replace_logo=False,
)
dumped = response.model_dump(mode="json")
assert dumped["end_user_id"] is None
assert dumped["site"]["chat_color_theme"] is None
assert dumped["site"]["icon_type"] is None
assert dumped["site"]["icon"] is None
assert dumped["site"]["icon_background"] is None
assert dumped["site"]["description"] is None
assert dumped["site"]["copyright"] is None
assert dumped["site"]["privacy_policy"] is None
assert dumped["site"]["custom_disclaimer"] == ""
@patch("controllers.web.site.dify_config.FILES_URL", "https://files.example.com")
def test_can_replace_logo_sets_custom_config(self) -> None:
tenant = _tenant_model(
plan="pro",
custom_config={"remove_webapp_brand": True, "replace_webapp_logo": "enabled"},
)
app_model = _app_model(tenant=tenant)
response = WebAppSiteResponse.from_app_site(
tenant=tenant,
app_model=app_model,
site=_site_model(app_id=app_model.id),
end_user_id="eu-1",
can_replace_logo=True,
)
assert response.can_replace_logo is True
assert response.custom_config is not None
assert response.custom_config.remove_webapp_brand is True
assert response.custom_config.replace_webapp_logo is not None
assert "webapp-logo" in response.custom_config.replace_webapp_logo
class TestWebModelConfigResponse:
def test_serializes_internal_model_config_properties_to_public_keys(self) -> None:
model_config = AppModelConfig(
app_id="app-test",
opening_statement="Hello",
suggested_questions='["Question?"]',
suggested_questions_after_answer='{"enabled": true}',
more_like_this='{"enabled": false}',
model='{"provider": "openai", "name": "gpt-4o", "mode": "chat"}',
user_input_form='[{"text-input": {"label": "Name", "variable": "name", "required": true}}]',
pre_prompt="System prompt",
created_by="account-1",
updated_by="account-1",
)
dumped = WebModelConfigResponse.model_validate(model_config, from_attributes=True).model_dump(mode="json")
assert dumped == {
"opening_statement": "Hello",
"suggested_questions": ["Question?"],
"suggested_questions_after_answer": {"enabled": True},
"more_like_this": {"enabled": False},
"model": {"provider": "openai", "name": "gpt-4o", "mode": "chat"},
"user_input_form": [{"text-input": {"label": "Name", "variable": "name", "required": True}}],
"pre_prompt": "System prompt",
}

View File

@ -77,9 +77,11 @@ def test_human_input_preview_delegates_to_service(
preview_payload = {
"form_id": "node-42",
"node_id": "node-42",
"node_title": "Human Input",
"form_content": "<div>example</div>",
"inputs": [{"name": "topic"}],
"actions": [{"id": "continue"}],
"actions": [{"id": "continue", "title": "Continue"}],
}
service_instance = MagicMock()
service_instance.get_human_input_form_preview.return_value = preview_payload
@ -88,7 +90,15 @@ def test_human_input_preview_delegates_to_service(
with app.test_request_context(case.path, method="POST", json={"inputs": {"topic": "tech"}}):
response = case.resource_cls().post(app_id=app_model.id, node_id="node-42")
assert response == preview_payload
assert response == {
**preview_payload,
"TYPE": "human_input_required",
"actions": [{"id": "continue", "title": "Continue", "button_style": "default"}],
"resolved_default_values": {},
"display_in_ui": False,
"form_token": None,
"expiration_time": None,
}
service_instance.get_human_input_form_preview.assert_called_once_with(
app_model=app_model,
account=account,

View File

@ -1,4 +1,6 @@
import inspect
from types import SimpleNamespace
from typing import Any
from unittest.mock import MagicMock, PropertyMock, patch
import pytest
@ -16,6 +18,7 @@ from controllers.console.datasets.external import (
ExternalDatasetCreateApi,
ExternalKnowledgeHitTestingApi,
)
from extensions.ext_database import db
from models.account import Account, TenantAccountRole
from services.dataset_service import DatasetService
from services.external_knowledge_service import ExternalDatasetService
@ -38,28 +41,183 @@ def current_user() -> Account:
return user
def _external_api_dict(api_id: str = "api-1") -> dict:
return {
"id": api_id,
"tenant_id": "tenant-1",
"name": f"External API {api_id}",
"description": f"Description for {api_id}",
"settings": {
"endpoint": f"https://external.example.com/{api_id}",
"api_key": "secret",
"headers": {"X-Source": "unit-test"},
"timeout": 30,
},
"dataset_bindings": [
{"id": f"dataset-{api_id}", "name": f"Dataset {api_id}"},
],
"created_by": "user-1",
"created_at": "2024-01-01T00:00:00",
}
def _external_api_object(api_id: str = "api-1") -> SimpleNamespace:
payload = _external_api_dict(api_id)
return SimpleNamespace(
**{
**payload,
"dataset_bindings": [SimpleNamespace(**binding) for binding in payload["dataset_bindings"]],
}
)
def _expected_dataset_detail_payload() -> dict[str, Any]:
return {
"id": "dataset-1",
"name": "Support knowledge",
"description": "External support articles",
"provider": "external",
"permission": "only_me",
"data_source_type": "external",
"indexing_technique": "economy",
"app_count": 2,
"document_count": 7,
"word_count": 2048,
"created_by": "user-1",
"author_name": "Test User",
"created_at": 1710000000,
"updated_by": "user-2",
"updated_at": 1710003600,
"embedding_model": None,
"embedding_model_provider": None,
"embedding_available": False,
"retrieval_model_dict": {
"search_method": "semantic_search",
"reranking_enable": False,
"reranking_mode": None,
"reranking_model": {"reranking_provider_name": None, "reranking_model_name": None},
"weights": None,
"top_k": 4,
"score_threshold_enabled": True,
"score_threshold": 0.5,
},
"summary_index_setting": {
"enable": True,
"model_name": "summary-model",
"model_provider_name": "provider-a",
"summary_prompt": "Summarize this.",
},
"tags": [{"id": "tag-1", "name": "Support", "type": "knowledge"}],
"doc_form": "text_model",
"external_knowledge_info": {
"external_knowledge_id": "knowledge-1",
"external_knowledge_api_id": "api-1",
"external_knowledge_api_name": "External API api-1",
"external_knowledge_api_endpoint": "https://external.example.com/api-1",
},
"external_retrieval_model": {
"top_k": 4,
"score_threshold": 0.5,
"score_threshold_enabled": True,
},
"doc_metadata": [{"id": "metadata-1", "name": "source", "type": "string"}],
"built_in_field_enabled": True,
"pipeline_id": None,
"runtime_mode": "external",
"chunk_structure": "general",
"icon_info": {
"icon_type": "emoji",
"icon": "book",
"icon_background": "#FFF4ED",
"icon_url": None,
},
"is_published": True,
"total_documents": 7,
"total_available_documents": 6,
"enable_api": True,
"is_multimodal": False,
"maintainer": None,
"permission_keys": [],
}
def _dataset_detail_object() -> SimpleNamespace:
payload = _expected_dataset_detail_payload()
return SimpleNamespace(
**{
**payload,
"summary_index_setting": SimpleNamespace(**payload["summary_index_setting"]),
"tags": [SimpleNamespace(**tag) for tag in payload["tags"]],
"external_knowledge_info": SimpleNamespace(**payload["external_knowledge_info"]),
"external_retrieval_model": SimpleNamespace(**payload["external_retrieval_model"]),
"doc_metadata": [SimpleNamespace(**item) for item in payload["doc_metadata"]],
"icon_info": SimpleNamespace(**payload["icon_info"]),
}
)
class TestExternalApiTemplateListApi:
def test_get_success(self, app: Flask):
api = ExternalApiTemplateListApi()
method = inspect.unwrap(api.get)
api_item = MagicMock()
api_item.to_dict.return_value = {"id": "1"}
api_item = _external_api_object("api-1")
with (
app.test_request_context("/?page=1&limit=20"),
app.test_request_context("/?page=2&limit=1&keyword=vector"),
patch.object(
ExternalDatasetService,
"get_external_knowledge_apis",
return_value=([api_item], 1),
return_value=([api_item], 3),
) as get_external_knowledge_apis,
):
resp, status = method(api, "tenant-1")
assert status == 200
assert resp["total"] == 1
assert resp["data"][0]["id"] == "1"
get_external_knowledge_apis.assert_called_once_with(1, 20, "tenant-1", None)
assert resp == {
"data": [_external_api_dict("api-1")],
"has_more": True,
"limit": 1,
"total": 3,
"page": 2,
}
get_external_knowledge_apis.assert_called_once_with(2, 1, "tenant-1", "vector")
def test_post_success_uses_validated_payload_and_returns_template(self, app: Flask, current_user: Account):
api = ExternalApiTemplateListApi()
method = inspect.unwrap(api.post)
payload = {
"name": "Vendor Search",
"settings": {
"endpoint": "https://external.example.com/search",
"api_key": "secret",
"headers": {"X-Source": "unit-test"},
"timeout": 30,
},
}
created = _external_api_object("api-created")
with (
app.test_request_context("/", json=payload),
patch.object(type(console_ns), "payload", new_callable=PropertyMock, return_value=payload),
patch.object(ExternalDatasetService, "validate_api_list") as validate_api_list,
patch.object(
ExternalDatasetService,
"create_external_knowledge_api",
return_value=created,
) as create_external_knowledge_api,
):
resp, status = method(api, "tenant-1", current_user)
assert status == 201
assert resp == _external_api_dict("api-created")
validate_api_list.assert_called_once_with(payload["settings"])
create_external_knowledge_api.assert_called_once_with(
tenant_id="tenant-1",
user_id="user-1",
args=payload,
)
def test_post_forbidden(self, app: Flask, current_user: Account):
current_user.role = TenantAccountRole.NORMAL
@ -97,6 +255,25 @@ class TestExternalApiTemplateListApi:
class TestExternalApiTemplateApi:
def test_get_success_returns_template_contract(self, app: Flask):
api = ExternalApiTemplateApi()
method = inspect.unwrap(api.get)
template = _external_api_object("api-detail")
with (
app.test_request_context("/"),
patch.object(
ExternalDatasetService,
"get_external_knowledge_api",
return_value=template,
) as get_external_knowledge_api,
):
resp, status = method(api, "tenant-1", "api-detail")
assert status == 200
assert resp == _external_api_dict("api-detail")
get_external_knowledge_api.assert_called_once_with("api-detail", "tenant-1")
def test_get_not_found(self, app: Flask):
api = ExternalApiTemplateApi()
method = inspect.unwrap(api.get)
@ -112,6 +289,42 @@ class TestExternalApiTemplateApi:
with pytest.raises(NotFound):
method(api, "tenant-1", "api-id")
def test_patch_success_uses_validated_payload_and_returns_template(self, app: Flask, current_user: Account):
api = ExternalApiTemplateApi()
method = inspect.unwrap(api.patch)
payload = {
"name": "Updated API",
"settings": {
"endpoint": "https://external.example.com/updated",
"api_key": "new-secret",
"headers": {"X-Version": "2"},
},
}
updated = _external_api_object("api-updated")
with (
app.test_request_context("/", json=payload),
patch.object(type(console_ns), "payload", new_callable=PropertyMock, return_value=payload),
patch.object(ExternalDatasetService, "validate_api_list") as validate_api_list,
patch.object(
ExternalDatasetService,
"update_external_knowledge_api",
return_value=updated,
) as update_external_knowledge_api,
):
resp, status = method(api, "tenant-1", current_user, "api-updated")
assert status == 200
assert resp == _external_api_dict("api-updated")
validate_api_list.assert_called_once_with(payload["settings"])
update_external_knowledge_api.assert_called_once_with(
tenant_id="tenant-1",
user_id="user-1",
external_knowledge_api_id="api-updated",
args=payload,
)
def test_delete_forbidden(self, app: Flask, current_user: Account):
current_user.role = TenantAccountRole.NORMAL
@ -149,45 +362,37 @@ class TestExternalDatasetCreateApi:
method = inspect.unwrap(api.post)
payload = {
"external_knowledge_api_id": "api",
"external_knowledge_id": "kid",
"name": "dataset",
"external_knowledge_api_id": "api-1",
"external_knowledge_id": "knowledge-1",
"name": "Support knowledge",
"description": "External support articles",
"external_retrieval_model": {
"top_k": 4,
"score_threshold": 0.5,
"score_threshold_enabled": True,
},
}
dataset = MagicMock()
dataset.embedding_available = False
dataset.built_in_field_enabled = False
dataset.is_published = False
dataset.enable_api = False
dataset.enable_qa = False
dataset.enable_vector_store = False
dataset.vector_store_setting = None
dataset.is_multimodal = False
dataset.retrieval_model_dict = {}
dataset.tags = []
dataset.external_knowledge_info = None
dataset.external_retrieval_model = None
dataset.doc_metadata = []
dataset.icon_info = None
dataset.permission_keys = []
dataset.summary_index_setting = MagicMock()
dataset.summary_index_setting.enable = False
dataset = _dataset_detail_object()
with (
app.test_request_context("/"),
app.test_request_context("/", json=payload),
patch.object(type(console_ns), "payload", new_callable=PropertyMock, return_value=payload),
patch.object(
ExternalDatasetService,
"create_external_dataset",
return_value=dataset,
),
) as create_external_dataset,
):
_, status = method(api, "tenant-1", current_user)
resp, status = method(api, "tenant-1", current_user)
assert status == 201
assert resp == _expected_dataset_detail_payload()
create_external_dataset.assert_called_once_with(
tenant_id="tenant-1",
user_id="user-1",
args=payload,
)
def test_create_forbidden(self, app: Flask, current_user: Account):
current_user.role = TenantAccountRole.NORMAL
@ -228,24 +433,58 @@ class TestExternalKnowledgeHitTestingApi:
api = ExternalKnowledgeHitTestingApi()
method = inspect.unwrap(api.post)
payload = {"query": "hello"}
payload = {
"query": "hello",
"external_retrieval_model": {
"top_k": 3,
"score_threshold": 0.25,
"score_threshold_enabled": True,
},
"metadata_filtering_conditions": {
"logical_operator": "and",
"conditions": [{"name": "source", "comparison_operator": "contains", "value": "external"}],
},
}
dataset = MagicMock()
retrieve_response = {
"query": {"content": "hello"},
"records": [
{
"content": "answer",
"title": "doc",
"score": 0.9,
"metadata": {"source": "external", "page": 2},
}
],
}
with (
app.test_request_context("/"),
app.test_request_context("/", json=payload),
patch.object(type(console_ns), "payload", new_callable=PropertyMock, return_value=payload),
patch.object(DatasetService, "get_dataset", return_value=dataset),
patch.object(DatasetService, "check_dataset_permission"),
patch.object(DatasetService, "check_dataset_permission") as check_dataset_permission,
patch.object(HitTestingService, "hit_testing_args_check") as hit_testing_args_check,
patch.object(
HitTestingService,
"external_retrieve",
return_value={"ok": True},
),
return_value=retrieve_response,
) as external_retrieve,
patch("controllers.console.datasets.external.dump_response", side_effect=lambda _model, value: value),
):
resp = method(api, current_user, "dataset-id")
assert resp["ok"] is True
assert resp == retrieve_response
check_dataset_permission.assert_called_once_with(dataset, current_user)
hit_testing_args_check.assert_called_once_with(payload)
external_retrieve.assert_called_once_with(
session=db.session,
dataset=dataset,
query="hello",
account=current_user,
external_retrieval_model=payload["external_retrieval_model"],
metadata_filtering_conditions=payload["metadata_filtering_conditions"],
)
class TestBedrockRetrievalApi:
@ -254,24 +493,44 @@ class TestBedrockRetrievalApi:
method = inspect.unwrap(api.post)
payload = {
"retrieval_setting": {},
"query": "hello",
"knowledge_id": "kid",
"retrieval_setting": {"top_k": 5, "score_threshold": 0.72},
"query": "hello bedrock",
"knowledge_id": "knowledge-base-1",
}
retrieval_response = {
"records": [
{
"metadata": {"source": "bedrock", "uri": "s3://bucket/doc.txt"},
"score": 0.8,
"title": "doc",
"content": "answer",
},
{
"metadata": {"source": "bedrock", "uri": "s3://bucket/other.txt"},
"score": 0.65,
"title": None,
"content": None,
},
]
}
with (
app.test_request_context("/"),
app.test_request_context("/", json=payload),
patch.object(type(console_ns), "payload", new_callable=PropertyMock, return_value=payload),
patch.object(
ExternalDatasetTestService,
"knowledge_retrieval",
return_value={"ok": True},
),
return_value=retrieval_response,
) as knowledge_retrieval,
):
resp, status = method()
assert status == 200
assert resp["ok"] is True
assert resp == retrieval_response
retrieval_setting, query, knowledge_id = knowledge_retrieval.call_args.args
assert retrieval_setting.model_dump() == payload["retrieval_setting"]
assert query == "hello bedrock"
assert knowledge_id == "knowledge-base-1"
class TestExternalApiTemplateListApiAdvanced:
@ -297,10 +556,10 @@ class TestExternalApiTemplateListApiAdvanced:
api = ExternalApiTemplateListApi()
method = inspect.unwrap(api.get)
templates = [MagicMock(id=f"api-{i}") for i in range(3)]
templates = [_external_api_object(f"api-{i}") for i in range(3)]
with (
app.test_request_context("/?page=1&limit=20"),
app.test_request_context("/?page=2&limit=3"),
patch(
"controllers.console.datasets.external.ExternalDatasetService.get_external_knowledge_apis",
return_value=(templates, 25),
@ -309,9 +568,14 @@ class TestExternalApiTemplateListApiAdvanced:
resp, status = method(api, "tenant-1")
assert status == 200
assert resp["total"] == 25
assert len(resp["data"]) == 3
get_external_knowledge_apis.assert_called_once_with(1, 20, "tenant-1", None)
assert resp == {
"data": [_external_api_dict(f"api-{i}") for i in range(3)],
"has_more": True,
"limit": 3,
"total": 25,
"page": 2,
}
get_external_knowledge_apis.assert_called_once_with(2, 3, "tenant-1", None)
class TestExternalDatasetCreateApiAdvanced:
@ -374,15 +638,46 @@ class TestExternalKnowledgeHitTestingApiAdvanced:
"controllers.console.datasets.external.DatasetService.get_dataset",
return_value=dataset,
),
patch("controllers.console.datasets.external.DatasetService.check_dataset_permission"),
patch("controllers.console.datasets.external.DatasetService.check_dataset_permission") as check_permission,
patch("controllers.console.datasets.external.HitTestingService.hit_testing_args_check") as args_check,
patch(
"controllers.console.datasets.external.HitTestingService.external_retrieve",
return_value={"results": []},
),
return_value={
"query": {"content": "test query"},
"records": [
{
"content": None,
"title": "metadata-only",
"score": None,
"metadata": {"status": "active"},
}
],
},
) as external_retrieve,
):
resp = method(api, current_user, "ds-1")
assert resp["results"] == []
assert resp == {
"query": {"content": "test query"},
"records": [
{
"content": None,
"title": "metadata-only",
"score": None,
"metadata": {"status": "active"},
}
],
}
check_permission.assert_called_once_with(dataset, current_user)
args_check.assert_called_once_with(payload)
external_retrieve.assert_called_once_with(
session=db.session,
dataset=dataset,
query="test query",
account=current_user,
external_retrieval_model={"type": "bm25"},
metadata_filtering_conditions={"status": "active"},
)
class TestBedrockRetrievalApiAdvanced:

View File

@ -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)

View File

@ -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",

View File

@ -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()

View File

@ -325,10 +325,12 @@ class TestPipelineRunApiEntity:
def test_entity_missing_required_field(self):
"""Test entity raises on missing required field."""
with pytest.raises(ValueError):
PipelineRunApiEntity(
inputs={},
datasource_type="online_document",
# missing datasource_info_list, start_node_id, etc.
PipelineRunApiEntity.model_validate(
{
"inputs": {},
"datasource_type": "online_document",
# missing datasource_info_list, start_node_id, etc.
}
)
@ -382,8 +384,19 @@ class TestDatasourcePluginsApiGet:
mock_dataset = Mock()
mock_db.session.scalar.return_value = mock_dataset
datasource_plugins = [
{
"node_id": "node-datasource-1",
"plugin_id": "plugin-a",
"provider_name": "provider-a",
"datasource_type": "online_document",
"title": "Online Docs",
"user_input_variables": [{"variable": "url", "label": "URL", "type": "text-input", "required": True}],
"credentials": [{"id": "cred-1", "name": "Default credential", "type": "oauth2", "is_default": True}],
}
]
mock_svc_instance = Mock()
mock_svc_instance.get_datasource_plugins.return_value = [{"name": "plugin_a"}]
mock_svc_instance.get_datasource_plugins.return_value = datasource_plugins
mock_svc_cls.return_value = mock_svc_instance
with app.test_request_context("/datasets/test/pipeline/datasource-plugins?is_published=true"):
@ -391,11 +404,33 @@ class TestDatasourcePluginsApiGet:
response, status = api.get(tenant_id=tenant_id, dataset_id=dataset_id)
assert status == 200
assert response == [{"name": "plugin_a"}]
assert response == datasource_plugins
mock_svc_instance.get_datasource_plugins.assert_called_once_with(
tenant_id=tenant_id, dataset_id=dataset_id, is_published=True
)
@patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.db")
@patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.RagPipelineService")
def test_get_plugins_parses_false_is_published_query(self, mock_svc_cls, mock_db, app: Flask):
"""Test false query string is parsed as boolean False."""
tenant_id = str(uuid.uuid4())
dataset_id = str(uuid.uuid4())
mock_db.session.scalar.return_value = Mock()
mock_svc_instance = Mock()
mock_svc_instance.get_datasource_plugins.return_value = []
mock_svc_cls.return_value = mock_svc_instance
with app.test_request_context("/datasets/test/pipeline/datasource-plugins?is_published=false"):
api = DatasourcePluginsApi()
response, status = api.get(tenant_id=tenant_id, dataset_id=dataset_id)
assert status == 200
assert response == []
mock_svc_instance.get_datasource_plugins.assert_called_once_with(
tenant_id=tenant_id, dataset_id=dataset_id, is_published=False
)
@patch("controllers.service_api.dataset.rag_pipeline.rag_pipeline_workflow.db")
def test_get_plugins_not_found(self, mock_db, app: Flask):
"""Test NotFound when dataset check fails."""

View File

@ -2,7 +2,6 @@
from __future__ import annotations
import json
from datetime import UTC, datetime
from types import SimpleNamespace
from typing import Any
@ -112,7 +111,7 @@ def test_get_form_includes_site(monkeypatch: pytest.MonkeyPatch, app: Flask):
chat_color_theme_inverted=False,
copyright=None,
privacy_policy=None,
custom_disclaimer=None,
custom_disclaimer="",
prompt_public=False,
show_workflow_steps=True,
use_icon_as_answer_icon=False,
@ -138,7 +137,7 @@ def test_get_form_includes_site(monkeypatch: pytest.MonkeyPatch, app: Flask):
with app.test_request_context("/api/form/human_input/token-1", method="GET"):
response = HumanInputFormApi().get("token-1")
body = json.loads(response.get_data(as_text=True))
body = response
assert set(body.keys()) == {
"site",
"form_content",
@ -167,7 +166,7 @@ def test_get_form_includes_site(monkeypatch: pytest.MonkeyPatch, app: Flask):
"description": "desc",
"copyright": None,
"privacy_policy": None,
"custom_disclaimer": None,
"custom_disclaimer": "",
"default_language": "en",
"prompt_public": False,
"show_workflow_steps": True,
@ -256,7 +255,7 @@ def test_get_form_uses_runtime_select_options(monkeypatch: pytest.MonkeyPatch, a
chat_color_theme_inverted=False,
copyright=None,
privacy_policy=None,
custom_disclaimer=None,
custom_disclaimer="",
prompt_public=False,
show_workflow_steps=True,
use_icon_as_answer_icon=False,
@ -277,7 +276,7 @@ def test_get_form_uses_runtime_select_options(monkeypatch: pytest.MonkeyPatch, a
with app.test_request_context("/api/form/human_input/token-1", method="GET"):
response = HumanInputFormApi().get("token-1")
body = json.loads(response.get_data(as_text=True))
body = response
assert body["inputs"] == [input_config.model_dump(mode="json") for input_config in runtime_inputs]
service_mock.resolve_form_inputs.assert_called_once_with(form)
@ -380,7 +379,7 @@ def test_get_form_allows_backstage_token(monkeypatch: pytest.MonkeyPatch, app: F
chat_color_theme_inverted=False,
copyright=None,
privacy_policy=None,
custom_disclaimer=None,
custom_disclaimer="",
prompt_public=False,
show_workflow_steps=True,
use_icon_as_answer_icon=False,
@ -403,7 +402,7 @@ def test_get_form_allows_backstage_token(monkeypatch: pytest.MonkeyPatch, app: F
with app.test_request_context("/api/form/human_input/token-1", method="GET"):
response = HumanInputFormApi().get("token-1")
body = json.loads(response.get_data(as_text=True))
body = response
assert set(body.keys()) == {
"site",
"form_content",
@ -432,7 +431,7 @@ def test_get_form_allows_backstage_token(monkeypatch: pytest.MonkeyPatch, app: F
"description": "desc",
"copyright": None,
"privacy_policy": None,
"custom_disclaimer": None,
"custom_disclaimer": "",
"default_language": "en",
"prompt_public": False,
"show_workflow_steps": True,

View File

@ -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"

View File

@ -1,8 +1,9 @@
from datetime import datetime
from typing import Any, cast
import pytest
from libs.helper import OptionalTimestampField, escape_like_pattern, extract_tenant_id
from libs.helper import escape_like_pattern, extract_tenant_id, to_timestamp
from models.account import Account
from models.model import EndUser
@ -42,7 +43,7 @@ class TestExtractTenantId:
"""Test extracting tenant_id from EndUser without tenant_id."""
# Create a mock EndUser object
end_user = EndUser()
end_user.tenant_id = None
cast(Any, end_user).tenant_id = None
tenant_id = extract_tenant_id(end_user)
assert tenant_id is None
@ -52,32 +53,29 @@ class TestExtractTenantId:
invalid_user = "not_a_user_object"
with pytest.raises(ValueError, match="Invalid user type.*Expected Account or EndUser"):
extract_tenant_id(invalid_user)
extract_tenant_id(cast(Any, invalid_user))
def test_extract_tenant_id_with_none_user(self):
"""Test extracting tenant_id with None user raises ValueError."""
with pytest.raises(ValueError, match="Invalid user type.*Expected Account or EndUser"):
extract_tenant_id(None)
extract_tenant_id(cast(Any, None))
def test_extract_tenant_id_with_dict_user(self):
"""Test extracting tenant_id with dict user raises ValueError."""
dict_user = {"id": "123", "tenant_id": "456"}
with pytest.raises(ValueError, match="Invalid user type.*Expected Account or EndUser"):
extract_tenant_id(dict_user)
extract_tenant_id(cast(Any, dict_user))
class TestOptionalTimestampField:
class TestToTimestamp:
def test_format_returns_none_for_none(self):
field = OptionalTimestampField()
assert field.format(None) is None
assert to_timestamp(None) is None
def test_format_returns_unix_timestamp_for_datetime(self):
field = OptionalTimestampField()
value = datetime(2024, 1, 2, 3, 4, 5)
assert field.format(value) == int(value.timestamp())
assert to_timestamp(value) == int(value.timestamp())
class TestEscapeLikePattern:
@ -111,7 +109,7 @@ class TestEscapeLikePattern:
def test_escape_none_handling(self):
"""Test escaping None returns None (falsy check handles it)."""
# The function checks `if not pattern`, so None is falsy and returns as-is
result = escape_like_pattern(None)
result = escape_like_pattern(cast(Any, None))
assert result is None
def test_escape_normal_string_no_change(self):

View File

@ -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
@ -140,7 +140,7 @@ export type AccountIntegrateResponse = {
provider: string
}
export type AccountWritable = {
export type AccountResponseWritable = {
avatar?: string | null
created_at?: number | null
email: string
@ -177,7 +177,7 @@ export type PostAccountAvatarData = {
}
export type PostAccountAvatarResponses = {
200: Account
200: AccountResponse
}
export type PostAccountAvatarResponse = PostAccountAvatarResponses[keyof PostAccountAvatarResponses]
@ -218,7 +218,7 @@ export type PostAccountChangeEmailResetData = {
}
export type PostAccountChangeEmailResetResponses = {
200: Account
200: AccountResponse
}
export type PostAccountChangeEmailResetResponse
@ -374,7 +374,7 @@ export type PostAccountInterfaceLanguageData = {
}
export type PostAccountInterfaceLanguageResponses = {
200: Account
200: AccountResponse
}
export type PostAccountInterfaceLanguageResponse
@ -388,7 +388,7 @@ export type PostAccountInterfaceThemeData = {
}
export type PostAccountInterfaceThemeResponses = {
200: Account
200: AccountResponse
}
export type PostAccountInterfaceThemeResponse
@ -402,7 +402,7 @@ export type PostAccountNameData = {
}
export type PostAccountNameResponses = {
200: Account
200: AccountResponse
}
export type PostAccountNameResponse = PostAccountNameResponses[keyof PostAccountNameResponses]
@ -415,7 +415,7 @@ export type PostAccountPasswordData = {
}
export type PostAccountPasswordResponses = {
200: Account
200: AccountResponse
}
export type PostAccountPasswordResponse
@ -429,7 +429,7 @@ export type GetAccountProfileData = {
}
export type GetAccountProfileResponses = {
200: Account
200: AccountResponse
}
export type GetAccountProfileResponse = GetAccountProfileResponses[keyof GetAccountProfileResponses]
@ -442,7 +442,7 @@ export type PostAccountTimezoneData = {
}
export type PostAccountTimezoneResponses = {
200: Account
200: AccountResponse
}
export type PostAccountTimezoneResponse

View File

@ -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(),
@ -212,9 +212,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 +242,7 @@ export const zPostAccountAvatarBody = zAccountAvatarPayload
/**
* Success
*/
export const zPostAccountAvatarResponse = zAccount
export const zPostAccountAvatarResponse = zAccountResponse
export const zPostAccountChangeEmailBody = zChangeEmailSendPayload
@ -263,7 +263,7 @@ export const zPostAccountChangeEmailResetBody = zChangeEmailResetPayload
/**
* Success
*/
export const zPostAccountChangeEmailResetResponse = zAccount
export const zPostAccountChangeEmailResetResponse = zAccountResponse
export const zPostAccountChangeEmailValidityBody = zChangeEmailValidityPayload
@ -336,37 +336,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

View File

@ -269,6 +269,7 @@ export type MessageDetailResponse = {
agent_thoughts?: Array<AgentThought>
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<MessageFile>
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 = {
@ -436,16 +454,7 @@ export type Tag = {
type: string
}
export type JsonValue
= | string
| number
| number
| boolean
| {
[key: string]: unknown
}
| Array<unknown>
| null
export type JsonValue = unknown
export type WorkflowPartial = {
created_at?: number | null
@ -723,7 +732,6 @@ export type AgentThought = {
created_at?: number | null
files: Array<string>
id: string
message_chain_id?: string | null
message_id: string
observation?: string | null
position: number
@ -743,8 +751,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 +887,6 @@ export type AgentAppPublishedReferenceResponse = {
app_name: string
}
export type LlmMode = 'chat' | 'completion'
export type AgentKind = 'dify_agent'
export type AgentPublishedReferenceResponse = {

View File

@ -218,16 +218,37 @@ export const zTag = z.object({
type: z.string(),
})
export const zJsonValue = z
.union([
z.string(),
z.int(),
z.number(),
z.boolean(),
z.record(z.string(), z.unknown()),
z.array(z.unknown()),
])
.nullable()
export const zJsonValue = z.unknown()
/**
* 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 +261,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 +628,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 +830,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 +1059,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 +2038,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 +2052,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(),
})

View File

@ -4,7 +4,7 @@ export type ClientOptions = {
baseUrl: `${string}://${string}/console/api` | (string & {})
}
export type WorkspaceListResponse = {
export type WorkspacePaginationResponse = {
data: Array<WorkspaceListItemResponse>
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]

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -119,10 +119,9 @@ export type HumanInputFormPreviewPayload = {
}
export type HumanInputFormPreviewResponse = {
actions?: Array<{
[key: string]: unknown
}>
display_in_ui?: boolean | null
TYPE?: 'human_input_required'
actions?: Array<HumanInputUserActionResponse>
display_in_ui?: boolean
expiration_time?: number | null
form_content: string
form_id: string
@ -137,46 +136,6 @@ export type HumanInputFormPreviewResponse = {
}
}
export type HumanInputFormSubmitPayload = {
action: string
form_inputs: {
[key: string]: unknown
}
inputs: {
[key: string]: unknown
}
}
export type HumanInputFormSubmitResponse = {
[key: string]: unknown
}
export type IterationNodeRunPayload = {
inputs?: {
[key: string]: unknown
} | null
}
export type GeneratedAppResponse = JsonValue
export type LoopNodeRunPayload = {
inputs?: {
[key: string]: unknown
} | null
}
export type AdvancedChatWorkflowRunPayload = {
conversation_id?: string | null
files?: Array<{
[key: string]: unknown
}> | null
inputs?: {
[key: string]: unknown
} | null
parent_message_id?: string | null
query?: string
}
export type AgentDriveListResponse = {
items?: Array<AgentDriveItemResponse>
}
@ -422,6 +381,8 @@ export type CompletionMessagePayload = {
retriever_from?: string
}
export type GeneratedAppResponse = JsonValue
export type PaginatedConversationVariableResponse = {
data: Array<ConversationVariableResponse>
has_more: boolean
@ -472,6 +433,7 @@ export type MessageDetailResponse = {
agent_thoughts?: Array<AgentThought>
annotation?: ConversationAnnotation | null
annotation_hit_history?: ConversationAnnotationHitHistory | null
answer: string
answer_tokens?: number | null
conversation_id: string
created_at?: number | null
@ -487,12 +449,11 @@ export type MessageDetailResponse = {
}
message?: JsonValue | null
message_files?: Array<MessageFile>
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 +692,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 +760,7 @@ export type WorkflowCommentCreate = {
}
export type WorkflowCommentMentionUsersPayload = {
users: Array<AccountWithRole>
users: Array<AccountWithRoleResponse>
}
export type WorkflowCommentDetail = {
@ -876,18 +837,10 @@ export type WorkflowPaginationResponse = {
page: number
}
export type DefaultBlockConfigsResponse = Array<{
[key: string]: unknown
}>
export type DefaultBlockConfigResponse = {
[key: string]: unknown
}
export type WorkflowResponse = {
conversation_variables: Array<WorkflowConversationVariableResponse>
created_at: number
created_by?: SimpleAccount | null
created_by?: SimpleAccountResponse | null
environment_variables: Array<WorkflowEnvironmentVariableResponse>
features: {
[key: string]: unknown
@ -902,7 +855,7 @@ export type WorkflowResponse = {
rag_pipeline_variables: Array<PipelineVariableResponse>
tool_published: boolean
updated_at: number
updated_by?: SimpleAccount | null
updated_by?: SimpleAccountResponse | null
version: string
}
@ -923,9 +876,9 @@ export type SyncDraftWorkflowPayload = {
}
export type SyncDraftWorkflowResponse = {
hash?: string
result?: string
updated_at?: string
hash: string
result: string
updated_at: number
}
export type WorkflowDraftVariableList = {
@ -961,7 +914,7 @@ export type HumanInputDeliveryTestPayload = {
}
}
export type EmptyObjectResponse = {
export type HumanInputDeliveryTestResponse = {
[key: string]: unknown
}
@ -1029,7 +982,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
@ -1062,17 +1015,6 @@ export type DraftWorkflowNodeRunPayload = {
query?: string
}
export type DraftWorkflowRunPayload = {
datasource_info_list: Array<{
[key: string]: unknown
}>
datasource_type: string
inputs: {
[key: string]: unknown
}
start_node_id: string
}
export type WorkflowRunSnapshotView = {
node_outputs?: Array<NodeOutputsView>
workflow_run_id: string
@ -1099,14 +1041,6 @@ export type OutputPreviewView = {
value?: unknown
}
export type DraftWorkflowTriggerRunRequest = {
node_id: string
}
export type DraftWorkflowTriggerRunAllPayload = {
node_ids: Array<string>
}
export type WorkflowDraftVariableListWithoutValue = {
items?: Array<WorkflowDraftVariableWithoutValue>
total?: number
@ -1143,12 +1077,11 @@ export type WorkflowDraftVariableUpdatePayload = {
}
export type PublishWorkflowPayload = {
knowledge_base_setting?: {
[key: string]: unknown
} | null
marked_comment?: string | null
marked_name?: string | null
}
export type WorkflowPublishResponse = {
export type PublishWorkflowResponse = {
created_at: number
result: string
}
@ -1167,12 +1100,6 @@ export type WorkflowUpdatePayload = {
marked_name?: string | null
}
export type WorkflowRestoreResponse = {
hash: string
result: string
updated_at: number
}
export type ApiKeyList = {
data: Array<ApiKeyItem>
}
@ -1223,12 +1150,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 = {
@ -1254,16 +1199,7 @@ export type Tag = {
type: string
}
export type JsonValue
= | string
| number
| number
| boolean
| {
[key: string]: unknown
}
| Array<unknown>
| null
export type JsonValue = unknown
export type WorkflowPartial = {
created_at?: number | null
@ -1289,7 +1225,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
@ -1302,6 +1238,12 @@ export type AdvancedChatWorkflowRunForListResponse = {
version?: string | null
}
export type HumanInputUserActionResponse = {
button_style?: string
id: string
title: string
}
export type AgentDriveItemResponse = {
created_at?: number | null
file_kind: string
@ -1498,7 +1440,6 @@ export type AgentThought = {
created_at?: number | null
files: Array<string>
id: string
message_chain_id?: string | null
message_id: string
observation?: string | null
position: number
@ -1518,8 +1459,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 +1537,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 +1548,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 +1557,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 +1569,7 @@ export type WorkflowRunForListResponse = {
version?: string | null
}
export type SimpleAccount = {
export type SimpleAccountResponse = {
email: string
id: string
name: string
@ -1671,7 +1612,7 @@ export type WorkflowCommentBasic = {
updated_at?: number | null
}
export type AccountWithRole = {
export type AccountWithRoleResponse = {
avatar?: string | null
created_at?: number | null
email: string
@ -1982,8 +1923,6 @@ export type ModelConfigPartial = {
updated_by?: string | null
}
export type LlmMode = 'chat' | 'completion'
export type Type = 'github' | 'marketplace' | 'package'
export type Github = {
@ -2054,6 +1993,12 @@ export type SimpleMessageDetail = {
query: string
}
export type SimpleAccount = {
email: string
id: string
name: string
}
export type HumanInputFormDefinition = {
actions?: Array<UserActionConfig>
display_in_ui?: boolean
@ -2654,6 +2599,10 @@ export type WorkflowCommentDetailWritable = {
updated_at?: number | null
}
export type HumanInputDeliveryTestResponseWritable = {
[key: string]: unknown
}
export type AppPartialWritable = {
access_mode?: string | null
app_id?: string | null
@ -2999,88 +2948,6 @@ export type PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdForm
export type PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponse
= PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponses[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponses]
export type PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunData = {
body: HumanInputFormSubmitPayload
path: {
app_id: string
node_id: string
}
query?: never
url: '/apps/{app_id}/advanced-chat/workflows/draft/human-input/nodes/{node_id}/form/run'
}
export type PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunResponses = {
200: HumanInputFormSubmitResponse
}
export type PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunResponse
= PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunResponses[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunResponses]
export type PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunData = {
body: IterationNodeRunPayload
path: {
app_id: string
node_id: string
}
query?: never
url: '/apps/{app_id}/advanced-chat/workflows/draft/iteration/nodes/{node_id}/run'
}
export type PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunErrors = {
403: unknown
404: unknown
}
export type PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunResponses = {
200: GeneratedAppResponse
}
export type PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunResponse
= PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunResponses[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunResponses]
export type PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunData = {
body: LoopNodeRunPayload
path: {
app_id: string
node_id: string
}
query?: never
url: '/apps/{app_id}/advanced-chat/workflows/draft/loop/nodes/{node_id}/run'
}
export type PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunErrors = {
403: unknown
404: unknown
}
export type PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunResponses = {
200: GeneratedAppResponse
}
export type PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunResponse
= PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunResponses[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunResponses]
export type PostAppsByAppIdAdvancedChatWorkflowsDraftRunData = {
body: AdvancedChatWorkflowRunPayload
path: {
app_id: string
}
query?: never
url: '/apps/{app_id}/advanced-chat/workflows/draft/run'
}
export type PostAppsByAppIdAdvancedChatWorkflowsDraftRunErrors = {
400: unknown
403: unknown
}
export type PostAppsByAppIdAdvancedChatWorkflowsDraftRunResponses = {
200: GeneratedAppResponse
}
export type PostAppsByAppIdAdvancedChatWorkflowsDraftRunResponse
= PostAppsByAppIdAdvancedChatWorkflowsDraftRunResponses[keyof PostAppsByAppIdAdvancedChatWorkflowsDraftRunResponses]
export type GetAppsByAppIdAgentDriveFilesData = {
body?: never
path: {
@ -5114,45 +4981,6 @@ export type GetAppsByAppIdWorkflowsResponses = {
export type GetAppsByAppIdWorkflowsResponse
= GetAppsByAppIdWorkflowsResponses[keyof GetAppsByAppIdWorkflowsResponses]
export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsData = {
body?: never
path: {
app_id: string
}
query?: never
url: '/apps/{app_id}/workflows/default-workflow-block-configs'
}
export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsResponses = {
200: DefaultBlockConfigsResponse
}
export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsResponse
= GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsResponses[keyof GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsResponses]
export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeData = {
body?: never
path: {
app_id: string
block_type: string
}
query?: {
q?: string
}
url: '/apps/{app_id}/workflows/default-workflow-block-configs/{block_type}'
}
export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeErrors = {
404: unknown
}
export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponses = {
200: DefaultBlockConfigResponse
}
export type GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse
= GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponses[keyof GetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponses]
export type GetAppsByAppIdWorkflowsDraftData = {
body?: never
path: {
@ -5293,7 +5121,7 @@ export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestData
}
export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestResponses = {
200: EmptyObjectResponse
200: HumanInputDeliveryTestResponse
}
export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestResponse
@ -5316,67 +5144,6 @@ export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewRespo
export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponse
= PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponses[keyof PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponses]
export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunData = {
body: HumanInputFormSubmitPayload
path: {
app_id: string
node_id: string
}
query?: never
url: '/apps/{app_id}/workflows/draft/human-input/nodes/{node_id}/form/run'
}
export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunResponses = {
200: HumanInputFormSubmitResponse
}
export type PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunResponse
= PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunResponses[keyof PostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunResponses]
export type PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunData = {
body: IterationNodeRunPayload
path: {
app_id: string
node_id: string
}
query?: never
url: '/apps/{app_id}/workflows/draft/iteration/nodes/{node_id}/run'
}
export type PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunErrors = {
403: unknown
404: unknown
}
export type PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunResponses = {
200: GeneratedAppResponse
}
export type PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunResponse
= PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunResponses[keyof PostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunResponses]
export type PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunData = {
body: LoopNodeRunPayload
path: {
app_id: string
node_id: string
}
query?: never
url: '/apps/{app_id}/workflows/draft/loop/nodes/{node_id}/run'
}
export type PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunErrors = {
403: unknown
404: unknown
}
export type PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunResponses = {
200: GeneratedAppResponse
}
export type PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunResponse
= PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunResponses[keyof PostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunResponses]
export type GetAppsByAppIdWorkflowsDraftNodesByNodeIdAgentComposerData = {
body?: never
path: {
@ -5556,7 +5323,7 @@ export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunErrors = {
}
export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunResponses = {
200: GeneratedAppResponse
200: WorkflowRunNodeExecutionResponse
}
export type PostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunResponse
@ -5596,26 +5363,6 @@ export type GetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponses = {
export type GetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponse
= GetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponses[keyof GetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponses]
export type PostAppsByAppIdWorkflowsDraftRunData = {
body: DraftWorkflowRunPayload
path: {
app_id: string
}
query?: never
url: '/apps/{app_id}/workflows/draft/run'
}
export type PostAppsByAppIdWorkflowsDraftRunErrors = {
403: unknown
}
export type PostAppsByAppIdWorkflowsDraftRunResponses = {
200: GeneratedAppResponse
}
export type PostAppsByAppIdWorkflowsDraftRunResponse
= PostAppsByAppIdWorkflowsDraftRunResponses[keyof PostAppsByAppIdWorkflowsDraftRunResponses]
export type GetAppsByAppIdWorkflowsDraftRunsByRunIdNodeOutputsData = {
body?: never
path: {
@ -5720,48 +5467,6 @@ export type GetAppsByAppIdWorkflowsDraftSystemVariablesResponses = {
export type GetAppsByAppIdWorkflowsDraftSystemVariablesResponse
= GetAppsByAppIdWorkflowsDraftSystemVariablesResponses[keyof GetAppsByAppIdWorkflowsDraftSystemVariablesResponses]
export type PostAppsByAppIdWorkflowsDraftTriggerRunData = {
body: DraftWorkflowTriggerRunRequest
path: {
app_id: string
}
query?: never
url: '/apps/{app_id}/workflows/draft/trigger/run'
}
export type PostAppsByAppIdWorkflowsDraftTriggerRunErrors = {
403: unknown
500: unknown
}
export type PostAppsByAppIdWorkflowsDraftTriggerRunResponses = {
200: GeneratedAppResponse
}
export type PostAppsByAppIdWorkflowsDraftTriggerRunResponse
= PostAppsByAppIdWorkflowsDraftTriggerRunResponses[keyof PostAppsByAppIdWorkflowsDraftTriggerRunResponses]
export type PostAppsByAppIdWorkflowsDraftTriggerRunAllData = {
body: DraftWorkflowTriggerRunAllPayload
path: {
app_id: string
}
query?: never
url: '/apps/{app_id}/workflows/draft/trigger/run-all'
}
export type PostAppsByAppIdWorkflowsDraftTriggerRunAllErrors = {
403: unknown
500: unknown
}
export type PostAppsByAppIdWorkflowsDraftTriggerRunAllResponses = {
200: GeneratedAppResponse
}
export type PostAppsByAppIdWorkflowsDraftTriggerRunAllResponse
= PostAppsByAppIdWorkflowsDraftTriggerRunAllResponses[keyof PostAppsByAppIdWorkflowsDraftTriggerRunAllResponses]
export type DeleteAppsByAppIdWorkflowsDraftVariablesData = {
body?: never
path: {
@ -5908,7 +5613,7 @@ export type PostAppsByAppIdWorkflowsPublishData = {
}
export type PostAppsByAppIdWorkflowsPublishResponses = {
200: WorkflowPublishResponse
200: PublishWorkflowResponse
}
export type PostAppsByAppIdWorkflowsPublishResponse
@ -6077,7 +5782,7 @@ export type PostAppsByAppIdWorkflowsByWorkflowIdRestoreErrors = {
}
export type PostAppsByAppIdWorkflowsByWorkflowIdRestoreResponses = {
200: WorkflowRestoreResponse
200: SyncDraftWorkflowResponse
}
export type PostAppsByAppIdWorkflowsByWorkflowIdRestoreResponse

View File

@ -43,61 +43,6 @@ export const zHumanInputFormPreviewPayload = z.object({
inputs: z.record(z.string(), z.unknown()).optional(),
})
/**
* HumanInputFormPreviewResponse
*/
export const zHumanInputFormPreviewResponse = z.object({
actions: z.array(z.record(z.string(), z.unknown())).optional(),
display_in_ui: z.boolean().nullish(),
expiration_time: z.int().nullish(),
form_content: z.string(),
form_id: z.string(),
form_token: z.string().nullish(),
inputs: z.array(z.record(z.string(), z.unknown())).optional(),
node_id: z.string(),
node_title: z.string(),
resolved_default_values: z.record(z.string(), z.unknown()).optional(),
})
/**
* HumanInputFormSubmitPayload
*/
export const zHumanInputFormSubmitPayload = z.object({
action: z.string(),
form_inputs: z.record(z.string(), z.unknown()),
inputs: z.record(z.string(), z.unknown()),
})
/**
* HumanInputFormSubmitResponse
*/
export const zHumanInputFormSubmitResponse = z.record(z.string(), z.unknown())
/**
* IterationNodeRunPayload
*/
export const zIterationNodeRunPayload = z.object({
inputs: z.record(z.string(), z.unknown()).nullish(),
})
/**
* LoopNodeRunPayload
*/
export const zLoopNodeRunPayload = z.object({
inputs: z.record(z.string(), z.unknown()).nullish(),
})
/**
* AdvancedChatWorkflowRunPayload
*/
export const zAdvancedChatWorkflowRunPayload = z.object({
conversation_id: z.string().nullish(),
files: z.array(z.record(z.string(), z.unknown())).nullish(),
inputs: z.record(z.string(), z.unknown()).nullish(),
parent_message_id: z.string().nullish(),
query: z.string().optional().default(''),
})
/**
* AgentDriveDownloadResponse
*/
@ -581,16 +526,6 @@ export const zWorkflowCommentResolve = z.object({
resolved_by: z.string().nullish(),
})
/**
* DefaultBlockConfigsResponse
*/
export const zDefaultBlockConfigsResponse = z.array(z.record(z.string(), z.unknown()))
/**
* DefaultBlockConfigResponse
*/
export const zDefaultBlockConfigResponse = z.record(z.string(), z.unknown())
/**
* SyncDraftWorkflowPayload
*/
@ -602,10 +537,13 @@ export const zSyncDraftWorkflowPayload = z.object({
hash: z.string().nullish(),
})
/**
* SyncDraftWorkflowResponse
*/
export const zSyncDraftWorkflowResponse = z.object({
hash: z.string().optional(),
result: z.string().optional(),
updated_at: z.string().optional(),
hash: z.string(),
result: z.string(),
updated_at: z.int(),
})
/**
@ -638,9 +576,9 @@ export const zHumanInputDeliveryTestPayload = z.object({
})
/**
* EmptyObjectResponse
* HumanInputDeliveryTestResponse
*/
export const zEmptyObjectResponse = z.record(z.string(), z.unknown())
export const zHumanInputDeliveryTestResponse = z.record(z.string(), z.unknown())
/**
* WorkflowComposerCopyFromRosterPayload
@ -660,32 +598,11 @@ export const zDraftWorkflowNodeRunPayload = z.object({
query: z.string().optional().default(''),
})
/**
* DraftWorkflowRunPayload
*/
export const zDraftWorkflowRunPayload = z.object({
datasource_info_list: z.array(z.record(z.string(), z.unknown())),
datasource_type: z.string(),
inputs: z.record(z.string(), z.unknown()),
start_node_id: z.string(),
})
/**
* EventStreamResponse
*/
export const zEventStreamResponse = z.string()
export const zDraftWorkflowTriggerRunRequest = z.object({
node_id: z.string(),
})
/**
* DraftWorkflowTriggerRunAllPayload
*/
export const zDraftWorkflowTriggerRunAllPayload = z.object({
node_ids: z.array(z.string()),
})
export const zWorkflowDraftVariable = z.object({
description: z.string().optional(),
edited: z.boolean().optional(),
@ -723,17 +640,16 @@ export const zWorkflowDraftVariableUpdatePayload = z.object({
/**
* PublishWorkflowPayload
*
* Payload for publishing snippet workflow.
*/
export const zPublishWorkflowPayload = z.object({
knowledge_base_setting: z.record(z.string(), z.unknown()).nullish(),
marked_comment: z.string().max(100).nullish(),
marked_name: z.string().max(20).nullish(),
})
/**
* WorkflowPublishResponse
* PublishWorkflowResponse
*/
export const zWorkflowPublishResponse = z.object({
export const zPublishWorkflowResponse = z.object({
created_at: z.int(),
result: z.string(),
})
@ -758,15 +674,6 @@ export const zWorkflowUpdatePayload = z.object({
marked_name: z.string().max(20).nullish(),
})
/**
* WorkflowRestoreResponse
*/
export const zWorkflowRestoreResponse = z.object({
hash: z.string(),
result: z.string(),
updated_at: z.int(),
})
/**
* ApiKeyItem
*/
@ -873,22 +780,43 @@ export const zTag = z.object({
type: z.string(),
})
export const zJsonValue = z
.union([
z.string(),
z.int(),
z.number(),
z.boolean(),
z.record(z.string(), z.unknown()),
z.array(z.unknown()),
])
.nullable()
export const zJsonValue = z.unknown()
/**
* GeneratedAppResponse
*/
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 +828,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
*/
@ -919,6 +907,32 @@ export const zImport = z.object({
status: zImportStatus,
})
/**
* HumanInputUserActionResponse
*/
export const zHumanInputUserActionResponse = z.object({
button_style: z.string().optional().default('default'),
id: z.string(),
title: z.string(),
})
/**
* HumanInputFormPreviewResponse
*/
export const zHumanInputFormPreviewResponse = z.object({
TYPE: z.literal('human_input_required').optional().default('human_input_required'),
actions: z.array(zHumanInputUserActionResponse).optional(),
display_in_ui: z.boolean().optional().default(false),
expiration_time: z.int().nullish(),
form_content: z.string(),
form_id: z.string(),
form_token: z.string().nullish(),
inputs: z.array(z.record(z.string(), z.unknown())).optional(),
node_id: z.string(),
node_title: z.string(),
resolved_default_values: z.record(z.string(), z.unknown()).optional(),
})
/**
* AgentDriveItemResponse
*/
@ -1118,6 +1132,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 +1183,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 +1351,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 +1365,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 +1387,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 +1428,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 +1450,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,9 +1516,9 @@ export const zSandboxUploadResponse = z.object({
})
/**
* AccountWithRole
* AccountWithRoleResponse
*/
export const zAccountWithRole = z.object({
export const zAccountWithRoleResponse = z.object({
avatar: z.string().nullish(),
created_at: z.int().nullish(),
email: z.string(),
@ -1563,7 +1535,7 @@ export const zAccountWithRole = z.object({
* WorkflowCommentMentionUsersPayload
*/
export const zWorkflowCommentMentionUsersPayload = z.object({
users: z.array(zAccountWithRole),
users: z.array(zAccountWithRoleResponse),
})
/**
@ -1752,7 +1724,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 +1735,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,116 +2028,6 @@ 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
*/
@ -2366,6 +2228,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 +2280,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 +2370,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 +2406,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 +3400,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 +3414,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(),
})
@ -3492,6 +3437,11 @@ export const zMessageInfiniteScrollPaginationResponse = z.object({
*/
export const zGeneratedAppResponseWritable = zJsonValue
/**
* HumanInputDeliveryTestResponse
*/
export const zHumanInputDeliveryTestResponseWritable = z.record(z.string(), z.unknown())
/**
* AppPartial
*/
@ -3835,65 +3785,11 @@ export const zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFo
})
/**
* Human input form preview
* Human input form preview retrieved
*/
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponse
= zHumanInputFormPreviewResponse
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunBody
= zHumanInputFormSubmitPayload
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunPath
= z.object({
app_id: z.uuid(),
node_id: z.string(),
})
/**
* Human input form submission result
*/
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftHumanInputNodesByNodeIdFormRunResponse
= zHumanInputFormSubmitResponse
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunBody
= zIterationNodeRunPayload
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunPath = z.object({
app_id: z.uuid(),
node_id: z.string(),
})
/**
* Iteration node run started successfully
*/
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftIterationNodesByNodeIdRunResponse
= zGeneratedAppResponse
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunBody
= zLoopNodeRunPayload
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunPath = z.object({
app_id: z.uuid(),
node_id: z.string(),
})
/**
* Loop node run started successfully
*/
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftLoopNodesByNodeIdRunResponse
= zGeneratedAppResponse
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftRunBody = zAdvancedChatWorkflowRunPayload
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftRunPath = z.object({
app_id: z.uuid(),
})
/**
* Workflow run started successfully
*/
export const zPostAppsByAppIdAdvancedChatWorkflowsDraftRunResponse = zGeneratedAppResponse
export const zGetAppsByAppIdAgentDriveFilesPath = z.object({
app_id: z.uuid(),
})
@ -5163,31 +5059,6 @@ export const zGetAppsByAppIdWorkflowsQuery = z.object({
*/
export const zGetAppsByAppIdWorkflowsResponse = zWorkflowPaginationResponse
export const zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsPath = z.object({
app_id: z.uuid(),
})
/**
* Default block configurations retrieved successfully
*/
export const zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsResponse
= zDefaultBlockConfigsResponse
export const zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypePath = z.object({
app_id: z.uuid(),
block_type: z.string(),
})
export const zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeQuery = z.object({
q: z.string().optional(),
})
/**
* Default block configuration retrieved successfully
*/
export const zGetAppsByAppIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse
= zDefaultBlockConfigResponse
export const zGetAppsByAppIdWorkflowsDraftPath = z.object({
app_id: z.uuid(),
})
@ -5271,10 +5142,10 @@ export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestPa
})
/**
* Human input delivery test result
* Human input delivery tested
*/
export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdDeliveryTestResponse
= zEmptyObjectResponse
= zHumanInputDeliveryTestResponse
export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewBody
= zHumanInputFormPreviewPayload
@ -5285,49 +5156,11 @@ export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewPat
})
/**
* Human input form preview
* Human input form preview retrieved
*/
export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormPreviewResponse
= zHumanInputFormPreviewResponse
export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunBody
= zHumanInputFormSubmitPayload
export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunPath = z.object({
app_id: z.uuid(),
node_id: z.string(),
})
/**
* Human input form submission result
*/
export const zPostAppsByAppIdWorkflowsDraftHumanInputNodesByNodeIdFormRunResponse
= zHumanInputFormSubmitResponse
export const zPostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunBody = zIterationNodeRunPayload
export const zPostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunPath = z.object({
app_id: z.uuid(),
node_id: z.string(),
})
/**
* Workflow iteration node run started successfully
*/
export const zPostAppsByAppIdWorkflowsDraftIterationNodesByNodeIdRunResponse = zGeneratedAppResponse
export const zPostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunBody = zLoopNodeRunPayload
export const zPostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunPath = z.object({
app_id: z.uuid(),
node_id: z.string(),
})
/**
* Workflow loop node run started successfully
*/
export const zPostAppsByAppIdWorkflowsDraftLoopNodesByNodeIdRunResponse = zGeneratedAppResponse
export const zGetAppsByAppIdWorkflowsDraftNodesByNodeIdAgentComposerPath = z.object({
app_id: z.uuid(),
node_id: z.string(),
@ -5451,7 +5284,8 @@ export const zPostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunPath = z.objec
/**
* Trigger event received and node executed successfully
*/
export const zPostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunResponse = zGeneratedAppResponse
export const zPostAppsByAppIdWorkflowsDraftNodesByNodeIdTriggerRunResponse
= zWorkflowRunNodeExecutionResponse
export const zDeleteAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesPath = z.object({
app_id: z.uuid(),
@ -5474,17 +5308,6 @@ export const zGetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesPath = z.object(
export const zGetAppsByAppIdWorkflowsDraftNodesByNodeIdVariablesResponse
= zWorkflowDraftVariableList
export const zPostAppsByAppIdWorkflowsDraftRunBody = zDraftWorkflowRunPayload
export const zPostAppsByAppIdWorkflowsDraftRunPath = z.object({
app_id: z.uuid(),
})
/**
* Draft workflow run started successfully
*/
export const zPostAppsByAppIdWorkflowsDraftRunResponse = zGeneratedAppResponse
export const zGetAppsByAppIdWorkflowsDraftRunsByRunIdNodeOutputsPath = z.object({
app_id: z.uuid(),
run_id: z.uuid(),
@ -5540,28 +5363,6 @@ export const zGetAppsByAppIdWorkflowsDraftSystemVariablesPath = z.object({
*/
export const zGetAppsByAppIdWorkflowsDraftSystemVariablesResponse = zWorkflowDraftVariableList
export const zPostAppsByAppIdWorkflowsDraftTriggerRunBody = zDraftWorkflowTriggerRunRequest
export const zPostAppsByAppIdWorkflowsDraftTriggerRunPath = z.object({
app_id: z.uuid(),
})
/**
* Trigger event received and workflow executed successfully
*/
export const zPostAppsByAppIdWorkflowsDraftTriggerRunResponse = zGeneratedAppResponse
export const zPostAppsByAppIdWorkflowsDraftTriggerRunAllBody = zDraftWorkflowTriggerRunAllPayload
export const zPostAppsByAppIdWorkflowsDraftTriggerRunAllPath = z.object({
app_id: z.uuid(),
})
/**
* Workflow executed successfully
*/
export const zPostAppsByAppIdWorkflowsDraftTriggerRunAllResponse = zGeneratedAppResponse
export const zDeleteAppsByAppIdWorkflowsDraftVariablesPath = z.object({
app_id: z.uuid(),
})
@ -5646,7 +5447,7 @@ export const zPostAppsByAppIdWorkflowsPublishPath = z.object({
/**
* Workflow published successfully
*/
export const zPostAppsByAppIdWorkflowsPublishResponse = zWorkflowPublishResponse
export const zPostAppsByAppIdWorkflowsPublishResponse = zPublishWorkflowResponse
export const zGetAppsByAppIdWorkflowsPublishedRunsByRunIdNodeOutputsPath = z.object({
app_id: z.uuid(),
@ -5739,7 +5540,7 @@ export const zPostAppsByAppIdWorkflowsByWorkflowIdRestorePath = z.object({
/**
* Workflow restored successfully
*/
export const zPostAppsByAppIdWorkflowsByWorkflowIdRestoreResponse = zWorkflowRestoreResponse
export const zPostAppsByAppIdWorkflowsByWorkflowIdRestoreResponse = zSyncDraftWorkflowResponse
export const zGetAppsByResourceIdApiKeysPath = z.object({
resource_id: z.uuid(),

View File

@ -359,8 +359,12 @@ export const get5 = oc
.input(z.object({ params: zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdPath }))
.output(zGetDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponse)
/**
* Update external knowledge API template
*/
export const patch = oc
.route({
description: 'Update external knowledge API template',
inputStructure: 'detailed',
method: 'PATCH',
operationId: 'patchDatasetsExternalKnowledgeApiByExternalKnowledgeApiId',
@ -397,8 +401,12 @@ export const get6 = oc
.input(z.object({ query: zGetDatasetsExternalKnowledgeApiQuery.optional() }))
.output(zGetDatasetsExternalKnowledgeApiResponse)
/**
* Create external knowledge API template
*/
export const post4 = oc
.route({
description: 'Create external knowledge API template',
inputStructure: 'detailed',
method: 'POST',
operationId: 'postDatasetsExternalKnowledgeApi',

View File

@ -97,51 +97,12 @@ export type ExternalDatasetCreatePayload = {
name: string
}
export type DatasetDetail = {
app_count?: number
author_name?: string
built_in_field_enabled?: boolean
chunk_structure?: string
created_at?: number
created_by?: string
data_source_type?: string
description?: string
doc_form?: string
doc_metadata?: Array<DatasetDocMetadata>
document_count?: number
embedding_available?: boolean
embedding_model?: string
embedding_model_provider?: string
enable_api?: boolean
external_knowledge_info?: ExternalKnowledgeInfo
external_retrieval_model?: ExternalRetrievalModel
icon_info?: DatasetIconInfo
id?: string
indexing_technique?: string
is_multimodal?: boolean
is_published?: boolean
name?: string
permission?: string
permission_keys?: Array<string>
pipeline_id?: string
provider?: string
retrieval_model_dict?: DatasetRetrievalModel
runtime_mode?: string
summary_index_setting?: AnonymousInlineModelB1954337D565
tags?: Array<Tag>
total_available_documents?: number
total_documents?: number
updated_at?: number
updated_by?: string
word_count?: number
}
export type ExternalKnowledgeApiListResponse = {
data: Array<ExternalKnowledgeApiResponse>
has_more: boolean
limit: number
page: number
total: number
total: number | null
}
export type ExternalKnowledgeApiPayload = {
@ -154,11 +115,11 @@ export type ExternalKnowledgeApiPayload = {
export type ExternalKnowledgeApiResponse = {
created_at: string
created_by: string
dataset_bindings?: Array<ExternalKnowledgeDatasetBindingResponse>
dataset_bindings: Array<ExternalKnowledgeApiBindingResponse>
description: string
id: string
name: string
settings?: {
settings: {
[key: string]: unknown
} | null
tenant_id: string
@ -479,13 +440,10 @@ export type ExternalHitTestingPayload = {
query: string
}
export type ExternalRetrievalTestResponse
= | {
[key: string]: unknown
}
| Array<{
[key: string]: unknown
}>
export type ExternalHitTestingResponse = {
query: ExternalHitTestingQueryResponse
records: Array<ExternalHitTestingRecordResponse>
}
export type HitTestingPayload = {
attachment_ids?: Array<string> | null
@ -641,57 +599,7 @@ export type DatasetTagResponse = {
type: string
}
export type DatasetDocMetadata = {
id?: string
name?: string
type?: string
}
export type ExternalKnowledgeInfo = {
external_knowledge_api_endpoint?: string
external_knowledge_api_id?: string
external_knowledge_api_name?: string
external_knowledge_id?: string
}
export type ExternalRetrievalModel = {
score_threshold?: number
score_threshold_enabled?: boolean
top_k?: number
}
export type DatasetIconInfo = {
icon?: string
icon_background?: string
icon_type?: string
icon_url?: string
}
export type DatasetRetrievalModel = {
reranking_enable?: boolean
reranking_mode?: string
reranking_model?: DatasetRerankingModel
score_threshold?: number
score_threshold_enabled?: boolean
search_method?: string
top_k?: number
weights?: DatasetWeightedScore
}
export type AnonymousInlineModelB1954337D565 = {
enable?: boolean
model_name?: string
model_provider_name?: string
summary_prompt?: string
}
export type Tag = {
id: string
name: string
type: string
}
export type ExternalKnowledgeDatasetBindingResponse = {
export type ExternalKnowledgeApiBindingResponse = {
id: string
name: string
}
@ -844,6 +752,19 @@ export type ChildChunkUpdateArgs = {
id?: string | null
}
export type ExternalHitTestingQueryResponse = {
content: string
}
export type ExternalHitTestingRecordResponse = {
content?: string | null
metadata?: {
[key: string]: unknown
} | null
score?: number | null
title?: string | null
}
export type HitTestingQuery = {
content: string
}
@ -896,17 +817,6 @@ export type DatasetWeightedScoreResponse = {
weight_type?: string | null
}
export type DatasetRerankingModel = {
reranking_model_name?: string
reranking_provider_name?: string
}
export type DatasetWeightedScore = {
keyword_setting?: DatasetKeywordSetting
vector_setting?: DatasetVectorSetting
weight_type?: string
}
export type InfoList = {
data_source_type: 'notion_import' | 'upload_file' | 'website_crawl'
file_info_list?: FileInfo | null
@ -1018,16 +928,6 @@ export type DatasetVectorSettingResponse = {
vector_weight?: number | null
}
export type DatasetKeywordSetting = {
keyword_weight?: number
}
export type DatasetVectorSetting = {
embedding_model_name?: string
embedding_provider_name?: string
vector_weight?: number
}
export type FileInfo = {
file_ids: Array<string>
}
@ -1264,7 +1164,7 @@ export type PostDatasetsExternalErrors = {
}
export type PostDatasetsExternalResponses = {
201: DatasetDetail
201: DatasetDetailResponse
}
export type PostDatasetsExternalResponse
@ -1295,6 +1195,10 @@ export type PostDatasetsExternalKnowledgeApiData = {
url: '/datasets/external-knowledge-api'
}
export type PostDatasetsExternalKnowledgeApiErrors = {
403: unknown
}
export type PostDatasetsExternalKnowledgeApiResponses = {
201: ExternalKnowledgeApiResponse
}
@ -1347,6 +1251,10 @@ export type PatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdData = {
url: '/datasets/external-knowledge-api/{external_knowledge_api_id}'
}
export type PatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdErrors = {
404: unknown
}
export type PatchDatasetsExternalKnowledgeApiByExternalKnowledgeApiIdResponses = {
200: ExternalKnowledgeApiResponse
}
@ -2283,7 +2191,7 @@ export type PostDatasetsByDatasetIdExternalHitTestingErrors = {
}
export type PostDatasetsByDatasetIdExternalHitTestingResponses = {
200: ExternalRetrievalTestResponse
200: ExternalHitTestingResponse
}
export type PostDatasetsByDatasetIdExternalHitTestingResponse

View File

@ -247,14 +247,6 @@ export const zExternalHitTestingPayload = z.object({
query: z.string(),
})
/**
* ExternalRetrievalTestResponse
*/
export const zExternalRetrievalTestResponse = z.union([
z.record(z.string(), z.unknown()),
z.array(z.record(z.string(), z.unknown())),
])
/**
* MetadataArgs
*/
@ -397,52 +389,10 @@ export const zDatasetTagResponse = z.object({
type: z.string(),
})
export const zDatasetDocMetadata = z.object({
id: z.string().optional(),
name: z.string().optional(),
type: z.string().optional(),
})
export const zExternalKnowledgeInfo = z.object({
external_knowledge_api_endpoint: z.string().optional(),
external_knowledge_api_id: z.string().optional(),
external_knowledge_api_name: z.string().optional(),
external_knowledge_id: z.string().optional(),
})
export const zExternalRetrievalModel = z.object({
score_threshold: z.number().optional(),
score_threshold_enabled: z.boolean().optional(),
top_k: z.int().optional(),
})
export const zDatasetIconInfo = z.object({
icon: z.string().optional(),
icon_background: z.string().optional(),
icon_type: z.string().optional(),
icon_url: z.string().optional(),
})
export const zAnonymousInlineModelB1954337D565 = z.object({
enable: z.boolean().optional(),
model_name: z.string().optional(),
model_provider_name: z.string().optional(),
summary_prompt: z.string().optional(),
})
/**
* Tag
* ExternalKnowledgeApiBindingResponse
*/
export const zTag = z.object({
id: z.string(),
name: z.string(),
type: z.string(),
})
/**
* ExternalKnowledgeDatasetBindingResponse
*/
export const zExternalKnowledgeDatasetBindingResponse = z.object({
export const zExternalKnowledgeApiBindingResponse = z.object({
id: z.string(),
name: z.string(),
})
@ -453,11 +403,11 @@ export const zExternalKnowledgeDatasetBindingResponse = z.object({
export const zExternalKnowledgeApiResponse = z.object({
created_at: z.string(),
created_by: z.string(),
dataset_bindings: z.array(zExternalKnowledgeDatasetBindingResponse).optional(),
dataset_bindings: z.array(zExternalKnowledgeApiBindingResponse),
description: z.string(),
id: z.string(),
name: z.string(),
settings: z.record(z.string(), z.unknown()).nullish(),
settings: z.record(z.string(), z.unknown()).nullable(),
tenant_id: z.string(),
})
@ -469,7 +419,7 @@ export const zExternalKnowledgeApiListResponse = z.object({
has_more: z.boolean(),
limit: z.int(),
page: z.int(),
total: z.int(),
total: z.int().nullable(),
})
/**
@ -700,6 +650,31 @@ export const zChildChunkBatchUpdatePayload = z.object({
chunks: z.array(zChildChunkUpdateArgs),
})
/**
* ExternalHitTestingQueryResponse
*/
export const zExternalHitTestingQueryResponse = z.object({
content: z.string(),
})
/**
* ExternalHitTestingRecordResponse
*/
export const zExternalHitTestingRecordResponse = z.object({
content: z.string().nullish(),
metadata: z.record(z.string(), z.unknown()).nullish(),
score: z.number().nullish(),
title: z.string().nullish(),
})
/**
* ExternalHitTestingResponse
*/
export const zExternalHitTestingResponse = z.object({
query: zExternalHitTestingQueryResponse,
records: z.array(zExternalHitTestingRecordResponse),
})
/**
* HitTestingQuery
*/
@ -755,11 +730,6 @@ export const zDatasetRerankingModelResponse = z.object({
reranking_provider_name: z.string().nullish(),
})
export const zDatasetRerankingModel = z.object({
reranking_model_name: z.string().optional(),
reranking_provider_name: z.string().optional(),
})
/**
* ProcessRuleMode
*
@ -1079,88 +1049,6 @@ export const zDatasetListResponse = z.object({
total: z.int(),
})
export const zDatasetKeywordSetting = z.object({
keyword_weight: z.number().optional(),
})
export const zDatasetVectorSetting = z.object({
embedding_model_name: z.string().optional(),
embedding_provider_name: z.string().optional(),
vector_weight: z.number().optional(),
})
export const zDatasetWeightedScore = z.object({
keyword_setting: zDatasetKeywordSetting.optional(),
vector_setting: zDatasetVectorSetting.optional(),
weight_type: z.string().optional(),
})
export const zDatasetRetrievalModel = z.object({
reranking_enable: z.boolean().optional(),
reranking_mode: z.string().optional(),
reranking_model: zDatasetRerankingModel.optional(),
score_threshold: z.number().optional(),
score_threshold_enabled: z.boolean().optional(),
search_method: z.string().optional(),
top_k: z.int().optional(),
weights: zDatasetWeightedScore.optional(),
})
export const zDatasetDetail = z.object({
app_count: z.int().optional(),
author_name: z.string().optional(),
built_in_field_enabled: z.boolean().optional(),
chunk_structure: 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(),
data_source_type: z.string().optional(),
description: z.string().optional(),
doc_form: z.string().optional(),
doc_metadata: z.array(zDatasetDocMetadata).optional(),
document_count: z.int().optional(),
embedding_available: z.boolean().optional(),
embedding_model: z.string().optional(),
embedding_model_provider: z.string().optional(),
enable_api: z.boolean().optional(),
external_knowledge_info: zExternalKnowledgeInfo.optional(),
external_retrieval_model: zExternalRetrievalModel.optional(),
icon_info: zDatasetIconInfo.optional(),
id: z.string().optional(),
indexing_technique: z.string().optional(),
is_multimodal: z.boolean().optional(),
is_published: z.boolean().optional(),
name: z.string().optional(),
permission: z.string().optional(),
permission_keys: z.array(z.string()).optional(),
pipeline_id: z.string().optional(),
provider: z.string().optional(),
retrieval_model_dict: zDatasetRetrievalModel.optional(),
runtime_mode: z.string().optional(),
summary_index_setting: zAnonymousInlineModelB1954337D565.optional(),
tags: z.array(zTag).optional(),
total_available_documents: z.int().optional(),
total_documents: z.int().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(),
word_count: z.int().optional(),
})
/**
* FileInfo
*/
@ -1558,7 +1446,7 @@ export const zPostDatasetsExternalBody = zExternalDatasetCreatePayload
/**
* External dataset created successfully
*/
export const zPostDatasetsExternalResponse = zDatasetDetail
export const zPostDatasetsExternalResponse = zDatasetDetailResponse
export const zGetDatasetsExternalKnowledgeApiQuery = z.object({
keyword: z.string().optional(),
@ -2188,7 +2076,7 @@ export const zPostDatasetsByDatasetIdExternalHitTestingPath = z.object({
/**
* External hit testing completed successfully
*/
export const zPostDatasetsByDatasetIdExternalHitTestingResponse = zExternalRetrievalTestResponse
export const zPostDatasetsByDatasetIdExternalHitTestingResponse = zExternalHitTestingResponse
export const zPostDatasetsByDatasetIdHitTestingBody = zHitTestingPayload

View File

@ -176,16 +176,7 @@ export type InstalledAppResponse = {
uninstallable: boolean
}
export type JsonValue
= | string
| number
| number
| boolean
| {
[key: string]: unknown
}
| Array<unknown>
| null
export type JsonValue = unknown
export type ExploreMessageListItem = {
agent_thoughts: Array<AgentThought>
@ -246,7 +237,6 @@ export type AgentThought = {
created_at?: number | null
files: Array<string>
id: string
message_chain_id?: string | null
message_id: string
observation?: string | null
position: number

View File

@ -156,16 +156,7 @@ export const zWorkflowRunPayload = z.object({
inputs: z.record(z.string(), z.unknown()),
})
export const zJsonValue = z
.union([
z.string(),
z.int(),
z.number(),
z.boolean(),
z.record(z.string(), z.unknown()),
z.array(z.unknown()),
])
.nullable()
export const zJsonValue = z.unknown()
/**
* GeneratedAppResponse
@ -266,7 +257,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(),

View File

@ -25,15 +25,33 @@ 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 = unknown
export type PostInstructionGenerateData = {
body: InstructionGeneratePayload

View File

@ -21,21 +21,36 @@ 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.unknown()
/**
* 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(),
})
/**

View File

@ -24,11 +24,6 @@ import {
zGetRagPipelinesByPipelineIdWorkflowRunsPath,
zGetRagPipelinesByPipelineIdWorkflowRunsQuery,
zGetRagPipelinesByPipelineIdWorkflowRunsResponse,
zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypePath,
zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeQuery,
zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse,
zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsPath,
zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponse,
zGetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesPath,
zGetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponse,
zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunPath,
@ -93,35 +88,17 @@ import {
zPostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestorePath,
zPostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestoreResponse,
zPostRagPipelinesByPipelineIdWorkflowsDraftBody,
zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunBody,
zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunPath,
zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponse,
zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectBody,
zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectPath,
zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectResponse,
zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunBody,
zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunPath,
zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponse,
zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunBody,
zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunPath,
zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponse,
zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunBody,
zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunPath,
zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunResponse,
zPostRagPipelinesByPipelineIdWorkflowsDraftPath,
zPostRagPipelinesByPipelineIdWorkflowsDraftResponse,
zPostRagPipelinesByPipelineIdWorkflowsDraftRunBody,
zPostRagPipelinesByPipelineIdWorkflowsDraftRunPath,
zPostRagPipelinesByPipelineIdWorkflowsDraftRunResponse,
zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewBody,
zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewPath,
zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponse,
zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunBody,
zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunPath,
zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponse,
zPostRagPipelinesByPipelineIdWorkflowsPublishedRunBody,
zPostRagPipelinesByPipelineIdWorkflowsPublishedRunPath,
zPostRagPipelinesByPipelineIdWorkflowsPublishedRunResponse,
zPostRagPipelinesByPipelineIdWorkflowsPublishPath,
zPostRagPipelinesByPipelineIdWorkflowsPublishResponse,
zPostRagPipelinesImportsBody,
@ -506,87 +483,10 @@ export const workflowRuns = {
byRunId,
}
/**
* Get default block config
*/
export const get10 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
operationId: 'getRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockType',
path: '/rag/pipelines/{pipeline_id}/workflows/default-workflow-block-configs/{block_type}',
summary: 'Get default block config',
tags: ['console'],
})
.input(
z.object({
params: zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypePath,
query:
zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeQuery.optional(),
}),
)
.output(zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse)
export const byBlockType = {
get: get10,
}
/**
* Get default block config
*/
export const get11 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
operationId: 'getRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigs',
path: '/rag/pipelines/{pipeline_id}/workflows/default-workflow-block-configs',
summary: 'Get default block config',
tags: ['console'],
})
.input(z.object({ params: zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsPath }))
.output(zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponse)
export const defaultWorkflowBlockConfigs = {
get: get11,
byBlockType,
}
/**
* Run rag pipeline datasource
*/
export const post9 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
operationId: 'postRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRun',
path: '/rag/pipelines/{pipeline_id}/workflows/draft/datasource/nodes/{node_id}/run',
summary: 'Run rag pipeline datasource',
tags: ['console'],
})
.input(
z.object({
body: zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunBody,
params: zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunPath,
}),
)
.output(zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponse)
export const run = {
post: post9,
}
export const byNodeId = {
run,
}
export const nodes = {
byNodeId,
}
/**
* Set datasource variables
*/
export const post10 = oc
export const post9 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
@ -604,18 +504,17 @@ export const post10 = oc
.output(zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectResponse)
export const variablesInspect = {
post: post10,
post: post9,
}
export const datasource = {
nodes,
variablesInspect,
}
/**
* Get draft workflow
*/
export const get12 = oc
export const get10 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -628,82 +527,10 @@ export const get12 = oc
.output(zGetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponse)
export const environmentVariables = {
get: get12,
get: get10,
}
/**
* Run draft workflow iteration node
*/
export const post11 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
operationId: 'postRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRun',
path: '/rag/pipelines/{pipeline_id}/workflows/draft/iteration/nodes/{node_id}/run',
summary: 'Run draft workflow iteration node',
tags: ['console'],
})
.input(
z.object({
body: zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunBody,
params: zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunPath,
}),
)
.output(zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponse)
export const run2 = {
post: post11,
}
export const byNodeId2 = {
run: run2,
}
export const nodes2 = {
byNodeId: byNodeId2,
}
export const iteration = {
nodes: nodes2,
}
/**
* Run draft workflow loop node
*/
export const post12 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
operationId: 'postRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRun',
path: '/rag/pipelines/{pipeline_id}/workflows/draft/loop/nodes/{node_id}/run',
summary: 'Run draft workflow loop node',
tags: ['console'],
})
.input(
z.object({
body: zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunBody,
params: zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunPath,
}),
)
.output(zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponse)
export const run3 = {
post: post12,
}
export const byNodeId3 = {
run: run3,
}
export const nodes3 = {
byNodeId: byNodeId3,
}
export const loop = {
nodes: nodes3,
}
export const get13 = oc
export const get11 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -715,13 +542,13 @@ export const get13 = oc
.output(zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunResponse)
export const lastRun = {
get: get13,
get: get11,
}
/**
* Run draft workflow node
*/
export const post13 = oc
export const post10 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
@ -738,8 +565,8 @@ export const post13 = oc
)
.output(zPostRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdRunResponse)
export const run4 = {
post: post13,
export const run = {
post: post10,
}
export const delete2 = oc
@ -756,7 +583,7 @@ export const delete2 = oc
)
.output(zDeleteRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdVariablesResponse)
export const get14 = oc
export const get12 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -769,23 +596,23 @@ export const get14 = oc
export const variables = {
delete: delete2,
get: get14,
get: get12,
}
export const byNodeId4 = {
export const byNodeId = {
lastRun,
run: run4,
run,
variables,
}
export const nodes4 = {
byNodeId: byNodeId4,
export const nodes = {
byNodeId,
}
/**
* Get first step parameters of rag pipeline
*/
export const get15 = oc
export const get13 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -803,7 +630,7 @@ export const get15 = oc
.output(zGetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersResponse)
export const parameters = {
get: get15,
get: get13,
}
export const preProcessing = {
@ -813,7 +640,7 @@ export const preProcessing = {
/**
* Get second step parameters of rag pipeline
*/
export const get16 = oc
export const get14 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -831,38 +658,14 @@ export const get16 = oc
.output(zGetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponse)
export const parameters2 = {
get: get16,
get: get14,
}
export const processing = {
parameters: parameters2,
}
/**
* Run draft workflow
*/
export const post14 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
operationId: 'postRagPipelinesByPipelineIdWorkflowsDraftRun',
path: '/rag/pipelines/{pipeline_id}/workflows/draft/run',
summary: 'Run draft workflow',
tags: ['console'],
})
.input(
z.object({
body: zPostRagPipelinesByPipelineIdWorkflowsDraftRunBody,
params: zPostRagPipelinesByPipelineIdWorkflowsDraftRunPath,
}),
)
.output(zPostRagPipelinesByPipelineIdWorkflowsDraftRunResponse)
export const run5 = {
post: post14,
}
export const get17 = oc
export const get15 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -874,7 +677,7 @@ export const get17 = oc
.output(zGetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesResponse)
export const systemVariables = {
get: get17,
get: get15,
}
export const put = oc
@ -908,7 +711,7 @@ export const delete3 = oc
)
.output(zDeleteRagPipelinesByPipelineIdWorkflowsDraftVariablesByVariableIdResponse)
export const get18 = oc
export const get16 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -937,7 +740,7 @@ export const patch2 = oc
export const byVariableId = {
delete: delete3,
get: get18,
get: get16,
patch: patch2,
reset,
}
@ -957,7 +760,7 @@ export const delete4 = oc
/**
* Get draft workflow
*/
export const get19 = oc
export const get17 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -976,14 +779,14 @@ export const get19 = oc
export const variables2 = {
delete: delete4,
get: get19,
get: get17,
byVariableId,
}
/**
* Get draft rag pipeline's workflow
*/
export const get20 = oc
export const get18 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -998,7 +801,7 @@ export const get20 = oc
/**
* Sync draft workflow
*/
export const post15 = oc
export const post11 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
@ -1016,16 +819,13 @@ export const post15 = oc
.output(zPostRagPipelinesByPipelineIdWorkflowsDraftResponse)
export const draft = {
get: get20,
post: post15,
get: get18,
post: post11,
datasource,
environmentVariables,
iteration,
loop,
nodes: nodes4,
nodes,
preProcessing,
processing,
run: run5,
systemVariables,
variables: variables2,
}
@ -1033,7 +833,7 @@ export const draft = {
/**
* Get published pipeline
*/
export const get21 = oc
export const get19 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -1048,7 +848,7 @@ export const get21 = oc
/**
* Publish workflow
*/
export const post16 = oc
export const post12 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
@ -1061,14 +861,14 @@ export const post16 = oc
.output(zPostRagPipelinesByPipelineIdWorkflowsPublishResponse)
export const publish2 = {
get: get21,
post: post16,
get: get19,
post: post12,
}
/**
* Run datasource content preview
*/
export const post17 = oc
export const post13 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
@ -1086,50 +886,25 @@ export const post17 = oc
.output(zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponse)
export const preview = {
post: post17,
post: post13,
}
/**
* Run rag pipeline datasource
*/
export const post18 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
operationId: 'postRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRun',
path: '/rag/pipelines/{pipeline_id}/workflows/published/datasource/nodes/{node_id}/run',
summary: 'Run rag pipeline datasource',
tags: ['console'],
})
.input(
z.object({
body: zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunBody,
params: zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunPath,
}),
)
.output(zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponse)
export const run6 = {
post: post18,
}
export const byNodeId5 = {
export const byNodeId2 = {
preview,
run: run6,
}
export const nodes5 = {
byNodeId: byNodeId5,
export const nodes2 = {
byNodeId: byNodeId2,
}
export const datasource2 = {
nodes: nodes5,
nodes: nodes2,
}
/**
* Get first step parameters of rag pipeline
*/
export const get22 = oc
export const get20 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -1147,7 +922,7 @@ export const get22 = oc
.output(zGetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersResponse)
export const parameters3 = {
get: get22,
get: get20,
}
export const preProcessing2 = {
@ -1157,7 +932,7 @@ export const preProcessing2 = {
/**
* Get second step parameters of rag pipeline
*/
export const get23 = oc
export const get21 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -1175,45 +950,20 @@ export const get23 = oc
.output(zGetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponse)
export const parameters4 = {
get: get23,
get: get21,
}
export const processing2 = {
parameters: parameters4,
}
/**
* Run published workflow
*/
export const post19 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
operationId: 'postRagPipelinesByPipelineIdWorkflowsPublishedRun',
path: '/rag/pipelines/{pipeline_id}/workflows/published/run',
summary: 'Run published workflow',
tags: ['console'],
})
.input(
z.object({
body: zPostRagPipelinesByPipelineIdWorkflowsPublishedRunBody,
params: zPostRagPipelinesByPipelineIdWorkflowsPublishedRunPath,
}),
)
.output(zPostRagPipelinesByPipelineIdWorkflowsPublishedRunResponse)
export const run7 = {
post: post19,
}
export const published = {
datasource: datasource2,
preProcessing: preProcessing2,
processing: processing2,
run: run7,
}
export const post20 = oc
export const post14 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
@ -1225,7 +975,7 @@ export const post20 = oc
.output(zPostRagPipelinesByPipelineIdWorkflowsByWorkflowIdRestoreResponse)
export const restore = {
post: post20,
post: post14,
}
/**
@ -1273,7 +1023,7 @@ export const byWorkflowId = {
/**
* Get published workflows
*/
export const get24 = oc
export const get22 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -1291,8 +1041,7 @@ export const get24 = oc
.output(zGetRagPipelinesByPipelineIdWorkflowsResponse)
export const workflows = {
get: get24,
defaultWorkflowBlockConfigs,
get: get22,
draft,
publish: publish2,
published,

View File

@ -89,7 +89,7 @@ export type PipelineTemplateDetailResponse = {
name: string
}
export type RagPipelineOpaqueResponse = unknown
export type DatasourcePluginListResponse = Array<PluginDatasourceProviderEntity>
export type RagPipelineImportPayload = {
description?: string | null
@ -107,6 +107,21 @@ export type RagPipelineImportCheckDependenciesResponse = {
leaked_dependencies?: Array<PluginDependency>
}
export type RagPipelineRecommendedPluginResponse = {
installed_recommended_plugins: Array<{
[key: string]: unknown
}>
uninstalled_recommended_plugins: Array<{
[key: string]: unknown
}>
}
export type RagPipelineTransformResponse = {
dataset_id: string
pipeline_id: string
status: string
}
export type WorkflowRunPaginationResponse = {
data: Array<WorkflowRunForListResponse>
has_more: boolean
@ -119,7 +134,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
@ -147,18 +162,10 @@ export type WorkflowPaginationResponse = {
page: number
}
export type DefaultBlockConfigsResponse = Array<{
[key: string]: unknown
}>
export type DefaultBlockConfigResponse = {
[key: string]: unknown
}
export type WorkflowResponse = {
conversation_variables: Array<WorkflowConversationVariableResponse>
created_at: number
created_by?: SimpleAccount | null
created_by?: SimpleAccountResponse | null
environment_variables: Array<WorkflowEnvironmentVariableResponse>
features: {
[key: string]: unknown
@ -173,7 +180,7 @@ export type WorkflowResponse = {
rag_pipeline_variables: Array<PipelineVariableResponse>
tool_published: boolean
updated_at: number
updated_by?: SimpleAccount | null
updated_by?: SimpleAccountResponse | null
version: string
}
@ -202,14 +209,6 @@ export type RagPipelineWorkflowSyncResponse = {
updated_at: number
}
export type DatasourceNodeRunPayload = {
credential_id?: string | null
datasource_type: string
inputs: {
[key: string]: unknown
}
}
export type DatasourceVariablesPayload = {
datasource_info: {
[key: string]: unknown
@ -221,7 +220,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
@ -248,12 +247,6 @@ export type EnvironmentVariableListResponse = {
items: Array<EnvironmentVariableItemResponse>
}
export type NodeRunPayload = {
inputs?: {
[key: string]: unknown
} | null
}
export type NodeRunRequiredPayload = {
inputs: {
[key: string]: unknown
@ -264,21 +257,10 @@ export type WorkflowDraftVariableList = {
items?: Array<WorkflowDraftVariable>
}
export type RagPipelineStepParametersResponse = {
export type RagPipelineVariablesResponse = {
variables: unknown
}
export type DraftWorkflowRunPayload = {
datasource_info_list: Array<{
[key: string]: unknown
}>
datasource_type: string
inputs: {
[key: string]: unknown
}
start_node_id: string
}
export type WorkflowDraftVariableListWithoutValue = {
items?: Array<WorkflowDraftVariableWithoutValue>
total?: number
@ -329,20 +311,6 @@ export type Parser = {
export type DataSourceContentPreviewResponse = unknown
export type PublishedWorkflowRunPayload = {
datasource_info_list: Array<{
[key: string]: unknown
}>
datasource_type: string
inputs: {
[key: string]: unknown
}
is_preview?: boolean
original_document_id?: string | null
response_mode?: 'blocking' | 'streaming'
start_node_id: string
}
export type WorkflowUpdatePayload = {
marked_comment?: string | null
marked_name?: string | null
@ -413,6 +381,14 @@ export type PipelineTemplateItemResponse = {
privacy_policy?: string | null
}
export type PluginDatasourceProviderEntity = {
declaration: DatasourceProviderEntityWithPlugin
is_authorized?: boolean
plugin_id: string
plugin_unique_identifier: string
provider: string
}
export type PluginDependency = {
current_identifier?: string | null
type: Type
@ -421,7 +397,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 +409,7 @@ export type WorkflowRunForListResponse = {
version?: string | null
}
export type SimpleAccount = {
export type SimpleAccountResponse = {
email: string
id: string
name: string
@ -515,6 +491,14 @@ export type DatasetWeightedScoreResponse = {
weight_type?: string | null
}
export type DatasourceProviderEntityWithPlugin = {
credentials_schema?: Array<ProviderConfig>
datasources?: Array<DatasourceEntity>
identity: DatasourceProviderIdentity
oauth_schema?: OAuthSchema | null
provider_type: DatasourceProviderType
}
export type Type = 'github' | 'marketplace' | 'package'
export type Github = {
@ -544,6 +528,162 @@ export type DatasetVectorSettingResponse = {
vector_weight?: number | null
}
export type ProviderConfig = {
default?: number | string | number | boolean | null
help?: I18nObject | null
label?: I18nObject | null
multiple?: boolean
name: string
options?: Array<Option> | null
placeholder?: I18nObject | null
required?: boolean
scope?: AppSelectorScope | ModelSelectorScope | ToolSelectorScope | null
type: CoreEntitiesProviderEntitiesBasicProviderConfigType
url?: string | null
}
export type DatasourceEntity = {
description: I18nObject
identity: DatasourceIdentity
output_schema?: {
[key: string]: unknown
} | null
parameters?: Array<DatasourceParameter>
}
export type DatasourceProviderIdentity = {
author: string
description: I18nObject
icon: string
label: I18nObject
name: string
tags?: Array<ToolLabelEnum> | null
}
export type OAuthSchema = {
client_schema?: Array<ProviderConfig>
credentials_schema?: Array<ProviderConfig>
}
export type DatasourceProviderType
= | 'local_file'
| 'online_document'
| 'online_drive'
| 'website_crawl'
export type I18nObject = {
en_US: string
ja_JP?: string | null
pt_BR?: string | null
zh_Hans?: string | null
}
export type Option = {
label: I18nObject
value: string
}
export type AppSelectorScope = 'all' | 'chat' | 'completion' | 'workflow'
export type ModelSelectorScope
= | 'llm'
| 'moderation'
| 'rerank'
| 'speech2text'
| 'text-embedding'
| 'tts'
| 'vision'
export type ToolSelectorScope = 'all' | 'builtin' | 'custom' | 'workflow'
export type CoreEntitiesProviderEntitiesBasicProviderConfigType
= | 'app-selector'
| 'array[tools]'
| 'boolean'
| 'model-selector'
| 'secret-input'
| 'select'
| 'text-input'
export type DatasourceIdentity = {
author: string
icon?: string | null
label: I18nObject
name: string
provider: string
}
export type DatasourceParameter = {
auto_generate?: PluginParameterAutoGenerate | null
default?:
| number
| number
| string
| boolean
| Array<unknown>
| {
[key: string]: unknown
}
| null
description: I18nObject
label: I18nObject
max?: number | number | null
min?: number | number | null
name: string
options?: Array<PluginParameterOption>
placeholder?: I18nObject | null
precision?: number | null
required?: boolean
scope?: string | null
template?: PluginParameterTemplate | null
type: DatasourceParameterType
}
export type ToolLabelEnum
= | 'business'
| 'design'
| 'education'
| 'entertainment'
| 'finance'
| 'image'
| 'medical'
| 'news'
| 'other'
| 'productivity'
| 'rag'
| 'search'
| 'social'
| 'travel'
| 'utilities'
| 'videos'
| 'weather'
export type PluginParameterAutoGenerate = {
type: CorePluginEntitiesParametersPluginParameterAutoGenerateType
}
export type PluginParameterOption = {
icon?: string | null
label: I18nObject
value: string
}
export type PluginParameterTemplate = {
enabled?: boolean
}
export type DatasourceParameterType
= | 'boolean'
| 'file'
| 'files'
| 'number'
| 'secret-input'
| 'select'
| 'string'
| 'system-files'
export type CorePluginEntitiesParametersPluginParameterAutoGenerateType = 'prompt_instruction'
export type DeleteRagPipelineCustomizedTemplatesByTemplateIdData = {
body?: never
path: {
@ -663,7 +803,7 @@ export type GetRagPipelinesDatasourcePluginsData = {
}
export type GetRagPipelinesDatasourcePluginsResponses = {
200: RagPipelineOpaqueResponse
200: DatasourcePluginListResponse
}
export type GetRagPipelinesDatasourcePluginsResponse
@ -740,7 +880,7 @@ export type GetRagPipelinesRecommendedPluginsData = {
}
export type GetRagPipelinesRecommendedPluginsResponses = {
200: RagPipelineOpaqueResponse
200: RagPipelineRecommendedPluginResponse
}
export type GetRagPipelinesRecommendedPluginsResponse
@ -756,7 +896,7 @@ export type PostRagPipelinesTransformDatasetsByDatasetIdData = {
}
export type PostRagPipelinesTransformDatasetsByDatasetIdResponses = {
200: RagPipelineOpaqueResponse
200: RagPipelineTransformResponse
}
export type PostRagPipelinesTransformDatasetsByDatasetIdResponse
@ -891,41 +1031,6 @@ export type GetRagPipelinesByPipelineIdWorkflowsResponses = {
export type GetRagPipelinesByPipelineIdWorkflowsResponse
= GetRagPipelinesByPipelineIdWorkflowsResponses[keyof GetRagPipelinesByPipelineIdWorkflowsResponses]
export type GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsData = {
body?: never
path: {
pipeline_id: string
}
query?: never
url: '/rag/pipelines/{pipeline_id}/workflows/default-workflow-block-configs'
}
export type GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponses = {
200: DefaultBlockConfigsResponse
}
export type GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponse
= GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponses]
export type GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeData = {
body?: never
path: {
block_type: string
pipeline_id: string
}
query?: {
q?: string
}
url: '/rag/pipelines/{pipeline_id}/workflows/default-workflow-block-configs/{block_type}'
}
export type GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponses = {
200: DefaultBlockConfigResponse
}
export type GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse
= GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponses]
export type GetRagPipelinesByPipelineIdWorkflowsDraftData = {
body?: never
path: {
@ -962,23 +1067,6 @@ export type PostRagPipelinesByPipelineIdWorkflowsDraftResponses = {
export type PostRagPipelinesByPipelineIdWorkflowsDraftResponse
= PostRagPipelinesByPipelineIdWorkflowsDraftResponses[keyof PostRagPipelinesByPipelineIdWorkflowsDraftResponses]
export type PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunData = {
body: DatasourceNodeRunPayload
path: {
node_id: string
pipeline_id: string
}
query?: never
url: '/rag/pipelines/{pipeline_id}/workflows/draft/datasource/nodes/{node_id}/run'
}
export type PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponses = {
200: RagPipelineOpaqueResponse
}
export type PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponse
= PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponses]
export type PostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectData = {
body: DatasourceVariablesPayload
path: {
@ -1011,40 +1099,6 @@ export type GetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesRespons
export type GetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponse
= GetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponses]
export type PostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunData = {
body: NodeRunPayload
path: {
node_id: string
pipeline_id: string
}
query?: never
url: '/rag/pipelines/{pipeline_id}/workflows/draft/iteration/nodes/{node_id}/run'
}
export type PostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponses = {
200: RagPipelineOpaqueResponse
}
export type PostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponse
= PostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponses]
export type PostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunData = {
body: NodeRunPayload
path: {
node_id: string
pipeline_id: string
}
query?: never
url: '/rag/pipelines/{pipeline_id}/workflows/draft/loop/nodes/{node_id}/run'
}
export type PostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponses = {
200: RagPipelineOpaqueResponse
}
export type PostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponse
= PostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponses]
export type GetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunData = {
body?: never
path: {
@ -1125,7 +1179,7 @@ export type GetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersData
}
export type GetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersResponses = {
200: RagPipelineStepParametersResponse
200: RagPipelineVariablesResponse
}
export type GetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersResponse
@ -1143,28 +1197,12 @@ export type GetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersData =
}
export type GetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponses = {
200: RagPipelineStepParametersResponse
200: RagPipelineVariablesResponse
}
export type GetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponse
= GetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponses[keyof GetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponses]
export type PostRagPipelinesByPipelineIdWorkflowsDraftRunData = {
body: DraftWorkflowRunPayload
path: {
pipeline_id: string
}
query?: never
url: '/rag/pipelines/{pipeline_id}/workflows/draft/run'
}
export type PostRagPipelinesByPipelineIdWorkflowsDraftRunResponses = {
200: RagPipelineOpaqueResponse
}
export type PostRagPipelinesByPipelineIdWorkflowsDraftRunResponse
= PostRagPipelinesByPipelineIdWorkflowsDraftRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsDraftRunResponses]
export type GetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesData = {
body?: never
path: {
@ -1335,23 +1373,6 @@ export type PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeI
export type PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponse
= PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponses[keyof PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponses]
export type PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunData = {
body: DatasourceNodeRunPayload
path: {
node_id: string
pipeline_id: string
}
query?: never
url: '/rag/pipelines/{pipeline_id}/workflows/published/datasource/nodes/{node_id}/run'
}
export type PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponses = {
200: RagPipelineOpaqueResponse
}
export type PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponse
= PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponses]
export type GetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersData = {
body?: never
path: {
@ -1364,7 +1385,7 @@ export type GetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParameters
}
export type GetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersResponses = {
200: RagPipelineStepParametersResponse
200: RagPipelineVariablesResponse
}
export type GetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersResponse
@ -1382,28 +1403,12 @@ export type GetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersDat
}
export type GetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponses = {
200: RagPipelineStepParametersResponse
200: RagPipelineVariablesResponse
}
export type GetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponse
= GetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponses[keyof GetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponses]
export type PostRagPipelinesByPipelineIdWorkflowsPublishedRunData = {
body: PublishedWorkflowRunPayload
path: {
pipeline_id: string
}
query?: never
url: '/rag/pipelines/{pipeline_id}/workflows/published/run'
}
export type PostRagPipelinesByPipelineIdWorkflowsPublishedRunResponses = {
200: RagPipelineOpaqueResponse
}
export type PostRagPipelinesByPipelineIdWorkflowsPublishedRunResponse
= PostRagPipelinesByPipelineIdWorkflowsPublishedRunResponses[keyof PostRagPipelinesByPipelineIdWorkflowsPublishedRunResponses]
export type DeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdData = {
body?: never
path: {

View File

@ -39,11 +39,6 @@ export const zPipelineTemplateDetailResponse = z.object({
name: z.string(),
})
/**
* RagPipelineOpaqueResponse
*/
export const zRagPipelineOpaqueResponse = z.unknown()
/**
* RagPipelineImportPayload
*/
@ -59,6 +54,23 @@ export const zRagPipelineImportPayload = z.object({
yaml_url: z.string().nullish(),
})
/**
* RagPipelineRecommendedPluginResponse
*/
export const zRagPipelineRecommendedPluginResponse = z.object({
installed_recommended_plugins: z.array(z.record(z.string(), z.unknown())),
uninstalled_recommended_plugins: z.array(z.record(z.string(), z.unknown())),
})
/**
* RagPipelineTransformResponse
*/
export const zRagPipelineTransformResponse = z.object({
dataset_id: z.string(),
pipeline_id: z.string(),
status: z.string(),
})
/**
* SimpleResultResponse
*/
@ -66,16 +78,6 @@ export const zSimpleResultResponse = z.object({
result: z.string(),
})
/**
* DefaultBlockConfigsResponse
*/
export const zDefaultBlockConfigsResponse = z.array(z.record(z.string(), z.unknown()))
/**
* DefaultBlockConfigResponse
*/
export const zDefaultBlockConfigResponse = z.record(z.string(), z.unknown())
/**
* DraftWorkflowSyncPayload
*/
@ -97,15 +99,6 @@ export const zRagPipelineWorkflowSyncResponse = z.object({
updated_at: z.int(),
})
/**
* DatasourceNodeRunPayload
*/
export const zDatasourceNodeRunPayload = z.object({
credential_id: z.string().nullish(),
datasource_type: z.string(),
inputs: z.record(z.string(), z.unknown()),
})
/**
* DatasourceVariablesPayload
*/
@ -116,13 +109,6 @@ export const zDatasourceVariablesPayload = z.object({
start_node_title: z.string(),
})
/**
* NodeRunPayload
*/
export const zNodeRunPayload = z.object({
inputs: z.record(z.string(), z.unknown()).nullish(),
})
/**
* NodeRunRequiredPayload
*/
@ -131,22 +117,12 @@ export const zNodeRunRequiredPayload = z.object({
})
/**
* RagPipelineStepParametersResponse
* RagPipelineVariablesResponse
*/
export const zRagPipelineStepParametersResponse = z.object({
export const zRagPipelineVariablesResponse = z.object({
variables: z.unknown(),
})
/**
* DraftWorkflowRunPayload
*/
export const zDraftWorkflowRunPayload = z.object({
datasource_info_list: z.array(z.record(z.string(), z.unknown())),
datasource_type: z.string(),
inputs: z.record(z.string(), z.unknown()),
start_node_id: z.string(),
})
export const zWorkflowDraftVariable = z.object({
description: z.string().optional(),
edited: z.boolean().optional(),
@ -204,19 +180,6 @@ export const zParser = z.object({
*/
export const zDataSourceContentPreviewResponse = z.unknown()
/**
* PublishedWorkflowRunPayload
*/
export const zPublishedWorkflowRunPayload = z.object({
datasource_info_list: z.array(z.record(z.string(), z.unknown())),
datasource_type: z.string(),
inputs: z.record(z.string(), z.unknown()),
is_preview: z.boolean().optional().default(false),
original_document_id: z.string().nullish(),
response_mode: z.enum(['blocking', 'streaming']).optional().default('streaming'),
start_node_id: z.string(),
})
/**
* WorkflowUpdatePayload
*/
@ -322,9 +285,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 +298,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 +334,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 +356,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 +434,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 +445,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(),
})
@ -673,6 +636,263 @@ export const zDatasetDetailResponse = z.object({
word_count: z.int(),
})
/**
* DatasourceProviderType
*
* Enum class for datasource provider
*/
export const zDatasourceProviderType = z.enum([
'local_file',
'online_document',
'online_drive',
'website_crawl',
])
/**
* I18nObject
*
* Model class for i18n object.
*/
export const zI18nObject = z.object({
en_US: z.string(),
ja_JP: z.string().nullish(),
pt_BR: z.string().nullish(),
zh_Hans: z.string().nullish(),
})
/**
* Option
*/
export const zOption = z.object({
label: zI18nObject,
value: z.string(),
})
/**
* AppSelectorScope
*/
export const zAppSelectorScope = z.enum(['all', 'chat', 'completion', 'workflow'])
/**
* ModelSelectorScope
*/
export const zModelSelectorScope = z.enum([
'llm',
'moderation',
'rerank',
'speech2text',
'text-embedding',
'tts',
'vision',
])
/**
* ToolSelectorScope
*/
export const zToolSelectorScope = z.enum(['all', 'builtin', 'custom', 'workflow'])
/**
* Type
*/
export const zCoreEntitiesProviderEntitiesBasicProviderConfigType = z.enum([
'app-selector',
'array[tools]',
'boolean',
'model-selector',
'secret-input',
'select',
'text-input',
])
/**
* ProviderConfig
*
* Model class for common provider settings like credentials
*/
export const zProviderConfig = z.object({
default: z.union([z.int(), z.string(), z.number(), z.boolean()]).nullish(),
help: zI18nObject.nullish(),
label: zI18nObject.nullish(),
multiple: z.boolean().optional().default(false),
name: z.string(),
options: z.array(zOption).nullish(),
placeholder: zI18nObject.nullish(),
required: z.boolean().optional().default(false),
scope: z.union([zAppSelectorScope, zModelSelectorScope, zToolSelectorScope]).nullish(),
type: zCoreEntitiesProviderEntitiesBasicProviderConfigType,
url: z.string().nullish(),
})
/**
* OAuthSchema
*
* OAuth schema
*/
export const zOAuthSchema = z.object({
client_schema: z.array(zProviderConfig).optional(),
credentials_schema: z.array(zProviderConfig).optional(),
})
/**
* DatasourceIdentity
*/
export const zDatasourceIdentity = z.object({
author: z.string(),
icon: z.string().nullish(),
label: zI18nObject,
name: z.string(),
provider: z.string(),
})
/**
* ToolLabelEnum
*/
export const zToolLabelEnum = z.enum([
'business',
'design',
'education',
'entertainment',
'finance',
'image',
'medical',
'news',
'other',
'productivity',
'rag',
'search',
'social',
'travel',
'utilities',
'videos',
'weather',
])
/**
* DatasourceProviderIdentity
*/
export const zDatasourceProviderIdentity = z.object({
author: z.string(),
description: zI18nObject,
icon: z.string(),
label: zI18nObject,
name: z.string(),
tags: z.array(zToolLabelEnum).nullish().default([]),
})
/**
* PluginParameterOption
*/
export const zPluginParameterOption = z.object({
icon: z.string().nullish(),
label: zI18nObject,
value: z.string(),
})
/**
* PluginParameterTemplate
*/
export const zPluginParameterTemplate = z.object({
enabled: z.boolean().optional().default(false),
})
/**
* DatasourceParameterType
*
* removes TOOLS_SELECTOR from PluginParameterType
*/
export const zDatasourceParameterType = z.enum([
'boolean',
'file',
'files',
'number',
'secret-input',
'select',
'string',
'system-files',
])
/**
* Type
*/
export const zCorePluginEntitiesParametersPluginParameterAutoGenerateType = z.enum([
'prompt_instruction',
])
/**
* PluginParameterAutoGenerate
*/
export const zPluginParameterAutoGenerate = z.object({
type: zCorePluginEntitiesParametersPluginParameterAutoGenerateType,
})
/**
* DatasourceParameter
*
* Overrides type
*/
export const zDatasourceParameter = z.object({
auto_generate: zPluginParameterAutoGenerate.nullish(),
default: z
.union([
z.number(),
z.int(),
z.string(),
z.boolean(),
z.array(z.unknown()),
z.record(z.string(), z.unknown()),
])
.nullish(),
description: zI18nObject,
label: zI18nObject,
max: z.union([z.number(), z.int()]).nullish(),
min: z.union([z.number(), z.int()]).nullish(),
name: z.string(),
options: z.array(zPluginParameterOption).optional(),
placeholder: zI18nObject.nullish(),
precision: z.int().nullish(),
required: z.boolean().optional().default(false),
scope: z.string().nullish(),
template: zPluginParameterTemplate.nullish(),
type: zDatasourceParameterType,
})
/**
* DatasourceEntity
*/
export const zDatasourceEntity = z.object({
description: zI18nObject,
identity: zDatasourceIdentity,
output_schema: z.record(z.string(), z.unknown()).nullish(),
parameters: z.array(zDatasourceParameter).optional(),
})
/**
* DatasourceProviderEntityWithPlugin
*/
export const zDatasourceProviderEntityWithPlugin = z.object({
credentials_schema: z.array(zProviderConfig).optional(),
datasources: z.array(zDatasourceEntity).optional(),
identity: zDatasourceProviderIdentity,
oauth_schema: zOAuthSchema.nullish(),
provider_type: zDatasourceProviderType,
})
/**
* PluginDatasourceProviderEntity
*/
export const zPluginDatasourceProviderEntity = z.object({
declaration: zDatasourceProviderEntityWithPlugin,
is_authorized: z.boolean().optional().default(false),
plugin_id: z.string(),
plugin_unique_identifier: z.string(),
provider: z.string(),
})
/**
* DatasourcePluginListResponse
*/
export const zDatasourcePluginListResponse = z.array(zPluginDatasourceProviderEntity)
export const zDeleteRagPipelineCustomizedTemplatesByTemplateIdPath = z.object({
template_id: z.string(),
})
@ -739,9 +959,9 @@ export const zGetRagPipelineTemplatesByTemplateIdQuery = z.object({
export const zGetRagPipelineTemplatesByTemplateIdResponse = zPipelineTemplateDetailResponse
/**
* Success
* Datasource plugins retrieved successfully
*/
export const zGetRagPipelinesDatasourcePluginsResponse = zRagPipelineOpaqueResponse
export const zGetRagPipelinesDatasourcePluginsResponse = zDatasourcePluginListResponse
export const zPostRagPipelinesImportsBody = zRagPipelineImportPayload
@ -774,18 +994,18 @@ export const zGetRagPipelinesRecommendedPluginsQuery = z.object({
})
/**
* Success
* Recommended plugins retrieved successfully
*/
export const zGetRagPipelinesRecommendedPluginsResponse = zRagPipelineOpaqueResponse
export const zGetRagPipelinesRecommendedPluginsResponse = zRagPipelineRecommendedPluginResponse
export const zPostRagPipelinesTransformDatasetsByDatasetIdPath = z.object({
dataset_id: z.uuid(),
})
/**
* Success
* Dataset transformed successfully
*/
export const zPostRagPipelinesTransformDatasetsByDatasetIdResponse = zRagPipelineOpaqueResponse
export const zPostRagPipelinesTransformDatasetsByDatasetIdResponse = zRagPipelineTransformResponse
export const zPostRagPipelinesByPipelineIdCustomizedPublishBody = zCustomizedPipelineTemplatePayload
@ -873,33 +1093,6 @@ export const zGetRagPipelinesByPipelineIdWorkflowsQuery = z.object({
*/
export const zGetRagPipelinesByPipelineIdWorkflowsResponse = zWorkflowPaginationResponse
export const zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsPath = z.object({
pipeline_id: z.uuid(),
})
/**
* Default block configs retrieved successfully
*/
export const zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsResponse
= zDefaultBlockConfigsResponse
export const zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypePath
= z.object({
block_type: z.string(),
pipeline_id: z.uuid(),
})
export const zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeQuery
= z.object({
q: z.string().optional(),
})
/**
* Default block config retrieved successfully
*/
export const zGetRagPipelinesByPipelineIdWorkflowsDefaultWorkflowBlockConfigsByBlockTypeResponse
= zDefaultBlockConfigResponse
export const zGetRagPipelinesByPipelineIdWorkflowsDraftPath = z.object({
pipeline_id: z.uuid(),
})
@ -920,20 +1113,6 @@ export const zPostRagPipelinesByPipelineIdWorkflowsDraftPath = z.object({
*/
export const zPostRagPipelinesByPipelineIdWorkflowsDraftResponse = zRagPipelineWorkflowSyncResponse
export const zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunBody
= zDatasourceNodeRunPayload
export const zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunPath = z.object({
node_id: z.string(),
pipeline_id: z.uuid(),
})
/**
* Success
*/
export const zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceNodesByNodeIdRunResponse
= zRagPipelineOpaqueResponse
export const zPostRagPipelinesByPipelineIdWorkflowsDraftDatasourceVariablesInspectBody
= zDatasourceVariablesPayload
@ -957,33 +1136,6 @@ export const zGetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesPath
export const zGetRagPipelinesByPipelineIdWorkflowsDraftEnvironmentVariablesResponse
= zEnvironmentVariableListResponse
export const zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunBody
= zNodeRunPayload
export const zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunPath = z.object({
node_id: z.string(),
pipeline_id: z.uuid(),
})
/**
* Success
*/
export const zPostRagPipelinesByPipelineIdWorkflowsDraftIterationNodesByNodeIdRunResponse
= zRagPipelineOpaqueResponse
export const zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunBody = zNodeRunPayload
export const zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunPath = z.object({
node_id: z.string(),
pipeline_id: z.uuid(),
})
/**
* Success
*/
export const zPostRagPipelinesByPipelineIdWorkflowsDraftLoopNodesByNodeIdRunResponse
= zRagPipelineOpaqueResponse
export const zGetRagPipelinesByPipelineIdWorkflowsDraftNodesByNodeIdLastRunPath = z.object({
node_id: z.string(),
pipeline_id: z.uuid(),
@ -1039,10 +1191,10 @@ export const zGetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersQu
})
/**
* Success
* First step parameters retrieved successfully
*/
export const zGetRagPipelinesByPipelineIdWorkflowsDraftPreProcessingParametersResponse
= zRagPipelineStepParametersResponse
= zRagPipelineVariablesResponse
export const zGetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersPath = z.object({
pipeline_id: z.uuid(),
@ -1053,21 +1205,10 @@ export const zGetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersQuery
})
/**
* Success
* Second step parameters retrieved successfully
*/
export const zGetRagPipelinesByPipelineIdWorkflowsDraftProcessingParametersResponse
= zRagPipelineStepParametersResponse
export const zPostRagPipelinesByPipelineIdWorkflowsDraftRunBody = zDraftWorkflowRunPayload
export const zPostRagPipelinesByPipelineIdWorkflowsDraftRunPath = z.object({
pipeline_id: z.uuid(),
})
/**
* Success
*/
export const zPostRagPipelinesByPipelineIdWorkflowsDraftRunResponse = zRagPipelineOpaqueResponse
= zRagPipelineVariablesResponse
export const zGetRagPipelinesByPipelineIdWorkflowsDraftSystemVariablesPath = z.object({
pipeline_id: z.uuid(),
@ -1181,21 +1322,6 @@ export const zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNod
export const zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdPreviewResponse
= zDataSourceContentPreviewResponse
export const zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunBody
= zDatasourceNodeRunPayload
export const zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunPath
= z.object({
node_id: z.string(),
pipeline_id: z.uuid(),
})
/**
* Success
*/
export const zPostRagPipelinesByPipelineIdWorkflowsPublishedDatasourceNodesByNodeIdRunResponse
= zRagPipelineOpaqueResponse
export const zGetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersPath = z.object({
pipeline_id: z.uuid(),
})
@ -1205,10 +1331,10 @@ export const zGetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParamete
})
/**
* Success
* First step parameters retrieved successfully
*/
export const zGetRagPipelinesByPipelineIdWorkflowsPublishedPreProcessingParametersResponse
= zRagPipelineStepParametersResponse
= zRagPipelineVariablesResponse
export const zGetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersPath = z.object({
pipeline_id: z.uuid(),
@ -1219,21 +1345,10 @@ export const zGetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersQ
})
/**
* Success
* Second step parameters retrieved successfully
*/
export const zGetRagPipelinesByPipelineIdWorkflowsPublishedProcessingParametersResponse
= zRagPipelineStepParametersResponse
export const zPostRagPipelinesByPipelineIdWorkflowsPublishedRunBody = zPublishedWorkflowRunPayload
export const zPostRagPipelinesByPipelineIdWorkflowsPublishedRunPath = z.object({
pipeline_id: z.uuid(),
})
/**
* Success
*/
export const zPostRagPipelinesByPipelineIdWorkflowsPublishedRunResponse = zRagPipelineOpaqueResponse
= zRagPipelineVariablesResponse
export const zDeleteRagPipelinesByPipelineIdWorkflowsByWorkflowIdPath = z.object({
pipeline_id: z.uuid(),

View File

@ -14,15 +14,33 @@ 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 = unknown
export type PostRuleCodeGenerateData = {
body: RuleCodeGeneratePayload

View File

@ -7,21 +7,36 @@ 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.unknown()
/**
* 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(),
})
/**

View File

@ -13,15 +13,33 @@ 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 = unknown
export type PostRuleGenerateData = {
body: RuleGeneratePayload

View File

@ -7,21 +7,36 @@ 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.unknown()
/**
* 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(),
})
/**

View File

@ -12,15 +12,33 @@ 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 = unknown
export type PostRuleStructuredOutputGenerateData = {
body: RuleStructuredOutputPayload

View File

@ -7,21 +7,36 @@ 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.unknown()
/**
* 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(),
})
/**

View File

@ -17,8 +17,6 @@ import {
zGetSnippetsBySnippetIdWorkflowRunsPath,
zGetSnippetsBySnippetIdWorkflowRunsQuery,
zGetSnippetsBySnippetIdWorkflowRunsResponse,
zGetSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigsPath,
zGetSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigsResponse,
zGetSnippetsBySnippetIdWorkflowsDraftConfigPath,
zGetSnippetsBySnippetIdWorkflowsDraftConfigResponse,
zGetSnippetsBySnippetIdWorkflowsDraftConversationVariablesPath,
@ -65,7 +63,6 @@ import {
zPostSnippetsBySnippetIdWorkflowsDraftRunBody,
zPostSnippetsBySnippetIdWorkflowsDraftRunPath,
zPostSnippetsBySnippetIdWorkflowsDraftRunResponse,
zPostSnippetsBySnippetIdWorkflowsPublishBody,
zPostSnippetsBySnippetIdWorkflowsPublishPath,
zPostSnippetsBySnippetIdWorkflowsPublishResponse,
zPutSnippetsBySnippetIdWorkflowsDraftVariablesByVariableIdResetPath,
@ -169,29 +166,10 @@ export const workflowRuns = {
byRunId,
}
/**
* Get default block configurations for snippet workflow
*/
export const get4 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
operationId: 'getSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigs',
path: '/snippets/{snippet_id}/workflows/default-workflow-block-configs',
summary: 'Get default block configurations for snippet workflow',
tags: ['console'],
})
.input(z.object({ params: zGetSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigsPath }))
.output(zGetSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigsResponse)
export const defaultWorkflowBlockConfigs = {
get: get4,
}
/**
* Get snippet draft workflow configuration limits
*/
export const get5 = oc
export const get4 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -204,13 +182,13 @@ export const get5 = oc
.output(zGetSnippetsBySnippetIdWorkflowsDraftConfigResponse)
export const config = {
get: get5,
get: get4,
}
/**
* Conversation variables are not used in snippet workflows; returns an empty list for API parity
*/
export const get6 = oc
export const get5 = oc
.route({
description:
'Conversation variables are not used in snippet workflows; returns an empty list for API parity',
@ -224,13 +202,13 @@ export const get6 = oc
.output(zGetSnippetsBySnippetIdWorkflowsDraftConversationVariablesResponse)
export const conversationVariables = {
get: get6,
get: get5,
}
/**
* Get environment variables from snippet draft workflow graph
*/
export const get7 = oc
export const get6 = oc
.route({
description: 'Get environment variables from snippet draft workflow graph',
inputStructure: 'detailed',
@ -243,7 +221,7 @@ export const get7 = oc
.output(zGetSnippetsBySnippetIdWorkflowsDraftEnvironmentVariablesResponse)
export const environmentVariables = {
get: get7,
get: get6,
}
/**
@ -337,7 +315,7 @@ export const loop = {
* Returns the most recent execution record for the given node,
* including status, inputs, outputs, and timing information.
*/
export const get8 = oc
export const get7 = oc
.route({
description:
'Get last run result for a node in snippet draft workflow\nReturns the most recent execution record for the given node,\nincluding status, inputs, outputs, and timing information.',
@ -352,7 +330,7 @@ export const get8 = oc
.output(zGetSnippetsBySnippetIdWorkflowsDraftNodesByNodeIdLastRunResponse)
export const lastRun = {
get: get8,
get: get7,
}
/**
@ -404,7 +382,7 @@ export const delete_ = oc
/**
* Get variables for a specific node (snippet draft workflow)
*/
export const get9 = oc
export const get8 = oc
.route({
description: 'Get variables for a specific node (snippet draft workflow)',
inputStructure: 'detailed',
@ -418,7 +396,7 @@ export const get9 = oc
export const variables = {
delete: delete_,
get: get9,
get: get8,
}
export const byNodeId3 = {
@ -463,7 +441,7 @@ export const run4 = {
/**
* System variables are not used in snippet workflows; returns an empty list for API parity
*/
export const get10 = oc
export const get9 = oc
.route({
description:
'System variables are not used in snippet workflows; returns an empty list for API parity',
@ -477,7 +455,7 @@ export const get10 = oc
.output(zGetSnippetsBySnippetIdWorkflowsDraftSystemVariablesResponse)
export const systemVariables = {
get: get10,
get: get9,
}
/**
@ -518,7 +496,7 @@ export const delete2 = oc
/**
* Get a specific draft workflow variable (snippet scope)
*/
export const get11 = oc
export const get10 = oc
.route({
description: 'Get a specific draft workflow variable (snippet scope)',
inputStructure: 'detailed',
@ -552,7 +530,7 @@ export const patch = oc
export const byVariableId = {
delete: delete2,
get: get11,
get: get10,
patch,
reset,
}
@ -576,7 +554,7 @@ export const delete3 = oc
/**
* List draft workflow variables without values (paginated, snippet scope)
*/
export const get12 = oc
export const get11 = oc
.route({
description: 'List draft workflow variables without values (paginated, snippet scope)',
inputStructure: 'detailed',
@ -595,14 +573,14 @@ export const get12 = oc
export const variables2 = {
delete: delete3,
get: get12,
get: get11,
byVariableId,
}
/**
* Get draft workflow for snippet
*/
export const get13 = oc
export const get12 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -635,7 +613,7 @@ export const post6 = oc
.output(zPostSnippetsBySnippetIdWorkflowsDraftResponse)
export const draft = {
get: get13,
get: get12,
post: post6,
config,
conversationVariables,
@ -651,7 +629,7 @@ export const draft = {
/**
* Get published workflow for snippet
*/
export const get14 = oc
export const get13 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@ -675,16 +653,11 @@ export const post7 = oc
summary: 'Publish snippet workflow',
tags: ['console'],
})
.input(
z.object({
body: zPostSnippetsBySnippetIdWorkflowsPublishBody,
params: zPostSnippetsBySnippetIdWorkflowsPublishPath,
}),
)
.input(z.object({ params: zPostSnippetsBySnippetIdWorkflowsPublishPath }))
.output(zPostSnippetsBySnippetIdWorkflowsPublishResponse)
export const publish = {
get: get14,
get: get13,
post: post7,
}
@ -719,7 +692,7 @@ export const byWorkflowId = {
*
* Get all published workflows for a snippet
*/
export const get15 = oc
export const get14 = oc
.route({
description: 'Get all published workflows for a snippet',
inputStructure: 'detailed',
@ -738,8 +711,7 @@ export const get15 = oc
.output(zGetSnippetsBySnippetIdWorkflowsResponse)
export const workflows = {
get: get15,
defaultWorkflowBlockConfigs,
get: get14,
draft,
publish,
byWorkflowId,

View File

@ -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
@ -44,14 +44,10 @@ export type SnippetWorkflowPaginationResponse = {
page: number
}
export type DefaultBlockConfigsResponse = Array<{
[key: string]: unknown
}>
export type SnippetWorkflowResponse = {
conversation_variables: Array<WorkflowConversationVariableResponse>
created_at: number
created_by?: SimpleAccount | null
created_by?: SimpleAccountResponse | null
environment_variables: Array<WorkflowEnvironmentVariableResponse>
features: {
[key: string]: unknown
@ -69,7 +65,7 @@ export type SnippetWorkflowResponse = {
rag_pipeline_variables: Array<PipelineVariableResponse>
tool_published: boolean
updated_at: number
updated_by?: SimpleAccount | null
updated_by?: SimpleAccountResponse | null
version: string
}
@ -86,7 +82,7 @@ export type SnippetDraftSyncPayload = {
}> | null
}
export type WorkflowRestoreResponse = {
export type SyncDraftWorkflowResponse = {
hash: string
result: string
updated_at: number
@ -110,7 +106,7 @@ export type SnippetIterationNodeRunPayload = {
} | null
}
export type GeneratedAppResponse = JsonValue
export type EventStreamResponse = string
export type SnippetLoopNodeRunPayload = {
inputs?: {
@ -120,7 +116,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
@ -197,20 +193,14 @@ export type WorkflowDraftVariableUpdatePayload = {
value?: unknown | null
}
export type PublishWorkflowPayload = {
knowledge_base_setting?: {
[key: string]: unknown
} | null
}
export type WorkflowPublishResponse = {
export type PublishWorkflowResponse = {
created_at: number
result: string
}
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 +212,7 @@ export type WorkflowRunForListResponse = {
version?: string | null
}
export type SimpleAccount = {
export type SimpleAccountResponse = {
email: string
id: string
name: string
@ -281,17 +271,6 @@ export type EnvironmentVariableItemResponse = {
visible: boolean
}
export type JsonValue
= | string
| number
| number
| boolean
| {
[key: string]: unknown
}
| Array<unknown>
| null
export type WorkflowDraftVariableWithoutValue = {
description?: string
edited?: boolean
@ -401,22 +380,6 @@ export type GetSnippetsBySnippetIdWorkflowsResponses = {
export type GetSnippetsBySnippetIdWorkflowsResponse
= GetSnippetsBySnippetIdWorkflowsResponses[keyof GetSnippetsBySnippetIdWorkflowsResponses]
export type GetSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigsData = {
body?: never
path: {
snippet_id: string
}
query?: never
url: '/snippets/{snippet_id}/workflows/default-workflow-block-configs'
}
export type GetSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigsResponses = {
200: DefaultBlockConfigsResponse
}
export type GetSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigsResponse
= GetSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigsResponses[keyof GetSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigsResponses]
export type GetSnippetsBySnippetIdWorkflowsDraftData = {
body?: never
path: {
@ -451,7 +414,7 @@ export type PostSnippetsBySnippetIdWorkflowsDraftErrors = {
}
export type PostSnippetsBySnippetIdWorkflowsDraftResponses = {
200: WorkflowRestoreResponse
200: SyncDraftWorkflowResponse
}
export type PostSnippetsBySnippetIdWorkflowsDraftResponse
@ -524,7 +487,7 @@ export type PostSnippetsBySnippetIdWorkflowsDraftIterationNodesByNodeIdRunErrors
}
export type PostSnippetsBySnippetIdWorkflowsDraftIterationNodesByNodeIdRunResponses = {
200: GeneratedAppResponse
200: EventStreamResponse
}
export type PostSnippetsBySnippetIdWorkflowsDraftIterationNodesByNodeIdRunResponse
@ -545,7 +508,7 @@ export type PostSnippetsBySnippetIdWorkflowsDraftLoopNodesByNodeIdRunErrors = {
}
export type PostSnippetsBySnippetIdWorkflowsDraftLoopNodesByNodeIdRunResponses = {
200: GeneratedAppResponse
200: EventStreamResponse
}
export type PostSnippetsBySnippetIdWorkflowsDraftLoopNodesByNodeIdRunResponse
@ -641,7 +604,7 @@ export type PostSnippetsBySnippetIdWorkflowsDraftRunErrors = {
}
export type PostSnippetsBySnippetIdWorkflowsDraftRunResponses = {
200: GeneratedAppResponse
200: EventStreamResponse
}
export type PostSnippetsBySnippetIdWorkflowsDraftRunResponse
@ -804,7 +767,7 @@ export type GetSnippetsBySnippetIdWorkflowsPublishResponse
= GetSnippetsBySnippetIdWorkflowsPublishResponses[keyof GetSnippetsBySnippetIdWorkflowsPublishResponses]
export type PostSnippetsBySnippetIdWorkflowsPublishData = {
body: PublishWorkflowPayload
body?: never
path: {
snippet_id: string
}
@ -817,7 +780,7 @@ export type PostSnippetsBySnippetIdWorkflowsPublishErrors = {
}
export type PostSnippetsBySnippetIdWorkflowsPublishResponses = {
200: WorkflowPublishResponse
200: PublishWorkflowResponse
}
export type PostSnippetsBySnippetIdWorkflowsPublishResponse
@ -839,7 +802,7 @@ export type PostSnippetsBySnippetIdWorkflowsByWorkflowIdRestoreErrors = {
}
export type PostSnippetsBySnippetIdWorkflowsByWorkflowIdRestoreResponses = {
200: WorkflowRestoreResponse
200: SyncDraftWorkflowResponse
}
export type PostSnippetsBySnippetIdWorkflowsByWorkflowIdRestoreResponse

View File

@ -9,11 +9,6 @@ export const zSimpleResultResponse = z.object({
result: z.string(),
})
/**
* DefaultBlockConfigsResponse
*/
export const zDefaultBlockConfigsResponse = z.array(z.record(z.string(), z.unknown()))
/**
* SnippetDraftSyncPayload
*
@ -27,9 +22,9 @@ export const zSnippetDraftSyncPayload = z.object({
})
/**
* WorkflowRestoreResponse
* SyncDraftWorkflowResponse
*/
export const zWorkflowRestoreResponse = z.object({
export const zSyncDraftWorkflowResponse = z.object({
hash: z.string(),
result: z.string(),
updated_at: z.int(),
@ -51,6 +46,11 @@ export const zSnippetIterationNodeRunPayload = z.object({
inputs: z.record(z.string(), z.unknown()).nullish(),
})
/**
* EventStreamResponse
*/
export const zEventStreamResponse = z.string()
/**
* SnippetLoopNodeRunPayload
*
@ -117,26 +117,17 @@ export const zWorkflowDraftVariableUpdatePayload = z.object({
})
/**
* PublishWorkflowPayload
*
* Payload for publishing snippet workflow.
* PublishWorkflowResponse
*/
export const zPublishWorkflowPayload = z.object({
knowledge_base_setting: z.record(z.string(), z.unknown()).nullish(),
})
/**
* WorkflowPublishResponse
*/
export const zWorkflowPublishResponse = z.object({
export const zPublishWorkflowResponse = z.object({
created_at: z.int(),
result: z.string(),
})
/**
* SimpleAccount
* SimpleAccountResponse
*/
export const zSimpleAccount = z.object({
export const zSimpleAccountResponse = z.object({
email: z.string(),
id: z.string(),
name: z.string(),
@ -147,7 +138,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 +174,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 +196,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 +274,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 +286,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(),
})
@ -332,22 +323,6 @@ export const zEnvironmentVariableListResponse = z.object({
items: z.array(zEnvironmentVariableItemResponse),
})
export const zJsonValue = z
.union([
z.string(),
z.int(),
z.number(),
z.boolean(),
z.record(z.string(), z.unknown()),
z.array(z.unknown()),
])
.nullable()
/**
* GeneratedAppResponse
*/
export const zGeneratedAppResponse = zJsonValue
export const zWorkflowDraftVariableWithoutValue = z.object({
description: z.string().optional(),
edited: z.boolean().optional(),
@ -424,16 +399,6 @@ export const zGetSnippetsBySnippetIdWorkflowsQuery = z.object({
*/
export const zGetSnippetsBySnippetIdWorkflowsResponse = zSnippetWorkflowPaginationResponse
export const zGetSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigsPath = z.object({
snippet_id: z.uuid(),
})
/**
* Default block configs retrieved successfully
*/
export const zGetSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigsResponse
= zDefaultBlockConfigsResponse
export const zGetSnippetsBySnippetIdWorkflowsDraftPath = z.object({
snippet_id: z.uuid(),
})
@ -452,7 +417,7 @@ export const zPostSnippetsBySnippetIdWorkflowsDraftPath = z.object({
/**
* Draft workflow synced successfully
*/
export const zPostSnippetsBySnippetIdWorkflowsDraftResponse = zWorkflowRestoreResponse
export const zPostSnippetsBySnippetIdWorkflowsDraftResponse = zSyncDraftWorkflowResponse
export const zGetSnippetsBySnippetIdWorkflowsDraftConfigPath = z.object({
snippet_id: z.uuid(),
@ -495,7 +460,7 @@ export const zPostSnippetsBySnippetIdWorkflowsDraftIterationNodesByNodeIdRunPath
* Iteration node run started successfully (SSE stream)
*/
export const zPostSnippetsBySnippetIdWorkflowsDraftIterationNodesByNodeIdRunResponse
= zGeneratedAppResponse
= zEventStreamResponse
export const zPostSnippetsBySnippetIdWorkflowsDraftLoopNodesByNodeIdRunBody
= zSnippetLoopNodeRunPayload
@ -509,7 +474,7 @@ export const zPostSnippetsBySnippetIdWorkflowsDraftLoopNodesByNodeIdRunPath = z.
* Loop node run started successfully (SSE stream)
*/
export const zPostSnippetsBySnippetIdWorkflowsDraftLoopNodesByNodeIdRunResponse
= zGeneratedAppResponse
= zEventStreamResponse
export const zGetSnippetsBySnippetIdWorkflowsDraftNodesByNodeIdLastRunPath = z.object({
node_id: z.string(),
@ -566,7 +531,7 @@ export const zPostSnippetsBySnippetIdWorkflowsDraftRunPath = z.object({
/**
* Draft workflow run started successfully (SSE stream)
*/
export const zPostSnippetsBySnippetIdWorkflowsDraftRunResponse = zGeneratedAppResponse
export const zPostSnippetsBySnippetIdWorkflowsDraftRunResponse = zEventStreamResponse
export const zGetSnippetsBySnippetIdWorkflowsDraftSystemVariablesPath = z.object({
snippet_id: z.uuid(),
@ -656,8 +621,6 @@ export const zGetSnippetsBySnippetIdWorkflowsPublishPath = z.object({
*/
export const zGetSnippetsBySnippetIdWorkflowsPublishResponse = zSnippetWorkflowResponse
export const zPostSnippetsBySnippetIdWorkflowsPublishBody = zPublishWorkflowPayload
export const zPostSnippetsBySnippetIdWorkflowsPublishPath = z.object({
snippet_id: z.uuid(),
})
@ -665,7 +628,7 @@ export const zPostSnippetsBySnippetIdWorkflowsPublishPath = z.object({
/**
* Workflow published successfully
*/
export const zPostSnippetsBySnippetIdWorkflowsPublishResponse = zWorkflowPublishResponse
export const zPostSnippetsBySnippetIdWorkflowsPublishResponse = zPublishWorkflowResponse
export const zPostSnippetsBySnippetIdWorkflowsByWorkflowIdRestorePath = z.object({
snippet_id: z.uuid(),
@ -675,4 +638,5 @@ export const zPostSnippetsBySnippetIdWorkflowsByWorkflowIdRestorePath = z.object
/**
* Workflow restored successfully
*/
export const zPostSnippetsBySnippetIdWorkflowsByWorkflowIdRestoreResponse = zWorkflowRestoreResponse
export const zPostSnippetsBySnippetIdWorkflowsByWorkflowIdRestoreResponse
= zSyncDraftWorkflowResponse

View File

@ -10,19 +10,24 @@ export type BedrockRetrievalPayload = {
retrieval_setting: BedrockRetrievalSetting
}
export type ExternalRetrievalTestResponse
= | {
[key: string]: unknown
}
| Array<{
[key: string]: unknown
}>
export type BedrockRetrievalResponse = {
records: Array<BedrockRetrievalRecordResponse>
}
export type BedrockRetrievalSetting = {
score_threshold?: number
top_k?: number | null
}
export type BedrockRetrievalRecordResponse = {
content?: string | null
metadata?: {
[key: string]: unknown
} | null
score: number
title?: string | null
}
export type PostTestRetrievalData = {
body: BedrockRetrievalPayload
path?: never
@ -31,7 +36,7 @@ export type PostTestRetrievalData = {
}
export type PostTestRetrievalResponses = {
200: ExternalRetrievalTestResponse
200: BedrockRetrievalResponse
}
export type PostTestRetrievalResponse = PostTestRetrievalResponses[keyof PostTestRetrievalResponses]

View File

@ -2,14 +2,6 @@
import * as z from 'zod'
/**
* ExternalRetrievalTestResponse
*/
export const zExternalRetrievalTestResponse = z.union([
z.record(z.string(), z.unknown()),
z.array(z.record(z.string(), z.unknown())),
])
/**
* BedrockRetrievalSetting
*
@ -29,9 +21,26 @@ export const zBedrockRetrievalPayload = z.object({
retrieval_setting: zBedrockRetrievalSetting,
})
/**
* BedrockRetrievalRecordResponse
*/
export const zBedrockRetrievalRecordResponse = z.object({
content: z.string().nullish(),
metadata: z.record(z.string(), z.unknown()).nullish(),
score: z.number(),
title: z.string().nullish(),
})
/**
* BedrockRetrievalResponse
*/
export const zBedrockRetrievalResponse = z.object({
records: z.array(zBedrockRetrievalRecordResponse),
})
export const zPostTestRetrievalBody = zBedrockRetrievalPayload
/**
* Bedrock retrieval test completed
*/
export const zPostTestRetrievalResponse = zExternalRetrievalTestResponse
export const zPostTestRetrievalResponse = zBedrockRetrievalResponse

View File

@ -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,

View File

@ -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<TrialDeletedTool>
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<DeletedTool>
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<string>
site?: TrialSite
tags?: Array<TrialTag>
updated_at?: number
updated_by?: string
use_icon_as_answer_icon?: boolean
workflow?: TrialWorkflowPartial
site?: Site | null
tags?: Array<Tag>
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<unknown> | null
inputs: {
[key: string]: unknown
}
parent_message_id?: string | null
query: string
retriever_from?: string
}
export type GeneratedAppResponse = JsonValue
export type CompletionRequest = {
files?: Array<unknown> | null
inputs: {
[key: string]: unknown
}
query?: string
response_mode?: 'blocking' | 'streaming' | null
retriever_from?: string
}
export type TrialDatasetList = {
data?: Array<TrialDataset>
has_more?: boolean
limit?: number
page?: number
total?: number
export type TrialDatasetListResponse = {
data: Array<TrialDatasetListItemResponse>
has_more: boolean
limit: number
page: number
total: number
}
export type SuggestedQuestionsResponse = {
@ -111,166 +92,119 @@ export type TextToSpeechRequest = {
export type AudioBinaryResponse = Blob | File
export type TrialWorkflow = {
conversation_variables?: Array<TrialConversationVariable>
created_at?: number
created_by?: TrialSimpleAccount
environment_variables?: Array<{
[key: string]: unknown
}>
features?: {
export type WorkflowResponse = {
conversation_variables: Array<WorkflowConversationVariableResponse>
created_at: number
created_by?: SimpleAccountResponse | null
environment_variables: Array<WorkflowEnvironmentVariableResponse>
features: {
[key: string]: unknown
}
graph?: {
[key: string]: unknown
}
hash?: string
id?: string
marked_comment?: string
marked_name?: string
rag_pipeline_variables?: Array<TrialPipelineVariable>
tool_published?: boolean
updated_at?: number
updated_by?: TrialSimpleAccount
version?: string
}
export type WorkflowRunRequest = {
files?: Array<unknown> | null
inputs: {
graph: {
[key: string]: unknown
}
hash: string
id: string
marked_comment: string
marked_name: string
rag_pipeline_variables: Array<PipelineVariableResponse>
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<string>
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 Tag = {
id: string
name: string
type: string
}
export type TrialTag = {
id?: string
name?: string
type?: string
export type JsonValue = unknown
export type WorkflowPartial = {
created_at?: number | null
created_by?: string | null
id: string
updated_at?: number | null
updated_by?: string | null
}
export type TrialWorkflowPartial = {
created_at?: number
created_by?: string
id?: string
updated_at?: number
updated_by?: string
}
export type JsonValue
= | string
| number
| number
| boolean
| {
[key: string]: unknown
}
| Array<unknown>
| 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 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<DatasetDocMetadataResponse>
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<string>
pipeline_id: string | null
provider: string
retrieval_model_dict: DatasetRetrievalModelResponse
runtime_mode: string | null
summary_index_setting?: DatasetSummaryIndexSettingResponse
tags: Array<DatasetTagResponse>
total_available_documents: number
total_documents: number
updated_at: number
updated_by: string | null
word_count: number
}
export type JsonObject = {
@ -285,56 +219,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<unknown>
| 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<string>
allow_file_upload_methods?: Array<string>
allowed_file_types?: Array<string>
belong_to_node_id?: string
default_value?:
| string
| number
| number
| boolean
| {
[key: string]: unknown
}
| Array<unknown>
| null
label?: string
max_length?: number
options?: Array<string>
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<string> | null
allowed_file_types?: Array<string> | null
allowed_file_upload_methods?: Array<string> | null
belong_to_node_id: string
default_value?: unknown
label: string
max_length?: number | null
options?: Array<string> | 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<DeletedTool>
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<string>
site?: SiteWritable | null
tags?: Array<Tag>
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 +385,7 @@ export type GetTrialAppsByAppIdData = {
}
export type GetTrialAppsByAppIdResponses = {
200: TrialAppDetailWithSite
200: AppDetailWithSite
}
export type GetTrialAppsByAppIdResponse
@ -384,38 +407,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 +421,7 @@ export type GetTrialAppsByAppIdDatasetsData = {
}
export type GetTrialAppsByAppIdDatasetsResponses = {
200: TrialDatasetList
200: TrialDatasetListResponse
}
export type GetTrialAppsByAppIdDatasetsResponse
@ -511,28 +502,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: {

View File

@ -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<Blob | File>()
/**
* WorkflowRunRequest
*/
export const zWorkflowRunRequest = z.object({
files: z.array(z.unknown()).nullish(),
inputs: z.record(z.string(), z.unknown()),
})
/**
* SimpleResultResponse
*/
@ -89,213 +58,99 @@ 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(),
})
export const zJsonValue = z
.union([
z.string(),
z.int(),
z.number(),
z.boolean(),
z.record(z.string(), z.unknown()),
z.array(z.unknown()),
])
.nullable()
/**
* GeneratedAppResponse
* Tag
*/
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 zTag = z.object({
id: z.string(),
name: z.string(),
type: z.string(),
})
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(),
export const zJsonValue = z.unknown()
/**
* 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
*/
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 +184,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 +433,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 +484,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 +497,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 +544,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(),

View File

@ -17,15 +17,33 @@ 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 = unknown
export type PostWorkflowGenerateData = {
body: WorkflowGeneratePayload

View File

@ -7,21 +7,36 @@ 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.unknown()
/**
* 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(),
})
/**

View File

@ -31,12 +31,12 @@ export type AgentProviderListResponse = Array<{
[key: string]: unknown
}>
export type SnippetPagination = {
data?: Array<AnonymousInlineModel744Ff9Cc03E6>
has_more?: boolean
limit?: number
page?: number
total?: number
export type SnippetPaginationResponse = {
data: Array<SnippetListItemResponse>
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<AnonymousInlineModel7B8B49Ca164e>
type?: string
updated_at?: number
updated_by?: AnonymousInlineModelB0Fd3F86D9D5
use_count?: number
version?: number
}> | null
is_published: boolean
name: string
tags?: Array<SnippetTagResponse>
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<PluginDependency>
}
export type TextFileResponse = string
export type SnippetUseCountResponse = {
export type SnippetUseCountIncrementResponse = {
result: string
use_count: number
}
export type AccountWithRoleList = {
accounts: Array<AccountWithRole>
export type AccountWithRoleListResponse = {
accounts: Array<AccountWithRoleResponse>
}
export type DefaultModelDataResponse = {
@ -836,7 +839,7 @@ export type WorkspaceCustomConfigPayload = {
replace_webapp_logo?: string | null
}
export type WorkspaceMutationResponse = {
export type WorkspaceTenantResultResponse = {
result: string
tenant: TenantInfoResponse
}
@ -862,6 +865,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 +876,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<AnonymousInlineModel7B8B49Ca164e>
type?: string
updated_at?: number
updated_by?: string
use_count?: number
version?: number
} | null
id: string
is_published: boolean
name: string
tags?: Array<SnippetTagResponse>
type: string
updated_at?: number | null
updated_by?: string | null
use_count: number
version: number
}
export type IconInfo = {
@ -909,19 +913,27 @@ 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
created_at?: number | null
email: string
@ -1198,6 +1210,25 @@ export type WorkflowToolParameterConfiguration = {
name: string
}
export type Type = 'github' | 'marketplace' | 'package'
export type Github = {
github_plugin_unique_identifier: string
package: string
repo: string
version: string
}
export type Marketplace = {
marketplace_plugin_unique_identifier: string
version?: string | null
}
export type Package = {
plugin_unique_identifier: string
version?: string | null
}
export type SimpleProviderEntityResponse = {
icon_small?: I18nObject | null
icon_small_dark?: I18nObject | null
@ -1583,7 +1614,7 @@ export type GetWorkspacesCurrentCustomizedSnippetsData = {
}
export type GetWorkspacesCurrentCustomizedSnippetsResponses = {
200: SnippetPagination
200: SnippetPaginationResponse
}
export type GetWorkspacesCurrentCustomizedSnippetsResponse
@ -1601,7 +1632,7 @@ export type PostWorkspacesCurrentCustomizedSnippetsErrors = {
}
export type PostWorkspacesCurrentCustomizedSnippetsResponses = {
201: Snippet
201: SnippetResponse
}
export type PostWorkspacesCurrentCustomizedSnippetsResponse
@ -1619,8 +1650,8 @@ export type PostWorkspacesCurrentCustomizedSnippetsImportsErrors = {
}
export type PostWorkspacesCurrentCustomizedSnippetsImportsResponses = {
200: SnippetImportResponse
202: SnippetImportResponse
200: SnippetImportInfo
202: SnippetImportInfo
}
export type PostWorkspacesCurrentCustomizedSnippetsImportsResponse
@ -1640,7 +1671,7 @@ export type PostWorkspacesCurrentCustomizedSnippetsImportsByImportIdConfirmError
}
export type PostWorkspacesCurrentCustomizedSnippetsImportsByImportIdConfirmResponses = {
200: SnippetImportResponse
200: SnippetImportInfo
}
export type PostWorkspacesCurrentCustomizedSnippetsImportsByImportIdConfirmResponse
@ -1680,7 +1711,7 @@ export type GetWorkspacesCurrentCustomizedSnippetsBySnippetIdErrors = {
}
export type GetWorkspacesCurrentCustomizedSnippetsBySnippetIdResponses = {
200: Snippet
200: SnippetResponse
}
export type GetWorkspacesCurrentCustomizedSnippetsBySnippetIdResponse
@ -1701,7 +1732,7 @@ export type PatchWorkspacesCurrentCustomizedSnippetsBySnippetIdErrors = {
}
export type PatchWorkspacesCurrentCustomizedSnippetsBySnippetIdResponses = {
200: Snippet
200: SnippetResponse
}
export type PatchWorkspacesCurrentCustomizedSnippetsBySnippetIdResponse
@ -1721,34 +1752,12 @@ export type GetWorkspacesCurrentCustomizedSnippetsBySnippetIdCheckDependenciesEr
}
export type GetWorkspacesCurrentCustomizedSnippetsBySnippetIdCheckDependenciesResponses = {
200: SnippetDependencyCheckResponse
200: CheckDependenciesResult
}
export type GetWorkspacesCurrentCustomizedSnippetsBySnippetIdCheckDependenciesResponse
= GetWorkspacesCurrentCustomizedSnippetsBySnippetIdCheckDependenciesResponses[keyof GetWorkspacesCurrentCustomizedSnippetsBySnippetIdCheckDependenciesResponses]
export type GetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportData = {
body?: never
path: {
snippet_id: string
}
query?: {
include_secret?: string
}
url: '/workspaces/current/customized-snippets/{snippet_id}/export'
}
export type GetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportErrors = {
404: unknown
}
export type GetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportResponses = {
200: TextFileResponse
}
export type GetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportResponse
= GetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportResponses[keyof GetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportResponses]
export type PostWorkspacesCurrentCustomizedSnippetsBySnippetIdUseCountIncrementData = {
body?: never
path: {
@ -1763,7 +1772,7 @@ export type PostWorkspacesCurrentCustomizedSnippetsBySnippetIdUseCountIncrementE
}
export type PostWorkspacesCurrentCustomizedSnippetsBySnippetIdUseCountIncrementResponses = {
200: SnippetUseCountResponse
200: SnippetUseCountIncrementResponse
}
export type PostWorkspacesCurrentCustomizedSnippetsBySnippetIdUseCountIncrementResponse
@ -1777,7 +1786,7 @@ export type GetWorkspacesCurrentDatasetOperatorsData = {
}
export type GetWorkspacesCurrentDatasetOperatorsResponses = {
200: AccountWithRoleList
200: AccountWithRoleListResponse
}
export type GetWorkspacesCurrentDatasetOperatorsResponse
@ -2004,7 +2013,7 @@ export type GetWorkspacesCurrentMembersData = {
}
export type GetWorkspacesCurrentMembersResponses = {
200: AccountWithRoleList
200: AccountWithRoleListResponse
}
export type GetWorkspacesCurrentMembersResponse
@ -4597,14 +4606,16 @@ export type PostWorkspacesCustomConfigData = {
}
export type PostWorkspacesCustomConfigResponses = {
200: WorkspaceMutationResponse
200: WorkspaceTenantResultResponse
}
export type PostWorkspacesCustomConfigResponse
= PostWorkspacesCustomConfigResponses[keyof PostWorkspacesCustomConfigResponses]
export type PostWorkspacesCustomConfigWebappLogoUploadData = {
body?: never
body: {
file: Blob | File
}
path?: never
query?: never
url: '/workspaces/custom-config/webapp-logo/upload'
@ -4625,7 +4636,7 @@ export type PostWorkspacesInfoData = {
}
export type PostWorkspacesInfoResponses = {
200: WorkspaceMutationResponse
200: WorkspaceTenantResultResponse
}
export type PostWorkspacesInfoResponse

View File

@ -27,24 +27,9 @@ export const zSnippetImportPayload = z.object({
})
/**
* SnippetImportResponse
* SnippetUseCountIncrementResponse
*/
export const zSnippetImportResponse = z.record(z.string(), z.unknown())
/**
* SnippetDependencyCheckResponse
*/
export const zSnippetDependencyCheckResponse = z.record(z.string(), z.unknown())
/**
* TextFileResponse
*/
export const zTextFileResponse = z.string()
/**
* SnippetUseCountResponse
*/
export const zSnippetUseCountResponse = z.object({
export const zSnippetUseCountIncrementResponse = z.object({
result: z.string(),
use_count: z.int(),
})
@ -694,6 +679,7 @@ export const zTenantListItemResponse = z.object({
created_at: z.int().nullish(),
current: z.boolean(),
id: z.string(),
last_opened_at: z.int().nullish(),
name: z.string().nullish(),
plan: z.string().nullish(),
status: z.string().nullish(),
@ -733,9 +719,9 @@ export const zTenantInfoResponse = z.object({
})
/**
* WorkspaceMutationResponse
* WorkspaceTenantResultResponse
*/
export const zWorkspaceMutationResponse = z.object({
export const zWorkspaceTenantResultResponse = z.object({
result: z.string(),
tenant: zTenantInfoResponse,
})
@ -801,97 +787,97 @@ export const zCreateSnippetPayload = z.object({
type: z.enum(['group', 'node']).optional().default('node'),
})
export const zAnonymousInlineModelB0Fd3F86D9D5 = z.object({
email: z.string().optional(),
id: z.string().optional(),
name: z.string().optional(),
})
export const zAnonymousInlineModel7B8B49Ca164e = z.object({
id: z.string().optional(),
name: z.string().optional(),
type: z.string().optional(),
})
export const zSnippet = 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: zAnonymousInlineModelB0Fd3F86D9D5.optional(),
description: z.string().optional(),
graph: z.record(z.string(), z.unknown()).optional(),
icon_info: z.record(z.string(), z.unknown()).optional(),
id: z.string().optional(),
input_fields: z.record(z.string(), z.unknown()).optional(),
is_published: z.boolean().optional(),
name: z.string().optional(),
tags: z.array(zAnonymousInlineModel7B8B49Ca164e).optional(),
type: 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: zAnonymousInlineModelB0Fd3F86D9D5.optional(),
use_count: z.int().optional(),
version: z.int().optional(),
})
export const zAnonymousInlineModel744Ff9Cc03E6 = z.object({
author_name: 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(),
description: z.string().optional(),
icon_info: z.record(z.string(), z.unknown()).optional(),
id: z.string().optional(),
is_published: z.boolean().optional(),
name: z.string().optional(),
tags: z.array(zAnonymousInlineModel7B8B49Ca164e).optional(),
type: 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_count: z.int().optional(),
version: z.int().optional(),
})
export const zSnippetPagination = z.object({
data: z.array(zAnonymousInlineModel744Ff9Cc03E6).optional(),
has_more: z.boolean().optional(),
limit: z.int().optional(),
page: z.int().optional(),
total: z.int().optional(),
/**
* SimpleAccountResponse
*/
export const zSimpleAccountResponse = z.object({
email: z.string(),
id: z.string(),
name: z.string(),
})
/**
* AccountWithRole
* SnippetTagResponse
*/
export const zAccountWithRole = z.object({
export const zSnippetTagResponse = z.object({
id: z.string(),
name: z.string(),
type: z.string(),
})
/**
* SnippetResponse
*/
export const zSnippetResponse = z.object({
created_at: z.int().nullish(),
created_by: zSimpleAccountResponse.nullish(),
description: z.string().nullish(),
graph: z.record(z.string(), z.unknown()).nullish(),
icon_info: z.record(z.string(), z.unknown()).nullish(),
id: z.string(),
input_fields: z.array(z.record(z.string(), z.unknown())).nullish(),
is_published: z.boolean(),
name: z.string(),
tags: z.array(zSnippetTagResponse).optional(),
type: z.string(),
updated_at: z.int().nullish(),
updated_by: zSimpleAccountResponse.nullish(),
use_count: z.int(),
version: z.int(),
})
/**
* SnippetListItemResponse
*/
export const zSnippetListItemResponse = z.object({
author_name: z.string().nullish(),
created_at: z.int().nullish(),
created_by: z.string().nullish(),
description: z.string().nullish(),
icon_info: z.record(z.string(), z.unknown()).nullish(),
id: z.string(),
is_published: z.boolean(),
name: z.string(),
tags: z.array(zSnippetTagResponse).optional(),
type: z.string(),
updated_at: z.int().nullish(),
updated_by: z.string().nullish(),
use_count: z.int(),
version: z.int(),
})
/**
* SnippetPaginationResponse
*/
export const zSnippetPaginationResponse = z.object({
data: z.array(zSnippetListItemResponse),
has_more: z.boolean(),
limit: z.int(),
page: z.int(),
total: z.int(),
})
/**
* ImportStatus
*/
export const zImportStatus = z.enum(['completed', 'completed-with-warnings', 'failed', 'pending'])
/**
* SnippetImportInfo
*/
export const zSnippetImportInfo = z.object({
current_dsl_version: z.string().optional().default('0.1.0'),
error: z.string().optional().default(''),
id: z.string(),
imported_dsl_version: z.string().optional().default(''),
snippet_id: z.string().nullish(),
status: zImportStatus,
})
/**
* AccountWithRoleResponse
*/
export const zAccountWithRoleResponse = z.object({
avatar: z.string().nullish(),
created_at: z.int().nullish(),
email: z.string(),
@ -905,10 +891,10 @@ export const zAccountWithRole = z.object({
})
/**
* AccountWithRoleList
* AccountWithRoleListResponse
*/
export const zAccountWithRoleList = z.object({
accounts: z.array(zAccountWithRole),
export const zAccountWithRoleListResponse = z.object({
accounts: z.array(zAccountWithRoleResponse),
})
/**
@ -1374,6 +1360,53 @@ export const zMcpProviderUpdatePayload = z.object({
server_url: z.string(),
})
/**
* Type
*/
export const zType = z.enum(['github', 'marketplace', 'package'])
/**
* Github
*/
export const zGithub = z.object({
github_plugin_unique_identifier: z.string(),
package: z.string(),
repo: z.string(),
version: z.string(),
})
/**
* Marketplace
*/
export const zMarketplace = z.object({
marketplace_plugin_unique_identifier: z.string(),
version: z.string().nullish(),
})
/**
* Package
*/
export const zPackage = z.object({
plugin_unique_identifier: z.string(),
version: z.string().nullish(),
})
/**
* PluginDependency
*/
export const zPluginDependency = z.object({
current_identifier: z.string().nullish(),
type: zType,
value: z.union([zGithub, zMarketplace, zPackage]),
})
/**
* CheckDependenciesResult
*/
export const zCheckDependenciesResult = z.object({
leaked_dependencies: z.array(zPluginDependency).optional(),
})
/**
* ConfigurateMethod
*
@ -2183,21 +2216,21 @@ export const zGetWorkspacesCurrentCustomizedSnippetsQuery = z.object({
/**
* Snippets retrieved successfully
*/
export const zGetWorkspacesCurrentCustomizedSnippetsResponse = zSnippetPagination
export const zGetWorkspacesCurrentCustomizedSnippetsResponse = zSnippetPaginationResponse
export const zPostWorkspacesCurrentCustomizedSnippetsBody = zCreateSnippetPayload
/**
* Snippet created successfully
*/
export const zPostWorkspacesCurrentCustomizedSnippetsResponse = zSnippet
export const zPostWorkspacesCurrentCustomizedSnippetsResponse = zSnippetResponse
export const zPostWorkspacesCurrentCustomizedSnippetsImportsBody = zSnippetImportPayload
/**
* Snippet imported successfully
*/
export const zPostWorkspacesCurrentCustomizedSnippetsImportsResponse = zSnippetImportResponse
export const zPostWorkspacesCurrentCustomizedSnippetsImportsResponse = zSnippetImportInfo
export const zPostWorkspacesCurrentCustomizedSnippetsImportsByImportIdConfirmPath = z.object({
import_id: z.string(),
@ -2207,7 +2240,7 @@ export const zPostWorkspacesCurrentCustomizedSnippetsImportsByImportIdConfirmPat
* Import confirmed successfully
*/
export const zPostWorkspacesCurrentCustomizedSnippetsImportsByImportIdConfirmResponse
= zSnippetImportResponse
= zSnippetImportInfo
export const zDeleteWorkspacesCurrentCustomizedSnippetsBySnippetIdPath = z.object({
snippet_id: z.uuid(),
@ -2225,7 +2258,7 @@ export const zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdPath = z.object({
/**
* Snippet retrieved successfully
*/
export const zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdResponse = zSnippet
export const zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdResponse = zSnippetResponse
export const zPatchWorkspacesCurrentCustomizedSnippetsBySnippetIdBody = zUpdateSnippetPayload
@ -2236,7 +2269,7 @@ export const zPatchWorkspacesCurrentCustomizedSnippetsBySnippetIdPath = z.object
/**
* Snippet updated successfully
*/
export const zPatchWorkspacesCurrentCustomizedSnippetsBySnippetIdResponse = zSnippet
export const zPatchWorkspacesCurrentCustomizedSnippetsBySnippetIdResponse = zSnippetResponse
export const zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdCheckDependenciesPath = z.object({
snippet_id: z.uuid(),
@ -2246,20 +2279,7 @@ export const zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdCheckDependencies
* Dependencies checked successfully
*/
export const zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdCheckDependenciesResponse
= zSnippetDependencyCheckResponse
export const zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportPath = z.object({
snippet_id: z.uuid(),
})
export const zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportQuery = z.object({
include_secret: z.string().optional().default('false'),
})
/**
* Snippet exported successfully
*/
export const zGetWorkspacesCurrentCustomizedSnippetsBySnippetIdExportResponse = zTextFileResponse
= zCheckDependenciesResult
export const zPostWorkspacesCurrentCustomizedSnippetsBySnippetIdUseCountIncrementPath = z.object({
snippet_id: z.uuid(),
@ -2269,12 +2289,12 @@ export const zPostWorkspacesCurrentCustomizedSnippetsBySnippetIdUseCountIncremen
* Use count incremented successfully
*/
export const zPostWorkspacesCurrentCustomizedSnippetsBySnippetIdUseCountIncrementResponse
= zSnippetUseCountResponse
= zSnippetUseCountIncrementResponse
/**
* Success
*/
export const zGetWorkspacesCurrentDatasetOperatorsResponse = zAccountWithRoleList
export const zGetWorkspacesCurrentDatasetOperatorsResponse = zAccountWithRoleListResponse
export const zGetWorkspacesCurrentDefaultModelQuery = z.object({
model_type: z.enum(['llm', 'moderation', 'rerank', 'speech2text', 'text-embedding', 'tts']),
@ -2378,7 +2398,7 @@ export const zPatchWorkspacesCurrentEndpointsByIdResponse = zEndpointUpdateRespo
/**
* Success
*/
export const zGetWorkspacesCurrentMembersResponse = zAccountWithRoleList
export const zGetWorkspacesCurrentMembersResponse = zAccountWithRoleListResponse
export const zPostWorkspacesCurrentMembersInviteEmailBody = zMemberInvitePayload
@ -3952,7 +3972,11 @@ export const zPostWorkspacesCustomConfigBody = zWorkspaceCustomConfigPayload
/**
* Success
*/
export const zPostWorkspacesCustomConfigResponse = zWorkspaceMutationResponse
export const zPostWorkspacesCustomConfigResponse = zWorkspaceTenantResultResponse
export const zPostWorkspacesCustomConfigWebappLogoUploadBody = z.object({
file: z.custom<Blob | File>(),
})
/**
* Logo uploaded
@ -3964,7 +3988,7 @@ export const zPostWorkspacesInfoBody = zWorkspaceInfoPayload
/**
* Success
*/
export const zPostWorkspacesInfoResponse = zWorkspaceMutationResponse
export const zPostWorkspacesInfoResponse = zWorkspaceTenantResultResponse
export const zPostWorkspacesSwitchBody = zSwitchWorkspacePayload

View File

@ -1414,7 +1414,7 @@ export type SelectInputConfig = {
type?: 'select'
}
export type SimpleAccount = {
export type SimpleAccountResponse = {
email: string
id: string
name: string
@ -1572,7 +1572,7 @@ export type WorkflowAppLogPaginationResponse = {
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

View File

@ -1676,9 +1676,9 @@ export const zProcessRule = z.object({
})
/**
* SimpleAccount
* SimpleAccountResponse
*/
export const zSimpleAccount = z.object({
export const zSimpleAccountResponse = z.object({
email: z.string(),
id: z.string(),
name: z.string(),
@ -2196,7 +2196,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(),

View File

@ -453,11 +453,13 @@ export const forgotPassword = {
/**
* Issue an upload token for a human input form
*
* Issue an upload token for an active human input form
* POST /api/form/human_input/<form_token>/upload-token
*/
export const post13 = oc
.route({
description: 'POST /api/form/human_input/<form_token>/upload-token',
description:
'Issue an upload token for an active human input form\nPOST /api/form/human_input/<form_token>/upload-token',
inputStructure: 'detailed',
method: 'POST',
operationId: 'postFormHumanInputByFormTokenUploadToken',
@ -475,11 +477,13 @@ export const uploadToken = {
/**
* Get human input form definition by token
*
* Get a human input form definition by token
* GET /api/form/human_input/<form_token>
*/
export const get2 = oc
.route({
description: 'GET /api/form/human_input/<form_token>',
description:
'Get a human input form definition by token\nGET /api/form/human_input/<form_token>',
inputStructure: 'detailed',
method: 'GET',
operationId: 'getFormHumanInputByFormToken',
@ -493,6 +497,7 @@ export const get2 = oc
/**
* Submit human input form by token
*
* Submit a human input form by token
* POST /api/form/human_input/<form_token>
*
* Request body:
@ -506,7 +511,7 @@ export const get2 = oc
export const post14 = oc
.route({
description:
'POST /api/form/human_input/<form_token>\n\nRequest body:\n{\n "inputs": {\n "content": "User input content"\n },\n "action": "Approve"\n}',
'Submit a human input form by token\nPOST /api/form/human_input/<form_token>\n\nRequest body:\n{\n "inputs": {\n "content": "User input content"\n },\n "action": "Approve"\n}',
inputStructure: 'detailed',
method: 'POST',
operationId: 'postFormHumanInputByFormToken',

View File

@ -46,47 +46,6 @@ export type AppPermissionQuery = {
appId: string
}
export type AppSiteInfoResponse = {
app_id: string
can_replace_logo: boolean
custom_config?: {
[key: string]: unknown
} | null
enable_site: boolean
end_user_id?: string | null
model_config?: AppSiteModelConfigResponse | null
plan?: string | null
site: AppSiteResponse
}
export type AppSiteModelConfigResponse = {
model: unknown
more_like_this: unknown
opening_statement?: string | null
pre_prompt?: string | null
suggested_questions: unknown
suggested_questions_after_answer: unknown
user_input_form: unknown
}
export type AppSiteResponse = {
chat_color_theme?: string | null
chat_color_theme_inverted?: boolean | null
copyright?: string | null
custom_disclaimer?: string | null
default_language?: string | null
description?: string | null
icon?: string | null
icon_background?: string | null
icon_type?: string | null
icon_url?: string | null
privacy_policy?: string | null
prompt_public?: boolean | null
show_workflow_steps?: boolean | null
title?: string | null
use_icon_as_answer_icon?: boolean | null
}
export type AudioBinaryResponse = Blob | File
export type AudioTranscriptResponse = {
@ -287,15 +246,13 @@ export type HumanInputFormDefinition = {
export type HumanInputFormDefinitionResponse = {
expiration_time: number
form_content: unknown
inputs: unknown
form_content: string
inputs: Array<FormInputConfig>
resolved_default_values: {
[key: string]: string
}
site?: {
[key: string]: unknown
} | null
user_actions: unknown
site?: WebAppSiteResponse | null
user_actions: Array<UserActionConfig>
}
export type HumanInputFormSubmissionData = {
@ -317,7 +274,7 @@ export type HumanInputFormSubmitPayload = {
}
export type HumanInputFormSubmitResponse = {
[key: string]: never
[key: string]: unknown
}
export type HumanInputUploadTokenResponse = {
@ -614,6 +571,22 @@ export type WebAppAuthSsoModel = {
protocol: string
}
export type WebAppCustomConfigResponse = {
remove_webapp_brand: boolean
replace_webapp_logo?: string | null
}
export type WebAppSiteResponse = {
app_id: string
can_replace_logo: boolean
custom_config?: WebAppCustomConfigResponse | null
enable_site: boolean
end_user_id?: string | null
model_config?: WebModelConfigResponse | null
plan: string
site: WebSiteResponse
}
export type WebMessageInfiniteScrollPagination = {
data: Array<WebMessageListItem>
has_more: boolean
@ -640,6 +613,34 @@ export type WebMessageListItem = {
status: string
}
export type WebModelConfigResponse = {
model?: unknown
more_like_this?: unknown
opening_statement?: string | null
pre_prompt?: string | null
suggested_questions?: unknown
suggested_questions_after_answer?: unknown
user_input_form?: unknown
}
export type WebSiteResponse = {
chat_color_theme?: string | null
chat_color_theme_inverted: boolean
copyright?: string | null
custom_disclaimer?: string | null
default_language?: string | null
description?: string | null
icon?: string | null
icon_background?: string | null
icon_type?: string | null
readonly icon_url: string | null
privacy_policy?: string | null
prompt_public?: boolean | null
show_workflow_steps?: boolean | null
title: string
use_icon_as_answer_icon?: boolean | null
}
export type WorkflowRunPayload = {
files?: Array<{
transfer_method: 'local_file' | 'remote_url'
@ -652,6 +653,51 @@ export type WorkflowRunPayload = {
}
}
export type GeneratedAppResponseWritable = JsonValue
export type HumanInputFormDefinitionResponseWritable = {
expiration_time: number
form_content: string
inputs: Array<FormInputConfig>
resolved_default_values: {
[key: string]: string
}
site?: WebAppSiteResponseWritable | null
user_actions: Array<UserActionConfig>
}
export type HumanInputFormSubmitResponseWritable = {
[key: string]: unknown
}
export type WebAppSiteResponseWritable = {
app_id: string
can_replace_logo: boolean
custom_config?: WebAppCustomConfigResponse | null
enable_site: boolean
end_user_id?: string | null
model_config?: WebModelConfigResponse | null
plan: string
site: WebSiteResponseWritable
}
export type WebSiteResponseWritable = {
chat_color_theme?: string | null
chat_color_theme_inverted: boolean
copyright?: string | null
custom_disclaimer?: string | null
default_language?: string | null
description?: string | null
icon?: string | null
icon_background?: string | null
icon_type?: string | null
privacy_policy?: string | null
prompt_public?: boolean | null
show_workflow_steps?: boolean | null
title: string
use_icon_as_answer_icon?: boolean | null
}
export type PostAudioToTextData = {
body?: never
path?: never
@ -1016,6 +1062,13 @@ export type GetFormHumanInputByFormTokenData = {
url: '/form/human_input/{form_token}'
}
export type GetFormHumanInputByFormTokenErrors = {
403: unknown
404: unknown
412: unknown
429: unknown
}
export type GetFormHumanInputByFormTokenResponses = {
200: HumanInputFormDefinitionResponse
}
@ -1032,6 +1085,13 @@ export type PostFormHumanInputByFormTokenData = {
url: '/form/human_input/{form_token}'
}
export type PostFormHumanInputByFormTokenErrors = {
400: unknown
404: unknown
412: unknown
429: unknown
}
export type PostFormHumanInputByFormTokenResponses = {
200: HumanInputFormSubmitResponse
}
@ -1048,6 +1108,12 @@ export type PostFormHumanInputByFormTokenUploadTokenData = {
url: '/form/human_input/{form_token}/upload-token'
}
export type PostFormHumanInputByFormTokenUploadTokenErrors = {
404: unknown
412: unknown
429: unknown
}
export type PostFormHumanInputByFormTokenUploadTokenResponses = {
200: HumanInputUploadTokenResponse
}
@ -1416,7 +1482,7 @@ export type GetSiteErrors = {
}
export type GetSiteResponses = {
200: AppSiteInfoResponse
200: WebAppSiteResponse
}
export type GetSiteResponse = GetSiteResponses[keyof GetSiteResponses]

View File

@ -46,54 +46,6 @@ export const zAppPermissionQuery = z.object({
appId: z.string(),
})
/**
* AppSiteModelConfigResponse
*/
export const zAppSiteModelConfigResponse = z.object({
model: z.unknown(),
more_like_this: z.unknown(),
opening_statement: z.string().nullish(),
pre_prompt: z.string().nullish(),
suggested_questions: z.unknown(),
suggested_questions_after_answer: z.unknown(),
user_input_form: z.unknown(),
})
/**
* AppSiteResponse
*/
export const zAppSiteResponse = z.object({
chat_color_theme: z.string().nullish(),
chat_color_theme_inverted: z.boolean().nullish(),
copyright: z.string().nullish(),
custom_disclaimer: z.string().nullish(),
default_language: z.string().nullish(),
description: z.string().nullish(),
icon: z.string().nullish(),
icon_background: z.string().nullish(),
icon_type: z.string().nullish(),
icon_url: z.string().nullish(),
privacy_policy: z.string().nullish(),
prompt_public: z.boolean().nullish(),
show_workflow_steps: z.boolean().nullish(),
title: z.string().nullish(),
use_icon_as_answer_icon: z.boolean().nullish(),
})
/**
* AppSiteInfoResponse
*/
export const zAppSiteInfoResponse = z.object({
app_id: z.string(),
can_replace_logo: z.boolean(),
custom_config: z.record(z.string(), z.unknown()).nullish(),
enable_site: z.boolean(),
end_user_id: z.string().nullish(),
model_config: zAppSiteModelConfigResponse.nullish(),
plan: z.string().nullish(),
site: zAppSiteResponse,
})
/**
* AudioBinaryResponse
*/
@ -320,22 +272,10 @@ export const zHumanInputFileUploadFormPayload = z.object({
url: z.url().min(1).max(2083).nullish(),
})
/**
* HumanInputFormDefinitionResponse
*/
export const zHumanInputFormDefinitionResponse = z.object({
expiration_time: z.int(),
form_content: z.unknown(),
inputs: z.unknown(),
resolved_default_values: z.record(z.string(), z.string()),
site: z.record(z.string(), z.unknown()).nullish(),
user_actions: z.unknown(),
})
/**
* HumanInputFormSubmitResponse
*/
export const zHumanInputFormSubmitResponse = z.record(z.string(), z.never())
export const zHumanInputFormSubmitResponse = z.record(z.string(), z.unknown())
/**
* HumanInputUploadTokenResponse
@ -874,6 +814,14 @@ export const zSystemFeatureModel = z.object({
}),
})
/**
* WebAppCustomConfigResponse
*/
export const zWebAppCustomConfigResponse = z.object({
remove_webapp_brand: z.boolean(),
replace_webapp_logo: z.string().nullish(),
})
/**
* WebMessageListItem
*/
@ -904,6 +852,66 @@ export const zWebMessageInfiniteScrollPagination = z.object({
limit: z.int(),
})
/**
* WebModelConfigResponse
*/
export const zWebModelConfigResponse = z.object({
model: z.unknown().optional(),
more_like_this: z.unknown().optional(),
opening_statement: z.string().nullish(),
pre_prompt: z.string().nullish(),
suggested_questions: z.unknown().optional(),
suggested_questions_after_answer: z.unknown().optional(),
user_input_form: z.unknown().optional(),
})
/**
* WebSiteResponse
*/
export const zWebSiteResponse = z.object({
chat_color_theme: z.string().nullish(),
chat_color_theme_inverted: z.boolean(),
copyright: z.string().nullish(),
custom_disclaimer: z.string().nullish(),
default_language: z.string().nullish(),
description: z.string().nullish(),
icon: z.string().nullish(),
icon_background: z.string().nullish(),
icon_type: z.string().nullish(),
icon_url: z.string().nullable(),
privacy_policy: z.string().nullish(),
prompt_public: z.boolean().nullish(),
show_workflow_steps: z.boolean().nullish(),
title: z.string(),
use_icon_as_answer_icon: z.boolean().nullish(),
})
/**
* WebAppSiteResponse
*/
export const zWebAppSiteResponse = z.object({
app_id: z.string(),
can_replace_logo: z.boolean(),
custom_config: zWebAppCustomConfigResponse.nullish(),
enable_site: z.boolean(),
end_user_id: z.string().nullish(),
model_config: zWebModelConfigResponse.nullish(),
plan: z.string(),
site: zWebSiteResponse,
})
/**
* HumanInputFormDefinitionResponse
*/
export const zHumanInputFormDefinitionResponse = z.object({
expiration_time: z.int(),
form_content: z.string(),
inputs: z.array(zFormInputConfig),
resolved_default_values: z.record(z.string(), z.string()),
site: zWebAppSiteResponse.nullish(),
user_actions: z.array(zUserActionConfig),
})
/**
* WorkflowRunPayload
*/
@ -921,6 +929,62 @@ export const zWorkflowRunPayload = z.object({
inputs: z.record(z.string(), z.unknown()),
})
/**
* GeneratedAppResponse
*/
export const zGeneratedAppResponseWritable = zJsonValue
/**
* HumanInputFormSubmitResponse
*/
export const zHumanInputFormSubmitResponseWritable = z.record(z.string(), z.unknown())
/**
* WebSiteResponse
*/
export const zWebSiteResponseWritable = z.object({
chat_color_theme: z.string().nullish(),
chat_color_theme_inverted: z.boolean(),
copyright: z.string().nullish(),
custom_disclaimer: z.string().nullish(),
default_language: z.string().nullish(),
description: z.string().nullish(),
icon: z.string().nullish(),
icon_background: z.string().nullish(),
icon_type: z.string().nullish(),
privacy_policy: z.string().nullish(),
prompt_public: z.boolean().nullish(),
show_workflow_steps: z.boolean().nullish(),
title: z.string(),
use_icon_as_answer_icon: z.boolean().nullish(),
})
/**
* WebAppSiteResponse
*/
export const zWebAppSiteResponseWritable = z.object({
app_id: z.string(),
can_replace_logo: z.boolean(),
custom_config: zWebAppCustomConfigResponse.nullish(),
enable_site: z.boolean(),
end_user_id: z.string().nullish(),
model_config: zWebModelConfigResponse.nullish(),
plan: z.string(),
site: zWebSiteResponseWritable,
})
/**
* HumanInputFormDefinitionResponse
*/
export const zHumanInputFormDefinitionResponseWritable = z.object({
expiration_time: z.int(),
form_content: z.string(),
inputs: z.array(zFormInputConfig),
resolved_default_values: z.record(z.string(), z.string()),
site: zWebAppSiteResponseWritable.nullish(),
user_actions: z.array(zUserActionConfig),
})
/**
* Success
*/
@ -1061,7 +1125,7 @@ export const zGetFormHumanInputByFormTokenPath = z.object({
})
/**
* Success
* Form retrieved successfully
*/
export const zGetFormHumanInputByFormTokenResponse = zHumanInputFormDefinitionResponse
@ -1072,7 +1136,7 @@ export const zPostFormHumanInputByFormTokenPath = z.object({
})
/**
* Success
* Form submitted successfully
*/
export const zPostFormHumanInputByFormTokenResponse = zHumanInputFormSubmitResponse
@ -1081,7 +1145,7 @@ export const zPostFormHumanInputByFormTokenUploadTokenPath = z.object({
})
/**
* Success
* Upload token issued successfully
*/
export const zPostFormHumanInputByFormTokenUploadTokenResponse = zHumanInputUploadTokenResponse
@ -1229,7 +1293,7 @@ export const zDeleteSavedMessagesByMessageIdResponse = z.void()
/**
* Success
*/
export const zGetSiteResponse = zAppSiteInfoResponse
export const zGetSiteResponse = zWebAppSiteResponse
/**
* System features retrieved successfully

View File

@ -10,13 +10,21 @@ type SwaggerSchema = JsonObject & {
$ref?: string
}
type OpenApiMediaType = JsonObject & {
schema?: SwaggerSchema
}
type OpenApiResponse = JsonObject & {
content?: Record<string, OpenApiMediaType>
}
type OpenApiComponents = JsonObject & {
schemas?: Record<string, SwaggerSchema>
}
type SwaggerOperation = JsonObject & {
operationId?: string
responses?: Record<string, unknown>
responses?: Record<string, OpenApiResponse>
}
type SwaggerDocument = JsonObject & {
@ -52,6 +60,17 @@ const currentDir = path.dirname(fileURLToPath(import.meta.url))
const apiOpenApiDir = path.resolve(currentDir, 'openapi')
const operationMethods = new Set(['delete', 'get', 'patch', 'post', 'put'])
const pydanticDecimalStringPattern = '^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$'
const codegenSafeDecimalStringPattern = '^(?![-+.]*$)[+-]?0*\\d*\\.?\\d*$'
const opaqueJsonContent = (): Record<string, OpenApiMediaType> => ({
'application/json': {
schema: {
additionalProperties: true,
type: 'object',
},
},
})
const apiSpecs: ApiSpec[] = [
{ filename: 'console-openapi.json', name: 'console' },
@ -182,6 +201,46 @@ const addOperationIds = (document: SwaggerDocument) => {
}
}
const isOpaqueContractResponse = (response: OpenApiResponse) => {
const content = response.content
if (!isObject(content))
return false
return Object.entries(content).some(([mediaType, media]) => {
if (!isObject(media))
return false
return (mediaType === 'application/json' || mediaType === 'text/event-stream') && !('schema' in media)
})
}
const hasOpaqueContractSuccessResponse = (operation: SwaggerOperation) => {
return Object.entries(operation.responses ?? {}).some(([status, response]) => {
return /^2\d\d$/.test(status) && isObject(response) && isOpaqueContractResponse(response)
})
}
const normalizeOpaqueContractResponses = (document: SwaggerDocument) => {
// Some backend endpoints has no schema (e.g. external) and will trap heyapi here
// So we forge an opaque schema here
for (const pathItem of Object.values(document.paths ?? {})) {
for (const [method, operation] of Object.entries(pathItem)) {
if (!operationMethods.has(method) || !isObject(operation))
continue
const swaggerOperation = operation as SwaggerOperation
if (!hasOpaqueContractSuccessResponse(swaggerOperation))
continue
Object.values(swaggerOperation.responses ?? {})
.filter(response => isObject(response) && isOpaqueContractResponse(response))
.forEach((response) => {
response.content = opaqueJsonContent()
})
}
}
}
const hasSuccessResponse = (operation: SwaggerOperation) => {
return Object.entries(operation.responses ?? {}).some(([status, response]) => {
if (!/^2\d\d$/.test(status))
@ -215,6 +274,7 @@ const filterContractOperations = (document: SwaggerDocument) => {
}
const normalizeApiSwagger = (document: SwaggerDocument) => {
normalizeOpaqueContractResponses(document)
filterContractOperations(document)
addOperationIds(document)
@ -380,10 +440,20 @@ const createApiConfig = (job: ApiJob): UserConfig => ({
'name': 'zod',
'~resolvers': {
string: (ctx) => {
if (ctx.schema.format !== 'binary')
return undefined
if (ctx.schema.format === 'binary')
return $(ctx.symbols.z).attr('custom').call().generic($.type.or($.type('Blob'), $.type('File')))
return $(ctx.symbols.z).attr('custom').call().generic($.type.or($.type('Blob'), $.type('File')))
if (ctx.schema.pattern === pydanticDecimalStringPattern) {
// the pydantic generated regex will emit error like
// regexp/no-useless-assertions, so patch the regex here
return $(ctx.symbols.z)
.attr('string')
.call()
.attr('regex')
.call($.regexp(codegenSafeDecimalStringPattern))
}
return undefined
},
},
},

View File

@ -217,14 +217,8 @@ const toFeedback = (feedback: NonNullable<MessageDetailResponse['feedbacks']>[nu
}
}
type AgentDebugMessageWithLegacyAnswer = MessageDetailResponse & {
answer?: string | null
}
const getAgentDebugMessageAnswer = (message: MessageDetailResponse) => {
const legacyAnswer = (message as AgentDebugMessageWithLegacyAnswer).answer
return message.re_sign_file_url_answer ?? legacyAnswer ?? ''
return message.answer ?? ''
}
function getFormattedAgentDebugChatTree(messages: MessageDetailResponse[]): ChatItemInTree[] {