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 c64063e4d5..45597d3213 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,8 +13,7 @@ const i18nPrefix = 'nodes.llm.computerUse' type Props = { readonly: boolean - isDisabledByStructuredOutput?: boolean - disabled?: boolean + isDisabledByStructuredOutput: boolean disabledTip?: string enabled: boolean onChange: (enabled: boolean) => void @@ -26,7 +25,6 @@ type Props = { const ComputerUseConfig: FC = ({ readonly, isDisabledByStructuredOutput, - disabled, disabledTip, enabled, onChange, @@ -35,8 +33,7 @@ const ComputerUseConfig: FC = ({ promptTemplateKey, }) => { const { t } = useTranslation() - const disabledByStructuredOutput = isDisabledByStructuredOutput ?? disabled ?? false - const isDisabled = readonly || disabledByStructuredOutput + const isDisabled = readonly || isDisabledByStructuredOutput return (
@@ -76,7 +73,7 @@ const ComputerUseConfig: FC = ({
= ({ readonly, isDisabledByStructuredOutput, isComputerUseEnabled, - disabledByStructuredOutput, - computerUseEnabled, nodeId, toolSettings, promptTemplateKey, }) => { - const resolvedIsComputerUseEnabled = isComputerUseEnabled ?? computerUseEnabled ?? false - const resolvedIsDisabledByStructuredOutput = isDisabledByStructuredOutput ?? disabledByStructuredOutput ?? false - const isReferenceToolsDisabled = readonly || !resolvedIsComputerUseEnabled || resolvedIsDisabledByStructuredOutput + const isReferenceToolsDisabled = readonly || !isComputerUseEnabled || isDisabledByStructuredOutput const { i18n, t } = useTranslation() const { handleNodeDataUpdate } = useNodeCurdKit(nodeId) const { theme } = useTheme() 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 index 310750457d..60923cd151 100644 --- 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 @@ -2,6 +2,7 @@ import type { LLMNodeType } from './types' import type { ToolDependency } from './use-node-skills' import { useMemo } from 'react' import { useTranslation } from 'react-i18next' +import { getToolTokenListRegexString, getToolTokenRegexString } from '@/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/utils' type Params = { inputs: LLMNodeType @@ -17,8 +18,31 @@ export const useStructuredOutputMutualExclusion = ({ toolDependencies, }: Params) => { const { t } = useTranslation() + const toolTokenRegex = useMemo(() => new RegExp(getToolTokenRegexString()), []) + const toolTokenListRegex = useMemo(() => new RegExp(getToolTokenListRegexString()), []) + const hasToolTokensInText = useMemo(() => { + return (value?: string) => { + if (!value) + return false + return toolTokenRegex.test(value) || toolTokenListRegex.test(value) + } + }, [toolTokenListRegex, toolTokenRegex]) + const hasToolTokensInPrompt = useMemo(() => { + const template = inputs.prompt_template + const check = hasToolTokensInText + if (Array.isArray(template)) { + return template.some((item) => { + if ('text' in item && check(item.text)) + return true + if ('jinja2_text' in item && check(item.jinja2_text)) + return true + return false + }) + } + return check(template.text) || check(template.jinja2_text) + }, [hasToolTokensInText, inputs.prompt_template]) const isStructuredOutputEnabled = !!inputs.structured_output_enabled - const hasToolDependencies = isSupportSandbox && toolDependencies.length > 0 + const hasToolDependencies = isSupportSandbox && (toolDependencies.length > 0 || hasToolTokensInPrompt) const hasEnabledTools = (inputs.tools?.length ?? 0) > 0 const hasToolConflict = !!inputs.computer_use || hasToolDependencies || hasEnabledTools