mirror of
https://github.com/langgenius/dify.git
synced 2026-09-08 11:04:27 +08:00
refactor(api): migrate workspace tool endpoints to BaseModel (#37959)
This commit is contained in:
parent
af5b08ac5c
commit
74f177efe6
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,19 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Any, Literal
|
from typing import Any
|
||||||
|
|
||||||
from flask import make_response, redirect, request
|
from flask import make_response, redirect, request
|
||||||
from flask_restx import Resource
|
from flask_restx import Resource
|
||||||
from pydantic import BaseModel, Field, RootModel, model_validator
|
from pydantic import BaseModel, RootModel, model_validator
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
from werkzeug.exceptions import BadRequest, Forbidden
|
from werkzeug.exceptions import BadRequest, Forbidden
|
||||||
|
|
||||||
from configs import dify_config
|
from configs import dify_config
|
||||||
from controllers.common.errors import NotFoundError
|
from controllers.common.errors import NotFoundError
|
||||||
from controllers.common.fields import BinaryFileResponse, RedirectResponse, SimpleResultResponse
|
from controllers.common.fields import SimpleResultResponse
|
||||||
from controllers.common.schema import register_response_schema_models, register_schema_models
|
from controllers.common.schema import register_response_schema_models, register_schema_models
|
||||||
from core.entities.parameter_entities import AppSelectorScope, ModelSelectorScope, ToolSelectorScope
|
from core.entities.provider_entities import ProviderConfig
|
||||||
from core.plugin.entities.plugin_daemon import CredentialType
|
from core.plugin.entities.plugin_daemon import CredentialType
|
||||||
from core.plugin.impl.oauth import OAuthHandler
|
from core.plugin.impl.oauth import OAuthHandler
|
||||||
from core.tools.entities.common_entities import I18nObject
|
|
||||||
from core.trigger.entities.api_entities import (
|
from core.trigger.entities.api_entities import (
|
||||||
SubscriptionBuilderApiEntity,
|
SubscriptionBuilderApiEntity,
|
||||||
TriggerProviderApiEntity,
|
TriggerProviderApiEntity,
|
||||||
@ -24,7 +23,7 @@ from core.trigger.entities.entities import RequestLog, SubscriptionBuilderUpdate
|
|||||||
from core.trigger.trigger_manager import TriggerManager
|
from core.trigger.trigger_manager import TriggerManager
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
from fields.base import ResponseModel
|
from fields.base import ResponseModel
|
||||||
from graphon.model_runtime.utils.encoders import jsonable_encoder
|
from libs.helper import dump_response
|
||||||
from libs.login import login_required
|
from libs.login import login_required
|
||||||
from models.account import Account
|
from models.account import Account
|
||||||
from models.provider_ids import TriggerProviderID
|
from models.provider_ids import TriggerProviderID
|
||||||
@ -59,9 +58,9 @@ class TriggerSubscriptionBuilderVerifyPayload(BaseModel):
|
|||||||
|
|
||||||
class TriggerSubscriptionBuilderUpdatePayload(BaseModel):
|
class TriggerSubscriptionBuilderUpdatePayload(BaseModel):
|
||||||
name: str | None = None
|
name: str | None = None
|
||||||
parameters: dict[str, Any] | None = Field(default=None)
|
parameters: dict[str, Any] | None = None
|
||||||
properties: dict[str, Any] | None = Field(default=None)
|
properties: dict[str, Any] | None = None
|
||||||
credentials: dict[str, Any] | None = Field(default=None)
|
credentials: dict[str, Any] | None = None
|
||||||
|
|
||||||
@model_validator(mode="after")
|
@model_validator(mode="after")
|
||||||
def check_at_least_one_field(self):
|
def check_at_least_one_field(self):
|
||||||
@ -71,70 +70,23 @@ class TriggerSubscriptionBuilderUpdatePayload(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class TriggerOAuthClientPayload(BaseModel):
|
class TriggerOAuthClientPayload(BaseModel):
|
||||||
client_params: dict[str, Any] | None = Field(default=None)
|
client_params: dict[str, Any] | None = None
|
||||||
enabled: bool | None = None
|
enabled: bool | None = None
|
||||||
|
|
||||||
|
|
||||||
class TriggerOAuthAuthorizeResponse(BaseModel):
|
|
||||||
authorization_url: str
|
|
||||||
subscription_builder_id: str
|
|
||||||
subscription_builder: SubscriptionBuilderApiEntity
|
|
||||||
|
|
||||||
|
|
||||||
class TriggerProviderConfigOptionResponse(BaseModel):
|
|
||||||
value: str = Field(..., description="The value of the option")
|
|
||||||
label: I18nObject = Field(..., description="The label of the option")
|
|
||||||
|
|
||||||
|
|
||||||
class TriggerProviderConfigResponse(BaseModel):
|
|
||||||
type: Literal[
|
|
||||||
"secret-input",
|
|
||||||
"text-input",
|
|
||||||
"select",
|
|
||||||
"boolean",
|
|
||||||
"app-selector",
|
|
||||||
"model-selector",
|
|
||||||
"array[tools]",
|
|
||||||
] = Field(..., description="The type of the credentials")
|
|
||||||
name: str = Field(..., description="The name of the credentials")
|
|
||||||
scope: AppSelectorScope | ModelSelectorScope | ToolSelectorScope | None = None
|
|
||||||
required: bool = False
|
|
||||||
default: int | str | float | bool | None = None
|
|
||||||
options: list[TriggerProviderConfigOptionResponse] | None = None
|
|
||||||
multiple: bool = False
|
|
||||||
label: I18nObject | None = None
|
|
||||||
help: I18nObject | None = None
|
|
||||||
url: str | None = None
|
|
||||||
placeholder: I18nObject | None = None
|
|
||||||
|
|
||||||
|
|
||||||
class TriggerOAuthClientResponse(BaseModel):
|
|
||||||
configured: bool
|
|
||||||
system_configured: bool
|
|
||||||
custom_configured: bool
|
|
||||||
oauth_client_schema: list[TriggerProviderConfigResponse]
|
|
||||||
custom_enabled: bool
|
|
||||||
redirect_uri: str
|
|
||||||
params: dict[str, Any]
|
|
||||||
|
|
||||||
|
|
||||||
class TriggerProviderOpaqueResponse(RootModel[Any]):
|
|
||||||
root: Any
|
|
||||||
|
|
||||||
|
|
||||||
class TriggerProviderListResponse(RootModel[list[TriggerProviderApiEntity]]):
|
class TriggerProviderListResponse(RootModel[list[TriggerProviderApiEntity]]):
|
||||||
root: list[TriggerProviderApiEntity]
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TriggerSubscriptionListResponse(RootModel[list[TriggerProviderSubscriptionApiEntity]]):
|
class TriggerProviderSubscriptionListResponse(RootModel[list[TriggerProviderSubscriptionApiEntity]]):
|
||||||
root: list[TriggerProviderSubscriptionApiEntity]
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TriggerSubscriptionBuilderCreateResponse(ResponseModel):
|
class TriggerSubscriptionBuilderCreateResponse(ResponseModel):
|
||||||
subscription_builder: SubscriptionBuilderApiEntity
|
subscription_builder: SubscriptionBuilderApiEntity
|
||||||
|
|
||||||
|
|
||||||
class TriggerSubscriptionBuilderVerifyResponse(ResponseModel):
|
class TriggerVerificationResponse(ResponseModel):
|
||||||
verified: bool
|
verified: bool
|
||||||
|
|
||||||
|
|
||||||
@ -142,6 +94,26 @@ class TriggerSubscriptionBuilderLogsResponse(ResponseModel):
|
|||||||
logs: list[RequestLog]
|
logs: list[RequestLog]
|
||||||
|
|
||||||
|
|
||||||
|
class TriggerOAuthAuthorizeResponse(ResponseModel):
|
||||||
|
authorization_url: str
|
||||||
|
subscription_builder_id: str
|
||||||
|
subscription_builder: SubscriptionBuilderApiEntity
|
||||||
|
|
||||||
|
|
||||||
|
class TriggerOAuthClientResponse(ResponseModel):
|
||||||
|
configured: bool
|
||||||
|
system_configured: bool
|
||||||
|
custom_configured: bool
|
||||||
|
oauth_client_schema: list[ProviderConfig]
|
||||||
|
custom_enabled: bool
|
||||||
|
redirect_uri: str
|
||||||
|
params: dict[str, Any]
|
||||||
|
|
||||||
|
|
||||||
|
class TriggerProviderErrorResponse(ResponseModel):
|
||||||
|
error: str
|
||||||
|
|
||||||
|
|
||||||
register_schema_models(
|
register_schema_models(
|
||||||
console_ns,
|
console_ns,
|
||||||
TriggerSubscriptionBuilderCreatePayload,
|
TriggerSubscriptionBuilderCreatePayload,
|
||||||
@ -151,27 +123,24 @@ register_schema_models(
|
|||||||
)
|
)
|
||||||
register_response_schema_models(
|
register_response_schema_models(
|
||||||
console_ns,
|
console_ns,
|
||||||
BinaryFileResponse,
|
|
||||||
RedirectResponse,
|
|
||||||
SimpleResultResponse,
|
SimpleResultResponse,
|
||||||
TriggerOAuthAuthorizeResponse,
|
TriggerOAuthAuthorizeResponse,
|
||||||
TriggerOAuthClientResponse,
|
TriggerOAuthClientResponse,
|
||||||
TriggerProviderOpaqueResponse,
|
|
||||||
TriggerProviderApiEntity,
|
TriggerProviderApiEntity,
|
||||||
|
TriggerProviderErrorResponse,
|
||||||
TriggerProviderListResponse,
|
TriggerProviderListResponse,
|
||||||
TriggerProviderSubscriptionApiEntity,
|
TriggerProviderSubscriptionListResponse,
|
||||||
TriggerSubscriptionListResponse,
|
|
||||||
SubscriptionBuilderApiEntity,
|
|
||||||
TriggerSubscriptionBuilderCreateResponse,
|
TriggerSubscriptionBuilderCreateResponse,
|
||||||
TriggerSubscriptionBuilderVerifyResponse,
|
|
||||||
RequestLog,
|
|
||||||
TriggerSubscriptionBuilderLogsResponse,
|
TriggerSubscriptionBuilderLogsResponse,
|
||||||
|
SubscriptionBuilderApiEntity,
|
||||||
|
TriggerVerificationResponse,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@console_ns.route("/workspaces/current/trigger-provider/<path:provider>/icon")
|
@console_ns.route("/workspaces/current/trigger-provider/<path:provider>/icon")
|
||||||
class TriggerProviderIconApi(Resource):
|
class TriggerProviderIconApi(Resource):
|
||||||
@console_ns.response(200, "Success", console_ns.models[BinaryFileResponse.__name__])
|
# response-contract:ignore binary trigger provider icon
|
||||||
|
@console_ns.response(200, "Trigger provider icon")
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@account_initialization_required
|
@account_initialization_required
|
||||||
@ -182,31 +151,45 @@ class TriggerProviderIconApi(Resource):
|
|||||||
|
|
||||||
@console_ns.route("/workspaces/current/triggers")
|
@console_ns.route("/workspaces/current/triggers")
|
||||||
class TriggerProviderListApi(Resource):
|
class TriggerProviderListApi(Resource):
|
||||||
@console_ns.response(200, "Success", console_ns.models[TriggerProviderListResponse.__name__])
|
@console_ns.response(
|
||||||
|
200,
|
||||||
|
"Trigger providers retrieved successfully",
|
||||||
|
console_ns.models[TriggerProviderListResponse.__name__],
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@account_initialization_required
|
@account_initialization_required
|
||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def get(self, tenant_id: str):
|
def get(self, tenant_id: str):
|
||||||
"""List all trigger providers for the current tenant"""
|
"""List all trigger providers for the current tenant"""
|
||||||
return jsonable_encoder(TriggerProviderService.list_trigger_providers(tenant_id))
|
return dump_response(TriggerProviderListResponse, TriggerProviderService.list_trigger_providers(tenant_id))
|
||||||
|
|
||||||
|
|
||||||
@console_ns.route("/workspaces/current/trigger-provider/<path:provider>/info")
|
@console_ns.route("/workspaces/current/trigger-provider/<path:provider>/info")
|
||||||
class TriggerProviderInfoApi(Resource):
|
class TriggerProviderInfoApi(Resource):
|
||||||
@console_ns.response(200, "Success", console_ns.models[TriggerProviderApiEntity.__name__])
|
@console_ns.response(
|
||||||
|
200,
|
||||||
|
"Trigger provider retrieved successfully",
|
||||||
|
console_ns.models[TriggerProviderApiEntity.__name__],
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@account_initialization_required
|
@account_initialization_required
|
||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def get(self, tenant_id: str, provider: str):
|
def get(self, tenant_id: str, provider: str):
|
||||||
"""Get info for a trigger provider"""
|
"""Get info for a trigger provider"""
|
||||||
return jsonable_encoder(TriggerProviderService.get_trigger_provider(tenant_id, TriggerProviderID(provider)))
|
provider_entity = TriggerProviderService.get_trigger_provider(tenant_id, TriggerProviderID(provider))
|
||||||
|
return provider_entity.model_dump(mode="json")
|
||||||
|
|
||||||
|
|
||||||
@console_ns.route("/workspaces/current/trigger-provider/<path:provider>/subscriptions/list")
|
@console_ns.route("/workspaces/current/trigger-provider/<path:provider>/subscriptions/list")
|
||||||
class TriggerSubscriptionListApi(Resource):
|
class TriggerSubscriptionListApi(Resource):
|
||||||
@console_ns.response(200, "Success", console_ns.models[TriggerSubscriptionListResponse.__name__])
|
@console_ns.response(
|
||||||
|
200,
|
||||||
|
"Trigger subscriptions retrieved successfully",
|
||||||
|
console_ns.models[TriggerProviderSubscriptionListResponse.__name__],
|
||||||
|
)
|
||||||
|
@console_ns.response(404, "Trigger provider not found", console_ns.models[TriggerProviderErrorResponse.__name__])
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@edit_permission_required
|
@edit_permission_required
|
||||||
@ -216,16 +199,18 @@ class TriggerSubscriptionListApi(Resource):
|
|||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def get(self, tenant_id: str, user: Account, provider: str):
|
def get(self, tenant_id: str, user: Account, provider: str):
|
||||||
"""List all trigger subscriptions for the current tenant's provider"""
|
"""List all trigger subscriptions for the current tenant's provider"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return jsonable_encoder(
|
return dump_response(
|
||||||
|
TriggerProviderSubscriptionListResponse,
|
||||||
TriggerProviderService.list_trigger_provider_subscriptions(
|
TriggerProviderService.list_trigger_provider_subscriptions(
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
provider_id=TriggerProviderID(provider),
|
provider_id=TriggerProviderID(provider),
|
||||||
user=user,
|
user=user,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
return jsonable_encoder({"error": str(e)}), 404
|
return TriggerProviderErrorResponse(error=str(e)).model_dump(mode="json"), 404
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("Error listing trigger providers", exc_info=e)
|
logger.exception("Error listing trigger providers", exc_info=e)
|
||||||
raise
|
raise
|
||||||
@ -236,7 +221,11 @@ class TriggerSubscriptionListApi(Resource):
|
|||||||
)
|
)
|
||||||
class TriggerSubscriptionBuilderCreateApi(Resource):
|
class TriggerSubscriptionBuilderCreateApi(Resource):
|
||||||
@console_ns.expect(console_ns.models[TriggerSubscriptionBuilderCreatePayload.__name__])
|
@console_ns.expect(console_ns.models[TriggerSubscriptionBuilderCreatePayload.__name__])
|
||||||
@console_ns.response(200, "Success", console_ns.models[TriggerSubscriptionBuilderCreateResponse.__name__])
|
@console_ns.response(
|
||||||
|
200,
|
||||||
|
"Trigger subscription builder created successfully",
|
||||||
|
console_ns.models[TriggerSubscriptionBuilderCreateResponse.__name__],
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@edit_permission_required
|
@edit_permission_required
|
||||||
@ -246,6 +235,7 @@ class TriggerSubscriptionBuilderCreateApi(Resource):
|
|||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def post(self, tenant_id: str, user: Account, provider: str):
|
def post(self, tenant_id: str, user: Account, provider: str):
|
||||||
"""Add a new subscription instance for a trigger provider"""
|
"""Add a new subscription instance for a trigger provider"""
|
||||||
|
|
||||||
payload = TriggerSubscriptionBuilderCreatePayload.model_validate(console_ns.payload or {})
|
payload = TriggerSubscriptionBuilderCreatePayload.model_validate(console_ns.payload or {})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -256,7 +246,9 @@ class TriggerSubscriptionBuilderCreateApi(Resource):
|
|||||||
provider_id=TriggerProviderID(provider),
|
provider_id=TriggerProviderID(provider),
|
||||||
credential_type=credential_type,
|
credential_type=credential_type,
|
||||||
)
|
)
|
||||||
return jsonable_encoder({"subscription_builder": subscription_builder})
|
return TriggerSubscriptionBuilderCreateResponse(subscription_builder=subscription_builder).model_dump(
|
||||||
|
mode="json"
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("Error adding provider credential", exc_info=e)
|
logger.exception("Error adding provider credential", exc_info=e)
|
||||||
raise
|
raise
|
||||||
@ -266,7 +258,11 @@ class TriggerSubscriptionBuilderCreateApi(Resource):
|
|||||||
"/workspaces/current/trigger-provider/<path:provider>/subscriptions/builder/<path:subscription_builder_id>",
|
"/workspaces/current/trigger-provider/<path:provider>/subscriptions/builder/<path:subscription_builder_id>",
|
||||||
)
|
)
|
||||||
class TriggerSubscriptionBuilderGetApi(Resource):
|
class TriggerSubscriptionBuilderGetApi(Resource):
|
||||||
@console_ns.response(200, "Success", console_ns.models[SubscriptionBuilderApiEntity.__name__])
|
@console_ns.response(
|
||||||
|
200,
|
||||||
|
"Trigger subscription builder retrieved successfully",
|
||||||
|
console_ns.models[SubscriptionBuilderApiEntity.__name__],
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@edit_permission_required
|
@edit_permission_required
|
||||||
@ -274,9 +270,8 @@ class TriggerSubscriptionBuilderGetApi(Resource):
|
|||||||
@account_initialization_required
|
@account_initialization_required
|
||||||
def get(self, provider: str, subscription_builder_id: str):
|
def get(self, provider: str, subscription_builder_id: str):
|
||||||
"""Get a subscription instance for a trigger provider"""
|
"""Get a subscription instance for a trigger provider"""
|
||||||
return jsonable_encoder(
|
subscription_builder = TriggerSubscriptionBuilderService.get_subscription_builder_by_id(subscription_builder_id)
|
||||||
TriggerSubscriptionBuilderService.get_subscription_builder_by_id(subscription_builder_id)
|
return subscription_builder.model_dump(mode="json")
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@console_ns.route(
|
@console_ns.route(
|
||||||
@ -284,7 +279,11 @@ class TriggerSubscriptionBuilderGetApi(Resource):
|
|||||||
)
|
)
|
||||||
class TriggerSubscriptionBuilderVerifyApi(Resource):
|
class TriggerSubscriptionBuilderVerifyApi(Resource):
|
||||||
@console_ns.expect(console_ns.models[TriggerSubscriptionBuilderVerifyPayload.__name__])
|
@console_ns.expect(console_ns.models[TriggerSubscriptionBuilderVerifyPayload.__name__])
|
||||||
@console_ns.response(200, "Success", console_ns.models[TriggerSubscriptionBuilderVerifyResponse.__name__])
|
@console_ns.response(
|
||||||
|
200,
|
||||||
|
"Trigger subscription builder verified successfully",
|
||||||
|
console_ns.models[TriggerVerificationResponse.__name__],
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@edit_permission_required
|
@edit_permission_required
|
||||||
@ -294,11 +293,12 @@ class TriggerSubscriptionBuilderVerifyApi(Resource):
|
|||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def post(self, tenant_id: str, user: Account, provider: str, subscription_builder_id: str):
|
def post(self, tenant_id: str, user: Account, provider: str, subscription_builder_id: str):
|
||||||
"""Verify and update a subscription instance for a trigger provider"""
|
"""Verify and update a subscription instance for a trigger provider"""
|
||||||
|
|
||||||
payload = TriggerSubscriptionBuilderVerifyPayload.model_validate(console_ns.payload or {})
|
payload = TriggerSubscriptionBuilderVerifyPayload.model_validate(console_ns.payload or {})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Use atomic update_and_verify to prevent race conditions
|
# Use atomic update_and_verify to prevent race conditions
|
||||||
return TriggerSubscriptionBuilderService.update_and_verify_builder(
|
result = TriggerSubscriptionBuilderService.update_and_verify_builder(
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
provider_id=TriggerProviderID(provider),
|
provider_id=TriggerProviderID(provider),
|
||||||
@ -307,6 +307,7 @@ class TriggerSubscriptionBuilderVerifyApi(Resource):
|
|||||||
credentials=payload.credentials,
|
credentials=payload.credentials,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
return dump_response(TriggerVerificationResponse, result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("Error verifying provider credential", exc_info=e)
|
logger.exception("Error verifying provider credential", exc_info=e)
|
||||||
raise ValueError(str(e)) from e
|
raise ValueError(str(e)) from e
|
||||||
@ -317,7 +318,11 @@ class TriggerSubscriptionBuilderVerifyApi(Resource):
|
|||||||
)
|
)
|
||||||
class TriggerSubscriptionBuilderUpdateApi(Resource):
|
class TriggerSubscriptionBuilderUpdateApi(Resource):
|
||||||
@console_ns.expect(console_ns.models[TriggerSubscriptionBuilderUpdatePayload.__name__])
|
@console_ns.expect(console_ns.models[TriggerSubscriptionBuilderUpdatePayload.__name__])
|
||||||
@console_ns.response(200, "Success", console_ns.models[SubscriptionBuilderApiEntity.__name__])
|
@console_ns.response(
|
||||||
|
200,
|
||||||
|
"Trigger subscription builder updated successfully",
|
||||||
|
console_ns.models[SubscriptionBuilderApiEntity.__name__],
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@edit_permission_required
|
@edit_permission_required
|
||||||
@ -326,21 +331,20 @@ class TriggerSubscriptionBuilderUpdateApi(Resource):
|
|||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def post(self, tenant_id: str, provider: str, subscription_builder_id: str):
|
def post(self, tenant_id: str, provider: str, subscription_builder_id: str):
|
||||||
"""Update a subscription instance for a trigger provider"""
|
"""Update a subscription instance for a trigger provider"""
|
||||||
|
|
||||||
payload = TriggerSubscriptionBuilderUpdatePayload.model_validate(console_ns.payload or {})
|
payload = TriggerSubscriptionBuilderUpdatePayload.model_validate(console_ns.payload or {})
|
||||||
try:
|
try:
|
||||||
return jsonable_encoder(
|
return TriggerSubscriptionBuilderService.update_trigger_subscription_builder(
|
||||||
TriggerSubscriptionBuilderService.update_trigger_subscription_builder(
|
tenant_id=tenant_id,
|
||||||
tenant_id=tenant_id,
|
provider_id=TriggerProviderID(provider),
|
||||||
provider_id=TriggerProviderID(provider),
|
subscription_builder_id=subscription_builder_id,
|
||||||
subscription_builder_id=subscription_builder_id,
|
subscription_builder_updater=SubscriptionBuilderUpdater(
|
||||||
subscription_builder_updater=SubscriptionBuilderUpdater(
|
name=payload.name,
|
||||||
name=payload.name,
|
parameters=payload.parameters,
|
||||||
parameters=payload.parameters,
|
properties=payload.properties,
|
||||||
properties=payload.properties,
|
credentials=payload.credentials,
|
||||||
credentials=payload.credentials,
|
),
|
||||||
),
|
).model_dump(mode="json")
|
||||||
)
|
|
||||||
)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("Error updating provider credential", exc_info=e)
|
logger.exception("Error updating provider credential", exc_info=e)
|
||||||
raise
|
raise
|
||||||
@ -350,7 +354,11 @@ class TriggerSubscriptionBuilderUpdateApi(Resource):
|
|||||||
"/workspaces/current/trigger-provider/<path:provider>/subscriptions/builder/logs/<path:subscription_builder_id>",
|
"/workspaces/current/trigger-provider/<path:provider>/subscriptions/builder/logs/<path:subscription_builder_id>",
|
||||||
)
|
)
|
||||||
class TriggerSubscriptionBuilderLogsApi(Resource):
|
class TriggerSubscriptionBuilderLogsApi(Resource):
|
||||||
@console_ns.response(200, "Success", console_ns.models[TriggerSubscriptionBuilderLogsResponse.__name__])
|
@console_ns.response(
|
||||||
|
200,
|
||||||
|
"Trigger subscription builder logs retrieved successfully",
|
||||||
|
console_ns.models[TriggerSubscriptionBuilderLogsResponse.__name__],
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@edit_permission_required
|
@edit_permission_required
|
||||||
@ -358,9 +366,10 @@ class TriggerSubscriptionBuilderLogsApi(Resource):
|
|||||||
@account_initialization_required
|
@account_initialization_required
|
||||||
def get(self, provider: str, subscription_builder_id: str):
|
def get(self, provider: str, subscription_builder_id: str):
|
||||||
"""Get the request logs for a subscription instance for a trigger provider"""
|
"""Get the request logs for a subscription instance for a trigger provider"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logs = TriggerSubscriptionBuilderService.list_logs(subscription_builder_id)
|
logs = TriggerSubscriptionBuilderService.list_logs(subscription_builder_id)
|
||||||
return jsonable_encoder({"logs": [log.model_dump(mode="json") for log in logs]})
|
return dump_response(TriggerSubscriptionBuilderLogsResponse, {"logs": logs})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("Error getting request logs for subscription builder", exc_info=e)
|
logger.exception("Error getting request logs for subscription builder", exc_info=e)
|
||||||
raise
|
raise
|
||||||
@ -371,7 +380,9 @@ class TriggerSubscriptionBuilderLogsApi(Resource):
|
|||||||
)
|
)
|
||||||
class TriggerSubscriptionBuilderBuildApi(Resource):
|
class TriggerSubscriptionBuilderBuildApi(Resource):
|
||||||
@console_ns.expect(console_ns.models[TriggerSubscriptionBuilderUpdatePayload.__name__])
|
@console_ns.expect(console_ns.models[TriggerSubscriptionBuilderUpdatePayload.__name__])
|
||||||
@console_ns.response(200, "Success", console_ns.models[TriggerProviderOpaqueResponse.__name__])
|
@console_ns.response(
|
||||||
|
200, "Trigger subscription builder built successfully", console_ns.models[SimpleResultResponse.__name__]
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@edit_permission_required
|
@edit_permission_required
|
||||||
@ -395,7 +406,7 @@ class TriggerSubscriptionBuilderBuildApi(Resource):
|
|||||||
properties=payload.properties,
|
properties=payload.properties,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return 200
|
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("Error building provider credential", exc_info=e)
|
logger.exception("Error building provider credential", exc_info=e)
|
||||||
raise ValueError(str(e)) from e
|
raise ValueError(str(e)) from e
|
||||||
@ -406,7 +417,9 @@ class TriggerSubscriptionBuilderBuildApi(Resource):
|
|||||||
)
|
)
|
||||||
class TriggerSubscriptionUpdateApi(Resource):
|
class TriggerSubscriptionUpdateApi(Resource):
|
||||||
@console_ns.expect(console_ns.models[TriggerSubscriptionBuilderUpdatePayload.__name__])
|
@console_ns.expect(console_ns.models[TriggerSubscriptionBuilderUpdatePayload.__name__])
|
||||||
@console_ns.response(200, "Success", console_ns.models[TriggerProviderOpaqueResponse.__name__])
|
@console_ns.response(
|
||||||
|
200, "Trigger subscription updated successfully", console_ns.models[SimpleResultResponse.__name__]
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@edit_permission_required
|
@edit_permission_required
|
||||||
@ -415,6 +428,7 @@ class TriggerSubscriptionUpdateApi(Resource):
|
|||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def post(self, tenant_id: str, subscription_id: str):
|
def post(self, tenant_id: str, subscription_id: str):
|
||||||
"""Update a subscription instance"""
|
"""Update a subscription instance"""
|
||||||
|
|
||||||
request = TriggerSubscriptionBuilderUpdatePayload.model_validate(console_ns.payload or {})
|
request = TriggerSubscriptionBuilderUpdatePayload.model_validate(console_ns.payload or {})
|
||||||
|
|
||||||
subscription = TriggerProviderService.get_subscription_by_id(
|
subscription = TriggerProviderService.get_subscription_by_id(
|
||||||
@ -440,7 +454,7 @@ class TriggerSubscriptionUpdateApi(Resource):
|
|||||||
name=request.name,
|
name=request.name,
|
||||||
properties=request.properties,
|
properties=request.properties,
|
||||||
)
|
)
|
||||||
return 200
|
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||||
|
|
||||||
# For the rest cases(API_KEY, OAUTH2)
|
# For the rest cases(API_KEY, OAUTH2)
|
||||||
# we need to call third party provider(e.g. GitHub) to rebuild the subscription
|
# we need to call third party provider(e.g. GitHub) to rebuild the subscription
|
||||||
@ -452,7 +466,7 @@ class TriggerSubscriptionUpdateApi(Resource):
|
|||||||
credentials=request.credentials or subscription.credentials,
|
credentials=request.credentials or subscription.credentials,
|
||||||
parameters=request.parameters or subscription.parameters,
|
parameters=request.parameters or subscription.parameters,
|
||||||
)
|
)
|
||||||
return 200
|
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise BadRequest(str(e))
|
raise BadRequest(str(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -473,6 +487,7 @@ class TriggerSubscriptionDeleteApi(Resource):
|
|||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def post(self, tenant_id: str, subscription_id: str):
|
def post(self, tenant_id: str, subscription_id: str):
|
||||||
"""Delete a subscription instance"""
|
"""Delete a subscription instance"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with sessionmaker(db.engine).begin() as session:
|
with sessionmaker(db.engine).begin() as session:
|
||||||
# Delete trigger provider subscription
|
# Delete trigger provider subscription
|
||||||
@ -487,7 +502,7 @@ class TriggerSubscriptionDeleteApi(Resource):
|
|||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
subscription_id=subscription_id,
|
subscription_id=subscription_id,
|
||||||
)
|
)
|
||||||
return {"result": "success"}
|
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise BadRequest(str(e))
|
raise BadRequest(str(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -497,9 +512,10 @@ class TriggerSubscriptionDeleteApi(Resource):
|
|||||||
|
|
||||||
@console_ns.route("/workspaces/current/trigger-provider/<path:provider>/subscriptions/oauth/authorize")
|
@console_ns.route("/workspaces/current/trigger-provider/<path:provider>/subscriptions/oauth/authorize")
|
||||||
class TriggerOAuthAuthorizeApi(Resource):
|
class TriggerOAuthAuthorizeApi(Resource):
|
||||||
|
# response-contract:ignore cookie-bearing Flask response
|
||||||
@console_ns.response(
|
@console_ns.response(
|
||||||
200,
|
200,
|
||||||
"Authorization URL retrieved successfully",
|
"Trigger OAuth authorization URL generated successfully",
|
||||||
console_ns.models[TriggerOAuthAuthorizeResponse.__name__],
|
console_ns.models[TriggerOAuthAuthorizeResponse.__name__],
|
||||||
)
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@ -509,10 +525,12 @@ class TriggerOAuthAuthorizeApi(Resource):
|
|||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def get(self, tenant_id: str, user: Account, provider: str):
|
def get(self, tenant_id: str, user: Account, provider: str):
|
||||||
"""Initiate OAuth authorization flow for a trigger provider"""
|
"""Initiate OAuth authorization flow for a trigger provider"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
provider_id = TriggerProviderID(provider)
|
provider_id = TriggerProviderID(provider)
|
||||||
plugin_id = provider_id.plugin_id
|
plugin_id = provider_id.plugin_id
|
||||||
provider_name = provider_id.provider_name
|
provider_name = provider_id.provider_name
|
||||||
|
tenant_id = tenant_id
|
||||||
|
|
||||||
# Get OAuth client configuration
|
# Get OAuth client configuration
|
||||||
oauth_client_params = TriggerProviderService.get_oauth_client(
|
oauth_client_params = TriggerProviderService.get_oauth_client(
|
||||||
@ -556,15 +574,12 @@ class TriggerOAuthAuthorizeApi(Resource):
|
|||||||
system_credentials=oauth_client_params,
|
system_credentials=oauth_client_params,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create response with cookie
|
|
||||||
response = make_response(
|
response = make_response(
|
||||||
jsonable_encoder(
|
TriggerOAuthAuthorizeResponse(
|
||||||
{
|
authorization_url=authorization_url_response.authorization_url,
|
||||||
"authorization_url": authorization_url_response.authorization_url,
|
subscription_builder_id=subscription_builder.id,
|
||||||
"subscription_builder_id": subscription_builder.id,
|
subscription_builder=subscription_builder,
|
||||||
"subscription_builder": subscription_builder,
|
).model_dump(mode="json")
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
response.set_cookie(
|
response.set_cookie(
|
||||||
"context_id",
|
"context_id",
|
||||||
@ -583,11 +598,8 @@ class TriggerOAuthAuthorizeApi(Resource):
|
|||||||
|
|
||||||
@console_ns.route("/oauth/plugin/<path:provider>/trigger/callback")
|
@console_ns.route("/oauth/plugin/<path:provider>/trigger/callback")
|
||||||
class TriggerOAuthCallbackApi(Resource):
|
class TriggerOAuthCallbackApi(Resource):
|
||||||
@console_ns.response(
|
# response-contract:ignore redirect response
|
||||||
302,
|
@console_ns.response(302, "Redirect to OAuth callback page")
|
||||||
"Redirect to console OAuth callback page",
|
|
||||||
console_ns.models[RedirectResponse.__name__],
|
|
||||||
)
|
|
||||||
@setup_required
|
@setup_required
|
||||||
def get(self, provider: str):
|
def get(self, provider: str):
|
||||||
"""Handle OAuth callback for trigger provider"""
|
"""Handle OAuth callback for trigger provider"""
|
||||||
@ -653,7 +665,11 @@ class TriggerOAuthCallbackApi(Resource):
|
|||||||
|
|
||||||
@console_ns.route("/workspaces/current/trigger-provider/<path:provider>/oauth/client")
|
@console_ns.route("/workspaces/current/trigger-provider/<path:provider>/oauth/client")
|
||||||
class TriggerOAuthClientManageApi(Resource):
|
class TriggerOAuthClientManageApi(Resource):
|
||||||
@console_ns.response(200, "Success", console_ns.models[TriggerOAuthClientResponse.__name__])
|
@console_ns.response(
|
||||||
|
200,
|
||||||
|
"Trigger OAuth client retrieved successfully",
|
||||||
|
console_ns.models[TriggerOAuthClientResponse.__name__],
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@is_admin_or_owner_required
|
@is_admin_or_owner_required
|
||||||
@ -662,6 +678,7 @@ class TriggerOAuthClientManageApi(Resource):
|
|||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def get(self, tenant_id: str, provider: str):
|
def get(self, tenant_id: str, provider: str):
|
||||||
"""Get OAuth client configuration for a provider"""
|
"""Get OAuth client configuration for a provider"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
provider_id = TriggerProviderID(provider)
|
provider_id = TriggerProviderID(provider)
|
||||||
|
|
||||||
@ -682,24 +699,24 @@ class TriggerOAuthClientManageApi(Resource):
|
|||||||
)
|
)
|
||||||
provider_controller = TriggerManager.get_trigger_provider(tenant_id, provider_id)
|
provider_controller = TriggerManager.get_trigger_provider(tenant_id, provider_id)
|
||||||
redirect_uri = f"{dify_config.CONSOLE_API_URL}/console/api/oauth/plugin/{provider}/trigger/callback"
|
redirect_uri = f"{dify_config.CONSOLE_API_URL}/console/api/oauth/plugin/{provider}/trigger/callback"
|
||||||
return jsonable_encoder(
|
return TriggerOAuthClientResponse(
|
||||||
{
|
configured=bool(custom_params or system_client_exists),
|
||||||
"configured": bool(custom_params or system_client_exists),
|
system_configured=system_client_exists,
|
||||||
"system_configured": system_client_exists,
|
custom_configured=bool(custom_params),
|
||||||
"custom_configured": bool(custom_params),
|
oauth_client_schema=provider_controller.get_oauth_client_schema(),
|
||||||
"oauth_client_schema": provider_controller.get_oauth_client_schema(),
|
custom_enabled=is_custom_enabled,
|
||||||
"custom_enabled": is_custom_enabled,
|
redirect_uri=redirect_uri,
|
||||||
"redirect_uri": redirect_uri,
|
params=dict(custom_params or {}),
|
||||||
"params": custom_params or {},
|
).model_dump(mode="json")
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("Error getting OAuth client", exc_info=e)
|
logger.exception("Error getting OAuth client", exc_info=e)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@console_ns.expect(console_ns.models[TriggerOAuthClientPayload.__name__])
|
@console_ns.expect(console_ns.models[TriggerOAuthClientPayload.__name__])
|
||||||
@console_ns.response(200, "Success", console_ns.models[SimpleResultResponse.__name__])
|
@console_ns.response(
|
||||||
|
200, "Trigger OAuth client saved successfully", console_ns.models[SimpleResultResponse.__name__]
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@is_admin_or_owner_required
|
@is_admin_or_owner_required
|
||||||
@ -708,16 +725,18 @@ class TriggerOAuthClientManageApi(Resource):
|
|||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def post(self, tenant_id: str, provider: str):
|
def post(self, tenant_id: str, provider: str):
|
||||||
"""Configure custom OAuth client for a provider"""
|
"""Configure custom OAuth client for a provider"""
|
||||||
|
|
||||||
payload = TriggerOAuthClientPayload.model_validate(console_ns.payload or {})
|
payload = TriggerOAuthClientPayload.model_validate(console_ns.payload or {})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
provider_id = TriggerProviderID(provider)
|
provider_id = TriggerProviderID(provider)
|
||||||
return TriggerProviderService.save_custom_oauth_client_params(
|
result = TriggerProviderService.save_custom_oauth_client_params(
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
provider_id=provider_id,
|
provider_id=provider_id,
|
||||||
client_params=payload.client_params,
|
client_params=payload.client_params,
|
||||||
enabled=payload.enabled,
|
enabled=payload.enabled,
|
||||||
)
|
)
|
||||||
|
return dump_response(SimpleResultResponse, result)
|
||||||
|
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise BadRequest(str(e))
|
raise BadRequest(str(e))
|
||||||
@ -725,22 +744,26 @@ class TriggerOAuthClientManageApi(Resource):
|
|||||||
logger.exception("Error configuring OAuth client", exc_info=e)
|
logger.exception("Error configuring OAuth client", exc_info=e)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
@console_ns.response(
|
||||||
|
200, "Trigger OAuth client deleted successfully", console_ns.models[SimpleResultResponse.__name__]
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@is_admin_or_owner_required
|
@is_admin_or_owner_required
|
||||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
|
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
|
||||||
@account_initialization_required
|
@account_initialization_required
|
||||||
@console_ns.response(200, "Success", console_ns.models[SimpleResultResponse.__name__])
|
|
||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def delete(self, tenant_id: str, provider: str):
|
def delete(self, tenant_id: str, provider: str):
|
||||||
"""Remove custom OAuth client configuration"""
|
"""Remove custom OAuth client configuration"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
provider_id = TriggerProviderID(provider)
|
provider_id = TriggerProviderID(provider)
|
||||||
|
|
||||||
return TriggerProviderService.delete_custom_oauth_client_params(
|
result = TriggerProviderService.delete_custom_oauth_client_params(
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
provider_id=provider_id,
|
provider_id=provider_id,
|
||||||
)
|
)
|
||||||
|
return dump_response(SimpleResultResponse, result)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise BadRequest(str(e))
|
raise BadRequest(str(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -753,7 +776,11 @@ class TriggerOAuthClientManageApi(Resource):
|
|||||||
)
|
)
|
||||||
class TriggerSubscriptionVerifyApi(Resource):
|
class TriggerSubscriptionVerifyApi(Resource):
|
||||||
@console_ns.expect(console_ns.models[TriggerSubscriptionBuilderVerifyPayload.__name__])
|
@console_ns.expect(console_ns.models[TriggerSubscriptionBuilderVerifyPayload.__name__])
|
||||||
@console_ns.response(200, "Success", console_ns.models[TriggerSubscriptionBuilderVerifyResponse.__name__])
|
@console_ns.response(
|
||||||
|
200,
|
||||||
|
"Trigger subscription verified successfully",
|
||||||
|
console_ns.models[TriggerVerificationResponse.__name__],
|
||||||
|
)
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@edit_permission_required
|
@edit_permission_required
|
||||||
@ -763,6 +790,7 @@ class TriggerSubscriptionVerifyApi(Resource):
|
|||||||
@with_current_tenant_id
|
@with_current_tenant_id
|
||||||
def post(self, tenant_id: str, user: Account, provider: str, subscription_id: str):
|
def post(self, tenant_id: str, user: Account, provider: str, subscription_id: str):
|
||||||
"""Verify credentials for an existing subscription (edit mode only)"""
|
"""Verify credentials for an existing subscription (edit mode only)"""
|
||||||
|
|
||||||
verify_request = TriggerSubscriptionBuilderVerifyPayload.model_validate(console_ns.payload or {})
|
verify_request = TriggerSubscriptionBuilderVerifyPayload.model_validate(console_ns.payload or {})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -773,7 +801,7 @@ class TriggerSubscriptionVerifyApi(Resource):
|
|||||||
subscription_id=subscription_id,
|
subscription_id=subscription_id,
|
||||||
credentials=verify_request.credentials,
|
credentials=verify_request.credentials,
|
||||||
)
|
)
|
||||||
return result
|
return dump_response(TriggerVerificationResponse, result)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
logger.warning("Credential verification failed", exc_info=e)
|
logger.warning("Credential verification failed", exc_info=e)
|
||||||
raise BadRequest(str(e)) from e
|
raise BadRequest(str(e)) from e
|
||||||
|
|||||||
@ -74,8 +74,6 @@ class ToolProviderApiEntity(BaseModel):
|
|||||||
for parameter in tool.get("parameters"):
|
for parameter in tool.get("parameters"):
|
||||||
if parameter.get("type") == ToolParameter.ToolParameterType.SYSTEM_FILES:
|
if parameter.get("type") == ToolParameter.ToolParameterType.SYSTEM_FILES:
|
||||||
parameter["type"] = "files"
|
parameter["type"] = "files"
|
||||||
if parameter.get("input_schema") is None:
|
|
||||||
parameter.pop("input_schema", None)
|
|
||||||
# -------------
|
# -------------
|
||||||
optional_fields = self.optional_field("server_url", self.server_url)
|
optional_fields = self.optional_field("server_url", self.server_url)
|
||||||
match self.type:
|
match self.type:
|
||||||
|
|||||||
@ -16,30 +16,16 @@ from yarl import URL
|
|||||||
|
|
||||||
import contexts
|
import contexts
|
||||||
from configs import dify_config
|
from configs import dify_config
|
||||||
from core.entities import PluginCredentialType
|
|
||||||
from core.helper.provider_cache import ToolProviderCredentialsCache
|
|
||||||
from core.plugin.impl.tool import PluginToolManager
|
|
||||||
from core.tools.__base.tool_provider import ToolProviderController
|
|
||||||
from core.tools.__base.tool_runtime import ToolRuntime
|
|
||||||
from core.tools.mcp_tool.provider import MCPToolProviderController
|
|
||||||
from core.tools.mcp_tool.tool import MCPTool
|
|
||||||
from core.tools.plugin_tool.provider import PluginToolProviderController
|
|
||||||
from core.tools.plugin_tool.tool import PluginTool
|
|
||||||
from core.tools.utils.uuid_utils import is_valid_uuid
|
|
||||||
from core.tools.workflow_as_tool.provider import WorkflowToolProviderController
|
|
||||||
from extensions.ext_database import db
|
|
||||||
from graphon.runtime import VariablePool
|
|
||||||
from models.provider_ids import ToolProviderID
|
|
||||||
from services.tools.mcp_tools_manage_service import MCPToolManageService
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
pass
|
|
||||||
|
|
||||||
from core.agent.entities import AgentToolEntity
|
from core.agent.entities import AgentToolEntity
|
||||||
from core.app.entities.app_invoke_entities import InvokeFrom
|
from core.app.entities.app_invoke_entities import InvokeFrom
|
||||||
|
from core.entities import PluginCredentialType
|
||||||
from core.helper.module_import_helper import load_single_subclass_from_source
|
from core.helper.module_import_helper import load_single_subclass_from_source
|
||||||
from core.helper.position_helper import is_filtered
|
from core.helper.position_helper import is_filtered
|
||||||
|
from core.helper.provider_cache import ToolProviderCredentialsCache
|
||||||
|
from core.plugin.impl.tool import PluginToolManager
|
||||||
from core.tools.__base.tool import Tool
|
from core.tools.__base.tool import Tool
|
||||||
|
from core.tools.__base.tool_provider import ToolProviderController
|
||||||
|
from core.tools.__base.tool_runtime import ToolRuntime
|
||||||
from core.tools.builtin_tool.provider import BuiltinToolProviderController
|
from core.tools.builtin_tool.provider import BuiltinToolProviderController
|
||||||
from core.tools.builtin_tool.providers._positions import BuiltinToolProviderSort
|
from core.tools.builtin_tool.providers._positions import BuiltinToolProviderSort
|
||||||
from core.tools.builtin_tool.tool import BuiltinTool
|
from core.tools.builtin_tool.tool import BuiltinTool
|
||||||
@ -49,6 +35,7 @@ from core.tools.entities.api_entities import ToolProviderApiEntity, ToolProvider
|
|||||||
from core.tools.entities.common_entities import I18nObject
|
from core.tools.entities.common_entities import I18nObject
|
||||||
from core.tools.entities.tool_entities import (
|
from core.tools.entities.tool_entities import (
|
||||||
ApiProviderAuthType,
|
ApiProviderAuthType,
|
||||||
|
ApiProviderSchemaType,
|
||||||
EmojiIconDict,
|
EmojiIconDict,
|
||||||
ToolInvokeFrom,
|
ToolInvokeFrom,
|
||||||
ToolParameter,
|
ToolParameter,
|
||||||
@ -56,12 +43,21 @@ from core.tools.entities.tool_entities import (
|
|||||||
emoji_icon_adapter,
|
emoji_icon_adapter,
|
||||||
)
|
)
|
||||||
from core.tools.errors import ToolProviderNotFoundError
|
from core.tools.errors import ToolProviderNotFoundError
|
||||||
|
from core.tools.mcp_tool.provider import MCPToolProviderController
|
||||||
|
from core.tools.mcp_tool.tool import MCPTool
|
||||||
|
from core.tools.plugin_tool.provider import PluginToolProviderController
|
||||||
|
from core.tools.plugin_tool.tool import PluginTool
|
||||||
from core.tools.tool_label_manager import ToolLabelManager
|
from core.tools.tool_label_manager import ToolLabelManager
|
||||||
from core.tools.utils.configuration import ToolParameterConfigurationManager
|
from core.tools.utils.configuration import ToolParameterConfigurationManager
|
||||||
from core.tools.utils.encryption import create_provider_encrypter, create_tool_provider_encrypter
|
from core.tools.utils.encryption import create_provider_encrypter, create_tool_provider_encrypter
|
||||||
|
from core.tools.utils.uuid_utils import is_valid_uuid
|
||||||
|
from core.tools.workflow_as_tool.provider import WorkflowToolProviderController
|
||||||
from core.tools.workflow_as_tool.tool import WorkflowTool
|
from core.tools.workflow_as_tool.tool import WorkflowTool
|
||||||
from graphon.model_runtime.utils.encoders import jsonable_encoder
|
from extensions.ext_database import db
|
||||||
|
from graphon.runtime import VariablePool
|
||||||
|
from models.provider_ids import ToolProviderID
|
||||||
from models.tools import ApiToolProvider, BuiltinToolProvider, WorkflowToolProvider
|
from models.tools import ApiToolProvider, BuiltinToolProvider, WorkflowToolProvider
|
||||||
|
from services.tools.mcp_tools_manage_service import MCPToolManageService
|
||||||
from services.tools.tools_transform_service import ToolTransformService
|
from services.tools.tools_transform_service import ToolTransformService
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -921,23 +917,20 @@ class ToolManager:
|
|||||||
|
|
||||||
# add tool labels
|
# add tool labels
|
||||||
labels = ToolLabelManager.get_tool_labels(controller)
|
labels = ToolLabelManager.get_tool_labels(controller)
|
||||||
|
schema_type = provider_obj.schema_type
|
||||||
|
schema_type_value = schema_type.value if isinstance(schema_type, ApiProviderSchemaType) else schema_type
|
||||||
|
|
||||||
return cast(
|
return {
|
||||||
dict,
|
"schema_type": schema_type_value,
|
||||||
jsonable_encoder(
|
"schema": provider_obj.schema,
|
||||||
{
|
"tools": [tool.model_dump(mode="json") for tool in provider_obj.tools],
|
||||||
"schema_type": provider_obj.schema_type,
|
"icon": icon,
|
||||||
"schema": provider_obj.schema,
|
"description": provider_obj.description,
|
||||||
"tools": provider_obj.tools,
|
"credentials": masked_credentials,
|
||||||
"icon": icon,
|
"privacy_policy": provider_obj.privacy_policy,
|
||||||
"description": provider_obj.description,
|
"custom_disclaimer": provider_obj.custom_disclaimer,
|
||||||
"credentials": masked_credentials,
|
"labels": labels,
|
||||||
"privacy_policy": provider_obj.privacy_policy,
|
}
|
||||||
"custom_disclaimer": provider_obj.custom_disclaimer,
|
|
||||||
"labels": labels,
|
|
||||||
}
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate_builtin_tool_icon_url(cls, provider_id: str) -> str:
|
def generate_builtin_tool_icon_url(cls, provider_id: str) -> str:
|
||||||
|
|||||||
@ -7460,9 +7460,9 @@ Get instruction generation template
|
|||||||
|
|
||||||
#### Responses
|
#### Responses
|
||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- |
|
||||||
| 302 | Redirect to console OAuth callback page | **application/json**: [RedirectResponse](#redirectresponse)<br> |
|
| 302 | Redirect to OAuth callback page |
|
||||||
|
|
||||||
### [GET] /notification
|
### [GET] /notification
|
||||||
Return the active in-product notification for the current user in their interface language (falls back to English if unavailable). The notification is NOT marked as seen here; call POST /notification/dismiss when the user explicitly closes the modal.
|
Return the active in-product notification for the current user in their interface language (falls back to English if unavailable). The notification is NOT marked as seen here; call POST /notification/dismiss when the user explicitly closes the modal.
|
||||||
@ -7667,7 +7667,7 @@ Initiate OAuth login process
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Authorization URL retrieved successfully | **application/json**: [PluginOAuthAuthorizationUrlResponse](#pluginoauthauthorizationurlresponse)<br> |
|
| 200 | Tool OAuth authorization URL generated successfully | **application/json**: [PluginOAuthAuthorizationUrlResponse](#pluginoauthauthorizationurlresponse)<br> |
|
||||||
|
|
||||||
### [GET] /oauth/plugin/{provider}/tool/callback
|
### [GET] /oauth/plugin/{provider}/tool/callback
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -7678,9 +7678,9 @@ Initiate OAuth login process
|
|||||||
|
|
||||||
#### Responses
|
#### Responses
|
||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- |
|
||||||
| 302 | Redirect to console OAuth callback page | **application/json**: [RedirectResponse](#redirectresponse)<br> |
|
| 302 | Redirect to OAuth callback page |
|
||||||
|
|
||||||
### [GET] /oauth/plugin/{provider}/trigger/callback
|
### [GET] /oauth/plugin/{provider}/trigger/callback
|
||||||
**Handle OAuth callback for trigger provider**
|
**Handle OAuth callback for trigger provider**
|
||||||
@ -7693,9 +7693,9 @@ Initiate OAuth login process
|
|||||||
|
|
||||||
#### Responses
|
#### Responses
|
||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- |
|
||||||
| 302 | Redirect to console OAuth callback page | **application/json**: [RedirectResponse](#redirectresponse)<br> |
|
| 302 | Redirect to OAuth callback page |
|
||||||
|
|
||||||
### [POST] /oauth/provider
|
### [POST] /oauth/provider
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -11660,7 +11660,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Tool labels retrieved successfully | **application/json**: [ToolLabelListResponse](#toollabellistresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/api/add
|
### [POST] /workspaces/current/tool-provider/api/add
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -11673,7 +11673,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | API provider added successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/api/delete
|
### [POST] /workspaces/current/tool-provider/api/delete
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -11686,7 +11686,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | API provider deleted successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/api/get
|
### [GET] /workspaces/current/tool-provider/api/get
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11699,7 +11699,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | API provider retrieved successfully | **application/json**: [ApiProviderDetailResponse](#apiproviderdetailresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/api/remote
|
### [GET] /workspaces/current/tool-provider/api/remote
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11712,7 +11712,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Remote API provider schema retrieved successfully | **application/json**: [ApiProviderRemoteSchemaResponse](#apiproviderremoteschemaresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/api/schema
|
### [POST] /workspaces/current/tool-provider/api/schema
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -11725,7 +11725,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | API schema parsed successfully | **application/json**: [ApiSchemaParseResponse](#apischemaparseresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/api/test/pre
|
### [POST] /workspaces/current/tool-provider/api/test/pre
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -11738,7 +11738,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | API tool test preview completed successfully | **application/json**: [ApiToolPreviewResponse](#apitoolpreviewresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/api/tools
|
### [GET] /workspaces/current/tool-provider/api/tools
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11751,7 +11751,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | API provider tools retrieved successfully | **application/json**: [ToolApiListResponse](#toolapilistresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/api/update
|
### [POST] /workspaces/current/tool-provider/api/update
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -11764,7 +11764,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | API provider updated successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/builtin/{provider}/add
|
### [POST] /workspaces/current/tool-provider/builtin/{provider}/add
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11783,7 +11783,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Builtin provider added successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/builtin/{provider}/credential/info
|
### [GET] /workspaces/current/tool-provider/builtin/{provider}/credential/info
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11797,7 +11797,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Builtin provider credential info retrieved successfully | **application/json**: [ToolProviderCredentialInfoApiEntity](#toolprovidercredentialinfoapientity)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/builtin/{provider}/credential/schema/{credential_type}
|
### [GET] /workspaces/current/tool-provider/builtin/{provider}/credential/schema/{credential_type}
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11811,7 +11811,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Builtin provider credential schema retrieved successfully | **application/json**: [ProviderConfigListResponse](#providerconfiglistresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/builtin/{provider}/credentials
|
### [GET] /workspaces/current/tool-provider/builtin/{provider}/credentials
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11825,7 +11825,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Builtin provider credentials retrieved successfully | **application/json**: [ToolProviderCredentialListResponse](#toolprovidercredentiallistresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/builtin/{provider}/default-credential
|
### [POST] /workspaces/current/tool-provider/builtin/{provider}/default-credential
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11844,7 +11844,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Default credential set successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/builtin/{provider}/delete
|
### [POST] /workspaces/current/tool-provider/builtin/{provider}/delete
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11863,7 +11863,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Builtin provider credential deleted successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/builtin/{provider}/icon
|
### [GET] /workspaces/current/tool-provider/builtin/{provider}/icon
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11874,9 +11874,9 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
#### Responses
|
#### Responses
|
||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- |
|
||||||
| 200 | Success | **application/json**: [BinaryFileResponse](#binaryfileresponse)<br> |
|
| 200 | Builtin provider icon |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/builtin/{provider}/info
|
### [GET] /workspaces/current/tool-provider/builtin/{provider}/info
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11889,7 +11889,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Builtin provider info retrieved successfully | **application/json**: [ToolProviderApiEntityResponse](#toolproviderapientityresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/builtin/{provider}/oauth/client-schema
|
### [GET] /workspaces/current/tool-provider/builtin/{provider}/oauth/client-schema
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11902,7 +11902,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolOAuthClientSchemaResponse](#tooloauthclientschemaresponse)<br> |
|
| 200 | Builtin provider OAuth client schema retrieved successfully | **application/json**: [BuiltinProviderOAuthClientSchemaResponse](#builtinprovideroauthclientschemaresponse)<br> |
|
||||||
|
|
||||||
### [DELETE] /workspaces/current/tool-provider/builtin/{provider}/oauth/custom-client
|
### [DELETE] /workspaces/current/tool-provider/builtin/{provider}/oauth/custom-client
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11915,7 +11915,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
| 200 | Custom OAuth client deleted successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/builtin/{provider}/oauth/custom-client
|
### [GET] /workspaces/current/tool-provider/builtin/{provider}/oauth/custom-client
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11926,9 +11926,9 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
#### Responses
|
#### Responses
|
||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- |
|
||||||
| 200 | Success | **application/json**: [ToolOAuthCustomClientResponse](#tooloauthcustomclientresponse)<br> |
|
| 200 | Custom OAuth client retrieved successfully |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/builtin/{provider}/oauth/custom-client
|
### [POST] /workspaces/current/tool-provider/builtin/{provider}/oauth/custom-client
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11947,7 +11947,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
| 200 | Custom OAuth client saved successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/builtin/{provider}/tools
|
### [GET] /workspaces/current/tool-provider/builtin/{provider}/tools
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11960,7 +11960,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Builtin provider tools retrieved successfully | **application/json**: [ToolApiListResponse](#toolapilistresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/builtin/{provider}/update
|
### [POST] /workspaces/current/tool-provider/builtin/{provider}/update
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -11979,7 +11979,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Builtin provider updated successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [DELETE] /workspaces/current/tool-provider/mcp
|
### [DELETE] /workspaces/current/tool-provider/mcp
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -12005,7 +12005,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | MCP provider created successfully | **application/json**: [ToolProviderApiEntityResponse](#toolproviderapientityresponse)<br> |
|
||||||
|
|
||||||
### [PUT] /workspaces/current/tool-provider/mcp
|
### [PUT] /workspaces/current/tool-provider/mcp
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -12018,7 +12018,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
| 200 | MCP provider updated successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/mcp/auth
|
### [POST] /workspaces/current/tool-provider/mcp/auth
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -12031,7 +12031,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | MCP provider authorized successfully | **application/json**: [MCPAuthResponse](#mcpauthresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/mcp/tools/{provider_id}
|
### [GET] /workspaces/current/tool-provider/mcp/tools/{provider_id}
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -12044,7 +12044,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | MCP provider retrieved successfully | **application/json**: [ToolProviderApiEntityResponse](#toolproviderapientityresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/mcp/update/{provider_id}
|
### [GET] /workspaces/current/tool-provider/mcp/update/{provider_id}
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -12057,7 +12057,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | MCP provider tools refreshed successfully | **application/json**: [ToolProviderApiEntityResponse](#toolproviderapientityresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/workflow/create
|
### [POST] /workspaces/current/tool-provider/workflow/create
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -12070,7 +12070,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Workflow tool created successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/workflow/delete
|
### [POST] /workspaces/current/tool-provider/workflow/delete
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -12083,7 +12083,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Workflow tool deleted successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/workflow/get
|
### [GET] /workspaces/current/tool-provider/workflow/get
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -12097,7 +12097,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Workflow tool retrieved successfully | **application/json**: [WorkflowToolDetailResponse](#workflowtooldetailresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-provider/workflow/tools
|
### [GET] /workspaces/current/tool-provider/workflow/tools
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -12110,7 +12110,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Workflow provider tools retrieved successfully | **application/json**: [ToolApiListResponse](#toolapilistresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/tool-provider/workflow/update
|
### [POST] /workspaces/current/tool-provider/workflow/update
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -12123,7 +12123,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Workflow tool updated successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tool-providers
|
### [GET] /workspaces/current/tool-providers
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -12136,35 +12136,35 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Tool providers retrieved successfully | **application/json**: [ToolProviderListResponse](#toolproviderlistresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tools/api
|
### [GET] /workspaces/current/tools/api
|
||||||
#### Responses
|
#### Responses
|
||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | API tools retrieved successfully | **application/json**: [ToolProviderListResponse](#toolproviderlistresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tools/builtin
|
### [GET] /workspaces/current/tools/builtin
|
||||||
#### Responses
|
#### Responses
|
||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Builtin tools retrieved successfully | **application/json**: [ToolProviderListResponse](#toolproviderlistresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tools/mcp
|
### [GET] /workspaces/current/tools/mcp
|
||||||
#### Responses
|
#### Responses
|
||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | MCP tools retrieved successfully | **application/json**: [ToolProviderListResponse](#toolproviderlistresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/tools/workflow
|
### [GET] /workspaces/current/tools/workflow
|
||||||
#### Responses
|
#### Responses
|
||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [ToolProviderOpaqueResponse](#toolprovideropaqueresponse)<br> |
|
| 200 | Workflow tools retrieved successfully | **application/json**: [ToolProviderListResponse](#toolproviderlistresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/trigger-provider/{provider}/icon
|
### [GET] /workspaces/current/trigger-provider/{provider}/icon
|
||||||
#### Parameters
|
#### Parameters
|
||||||
@ -12175,9 +12175,9 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
#### Responses
|
#### Responses
|
||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- |
|
||||||
| 200 | Success | **application/json**: [BinaryFileResponse](#binaryfileresponse)<br> |
|
| 200 | Trigger provider icon |
|
||||||
|
|
||||||
### [GET] /workspaces/current/trigger-provider/{provider}/info
|
### [GET] /workspaces/current/trigger-provider/{provider}/info
|
||||||
**Get info for a trigger provider**
|
**Get info for a trigger provider**
|
||||||
@ -12192,7 +12192,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [TriggerProviderApiEntity](#triggerproviderapientity)<br> |
|
| 200 | Trigger provider retrieved successfully | **application/json**: [TriggerProviderApiEntity](#triggerproviderapientity)<br> |
|
||||||
|
|
||||||
### [DELETE] /workspaces/current/trigger-provider/{provider}/oauth/client
|
### [DELETE] /workspaces/current/trigger-provider/{provider}/oauth/client
|
||||||
**Remove custom OAuth client configuration**
|
**Remove custom OAuth client configuration**
|
||||||
@ -12207,7 +12207,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
| 200 | Trigger OAuth client deleted successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/trigger-provider/{provider}/oauth/client
|
### [GET] /workspaces/current/trigger-provider/{provider}/oauth/client
|
||||||
**Get OAuth client configuration for a provider**
|
**Get OAuth client configuration for a provider**
|
||||||
@ -12222,7 +12222,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [TriggerOAuthClientResponse](#triggeroauthclientresponse)<br> |
|
| 200 | Trigger OAuth client retrieved successfully | **application/json**: [TriggerOAuthClientResponse](#triggeroauthclientresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/trigger-provider/{provider}/oauth/client
|
### [POST] /workspaces/current/trigger-provider/{provider}/oauth/client
|
||||||
**Configure custom OAuth client for a provider**
|
**Configure custom OAuth client for a provider**
|
||||||
@ -12243,7 +12243,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
| 200 | Trigger OAuth client saved successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/trigger-provider/{provider}/subscriptions/builder/build/{subscription_builder_id}
|
### [POST] /workspaces/current/trigger-provider/{provider}/subscriptions/builder/build/{subscription_builder_id}
|
||||||
**Build a subscription instance for a trigger provider**
|
**Build a subscription instance for a trigger provider**
|
||||||
@ -12265,7 +12265,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [TriggerProviderOpaqueResponse](#triggerprovideropaqueresponse)<br> |
|
| 200 | Trigger subscription builder built successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/trigger-provider/{provider}/subscriptions/builder/create
|
### [POST] /workspaces/current/trigger-provider/{provider}/subscriptions/builder/create
|
||||||
**Add a new subscription instance for a trigger provider**
|
**Add a new subscription instance for a trigger provider**
|
||||||
@ -12286,7 +12286,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [TriggerSubscriptionBuilderCreateResponse](#triggersubscriptionbuildercreateresponse)<br> |
|
| 200 | Trigger subscription builder created successfully | **application/json**: [TriggerSubscriptionBuilderCreateResponse](#triggersubscriptionbuildercreateresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/trigger-provider/{provider}/subscriptions/builder/logs/{subscription_builder_id}
|
### [GET] /workspaces/current/trigger-provider/{provider}/subscriptions/builder/logs/{subscription_builder_id}
|
||||||
**Get the request logs for a subscription instance for a trigger provider**
|
**Get the request logs for a subscription instance for a trigger provider**
|
||||||
@ -12302,7 +12302,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [TriggerSubscriptionBuilderLogsResponse](#triggersubscriptionbuilderlogsresponse)<br> |
|
| 200 | Trigger subscription builder logs retrieved successfully | **application/json**: [TriggerSubscriptionBuilderLogsResponse](#triggersubscriptionbuilderlogsresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/trigger-provider/{provider}/subscriptions/builder/update/{subscription_builder_id}
|
### [POST] /workspaces/current/trigger-provider/{provider}/subscriptions/builder/update/{subscription_builder_id}
|
||||||
**Update a subscription instance for a trigger provider**
|
**Update a subscription instance for a trigger provider**
|
||||||
@ -12324,7 +12324,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [SubscriptionBuilderApiEntity](#subscriptionbuilderapientity)<br> |
|
| 200 | Trigger subscription builder updated successfully | **application/json**: [SubscriptionBuilderApiEntity](#subscriptionbuilderapientity)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/trigger-provider/{provider}/subscriptions/builder/verify-and-update/{subscription_builder_id}
|
### [POST] /workspaces/current/trigger-provider/{provider}/subscriptions/builder/verify-and-update/{subscription_builder_id}
|
||||||
**Verify and update a subscription instance for a trigger provider**
|
**Verify and update a subscription instance for a trigger provider**
|
||||||
@ -12346,7 +12346,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [TriggerSubscriptionBuilderVerifyResponse](#triggersubscriptionbuilderverifyresponse)<br> |
|
| 200 | Trigger subscription builder verified successfully | **application/json**: [TriggerVerificationResponse](#triggerverificationresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/trigger-provider/{provider}/subscriptions/builder/{subscription_builder_id}
|
### [GET] /workspaces/current/trigger-provider/{provider}/subscriptions/builder/{subscription_builder_id}
|
||||||
**Get a subscription instance for a trigger provider**
|
**Get a subscription instance for a trigger provider**
|
||||||
@ -12362,7 +12362,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [SubscriptionBuilderApiEntity](#subscriptionbuilderapientity)<br> |
|
| 200 | Trigger subscription builder retrieved successfully | **application/json**: [SubscriptionBuilderApiEntity](#subscriptionbuilderapientity)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/trigger-provider/{provider}/subscriptions/list
|
### [GET] /workspaces/current/trigger-provider/{provider}/subscriptions/list
|
||||||
**List all trigger subscriptions for the current tenant's provider**
|
**List all trigger subscriptions for the current tenant's provider**
|
||||||
@ -12377,7 +12377,8 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [TriggerSubscriptionListResponse](#triggersubscriptionlistresponse)<br> |
|
| 200 | Trigger subscriptions retrieved successfully | **application/json**: [TriggerProviderSubscriptionListResponse](#triggerprovidersubscriptionlistresponse)<br> |
|
||||||
|
| 404 | Trigger provider not found | **application/json**: [TriggerProviderErrorResponse](#triggerprovidererrorresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/trigger-provider/{provider}/subscriptions/oauth/authorize
|
### [GET] /workspaces/current/trigger-provider/{provider}/subscriptions/oauth/authorize
|
||||||
**Initiate OAuth authorization flow for a trigger provider**
|
**Initiate OAuth authorization flow for a trigger provider**
|
||||||
@ -12392,7 +12393,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Authorization URL retrieved successfully | **application/json**: [TriggerOAuthAuthorizeResponse](#triggeroauthauthorizeresponse)<br> |
|
| 200 | Trigger OAuth authorization URL generated successfully | **application/json**: [TriggerOAuthAuthorizeResponse](#triggeroauthauthorizeresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/trigger-provider/{provider}/subscriptions/verify/{subscription_id}
|
### [POST] /workspaces/current/trigger-provider/{provider}/subscriptions/verify/{subscription_id}
|
||||||
**Verify credentials for an existing subscription (edit mode only)**
|
**Verify credentials for an existing subscription (edit mode only)**
|
||||||
@ -12414,7 +12415,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [TriggerSubscriptionBuilderVerifyResponse](#triggersubscriptionbuilderverifyresponse)<br> |
|
| 200 | Trigger subscription verified successfully | **application/json**: [TriggerVerificationResponse](#triggerverificationresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/current/trigger-provider/{subscription_id}/subscriptions/delete
|
### [POST] /workspaces/current/trigger-provider/{subscription_id}/subscriptions/delete
|
||||||
**Delete a subscription instance**
|
**Delete a subscription instance**
|
||||||
@ -12450,7 +12451,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [TriggerProviderOpaqueResponse](#triggerprovideropaqueresponse)<br> |
|
| 200 | Trigger subscription updated successfully | **application/json**: [SimpleResultResponse](#simpleresultresponse)<br> |
|
||||||
|
|
||||||
### [GET] /workspaces/current/triggers
|
### [GET] /workspaces/current/triggers
|
||||||
**List all trigger providers for the current tenant**
|
**List all trigger providers for the current tenant**
|
||||||
@ -12459,7 +12460,7 @@ Returns permission flags that control workspace features like member invitations
|
|||||||
|
|
||||||
| Code | Description | Schema |
|
| Code | Description | Schema |
|
||||||
| ---- | ----------- | ------ |
|
| ---- | ----------- | ------ |
|
||||||
| 200 | Success | **application/json**: [TriggerProviderListResponse](#triggerproviderlistresponse)<br> |
|
| 200 | Trigger providers retrieved successfully | **application/json**: [TriggerProviderListResponse](#triggerproviderlistresponse)<br> |
|
||||||
|
|
||||||
### [POST] /workspaces/custom-config
|
### [POST] /workspaces/custom-config
|
||||||
#### Request Body
|
#### Request Body
|
||||||
@ -14872,6 +14873,26 @@ Legacy Chat App model config used only for follow-up question generation.
|
|||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| data | [ [ApiKeyItem](#apikeyitem) ] | | Yes |
|
| data | [ [ApiKeyItem](#apikeyitem) ] | | Yes |
|
||||||
|
|
||||||
|
#### ApiProviderDetailResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| credentials | object | | No |
|
||||||
|
| custom_disclaimer | string | | No |
|
||||||
|
| description | string | | No |
|
||||||
|
| icon | [ToolEmojiIcon](#toolemojiicon) | | Yes |
|
||||||
|
| labels | [ string ] | | No |
|
||||||
|
| privacy_policy | string | | No |
|
||||||
|
| schema | string | | Yes |
|
||||||
|
| schema_type | [ApiProviderSchemaType](#apiproviderschematype) | | Yes |
|
||||||
|
| tools | [ [ApiToolBundle](#apitoolbundle) ] | | Yes |
|
||||||
|
|
||||||
|
#### ApiProviderRemoteSchemaResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| schema | string | | Yes |
|
||||||
|
|
||||||
#### ApiProviderSchemaType
|
#### ApiProviderSchemaType
|
||||||
|
|
||||||
Enum class for api provider schema type.
|
Enum class for api provider schema type.
|
||||||
@ -14880,13 +14901,52 @@ Enum class for api provider schema type.
|
|||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| ApiProviderSchemaType | string | Enum class for api provider schema type. | |
|
| ApiProviderSchemaType | string | Enum class for api provider schema type. | |
|
||||||
|
|
||||||
|
#### ApiSchemaParseResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| credentials_schema | [ [ProviderConfig](#providerconfig) ] | | Yes |
|
||||||
|
| parameters_schema | [ [ApiToolBundle](#apitoolbundle) ] | | Yes |
|
||||||
|
| schema_type | [ApiProviderSchemaType](#apiproviderschematype) | | Yes |
|
||||||
|
| warning | object | | Yes |
|
||||||
|
|
||||||
|
#### ApiToolBundle
|
||||||
|
|
||||||
|
This class is used to store the schema information of an api based tool.
|
||||||
|
such as the url, the method, the parameters, etc.
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| author | string | | Yes |
|
||||||
|
| icon | string | | No |
|
||||||
|
| method | string | | Yes |
|
||||||
|
| openapi | object | | Yes |
|
||||||
|
| operation_id | string | | No |
|
||||||
|
| output_schema | object | | No |
|
||||||
|
| parameters | [ [ToolParameter](#toolparameter) ] | | No |
|
||||||
|
| server_url | string | | Yes |
|
||||||
|
| summary | string | | No |
|
||||||
|
|
||||||
|
#### ApiToolPreviewResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| ApiToolPreviewResponse | | | |
|
||||||
|
|
||||||
|
#### ApiToolPreviewResult
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| error | string | | No |
|
||||||
|
| result | string | | No |
|
||||||
|
|
||||||
#### ApiToolProviderAddPayload
|
#### ApiToolProviderAddPayload
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| credentials | object | | Yes |
|
| credentials | object | | Yes |
|
||||||
| custom_disclaimer | string | | No |
|
| custom_disclaimer | string | | No |
|
||||||
| icon | object | | Yes |
|
| icon | [ToolEmojiIcon](#toolemojiicon) | | Yes |
|
||||||
| labels | [ string ] | | No |
|
| labels | [ string ] | | No |
|
||||||
| privacy_policy | string | | No |
|
| privacy_policy | string | | No |
|
||||||
| provider | string | | Yes |
|
| provider | string | | Yes |
|
||||||
@ -14905,7 +14965,7 @@ Enum class for api provider schema type.
|
|||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| credentials | object | | Yes |
|
| credentials | object | | Yes |
|
||||||
| custom_disclaimer | string | | No |
|
| custom_disclaimer | string | | No |
|
||||||
| icon | object | | Yes |
|
| icon | [ToolEmojiIcon](#toolemojiicon) | | Yes |
|
||||||
| labels | [ string ] | | No |
|
| labels | [ string ] | | No |
|
||||||
| original_provider | string | | Yes |
|
| original_provider | string | | Yes |
|
||||||
| privacy_policy | string | | No |
|
| privacy_policy | string | | No |
|
||||||
@ -15381,6 +15441,16 @@ Retrieval settings for Amazon Bedrock knowledge base queries.
|
|||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| id | string | | Yes |
|
| id | string | | Yes |
|
||||||
|
|
||||||
|
#### BuiltinProviderOAuthClientSchemaResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| client_params | object | | No |
|
||||||
|
| is_oauth_custom_client_enabled | boolean | | Yes |
|
||||||
|
| is_system_oauth_params_exists | boolean | | Yes |
|
||||||
|
| redirect_uri | string | | Yes |
|
||||||
|
| schema | [ [ProviderConfig](#providerconfig) ] | | Yes |
|
||||||
|
|
||||||
#### BuiltinToolAddPayload
|
#### BuiltinToolAddPayload
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
@ -18350,6 +18420,20 @@ Enum class for large language model mode.
|
|||||||
| authorization_code | string | | No |
|
| authorization_code | string | | No |
|
||||||
| provider_id | string | | Yes |
|
| provider_id | string | | Yes |
|
||||||
|
|
||||||
|
#### MCPAuthResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| authorization_url | string | | No |
|
||||||
|
| result | string | | No |
|
||||||
|
|
||||||
|
#### MCPAuthentication
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| client_id | string | | Yes |
|
||||||
|
| client_secret | string | | No |
|
||||||
|
|
||||||
#### MCPCallbackQuery
|
#### MCPCallbackQuery
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
@ -18357,12 +18441,19 @@ Enum class for large language model mode.
|
|||||||
| code | string | | Yes |
|
| code | string | | Yes |
|
||||||
| state | string | | Yes |
|
| state | string | | Yes |
|
||||||
|
|
||||||
|
#### MCPConfiguration
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| sse_read_timeout | number, <br>**Default:** 300 | | No |
|
||||||
|
| timeout | number, <br>**Default:** 30 | | No |
|
||||||
|
|
||||||
#### MCPProviderCreatePayload
|
#### MCPProviderCreatePayload
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| authentication | object | | No |
|
| authentication | [MCPAuthentication](#mcpauthentication) | | No |
|
||||||
| configuration | object | | No |
|
| configuration | [MCPConfiguration](#mcpconfiguration) | | No |
|
||||||
| headers | object | | No |
|
| headers | object | | No |
|
||||||
| icon | string | | Yes |
|
| icon | string | | Yes |
|
||||||
| icon_background | string | | No |
|
| icon_background | string | | No |
|
||||||
@ -18382,8 +18473,8 @@ Enum class for large language model mode.
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| authentication | object | | No |
|
| authentication | [MCPAuthentication](#mcpauthentication) | | No |
|
||||||
| configuration | object | | No |
|
| configuration | [MCPConfiguration](#mcpconfiguration) | | No |
|
||||||
| headers | object | | No |
|
| headers | object | | No |
|
||||||
| icon | string | | Yes |
|
| icon | string | | Yes |
|
||||||
| icon_background | string | | No |
|
| icon_background | string | | No |
|
||||||
@ -19945,6 +20036,12 @@ Model class for common provider settings like credentials
|
|||||||
| type | [ProviderConfigType](#providerconfigtype) | The type of the credentials | Yes |
|
| type | [ProviderConfigType](#providerconfigtype) | The type of the credentials | Yes |
|
||||||
| url | string | | No |
|
| url | string | | No |
|
||||||
|
|
||||||
|
#### ProviderConfigListResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| ProviderConfigListResponse | array | | |
|
||||||
|
|
||||||
#### ProviderConfigType
|
#### ProviderConfigType
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
@ -21455,11 +21552,46 @@ Available voices
|
|||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| data | [ [TokensPerSecondStatisticItem](#tokenspersecondstatisticitem) ] | | Yes |
|
| data | [ [TokensPerSecondStatisticItem](#tokenspersecondstatisticitem) ] | | Yes |
|
||||||
|
|
||||||
#### ToolOAuthClientSchemaResponse
|
#### ToolApiEntity
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| ToolOAuthClientSchemaResponse | array | | |
|
| author | string | | Yes |
|
||||||
|
| description | [I18nObject](#i18nobject) | | Yes |
|
||||||
|
| label | [I18nObject](#i18nobject) | | Yes |
|
||||||
|
| labels | [ string ] | | No |
|
||||||
|
| name | string | | Yes |
|
||||||
|
| output_schema | object | | No |
|
||||||
|
| parameters | [ [ToolParameter](#toolparameter) ] | | No |
|
||||||
|
|
||||||
|
#### ToolApiListResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| ToolApiListResponse | array | | |
|
||||||
|
|
||||||
|
#### ToolEmojiIcon
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| background | string | | Yes |
|
||||||
|
| content | string | | Yes |
|
||||||
|
|
||||||
|
#### ToolLabel
|
||||||
|
|
||||||
|
Tool label
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| icon | string | The icon of the tool | Yes |
|
||||||
|
| label | [I18nObject](#i18nobject) | The label of the tool | Yes |
|
||||||
|
| name | string | The name of the tool | Yes |
|
||||||
|
|
||||||
|
#### ToolLabelListResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| ToolLabelListResponse | array | | |
|
||||||
|
|
||||||
#### ToolOAuthCustomClientPayload
|
#### ToolOAuthCustomClientPayload
|
||||||
|
|
||||||
@ -21468,11 +21600,29 @@ Available voices
|
|||||||
| client_params | object | | No |
|
| client_params | object | | No |
|
||||||
| enable_oauth_custom_client | boolean | | No |
|
| enable_oauth_custom_client | boolean | | No |
|
||||||
|
|
||||||
#### ToolOAuthCustomClientResponse
|
#### ToolParameter
|
||||||
|
|
||||||
|
Overrides type
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| ToolOAuthCustomClientResponse | object | | |
|
| auto_generate | [PluginParameterAutoGenerate](#pluginparameterautogenerate) | | No |
|
||||||
|
| default | number<br>integer<br>string<br>boolean<br>[ object ]<br>object | | No |
|
||||||
|
| form | [ToolParameterForm](#toolparameterform) | The form of the parameter, schema/form/llm | Yes |
|
||||||
|
| human_description | [I18nObject](#i18nobject) | The description presented to the user | No |
|
||||||
|
| input_schema | object | | No |
|
||||||
|
| label | [I18nObject](#i18nobject) | The label presented to the user | Yes |
|
||||||
|
| llm_description | string | | No |
|
||||||
|
| max | number<br>integer | | No |
|
||||||
|
| min | number<br>integer | | No |
|
||||||
|
| name | string | The name of the parameter | Yes |
|
||||||
|
| options | [ [PluginParameterOption](#pluginparameteroption) ] | | No |
|
||||||
|
| placeholder | [I18nObject](#i18nobject) | The placeholder presented to the user | No |
|
||||||
|
| precision | integer | | No |
|
||||||
|
| required | boolean | | No |
|
||||||
|
| scope | string | | No |
|
||||||
|
| template | [PluginParameterTemplate](#pluginparametertemplate) | | No |
|
||||||
|
| type | [ToolParameterType](#toolparametertype) | The type of the parameter | Yes |
|
||||||
|
|
||||||
#### ToolParameterForm
|
#### ToolParameterForm
|
||||||
|
|
||||||
@ -21480,17 +21630,84 @@ Available voices
|
|||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| ToolParameterForm | string | | |
|
| ToolParameterForm | string | | |
|
||||||
|
|
||||||
|
#### ToolParameterType
|
||||||
|
|
||||||
|
removes TOOLS_SELECTOR from PluginParameterType
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| ToolParameterType | string | removes TOOLS_SELECTOR from PluginParameterType | |
|
||||||
|
|
||||||
|
#### ToolProviderApiEntityResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| allow_delete | boolean, <br>**Default:** true | | No |
|
||||||
|
| authentication | [MCPAuthentication](#mcpauthentication) | The OAuth config of the MCP tool | No |
|
||||||
|
| author | string | | Yes |
|
||||||
|
| configuration | [MCPConfiguration](#mcpconfiguration) | The timeout and sse_read_timeout of the MCP tool | No |
|
||||||
|
| description | [I18nObject](#i18nobject) | | Yes |
|
||||||
|
| icon | string<br>object | | Yes |
|
||||||
|
| icon_dark | string<br>object | | No |
|
||||||
|
| id | string | | Yes |
|
||||||
|
| identity_mode | string, <br>**Default:** off | Identity-forwarding mechanism: 'off' or 'idp_token' | No |
|
||||||
|
| is_dynamic_registration | boolean, <br>**Default:** true | Whether the MCP tool is dynamically registered | No |
|
||||||
|
| is_team_authorization | boolean | | No |
|
||||||
|
| label | [I18nObject](#i18nobject) | | Yes |
|
||||||
|
| labels | [ string ] | | No |
|
||||||
|
| masked_headers | object | The masked headers of the MCP tool | No |
|
||||||
|
| name | string | | Yes |
|
||||||
|
| original_headers | object | The original headers of the MCP tool | No |
|
||||||
|
| plugin_id | string | The plugin id of the tool | No |
|
||||||
|
| plugin_unique_identifier | string | The unique identifier of the tool | No |
|
||||||
|
| server_identifier | string | The server identifier of the MCP tool | No |
|
||||||
|
| server_url | string | The server url of the tool | No |
|
||||||
|
| team_credentials | object | | No |
|
||||||
|
| tools | [ [ToolApiEntity](#toolapientity) ] | | No |
|
||||||
|
| type | [ToolProviderType](#toolprovidertype) | | Yes |
|
||||||
|
| updated_at | integer | | No |
|
||||||
|
| workflow_app_id | string | The app id of the workflow tool | No |
|
||||||
|
|
||||||
|
#### ToolProviderCredentialApiEntity
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| created_by | string | User ID of the credential creator | No |
|
||||||
|
| credential_type | [CredentialType](#credentialtype) | The type of the credential | Yes |
|
||||||
|
| credentials | object | The credentials of the provider | No |
|
||||||
|
| from_other_member | boolean | True when this credential is being returned only because a workflow/agent node still references it but it would normally be hidden from this user by the visibility filter (another member's only_me credential). The frontend renders it as 'borrowed' — selectable until the node switches away, but not editable/deletable. | No |
|
||||||
|
| id | string | The unique id of the credential | Yes |
|
||||||
|
| is_default | boolean | Whether the credential is the default credential for the provider in the workspace | No |
|
||||||
|
| name | string | The name of the credential | Yes |
|
||||||
|
| partial_member_list | [ string ] | List of user IDs allowed when visibility is partial_members | No |
|
||||||
|
| provider | string | The provider of the credential | Yes |
|
||||||
|
| visibility | string, <br>**Default:** all_team_members | Credential visibility: only_me, all_team_members, or partial_members | No |
|
||||||
|
|
||||||
|
#### ToolProviderCredentialInfoApiEntity
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| credentials | [ [ToolProviderCredentialApiEntity](#toolprovidercredentialapientity) ] | The credentials of the provider | Yes |
|
||||||
|
| is_oauth_custom_client_enabled | boolean | Whether the OAuth custom client is enabled for the provider | No |
|
||||||
|
| supported_credential_types | [ [CredentialType](#credentialtype) ] | The supported credential types of the provider | Yes |
|
||||||
|
|
||||||
|
#### ToolProviderCredentialListResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| ToolProviderCredentialListResponse | array | | |
|
||||||
|
|
||||||
#### ToolProviderListQuery
|
#### ToolProviderListQuery
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| type | string | | No |
|
| type | string | | No |
|
||||||
|
|
||||||
#### ToolProviderOpaqueResponse
|
#### ToolProviderListResponse
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| ToolProviderOpaqueResponse | | | |
|
| ToolProviderListResponse | array | | |
|
||||||
|
|
||||||
#### ToolProviderType
|
#### ToolProviderType
|
||||||
|
|
||||||
@ -21771,7 +21988,7 @@ Enum class for tool provider
|
|||||||
| configured | boolean | | Yes |
|
| configured | boolean | | Yes |
|
||||||
| custom_configured | boolean | | Yes |
|
| custom_configured | boolean | | Yes |
|
||||||
| custom_enabled | boolean | | Yes |
|
| custom_enabled | boolean | | Yes |
|
||||||
| oauth_client_schema | [ [TriggerProviderConfigResponse](#triggerproviderconfigresponse) ] | | Yes |
|
| oauth_client_schema | [ [ProviderConfig](#providerconfig) ] | | Yes |
|
||||||
| params | object | | Yes |
|
| params | object | | Yes |
|
||||||
| redirect_uri | string | | Yes |
|
| redirect_uri | string | | Yes |
|
||||||
| system_configured | boolean | | Yes |
|
| system_configured | boolean | | Yes |
|
||||||
@ -21794,28 +22011,11 @@ Enum class for tool provider
|
|||||||
| supported_creation_methods | [ [TriggerCreationMethod](#triggercreationmethod) ] | Supported creation methods for the trigger provider. like 'OAUTH', 'APIKEY', 'MANUAL'. | No |
|
| supported_creation_methods | [ [TriggerCreationMethod](#triggercreationmethod) ] | Supported creation methods for the trigger provider. like 'OAUTH', 'APIKEY', 'MANUAL'. | No |
|
||||||
| tags | [ string ] | The tags of the trigger provider | No |
|
| tags | [ string ] | The tags of the trigger provider | No |
|
||||||
|
|
||||||
#### TriggerProviderConfigOptionResponse
|
#### TriggerProviderErrorResponse
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| label | [I18nObject](#i18nobject) | The label of the option | Yes |
|
| error | string | | Yes |
|
||||||
| value | string | The value of the option | Yes |
|
|
||||||
|
|
||||||
#### TriggerProviderConfigResponse
|
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
|
||||||
| ---- | ---- | ----------- | -------- |
|
|
||||||
| default | integer<br>string<br>number<br>boolean | | No |
|
|
||||||
| help | [I18nObject](#i18nobject) | | No |
|
|
||||||
| label | [I18nObject](#i18nobject) | | No |
|
|
||||||
| multiple | boolean | | No |
|
|
||||||
| name | string | The name of the credentials | Yes |
|
|
||||||
| options | [ [TriggerProviderConfigOptionResponse](#triggerproviderconfigoptionresponse) ] | | No |
|
|
||||||
| placeholder | [I18nObject](#i18nobject) | | No |
|
|
||||||
| required | boolean | | No |
|
|
||||||
| scope | [AppSelectorScope](#appselectorscope)<br>[ModelSelectorScope](#modelselectorscope)<br>[ToolSelectorScope](#toolselectorscope) | | No |
|
|
||||||
| type | string, <br>**Available values:** "app-selector", "array[tools]", "boolean", "model-selector", "secret-input", "select", "text-input" | The type of the credentials<br>*Enum:* `"app-selector"`, `"array[tools]"`, `"boolean"`, `"model-selector"`, `"secret-input"`, `"select"`, `"text-input"` | Yes |
|
|
||||||
| url | string | | No |
|
|
||||||
|
|
||||||
#### TriggerProviderListResponse
|
#### TriggerProviderListResponse
|
||||||
|
|
||||||
@ -21823,12 +22023,6 @@ Enum class for tool provider
|
|||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| TriggerProviderListResponse | array | | |
|
| TriggerProviderListResponse | array | | |
|
||||||
|
|
||||||
#### TriggerProviderOpaqueResponse
|
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
|
||||||
| ---- | ---- | ----------- | -------- |
|
|
||||||
| TriggerProviderOpaqueResponse | | | |
|
|
||||||
|
|
||||||
#### TriggerProviderSubscriptionApiEntity
|
#### TriggerProviderSubscriptionApiEntity
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
@ -21843,6 +22037,12 @@ Enum class for tool provider
|
|||||||
| provider | string | The provider id of the subscription | Yes |
|
| provider | string | The provider id of the subscription | Yes |
|
||||||
| workflows_in_use | integer | The number of workflows using this subscription | Yes |
|
| workflows_in_use | integer | The number of workflows using this subscription | Yes |
|
||||||
|
|
||||||
|
#### TriggerProviderSubscriptionListResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| TriggerProviderSubscriptionListResponse | array | | |
|
||||||
|
|
||||||
#### TriggerSubscriptionBuilderCreatePayload
|
#### TriggerSubscriptionBuilderCreatePayload
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
@ -21876,18 +22076,12 @@ Enum class for tool provider
|
|||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| credentials | object | | Yes |
|
| credentials | object | | Yes |
|
||||||
|
|
||||||
#### TriggerSubscriptionBuilderVerifyResponse
|
#### TriggerVerificationResponse
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| verified | boolean | | Yes |
|
| verified | boolean | | Yes |
|
||||||
|
|
||||||
#### TriggerSubscriptionListResponse
|
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
|
||||||
| ---- | ---- | ----------- | -------- |
|
|
||||||
| TriggerSubscriptionListResponse | array | | |
|
|
||||||
|
|
||||||
#### UnaddedModelConfiguration
|
#### UnaddedModelConfiguration
|
||||||
|
|
||||||
Model class for provider unadded model configuration.
|
Model class for provider unadded model configuration.
|
||||||
@ -22938,7 +23132,7 @@ Query parameters for workflow runs.
|
|||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| description | string | | Yes |
|
| description | string | | Yes |
|
||||||
| icon | object | | Yes |
|
| icon | [ToolEmojiIcon](#toolemojiicon) | | Yes |
|
||||||
| label | string | | Yes |
|
| label | string | | Yes |
|
||||||
| labels | [ string ] | | No |
|
| labels | [ string ] | | No |
|
||||||
| name | string | | Yes |
|
| name | string | | Yes |
|
||||||
@ -22952,6 +23146,22 @@ Query parameters for workflow runs.
|
|||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| workflow_tool_id | string | | Yes |
|
| workflow_tool_id | string | | Yes |
|
||||||
|
|
||||||
|
#### WorkflowToolDetailResponse
|
||||||
|
|
||||||
|
| Name | Type | Description | Required |
|
||||||
|
| ---- | ---- | ----------- | -------- |
|
||||||
|
| description | string | | Yes |
|
||||||
|
| icon | [ToolEmojiIcon](#toolemojiicon) | | Yes |
|
||||||
|
| label | string | | Yes |
|
||||||
|
| name | string | | Yes |
|
||||||
|
| output_schema | object | | No |
|
||||||
|
| parameters | [ [WorkflowToolParameterConfiguration](#workflowtoolparameterconfiguration) ] | | Yes |
|
||||||
|
| privacy_policy | string | | No |
|
||||||
|
| synced | boolean | | Yes |
|
||||||
|
| tool | [ToolApiEntity](#toolapientity) | | Yes |
|
||||||
|
| workflow_app_id | string | | Yes |
|
||||||
|
| workflow_tool_id | string | | Yes |
|
||||||
|
|
||||||
#### WorkflowToolGetQuery
|
#### WorkflowToolGetQuery
|
||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
@ -22980,7 +23190,7 @@ Workflow tool configuration
|
|||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
| ---- | ---- | ----------- | -------- |
|
| ---- | ---- | ----------- | -------- |
|
||||||
| description | string | | Yes |
|
| description | string | | Yes |
|
||||||
| icon | object | | Yes |
|
| icon | [ToolEmojiIcon](#toolemojiicon) | | Yes |
|
||||||
| label | string | | Yes |
|
| label | string | | Yes |
|
||||||
| labels | [ string ] | | No |
|
| labels | [ string ] | | No |
|
||||||
| name | string | | Yes |
|
| name | string | | Yes |
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, TypedDict, cast
|
from typing import Any, Literal, TypedDict, cast
|
||||||
|
|
||||||
from httpx import get
|
from httpx import get
|
||||||
|
from pydantic import TypeAdapter
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
@ -22,7 +23,6 @@ from core.tools.tool_manager import ToolManager
|
|||||||
from core.tools.utils.encryption import create_tool_provider_encrypter
|
from core.tools.utils.encryption import create_tool_provider_encrypter
|
||||||
from core.tools.utils.parser import ApiBasedToolSchemaParser
|
from core.tools.utils.parser import ApiBasedToolSchemaParser
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
from graphon.model_runtime.utils.encoders import jsonable_encoder
|
|
||||||
from models.tools import ApiToolProvider
|
from models.tools import ApiToolProvider
|
||||||
from services.tools.tools_transform_service import ToolTransformService
|
from services.tools.tools_transform_service import ToolTransformService
|
||||||
|
|
||||||
@ -36,6 +36,27 @@ class ApiSchemaParseResult(TypedDict):
|
|||||||
warning: dict[str, str]
|
warning: dict[str, str]
|
||||||
|
|
||||||
|
|
||||||
|
class ApiToolPreviewResult(TypedDict, total=False):
|
||||||
|
result: str
|
||||||
|
error: str
|
||||||
|
|
||||||
|
|
||||||
|
class RemoteSchemaResult(TypedDict):
|
||||||
|
schema: str
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleSuccessResult(TypedDict):
|
||||||
|
result: Literal["success"]
|
||||||
|
|
||||||
|
|
||||||
|
def _dump_api_tool_bundles(tool_bundles: list[ApiToolBundle]) -> list[dict[str, Any]]:
|
||||||
|
return cast(list[dict[str, Any]], TypeAdapter(list[ApiToolBundle]).dump_python(tool_bundles, mode="json"))
|
||||||
|
|
||||||
|
|
||||||
|
def _dump_provider_configs(configs: list[ProviderConfig]) -> list[dict[str, Any]]:
|
||||||
|
return cast(list[dict[str, Any]], TypeAdapter(list[ProviderConfig]).dump_python(configs, mode="json"))
|
||||||
|
|
||||||
|
|
||||||
class ApiToolManageService:
|
class ApiToolManageService:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def parser_api_schema(schema: str) -> ApiSchemaParseResult:
|
def parser_api_schema(schema: str) -> ApiSchemaParseResult:
|
||||||
@ -80,14 +101,12 @@ class ApiToolManageService:
|
|||||||
|
|
||||||
return cast(
|
return cast(
|
||||||
ApiSchemaParseResult,
|
ApiSchemaParseResult,
|
||||||
jsonable_encoder(
|
{
|
||||||
{
|
"schema_type": schema_type.value,
|
||||||
"schema_type": schema_type,
|
"parameters_schema": _dump_api_tool_bundles(tool_bundles),
|
||||||
"parameters_schema": tool_bundles,
|
"credentials_schema": _dump_provider_configs(credentials_schema),
|
||||||
"credentials_schema": credentials_schema,
|
"warning": warnings,
|
||||||
"warning": warnings,
|
},
|
||||||
}
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ValueError(f"invalid schema: {str(e)}")
|
raise ValueError(f"invalid schema: {str(e)}")
|
||||||
@ -118,7 +137,7 @@ class ApiToolManageService:
|
|||||||
privacy_policy: str,
|
privacy_policy: str,
|
||||||
custom_disclaimer: str,
|
custom_disclaimer: str,
|
||||||
labels: list[str],
|
labels: list[str],
|
||||||
) -> dict[str, Any]:
|
) -> SimpleSuccessResult:
|
||||||
"""
|
"""
|
||||||
Create a new API tool provider.
|
Create a new API tool provider.
|
||||||
|
|
||||||
@ -169,7 +188,7 @@ class ApiToolManageService:
|
|||||||
schema=schema,
|
schema=schema,
|
||||||
description=extra_info.get("description", ""),
|
description=extra_info.get("description", ""),
|
||||||
schema_type_str=schema_type,
|
schema_type_str=schema_type,
|
||||||
tools_str=json.dumps(jsonable_encoder(tool_bundles)),
|
tools_str=json.dumps(_dump_api_tool_bundles(tool_bundles)),
|
||||||
credentials_str="{}",
|
credentials_str="{}",
|
||||||
privacy_policy=privacy_policy,
|
privacy_policy=privacy_policy,
|
||||||
custom_disclaimer=custom_disclaimer,
|
custom_disclaimer=custom_disclaimer,
|
||||||
@ -201,7 +220,7 @@ class ApiToolManageService:
|
|||||||
return {"result": "success"}
|
return {"result": "success"}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_api_tool_provider_remote_schema(user_id: str, tenant_id: str, url: str):
|
def get_api_tool_provider_remote_schema(user_id: str, tenant_id: str, url: str) -> RemoteSchemaResult:
|
||||||
"""
|
"""
|
||||||
get api tool provider remote schema
|
get api tool provider remote schema
|
||||||
"""
|
"""
|
||||||
@ -276,7 +295,7 @@ class ApiToolManageService:
|
|||||||
privacy_policy: str | None,
|
privacy_policy: str | None,
|
||||||
custom_disclaimer: str,
|
custom_disclaimer: str,
|
||||||
labels: list[str],
|
labels: list[str],
|
||||||
) -> dict[str, Any]:
|
) -> SimpleSuccessResult:
|
||||||
"""
|
"""
|
||||||
Update an existing API tool provider.
|
Update an existing API tool provider.
|
||||||
|
|
||||||
@ -322,7 +341,7 @@ class ApiToolManageService:
|
|||||||
provider.schema = schema
|
provider.schema = schema
|
||||||
provider.description = extra_info.get("description", "")
|
provider.description = extra_info.get("description", "")
|
||||||
provider.schema_type_str = schema_type
|
provider.schema_type_str = schema_type
|
||||||
provider.tools_str = json.dumps(jsonable_encoder(tool_bundles))
|
provider.tools_str = json.dumps(_dump_api_tool_bundles(tool_bundles))
|
||||||
provider.privacy_policy = privacy_policy
|
provider.privacy_policy = privacy_policy
|
||||||
provider.custom_disclaimer = custom_disclaimer
|
provider.custom_disclaimer = custom_disclaimer
|
||||||
|
|
||||||
@ -365,7 +384,7 @@ class ApiToolManageService:
|
|||||||
return {"result": "success"}
|
return {"result": "success"}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def delete_api_tool_provider(user_id: str, tenant_id: str, provider_name: str):
|
def delete_api_tool_provider(user_id: str, tenant_id: str, provider_name: str) -> SimpleSuccessResult:
|
||||||
"""
|
"""
|
||||||
Delete an API tool provider.
|
Delete an API tool provider.
|
||||||
|
|
||||||
@ -413,9 +432,9 @@ class ApiToolManageService:
|
|||||||
tool_name: str,
|
tool_name: str,
|
||||||
credentials: dict[str, Any],
|
credentials: dict[str, Any],
|
||||||
parameters: dict[str, Any],
|
parameters: dict[str, Any],
|
||||||
schema_type: ApiProviderSchemaType,
|
schema_type: ApiProviderSchemaType | str,
|
||||||
schema: str,
|
schema: str,
|
||||||
) -> dict[str, Any]:
|
) -> ApiToolPreviewResult:
|
||||||
"""
|
"""
|
||||||
Test an API tool before adding the API tool provider.
|
Test an API tool before adding the API tool provider.
|
||||||
|
|
||||||
@ -464,7 +483,7 @@ class ApiToolManageService:
|
|||||||
schema=schema,
|
schema=schema,
|
||||||
description="",
|
description="",
|
||||||
schema_type_str=ApiProviderSchemaType.OPENAPI,
|
schema_type_str=ApiProviderSchemaType.OPENAPI,
|
||||||
tools_str=json.dumps(jsonable_encoder(tool_bundles)),
|
tools_str=json.dumps(_dump_api_tool_bundles(tool_bundles)),
|
||||||
credentials_str=json.dumps(credentials),
|
credentials_str=json.dumps(credentials),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,7 @@ from controllers.console.workspace.tool_providers import (
|
|||||||
ToolWorkflowProviderUpdateApi,
|
ToolWorkflowProviderUpdateApi,
|
||||||
is_valid_url,
|
is_valid_url,
|
||||||
)
|
)
|
||||||
|
from core.tools.entities.api_entities import ToolProviderApiEntity as CoreToolProviderApiEntity
|
||||||
from models.account import Account, TenantAccountRole
|
from models.account import Account, TenantAccountRole
|
||||||
from services.tools.mcp_tools_manage_service import ReconnectResult
|
from services.tools.mcp_tools_manage_service import ReconnectResult
|
||||||
from tests.test_containers_integration_tests.controllers.console.helpers import (
|
from tests.test_containers_integration_tests.controllers.console.helpers import (
|
||||||
@ -60,6 +61,148 @@ def empty_list() -> list[object]:
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def emoji_icon() -> dict[str, str]:
|
||||||
|
return {"content": "tool", "background": "#252525"}
|
||||||
|
|
||||||
|
|
||||||
|
def i18n(text: str) -> dict[str, str]:
|
||||||
|
return {"en_US": text}
|
||||||
|
|
||||||
|
|
||||||
|
def tool_payload(name: str = "ping") -> dict[str, object]:
|
||||||
|
return {
|
||||||
|
"author": "langgenius",
|
||||||
|
"name": name,
|
||||||
|
"label": i18n(name.title()),
|
||||||
|
"description": i18n(f"{name} description"),
|
||||||
|
"parameters": [],
|
||||||
|
"labels": ["utilities"],
|
||||||
|
"output_schema": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def provider_payload(
|
||||||
|
*,
|
||||||
|
provider_id: str = "provider-1",
|
||||||
|
name: str = "provider",
|
||||||
|
provider_type: str = "builtin",
|
||||||
|
tools: list[dict[str, object]] | None = None,
|
||||||
|
) -> dict[str, object]:
|
||||||
|
return {
|
||||||
|
"id": provider_id,
|
||||||
|
"author": "langgenius",
|
||||||
|
"name": name,
|
||||||
|
"description": i18n(f"{name} description"),
|
||||||
|
"icon": emoji_icon(),
|
||||||
|
"icon_dark": emoji_icon(),
|
||||||
|
"label": i18n(name.title()),
|
||||||
|
"type": provider_type,
|
||||||
|
"masked_credentials": {"api_key": "[__HIDDEN__]"},
|
||||||
|
"original_credentials": {"api_key": "sk-secret"},
|
||||||
|
"is_team_authorization": False,
|
||||||
|
"allow_delete": True,
|
||||||
|
"plugin_id": "langgenius/provider",
|
||||||
|
"plugin_unique_identifier": "langgenius/provider:1.0.0",
|
||||||
|
"tools": tools or [tool_payload()],
|
||||||
|
"labels": ["utilities"],
|
||||||
|
"server_url": "",
|
||||||
|
"updated_at": 1710000000,
|
||||||
|
"server_identifier": "",
|
||||||
|
"masked_headers": None,
|
||||||
|
"original_headers": None,
|
||||||
|
"authentication": None,
|
||||||
|
"is_dynamic_registration": True,
|
||||||
|
"configuration": None,
|
||||||
|
"identity_mode": "off",
|
||||||
|
"workflow_app_id": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def provider_entity(
|
||||||
|
*,
|
||||||
|
provider_id: str = "provider-1",
|
||||||
|
name: str = "provider",
|
||||||
|
provider_type: str = "builtin",
|
||||||
|
tools: list[dict[str, object]] | None = None,
|
||||||
|
) -> CoreToolProviderApiEntity:
|
||||||
|
return CoreToolProviderApiEntity.model_validate(
|
||||||
|
provider_payload(provider_id=provider_id, name=name, provider_type=provider_type, tools=tools)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def credential_payload() -> dict[str, object]:
|
||||||
|
return {
|
||||||
|
"id": "credential-1",
|
||||||
|
"name": "Default credential",
|
||||||
|
"provider": "provider",
|
||||||
|
"credential_type": "api-key",
|
||||||
|
"is_default": True,
|
||||||
|
"credentials": {"api_key": "masked"},
|
||||||
|
"visibility": "all_team_members",
|
||||||
|
"created_by": "user-1",
|
||||||
|
"partial_member_list": [],
|
||||||
|
"from_other_member": False,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def provider_config_payload() -> dict[str, object]:
|
||||||
|
return {"type": "secret-input", "name": "api_key", "required": True}
|
||||||
|
|
||||||
|
|
||||||
|
def api_tool_bundle_payload() -> dict[str, object]:
|
||||||
|
return {
|
||||||
|
"server_url": "https://api.example.com",
|
||||||
|
"method": "get",
|
||||||
|
"summary": "Ping",
|
||||||
|
"operation_id": "ping",
|
||||||
|
"parameters": [],
|
||||||
|
"author": "langgenius",
|
||||||
|
"icon": None,
|
||||||
|
"openapi": {"operationId": "ping"},
|
||||||
|
"output_schema": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def api_provider_detail_payload() -> dict[str, object]:
|
||||||
|
return {
|
||||||
|
"schema_type": "openapi",
|
||||||
|
"schema": "{}",
|
||||||
|
"tools": [api_tool_bundle_payload()],
|
||||||
|
"icon": emoji_icon(),
|
||||||
|
"description": "API provider",
|
||||||
|
"credentials": {},
|
||||||
|
"privacy_policy": "",
|
||||||
|
"custom_disclaimer": "",
|
||||||
|
"labels": ["utilities"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def credential_info_payload() -> dict[str, object]:
|
||||||
|
return {
|
||||||
|
"supported_credential_types": ["api-key", "oauth2"],
|
||||||
|
"is_oauth_custom_client_enabled": False,
|
||||||
|
"credentials": [credential_payload()],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def oauth_client_schema_payload() -> dict[str, object]:
|
||||||
|
return {
|
||||||
|
"schema": [provider_config_payload()],
|
||||||
|
"is_oauth_custom_client_enabled": False,
|
||||||
|
"is_system_oauth_params_exists": True,
|
||||||
|
"client_params": {"client_id": "masked"},
|
||||||
|
"redirect_uri": "https://console.example.com/oauth/callback",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def tool_label_payload() -> dict[str, object]:
|
||||||
|
return {
|
||||||
|
"name": "utilities",
|
||||||
|
"label": i18n("Utilities"),
|
||||||
|
"icon": "wrench",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def _mock_cache() -> None:
|
def _mock_cache() -> None:
|
||||||
return
|
return
|
||||||
@ -127,7 +270,7 @@ def test_create_mcp_provider_populates_tools(
|
|||||||
with (
|
with (
|
||||||
patch(
|
patch(
|
||||||
"services.tools.tools_transform_service.ToolTransformService.mcp_provider_to_user_provider",
|
"services.tools.tools_transform_service.ToolTransformService.mcp_provider_to_user_provider",
|
||||||
return_value={"id": "provider-1", "tools": [{"name": "ping"}]},
|
return_value=provider_entity(provider_id="provider-1", provider_type="mcp", tools=[tool_payload()]),
|
||||||
autospec=True,
|
autospec=True,
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
@ -138,13 +281,15 @@ def test_create_mcp_provider_populates_tools(
|
|||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert resp.status_code == 200
|
assert resp.status_code == 200
|
||||||
body = resp.get_json()
|
body = resp.get_json()
|
||||||
assert body.get("id") == "provider-1"
|
assert body.get("id") == "provider-1"
|
||||||
# 若 transform 后包含 tools 字段,确保非空
|
assert body["team_credentials"] == {"api_key": "[__HIDDEN__]"}
|
||||||
assert isinstance(body.get("tools"), list)
|
assert "masked_credentials" not in body
|
||||||
assert body["tools"]
|
assert "original_credentials" not in body
|
||||||
|
assert isinstance(body.get("tools"), list)
|
||||||
|
assert body["tools"]
|
||||||
|
|
||||||
|
|
||||||
class TestUtils:
|
class TestUtils:
|
||||||
@ -170,10 +315,16 @@ class TestToolProviderListApi:
|
|||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.ToolCommonService.list_tool_providers",
|
"controllers.console.workspace.tool_providers.ToolCommonService.list_tool_providers",
|
||||||
return_value=["p1"],
|
return_value=[provider_entity(provider_id="p1").to_dict()],
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t1", make_account(id="u1")) == ["p1"]
|
result = method(api, "t1", make_account(id="u1"))
|
||||||
|
|
||||||
|
assert result[0]["id"] == "p1"
|
||||||
|
assert result[0]["team_credentials"] == {"api_key": "[__HIDDEN__]"}
|
||||||
|
assert "masked_credentials" not in result[0]
|
||||||
|
assert "original_credentials" not in result[0]
|
||||||
|
assert result[0]["tools"][0]["name"] == "ping"
|
||||||
|
|
||||||
|
|
||||||
class TestBuiltinProviderApis:
|
class TestBuiltinProviderApis:
|
||||||
@ -189,10 +340,10 @@ class TestBuiltinProviderApis:
|
|||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.BuiltinToolManageService.list_builtin_tool_provider_tools",
|
"controllers.console.workspace.tool_providers.BuiltinToolManageService.list_builtin_tool_provider_tools",
|
||||||
return_value=[{"a": 1}],
|
return_value=[tool_payload()],
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t1", "provider") == [{"a": 1}]
|
assert method(api, "t1", "provider")[0]["name"] == "ping"
|
||||||
|
|
||||||
def test_info(self, app: Flask) -> None:
|
def test_info(self, app: Flask) -> None:
|
||||||
api = ToolBuiltinProviderInfoApi()
|
api = ToolBuiltinProviderInfoApi()
|
||||||
@ -202,10 +353,15 @@ class TestBuiltinProviderApis:
|
|||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.BuiltinToolManageService.get_builtin_tool_provider_info",
|
"controllers.console.workspace.tool_providers.BuiltinToolManageService.get_builtin_tool_provider_info",
|
||||||
return_value={"x": 1},
|
return_value=provider_entity(),
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t1", "provider") == {"x": 1}
|
result = method(api, "t1", "provider")
|
||||||
|
|
||||||
|
assert result["id"] == "provider-1"
|
||||||
|
assert result["team_credentials"] == {"api_key": "[__HIDDEN__]"}
|
||||||
|
assert "masked_credentials" not in result
|
||||||
|
assert "original_credentials" not in result
|
||||||
|
|
||||||
def test_delete(self, app: Flask) -> None:
|
def test_delete(self, app: Flask) -> None:
|
||||||
api = ToolBuiltinProviderDeleteApi()
|
api = ToolBuiltinProviderDeleteApi()
|
||||||
@ -240,10 +396,10 @@ class TestBuiltinProviderApis:
|
|||||||
app.test_request_context("/", json=payload),
|
app.test_request_context("/", json=payload),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.BuiltinToolManageService.add_builtin_tool_provider",
|
"controllers.console.workspace.tool_providers.BuiltinToolManageService.add_builtin_tool_provider",
|
||||||
return_value={"id": 1},
|
return_value={"result": "success"},
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account(), "provider")["id"] == 1
|
assert method(api, "t", make_account(), "provider")["result"] == "success"
|
||||||
|
|
||||||
def test_update(self, app: Flask) -> None:
|
def test_update(self, app: Flask) -> None:
|
||||||
api = ToolBuiltinProviderUpdateApi()
|
api = ToolBuiltinProviderUpdateApi()
|
||||||
@ -255,10 +411,10 @@ class TestBuiltinProviderApis:
|
|||||||
app.test_request_context("/", json=payload),
|
app.test_request_context("/", json=payload),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.BuiltinToolManageService.update_builtin_tool_provider",
|
"controllers.console.workspace.tool_providers.BuiltinToolManageService.update_builtin_tool_provider",
|
||||||
return_value={"ok": True},
|
return_value={"result": "success"},
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account(), "provider")["ok"]
|
assert method(api, "t", make_account(), "provider")["result"] == "success"
|
||||||
|
|
||||||
def test_get_credentials(self, app: Flask) -> None:
|
def test_get_credentials(self, app: Flask) -> None:
|
||||||
api = ToolBuiltinProviderGetCredentialsApi()
|
api = ToolBuiltinProviderGetCredentialsApi()
|
||||||
@ -268,10 +424,10 @@ class TestBuiltinProviderApis:
|
|||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.BuiltinToolManageService.get_builtin_tool_provider_credentials",
|
"controllers.console.workspace.tool_providers.BuiltinToolManageService.get_builtin_tool_provider_credentials",
|
||||||
return_value={"k": "v"},
|
return_value=[credential_payload()],
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account(id="user-1"), "provider") == {"k": "v"}
|
assert method(api, "t", make_account(id="user-1"), "provider")[0]["id"] == "credential-1"
|
||||||
|
|
||||||
def test_icon(self, app: Flask) -> None:
|
def test_icon(self, app: Flask) -> None:
|
||||||
api = ToolBuiltinProviderIconApi()
|
api = ToolBuiltinProviderIconApi()
|
||||||
@ -295,10 +451,10 @@ class TestBuiltinProviderApis:
|
|||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.BuiltinToolManageService.list_builtin_provider_credentials_schema",
|
"controllers.console.workspace.tool_providers.BuiltinToolManageService.list_builtin_provider_credentials_schema",
|
||||||
return_value={"schema": {}},
|
return_value=[provider_config_payload()],
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", "provider", "oauth2") == {"schema": {}}
|
assert method(api, "t", "provider", "oauth2")[0]["name"] == "api_key"
|
||||||
|
|
||||||
def test_set_default_credential(self, app: Flask) -> None:
|
def test_set_default_credential(self, app: Flask) -> None:
|
||||||
api = ToolBuiltinProviderSetDefaultApi()
|
api = ToolBuiltinProviderSetDefaultApi()
|
||||||
@ -308,10 +464,10 @@ class TestBuiltinProviderApis:
|
|||||||
app.test_request_context("/", json={"id": "c1"}),
|
app.test_request_context("/", json={"id": "c1"}),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.BuiltinToolManageService.set_default_provider",
|
"controllers.console.workspace.tool_providers.BuiltinToolManageService.set_default_provider",
|
||||||
return_value={"ok": True},
|
return_value={"result": "success"},
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", "provider")["ok"]
|
assert method(api, "t", "provider")["result"] == "success"
|
||||||
|
|
||||||
def test_get_credential_info(self, app: Flask) -> None:
|
def test_get_credential_info(self, app: Flask) -> None:
|
||||||
api = ToolBuiltinProviderGetCredentialInfoApi()
|
api = ToolBuiltinProviderGetCredentialInfoApi()
|
||||||
@ -321,10 +477,10 @@ class TestBuiltinProviderApis:
|
|||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.BuiltinToolManageService.get_builtin_tool_provider_credential_info",
|
"controllers.console.workspace.tool_providers.BuiltinToolManageService.get_builtin_tool_provider_credential_info",
|
||||||
return_value={"info": "x"},
|
return_value=credential_info_payload(),
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account(), "provider") == {"info": "x"}
|
assert method(api, "t", make_account(), "provider")["credentials"][0]["id"] == "credential-1"
|
||||||
|
|
||||||
def test_get_oauth_client_schema(self, app: Flask) -> None:
|
def test_get_oauth_client_schema(self, app: Flask) -> None:
|
||||||
api = ToolBuiltinProviderGetOauthClientSchemaApi()
|
api = ToolBuiltinProviderGetOauthClientSchemaApi()
|
||||||
@ -334,10 +490,10 @@ class TestBuiltinProviderApis:
|
|||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.BuiltinToolManageService.get_builtin_tool_provider_oauth_client_schema",
|
"controllers.console.workspace.tool_providers.BuiltinToolManageService.get_builtin_tool_provider_oauth_client_schema",
|
||||||
return_value={"schema": {}},
|
return_value=oauth_client_schema_payload(),
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", "provider") == {"schema": {}}
|
assert method(api, "t", "provider")["schema"][0]["name"] == "api_key"
|
||||||
|
|
||||||
|
|
||||||
class TestApiProviderApis:
|
class TestApiProviderApis:
|
||||||
@ -354,30 +510,34 @@ class TestApiProviderApis:
|
|||||||
"schema_type": "openapi",
|
"schema_type": "openapi",
|
||||||
"schema": "{}",
|
"schema": "{}",
|
||||||
"provider": "p",
|
"provider": "p",
|
||||||
"icon": empty_mapping(),
|
"icon": emoji_icon(),
|
||||||
}
|
}
|
||||||
|
|
||||||
with (
|
with (
|
||||||
app.test_request_context("/", json=payload),
|
app.test_request_context("/", json=payload),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.ApiToolManageService.create_api_tool_provider",
|
"controllers.console.workspace.tool_providers.ApiToolManageService.create_api_tool_provider",
|
||||||
return_value={"id": 1},
|
return_value={"result": "success"},
|
||||||
),
|
) as create_api_tool_provider,
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account())["id"] == 1
|
assert method(api, "t", make_account()) == {"result": "success"}
|
||||||
|
|
||||||
|
create_api_tool_provider.assert_called_once()
|
||||||
|
assert create_api_tool_provider.call_args.args[3] == emoji_icon()
|
||||||
|
|
||||||
def test_remote_schema(self, app: Flask) -> None:
|
def test_remote_schema(self, app: Flask) -> None:
|
||||||
api = ToolApiProviderGetRemoteSchemaApi()
|
api = ToolApiProviderGetRemoteSchemaApi()
|
||||||
method = unwrap(api.get)
|
method = unwrap(api.get)
|
||||||
|
openapi_schema = '{"openapi":"3.0.0","info":{"title":"Demo API","version":"1.0.0"},"paths":{}}'
|
||||||
|
|
||||||
with (
|
with (
|
||||||
app.test_request_context("/?url=http://x.com"),
|
app.test_request_context("/?url=http://x.com"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.ApiToolManageService.get_api_tool_provider_remote_schema",
|
"controllers.console.workspace.tool_providers.ApiToolManageService.get_api_tool_provider_remote_schema",
|
||||||
return_value={"schema": "x"},
|
return_value={"schema": openapi_schema},
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account())["schema"] == "x"
|
assert method(api, "t", make_account()) == {"schema": openapi_schema}
|
||||||
|
|
||||||
def test_list_tools(self, app: Flask) -> None:
|
def test_list_tools(self, app: Flask) -> None:
|
||||||
api = ToolApiProviderListToolsApi()
|
api = ToolApiProviderListToolsApi()
|
||||||
@ -387,10 +547,10 @@ class TestApiProviderApis:
|
|||||||
app.test_request_context("/?provider=p"),
|
app.test_request_context("/?provider=p"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.ApiToolManageService.list_api_tool_provider_tools",
|
"controllers.console.workspace.tool_providers.ApiToolManageService.list_api_tool_provider_tools",
|
||||||
return_value=[{"tool": 1}],
|
return_value=[tool_payload("api_ping")],
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account()) == [{"tool": 1}]
|
assert method(api, "t", make_account())[0]["name"] == "api_ping"
|
||||||
|
|
||||||
def test_update(self, app: Flask) -> None:
|
def test_update(self, app: Flask) -> None:
|
||||||
api = ToolApiProviderUpdateApi()
|
api = ToolApiProviderUpdateApi()
|
||||||
@ -402,7 +562,7 @@ class TestApiProviderApis:
|
|||||||
"schema": "{}",
|
"schema": "{}",
|
||||||
"provider": "p",
|
"provider": "p",
|
||||||
"original_provider": "o",
|
"original_provider": "o",
|
||||||
"icon": empty_mapping(),
|
"icon": emoji_icon(),
|
||||||
"privacy_policy": "",
|
"privacy_policy": "",
|
||||||
"custom_disclaimer": "",
|
"custom_disclaimer": "",
|
||||||
}
|
}
|
||||||
@ -411,10 +571,13 @@ class TestApiProviderApis:
|
|||||||
app.test_request_context("/", json=payload),
|
app.test_request_context("/", json=payload),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.ApiToolManageService.update_api_tool_provider",
|
"controllers.console.workspace.tool_providers.ApiToolManageService.update_api_tool_provider",
|
||||||
return_value={"ok": True},
|
return_value={"result": "success"},
|
||||||
),
|
) as update_api_tool_provider,
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account())["ok"]
|
assert method(api, "t", make_account()) == {"result": "success"}
|
||||||
|
|
||||||
|
update_api_tool_provider.assert_called_once()
|
||||||
|
assert update_api_tool_provider.call_args.args[4] == emoji_icon()
|
||||||
|
|
||||||
def test_delete(self, app: Flask) -> None:
|
def test_delete(self, app: Flask) -> None:
|
||||||
api = ToolApiProviderDeleteApi()
|
api = ToolApiProviderDeleteApi()
|
||||||
@ -437,10 +600,10 @@ class TestApiProviderApis:
|
|||||||
app.test_request_context("/?provider=p"),
|
app.test_request_context("/?provider=p"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.ApiToolManageService.get_api_tool_provider",
|
"controllers.console.workspace.tool_providers.ApiToolManageService.get_api_tool_provider",
|
||||||
return_value={"x": 1},
|
return_value=api_provider_detail_payload(),
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account()) == {"x": 1}
|
assert method(api, "t", make_account())["schema"] == "{}"
|
||||||
|
|
||||||
|
|
||||||
class TestWorkflowApis:
|
class TestWorkflowApis:
|
||||||
@ -457,7 +620,7 @@ class TestWorkflowApis:
|
|||||||
"name": "n",
|
"name": "n",
|
||||||
"label": "l",
|
"label": "l",
|
||||||
"description": "d",
|
"description": "d",
|
||||||
"icon": empty_mapping(),
|
"icon": emoji_icon(),
|
||||||
"parameters": empty_list(),
|
"parameters": empty_list(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,10 +628,13 @@ class TestWorkflowApis:
|
|||||||
app.test_request_context("/", json=payload),
|
app.test_request_context("/", json=payload),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.WorkflowToolManageService.create_workflow_tool",
|
"controllers.console.workspace.tool_providers.WorkflowToolManageService.create_workflow_tool",
|
||||||
return_value={"id": 1},
|
return_value={"result": "success"},
|
||||||
),
|
) as create_workflow_tool,
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account())["id"] == 1
|
assert method(api, "t", make_account()) == {"result": "success"}
|
||||||
|
|
||||||
|
create_workflow_tool.assert_called_once()
|
||||||
|
assert create_workflow_tool.call_args.kwargs["icon"] == emoji_icon()
|
||||||
|
|
||||||
def test_update_invalid(self, app: Flask) -> None:
|
def test_update_invalid(self, app: Flask) -> None:
|
||||||
api = ToolWorkflowProviderUpdateApi()
|
api = ToolWorkflowProviderUpdateApi()
|
||||||
@ -479,18 +645,21 @@ class TestWorkflowApis:
|
|||||||
"name": "Tool",
|
"name": "Tool",
|
||||||
"label": "Tool Label",
|
"label": "Tool Label",
|
||||||
"description": "A tool",
|
"description": "A tool",
|
||||||
"icon": empty_mapping(),
|
"icon": emoji_icon(),
|
||||||
}
|
}
|
||||||
|
|
||||||
with (
|
with (
|
||||||
app.test_request_context("/", json=payload),
|
app.test_request_context("/", json=payload),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.WorkflowToolManageService.update_workflow_tool",
|
"controllers.console.workspace.tool_providers.WorkflowToolManageService.update_workflow_tool",
|
||||||
return_value={"ok": True},
|
return_value={"result": "success"},
|
||||||
),
|
) as update_workflow_tool,
|
||||||
):
|
):
|
||||||
result = method(api, "t", make_account())
|
result = method(api, "t", make_account())
|
||||||
assert result["ok"]
|
assert result == {"result": "success"}
|
||||||
|
|
||||||
|
update_workflow_tool.assert_called_once()
|
||||||
|
assert update_workflow_tool.call_args.args[5] == emoji_icon()
|
||||||
|
|
||||||
def test_delete(self, app: Flask) -> None:
|
def test_delete(self, app: Flask) -> None:
|
||||||
api = ToolWorkflowProviderDeleteApi()
|
api = ToolWorkflowProviderDeleteApi()
|
||||||
@ -500,10 +669,10 @@ class TestWorkflowApis:
|
|||||||
app.test_request_context("/", json={"workflow_tool_id": "123e4567-e89b-12d3-a456-426614174000"}),
|
app.test_request_context("/", json={"workflow_tool_id": "123e4567-e89b-12d3-a456-426614174000"}),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.WorkflowToolManageService.delete_workflow_tool",
|
"controllers.console.workspace.tool_providers.WorkflowToolManageService.delete_workflow_tool",
|
||||||
return_value={"ok": True},
|
return_value={"result": "success"},
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account())["ok"]
|
assert method(api, "t", make_account())["result"] == "success"
|
||||||
|
|
||||||
def test_get_error(self, app: Flask) -> None:
|
def test_get_error(self, app: Flask) -> None:
|
||||||
api = ToolWorkflowProviderGetApi()
|
api = ToolWorkflowProviderGetApi()
|
||||||
@ -525,49 +694,40 @@ class TestLists:
|
|||||||
api = ToolBuiltinListApi()
|
api = ToolBuiltinListApi()
|
||||||
method = unwrap(api.get)
|
method = unwrap(api.get)
|
||||||
|
|
||||||
m = MagicMock()
|
|
||||||
m.to_dict.return_value = {"x": 1}
|
|
||||||
|
|
||||||
with (
|
with (
|
||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.BuiltinToolManageService.list_builtin_tools",
|
"controllers.console.workspace.tool_providers.BuiltinToolManageService.list_builtin_tools",
|
||||||
return_value=[m],
|
return_value=[provider_entity(provider_id="builtin-1")],
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account()) == [{"x": 1}]
|
assert method(api, "t", make_account())[0]["id"] == "builtin-1"
|
||||||
|
|
||||||
def test_api_list(self, app: Flask) -> None:
|
def test_api_list(self, app: Flask) -> None:
|
||||||
api = ToolApiListApi()
|
api = ToolApiListApi()
|
||||||
method = unwrap(api.get)
|
method = unwrap(api.get)
|
||||||
|
|
||||||
m = MagicMock()
|
|
||||||
m.to_dict.return_value = {"x": 1}
|
|
||||||
|
|
||||||
with (
|
with (
|
||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.ApiToolManageService.list_api_tools",
|
"controllers.console.workspace.tool_providers.ApiToolManageService.list_api_tools",
|
||||||
return_value=[m],
|
return_value=[provider_entity(provider_id="api-1", provider_type="api")],
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t") == [{"x": 1}]
|
assert method(api, "t")[0]["id"] == "api-1"
|
||||||
|
|
||||||
def test_workflow_list(self, app: Flask) -> None:
|
def test_workflow_list(self, app: Flask) -> None:
|
||||||
api = ToolWorkflowListApi()
|
api = ToolWorkflowListApi()
|
||||||
method = unwrap(api.get)
|
method = unwrap(api.get)
|
||||||
|
|
||||||
m = MagicMock()
|
|
||||||
m.to_dict.return_value = {"x": 1}
|
|
||||||
|
|
||||||
with (
|
with (
|
||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.WorkflowToolManageService.list_tenant_workflow_tools",
|
"controllers.console.workspace.tool_providers.WorkflowToolManageService.list_tenant_workflow_tools",
|
||||||
return_value=[m],
|
return_value=[provider_entity(provider_id="workflow-1", provider_type="workflow")],
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", make_account()) == [{"x": 1}]
|
assert method(api, "t", make_account())[0]["id"] == "workflow-1"
|
||||||
|
|
||||||
|
|
||||||
class TestLabels:
|
class TestLabels:
|
||||||
@ -583,10 +743,10 @@ class TestLabels:
|
|||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.ToolLabelsService.list_tool_labels",
|
"controllers.console.workspace.tool_providers.ToolLabelsService.list_tool_labels",
|
||||||
return_value=["l1"],
|
return_value=[tool_label_payload()],
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api) == ["l1"]
|
assert method(api)[0]["name"] == "utilities"
|
||||||
|
|
||||||
|
|
||||||
class TestOAuth:
|
class TestOAuth:
|
||||||
@ -630,10 +790,10 @@ class TestOAuthCustomClient:
|
|||||||
app.test_request_context("/", json={"client_params": {"a": 1}}),
|
app.test_request_context("/", json={"client_params": {"a": 1}}),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.BuiltinToolManageService.save_custom_oauth_client_params",
|
"controllers.console.workspace.tool_providers.BuiltinToolManageService.save_custom_oauth_client_params",
|
||||||
return_value={"ok": True},
|
return_value={"result": "success"},
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", "provider")["ok"]
|
assert method(api, "t", "provider") == {"result": "success"}
|
||||||
|
|
||||||
def test_get_custom_client(self, app: Flask) -> None:
|
def test_get_custom_client(self, app: Flask) -> None:
|
||||||
api = ToolOAuthCustomClient()
|
api = ToolOAuthCustomClient()
|
||||||
@ -656,7 +816,7 @@ class TestOAuthCustomClient:
|
|||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.tool_providers.BuiltinToolManageService.delete_custom_oauth_client_params",
|
"controllers.console.workspace.tool_providers.BuiltinToolManageService.delete_custom_oauth_client_params",
|
||||||
return_value={"ok": True},
|
return_value={"result": "success"},
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t", "provider")["ok"]
|
assert method(api, "t", "provider") == {"result": "success"}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
from inspect import unwrap
|
from inspect import unwrap
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
@ -29,6 +30,8 @@ from controllers.console.workspace.trigger_providers import (
|
|||||||
TriggerSubscriptionVerifyApi,
|
TriggerSubscriptionVerifyApi,
|
||||||
)
|
)
|
||||||
from core.plugin.entities.plugin_daemon import CredentialType
|
from core.plugin.entities.plugin_daemon import CredentialType
|
||||||
|
from core.trigger.entities.api_entities import SubscriptionBuilderApiEntity, TriggerProviderApiEntity
|
||||||
|
from core.trigger.entities.entities import RequestLog
|
||||||
from models.account import Account
|
from models.account import Account
|
||||||
|
|
||||||
|
|
||||||
@ -38,6 +41,47 @@ def mock_user() -> Account:
|
|||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
def trigger_provider() -> TriggerProviderApiEntity:
|
||||||
|
return TriggerProviderApiEntity(
|
||||||
|
author="Dify",
|
||||||
|
name="github",
|
||||||
|
label={"en_US": "GitHub"},
|
||||||
|
description={"en_US": "GitHub trigger provider"},
|
||||||
|
icon="icon.svg",
|
||||||
|
icon_dark=None,
|
||||||
|
tags=["code"],
|
||||||
|
plugin_id="plugin",
|
||||||
|
plugin_unique_identifier="plugin:github",
|
||||||
|
supported_creation_methods=[],
|
||||||
|
subscription_constructor=None,
|
||||||
|
subscription_schema=[],
|
||||||
|
events=[],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def subscription_builder() -> SubscriptionBuilderApiEntity:
|
||||||
|
return SubscriptionBuilderApiEntity(
|
||||||
|
id="b1",
|
||||||
|
name="Builder",
|
||||||
|
provider="github",
|
||||||
|
endpoint="b1",
|
||||||
|
parameters={"repo": "dify"},
|
||||||
|
properties={"branch": "main"},
|
||||||
|
credentials={"token": "secret"},
|
||||||
|
credential_type=CredentialType.UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def request_log() -> RequestLog:
|
||||||
|
return RequestLog(
|
||||||
|
id="log1",
|
||||||
|
endpoint="/hooks/b1",
|
||||||
|
request={"headers": {}, "body": {"event": "push"}},
|
||||||
|
response={"status": 200, "body": {"ok": True}},
|
||||||
|
created_at=datetime(2024, 1, 1),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestTriggerProviderApis:
|
class TestTriggerProviderApis:
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def app(self, flask_app_with_containers: Flask) -> Flask:
|
def app(self, flask_app_with_containers: Flask) -> Flask:
|
||||||
@ -77,10 +121,10 @@ class TestTriggerProviderApis:
|
|||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.trigger_providers.TriggerProviderService.get_trigger_provider",
|
"controllers.console.workspace.trigger_providers.TriggerProviderService.get_trigger_provider",
|
||||||
return_value={"id": "p1"},
|
return_value=trigger_provider(),
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t1", "github") == {"id": "p1"}
|
assert method(api, "t1", "github")["name"] == "github"
|
||||||
|
|
||||||
|
|
||||||
class TestTriggerSubscriptionListApi:
|
class TestTriggerSubscriptionListApi:
|
||||||
@ -129,11 +173,11 @@ class TestTriggerSubscriptionBuilderApis:
|
|||||||
app.test_request_context("/", json={"credential_type": "UNAUTHORIZED"}),
|
app.test_request_context("/", json={"credential_type": "UNAUTHORIZED"}),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.trigger_providers.TriggerSubscriptionBuilderService.create_trigger_subscription_builder",
|
"controllers.console.workspace.trigger_providers.TriggerSubscriptionBuilderService.create_trigger_subscription_builder",
|
||||||
return_value={"id": "b1"},
|
return_value=subscription_builder(),
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
result = method(api, "t1", mock_user(), "github")
|
result = method(api, "t1", mock_user(), "github")
|
||||||
assert "subscription_builder" in result
|
assert result["subscription_builder"]["id"] == "b1"
|
||||||
|
|
||||||
def test_get_builder(self, app: Flask) -> None:
|
def test_get_builder(self, app: Flask) -> None:
|
||||||
api = TriggerSubscriptionBuilderGetApi()
|
api = TriggerSubscriptionBuilderGetApi()
|
||||||
@ -143,10 +187,10 @@ class TestTriggerSubscriptionBuilderApis:
|
|||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.trigger_providers.TriggerSubscriptionBuilderService.get_subscription_builder_by_id",
|
"controllers.console.workspace.trigger_providers.TriggerSubscriptionBuilderService.get_subscription_builder_by_id",
|
||||||
return_value={"id": "b1"},
|
return_value=subscription_builder(),
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "github", "b1") == {"id": "b1"}
|
assert method(api, "github", "b1")["id"] == "b1"
|
||||||
|
|
||||||
def test_verify_builder(self, app: Flask) -> None:
|
def test_verify_builder(self, app: Flask) -> None:
|
||||||
api = TriggerSubscriptionBuilderVerifyApi()
|
api = TriggerSubscriptionBuilderVerifyApi()
|
||||||
@ -156,10 +200,10 @@ class TestTriggerSubscriptionBuilderApis:
|
|||||||
app.test_request_context("/", json={"credentials": {"a": 1}}),
|
app.test_request_context("/", json={"credentials": {"a": 1}}),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.trigger_providers.TriggerSubscriptionBuilderService.update_and_verify_builder",
|
"controllers.console.workspace.trigger_providers.TriggerSubscriptionBuilderService.update_and_verify_builder",
|
||||||
return_value={"ok": True},
|
return_value={"verified": True},
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t1", mock_user(), "github", "b1") == {"ok": True}
|
assert method(api, "t1", mock_user(), "github", "b1") == {"verified": True}
|
||||||
|
|
||||||
def test_verify_builder_error(self, app: Flask) -> None:
|
def test_verify_builder_error(self, app: Flask) -> None:
|
||||||
api = TriggerSubscriptionBuilderVerifyApi()
|
api = TriggerSubscriptionBuilderVerifyApi()
|
||||||
@ -183,26 +227,24 @@ class TestTriggerSubscriptionBuilderApis:
|
|||||||
app.test_request_context("/", json={"name": "n"}),
|
app.test_request_context("/", json={"name": "n"}),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.trigger_providers.TriggerSubscriptionBuilderService.update_trigger_subscription_builder",
|
"controllers.console.workspace.trigger_providers.TriggerSubscriptionBuilderService.update_trigger_subscription_builder",
|
||||||
return_value={"id": "b1"},
|
return_value=subscription_builder(),
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t1", "github", "b1") == {"id": "b1"}
|
assert method(api, "t1", "github", "b1")["id"] == "b1"
|
||||||
|
|
||||||
def test_logs(self, app: Flask) -> None:
|
def test_logs(self, app: Flask) -> None:
|
||||||
api = TriggerSubscriptionBuilderLogsApi()
|
api = TriggerSubscriptionBuilderLogsApi()
|
||||||
method = unwrap(api.get)
|
method = unwrap(api.get)
|
||||||
|
|
||||||
log = MagicMock()
|
|
||||||
log.model_dump.return_value = {"a": 1}
|
|
||||||
|
|
||||||
with (
|
with (
|
||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.trigger_providers.TriggerSubscriptionBuilderService.list_logs",
|
"controllers.console.workspace.trigger_providers.TriggerSubscriptionBuilderService.list_logs",
|
||||||
return_value=[log],
|
return_value=[request_log()],
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert "logs" in method(api, "github", "b1")
|
result = method(api, "github", "b1")
|
||||||
|
assert result["logs"][0]["id"] == "log1"
|
||||||
|
|
||||||
def test_build(self, app: Flask) -> None:
|
def test_build(self, app: Flask) -> None:
|
||||||
api = TriggerSubscriptionBuilderBuildApi()
|
api = TriggerSubscriptionBuilderBuildApi()
|
||||||
@ -215,7 +257,7 @@ class TestTriggerSubscriptionBuilderApis:
|
|||||||
return_value=None,
|
return_value=None,
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t1", mock_user(), "github", "b1") == 200
|
assert method(api, "t1", mock_user(), "github", "b1") == {"result": "success"}
|
||||||
|
|
||||||
|
|
||||||
class TestTriggerSubscriptionCrud:
|
class TestTriggerSubscriptionCrud:
|
||||||
@ -239,7 +281,7 @@ class TestTriggerSubscriptionCrud:
|
|||||||
),
|
),
|
||||||
patch("controllers.console.workspace.trigger_providers.TriggerProviderService.update_trigger_subscription"),
|
patch("controllers.console.workspace.trigger_providers.TriggerProviderService.update_trigger_subscription"),
|
||||||
):
|
):
|
||||||
assert method(api, "t1", "s1") == 200
|
assert method(api, "t1", "s1") == {"result": "success"}
|
||||||
|
|
||||||
def test_update_not_found(self, app: Flask) -> None:
|
def test_update_not_found(self, app: Flask) -> None:
|
||||||
api = TriggerSubscriptionUpdateApi()
|
api = TriggerSubscriptionUpdateApi()
|
||||||
@ -275,7 +317,7 @@ class TestTriggerSubscriptionCrud:
|
|||||||
"controllers.console.workspace.trigger_providers.TriggerProviderService.rebuild_trigger_subscription"
|
"controllers.console.workspace.trigger_providers.TriggerProviderService.rebuild_trigger_subscription"
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t1", "s1") == 200
|
assert method(api, "t1", "s1") == {"result": "success"}
|
||||||
|
|
||||||
def test_delete_subscription(self, app: Flask) -> None:
|
def test_delete_subscription(self, app: Flask) -> None:
|
||||||
api = TriggerSubscriptionDeleteApi()
|
api = TriggerSubscriptionDeleteApi()
|
||||||
@ -336,7 +378,7 @@ class TestTriggerOAuthApis:
|
|||||||
),
|
),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.trigger_providers.TriggerSubscriptionBuilderService.create_trigger_subscription_builder",
|
"controllers.console.workspace.trigger_providers.TriggerSubscriptionBuilderService.create_trigger_subscription_builder",
|
||||||
return_value=MagicMock(id="b1"),
|
return_value=subscription_builder(),
|
||||||
),
|
),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.trigger_providers.OAuthProxyService.create_proxy_context",
|
"controllers.console.workspace.trigger_providers.OAuthProxyService.create_proxy_context",
|
||||||
@ -480,7 +522,7 @@ class TestTriggerOAuthClientManageApi:
|
|||||||
),
|
),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.trigger_providers.TriggerManager.get_trigger_provider",
|
"controllers.console.workspace.trigger_providers.TriggerManager.get_trigger_provider",
|
||||||
return_value=MagicMock(get_oauth_client_schema=lambda: {}),
|
return_value=MagicMock(get_oauth_client_schema=lambda: []),
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
result = method(api, "t1", "github")
|
result = method(api, "t1", "github")
|
||||||
@ -494,10 +536,10 @@ class TestTriggerOAuthClientManageApi:
|
|||||||
app.test_request_context("/", json={"enabled": True}),
|
app.test_request_context("/", json={"enabled": True}),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.trigger_providers.TriggerProviderService.save_custom_oauth_client_params",
|
"controllers.console.workspace.trigger_providers.TriggerProviderService.save_custom_oauth_client_params",
|
||||||
return_value={"ok": True},
|
return_value={"result": "success"},
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t1", "github") == {"ok": True}
|
assert method(api, "t1", "github") == {"result": "success"}
|
||||||
|
|
||||||
def test_delete_client(self, app: Flask) -> None:
|
def test_delete_client(self, app: Flask) -> None:
|
||||||
api = TriggerOAuthClientManageApi()
|
api = TriggerOAuthClientManageApi()
|
||||||
@ -507,10 +549,10 @@ class TestTriggerOAuthClientManageApi:
|
|||||||
app.test_request_context("/"),
|
app.test_request_context("/"),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.trigger_providers.TriggerProviderService.delete_custom_oauth_client_params",
|
"controllers.console.workspace.trigger_providers.TriggerProviderService.delete_custom_oauth_client_params",
|
||||||
return_value={"ok": True},
|
return_value={"result": "success"},
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t1", "github") == {"ok": True}
|
assert method(api, "t1", "github") == {"result": "success"}
|
||||||
|
|
||||||
def test_oauth_client_post_value_error(self, app: Flask) -> None:
|
def test_oauth_client_post_value_error(self, app: Flask) -> None:
|
||||||
api = TriggerOAuthClientManageApi()
|
api = TriggerOAuthClientManageApi()
|
||||||
@ -540,10 +582,10 @@ class TestTriggerSubscriptionVerifyApi:
|
|||||||
app.test_request_context("/", json={"credentials": {}}),
|
app.test_request_context("/", json={"credentials": {}}),
|
||||||
patch(
|
patch(
|
||||||
"controllers.console.workspace.trigger_providers.TriggerProviderService.verify_subscription_credentials",
|
"controllers.console.workspace.trigger_providers.TriggerProviderService.verify_subscription_credentials",
|
||||||
return_value={"ok": True},
|
return_value={"verified": True},
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
assert method(api, "t1", mock_user(), "github", "s1") == {"ok": True}
|
assert method(api, "t1", mock_user(), "github", "s1") == {"verified": True}
|
||||||
|
|
||||||
@pytest.mark.parametrize("raised_exception", [ValueError("bad"), Exception("boom")])
|
@pytest.mark.parametrize("raised_exception", [ValueError("bad"), Exception("boom")])
|
||||||
def test_verify_errors(self, app: Flask, raised_exception: Exception) -> None:
|
def test_verify_errors(self, app: Flask, raised_exception: Exception) -> None:
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import inspect
|
import inspect
|
||||||
import json
|
import json
|
||||||
from unittest.mock import patch
|
from collections.abc import Iterator
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from faker import Faker
|
from faker import Faker
|
||||||
@ -10,16 +11,18 @@ from sqlalchemy.orm import Session
|
|||||||
from core.tools.entities.tool_entities import ApiProviderSchemaType
|
from core.tools.entities.tool_entities import ApiProviderSchemaType
|
||||||
from core.tools.errors import ApiToolProviderNotFoundError
|
from core.tools.errors import ApiToolProviderNotFoundError
|
||||||
from core.tools.tool_label_manager import ToolLabelManager
|
from core.tools.tool_label_manager import ToolLabelManager
|
||||||
from models import Account, Tenant
|
from models import Account, AccountStatus, Tenant, TenantStatus
|
||||||
from models.tools import ApiToolProvider
|
from models.tools import ApiToolProvider
|
||||||
from services.tools.api_tools_manage_service import ApiToolManageService
|
from services.tools.api_tools_manage_service import ApiToolManageService
|
||||||
|
|
||||||
|
MockDependencies = dict[str, MagicMock]
|
||||||
|
|
||||||
|
|
||||||
class TestApiToolManageService:
|
class TestApiToolManageService:
|
||||||
"""Integration tests for ApiToolManageService using testcontainers."""
|
"""Integration tests for ApiToolManageService using testcontainers."""
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_external_service_dependencies(self):
|
def mock_external_service_dependencies(self) -> Iterator[MockDependencies]:
|
||||||
"""Mock setup for external service dependencies."""
|
"""Mock setup for external service dependencies."""
|
||||||
with (
|
with (
|
||||||
patch("services.tools.api_tools_manage_service.ToolLabelManager") as mock_tool_label_manager,
|
patch("services.tools.api_tools_manage_service.ToolLabelManager") as mock_tool_label_manager,
|
||||||
@ -39,7 +42,9 @@ class TestApiToolManageService:
|
|||||||
"provider_controller": mock_provider_controller,
|
"provider_controller": mock_provider_controller,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _create_test_account_and_tenant(self, db_session_with_containers: Session, mock_external_service_dependencies):
|
def _create_test_account_and_tenant(
|
||||||
|
self, db_session_with_containers: Session, mock_external_service_dependencies: MockDependencies
|
||||||
|
) -> tuple[Account, Tenant]:
|
||||||
"""
|
"""
|
||||||
Helper method to create a test account and tenant for testing.
|
Helper method to create a test account and tenant for testing.
|
||||||
|
|
||||||
@ -57,7 +62,7 @@ class TestApiToolManageService:
|
|||||||
email=fake.email(),
|
email=fake.email(),
|
||||||
name=fake.name(),
|
name=fake.name(),
|
||||||
interface_language="en-US",
|
interface_language="en-US",
|
||||||
status="active",
|
status=AccountStatus.ACTIVE,
|
||||||
)
|
)
|
||||||
|
|
||||||
db_session_with_containers.add(account)
|
db_session_with_containers.add(account)
|
||||||
@ -66,7 +71,7 @@ class TestApiToolManageService:
|
|||||||
# Create tenant for the account
|
# Create tenant for the account
|
||||||
tenant = Tenant(
|
tenant = Tenant(
|
||||||
name=fake.company(),
|
name=fake.company(),
|
||||||
status="normal",
|
status=TenantStatus.NORMAL,
|
||||||
)
|
)
|
||||||
db_session_with_containers.add(tenant)
|
db_session_with_containers.add(tenant)
|
||||||
db_session_with_containers.commit()
|
db_session_with_containers.commit()
|
||||||
@ -88,7 +93,7 @@ class TestApiToolManageService:
|
|||||||
|
|
||||||
return account, tenant
|
return account, tenant
|
||||||
|
|
||||||
def _create_test_openapi_schema(self):
|
def _create_test_openapi_schema(self) -> str:
|
||||||
"""Helper method to create a test OpenAPI schema."""
|
"""Helper method to create a test OpenAPI schema."""
|
||||||
return """
|
return """
|
||||||
{
|
{
|
||||||
@ -121,8 +126,11 @@ class TestApiToolManageService:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def test_parser_api_schema_success(
|
def test_parser_api_schema_success(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Test successful parsing of API schema.
|
Test successful parsing of API schema.
|
||||||
|
|
||||||
@ -148,6 +156,8 @@ class TestApiToolManageService:
|
|||||||
# Verify credentials schema structure
|
# Verify credentials schema structure
|
||||||
credentials_schema = result["credentials_schema"]
|
credentials_schema = result["credentials_schema"]
|
||||||
assert len(credentials_schema) == 3
|
assert len(credentials_schema) == 3
|
||||||
|
assert all(isinstance(field, dict) for field in credentials_schema)
|
||||||
|
assert all(isinstance(tool, dict) for tool in result["parameters_schema"])
|
||||||
|
|
||||||
# Check auth_type field
|
# Check auth_type field
|
||||||
auth_type_field = next(field for field in credentials_schema if field["name"] == "auth_type")
|
auth_type_field = next(field for field in credentials_schema if field["name"] == "auth_type")
|
||||||
@ -166,8 +176,11 @@ class TestApiToolManageService:
|
|||||||
assert api_key_value_field["default"] == ""
|
assert api_key_value_field["default"] == ""
|
||||||
|
|
||||||
def test_parser_api_schema_invalid_schema(
|
def test_parser_api_schema_invalid_schema(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Test parsing of invalid API schema.
|
Test parsing of invalid API schema.
|
||||||
|
|
||||||
@ -186,8 +199,11 @@ class TestApiToolManageService:
|
|||||||
assert "invalid schema" in str(exc_info.value)
|
assert "invalid schema" in str(exc_info.value)
|
||||||
|
|
||||||
def test_parser_api_schema_malformed_json(
|
def test_parser_api_schema_malformed_json(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Test parsing of malformed JSON schema.
|
Test parsing of malformed JSON schema.
|
||||||
|
|
||||||
@ -206,8 +222,11 @@ class TestApiToolManageService:
|
|||||||
assert "invalid schema" in str(exc_info.value)
|
assert "invalid schema" in str(exc_info.value)
|
||||||
|
|
||||||
def test_convert_schema_to_tool_bundles_success(
|
def test_convert_schema_to_tool_bundles_success(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Test successful conversion of schema to tool bundles.
|
Test successful conversion of schema to tool bundles.
|
||||||
|
|
||||||
@ -236,8 +255,11 @@ class TestApiToolManageService:
|
|||||||
assert tool_bundle.operation_id == "testOperation"
|
assert tool_bundle.operation_id == "testOperation"
|
||||||
|
|
||||||
def test_convert_schema_to_tool_bundles_with_extra_info(
|
def test_convert_schema_to_tool_bundles_with_extra_info(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Test successful conversion of schema to tool bundles with extra info.
|
Test successful conversion of schema to tool bundles with extra info.
|
||||||
|
|
||||||
@ -262,8 +284,11 @@ class TestApiToolManageService:
|
|||||||
assert isinstance(schema_type, str)
|
assert isinstance(schema_type, str)
|
||||||
|
|
||||||
def test_convert_schema_to_tool_bundles_invalid_schema(
|
def test_convert_schema_to_tool_bundles_invalid_schema(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Test conversion of invalid schema to tool bundles.
|
Test conversion of invalid schema to tool bundles.
|
||||||
|
|
||||||
@ -282,8 +307,11 @@ class TestApiToolManageService:
|
|||||||
assert "invalid schema" in str(exc_info.value)
|
assert "invalid schema" in str(exc_info.value)
|
||||||
|
|
||||||
def test_create_api_tool_provider_success(
|
def test_create_api_tool_provider_success(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Test successful creation of API tool provider.
|
Test successful creation of API tool provider.
|
||||||
|
|
||||||
@ -301,7 +329,7 @@ class TestApiToolManageService:
|
|||||||
)
|
)
|
||||||
|
|
||||||
provider_name = fake.company()
|
provider_name = fake.company()
|
||||||
icon = {"type": "emoji", "value": "🔧"}
|
icon = {"content": "🔧", "background": "#FFF"}
|
||||||
credentials = {"auth_type": "none", "api_key_header": "X-API-Key", "api_key_value": ""}
|
credentials = {"auth_type": "none", "api_key_header": "X-API-Key", "api_key_value": ""}
|
||||||
schema_type = ApiProviderSchemaType.OPENAPI
|
schema_type = ApiProviderSchemaType.OPENAPI
|
||||||
schema = self._create_test_openapi_schema()
|
schema = self._create_test_openapi_schema()
|
||||||
@ -341,6 +369,7 @@ class TestApiToolManageService:
|
|||||||
assert provider.schema_type_str == schema_type
|
assert provider.schema_type_str == schema_type
|
||||||
assert provider.privacy_policy == privacy_policy
|
assert provider.privacy_policy == privacy_policy
|
||||||
assert provider.custom_disclaimer == custom_disclaimer
|
assert provider.custom_disclaimer == custom_disclaimer
|
||||||
|
assert json.loads(provider.icon) == icon
|
||||||
|
|
||||||
# Verify mock interactions
|
# Verify mock interactions
|
||||||
mock_external_service_dependencies["tool_label_manager"].update_tool_labels.assert_called_once()
|
mock_external_service_dependencies["tool_label_manager"].update_tool_labels.assert_called_once()
|
||||||
@ -349,8 +378,11 @@ class TestApiToolManageService:
|
|||||||
mock_external_service_dependencies["provider_controller"].load_bundled_tools.assert_called_once()
|
mock_external_service_dependencies["provider_controller"].load_bundled_tools.assert_called_once()
|
||||||
|
|
||||||
def test_create_api_tool_provider_duplicate_name(
|
def test_create_api_tool_provider_duplicate_name(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Test creation of API tool provider with duplicate name.
|
Test creation of API tool provider with duplicate name.
|
||||||
|
|
||||||
@ -366,7 +398,7 @@ class TestApiToolManageService:
|
|||||||
)
|
)
|
||||||
|
|
||||||
provider_name = fake.company()
|
provider_name = fake.company()
|
||||||
icon = {"type": "emoji", "value": "🔧"}
|
icon = {"content": "🔧", "background": "#FFF"}
|
||||||
credentials = {"auth_type": "none"}
|
credentials = {"auth_type": "none"}
|
||||||
schema_type = ApiProviderSchemaType.OPENAPI
|
schema_type = ApiProviderSchemaType.OPENAPI
|
||||||
schema = self._create_test_openapi_schema()
|
schema = self._create_test_openapi_schema()
|
||||||
@ -406,8 +438,11 @@ class TestApiToolManageService:
|
|||||||
assert f"provider {provider_name} already exists" in str(exc_info.value)
|
assert f"provider {provider_name} already exists" in str(exc_info.value)
|
||||||
|
|
||||||
def test_create_api_tool_provider_invalid_schema_type(
|
def test_create_api_tool_provider_invalid_schema_type(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Test creation of API tool provider with invalid schema type.
|
Test creation of API tool provider with invalid schema type.
|
||||||
|
|
||||||
@ -423,7 +458,7 @@ class TestApiToolManageService:
|
|||||||
)
|
)
|
||||||
|
|
||||||
provider_name = fake.company()
|
provider_name = fake.company()
|
||||||
icon = {"type": "emoji", "value": "🔧"}
|
icon = {"content": "🔧", "background": "#FFF"}
|
||||||
credentials = {"auth_type": "none"}
|
credentials = {"auth_type": "none"}
|
||||||
schema_type = "invalid_type"
|
schema_type = "invalid_type"
|
||||||
schema = self._create_test_openapi_schema()
|
schema = self._create_test_openapi_schema()
|
||||||
@ -438,8 +473,11 @@ class TestApiToolManageService:
|
|||||||
assert "validation error" in str(exc_info.value)
|
assert "validation error" in str(exc_info.value)
|
||||||
|
|
||||||
def test_create_api_tool_provider_missing_auth_type(
|
def test_create_api_tool_provider_missing_auth_type(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Test creation of API tool provider with missing auth type.
|
Test creation of API tool provider with missing auth type.
|
||||||
|
|
||||||
@ -455,7 +493,7 @@ class TestApiToolManageService:
|
|||||||
)
|
)
|
||||||
|
|
||||||
provider_name = fake.company()
|
provider_name = fake.company()
|
||||||
icon = {"type": "emoji", "value": "🔧"}
|
icon = {"content": "🔧", "background": "#FFF"}
|
||||||
credentials = {} # Missing auth_type
|
credentials = {} # Missing auth_type
|
||||||
schema_type = ApiProviderSchemaType.OPENAPI
|
schema_type = ApiProviderSchemaType.OPENAPI
|
||||||
schema = self._create_test_openapi_schema()
|
schema = self._create_test_openapi_schema()
|
||||||
@ -481,8 +519,11 @@ class TestApiToolManageService:
|
|||||||
assert "auth_type is required" in str(exc_info.value)
|
assert "auth_type is required" in str(exc_info.value)
|
||||||
|
|
||||||
def test_create_api_tool_provider_with_api_key_auth(
|
def test_create_api_tool_provider_with_api_key_auth(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Test successful creation of API tool provider with API key authentication.
|
Test successful creation of API tool provider with API key authentication.
|
||||||
|
|
||||||
@ -498,7 +539,7 @@ class TestApiToolManageService:
|
|||||||
)
|
)
|
||||||
|
|
||||||
provider_name = fake.company()
|
provider_name = fake.company()
|
||||||
icon = {"type": "emoji", "value": "🔑"}
|
icon = {"content": "🔑", "background": "#FFF"}
|
||||||
credentials = {"auth_type": "api_key", "api_key_header": "X-API-Key", "api_key_value": fake.uuid4()}
|
credentials = {"auth_type": "api_key", "api_key_header": "X-API-Key", "api_key_value": fake.uuid4()}
|
||||||
schema_type = ApiProviderSchemaType.OPENAPI
|
schema_type = ApiProviderSchemaType.OPENAPI
|
||||||
schema = self._create_test_openapi_schema()
|
schema = self._create_test_openapi_schema()
|
||||||
@ -542,8 +583,11 @@ class TestApiToolManageService:
|
|||||||
mock_external_service_dependencies["provider_controller"].from_db.assert_called_once()
|
mock_external_service_dependencies["provider_controller"].from_db.assert_called_once()
|
||||||
|
|
||||||
def test_delete_api_tool_provider_success(
|
def test_delete_api_tool_provider_success(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""Test successful deletion of an API tool provider."""
|
"""Test successful deletion of an API tool provider."""
|
||||||
fake = Faker()
|
fake = Faker()
|
||||||
account, tenant = self._create_test_account_and_tenant(
|
account, tenant = self._create_test_account_and_tenant(
|
||||||
@ -583,8 +627,8 @@ class TestApiToolManageService:
|
|||||||
assert deleted is None
|
assert deleted is None
|
||||||
|
|
||||||
def test_delete_api_tool_provider_not_found(
|
def test_delete_api_tool_provider_not_found(
|
||||||
self, db_session_with_containers: Session, mock_external_service_dependencies
|
self, db_session_with_containers: Session, mock_external_service_dependencies: MockDependencies
|
||||||
):
|
) -> None:
|
||||||
"""Test deletion raises ValueError when provider not found."""
|
"""Test deletion raises ValueError when provider not found."""
|
||||||
fake = Faker()
|
fake = Faker()
|
||||||
account, tenant = self._create_test_account_and_tenant(
|
account, tenant = self._create_test_account_and_tenant(
|
||||||
@ -595,14 +639,15 @@ class TestApiToolManageService:
|
|||||||
ApiToolManageService.delete_api_tool_provider(account.id, tenant.id, "nonexistent")
|
ApiToolManageService.delete_api_tool_provider(account.id, tenant.id, "nonexistent")
|
||||||
|
|
||||||
def test_update_api_tool_provider_success(
|
def test_update_api_tool_provider_success(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
fake = Faker()
|
fake = Faker()
|
||||||
|
|
||||||
# Firmware fix for cache.delete() in update flow
|
# Firmware fix for cache.delete() in update flow
|
||||||
mock_encrypter = mock_external_service_dependencies["encrypter"]
|
mock_encrypter = mock_external_service_dependencies["encrypter"]
|
||||||
from unittest.mock import MagicMock
|
|
||||||
|
|
||||||
mock_cache = MagicMock()
|
mock_cache = MagicMock()
|
||||||
mock_cache.delete.return_value = None
|
mock_cache.delete.return_value = None
|
||||||
mock_encrypter.return_value = (mock_encrypter, mock_cache)
|
mock_encrypter.return_value = (mock_encrypter, mock_cache)
|
||||||
@ -620,7 +665,7 @@ class TestApiToolManageService:
|
|||||||
user_id=account.id,
|
user_id=account.id,
|
||||||
tenant_id=tenant.id,
|
tenant_id=tenant.id,
|
||||||
provider_name=original_name,
|
provider_name=original_name,
|
||||||
icon={"type": "emoji", "value": "🔧"},
|
icon={"content": "🔧", "background": "#FFF"},
|
||||||
credentials={"auth_type": "none"},
|
credentials={"auth_type": "none"},
|
||||||
schema_type=ApiProviderSchemaType.OPENAPI,
|
schema_type=ApiProviderSchemaType.OPENAPI,
|
||||||
schema=self._create_test_openapi_schema(),
|
schema=self._create_test_openapi_schema(),
|
||||||
@ -646,7 +691,7 @@ class TestApiToolManageService:
|
|||||||
provider_name=new_name,
|
provider_name=new_name,
|
||||||
original_provider=original_name,
|
original_provider=original_name,
|
||||||
# new icon - changed 2
|
# new icon - changed 2
|
||||||
icon={"type": "emoji", "value": "🚀"},
|
icon={"content": "🚀", "background": "#FFF"},
|
||||||
credentials={"auth_type": "none"},
|
credentials={"auth_type": "none"},
|
||||||
_schema_type=ApiProviderSchemaType.OPENAPI,
|
_schema_type=ApiProviderSchemaType.OPENAPI,
|
||||||
schema=self._create_test_openapi_schema(),
|
schema=self._create_test_openapi_schema(),
|
||||||
@ -677,9 +722,7 @@ class TestApiToolManageService:
|
|||||||
# - changed 1
|
# - changed 1
|
||||||
assert updated_provider.name == new_name
|
assert updated_provider.name == new_name
|
||||||
# - changed 2
|
# - changed 2
|
||||||
icon_data = json.loads(updated_provider.icon)
|
assert json.loads(updated_provider.icon) == {"content": "🚀", "background": "#FFF"}
|
||||||
assert icon_data["type"] == "emoji"
|
|
||||||
assert icon_data["value"] == "🚀"
|
|
||||||
# - changed 3
|
# - changed 3
|
||||||
assert updated_provider.privacy_policy == "https://new-policy.com"
|
assert updated_provider.privacy_policy == "https://new-policy.com"
|
||||||
# - changed 4
|
# - changed 4
|
||||||
@ -712,8 +755,11 @@ class TestApiToolManageService:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_update_api_tool_provider_not_found(
|
def test_update_api_tool_provider_not_found(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Test update raises ValueError when original provider not found.
|
Test update raises ValueError when original provider not found.
|
||||||
|
|
||||||
@ -733,7 +779,7 @@ class TestApiToolManageService:
|
|||||||
user_id=account.id,
|
user_id=account.id,
|
||||||
tenant_id=tenant.id,
|
tenant_id=tenant.id,
|
||||||
provider_name=existing_provider_name,
|
provider_name=existing_provider_name,
|
||||||
icon={"type": "emoji", "value": "🔧"},
|
icon={"content": "🔧", "background": "#FFF"},
|
||||||
credentials={"auth_type": "none"},
|
credentials={"auth_type": "none"},
|
||||||
schema_type=ApiProviderSchemaType.OPENAPI,
|
schema_type=ApiProviderSchemaType.OPENAPI,
|
||||||
schema=self._create_test_openapi_schema(),
|
schema=self._create_test_openapi_schema(),
|
||||||
@ -756,7 +802,7 @@ class TestApiToolManageService:
|
|||||||
tenant_id=tenant.id,
|
tenant_id=tenant.id,
|
||||||
provider_name=target_new_name,
|
provider_name=target_new_name,
|
||||||
original_provider=missing_original_name,
|
original_provider=missing_original_name,
|
||||||
icon={"type": "emoji", "value": "🚀"},
|
icon={"content": "🚀", "background": "#FFF"},
|
||||||
credentials={"auth_type": "none"},
|
credentials={"auth_type": "none"},
|
||||||
_schema_type=ApiProviderSchemaType.OPENAPI,
|
_schema_type=ApiProviderSchemaType.OPENAPI,
|
||||||
schema=self._create_test_openapi_schema(),
|
schema=self._create_test_openapi_schema(),
|
||||||
@ -793,8 +839,11 @@ class TestApiToolManageService:
|
|||||||
mock_external_service_dependencies["provider_controller"].from_db.assert_not_called()
|
mock_external_service_dependencies["provider_controller"].from_db.assert_not_called()
|
||||||
|
|
||||||
def test_update_api_tool_provider_missing_auth_type(
|
def test_update_api_tool_provider_missing_auth_type(
|
||||||
self, flask_req_ctx_with_containers, db_session_with_containers: Session, mock_external_service_dependencies
|
self,
|
||||||
):
|
flask_req_ctx_with_containers: object,
|
||||||
|
db_session_with_containers: Session,
|
||||||
|
mock_external_service_dependencies: MockDependencies,
|
||||||
|
) -> None:
|
||||||
"""Test update raises ValueError when auth_type is missing from credentials."""
|
"""Test update raises ValueError when auth_type is missing from credentials."""
|
||||||
fake = Faker()
|
fake = Faker()
|
||||||
account, tenant = self._create_test_account_and_tenant(
|
account, tenant = self._create_test_account_and_tenant(
|
||||||
@ -822,7 +871,7 @@ class TestApiToolManageService:
|
|||||||
tenant_id=tenant.id,
|
tenant_id=tenant.id,
|
||||||
provider_name=provider_name,
|
provider_name=provider_name,
|
||||||
original_provider=provider_name,
|
original_provider=provider_name,
|
||||||
icon={},
|
icon={"content": "🔧", "background": "#FFF"},
|
||||||
credentials={},
|
credentials={},
|
||||||
_schema_type=ApiProviderSchemaType.OPENAPI,
|
_schema_type=ApiProviderSchemaType.OPENAPI,
|
||||||
schema=schema,
|
schema=schema,
|
||||||
@ -832,8 +881,8 @@ class TestApiToolManageService:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_list_api_tool_provider_tools_not_found(
|
def test_list_api_tool_provider_tools_not_found(
|
||||||
self, db_session_with_containers: Session, mock_external_service_dependencies
|
self, db_session_with_containers: Session, mock_external_service_dependencies: MockDependencies
|
||||||
):
|
) -> None:
|
||||||
"""Test listing tools raises ValueError when provider not found."""
|
"""Test listing tools raises ValueError when provider not found."""
|
||||||
fake = Faker()
|
fake = Faker()
|
||||||
account, tenant = self._create_test_account_and_tenant(
|
account, tenant = self._create_test_account_and_tenant(
|
||||||
@ -844,8 +893,8 @@ class TestApiToolManageService:
|
|||||||
ApiToolManageService.list_api_tool_provider_tools(account.id, tenant.id, "nonexistent")
|
ApiToolManageService.list_api_tool_provider_tools(account.id, tenant.id, "nonexistent")
|
||||||
|
|
||||||
def test_test_api_tool_preview_invalid_schema_type(
|
def test_test_api_tool_preview_invalid_schema_type(
|
||||||
self, db_session_with_containers: Session, mock_external_service_dependencies
|
self, db_session_with_containers: Session, mock_external_service_dependencies: MockDependencies
|
||||||
):
|
) -> None:
|
||||||
"""Test preview raises ValueError for invalid schema type."""
|
"""Test preview raises ValueError for invalid schema type."""
|
||||||
fake = Faker()
|
fake = Faker()
|
||||||
account, tenant = self._create_test_account_and_tenant(
|
account, tenant = self._create_test_account_and_tenant(
|
||||||
|
|||||||
@ -13,6 +13,9 @@ import pytest
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask.views import MethodView
|
from flask.views import MethodView
|
||||||
|
|
||||||
|
from core.tools.entities.api_entities import ToolProviderApiEntity as CoreToolProviderApiEntity
|
||||||
|
from core.tools.entities.common_entities import I18nObject
|
||||||
|
from core.tools.entities.tool_entities import ToolParameter
|
||||||
from models import Account
|
from models import Account
|
||||||
from models.account import TenantAccountRole
|
from models.account import TenantAccountRole
|
||||||
|
|
||||||
@ -21,6 +24,7 @@ if not hasattr(builtins, "MethodView"):
|
|||||||
|
|
||||||
|
|
||||||
_CONTROLLER_MODULE: ModuleType | None = None
|
_CONTROLLER_MODULE: ModuleType | None = None
|
||||||
|
_WRAPS_MODULE: ModuleType | None = None
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
@ -69,10 +73,11 @@ def controller_module(monkeypatch: pytest.MonkeyPatch):
|
|||||||
_CONTROLLER_MODULE = importlib.import_module(module_name)
|
_CONTROLLER_MODULE = importlib.import_module(module_name)
|
||||||
|
|
||||||
module = _CONTROLLER_MODULE
|
module = _CONTROLLER_MODULE
|
||||||
monkeypatch.setattr(module, "jsonable_encoder", lambda payload: payload)
|
|
||||||
|
|
||||||
# Ensure decorators that consult deployment edition do not reach the database.
|
# Ensure decorators that consult deployment edition do not reach the database.
|
||||||
|
global _WRAPS_MODULE
|
||||||
wraps_module = importlib.import_module("controllers.console.wraps")
|
wraps_module = importlib.import_module("controllers.console.wraps")
|
||||||
|
_WRAPS_MODULE = wraps_module
|
||||||
monkeypatch.setattr(module.dify_config, "EDITION", "CLOUD")
|
monkeypatch.setattr(module.dify_config, "EDITION", "CLOUD")
|
||||||
monkeypatch.setattr(wraps_module.dify_config, "EDITION", "CLOUD")
|
monkeypatch.setattr(wraps_module.dify_config, "EDITION", "CLOUD")
|
||||||
|
|
||||||
@ -88,19 +93,194 @@ def _mock_account(user_id: str = "user-123") -> Account:
|
|||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
def _set_current_account(
|
||||||
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
|
controller_module: ModuleType,
|
||||||
|
user: Account,
|
||||||
|
tenant_id: str,
|
||||||
|
) -> None:
|
||||||
|
def _getter():
|
||||||
|
return user, tenant_id
|
||||||
|
|
||||||
|
monkeypatch.setattr(controller_module, "current_account_with_tenant", _getter, raising=False)
|
||||||
|
if _WRAPS_MODULE is not None:
|
||||||
|
monkeypatch.setattr(_WRAPS_MODULE, "current_account_with_tenant", _getter)
|
||||||
|
|
||||||
|
login_module = importlib.import_module("libs.login")
|
||||||
|
monkeypatch.setattr(login_module, "_get_user", lambda: user)
|
||||||
|
|
||||||
|
|
||||||
|
def _i18n(text: str) -> dict[str, str]:
|
||||||
|
return {"en_US": text, "zh_Hans": text, "pt_BR": text, "ja_JP": text}
|
||||||
|
|
||||||
|
|
||||||
|
def _tool_response(controller_module: ModuleType, name: str = "tool-a") -> tuple[dict, dict]:
|
||||||
|
expected = {
|
||||||
|
"author": "Dify",
|
||||||
|
"name": name,
|
||||||
|
"label": _i18n(name),
|
||||||
|
"description": _i18n(f"{name} description"),
|
||||||
|
"parameters": [],
|
||||||
|
"labels": [],
|
||||||
|
"output_schema": {},
|
||||||
|
}
|
||||||
|
tool = controller_module.ToolApiEntity.model_validate(expected)
|
||||||
|
return tool.model_dump(mode="json"), expected
|
||||||
|
|
||||||
|
|
||||||
|
def _provider_entity_response(
|
||||||
|
controller_module: ModuleType, name: str = "provider", provider_type: str = "builtin"
|
||||||
|
) -> tuple[CoreToolProviderApiEntity, dict]:
|
||||||
|
service_payload = {
|
||||||
|
"id": f"{name}-id",
|
||||||
|
"author": "Dify",
|
||||||
|
"name": name,
|
||||||
|
"description": _i18n(f"{name} description"),
|
||||||
|
"icon": "tool.svg",
|
||||||
|
"icon_dark": "",
|
||||||
|
"label": _i18n(name),
|
||||||
|
"type": provider_type,
|
||||||
|
"masked_credentials": {"api_key": "[__HIDDEN__]"},
|
||||||
|
"original_credentials": {"api_key": "sk-secret"},
|
||||||
|
"is_team_authorization": False,
|
||||||
|
"allow_delete": True,
|
||||||
|
"plugin_id": "",
|
||||||
|
"plugin_unique_identifier": "",
|
||||||
|
"tools": [],
|
||||||
|
"labels": [],
|
||||||
|
"server_url": "",
|
||||||
|
"updated_at": 1,
|
||||||
|
"server_identifier": "",
|
||||||
|
"masked_headers": None,
|
||||||
|
"original_headers": None,
|
||||||
|
"authentication": None,
|
||||||
|
"is_dynamic_registration": True,
|
||||||
|
"configuration": None,
|
||||||
|
"identity_mode": "off",
|
||||||
|
"workflow_app_id": None,
|
||||||
|
}
|
||||||
|
provider = CoreToolProviderApiEntity.model_validate(service_payload)
|
||||||
|
return provider, provider.to_dict()
|
||||||
|
|
||||||
|
|
||||||
|
def _provider_list_item(
|
||||||
|
controller_module: ModuleType, name: str = "provider", provider_type: str = "builtin"
|
||||||
|
) -> tuple[dict, dict]:
|
||||||
|
service_payload = {
|
||||||
|
"id": f"{name}-id",
|
||||||
|
"author": "Dify",
|
||||||
|
"name": name,
|
||||||
|
"description": _i18n(f"{name} description"),
|
||||||
|
"icon": "tool.svg",
|
||||||
|
"icon_dark": "",
|
||||||
|
"label": _i18n(name),
|
||||||
|
"type": provider_type,
|
||||||
|
"team_credentials": {"api_key": "[__HIDDEN__]"},
|
||||||
|
"is_team_authorization": False,
|
||||||
|
"allow_delete": True,
|
||||||
|
"plugin_id": "",
|
||||||
|
"plugin_unique_identifier": "",
|
||||||
|
"tools": [],
|
||||||
|
"labels": [],
|
||||||
|
}
|
||||||
|
expected = {
|
||||||
|
**service_payload,
|
||||||
|
}
|
||||||
|
provider = controller_module.ToolProviderApiEntityResponse.model_validate(expected)
|
||||||
|
return service_payload, provider.model_dump(mode="json", exclude_unset=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _credential_response(controller_module: ModuleType, credential_id: str = "cred-1") -> tuple[dict, dict]:
|
||||||
|
expected = {
|
||||||
|
"id": credential_id,
|
||||||
|
"name": "Credential",
|
||||||
|
"provider": "demo",
|
||||||
|
"credential_type": controller_module.CredentialType.API_KEY,
|
||||||
|
"is_default": False,
|
||||||
|
"credentials": {},
|
||||||
|
"visibility": "all_team_members",
|
||||||
|
"created_by": "",
|
||||||
|
"partial_member_list": [],
|
||||||
|
"from_other_member": False,
|
||||||
|
}
|
||||||
|
credential = controller_module.ToolProviderCredentialApiEntity.model_validate(expected)
|
||||||
|
return credential.model_dump(mode="json"), credential.model_dump(mode="json")
|
||||||
|
|
||||||
|
|
||||||
|
def _provider_config_response(controller_module: ModuleType) -> tuple[dict, dict]:
|
||||||
|
expected = {
|
||||||
|
"type": "secret-input",
|
||||||
|
"name": "api_key",
|
||||||
|
"scope": None,
|
||||||
|
"required": False,
|
||||||
|
"default": None,
|
||||||
|
"options": None,
|
||||||
|
"multiple": False,
|
||||||
|
"label": None,
|
||||||
|
"help": None,
|
||||||
|
"url": None,
|
||||||
|
"placeholder": None,
|
||||||
|
}
|
||||||
|
config = controller_module.ProviderConfig.model_validate(expected)
|
||||||
|
return config.model_dump(mode="json"), expected
|
||||||
|
|
||||||
|
|
||||||
|
def _api_provider_detail_response(controller_module: ModuleType) -> tuple[dict, dict]:
|
||||||
|
expected = {
|
||||||
|
"schema_type": "openapi",
|
||||||
|
"schema": "{}",
|
||||||
|
"tools": [],
|
||||||
|
"icon": {"background": "#252525", "content": "tool"},
|
||||||
|
"description": "provider description",
|
||||||
|
"credentials": {"auth_type": "none"},
|
||||||
|
"privacy_policy": "",
|
||||||
|
"custom_disclaimer": "",
|
||||||
|
"labels": [],
|
||||||
|
}
|
||||||
|
detail = controller_module.ApiProviderDetailResponse.model_validate(expected)
|
||||||
|
return detail.model_dump(mode="json", by_alias=True), expected
|
||||||
|
|
||||||
|
|
||||||
|
def _workflow_detail_response(controller_module: ModuleType) -> tuple[dict, dict]:
|
||||||
|
tool_payload, tool_expected = _tool_response(controller_module, "workflow-tool")
|
||||||
|
expected = {
|
||||||
|
"name": "workflow-tool",
|
||||||
|
"label": "Workflow Tool",
|
||||||
|
"workflow_tool_id": "00000000-0000-0000-0000-000000000001",
|
||||||
|
"workflow_app_id": "00000000-0000-0000-0000-000000000002",
|
||||||
|
"icon": {"background": "#252525", "content": "tool"},
|
||||||
|
"description": "description",
|
||||||
|
"parameters": [],
|
||||||
|
"output_schema": {},
|
||||||
|
"tool": tool_expected,
|
||||||
|
"synced": True,
|
||||||
|
"privacy_policy": "",
|
||||||
|
}
|
||||||
|
service_payload = {**expected, "tool": tool_payload}
|
||||||
|
detail = controller_module.WorkflowToolDetailResponse.model_validate(service_payload)
|
||||||
|
return detail.model_dump(mode="json"), expected
|
||||||
|
|
||||||
|
|
||||||
|
def _tool_label_response(controller_module: ModuleType, name: str = "search") -> tuple[dict, dict]:
|
||||||
|
expected = {"name": name, "label": _i18n(name), "icon": "search"}
|
||||||
|
label = controller_module.ToolLabel.model_validate(expected)
|
||||||
|
return label.model_dump(mode="json"), expected
|
||||||
|
|
||||||
|
|
||||||
def test_tool_provider_list_calls_service_with_query(
|
def test_tool_provider_list_calls_service_with_query(
|
||||||
app: Flask, controller_module: ModuleType, monkeypatch: pytest.MonkeyPatch
|
app: Flask, controller_module: ModuleType, monkeypatch: pytest.MonkeyPatch
|
||||||
):
|
):
|
||||||
user = _mock_account()
|
user = _mock_account()
|
||||||
|
_set_current_account(monkeypatch, controller_module, user, "tenant-456")
|
||||||
|
|
||||||
service_mock = MagicMock(return_value=[{"provider": "builtin"}])
|
service_payload, expected_response = _provider_list_item(controller_module, "builtin", "builtin")
|
||||||
|
service_mock = MagicMock(return_value=[service_payload])
|
||||||
monkeypatch.setattr(controller_module.ToolCommonService, "list_tool_providers", service_mock)
|
monkeypatch.setattr(controller_module.ToolCommonService, "list_tool_providers", service_mock)
|
||||||
|
|
||||||
with app.test_request_context("/workspaces/current/tool-providers?type=builtin"):
|
with app.test_request_context("/workspaces/current/tool-providers?type=builtin"):
|
||||||
api = controller_module.ToolProviderListApi()
|
response = controller_module.ToolProviderListApi().get()
|
||||||
response = unwrap(api.get)(api, "tenant-456", user)
|
|
||||||
|
|
||||||
assert response == [{"provider": "builtin"}]
|
assert response == [expected_response]
|
||||||
service_mock.assert_called_once_with(user.id, "tenant-456", "builtin")
|
service_mock.assert_called_once_with(user.id, "tenant-456", "builtin")
|
||||||
|
|
||||||
|
|
||||||
@ -108,8 +288,9 @@ def test_builtin_provider_add_passes_payload(
|
|||||||
app: Flask, controller_module: ModuleType, monkeypatch: pytest.MonkeyPatch
|
app: Flask, controller_module: ModuleType, monkeypatch: pytest.MonkeyPatch
|
||||||
):
|
):
|
||||||
user = _mock_account()
|
user = _mock_account()
|
||||||
|
_set_current_account(monkeypatch, controller_module, user, "tenant-456")
|
||||||
|
|
||||||
service_mock = MagicMock(return_value={"status": "ok"})
|
service_mock = MagicMock(return_value={"result": "success"})
|
||||||
monkeypatch.setattr(controller_module.BuiltinToolManageService, "add_builtin_tool_provider", service_mock)
|
monkeypatch.setattr(controller_module.BuiltinToolManageService, "add_builtin_tool_provider", service_mock)
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
@ -123,10 +304,9 @@ def test_builtin_provider_add_passes_payload(
|
|||||||
method="POST",
|
method="POST",
|
||||||
json=payload,
|
json=payload,
|
||||||
):
|
):
|
||||||
api = controller_module.ToolBuiltinProviderAddApi()
|
response = controller_module.ToolBuiltinProviderAddApi().post(provider="openai")
|
||||||
response = unwrap(api.post)(api, "tenant-456", user, provider="openai")
|
|
||||||
|
|
||||||
assert response == {"status": "ok"}
|
assert response == {"result": "success"}
|
||||||
service_mock.assert_called_once_with(
|
service_mock.assert_called_once_with(
|
||||||
user_id="user-123",
|
user_id="user-123",
|
||||||
tenant_id="tenant-456",
|
tenant_id="tenant-456",
|
||||||
@ -140,38 +320,88 @@ def test_builtin_provider_add_passes_payload(
|
|||||||
|
|
||||||
def test_builtin_provider_tools_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_builtin_provider_tools_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account("user-tenant-789")
|
user = _mock_account("user-tenant-789")
|
||||||
|
_set_current_account(monkeypatch, controller_module, user, "tenant-789")
|
||||||
|
|
||||||
service_mock = MagicMock(return_value=[{"name": "tool-a"}])
|
service_payload, expected_response = _tool_response(controller_module, "tool-a")
|
||||||
|
service_mock = MagicMock(return_value=[service_payload])
|
||||||
monkeypatch.setattr(controller_module.BuiltinToolManageService, "list_builtin_tool_provider_tools", service_mock)
|
monkeypatch.setattr(controller_module.BuiltinToolManageService, "list_builtin_tool_provider_tools", service_mock)
|
||||||
monkeypatch.setattr(controller_module, "jsonable_encoder", lambda payload: payload)
|
|
||||||
|
|
||||||
with app.test_request_context(
|
with app.test_request_context(
|
||||||
"/workspaces/current/tool-provider/builtin/my-provider/tools",
|
"/workspaces/current/tool-provider/builtin/my-provider/tools",
|
||||||
method="GET",
|
method="GET",
|
||||||
):
|
):
|
||||||
api = controller_module.ToolBuiltinProviderListToolsApi()
|
response = controller_module.ToolBuiltinProviderListToolsApi().get(provider="my-provider")
|
||||||
response = unwrap(api.get)(api, "tenant-789", provider="my-provider")
|
|
||||||
|
|
||||||
assert response == [{"name": "tool-a"}]
|
assert response == [expected_response]
|
||||||
service_mock.assert_called_once_with("tenant-789", "my-provider")
|
service_mock.assert_called_once_with("tenant-789", "my-provider")
|
||||||
|
|
||||||
|
|
||||||
def test_builtin_provider_info_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_builtin_provider_info_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account("user-tenant-9")
|
user = _mock_account("user-tenant-9")
|
||||||
service_mock = MagicMock(return_value={"info": True})
|
_set_current_account(monkeypatch, controller_module, user, "tenant-9")
|
||||||
|
service_payload, expected_response = _provider_entity_response(controller_module, "demo", "builtin")
|
||||||
|
service_mock = MagicMock(return_value=service_payload)
|
||||||
monkeypatch.setattr(controller_module.BuiltinToolManageService, "get_builtin_tool_provider_info", service_mock)
|
monkeypatch.setattr(controller_module.BuiltinToolManageService, "get_builtin_tool_provider_info", service_mock)
|
||||||
|
|
||||||
with app.test_request_context("/info", method="GET"):
|
with app.test_request_context("/info", method="GET"):
|
||||||
api = controller_module.ToolBuiltinProviderInfoApi()
|
resp = controller_module.ToolBuiltinProviderInfoApi().get(provider="demo")
|
||||||
resp = unwrap(api.get)(api, "tenant-9", provider="demo")
|
|
||||||
|
|
||||||
assert resp == {"info": True}
|
assert resp == expected_response
|
||||||
service_mock.assert_called_once_with("tenant-9", "demo")
|
service_mock.assert_called_once_with("tenant-9", "demo")
|
||||||
|
|
||||||
|
|
||||||
|
def test_builtin_provider_info_uses_core_to_dict_tool_projection(
|
||||||
|
app: Flask, controller_module: ModuleType, monkeypatch: pytest.MonkeyPatch
|
||||||
|
):
|
||||||
|
user = _mock_account("user-tenant-9")
|
||||||
|
_set_current_account(monkeypatch, controller_module, user, "tenant-9")
|
||||||
|
tool_parameter = ToolParameter(
|
||||||
|
name="system_files",
|
||||||
|
label=I18nObject(en_US="System Files", zh_Hans="System Files"),
|
||||||
|
type=ToolParameter.ToolParameterType.SYSTEM_FILES,
|
||||||
|
form=ToolParameter.ToolParameterForm.LLM,
|
||||||
|
input_schema=None,
|
||||||
|
)
|
||||||
|
tool = controller_module.ToolApiEntity(
|
||||||
|
author="Dify",
|
||||||
|
name="demo-tool",
|
||||||
|
label=I18nObject(en_US="Demo Tool", zh_Hans="Demo Tool"),
|
||||||
|
description=I18nObject(en_US="Demo Tool description", zh_Hans="Demo Tool description"),
|
||||||
|
parameters=[tool_parameter],
|
||||||
|
labels=[],
|
||||||
|
output_schema={},
|
||||||
|
)
|
||||||
|
provider = CoreToolProviderApiEntity(
|
||||||
|
id="demo-id",
|
||||||
|
author="Dify",
|
||||||
|
name="demo",
|
||||||
|
description=I18nObject(en_US="demo description", zh_Hans="demo description"),
|
||||||
|
icon="tool.svg",
|
||||||
|
label=I18nObject(en_US="demo", zh_Hans="demo"),
|
||||||
|
type=controller_module.ToolProviderType.BUILT_IN,
|
||||||
|
masked_credentials={"api_key": "[__HIDDEN__]"},
|
||||||
|
original_credentials={"api_key": "sk-secret"},
|
||||||
|
tools=[tool],
|
||||||
|
)
|
||||||
|
service_mock = MagicMock(return_value=provider)
|
||||||
|
monkeypatch.setattr(controller_module.BuiltinToolManageService, "get_builtin_tool_provider_info", service_mock)
|
||||||
|
|
||||||
|
with app.test_request_context("/info", method="GET"):
|
||||||
|
resp = controller_module.ToolBuiltinProviderInfoApi().get(provider="demo")
|
||||||
|
|
||||||
|
parameter = resp["tools"][0]["parameters"][0]
|
||||||
|
assert parameter["type"] == "files"
|
||||||
|
assert parameter["input_schema"] is None
|
||||||
|
assert resp["team_credentials"] == {"api_key": "[__HIDDEN__]"}
|
||||||
|
assert "masked_credentials" not in resp
|
||||||
|
assert "original_credentials" not in resp
|
||||||
|
|
||||||
|
|
||||||
def test_builtin_provider_credentials_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_builtin_provider_credentials_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account("user-tenant-cred")
|
user = _mock_account("user-tenant-cred")
|
||||||
service_mock = MagicMock(return_value=[{"cred": 1}])
|
_set_current_account(monkeypatch, controller_module, user, "tenant-cred")
|
||||||
|
service_payload, expected_response = _credential_response(controller_module)
|
||||||
|
service_mock = MagicMock(return_value=[service_payload])
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
controller_module.BuiltinToolManageService,
|
controller_module.BuiltinToolManageService,
|
||||||
"get_builtin_tool_provider_credentials",
|
"get_builtin_tool_provider_credentials",
|
||||||
@ -179,10 +409,9 @@ def test_builtin_provider_credentials_get(app: Flask, controller_module, monkeyp
|
|||||||
)
|
)
|
||||||
|
|
||||||
with app.test_request_context("/creds", method="GET"):
|
with app.test_request_context("/creds", method="GET"):
|
||||||
api = controller_module.ToolBuiltinProviderGetCredentialsApi()
|
resp = controller_module.ToolBuiltinProviderGetCredentialsApi().get(provider="demo")
|
||||||
resp = unwrap(api.get)(api, "tenant-cred", user, provider="demo")
|
|
||||||
|
|
||||||
assert resp == [{"cred": 1}]
|
assert resp == [expected_response]
|
||||||
service_mock.assert_called_once_with(
|
service_mock.assert_called_once_with(
|
||||||
tenant_id="tenant-cred",
|
tenant_id="tenant-cred",
|
||||||
provider_name="demo",
|
provider_name="demo",
|
||||||
@ -196,7 +425,8 @@ def test_builtin_provider_credentials_get_reads_repeated_include_ids(
|
|||||||
app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch
|
app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch
|
||||||
):
|
):
|
||||||
user = _mock_account("user-tenant-cred")
|
user = _mock_account("user-tenant-cred")
|
||||||
service_mock = MagicMock(return_value=[{"cred": 1}])
|
credential_payload, expected = _credential_response(controller_module)
|
||||||
|
service_mock = MagicMock(return_value=[credential_payload])
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
controller_module.BuiltinToolManageService,
|
controller_module.BuiltinToolManageService,
|
||||||
"get_builtin_tool_provider_credentials",
|
"get_builtin_tool_provider_credentials",
|
||||||
@ -207,7 +437,7 @@ def test_builtin_provider_credentials_get_reads_repeated_include_ids(
|
|||||||
api = controller_module.ToolBuiltinProviderGetCredentialsApi()
|
api = controller_module.ToolBuiltinProviderGetCredentialsApi()
|
||||||
resp = unwrap(api.get)(api, "tenant-cred", user, provider="demo")
|
resp = unwrap(api.get)(api, "tenant-cred", user, provider="demo")
|
||||||
|
|
||||||
assert resp == [{"cred": 1}]
|
assert resp == [expected]
|
||||||
service_mock.assert_called_once_with(
|
service_mock.assert_called_once_with(
|
||||||
tenant_id="tenant-cred",
|
tenant_id="tenant-cred",
|
||||||
provider_name="demo",
|
provider_name="demo",
|
||||||
@ -219,46 +449,51 @@ def test_builtin_provider_credentials_get_reads_repeated_include_ids(
|
|||||||
|
|
||||||
def test_api_provider_remote_schema_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_api_provider_remote_schema_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account()
|
user = _mock_account()
|
||||||
service_mock = MagicMock(return_value={"schema": "ok"})
|
_set_current_account(monkeypatch, controller_module, user, "tenant-10")
|
||||||
|
openapi_schema = '{"openapi":"3.0.0","info":{"title":"Demo API","version":"1.0.0"},"paths":{}}'
|
||||||
|
service_mock = MagicMock(return_value={"schema": openapi_schema})
|
||||||
monkeypatch.setattr(controller_module.ApiToolManageService, "get_api_tool_provider_remote_schema", service_mock)
|
monkeypatch.setattr(controller_module.ApiToolManageService, "get_api_tool_provider_remote_schema", service_mock)
|
||||||
|
|
||||||
with app.test_request_context("/remote?url=https://example.com/"):
|
with app.test_request_context("/remote?url=https://example.com/"):
|
||||||
api = controller_module.ToolApiProviderGetRemoteSchemaApi()
|
resp = controller_module.ToolApiProviderGetRemoteSchemaApi().get()
|
||||||
resp = unwrap(api.get)(api, "tenant-10", user)
|
|
||||||
|
|
||||||
assert resp == {"schema": "ok"}
|
assert resp == {"schema": openapi_schema}
|
||||||
service_mock.assert_called_once_with(user.id, "tenant-10", "https://example.com/")
|
service_mock.assert_called_once_with(user.id, "tenant-10", "https://example.com/")
|
||||||
|
|
||||||
|
|
||||||
def test_api_provider_list_tools_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_api_provider_list_tools_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account()
|
user = _mock_account()
|
||||||
service_mock = MagicMock(return_value=[{"tool": "t"}])
|
_set_current_account(monkeypatch, controller_module, user, "tenant-11")
|
||||||
|
service_payload, expected_response = _tool_response(controller_module, "t")
|
||||||
|
service_mock = MagicMock(return_value=[service_payload])
|
||||||
monkeypatch.setattr(controller_module.ApiToolManageService, "list_api_tool_provider_tools", service_mock)
|
monkeypatch.setattr(controller_module.ApiToolManageService, "list_api_tool_provider_tools", service_mock)
|
||||||
|
|
||||||
with app.test_request_context("/tools?provider=foo"):
|
with app.test_request_context("/tools?provider=foo"):
|
||||||
api = controller_module.ToolApiProviderListToolsApi()
|
resp = controller_module.ToolApiProviderListToolsApi().get()
|
||||||
resp = unwrap(api.get)(api, "tenant-11", user)
|
|
||||||
|
|
||||||
assert resp == [{"tool": "t"}]
|
assert resp == [expected_response]
|
||||||
service_mock.assert_called_once_with(user.id, "tenant-11", "foo")
|
service_mock.assert_called_once_with(user.id, "tenant-11", "foo")
|
||||||
|
|
||||||
|
|
||||||
def test_api_provider_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_api_provider_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account()
|
user = _mock_account()
|
||||||
service_mock = MagicMock(return_value={"provider": "foo"})
|
_set_current_account(monkeypatch, controller_module, user, "tenant-12")
|
||||||
|
service_payload, expected_response = _api_provider_detail_response(controller_module)
|
||||||
|
service_mock = MagicMock(return_value=service_payload)
|
||||||
monkeypatch.setattr(controller_module.ApiToolManageService, "get_api_tool_provider", service_mock)
|
monkeypatch.setattr(controller_module.ApiToolManageService, "get_api_tool_provider", service_mock)
|
||||||
|
|
||||||
with app.test_request_context("/get?provider=foo"):
|
with app.test_request_context("/get?provider=foo"):
|
||||||
api = controller_module.ToolApiProviderGetApi()
|
resp = controller_module.ToolApiProviderGetApi().get()
|
||||||
resp = unwrap(api.get)(api, "tenant-12", user)
|
|
||||||
|
|
||||||
assert resp == {"provider": "foo"}
|
assert resp == expected_response
|
||||||
service_mock.assert_called_once_with(user.id, "tenant-12", "foo")
|
service_mock.assert_called_once_with(user.id, "tenant-12", "foo")
|
||||||
|
|
||||||
|
|
||||||
def test_builtin_provider_credentials_schema_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_builtin_provider_credentials_schema_get(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account("user-tenant-13")
|
user = _mock_account("user-tenant-13")
|
||||||
service_mock = MagicMock(return_value={"schema": True})
|
_set_current_account(monkeypatch, controller_module, user, "tenant-13")
|
||||||
|
service_payload, expected_response = _provider_config_response(controller_module)
|
||||||
|
service_mock = MagicMock(return_value=[service_payload])
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
controller_module.BuiltinToolManageService,
|
controller_module.BuiltinToolManageService,
|
||||||
"list_builtin_provider_credentials_schema",
|
"list_builtin_provider_credentials_schema",
|
||||||
@ -266,16 +501,19 @@ def test_builtin_provider_credentials_schema_get(app: Flask, controller_module,
|
|||||||
)
|
)
|
||||||
|
|
||||||
with app.test_request_context("/schema", method="GET"):
|
with app.test_request_context("/schema", method="GET"):
|
||||||
api = controller_module.ToolBuiltinProviderCredentialsSchemaApi()
|
resp = controller_module.ToolBuiltinProviderCredentialsSchemaApi().get(
|
||||||
resp = unwrap(api.get)(api, "tenant-13", provider="demo", credential_type="api-key")
|
provider="demo", credential_type="api-key"
|
||||||
|
)
|
||||||
|
|
||||||
assert resp == {"schema": True}
|
assert resp == [expected_response]
|
||||||
service_mock.assert_called_once()
|
service_mock.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
def test_workflow_provider_get_by_tool(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_workflow_provider_get_by_tool(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account()
|
user = _mock_account()
|
||||||
tool_service = MagicMock(return_value={"wf": 1})
|
_set_current_account(monkeypatch, controller_module, user, "tenant-wf")
|
||||||
|
service_payload, expected_response = _workflow_detail_response(controller_module)
|
||||||
|
tool_service = MagicMock(return_value=service_payload)
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
controller_module.WorkflowToolManageService,
|
controller_module.WorkflowToolManageService,
|
||||||
"get_workflow_tool_by_tool_id",
|
"get_workflow_tool_by_tool_id",
|
||||||
@ -284,16 +522,17 @@ def test_workflow_provider_get_by_tool(app: Flask, controller_module, monkeypatc
|
|||||||
|
|
||||||
tool_id = "00000000-0000-0000-0000-000000000001"
|
tool_id = "00000000-0000-0000-0000-000000000001"
|
||||||
with app.test_request_context(f"/workflow?workflow_tool_id={tool_id}"):
|
with app.test_request_context(f"/workflow?workflow_tool_id={tool_id}"):
|
||||||
api = controller_module.ToolWorkflowProviderGetApi()
|
resp = controller_module.ToolWorkflowProviderGetApi().get()
|
||||||
resp = unwrap(api.get)(api, "tenant-wf", user)
|
|
||||||
|
|
||||||
assert resp == {"wf": 1}
|
assert resp == expected_response
|
||||||
tool_service.assert_called_once_with(user.id, "tenant-wf", tool_id)
|
tool_service.assert_called_once_with(user.id, "tenant-wf", tool_id)
|
||||||
|
|
||||||
|
|
||||||
def test_workflow_provider_get_by_app(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_workflow_provider_get_by_app(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account()
|
user = _mock_account()
|
||||||
service_mock = MagicMock(return_value={"app": 1})
|
_set_current_account(monkeypatch, controller_module, user, "tenant-wf2")
|
||||||
|
service_payload, expected_response = _workflow_detail_response(controller_module)
|
||||||
|
service_mock = MagicMock(return_value=service_payload)
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
controller_module.WorkflowToolManageService,
|
controller_module.WorkflowToolManageService,
|
||||||
"get_workflow_tool_by_app_id",
|
"get_workflow_tool_by_app_id",
|
||||||
@ -302,31 +541,32 @@ def test_workflow_provider_get_by_app(app: Flask, controller_module, monkeypatch
|
|||||||
|
|
||||||
app_id = "00000000-0000-0000-0000-000000000002"
|
app_id = "00000000-0000-0000-0000-000000000002"
|
||||||
with app.test_request_context(f"/workflow?workflow_app_id={app_id}"):
|
with app.test_request_context(f"/workflow?workflow_app_id={app_id}"):
|
||||||
api = controller_module.ToolWorkflowProviderGetApi()
|
resp = controller_module.ToolWorkflowProviderGetApi().get()
|
||||||
resp = unwrap(api.get)(api, "tenant-wf2", user)
|
|
||||||
|
|
||||||
assert resp == {"app": 1}
|
assert resp == expected_response
|
||||||
service_mock.assert_called_once_with(user.id, "tenant-wf2", app_id)
|
service_mock.assert_called_once_with(user.id, "tenant-wf2", app_id)
|
||||||
|
|
||||||
|
|
||||||
def test_workflow_provider_list_tools(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_workflow_provider_list_tools(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account()
|
user = _mock_account()
|
||||||
service_mock = MagicMock(return_value=[{"id": 1}])
|
_set_current_account(monkeypatch, controller_module, user, "tenant-wf3")
|
||||||
|
service_payload, expected_response = _tool_response(controller_module, "workflow-tool")
|
||||||
|
service_mock = MagicMock(return_value=[service_payload])
|
||||||
monkeypatch.setattr(controller_module.WorkflowToolManageService, "list_single_workflow_tools", service_mock)
|
monkeypatch.setattr(controller_module.WorkflowToolManageService, "list_single_workflow_tools", service_mock)
|
||||||
|
|
||||||
tool_id = "00000000-0000-0000-0000-000000000003"
|
tool_id = "00000000-0000-0000-0000-000000000003"
|
||||||
with app.test_request_context(f"/workflow/tools?workflow_tool_id={tool_id}"):
|
with app.test_request_context(f"/workflow/tools?workflow_tool_id={tool_id}"):
|
||||||
api = controller_module.ToolWorkflowProviderListToolApi()
|
resp = controller_module.ToolWorkflowProviderListToolApi().get()
|
||||||
resp = unwrap(api.get)(api, "tenant-wf3", user)
|
|
||||||
|
|
||||||
assert resp == [{"id": 1}]
|
assert resp == [expected_response]
|
||||||
service_mock.assert_called_once_with(user.id, "tenant-wf3", tool_id)
|
service_mock.assert_called_once_with(user.id, "tenant-wf3", tool_id)
|
||||||
|
|
||||||
|
|
||||||
def test_builtin_tools_list(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_builtin_tools_list(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account()
|
user = _mock_account()
|
||||||
|
_set_current_account(monkeypatch, controller_module, user, "tenant-bt")
|
||||||
|
|
||||||
provider = SimpleNamespace(to_dict=lambda: {"name": "builtin"})
|
provider, expected_response = _provider_entity_response(controller_module, "builtin", "builtin")
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
controller_module.BuiltinToolManageService,
|
controller_module.BuiltinToolManageService,
|
||||||
"list_builtin_tools",
|
"list_builtin_tools",
|
||||||
@ -334,16 +574,16 @@ def test_builtin_tools_list(app: Flask, controller_module, monkeypatch: pytest.M
|
|||||||
)
|
)
|
||||||
|
|
||||||
with app.test_request_context("/tools/builtin"):
|
with app.test_request_context("/tools/builtin"):
|
||||||
api = controller_module.ToolBuiltinListApi()
|
resp = controller_module.ToolBuiltinListApi().get()
|
||||||
resp = unwrap(api.get)(api, "tenant-bt", user)
|
|
||||||
|
|
||||||
assert resp == [{"name": "builtin"}]
|
assert resp == [expected_response]
|
||||||
|
|
||||||
|
|
||||||
def test_api_tools_list(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_api_tools_list(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account("user-tenant-api")
|
user = _mock_account("user-tenant-api")
|
||||||
|
_set_current_account(monkeypatch, controller_module, user, "tenant-api")
|
||||||
|
|
||||||
provider = SimpleNamespace(to_dict=lambda: {"name": "api"})
|
provider, expected_response = _provider_entity_response(controller_module, "api", "api")
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
controller_module.ApiToolManageService,
|
controller_module.ApiToolManageService,
|
||||||
"list_api_tools",
|
"list_api_tools",
|
||||||
@ -351,16 +591,16 @@ def test_api_tools_list(app: Flask, controller_module, monkeypatch: pytest.Monke
|
|||||||
)
|
)
|
||||||
|
|
||||||
with app.test_request_context("/tools/api"):
|
with app.test_request_context("/tools/api"):
|
||||||
api = controller_module.ToolApiListApi()
|
resp = controller_module.ToolApiListApi().get()
|
||||||
resp = unwrap(api.get)(api, "tenant-api")
|
|
||||||
|
|
||||||
assert resp == [{"name": "api"}]
|
assert resp == [expected_response]
|
||||||
|
|
||||||
|
|
||||||
def test_workflow_tools_list(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_workflow_tools_list(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
user = _mock_account()
|
user = _mock_account()
|
||||||
|
_set_current_account(monkeypatch, controller_module, user, "tenant-wf4")
|
||||||
|
|
||||||
provider = SimpleNamespace(to_dict=lambda: {"name": "wf"})
|
provider, expected_response = _provider_entity_response(controller_module, "wf", "workflow")
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
controller_module.WorkflowToolManageService,
|
controller_module.WorkflowToolManageService,
|
||||||
"list_tenant_workflow_tools",
|
"list_tenant_workflow_tools",
|
||||||
@ -368,20 +608,21 @@ def test_workflow_tools_list(app: Flask, controller_module, monkeypatch: pytest.
|
|||||||
)
|
)
|
||||||
|
|
||||||
with app.test_request_context("/tools/workflow"):
|
with app.test_request_context("/tools/workflow"):
|
||||||
api = controller_module.ToolWorkflowListApi()
|
resp = controller_module.ToolWorkflowListApi().get()
|
||||||
resp = unwrap(api.get)(api, "tenant-wf4", user)
|
|
||||||
|
|
||||||
assert resp == [{"name": "wf"}]
|
assert resp == [expected_response]
|
||||||
|
|
||||||
|
|
||||||
def test_tool_labels_list(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
def test_tool_labels_list(app: Flask, controller_module, monkeypatch: pytest.MonkeyPatch):
|
||||||
monkeypatch.setattr(controller_module.ToolLabelsService, "list_tool_labels", lambda: ["a", "b"])
|
user = _mock_account("user-label")
|
||||||
|
_set_current_account(monkeypatch, controller_module, user, "tenant-labels")
|
||||||
|
service_payload, expected_response = _tool_label_response(controller_module, "a")
|
||||||
|
monkeypatch.setattr(controller_module.ToolLabelsService, "list_tool_labels", lambda: [service_payload])
|
||||||
|
|
||||||
with app.test_request_context("/tool-labels"):
|
with app.test_request_context("/tool-labels"):
|
||||||
api = controller_module.ToolLabelsApi()
|
resp = controller_module.ToolLabelsApi().get()
|
||||||
resp = unwrap(api.get)(api)
|
|
||||||
|
|
||||||
assert resp == ["a", "b"]
|
assert resp == [expected_response]
|
||||||
|
|
||||||
|
|
||||||
# --- _resolve_identity_mode: gating + None-resolution (PR #36839 review) ---
|
# --- _resolve_identity_mode: gating + None-resolution (PR #36839 review) ---
|
||||||
|
|||||||
@ -1009,8 +1009,7 @@ class TestExternalDatasetApi:
|
|||||||
# 4. Provide default values when parameters are missing
|
# 4. Provide default values when parameters are missing
|
||||||
# 5. Raise BadRequest exceptions when validation fails
|
# 5. Raise BadRequest exceptions when validation fails
|
||||||
#
|
#
|
||||||
# Response formatting is handled by Flask-RESTX's marshal_with decorator
|
# Response formatting is handled by controller response schemas, which:
|
||||||
# or marshal function, which:
|
|
||||||
#
|
#
|
||||||
# 1. Formats response data according to defined models
|
# 1. Formats response data according to defined models
|
||||||
# 2. Handles nested objects and lists
|
# 2. Handles nested objects and lists
|
||||||
|
|||||||
@ -145,7 +145,7 @@ export const zGetOauthPluginByProviderToolAuthorizationUrlPath = z.object({
|
|||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authorization URL retrieved successfully
|
* Tool OAuth authorization URL generated successfully
|
||||||
*/
|
*/
|
||||||
export const zGetOauthPluginByProviderToolAuthorizationUrlResponse
|
export const zGetOauthPluginByProviderToolAuthorizationUrlResponse
|
||||||
= zPluginOAuthAuthorizationUrlResponse
|
= zPluginOAuthAuthorizationUrlResponse
|
||||||
|
|||||||
@ -609,16 +609,14 @@ export type WorkspaceAccessMatrix = {
|
|||||||
pagination?: Pagination | null
|
pagination?: Pagination | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ToolProviderOpaqueResponse = unknown
|
export type ToolLabelListResponse = Array<ToolLabel>
|
||||||
|
|
||||||
export type ApiToolProviderAddPayload = {
|
export type ApiToolProviderAddPayload = {
|
||||||
credentials: {
|
credentials: {
|
||||||
[key: string]: unknown
|
[key: string]: unknown
|
||||||
}
|
}
|
||||||
custom_disclaimer?: string
|
custom_disclaimer?: string
|
||||||
icon: {
|
icon: ToolEmojiIcon
|
||||||
[key: string]: unknown
|
|
||||||
}
|
|
||||||
labels?: Array<string> | null
|
labels?: Array<string> | null
|
||||||
privacy_policy?: string | null
|
privacy_policy?: string | null
|
||||||
provider: string
|
provider: string
|
||||||
@ -630,10 +628,37 @@ export type ApiToolProviderDeletePayload = {
|
|||||||
provider: string
|
provider: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ApiProviderDetailResponse = {
|
||||||
|
credentials?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
|
custom_disclaimer?: string | null
|
||||||
|
description?: string | null
|
||||||
|
icon: ToolEmojiIcon
|
||||||
|
labels?: Array<string>
|
||||||
|
privacy_policy?: string | null
|
||||||
|
schema: string
|
||||||
|
schema_type: ApiProviderSchemaType
|
||||||
|
tools: Array<ApiToolBundle>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ApiProviderRemoteSchemaResponse = {
|
||||||
|
schema: string
|
||||||
|
}
|
||||||
|
|
||||||
export type ApiToolSchemaPayload = {
|
export type ApiToolSchemaPayload = {
|
||||||
schema: string
|
schema: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ApiSchemaParseResponse = {
|
||||||
|
credentials_schema: Array<ProviderConfig>
|
||||||
|
parameters_schema: Array<ApiToolBundle>
|
||||||
|
schema_type: ApiProviderSchemaType
|
||||||
|
warning: {
|
||||||
|
[key: string]: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type ApiToolTestPayload = {
|
export type ApiToolTestPayload = {
|
||||||
credentials: {
|
credentials: {
|
||||||
[key: string]: unknown
|
[key: string]: unknown
|
||||||
@ -647,14 +672,16 @@ export type ApiToolTestPayload = {
|
|||||||
tool_name: string
|
tool_name: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ApiToolPreviewResponse = ApiToolPreviewResult
|
||||||
|
|
||||||
|
export type ToolApiListResponse = Array<ToolApiEntity>
|
||||||
|
|
||||||
export type ApiToolProviderUpdatePayload = {
|
export type ApiToolProviderUpdatePayload = {
|
||||||
credentials: {
|
credentials: {
|
||||||
[key: string]: unknown
|
[key: string]: unknown
|
||||||
}
|
}
|
||||||
custom_disclaimer?: string
|
custom_disclaimer?: string
|
||||||
icon: {
|
icon: ToolEmojiIcon
|
||||||
[key: string]: unknown
|
|
||||||
}
|
|
||||||
labels?: Array<string> | null
|
labels?: Array<string> | null
|
||||||
original_provider: string
|
original_provider: string
|
||||||
privacy_policy?: string | null
|
privacy_policy?: string | null
|
||||||
@ -672,6 +699,16 @@ export type BuiltinToolAddPayload = {
|
|||||||
visibility?: string | null
|
visibility?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ToolProviderCredentialInfoApiEntity = {
|
||||||
|
credentials: Array<ToolProviderCredentialApiEntity>
|
||||||
|
is_oauth_custom_client_enabled?: boolean
|
||||||
|
supported_credential_types: Array<CredentialType>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ProviderConfigListResponse = Array<ProviderConfig>
|
||||||
|
|
||||||
|
export type ToolProviderCredentialListResponse = Array<ToolProviderCredentialApiEntity>
|
||||||
|
|
||||||
export type BuiltinProviderDefaultCredentialPayload = {
|
export type BuiltinProviderDefaultCredentialPayload = {
|
||||||
id: string
|
id: string
|
||||||
}
|
}
|
||||||
@ -680,12 +717,56 @@ export type BuiltinToolCredentialDeletePayload = {
|
|||||||
credential_id: string
|
credential_id: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ToolOAuthClientSchemaResponse = Array<{
|
export type ToolProviderApiEntityResponse = {
|
||||||
[key: string]: unknown
|
allow_delete?: boolean
|
||||||
}>
|
authentication?: McpAuthentication | null
|
||||||
|
author: string
|
||||||
|
configuration?: McpConfiguration | null
|
||||||
|
description: I18nObject
|
||||||
|
icon:
|
||||||
|
| string
|
||||||
|
| {
|
||||||
|
[key: string]: string
|
||||||
|
}
|
||||||
|
icon_dark?:
|
||||||
|
| string
|
||||||
|
| {
|
||||||
|
[key: string]: string
|
||||||
|
}
|
||||||
|
id: string
|
||||||
|
identity_mode?: string
|
||||||
|
is_dynamic_registration?: boolean
|
||||||
|
is_team_authorization?: boolean
|
||||||
|
label: I18nObject
|
||||||
|
labels?: Array<string>
|
||||||
|
masked_headers?: {
|
||||||
|
[key: string]: string
|
||||||
|
} | null
|
||||||
|
name: string
|
||||||
|
original_headers?: {
|
||||||
|
[key: string]: string
|
||||||
|
} | null
|
||||||
|
plugin_id?: string | null
|
||||||
|
plugin_unique_identifier?: string | null
|
||||||
|
server_identifier?: string | null
|
||||||
|
server_url?: string | null
|
||||||
|
team_credentials?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
|
tools?: Array<ToolApiEntity>
|
||||||
|
type: ToolProviderType
|
||||||
|
updated_at?: number
|
||||||
|
workflow_app_id?: string | null
|
||||||
|
}
|
||||||
|
|
||||||
export type ToolOAuthCustomClientResponse = {
|
export type BuiltinProviderOAuthClientSchemaResponse = {
|
||||||
[key: string]: unknown
|
client_params?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
} | null
|
||||||
|
is_oauth_custom_client_enabled: boolean
|
||||||
|
is_system_oauth_params_exists: boolean
|
||||||
|
redirect_uri: string
|
||||||
|
schema: Array<ProviderConfig>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ToolOAuthCustomClientPayload = {
|
export type ToolOAuthCustomClientPayload = {
|
||||||
@ -708,14 +789,10 @@ export type McpProviderDeletePayload = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type McpProviderCreatePayload = {
|
export type McpProviderCreatePayload = {
|
||||||
authentication?: {
|
authentication?: McpAuthentication | null
|
||||||
[key: string]: unknown
|
configuration?: McpConfiguration | null
|
||||||
} | null
|
|
||||||
configuration?: {
|
|
||||||
[key: string]: unknown
|
|
||||||
} | null
|
|
||||||
headers?: {
|
headers?: {
|
||||||
[key: string]: unknown
|
[key: string]: string
|
||||||
} | null
|
} | null
|
||||||
icon: string
|
icon: string
|
||||||
icon_background?: string
|
icon_background?: string
|
||||||
@ -727,14 +804,10 @@ export type McpProviderCreatePayload = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type McpProviderUpdatePayload = {
|
export type McpProviderUpdatePayload = {
|
||||||
authentication?: {
|
authentication?: McpAuthentication | null
|
||||||
[key: string]: unknown
|
configuration?: McpConfiguration | null
|
||||||
} | null
|
|
||||||
configuration?: {
|
|
||||||
[key: string]: unknown
|
|
||||||
} | null
|
|
||||||
headers?: {
|
headers?: {
|
||||||
[key: string]: unknown
|
[key: string]: string
|
||||||
} | null
|
} | null
|
||||||
icon: string
|
icon: string
|
||||||
icon_background?: string
|
icon_background?: string
|
||||||
@ -751,11 +824,14 @@ export type McpAuthPayload = {
|
|||||||
provider_id: string
|
provider_id: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type McpAuthResponse = {
|
||||||
|
authorization_url?: string | null
|
||||||
|
result?: 'success' | null
|
||||||
|
}
|
||||||
|
|
||||||
export type WorkflowToolCreatePayload = {
|
export type WorkflowToolCreatePayload = {
|
||||||
description: string
|
description: string
|
||||||
icon: {
|
icon: ToolEmojiIcon
|
||||||
[key: string]: unknown
|
|
||||||
}
|
|
||||||
label: string
|
label: string
|
||||||
labels?: Array<string> | null
|
labels?: Array<string> | null
|
||||||
name: string
|
name: string
|
||||||
@ -768,11 +844,25 @@ export type WorkflowToolDeletePayload = {
|
|||||||
workflow_tool_id: string
|
workflow_tool_id: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WorkflowToolUpdatePayload = {
|
export type WorkflowToolDetailResponse = {
|
||||||
description: string
|
description: string
|
||||||
icon: {
|
icon: ToolEmojiIcon
|
||||||
|
label: string
|
||||||
|
name: string
|
||||||
|
output_schema?: {
|
||||||
[key: string]: unknown
|
[key: string]: unknown
|
||||||
}
|
}
|
||||||
|
parameters: Array<WorkflowToolParameterConfiguration>
|
||||||
|
privacy_policy?: string | null
|
||||||
|
synced: boolean
|
||||||
|
tool: ToolApiEntity
|
||||||
|
workflow_app_id: string
|
||||||
|
workflow_tool_id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type WorkflowToolUpdatePayload = {
|
||||||
|
description: string
|
||||||
|
icon: ToolEmojiIcon
|
||||||
label: string
|
label: string
|
||||||
labels?: Array<string> | null
|
labels?: Array<string> | null
|
||||||
name: string
|
name: string
|
||||||
@ -781,6 +871,8 @@ export type WorkflowToolUpdatePayload = {
|
|||||||
workflow_tool_id: string
|
workflow_tool_id: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ToolProviderListResponse = Array<ToolProviderApiEntityResponse>
|
||||||
|
|
||||||
export type TriggerProviderApiEntity = {
|
export type TriggerProviderApiEntity = {
|
||||||
author: string
|
author: string
|
||||||
description: I18nObject
|
description: I18nObject
|
||||||
@ -801,7 +893,7 @@ export type TriggerOAuthClientResponse = {
|
|||||||
configured: boolean
|
configured: boolean
|
||||||
custom_configured: boolean
|
custom_configured: boolean
|
||||||
custom_enabled: boolean
|
custom_enabled: boolean
|
||||||
oauth_client_schema: Array<TriggerProviderConfigResponse>
|
oauth_client_schema: Array<ProviderConfig>
|
||||||
params: {
|
params: {
|
||||||
[key: string]: unknown
|
[key: string]: unknown
|
||||||
}
|
}
|
||||||
@ -829,8 +921,6 @@ export type TriggerSubscriptionBuilderUpdatePayload = {
|
|||||||
} | null
|
} | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TriggerProviderOpaqueResponse = unknown
|
|
||||||
|
|
||||||
export type TriggerSubscriptionBuilderCreatePayload = {
|
export type TriggerSubscriptionBuilderCreatePayload = {
|
||||||
credential_type?: string
|
credential_type?: string
|
||||||
}
|
}
|
||||||
@ -866,11 +956,15 @@ export type TriggerSubscriptionBuilderVerifyPayload = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TriggerSubscriptionBuilderVerifyResponse = {
|
export type TriggerVerificationResponse = {
|
||||||
verified: boolean
|
verified: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TriggerSubscriptionListResponse = Array<TriggerProviderSubscriptionApiEntity>
|
export type TriggerProviderSubscriptionListResponse = Array<TriggerProviderSubscriptionApiEntity>
|
||||||
|
|
||||||
|
export type TriggerProviderErrorResponse = {
|
||||||
|
error: string
|
||||||
|
}
|
||||||
|
|
||||||
export type TriggerOAuthAuthorizeResponse = {
|
export type TriggerOAuthAuthorizeResponse = {
|
||||||
authorization_url: string
|
authorization_url: string
|
||||||
@ -1294,16 +1388,91 @@ export type AccessPolicyRole = {
|
|||||||
role_tag?: string
|
role_tag?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ToolLabel = {
|
||||||
|
icon: string
|
||||||
|
label: I18nObject
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ToolEmojiIcon = {
|
||||||
|
background: string
|
||||||
|
content: string
|
||||||
|
}
|
||||||
|
|
||||||
export type ApiProviderSchemaType = 'openai_actions' | 'openai_plugin' | 'openapi' | 'swagger'
|
export type ApiProviderSchemaType = 'openai_actions' | 'openai_plugin' | 'openapi' | 'swagger'
|
||||||
|
|
||||||
|
export type ApiToolBundle = {
|
||||||
|
author: string
|
||||||
|
icon?: string | null
|
||||||
|
method: string
|
||||||
|
openapi: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
|
operation_id?: string | null
|
||||||
|
output_schema?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
|
parameters?: Array<ToolParameter> | null
|
||||||
|
server_url: string
|
||||||
|
summary?: string | 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: ProviderConfigType
|
||||||
|
url?: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ApiToolPreviewResult = {
|
||||||
|
error?: string
|
||||||
|
result?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ToolApiEntity = {
|
||||||
|
author: string
|
||||||
|
description: I18nObject
|
||||||
|
label: I18nObject
|
||||||
|
labels?: Array<string>
|
||||||
|
name: string
|
||||||
|
output_schema?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
|
parameters?: Array<ToolParameter> | null
|
||||||
|
}
|
||||||
|
|
||||||
export type CredentialType = 'api-key' | 'oauth2' | 'unauthorized'
|
export type CredentialType = 'api-key' | 'oauth2' | 'unauthorized'
|
||||||
|
|
||||||
export type IdentityMode = 'idp_token' | 'off'
|
export type ToolProviderCredentialApiEntity = {
|
||||||
|
created_by?: string
|
||||||
export type WorkflowToolParameterConfiguration = {
|
credential_type: CredentialType
|
||||||
description: string
|
credentials?: {
|
||||||
form: ToolParameterForm
|
[key: string]: unknown
|
||||||
|
}
|
||||||
|
from_other_member?: boolean
|
||||||
|
id: string
|
||||||
|
is_default?: boolean
|
||||||
name: string
|
name: string
|
||||||
|
partial_member_list?: Array<string>
|
||||||
|
provider: string
|
||||||
|
visibility?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type McpAuthentication = {
|
||||||
|
client_id: string
|
||||||
|
client_secret?: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type McpConfiguration = {
|
||||||
|
sse_read_timeout?: number
|
||||||
|
timeout?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type I18nObject = {
|
export type I18nObject = {
|
||||||
@ -1313,6 +1482,23 @@ export type I18nObject = {
|
|||||||
zh_Hans?: string | null
|
zh_Hans?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ToolProviderType
|
||||||
|
= | 'api'
|
||||||
|
| 'app'
|
||||||
|
| 'builtin'
|
||||||
|
| 'dataset-retrieval'
|
||||||
|
| 'mcp'
|
||||||
|
| 'plugin'
|
||||||
|
| 'workflow'
|
||||||
|
|
||||||
|
export type IdentityMode = 'idp_token' | 'off'
|
||||||
|
|
||||||
|
export type WorkflowToolParameterConfiguration = {
|
||||||
|
description: string
|
||||||
|
form: ToolParameterForm
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
export type EventApiEntity = {
|
export type EventApiEntity = {
|
||||||
description: I18nObject
|
description: I18nObject
|
||||||
identity: EventIdentity
|
identity: EventIdentity
|
||||||
@ -1329,43 +1515,8 @@ export type SubscriptionConstructor = {
|
|||||||
parameters?: Array<EventParameter>
|
parameters?: Array<EventParameter>
|
||||||
}
|
}
|
||||||
|
|
||||||
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: ProviderConfigType
|
|
||||||
url?: string | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TriggerCreationMethod = 'APIKEY' | 'MANUAL' | 'OAUTH'
|
export type TriggerCreationMethod = 'APIKEY' | 'MANUAL' | 'OAUTH'
|
||||||
|
|
||||||
export type TriggerProviderConfigResponse = {
|
|
||||||
default?: number | string | number | boolean | null
|
|
||||||
help?: I18nObject | null
|
|
||||||
label?: I18nObject | null
|
|
||||||
multiple?: boolean
|
|
||||||
name: string
|
|
||||||
options?: Array<TriggerProviderConfigOptionResponse> | null
|
|
||||||
placeholder?: I18nObject | null
|
|
||||||
required?: boolean
|
|
||||||
scope?: AppSelectorScope | ModelSelectorScope | ToolSelectorScope | null
|
|
||||||
type:
|
|
||||||
| 'app-selector'
|
|
||||||
| 'array[tools]'
|
|
||||||
| 'boolean'
|
|
||||||
| 'model-selector'
|
|
||||||
| 'secret-input'
|
|
||||||
| 'select'
|
|
||||||
| 'text-input'
|
|
||||||
url?: string | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export type RequestLog = {
|
export type RequestLog = {
|
||||||
created_at: string
|
created_at: string
|
||||||
endpoint: string
|
endpoint: string
|
||||||
@ -1591,15 +1742,6 @@ export type PluginCategoryBuiltinToolResponse = {
|
|||||||
[key: string]: unknown
|
[key: string]: unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ToolProviderType
|
|
||||||
= | 'api'
|
|
||||||
| 'app'
|
|
||||||
| 'builtin'
|
|
||||||
| 'dataset-retrieval'
|
|
||||||
| 'mcp'
|
|
||||||
| 'plugin'
|
|
||||||
| 'workflow'
|
|
||||||
|
|
||||||
export type RbacRoleAccount = {
|
export type RbacRoleAccount = {
|
||||||
account_id: string
|
account_id: string
|
||||||
account_name?: string
|
account_name?: string
|
||||||
@ -1618,6 +1760,64 @@ export type PermissionCatalogItem = {
|
|||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ToolParameter = {
|
||||||
|
auto_generate?: PluginParameterAutoGenerate | null
|
||||||
|
default?:
|
||||||
|
| number
|
||||||
|
| number
|
||||||
|
| string
|
||||||
|
| boolean
|
||||||
|
| Array<unknown>
|
||||||
|
| {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
|
| null
|
||||||
|
form: ToolParameterForm
|
||||||
|
human_description?: I18nObject | null
|
||||||
|
input_schema?: {
|
||||||
|
[key: string]: unknown
|
||||||
|
} | null
|
||||||
|
label: I18nObject
|
||||||
|
llm_description?: string | null
|
||||||
|
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: ToolParameterType
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ProviderConfigType
|
||||||
|
= | 'app-selector'
|
||||||
|
| 'array[tools]'
|
||||||
|
| 'boolean'
|
||||||
|
| 'model-selector'
|
||||||
|
| 'secret-input'
|
||||||
|
| 'select'
|
||||||
|
| 'text-input'
|
||||||
|
|
||||||
export type ToolParameterForm = 'form' | 'llm' | 'schema'
|
export type ToolParameterForm = 'form' | 'llm' | 'schema'
|
||||||
|
|
||||||
export type EventIdentity = {
|
export type EventIdentity = {
|
||||||
@ -1649,38 +1849,6 @@ export type OAuthSchema = {
|
|||||||
credentials_schema?: Array<ProviderConfig>
|
credentials_schema?: Array<ProviderConfig>
|
||||||
}
|
}
|
||||||
|
|
||||||
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 ProviderConfigType
|
|
||||||
= | 'app-selector'
|
|
||||||
| 'array[tools]'
|
|
||||||
| 'boolean'
|
|
||||||
| 'model-selector'
|
|
||||||
| 'secret-input'
|
|
||||||
| 'select'
|
|
||||||
| 'text-input'
|
|
||||||
|
|
||||||
export type TriggerProviderConfigOptionResponse = {
|
|
||||||
label: I18nObject
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AiModelEntityResponse = {
|
export type AiModelEntityResponse = {
|
||||||
deprecated?: boolean
|
deprecated?: boolean
|
||||||
features?: Array<ModelFeature> | null
|
features?: Array<ModelFeature> | null
|
||||||
@ -1801,6 +1969,23 @@ export type PluginParameterTemplate = {
|
|||||||
enabled?: boolean
|
enabled?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ToolParameterType
|
||||||
|
= | 'any'
|
||||||
|
| 'app-selector'
|
||||||
|
| 'array'
|
||||||
|
| 'boolean'
|
||||||
|
| 'checkbox'
|
||||||
|
| 'dynamic-select'
|
||||||
|
| 'file'
|
||||||
|
| 'files'
|
||||||
|
| 'model-selector'
|
||||||
|
| 'number'
|
||||||
|
| 'object'
|
||||||
|
| 'secret-input'
|
||||||
|
| 'select'
|
||||||
|
| 'string'
|
||||||
|
| 'system-files'
|
||||||
|
|
||||||
export type EventParameterType
|
export type EventParameterType
|
||||||
= | 'app-selector'
|
= | 'app-selector'
|
||||||
| 'array'
|
| 'array'
|
||||||
@ -4099,7 +4284,7 @@ export type GetWorkspacesCurrentToolLabelsData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolLabelsResponses = {
|
export type GetWorkspacesCurrentToolLabelsResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolLabelListResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolLabelsResponse
|
export type GetWorkspacesCurrentToolLabelsResponse
|
||||||
@ -4113,7 +4298,7 @@ export type PostWorkspacesCurrentToolProviderApiAddData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderApiAddResponses = {
|
export type PostWorkspacesCurrentToolProviderApiAddResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: SimpleResultResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderApiAddResponse
|
export type PostWorkspacesCurrentToolProviderApiAddResponse
|
||||||
@ -4127,7 +4312,7 @@ export type PostWorkspacesCurrentToolProviderApiDeleteData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderApiDeleteResponses = {
|
export type PostWorkspacesCurrentToolProviderApiDeleteResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: SimpleResultResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderApiDeleteResponse
|
export type PostWorkspacesCurrentToolProviderApiDeleteResponse
|
||||||
@ -4143,7 +4328,7 @@ export type GetWorkspacesCurrentToolProviderApiGetData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderApiGetResponses = {
|
export type GetWorkspacesCurrentToolProviderApiGetResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ApiProviderDetailResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderApiGetResponse
|
export type GetWorkspacesCurrentToolProviderApiGetResponse
|
||||||
@ -4159,7 +4344,7 @@ export type GetWorkspacesCurrentToolProviderApiRemoteData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderApiRemoteResponses = {
|
export type GetWorkspacesCurrentToolProviderApiRemoteResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ApiProviderRemoteSchemaResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderApiRemoteResponse
|
export type GetWorkspacesCurrentToolProviderApiRemoteResponse
|
||||||
@ -4173,7 +4358,7 @@ export type PostWorkspacesCurrentToolProviderApiSchemaData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderApiSchemaResponses = {
|
export type PostWorkspacesCurrentToolProviderApiSchemaResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ApiSchemaParseResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderApiSchemaResponse
|
export type PostWorkspacesCurrentToolProviderApiSchemaResponse
|
||||||
@ -4187,7 +4372,7 @@ export type PostWorkspacesCurrentToolProviderApiTestPreData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderApiTestPreResponses = {
|
export type PostWorkspacesCurrentToolProviderApiTestPreResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ApiToolPreviewResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderApiTestPreResponse
|
export type PostWorkspacesCurrentToolProviderApiTestPreResponse
|
||||||
@ -4203,7 +4388,7 @@ export type GetWorkspacesCurrentToolProviderApiToolsData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderApiToolsResponses = {
|
export type GetWorkspacesCurrentToolProviderApiToolsResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolApiListResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderApiToolsResponse
|
export type GetWorkspacesCurrentToolProviderApiToolsResponse
|
||||||
@ -4217,7 +4402,7 @@ export type PostWorkspacesCurrentToolProviderApiUpdateData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderApiUpdateResponses = {
|
export type PostWorkspacesCurrentToolProviderApiUpdateResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: SimpleResultResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderApiUpdateResponse
|
export type PostWorkspacesCurrentToolProviderApiUpdateResponse
|
||||||
@ -4233,7 +4418,7 @@ export type PostWorkspacesCurrentToolProviderBuiltinByProviderAddData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderBuiltinByProviderAddResponses = {
|
export type PostWorkspacesCurrentToolProviderBuiltinByProviderAddResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: SimpleResultResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderBuiltinByProviderAddResponse
|
export type PostWorkspacesCurrentToolProviderBuiltinByProviderAddResponse
|
||||||
@ -4251,7 +4436,7 @@ export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoData
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoResponses = {
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolProviderCredentialInfoApiEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoResponse
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialInfoResponse
|
||||||
@ -4270,7 +4455,7 @@ export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByC
|
|||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypeResponses
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypeResponses
|
||||||
= {
|
= {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ProviderConfigListResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypeResponse
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialSchemaByCredentialTypeResponse
|
||||||
@ -4288,7 +4473,7 @@ export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsResponses = {
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolProviderCredentialListResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsResponse
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderCredentialsResponse
|
||||||
@ -4304,7 +4489,7 @@ export type PostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialD
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialResponses = {
|
export type PostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: SimpleResultResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialResponse
|
export type PostWorkspacesCurrentToolProviderBuiltinByProviderDefaultCredentialResponse
|
||||||
@ -4320,7 +4505,7 @@ export type PostWorkspacesCurrentToolProviderBuiltinByProviderDeleteData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderBuiltinByProviderDeleteResponses = {
|
export type PostWorkspacesCurrentToolProviderBuiltinByProviderDeleteResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: SimpleResultResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderBuiltinByProviderDeleteResponse
|
export type PostWorkspacesCurrentToolProviderBuiltinByProviderDeleteResponse
|
||||||
@ -4336,7 +4521,9 @@ export type GetWorkspacesCurrentToolProviderBuiltinByProviderIconData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderIconResponses = {
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderIconResponses = {
|
||||||
200: BinaryFileResponse
|
200: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderIconResponse
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderIconResponse
|
||||||
@ -4352,7 +4539,7 @@ export type GetWorkspacesCurrentToolProviderBuiltinByProviderInfoData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderInfoResponses = {
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderInfoResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolProviderApiEntityResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderInfoResponse
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderInfoResponse
|
||||||
@ -4368,7 +4555,7 @@ export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaResponses = {
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaResponses = {
|
||||||
200: ToolOAuthClientSchemaResponse
|
200: BuiltinProviderOAuthClientSchemaResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaResponse
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthClientSchemaResponse
|
||||||
@ -4400,7 +4587,9 @@ export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponses = {
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponses = {
|
||||||
200: ToolOAuthCustomClientResponse
|
200: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderOauthCustomClientResponse
|
||||||
@ -4432,7 +4621,7 @@ export type GetWorkspacesCurrentToolProviderBuiltinByProviderToolsData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderToolsResponses = {
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderToolsResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolApiListResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderBuiltinByProviderToolsResponse
|
export type GetWorkspacesCurrentToolProviderBuiltinByProviderToolsResponse
|
||||||
@ -4448,7 +4637,7 @@ export type PostWorkspacesCurrentToolProviderBuiltinByProviderUpdateData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderBuiltinByProviderUpdateResponses = {
|
export type PostWorkspacesCurrentToolProviderBuiltinByProviderUpdateResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: SimpleResultResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderBuiltinByProviderUpdateResponse
|
export type PostWorkspacesCurrentToolProviderBuiltinByProviderUpdateResponse
|
||||||
@ -4476,7 +4665,7 @@ export type PostWorkspacesCurrentToolProviderMcpData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderMcpResponses = {
|
export type PostWorkspacesCurrentToolProviderMcpResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolProviderApiEntityResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderMcpResponse
|
export type PostWorkspacesCurrentToolProviderMcpResponse
|
||||||
@ -4504,7 +4693,7 @@ export type PostWorkspacesCurrentToolProviderMcpAuthData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderMcpAuthResponses = {
|
export type PostWorkspacesCurrentToolProviderMcpAuthResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: McpAuthResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderMcpAuthResponse
|
export type PostWorkspacesCurrentToolProviderMcpAuthResponse
|
||||||
@ -4520,7 +4709,7 @@ export type GetWorkspacesCurrentToolProviderMcpToolsByProviderIdData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderMcpToolsByProviderIdResponses = {
|
export type GetWorkspacesCurrentToolProviderMcpToolsByProviderIdResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolProviderApiEntityResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderMcpToolsByProviderIdResponse
|
export type GetWorkspacesCurrentToolProviderMcpToolsByProviderIdResponse
|
||||||
@ -4536,7 +4725,7 @@ export type GetWorkspacesCurrentToolProviderMcpUpdateByProviderIdData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderMcpUpdateByProviderIdResponses = {
|
export type GetWorkspacesCurrentToolProviderMcpUpdateByProviderIdResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolProviderApiEntityResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderMcpUpdateByProviderIdResponse
|
export type GetWorkspacesCurrentToolProviderMcpUpdateByProviderIdResponse
|
||||||
@ -4550,7 +4739,7 @@ export type PostWorkspacesCurrentToolProviderWorkflowCreateData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderWorkflowCreateResponses = {
|
export type PostWorkspacesCurrentToolProviderWorkflowCreateResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: SimpleResultResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderWorkflowCreateResponse
|
export type PostWorkspacesCurrentToolProviderWorkflowCreateResponse
|
||||||
@ -4564,7 +4753,7 @@ export type PostWorkspacesCurrentToolProviderWorkflowDeleteData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderWorkflowDeleteResponses = {
|
export type PostWorkspacesCurrentToolProviderWorkflowDeleteResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: SimpleResultResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderWorkflowDeleteResponse
|
export type PostWorkspacesCurrentToolProviderWorkflowDeleteResponse
|
||||||
@ -4581,7 +4770,7 @@ export type GetWorkspacesCurrentToolProviderWorkflowGetData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderWorkflowGetResponses = {
|
export type GetWorkspacesCurrentToolProviderWorkflowGetResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: WorkflowToolDetailResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderWorkflowGetResponse
|
export type GetWorkspacesCurrentToolProviderWorkflowGetResponse
|
||||||
@ -4597,7 +4786,7 @@ export type GetWorkspacesCurrentToolProviderWorkflowToolsData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderWorkflowToolsResponses = {
|
export type GetWorkspacesCurrentToolProviderWorkflowToolsResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolApiListResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProviderWorkflowToolsResponse
|
export type GetWorkspacesCurrentToolProviderWorkflowToolsResponse
|
||||||
@ -4611,7 +4800,7 @@ export type PostWorkspacesCurrentToolProviderWorkflowUpdateData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderWorkflowUpdateResponses = {
|
export type PostWorkspacesCurrentToolProviderWorkflowUpdateResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: SimpleResultResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentToolProviderWorkflowUpdateResponse
|
export type PostWorkspacesCurrentToolProviderWorkflowUpdateResponse
|
||||||
@ -4627,7 +4816,7 @@ export type GetWorkspacesCurrentToolProvidersData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProvidersResponses = {
|
export type GetWorkspacesCurrentToolProvidersResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolProviderListResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolProvidersResponse
|
export type GetWorkspacesCurrentToolProvidersResponse
|
||||||
@ -4641,7 +4830,7 @@ export type GetWorkspacesCurrentToolsApiData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolsApiResponses = {
|
export type GetWorkspacesCurrentToolsApiResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolProviderListResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolsApiResponse
|
export type GetWorkspacesCurrentToolsApiResponse
|
||||||
@ -4655,7 +4844,7 @@ export type GetWorkspacesCurrentToolsBuiltinData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolsBuiltinResponses = {
|
export type GetWorkspacesCurrentToolsBuiltinResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolProviderListResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolsBuiltinResponse
|
export type GetWorkspacesCurrentToolsBuiltinResponse
|
||||||
@ -4669,7 +4858,7 @@ export type GetWorkspacesCurrentToolsMcpData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolsMcpResponses = {
|
export type GetWorkspacesCurrentToolsMcpResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolProviderListResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolsMcpResponse
|
export type GetWorkspacesCurrentToolsMcpResponse
|
||||||
@ -4683,7 +4872,7 @@ export type GetWorkspacesCurrentToolsWorkflowData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolsWorkflowResponses = {
|
export type GetWorkspacesCurrentToolsWorkflowResponses = {
|
||||||
200: ToolProviderOpaqueResponse
|
200: ToolProviderListResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentToolsWorkflowResponse
|
export type GetWorkspacesCurrentToolsWorkflowResponse
|
||||||
@ -4699,7 +4888,9 @@ export type GetWorkspacesCurrentTriggerProviderByProviderIconData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentTriggerProviderByProviderIconResponses = {
|
export type GetWorkspacesCurrentTriggerProviderByProviderIconResponses = {
|
||||||
200: BinaryFileResponse
|
200: {
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentTriggerProviderByProviderIconResponse
|
export type GetWorkspacesCurrentTriggerProviderByProviderIconResponse
|
||||||
@ -4782,7 +4973,7 @@ export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBu
|
|||||||
|
|
||||||
export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdResponses
|
export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdResponses
|
||||||
= {
|
= {
|
||||||
200: TriggerProviderOpaqueResponse
|
200: SimpleResultResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdResponse
|
export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderBuildBySubscriptionBuilderIdResponse
|
||||||
@ -4855,7 +5046,7 @@ export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVe
|
|||||||
|
|
||||||
export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdResponses
|
export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdResponses
|
||||||
= {
|
= {
|
||||||
200: TriggerSubscriptionBuilderVerifyResponse
|
200: TriggerVerificationResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdResponse
|
export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsBuilderVerifyAndUpdateBySubscriptionBuilderIdResponse
|
||||||
@ -4889,8 +5080,15 @@ export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListData =
|
|||||||
url: '/workspaces/current/trigger-provider/{provider}/subscriptions/list'
|
url: '/workspaces/current/trigger-provider/{provider}/subscriptions/list'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListErrors = {
|
||||||
|
404: TriggerProviderErrorResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListError
|
||||||
|
= GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListErrors[keyof GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListErrors]
|
||||||
|
|
||||||
export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListResponses = {
|
export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListResponses = {
|
||||||
200: TriggerSubscriptionListResponse
|
200: TriggerProviderSubscriptionListResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListResponse
|
export type GetWorkspacesCurrentTriggerProviderByProviderSubscriptionsListResponse
|
||||||
@ -4925,7 +5123,7 @@ export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyByS
|
|||||||
|
|
||||||
export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdResponses
|
export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdResponses
|
||||||
= {
|
= {
|
||||||
200: TriggerSubscriptionBuilderVerifyResponse
|
200: TriggerVerificationResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdResponse
|
export type PostWorkspacesCurrentTriggerProviderByProviderSubscriptionsVerifyBySubscriptionIdResponse
|
||||||
@ -4957,7 +5155,7 @@ export type PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpd
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateResponses = {
|
export type PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateResponses = {
|
||||||
200: TriggerProviderOpaqueResponse
|
200: SimpleResultResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateResponse
|
export type PostWorkspacesCurrentTriggerProviderBySubscriptionIdSubscriptionsUpdateResponse
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user