Revert "feat: propagate trigger metadata for plugin icons across UI"

This reverts commit 3bd62f3fdf.
This commit is contained in:
lyzno1 2025-10-27 17:06:40 +08:00
parent c79d75b32d
commit 1335be8d60
No known key found for this signature in database
9 changed files with 29 additions and 258 deletions

View File

@ -5,17 +5,16 @@ from sqlalchemy import select
from sqlalchemy.orm import Session
from werkzeug.exceptions import Forbidden, NotFound
from configs import dify_config
from controllers.console import api
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import account_initialization_required, setup_required
from core.trigger.trigger_manager import TriggerManager
from extensions.ext_database import db
from fields.workflow_trigger_fields import trigger_fields, triggers_list_fields, webhook_trigger_fields
from libs.login import current_user, login_required
from models.enums import AppTriggerStatus, AppTriggerType
from models.enums import AppTriggerStatus
from models.model import Account, App, AppMode
from models.provider_ids import TriggerProviderID
from models.trigger import AppTrigger, WorkflowPluginTrigger, WorkflowWebhookTrigger
from models.trigger import AppTrigger, WorkflowWebhookTrigger
logger = logging.getLogger(__name__)
@ -81,64 +80,13 @@ class AppTriggersApi(Resource):
.all()
)
plugin_node_ids = [
trigger.node_id for trigger in triggers if trigger.trigger_type == AppTriggerType.TRIGGER_PLUGIN.value
]
plugin_trigger_map: dict[str, WorkflowPluginTrigger] = {}
if plugin_node_ids:
plugin_triggers = (
session.execute(
select(WorkflowPluginTrigger).where(
WorkflowPluginTrigger.app_id == app_model.id,
WorkflowPluginTrigger.node_id.in_(plugin_node_ids),
)
)
.scalars()
.all()
)
plugin_trigger_map = {plugin_trigger.node_id: plugin_trigger for plugin_trigger in plugin_triggers}
tenant_id = current_user.current_tenant_id if isinstance(current_user, Account) else None
provider_cache: dict[str, dict[str, str]] = {}
def resolve_provider_metadata(provider_id: str) -> dict[str, str]:
if provider_id in provider_cache:
return provider_cache[provider_id]
metadata: dict[str, str] = {}
if not tenant_id:
provider_cache[provider_id] = metadata
return metadata
try:
controller = TriggerManager.get_trigger_provider(tenant_id, TriggerProviderID(provider_id))
api_entity = controller.to_api_entity()
metadata = {
"plugin_id": controller.plugin_id,
"plugin_unique_identifier": controller.plugin_unique_identifier,
"icon": api_entity.icon or "",
"provider_name": api_entity.name,
}
except Exception:
metadata = {}
provider_cache[provider_id] = metadata
return metadata
# Add computed icon field for each trigger
url_prefix = dify_config.CONSOLE_API_URL + "/console/api/workspaces/current/tool-provider/builtin/"
for trigger in triggers:
if trigger.trigger_type == AppTriggerType.TRIGGER_PLUGIN.value:
plugin_trigger = plugin_trigger_map.get(trigger.node_id)
if not plugin_trigger:
trigger.icon = "" # type: ignore[attr-defined]
continue
trigger.provider_id = plugin_trigger.provider_id # type: ignore[attr-defined]
trigger.subscription_id = plugin_trigger.subscription_id # type: ignore[attr-defined]
trigger.event_name = plugin_trigger.event_name # type: ignore[attr-defined]
metadata = resolve_provider_metadata(plugin_trigger.provider_id)
trigger.plugin_id = metadata.get("plugin_id") # type: ignore[attr-defined]
trigger.plugin_unique_identifier = metadata.get("plugin_unique_identifier") # type: ignore[attr-defined]
trigger.icon = metadata.get("icon", "") # type: ignore[attr-defined]
if not trigger.provider_name:
trigger.provider_name = metadata.get("provider_name", "")
if trigger.trigger_type == "trigger-plugin":
trigger.icon = url_prefix + trigger.provider_name + "/icon" # type: ignore
else:
trigger.icon = "" # type: ignore[attr-defined]
trigger.icon = "" # type: ignore
return {"data": triggers}
@ -182,31 +130,12 @@ class AppTriggerEnableApi(Resource):
session.commit()
session.refresh(trigger)
if trigger.trigger_type == AppTriggerType.TRIGGER_PLUGIN.value:
plugin_icon = ""
with Session(db.engine) as session:
plugin_trigger = session.execute(
select(WorkflowPluginTrigger).where(
WorkflowPluginTrigger.app_id == app_model.id,
WorkflowPluginTrigger.node_id == trigger.node_id,
)
).scalar_one_or_none()
if plugin_trigger and current_user.current_tenant_id:
try:
controller = TriggerManager.get_trigger_provider(
current_user.current_tenant_id, TriggerProviderID(plugin_trigger.provider_id)
)
trigger.provider_id = plugin_trigger.provider_id # type: ignore[attr-defined]
trigger.subscription_id = plugin_trigger.subscription_id # type: ignore[attr-defined]
trigger.event_name = plugin_trigger.event_name # type: ignore[attr-defined]
trigger.plugin_id = controller.plugin_id # type: ignore[attr-defined]
trigger.plugin_unique_identifier = controller.plugin_unique_identifier # type: ignore[attr-defined]
plugin_icon = controller.to_api_entity().icon or ""
except Exception:
plugin_icon = ""
trigger.icon = plugin_icon # type: ignore[attr-defined]
# Add computed icon field
url_prefix = dify_config.CONSOLE_API_URL + "/console/api/workspaces/current/tool-provider/builtin/"
if trigger.trigger_type == "trigger-plugin":
trigger.icon = url_prefix + trigger.provider_name + "/icon" # type: ignore
else:
trigger.icon = "" # type: ignore[attr-defined]
trigger.icon = "" # type: ignore
return trigger

