diff --git a/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx b/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx index 62bd57c5d1..4a4d76f1d8 100644 --- a/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx +++ b/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx @@ -193,7 +193,7 @@ const SettingBuiltInTool: FC = ({ onClick={onHide} > - BACK + {t('plugin.detailPanel.operation.back')} )}
diff --git a/web/app/components/base/divider/index.tsx b/web/app/components/base/divider/index.tsx index 6fe16b95a2..387f24a5e9 100644 --- a/web/app/components/base/divider/index.tsx +++ b/web/app/components/base/divider/index.tsx @@ -29,7 +29,7 @@ export type DividerProps = { const Divider: FC = ({ type, bgStyle, className = '', style }) => { return ( -
+
) } diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index 18b0a4556d..ae82b1f55a 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -35,7 +35,7 @@ const PluginDetailPanel: FC = ({ useEffect(() => { setDetail(!detail ? undefined : { plugin_id: detail.plugin_id, - provider: `${detail.plugin_id}/${detail.declaration.trigger.identity.name}`, + provider: `${detail.plugin_id}/${detail.declaration.name}`, declaration: detail.declaration, name: detail.name, }) diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/store.ts b/web/app/components/plugins/plugin-detail-panel/subscription-list/store.ts index ccb18ce9a3..e197a124c7 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/store.ts +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/store.ts @@ -1,7 +1,7 @@ import { create } from 'zustand' import type { PluginDetail } from '../../types' -type SimpleDetail = Pick & { provider: string } +export type SimpleDetail = Pick & { provider: string } type Shape = { detail: SimpleDetail | undefined diff --git a/web/app/components/plugins/plugin-detail-panel/trigger/event-detail-drawer.tsx b/web/app/components/plugins/plugin-detail-panel/trigger/event-detail-drawer.tsx index c5abd616e0..e241fadb8a 100644 --- a/web/app/components/plugins/plugin-detail-panel/trigger/event-detail-drawer.tsx +++ b/web/app/components/plugins/plugin-detail-panel/trigger/event-detail-drawer.tsx @@ -1,5 +1,6 @@ 'use client' import ActionButton from '@/app/components/base/action-button' +import Divider from '@/app/components/base/divider' import Drawer from '@/app/components/base/drawer' import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks' import Icon from '@/app/components/plugins/card/base/card-icon' @@ -7,8 +8,7 @@ import Description from '@/app/components/plugins/card/base/description' import OrgInfo from '@/app/components/plugins/card/base/org-info' import { triggerEventParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema' import type { TriggerProviderApiEntity } from '@/app/components/workflow/block-selector/types' -import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars' -// import Split from '@/app/components/workflow/nodes/_base/components/split' +import Field from '@/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/show/field' import cn from '@/utils/classnames' import { RiArrowLeftLine, @@ -37,16 +37,48 @@ const getType = (type: string, t: TFunction) => { return type } +// Convert JSON Schema to StructuredOutput format +const convertSchemaToField = (schema: any): any => { + const field: any = { + type: Array.isArray(schema.type) ? schema.type[0] : schema.type || 'string', + } + + if (schema.description) + field.description = schema.description + + if (schema.properties) { + field.properties = Object.entries(schema.properties).reduce((acc, [key, value]: [string, any]) => ({ + ...acc, + [key]: convertSchemaToField(value), + }), {}) + } + + if (schema.required) + field.required = schema.required + + if (schema.items) + field.items = convertSchemaToField(schema.items) + + if (schema.enum) + field.enum = schema.enum + + return field +} + export const EventDetailDrawer: FC = (props) => { const { eventInfo, providerInfo, onClose } = props const language = useLanguage() const { t } = useTranslation() const parametersSchemas = triggerEventParametersToFormSchemas(eventInfo.parameters) - const outputVars = Object.entries(eventInfo.output_schema?.properties || {}).map(([name, schema]: [string, any]) => ({ - name, - type: schema.type || 'string', - description: schema.description || '', - })) + + // Convert output_schema properties to array for direct rendering + const outputFields = eventInfo.output_schema?.properties + ? Object.entries(eventInfo.output_schema.properties).map(([name, schema]: [string, any]) => ({ + name, + field: convertSchemaToField(schema), + required: eventInfo.output_schema.required?.includes(name) || false, + })) + : [] return ( = (props) => { onClick={onClose} > - BACK + {t('plugin.detailPanel.operation.back')}
@@ -82,45 +114,43 @@ export const EventDetailDrawer: FC = (props) => {
{eventInfo?.identity?.label[language]}
-
-
{t('tools.setBuiltInTools.parameters')}
-
- {parametersSchemas.length > 0 && ( -
- {parametersSchemas.map((item, index) => ( -
-
-
{item.label[language]}
-
- {getType(item.type, t)} -
- {item.required && ( -
{t('tools.setBuiltInTools.required')}
- )} -
- {item.description && ( -
- {item.description?.[language]} -
- )} +
+
{t('tools.setBuiltInTools.parameters')}
+ {parametersSchemas.length > 0 ? ( + parametersSchemas.map((item, index) => ( +
+
+
{item.label[language]}
+
+ {getType(item.type, t)}
- ))} + {item.required && ( +
{t('tools.setBuiltInTools.required')}
+ )} +
+ {item.description && ( +
+ {item.description?.[language]} +
+ )}
- )} + )) + ) :
{t('pluginTrigger.events.item.noParameters')}
} + +
+
{t('pluginTrigger.events.output')}
+
+ {outputFields.map(item => ( + + ))} +
- {/* */} -
{t('pluginTrigger.events.output')}
- - {outputVars.map(varItem => ( - - ))} -
) diff --git a/web/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/show/field.tsx b/web/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/show/field.tsx index 7862dc824c..62133f3212 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/show/field.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/show/field.tsx @@ -1,14 +1,14 @@ 'use client' +import cn from '@/utils/classnames' +import { RiArrowDropDownLine } from '@remixicon/react' +import { useBoolean } from 'ahooks' import type { FC } from 'react' import React from 'react' +import { useTranslation } from 'react-i18next' +import type { Field as FieldType } from '../../../../../llm/types' import { Type } from '../../../../../llm/types' import { getFieldType } from '../../../../../llm/utils' -import type { Field as FieldType } from '../../../../../llm/types' -import cn from '@/utils/classnames' import TreeIndentLine from '../tree-indent-line' -import { useTranslation } from 'react-i18next' -import { useBoolean } from 'ahooks' -import { RiArrowDropDownLine } from '@remixicon/react' type Props = { name: string, @@ -28,6 +28,7 @@ const Field: FC = ({ const { t } = useTranslation() const isRoot = depth === 1 const hasChildren = payload.type === Type.object && payload.properties + const hasEnum = payload.enum && payload.enum.length > 0 const [fold, { toggle: toggleFold, }] = useBoolean(false) @@ -44,7 +45,10 @@ const Field: FC = ({ /> )}
{name}
-
{getFieldType(payload)}{(payload.schemaType && payload.schemaType !== 'file' && ` (${payload.schemaType})`)}
+
+ {getFieldType(payload)} + {(payload.schemaType && payload.schemaType !== 'file' && ` (${payload.schemaType})`)} +
{required &&
{t('app.structOutput.required')}
}
{payload.description && ( @@ -52,6 +56,18 @@ const Field: FC = ({
{payload.description}
)} + {hasEnum && ( +
+
+ {payload.enum!.map((value, index) => ( + + {typeof value === 'string' ? `"${value}"` : value} + {index < payload.enum!.length - 1 && ' | '} + + ))} +
+
+ )}
diff --git a/web/app/components/workflow/nodes/llm/types.ts b/web/app/components/workflow/nodes/llm/types.ts index 987fb75fef..70dc4d9cc7 100644 --- a/web/app/components/workflow/nodes/llm/types.ts +++ b/web/app/components/workflow/nodes/llm/types.ts @@ -30,6 +30,7 @@ export enum Type { arrayNumber = 'array[number]', arrayObject = 'array[object]', file = 'file', + enumType = 'enum', } export enum ArrayType { diff --git a/web/app/components/workflow/nodes/llm/utils.ts b/web/app/components/workflow/nodes/llm/utils.ts index 10c287f86b..1652d511d0 100644 --- a/web/app/components/workflow/nodes/llm/utils.ts +++ b/web/app/components/workflow/nodes/llm/utils.ts @@ -9,8 +9,9 @@ export const checkNodeValid = (_payload: LLMNodeType) => { } export const getFieldType = (field: Field) => { - const { type, items } = field - if(field.schemaType === 'file') return Type.file + const { type, items, enum: enums } = field + if (field.schemaType === 'file') return Type.file + if (enums && enums.length > 0) return Type.enumType if (type !== Type.array || !items) return type diff --git a/web/i18n/en-US/plugin-trigger.ts b/web/i18n/en-US/plugin-trigger.ts index 0a19844125..3a5902a2c7 100644 --- a/web/i18n/en-US/plugin-trigger.ts +++ b/web/i18n/en-US/plugin-trigger.ts @@ -164,6 +164,7 @@ const translation = { actionNum: '{{num}} {{event}} INCLUDED', item: { parameters: '{{count}} parameters', + noParameters: 'No parameters', }, output: 'Output', }, diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 90086257a6..16b7bebd82 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -64,6 +64,7 @@ const translation = { checkUpdate: 'Check Update', viewDetail: 'View Detail', remove: 'Remove', + back: 'Back', }, actionNum: '{{num}} {{action}} INCLUDED', strategyNum: '{{num}} {{strategy}} INCLUDED', diff --git a/web/i18n/zh-Hans/plugin-trigger.ts b/web/i18n/zh-Hans/plugin-trigger.ts index c793f0572d..c4e6940bd2 100644 --- a/web/i18n/zh-Hans/plugin-trigger.ts +++ b/web/i18n/zh-Hans/plugin-trigger.ts @@ -164,6 +164,7 @@ const translation = { actionNum: '包含 {{num}} 个 {{event}}', item: { parameters: '{{count}}个参数', + noParameters: '暂无参数', }, output: '输出', }, diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 7539f8224d..db92e34485 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -64,6 +64,7 @@ const translation = { checkUpdate: '检查更新', viewDetail: '查看详情', remove: '移除', + back: '返回', }, actionNum: '包含 {{num}} 个 {{action}}', strategyNum: '包含 {{num}} 个 {{strategy}}', @@ -79,7 +80,7 @@ const translation = { endpointModalDesc: '完成配置后可使用插件 API 端点提供的功能', serviceOk: '服务正常', disabled: '停用', - modelNum: '{{num}} 模型已包含', + modelNum: '包含 {{num}} 个模型', toolSelector: { title: '添加工具', toolSetting: '工具设置',