From 9bd714623e7324bb408444b7525eb91a25429427 Mon Sep 17 00:00:00 2001 From: zhsama Date: Wed, 4 Feb 2026 22:28:26 +0800 Subject: [PATCH] feat: Add mutual exclusion between structured output and tools in LLM node --- .../components/base/prompt-editor/index.tsx | 77 +++++++++++-------- .../nodes/_base/components/prompt/editor.tsx | 3 + .../llm/components/computer-use-config.tsx | 28 +++++-- .../llm/components/config-prompt-item.tsx | 3 + .../nodes/llm/components/config-prompt.tsx | 4 + .../llm/components/reference-tool-config.tsx | 64 +++++---------- .../nodes/llm/components/tools/index.tsx | 49 ++++++++---- .../components/workflow/nodes/llm/panel.tsx | 48 ++++++++++-- .../workflow/nodes/llm/use-node-skills.ts | 63 +++++++++++++++ .../use-structured-output-mutual-exclusion.ts | 59 ++++++++++++++ web/i18n/en-US/app.json | 2 + web/i18n/en-US/common.json | 1 + web/i18n/en-US/workflow.json | 2 + web/i18n/ja-JP/app.json | 2 + web/i18n/ja-JP/common.json | 2 + web/i18n/ja-JP/workflow.json | 2 + web/i18n/zh-Hans/app.json | 2 + web/i18n/zh-Hans/common.json | 1 + web/i18n/zh-Hans/workflow.json | 2 + web/i18n/zh-Hant/app.json | 2 + web/i18n/zh-Hant/common.json | 1 + web/i18n/zh-Hant/workflow.json | 2 + 22 files changed, 314 insertions(+), 105 deletions(-) create mode 100644 web/app/components/workflow/nodes/llm/use-node-skills.ts create mode 100644 web/app/components/workflow/nodes/llm/use-structured-output-mutual-exclusion.ts diff --git a/web/app/components/base/prompt-editor/index.tsx b/web/app/components/base/prompt-editor/index.tsx index d5212d5942..1ad380bd8d 100644 --- a/web/app/components/base/prompt-editor/index.tsx +++ b/web/app/components/base/prompt-editor/index.tsx @@ -151,6 +151,7 @@ export type PromptEditorProps = { agentBlock?: AgentBlockType isSupportFileVar?: boolean isSupportSandbox?: boolean + disableToolBlocks?: boolean } const PromptEditor: FC = ({ @@ -180,6 +181,7 @@ const PromptEditor: FC = ({ agentBlock, isSupportFileVar, isSupportSandbox, + disableToolBlocks, }) => { const { eventEmitter } = useEventEmitterContextContext() const initialConfig = { @@ -239,36 +241,49 @@ const PromptEditor: FC = ({ } }, [onToolMetadataChange, toolMetadata]) - const sandboxPlaceHolder = React.useMemo( - () => { - return isSupportSandbox && ( - , - , - , - , - ]} - /> - ) - }, - - [isSupportSandbox], - ) + const sandboxPlaceHolder = React.useMemo(() => { + if (!isSupportSandbox) + return null + const i18nKey = disableToolBlocks + ? 'promptEditor.placeholderSandboxNoTools' + : 'promptEditor.placeholderSandbox' + const components = disableToolBlocks + ? [ + , + , + ] + : [ + , + , + , + , + ] + return ( + + ) + }, [disableToolBlocks, isSupportSandbox]) return ( @@ -332,7 +347,7 @@ const PromptEditor: FC = ({ - {editable && } + {editable && !disableToolBlocks && } )} void onFocus?: () => void + disableToolBlocks?: boolean } const Editor: FC = ({ @@ -129,6 +130,7 @@ const Editor: FC = ({ required, onBlur, onFocus, + disableToolBlocks, }) => { const { t } = useTranslation() const { eventEmitter } = useEventEmitterContextContext() @@ -312,6 +314,7 @@ const Editor: FC = ({ editable={!readOnly} isSupportFileVar={isSupportFileVar} isSupportSandbox={isSupportSandbox} + disableToolBlocks={disableToolBlocks} toolMetadata={promptMetadata} onToolMetadataChange={onPromptMetadataChange} /> diff --git a/web/app/components/workflow/nodes/llm/components/computer-use-config.tsx b/web/app/components/workflow/nodes/llm/components/computer-use-config.tsx index 7ddad20c73..c64063e4d5 100644 --- a/web/app/components/workflow/nodes/llm/components/computer-use-config.tsx +++ b/web/app/components/workflow/nodes/llm/components/computer-use-config.tsx @@ -13,6 +13,9 @@ const i18nPrefix = 'nodes.llm.computerUse' type Props = { readonly: boolean + isDisabledByStructuredOutput?: boolean + disabled?: boolean + disabledTip?: string enabled: boolean onChange: (enabled: boolean) => void nodeId: string @@ -22,6 +25,9 @@ type Props = { const ComputerUseConfig: FC = ({ readonly, + isDisabledByStructuredOutput, + disabled, + disabledTip, enabled, onChange, nodeId, @@ -29,6 +35,8 @@ const ComputerUseConfig: FC = ({ promptTemplateKey, }) => { const { t } = useTranslation() + const disabledByStructuredOutput = isDisabledByStructuredOutput ?? disabled ?? false + const isDisabled = readonly || disabledByStructuredOutput return (
@@ -46,12 +54,17 @@ const ComputerUseConfig: FC = ({ noXSpacing operations={(
- + + +
)} > @@ -63,7 +76,8 @@ const ComputerUseConfig: FC = ({
void + disableToolBlocks?: boolean } const roleOptions = [ @@ -88,6 +89,7 @@ const ConfigPromptItem: FC = ({ modelConfig, isSupportSandbox, onPromptEditorBlur, + disableToolBlocks, }) => { const { t } = useTranslation() const workflowStore = useWorkflowStore() @@ -158,6 +160,7 @@ const ConfigPromptItem: FC = ({ handleAddVariable={handleAddVariable} isSupportFileVar isSupportSandbox={isSupportSandbox} + disableToolBlocks={disableToolBlocks} onBlur={onPromptEditorBlur} /> ) diff --git a/web/app/components/workflow/nodes/llm/components/config-prompt.tsx b/web/app/components/workflow/nodes/llm/components/config-prompt.tsx index 36c6b763c1..523dd779e1 100644 --- a/web/app/components/workflow/nodes/llm/components/config-prompt.tsx +++ b/web/app/components/workflow/nodes/llm/components/config-prompt.tsx @@ -66,6 +66,7 @@ type Props = { handleAddVariable: (payload: any) => void modelConfig: ModelConfig onPromptEditorBlur?: () => void + disableToolBlocks?: boolean } const ConfigPrompt: FC = ({ @@ -82,6 +83,7 @@ const ConfigPrompt: FC = ({ handleAddVariable, modelConfig, onPromptEditorBlur, + disableToolBlocks, }) => { const { t } = useTranslation() const workflowStore = useWorkflowStore() @@ -361,6 +363,7 @@ const ConfigPrompt: FC = ({ modelConfig={modelConfig} isSupportSandbox={isSupportSandbox} onPromptEditorBlur={onPromptEditorBlur} + disableToolBlocks={disableToolBlocks} /> ) @@ -438,6 +441,7 @@ const ConfigPrompt: FC = ({ modelConfig={modelConfig} isSupportSandbox={isSupportSandbox} onBlur={onPromptEditorBlur} + disableToolBlocks={disableToolBlocks} /> )} diff --git a/web/app/components/workflow/nodes/llm/components/reference-tool-config.tsx b/web/app/components/workflow/nodes/llm/components/reference-tool-config.tsx index cb5471127d..f71c6225f8 100644 --- a/web/app/components/workflow/nodes/llm/components/reference-tool-config.tsx +++ b/web/app/components/workflow/nodes/llm/components/reference-tool-config.tsx @@ -1,40 +1,36 @@ 'use client' import type { FC } from 'react' import type { LLMNodeType, ToolSetting } from '../types' +import type { ToolDependency } from '@/app/components/workflow/nodes/llm/use-node-skills' import type { ToolWithProvider } from '@/app/components/workflow/types' import type { Locale } from '@/i18n-config/language' -import { useQuery } from '@tanstack/react-query' import * as React from 'react' import { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' -import { useStore as useAppStore } from '@/app/components/app/store' import AppIcon from '@/app/components/base/app-icon' import { DefaultToolIcon } from '@/app/components/base/icons/src/public/other' import { ArrowDownRoundFill } from '@/app/components/base/icons/src/vender/solid/general' import { SkeletonRectangle, SkeletonRow } from '@/app/components/base/skeleton' import Switch from '@/app/components/base/switch' import { useNodeCurdKit } from '@/app/components/workflow/nodes/_base/hooks/use-node-crud' +import { useNodeSkills } from '@/app/components/workflow/nodes/llm/use-node-skills' import useTheme from '@/hooks/use-theme' import { getLanguage } from '@/i18n-config/language' -import { consoleClient, consoleQuery } from '@/service/client' import { useAllBuiltInTools, useAllCustomTools, useAllMCPTools, useAllWorkflowTools } from '@/service/use-tools' import { cn } from '@/utils/classnames' import { getIconFromMarketPlace } from '@/utils/get-icon' type ReferenceToolConfigProps = { readonly: boolean - enabled: boolean + isDisabledByStructuredOutput?: boolean + isComputerUseEnabled?: boolean + disabledByStructuredOutput?: boolean + computerUseEnabled?: boolean nodeId: string toolSettings?: ToolSetting[] promptTemplateKey: string } -type ToolDependency = { - type: string - provider: string - tool_name: string -} - type ToolProviderGroup = { id: string actions: ToolDependency[] @@ -42,14 +38,18 @@ type ToolProviderGroup = { const ReferenceToolConfig: FC = ({ readonly, - enabled, + isDisabledByStructuredOutput, + isComputerUseEnabled, + disabledByStructuredOutput, + computerUseEnabled, nodeId, toolSettings, promptTemplateKey, }) => { - const isDisabled = readonly || !enabled + const resolvedIsComputerUseEnabled = isComputerUseEnabled ?? computerUseEnabled ?? false + const resolvedIsDisabledByStructuredOutput = isDisabledByStructuredOutput ?? disabledByStructuredOutput ?? false + const isReferenceToolsDisabled = readonly || !resolvedIsComputerUseEnabled || resolvedIsDisabledByStructuredOutput const { i18n, t } = useTranslation() - const appId = useAppStore(s => s.appDetail?.id) const { handleNodeDataUpdate } = useNodeCurdKit(nodeId) const { theme } = useTheme() const { data: buildInTools } = useAllBuiltInTools() @@ -58,34 +58,11 @@ const ReferenceToolConfig: FC = ({ const { data: mcpTools } = useAllMCPTools() const locale = useMemo(() => getLanguage(i18n.language as Locale), [i18n.language]) - const queryKey = useMemo(() => { - return [ - ...consoleQuery.workflowDraft.nodeSkills.queryKey({ - input: { - params: { - appId: appId ?? '', - nodeId, - }, - }, - }), - promptTemplateKey, - ] - }, [appId, nodeId, promptTemplateKey]) - - const { data, isLoading } = useQuery({ - queryKey, - queryFn: () => consoleClient.workflowDraft.nodeSkills({ - params: { - appId: appId ?? '', - nodeId, - }, - }), - enabled: !!appId && !!nodeId, - placeholderData: previous => previous, + const { toolDependencies, isLoading, isQueryEnabled, hasData } = useNodeSkills({ + nodeId, + promptTemplateKey, }) - const toolDependencies = useMemo(() => data?.tool_dependencies ?? [], [data?.tool_dependencies]) - const providers = useMemo(() => { const map = new Map() toolDependencies.forEach((tool) => { @@ -214,8 +191,7 @@ const ReferenceToolConfig: FC = ({ })) }, []) - const isQueryEnabled = !!appId && !!nodeId - const isInitialLoading = isQueryEnabled && isLoading && !data + const isInitialLoading = isQueryEnabled && isLoading && !hasData const showNoData = !isInitialLoading && providers.length === 0 const renderProviderIcon = useCallback((providerId: string) => { @@ -244,7 +220,7 @@ const ReferenceToolConfig: FC = ({ }, [iconErrorMap, providerIcons]) return ( -
+
{isInitialLoading && [0, 1].map(index => (
= ({ key={`${action.type}-${action.provider}-${action.tool_name}`} className={cn( 'relative flex h-7 items-center justify-between rounded-md pl-9 pr-2', - !isDisabled && 'hover:bg-state-base-hover', + !isReferenceToolsDisabled && 'hover:bg-state-base-hover', )} >
@@ -307,7 +283,7 @@ const ReferenceToolConfig: FC = ({
handleToolEnabledChange(action, value)} /> diff --git a/web/app/components/workflow/nodes/llm/components/tools/index.tsx b/web/app/components/workflow/nodes/llm/components/tools/index.tsx index 285eab86a9..8ad9b0fa1e 100644 --- a/web/app/components/workflow/nodes/llm/components/tools/index.tsx +++ b/web/app/components/workflow/nodes/llm/components/tools/index.tsx @@ -1,8 +1,10 @@ import type { ToolValue } from '@/app/components/workflow/block-selector/types' import { memo } from 'react' import { useTranslation } from 'react-i18next' +import Tooltip from '@/app/components/base/tooltip' import MultipleToolSelector from '@/app/components/plugins/plugin-detail-panel/multiple-tool-selector' import { BoxGroup } from '@/app/components/workflow/nodes/_base/components/layout' +import { cn } from '@/utils/classnames' import MaxIterations from './max-iterations' import { useNodeTools } from './use-node-tools' @@ -11,14 +13,19 @@ type ToolsProps = { tools?: ToolValue[] maxIterations?: number hideMaxIterations?: boolean + disabled?: boolean + disabledTip?: string } const Tools = ({ nodeId, tools = [], maxIterations = 10, hideMaxIterations = false, + disabled, + disabledTip, }: ToolsProps) => { const { t } = useTranslation() + const isDisabled = !!disabled const { handleToolsChange, handleMaxIterationsChange, @@ -34,22 +41,32 @@ const Tools = ({ className: 'px-0', }} > - - {!hideMaxIterations && ( - - )} + +
+
+ + {!hideMaxIterations && ( + + )} +
+
+
) } diff --git a/web/app/components/workflow/nodes/llm/panel.tsx b/web/app/components/workflow/nodes/llm/panel.tsx index 9ccb02088f..cbb7e979ef 100644 --- a/web/app/components/workflow/nodes/llm/panel.tsx +++ b/web/app/components/workflow/nodes/llm/panel.tsx @@ -29,6 +29,8 @@ import Tools from './components/tools' import MaxIterations from './components/tools/max-iterations' import { useNodeTools } from './components/tools/use-node-tools' import useConfig from './use-config' +import { useNodeSkills } from './use-node-skills' +import { useStructuredOutputMutualExclusion } from './use-structured-output-mutual-exclusion' const i18nPrefix = 'nodes.llm' @@ -91,6 +93,27 @@ const Panel: FC> = ({ scheduleSkillsRefresh(promptTemplateKey) }, [promptTemplateKey, scheduleSkillsRefresh]) + const { toolDependencies } = useNodeSkills({ + nodeId: id, + promptTemplateKey: skillsRefreshKey, + enabled: isSupportSandbox, + }) + + const { + isStructuredOutputBlocked, + isComputerUseBlocked, + isToolsBlocked, + disableToolBlocks, + structuredOutputDisabledTip, + computerUseDisabledTip, + toolsDisabledTip, + } = useStructuredOutputMutualExclusion({ + inputs, + readOnly, + isSupportSandbox, + toolDependencies, + }) + const { handleMaxIterationsChange, } = useNodeTools(id) @@ -162,6 +185,7 @@ const Panel: FC> = ({ handleAddVariable={handleAddVariable} modelConfig={model} onPromptEditorBlur={handlePromptEditorBlur} + disableToolBlocks={disableToolBlocks} /> )} @@ -248,6 +272,8 @@ const Panel: FC> = ({ <> > = ({ tools={inputs.tools} maxIterations={inputs.max_iterations} hideMaxIterations + disabled={isToolsBlocked} + disabledTip={toolsDisabledTip} /> )}
@@ -364,13 +392,19 @@ const Panel: FC> = ({
- + +
+ +
+
)} > diff --git a/web/app/components/workflow/nodes/llm/use-node-skills.ts b/web/app/components/workflow/nodes/llm/use-node-skills.ts new file mode 100644 index 0000000000..6247339d62 --- /dev/null +++ b/web/app/components/workflow/nodes/llm/use-node-skills.ts @@ -0,0 +1,63 @@ +'use client' + +import { useQuery } from '@tanstack/react-query' +import { useMemo } from 'react' +import { useStore as useAppStore } from '@/app/components/app/store' +import { consoleClient, consoleQuery } from '@/service/client' + +export type ToolDependency = { + type: string + provider: string + tool_name: string +} + +type UseNodeSkillsParams = { + nodeId: string + promptTemplateKey: string + enabled?: boolean +} + +export function useNodeSkills({ nodeId, promptTemplateKey, enabled = true }: UseNodeSkillsParams) { + const appId = useAppStore(s => s.appDetail?.id) + const isQueryEnabled = enabled && !!appId && !!nodeId + + const queryKey = useMemo(() => { + return [ + ...consoleQuery.workflowDraft.nodeSkills.queryKey({ + input: { + params: { + appId: appId ?? '', + nodeId, + }, + }, + }), + promptTemplateKey, + ] + }, [appId, nodeId, promptTemplateKey]) + + const { data, isLoading } = useQuery({ + queryKey, + queryFn: () => consoleClient.workflowDraft.nodeSkills({ + params: { + appId: appId ?? '', + nodeId, + }, + }), + enabled: isQueryEnabled, + placeholderData: previous => previous, + }) + + const toolDependencies = useMemo( + () => data?.tool_dependencies ?? [], + [data?.tool_dependencies], + ) + + const hasData = !!data + + return { + toolDependencies, + isLoading, + isQueryEnabled, + hasData, + } +} diff --git a/web/app/components/workflow/nodes/llm/use-structured-output-mutual-exclusion.ts b/web/app/components/workflow/nodes/llm/use-structured-output-mutual-exclusion.ts new file mode 100644 index 0000000000..310750457d --- /dev/null +++ b/web/app/components/workflow/nodes/llm/use-structured-output-mutual-exclusion.ts @@ -0,0 +1,59 @@ +import type { LLMNodeType } from './types' +import type { ToolDependency } from './use-node-skills' +import { useMemo } from 'react' +import { useTranslation } from 'react-i18next' + +type Params = { + inputs: LLMNodeType + readOnly: boolean + isSupportSandbox: boolean + toolDependencies: ToolDependency[] +} + +export const useStructuredOutputMutualExclusion = ({ + inputs, + readOnly, + isSupportSandbox, + toolDependencies, +}: Params) => { + const { t } = useTranslation() + const isStructuredOutputEnabled = !!inputs.structured_output_enabled + const hasToolDependencies = isSupportSandbox && toolDependencies.length > 0 + const hasEnabledTools = (inputs.tools?.length ?? 0) > 0 + const hasToolConflict = !!inputs.computer_use || hasToolDependencies || hasEnabledTools + + const isStructuredOutputBlocked = readOnly || (hasToolConflict && !isStructuredOutputEnabled) + const isComputerUseBlocked = readOnly || (isStructuredOutputEnabled && !inputs.computer_use) + const isToolsBlocked = readOnly || isStructuredOutputEnabled + const disableToolBlocks = isStructuredOutputEnabled + + const structuredOutputDisabledTip = useMemo(() => { + if (readOnly || !isStructuredOutputBlocked) + return '' + return inputs.computer_use + ? t('structOutput.disabledByComputerUse', { ns: 'app' }) + : t('structOutput.disabledByTools', { ns: 'app' }) + }, [inputs.computer_use, isStructuredOutputBlocked, readOnly, t]) + + const computerUseDisabledTip = useMemo(() => { + if (readOnly || !isComputerUseBlocked) + return '' + return t('nodes.llm.computerUse.disabledByStructuredOutput', { ns: 'workflow' }) + }, [isComputerUseBlocked, readOnly, t]) + + const toolsDisabledTip = useMemo(() => { + if (readOnly || !isToolsBlocked) + return '' + return t('nodes.llm.tools.disabledByStructuredOutput', { ns: 'workflow' }) + }, [isToolsBlocked, readOnly, t]) + + return { + isStructuredOutputBlocked, + isComputerUseBlocked, + isToolsBlocked, + disableToolBlocks, + structuredOutputDisabledTip, + computerUseDisabledTip, + toolsDisabledTip, + } +} diff --git a/web/i18n/en-US/app.json b/web/i18n/en-US/app.json index 0167e6aad7..8dfae19f77 100644 --- a/web/i18n/en-US/app.json +++ b/web/i18n/en-US/app.json @@ -210,6 +210,8 @@ "showMyCreatedAppsOnly": "Created by me", "structOutput.LLMResponse": "LLM Response", "structOutput.configure": "Configure", + "structOutput.disabledByComputerUse": "Structured Output is disabled when Computer Use is enabled.", + "structOutput.disabledByTools": "Structured Output is disabled when tools are enabled.", "structOutput.modelNotSupported": "Model not supported", "structOutput.modelNotSupportedTip": "The current model does not support this feature and is automatically downgraded to prompt injection.", "structOutput.moreFillTip": "Showing max 10 levels of nesting", diff --git a/web/i18n/en-US/common.json b/web/i18n/en-US/common.json index b5cd71c064..0b8f316ae4 100644 --- a/web/i18n/en-US/common.json +++ b/web/i18n/en-US/common.json @@ -510,6 +510,7 @@ "promptEditor.history.modal.user": "Hello", "promptEditor.placeholder": "Write your prompt word here, enter '{' to insert a variable, enter '/' to insert a prompt content block", "promptEditor.placeholderSandbox": "Write instructions here, <0>/ <1>insert, <2>@ <3>tools", + "promptEditor.placeholderSandboxNoTools": "Write instructions here, <0>/ <1>insert", "promptEditor.query.item.desc": "Insert user query template", "promptEditor.query.item.title": "Query", "promptEditor.skillMarkdown.placeholderPrefix": "Type to write,", diff --git a/web/i18n/en-US/workflow.json b/web/i18n/en-US/workflow.json index 666d7d8507..20e3bb089c 100644 --- a/web/i18n/en-US/workflow.json +++ b/web/i18n/en-US/workflow.json @@ -673,6 +673,7 @@ "nodes.llm.addContext": "Add Context", "nodes.llm.addMessage": "Add Message", "nodes.llm.advancedSettings": "Advanced Settings", + "nodes.llm.computerUse.disabledByStructuredOutput": "Computer Use is disabled when Structured Output is enabled.", "nodes.llm.computerUse.referenceTools": "Reference Tools", "nodes.llm.computerUse.referenceToolsEmpty": "Tools referenced in the prompt will appear here", "nodes.llm.computerUse.title": "Computer Use", @@ -727,6 +728,7 @@ "nodes.llm.roleDescription.user": "Provide instructions, queries, or any text-based input to the model", "nodes.llm.singleRun.variable": "Variable", "nodes.llm.sysQueryInUser": "sys.query in user message is required", + "nodes.llm.tools.disabledByStructuredOutput": "Tools are disabled when Structured Output is enabled.", "nodes.llm.tools.title": "Tools", "nodes.llm.variables": "variables", "nodes.llm.vision": "vision", diff --git a/web/i18n/ja-JP/app.json b/web/i18n/ja-JP/app.json index 8cbfda3295..f795866c43 100644 --- a/web/i18n/ja-JP/app.json +++ b/web/i18n/ja-JP/app.json @@ -207,6 +207,8 @@ "showMyCreatedAppsOnly": "自分が作成したアプリ", "structOutput.LLMResponse": "LLM のレスポンス", "structOutput.configure": "設定", + "structOutput.disabledByComputerUse": "Computer Use を有効にすると、構造化出力は無効になります。", + "structOutput.disabledByTools": "ツールを有効にすると、構造化出力は無効になります。", "structOutput.modelNotSupported": "モデルが対応していません", "structOutput.modelNotSupportedTip": "現在のモデルはこの機能に対応しておらず、自動的にプロンプトインジェクションに切り替わります。", "structOutput.moreFillTip": "最大 10 レベルのネストを表示します", diff --git a/web/i18n/ja-JP/common.json b/web/i18n/ja-JP/common.json index 060e3d501d..fa2c68a0f7 100644 --- a/web/i18n/ja-JP/common.json +++ b/web/i18n/ja-JP/common.json @@ -509,6 +509,8 @@ "promptEditor.history.modal.title": "例", "promptEditor.history.modal.user": "こんにちは", "promptEditor.placeholder": "ここにプロンプトワードを入力してください。変数を挿入するには「{」を、プロンプトコンテンツブロックを挿入するには「/」を入力します。", + "promptEditor.placeholderSandbox": "ここに指示を書いて、<0>/ <1>挿入、<2>@ <3>ツール", + "promptEditor.placeholderSandboxNoTools": "ここに指示を書いて、<0>/ <1>挿入", "promptEditor.query.item.desc": "ユーザークエリテンプレートを挿入", "promptEditor.query.item.title": "クエリ", "promptEditor.variable.item.desc": "変数&外部ツールを挿入", diff --git a/web/i18n/ja-JP/workflow.json b/web/i18n/ja-JP/workflow.json index 04340e1d78..dbf0a4f341 100644 --- a/web/i18n/ja-JP/workflow.json +++ b/web/i18n/ja-JP/workflow.json @@ -648,6 +648,7 @@ "nodes.listFilter.selectVariableKeyPlaceholder": "サブ変数キーを選択する", "nodes.llm.addContext": "コンテキスト追加", "nodes.llm.addMessage": "メッセージ追加", + "nodes.llm.computerUse.disabledByStructuredOutput": "構造化出力を有効にすると、コンピュータ使用は無効になります。", "nodes.llm.context": "コンテキスト", "nodes.llm.contextBlock": "コンテキストブロック", "nodes.llm.contextMissing": "ノード「{{nodeName}}」のコンテキストがありません。コンテキスト変数を選択してください。", @@ -697,6 +698,7 @@ "nodes.llm.roleDescription.user": "指示/質問を入力", "nodes.llm.singleRun.variable": "変数", "nodes.llm.sysQueryInUser": "ユーザーメッセージに sys.query を含めてください", + "nodes.llm.tools.disabledByStructuredOutput": "構造化出力を有効にすると、ツールは無効になります。", "nodes.llm.variables": "変数", "nodes.llm.vision": "ビジョン", "nodes.loop.ErrorMethod.continueOnError": "エラーを無視して継続", diff --git a/web/i18n/zh-Hans/app.json b/web/i18n/zh-Hans/app.json index 05a5507f24..e0f8da54c3 100644 --- a/web/i18n/zh-Hans/app.json +++ b/web/i18n/zh-Hans/app.json @@ -208,6 +208,8 @@ "showMyCreatedAppsOnly": "我创建的", "structOutput.LLMResponse": "LLM 的响应", "structOutput.configure": "配置", + "structOutput.disabledByComputerUse": "启用计算机使用时,将禁用结构化输出。", + "structOutput.disabledByTools": "启用工具时,将禁用结构化输出。", "structOutput.modelNotSupported": "模型不支持", "structOutput.modelNotSupportedTip": "当前模型不支持此功能,将自动降级为提示注入。", "structOutput.moreFillTip": "最多显示 10 级嵌套", diff --git a/web/i18n/zh-Hans/common.json b/web/i18n/zh-Hans/common.json index f64bc8593e..5f0a3967cf 100644 --- a/web/i18n/zh-Hans/common.json +++ b/web/i18n/zh-Hans/common.json @@ -510,6 +510,7 @@ "promptEditor.history.modal.user": "你好", "promptEditor.placeholder": "在这里写你的提示词,输入'{' 插入变量、输入'/' 插入提示内容块", "promptEditor.placeholderSandbox": "在这里写你的指令,<0>/ <1>插入,<2>@ <3>工具", + "promptEditor.placeholderSandboxNoTools": "在这里写你的指令,<0>/ <1>插入", "promptEditor.query.item.desc": "插入用户查询模板", "promptEditor.query.item.title": "查询内容", "promptEditor.skillMarkdown.placeholderPrefix": "输入", diff --git a/web/i18n/zh-Hans/workflow.json b/web/i18n/zh-Hans/workflow.json index 012b746183..1c2c7fe20d 100644 --- a/web/i18n/zh-Hans/workflow.json +++ b/web/i18n/zh-Hans/workflow.json @@ -666,6 +666,7 @@ "nodes.listFilter.selectVariableKeyPlaceholder": "选择子变量的 Key", "nodes.llm.addContext": "添加上下文", "nodes.llm.addMessage": "添加消息", + "nodes.llm.computerUse.disabledByStructuredOutput": "启用结构化输出时,将禁用计算机使用。", "nodes.llm.computerUse.referenceTools": "引用工具", "nodes.llm.computerUse.referenceToolsEmpty": "提示词中引用的工具会显示在这里", "nodes.llm.computerUse.title": "计算机使用", @@ -720,6 +721,7 @@ "nodes.llm.roleDescription.user": "向模型提供指令、查询或任何基于文本的输入", "nodes.llm.singleRun.variable": "变量", "nodes.llm.sysQueryInUser": "user message 中必须包含 sys.query", + "nodes.llm.tools.disabledByStructuredOutput": "启用结构化输出时,将禁用工具。", "nodes.llm.variables": "变量", "nodes.llm.vision": "视觉", "nodes.loop.ErrorMethod.continueOnError": "忽略错误并继续", diff --git a/web/i18n/zh-Hant/app.json b/web/i18n/zh-Hant/app.json index 371650e803..ce32463307 100644 --- a/web/i18n/zh-Hant/app.json +++ b/web/i18n/zh-Hant/app.json @@ -201,6 +201,8 @@ "showMyCreatedAppsOnly": "我建立的", "structOutput.LLMResponse": "LLM 回應", "structOutput.configure": "配置", + "structOutput.disabledByComputerUse": "啟用電腦使用時,將停用結構化輸出。", + "structOutput.disabledByTools": "啟用工具時,將停用結構化輸出。", "structOutput.modelNotSupported": "模型不支持", "structOutput.modelNotSupportedTip": "當前模型不支持此功能,並自動降級為提示注入。", "structOutput.moreFillTip": "顯示最多 10 層的嵌套", diff --git a/web/i18n/zh-Hant/common.json b/web/i18n/zh-Hant/common.json index a3d688babb..df029ed358 100644 --- a/web/i18n/zh-Hant/common.json +++ b/web/i18n/zh-Hant/common.json @@ -510,6 +510,7 @@ "promptEditor.history.modal.user": "你好", "promptEditor.placeholder": "在這裡寫你的提示詞,輸入'{' 插入變數、輸入'/' 插入提示內容塊", "promptEditor.placeholderSandbox": "在這裡寫你的指令,<0>/ <1>插入,<2>@ <3>工具", + "promptEditor.placeholderSandboxNoTools": "在這裡寫你的指令,<0>/ <1>插入", "promptEditor.query.item.desc": "插入使用者查詢模板", "promptEditor.query.item.title": "查詢內容", "promptEditor.skillMarkdown.placeholderPrefix": "輸入", diff --git a/web/i18n/zh-Hant/workflow.json b/web/i18n/zh-Hant/workflow.json index 841f932549..0b0cf26cf0 100644 --- a/web/i18n/zh-Hant/workflow.json +++ b/web/i18n/zh-Hant/workflow.json @@ -648,6 +648,7 @@ "nodes.listFilter.selectVariableKeyPlaceholder": "Select sub variable key(選擇子變數鍵)", "nodes.llm.addContext": "新增上下文", "nodes.llm.addMessage": "新增消息", + "nodes.llm.computerUse.disabledByStructuredOutput": "啟用結構化輸出時,將停用電腦使用。", "nodes.llm.computerUse.referenceToolsEmpty": "提示詞中引用的工具會顯示在這裡", "nodes.llm.context": "上下文", "nodes.llm.contextBlock": "上下文區塊", @@ -698,6 +699,7 @@ "nodes.llm.roleDescription.user": "向模型提供指令、查詢或任何基於文本的輸入", "nodes.llm.singleRun.variable": "變數", "nodes.llm.sysQueryInUser": "user message 中必須包含 sys.query", + "nodes.llm.tools.disabledByStructuredOutput": "啟用結構化輸出時,將停用工具。", "nodes.llm.variables": "變數", "nodes.llm.vision": "視覺", "nodes.loop.ErrorMethod.continueOnError": "繼續出錯",