From df6c1064c64a1e487b403d1578b99fadda19526c Mon Sep 17 00:00:00 2001 From: Yansong Zhang <916125788@qq.com> Date: Fri, 10 Apr 2026 16:00:16 +0800 Subject: [PATCH] fix(web): resolve all TypeScript errors in Agent V2 frontend - Fix toast API: use toast.success()/toast.error() instead of object - Fix panel: use native HTML elements instead of mismatched component APIs - Add BlockEnum.AgentV2 to block-icon map (icon + color) - Add BlockEnum.AgentV2 to use-last-run.ts form params maps - Add i18n keys: blocks.agent-v2, blocksAbout.agent-v2 (en + zh) - TypeScript: 0 errors Made-with: Cursor --- .../sandbox-provider-page/index.tsx | 12 +- web/app/components/workflow/block-icon.tsx | 2 + .../workflow-panel/last-run/use-last-run.ts | 2 + .../workflow/nodes/agent-v2/panel.tsx | 118 +++++++++--------- web/i18n/en-US/workflow.json | 2 + web/i18n/zh-Hans/workflow.json | 2 + 6 files changed, 70 insertions(+), 68 deletions(-) diff --git a/web/app/components/header/account-setting/sandbox-provider-page/index.tsx b/web/app/components/header/account-setting/sandbox-provider-page/index.tsx index c840eccb3f..c71142ce9b 100644 --- a/web/app/components/header/account-setting/sandbox-provider-page/index.tsx +++ b/web/app/components/header/account-setting/sandbox-provider-page/index.tsx @@ -76,12 +76,12 @@ export default function SandboxProviderPage() { setLoading(true) try { await saveSandboxProviderConfig(providerType, editConfig, true) - toast({ type: 'success', message: 'Saved and activated' }) + toast.success('Saved and activated') setEditingType(null) fetchProviders() } catch (e: any) { - toast({ type: 'error', message: e.message || 'Failed to save' }) + toast.error(e.message || 'Failed to save') } finally { setLoading(false) } } @@ -89,22 +89,22 @@ export default function SandboxProviderPage() { const handleDelete = async (providerType: string) => { try { await deleteSandboxProviderConfig(providerType) - toast({ type: 'success', message: 'Deleted' }) + toast.success('Deleted') fetchProviders() } catch (e: any) { - toast({ type: 'error', message: e.message || 'Failed to delete' }) + toast.error(e.message || 'Failed to delete') } } const handleActivate = async (providerType: string) => { try { await activateSandboxProvider(providerType) - toast({ type: 'success', message: 'Activated' }) + toast.success('Activated') fetchProviders() } catch (e: any) { - toast({ type: 'error', message: e.message || 'Failed to activate' }) + toast.error(e.message || 'Failed to activate') } } diff --git a/web/app/components/workflow/block-icon.tsx b/web/app/components/workflow/block-icon.tsx index 92227fa66e..01c26910b9 100644 --- a/web/app/components/workflow/block-icon.tsx +++ b/web/app/components/workflow/block-icon.tsx @@ -67,6 +67,7 @@ const DEFAULT_ICON_MAP: Record null, @@ -116,6 +117,7 @@ const ICON_CONTAINER_BG_COLOR_MAP: Record = { [BlockEnum.DocExtractor]: 'bg-util-colors-green-green-500', [BlockEnum.ListFilter]: 'bg-util-colors-cyan-cyan-500', [BlockEnum.Agent]: 'bg-util-colors-indigo-indigo-500', + [BlockEnum.AgentV2]: 'bg-util-colors-violet-violet-500', [BlockEnum.HumanInput]: 'bg-util-colors-cyan-cyan-500', [BlockEnum.KnowledgeBase]: 'bg-util-colors-warning-warning-500', [BlockEnum.DataSource]: 'bg-components-icon-bg-midnight-solid', diff --git a/web/app/components/workflow/nodes/_base/components/workflow-panel/last-run/use-last-run.ts b/web/app/components/workflow/nodes/_base/components/workflow-panel/last-run/use-last-run.ts index d58c787bd8..b708057f46 100644 --- a/web/app/components/workflow/nodes/_base/components/workflow-panel/last-run/use-last-run.ts +++ b/web/app/components/workflow/nodes/_base/components/workflow-panel/last-run/use-last-run.ts @@ -51,6 +51,7 @@ const singleRunFormParamsHooks: Record = { [BlockEnum.ParameterExtractor]: useParameterExtractorSingleRunFormParams, [BlockEnum.Iteration]: useIterationSingleRunFormParams, [BlockEnum.Agent]: useAgentSingleRunFormParams, + [BlockEnum.AgentV2]: undefined, [BlockEnum.DocExtractor]: useDocExtractorSingleRunFormParams, [BlockEnum.Loop]: useLoopSingleRunFormParams, [BlockEnum.Start]: useStartSingleRunFormParams, @@ -90,6 +91,7 @@ const getDataForCheckMoreHooks: Record = { [BlockEnum.ParameterExtractor]: undefined, [BlockEnum.Iteration]: undefined, [BlockEnum.Agent]: undefined, + [BlockEnum.AgentV2]: undefined, [BlockEnum.DocExtractor]: undefined, [BlockEnum.Loop]: undefined, [BlockEnum.Start]: undefined, diff --git a/web/app/components/workflow/nodes/agent-v2/panel.tsx b/web/app/components/workflow/nodes/agent-v2/panel.tsx index ff3e24d605..9279a8cd6d 100644 --- a/web/app/components/workflow/nodes/agent-v2/panel.tsx +++ b/web/app/components/workflow/nodes/agent-v2/panel.tsx @@ -3,24 +3,14 @@ import type { AgentV2NodeType } from './types' import type { NodePanelProps } from '@/app/components/workflow/types' import { memo, useCallback } from 'react' import { useTranslation } from 'react-i18next' -import { RiAddLine, RiDeleteBin7Line } from '@remixicon/react' -import Button from '@/app/components/base/button' -import Select from '@/app/components/base/select' -import Switch from '@/app/components/base/switch' import Field from '@/app/components/workflow/nodes/_base/components/field' import Split from '@/app/components/workflow/nodes/_base/components/split' -import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal' -import ConfigVision from '../_base/components/config-vision' -import MemoryConfig from '../_base/components/memory-config' -import Editor from '@/app/components/workflow/nodes/_base/components/prompt/editor' -import ConfigPrompt from '../llm/components/config-prompt' -import { useProviderContextSelector } from '@/context/provider-context' import { useNodeDataUpdate } from '../../hooks/use-node-data-update' const strategyOptions = [ - { value: 'auto', name: 'Auto (based on model capability)' }, - { value: 'function-calling', name: 'Function Calling' }, - { value: 'chain-of-thought', name: 'ReAct (Chain of Thought)' }, + { value: 'auto', label: 'Auto (based on model capability)' }, + { value: 'function-calling', label: 'Function Calling' }, + { value: 'chain-of-thought', label: 'ReAct (Chain of Thought)' }, ] const Panel: FC> = ({ id, data }) => { @@ -35,44 +25,28 @@ const Panel: FC> = ({ id, data }) => { return (
- {/* Model Selection */} + {/* Model */} - { - updateData({ - model: { - ...inputs.model, - provider: model.provider, - name: model.modelId, - mode: model.mode || 'chat', - completion_params: model.completionParams || {}, - }, - }) - }} - onCompletionParamsChange={(params) => { - updateData({ - model: { ...inputs.model, completion_params: params }, - }) - }} - /> +
+ {inputs.model?.name + ? `${inputs.model.provider?.split('/').pop()} / ${inputs.model.name}` + : 'Not configured'} +
- {/* Agent Strategy */} + {/* Strategy */} - updateData({ agent_strategy: e.target.value as any })} + > + {strategyOptions.map(opt => ( + + ))} + {/* Max Iterations */} @@ -81,9 +55,9 @@ const Panel: FC> = ({ id, data }) => { type="number" min={1} max={99} - className="w-full rounded-lg border border-components-input-border-active px-3 py-1.5 text-[13px]" + className="w-full rounded-lg border border-components-input-border-active bg-transparent px-3 py-1.5 text-[13px] text-text-secondary" value={inputs.max_iterations || 10} - onChange={(e) => updateData({ max_iterations: parseInt(e.target.value) || 10 })} + onChange={e => updateData({ max_iterations: parseInt(e.target.value) || 10 })} /> @@ -95,14 +69,15 @@ const Panel: FC> = ({ id, data }) => { {(inputs.tools || []).map((tool, idx) => (
- { + { const tools = [...(inputs.tools || [])] - tools[idx] = { ...tools[idx], enabled: v } + tools[idx] = { ...tools[idx], enabled: e.target.checked } updateData({ tools }) }} + className="h-4 w-4" /> {tool.tool_name}
@@ -111,7 +86,7 @@ const Panel: FC> = ({ id, data }) => { ))} {(inputs.tools || []).length === 0 && (
- No tools configured. Add tools from the workflow toolbar. + No tools configured
)}
@@ -121,21 +96,40 @@ const Panel: FC> = ({ id, data }) => { {/* Memory */} - updateData({ memory })} - /> +
+ Window Size + updateData({ + memory: { + role_prefix: inputs.memory?.role_prefix, + query_prompt_template: inputs.memory?.query_prompt_template, + window: { enabled: true, size: parseInt(e.target.value) || 50 }, + }, + })} + /> +
{/* Vision */} - updateData({ vision })} - /> +
+ Enable image understanding + updateData({ + vision: { ...inputs.vision, enabled: e.target.checked }, + })} + className="h-4 w-4" + /> +
) diff --git a/web/i18n/en-US/workflow.json b/web/i18n/en-US/workflow.json index 5c7df02791..d981845948 100644 --- a/web/i18n/en-US/workflow.json +++ b/web/i18n/en-US/workflow.json @@ -1,5 +1,6 @@ { "blocks.agent": "Agent", + "blocks.agent-v2": "Agent V2", "blocks.answer": "Answer", "blocks.assigner": "Variable Assigner", "blocks.code": "Code", @@ -31,6 +32,7 @@ "blocks.variable-aggregator": "Variable Aggregator", "blocks.variable-assigner": "Variable Aggregator", "blocksAbout.agent": "Invoking large language models to answer questions or process natural language", + "blocksAbout.agent-v2": "Next-gen agent with LLM, tools, sandbox execution, and configurable strategies", "blocksAbout.answer": "Define the reply content of a chat conversation", "blocksAbout.assigner": "The variable assignment node is used for assigning values to writable variables(like conversation variables).", "blocksAbout.code": "Execute a piece of Python or NodeJS code to implement custom logic", diff --git a/web/i18n/zh-Hans/workflow.json b/web/i18n/zh-Hans/workflow.json index e6fc7d9ba9..1663da7b31 100644 --- a/web/i18n/zh-Hans/workflow.json +++ b/web/i18n/zh-Hans/workflow.json @@ -1,5 +1,6 @@ { "blocks.agent": "Agent", + "blocks.agent-v2": "Agent V2", "blocks.answer": "直接回复", "blocks.assigner": "变量赋值", "blocks.code": "代码执行", @@ -31,6 +32,7 @@ "blocks.variable-aggregator": "变量聚合器", "blocks.variable-assigner": "变量赋值器", "blocksAbout.agent": "调用大型语言模型回答问题或处理自然语言", + "blocksAbout.agent-v2": "新一代 Agent,支持 LLM、工具调用、沙箱执行和可配置策略", "blocksAbout.answer": "定义一个聊天对话的回复内容", "blocksAbout.assigner": "变量赋值节点用于向可写入变量(例如会话变量)进行变量赋值。", "blocksAbout.code": "执行一段 Python 或 NodeJS 代码实现自定义逻辑",