View File

@ -13,7 +13,6 @@ workflow_app_log_partial_fields = {
"created_by_account": fields.Nested(simple_account_fields, attribute="created_by_account", allow_null=True),
"created_by_end_user": fields.Nested(simple_end_user_fields, attribute="created_by_end_user", allow_null=True),
"created_at": TimestampField,
"trigger_info": fields.Raw(attribute="trigger_info"),
}

View File

@ -6,11 +6,6 @@ trigger_fields = {
"title": fields.String,
"node_id": fields.String,
"provider_name": fields.String,
"provider_id": fields.String,
"subscription_id": fields.String,
"event_name": fields.String,
"plugin_id": fields.String,
"plugin_unique_identifier": fields.String,
"icon": fields.String,
"status": fields.String,
"created_at": fields.DateTime(dt_format="iso8601"),

View File

@ -1,16 +1,12 @@
import json
import uuid
from datetime import datetime
from sqlalchemy import and_, func, or_, select
from sqlalchemy.orm import Session
from core.trigger.trigger_manager import TriggerManager
from core.workflow.enums import WorkflowExecutionStatus
from models import Account, App, EndUser, WorkflowAppLog, WorkflowRun
from models.enums import AppTriggerType, CreatorUserRole
from models.provider_ids import TriggerProviderID
from models.trigger import WorkflowPluginTrigger, WorkflowTriggerLog
from models.enums import CreatorUserRole
class WorkflowAppService:
@ -115,10 +111,6 @@ class WorkflowAppService:
# Execute query and get items
items = list(session.scalars(offset_stmt).all())
trigger_info_map = self._build_trigger_info_map(session, app_model, items)
for log in items:
log.trigger_info = trigger_info_map.get(log.workflow_run_id)
return {
"page": page,
"limit": limit,
@ -137,101 +129,3 @@ class WorkflowAppService:
return uuid.UUID(value)
except ValueError:
return None
def _build_trigger_info_map(self, session: Session, app_model: App, logs: list[WorkflowAppLog]) -> dict[str, dict]:
run_ids = [log.workflow_run_id for log in logs if log.workflow_run_id]
if not run_ids:
return {}
trigger_logs = (
session.execute(select(WorkflowTriggerLog).where(WorkflowTriggerLog.workflow_run_id.in_(run_ids)))
.scalars()
.all()
)
if not trigger_logs:
return {}
trigger_data_map: dict[str, dict] = {}
node_ids: set[str] = set()
for trigger_log in trigger_logs:
if not trigger_log.workflow_run_id:
continue
try:
trigger_data = json.loads(trigger_log.trigger_data)
except json.JSONDecodeError:
trigger_data = {}
node_id = trigger_data.get("root_node_id")
if node_id:
node_ids.add(node_id)
trigger_data_map[trigger_log.workflow_run_id] = {
"log": trigger_log,
"node_id": node_id,
}
plugin_trigger_map: dict[str, WorkflowPluginTrigger] = {}
if node_ids:
plugin_triggers = (
session.execute(
select(WorkflowPluginTrigger).where(
WorkflowPluginTrigger.app_id == app_model.id,
WorkflowPluginTrigger.node_id.in_(node_ids),
)
)
.scalars()
.all()
)
plugin_trigger_map = {plugin.node_id: plugin for plugin in plugin_triggers}
provider_cache: dict[str, dict[str, str]] = {}
def resolve_provider(provider_id: str) -> dict[str, str]:
if provider_id in provider_cache:
return provider_cache[provider_id]
metadata: dict[str, str] = {}
try:
controller = TriggerManager.get_trigger_provider(app_model.tenant_id, TriggerProviderID(provider_id))
api_entity = controller.to_api_entity()
metadata = {
"provider_name": api_entity.name,
"icon": api_entity.icon or "",
"plugin_id": controller.plugin_id,
"plugin_unique_identifier": controller.plugin_unique_identifier,
}
except Exception:
metadata = {}
provider_cache[provider_id] = metadata
return metadata
trigger_info_map: dict[str, dict] = {}
for run_id, context in trigger_data_map.items():
trigger_log = context["log"]
if isinstance(trigger_log.trigger_type, AppTriggerType):
trigger_type_value = trigger_log.trigger_type.value
else:
trigger_type_value = trigger_log.trigger_type
info = {
"type": trigger_type_value,
"node_id": context["node_id"],
"workflow_trigger_log_id": trigger_log.id,
}
if (
trigger_log.trigger_type == AppTriggerType.TRIGGER_PLUGIN # type: ignore[comparison-overlap]
and context["node_id"]
):
plugin_trigger = plugin_trigger_map.get(context["node_id"])
if plugin_trigger:
info.update(
{
"provider_id": plugin_trigger.provider_id,
"subscription_id": plugin_trigger.subscription_id,
"event_name": plugin_trigger.event_name,
}
)
provider_metadata = resolve_provider(plugin_trigger.provider_id)
if provider_metadata:
info.update(provider_metadata)
trigger_info_map[run_id] = info
return trigger_info_map

View File

@ -26,13 +26,7 @@ export type ITriggerCardProps = {
}
const getTriggerIcon = (trigger: AppTrigger, triggerPlugins: any[]) => {
const {
trigger_type,
status,
provider_name,
provider_id,
icon: triggerIconFromApi,
} = trigger
const { trigger_type, status, provider_name } = trigger
// Status dot styling based on trigger status
const getStatusDot = () => {
@ -64,18 +58,16 @@ const getTriggerIcon = (trigger: AppTrigger, triggerPlugins: any[]) => {
blockType = BlockEnum.TriggerWebhook
}
let triggerIcon: string | undefined = triggerIconFromApi
if (!triggerIcon && trigger_type === 'trigger-plugin') {
let triggerIcon: string | undefined
if (trigger_type === 'trigger-plugin' && provider_name) {
const targetTriggers = triggerPlugins || []
const identifiers = [provider_id, provider_name].filter(Boolean) as string[]
const foundTrigger = targetTriggers.find((triggerWithProvider) => {
return identifiers.some(identifier =>
canFindTool(triggerWithProvider.id, identifier)
|| triggerWithProvider.id.includes(identifier)
|| triggerWithProvider.name === identifier,
)
})
const foundTrigger = targetTriggers.find(triggerWithProvider =>
canFindTool(triggerWithProvider.id, provider_name)
|| triggerWithProvider.id.includes(provider_name)
|| triggerWithProvider.name === provider_name,
)
triggerIcon = foundTrigger?.icon
console.log('triggerIcon', triggerIcon)
}
return (

View File

@ -162,10 +162,7 @@ const WorkflowAppLogList: FC<ILogs> = ({ logs, appDetail, onRefresh }) => {
</td>
{isWorkflow && (
<td className='p-3 pr-2'>
<TriggerByDisplay
triggeredFrom={log.workflow_run.triggered_from || 'app-run'}
triggerInfo={log.trigger_info}
/>
<TriggerByDisplay triggeredFrom={log.workflow_run.triggered_from || 'app-run'} />
</td>
)}
</tr>

View File

@ -11,26 +11,11 @@ import {
} from '@/app/components/base/icons/src/vender/workflow'
import BlockIcon from '@/app/components/workflow/block-icon'
import { BlockEnum } from '@/app/components/workflow/types'
import type { TriggerInfo } from '@/models/log'
type TriggerByDisplayProps = {
triggeredFrom: string
className?: string
showText?: boolean
triggerInfo?: TriggerInfo
}
const resolveTriggerType = (value: string) => {
switch (value) {
case 'trigger-plugin':
return 'plugin'
case 'trigger-webhook':
return 'webhook'
case 'trigger-schedule':
return 'schedule'
default:
return value
}
}
const getTriggerDisplayName = (triggeredFrom: string, t: any) => {
@ -47,7 +32,7 @@ const getTriggerDisplayName = (triggeredFrom: string, t: any) => {
return nameMap[triggeredFrom] || triggeredFrom
}
const getTriggerIcon = (triggeredFrom: string, triggerInfo?: TriggerInfo) => {
const getTriggerIcon = (triggeredFrom: string) => {
switch (triggeredFrom) {
case 'webhook':
return (
@ -62,11 +47,12 @@ const getTriggerIcon = (triggeredFrom: string, triggerInfo?: TriggerInfo) => {
</div>
)
case 'plugin':
// For plugin triggers in logs, use a generic plugin icon since we don't have specific plugin info
// This matches the standard BlockIcon styling for TriggerPlugin
return (
<BlockIcon
type={BlockEnum.TriggerPlugin}
size="md"
toolIcon={triggerInfo?.icon}
/>
)
case 'debugging':
@ -97,13 +83,11 @@ const TriggerByDisplay: FC<TriggerByDisplayProps> = ({
triggeredFrom,
className = '',
showText = true,
triggerInfo,
}) => {
const { t } = useTranslation()
const resolvedType = resolveTriggerType(triggerInfo?.type || triggeredFrom)
const displayName = triggerInfo?.provider_name || getTriggerDisplayName(resolvedType, t)
const icon = getTriggerIcon(resolvedType, triggerInfo)
const displayName = getTriggerDisplayName(triggeredFrom, t)
const icon = getTriggerIcon(triggeredFrom)
return (
<div className={`flex items-center gap-1.5 ${className}`}>

View File

@ -242,19 +242,6 @@ export type WorkflowRunDetail = {
total_steps: number
finished_at: number
}
export type TriggerInfo = {
type: string
node_id?: string
workflow_trigger_log_id?: string
provider_id?: string
provider_name?: string
subscription_id?: string
event_name?: string
plugin_id?: string
plugin_unique_identifier?: string
icon?: string
}
export type AccountInfo = {
id: string
name: string
@ -275,7 +262,6 @@ export type WorkflowAppLogDetail = {
created_by_end_user?: EndUserInfo
created_at: number
read_at?: number
trigger_info?: TriggerInfo
}
export type WorkflowLogsResponse = {
data: Array<WorkflowAppLogDetail>

View File

@ -335,11 +335,6 @@ export type AppTrigger = {
title: string
node_id: string
provider_name: string
provider_id?: string
subscription_id?: string
plugin_id?: string
plugin_unique_identifier?: string
event_name?: string
icon: string
status: 'enabled' | 'disabled' | 'unauthorized'
created_at: string