mirror of
https://github.com/langgenius/dify.git
synced 2026-05-10 05:56:31 +08:00
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
This commit is contained in:
parent
f4e04fc872
commit
df6c1064c6
@ -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')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -67,6 +67,7 @@ const DEFAULT_ICON_MAP: Record<BlockEnum, React.ComponentType<{ className: strin
|
||||
[BlockEnum.DocExtractor]: DocsExtractor,
|
||||
[BlockEnum.ListFilter]: ListFilter,
|
||||
[BlockEnum.Agent]: Agent,
|
||||
[BlockEnum.AgentV2]: Agent,
|
||||
[BlockEnum.KnowledgeBase]: KnowledgeBase,
|
||||
[BlockEnum.DataSource]: Datasource,
|
||||
[BlockEnum.DataSourceEmpty]: () => null,
|
||||
@ -116,6 +117,7 @@ const ICON_CONTAINER_BG_COLOR_MAP: Record<string, string> = {
|
||||
[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',
|
||||
|
||||
@ -51,6 +51,7 @@ const singleRunFormParamsHooks: Record<BlockEnum, any> = {
|
||||
[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, any> = {
|
||||
[BlockEnum.ParameterExtractor]: undefined,
|
||||
[BlockEnum.Iteration]: undefined,
|
||||
[BlockEnum.Agent]: undefined,
|
||||
[BlockEnum.AgentV2]: undefined,
|
||||
[BlockEnum.DocExtractor]: undefined,
|
||||
[BlockEnum.Loop]: undefined,
|
||||
[BlockEnum.Start]: undefined,
|
||||
|
||||
@ -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<NodePanelProps<AgentV2NodeType>> = ({ id, data }) => {
|
||||
@ -35,44 +25,28 @@ const Panel: FC<NodePanelProps<AgentV2NodeType>> = ({ id, data }) => {
|
||||
|
||||
return (
|
||||
<div className="space-y-4 px-4 pb-4 pt-2">
|
||||
{/* Model Selection */}
|
||||
{/* Model */}
|
||||
<Field title={t('workflow.nodes.llm.model')}>
|
||||
<ModelParameterModal
|
||||
popupProps={{ disabled: false }}
|
||||
isInWorkflow
|
||||
isAdvancedMode
|
||||
mode={inputs.model?.mode || 'chat'}
|
||||
provider={inputs.model?.provider || ''}
|
||||
completionParams={inputs.model?.completion_params || {}}
|
||||
modelId={inputs.model?.name || ''}
|
||||
setModel={(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 },
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<div className="rounded-lg border border-divider-subtle px-3 py-2 text-[13px] text-text-secondary">
|
||||
{inputs.model?.name
|
||||
? `${inputs.model.provider?.split('/').pop()} / ${inputs.model.name}`
|
||||
: 'Not configured'}
|
||||
</div>
|
||||
</Field>
|
||||
|
||||
<Split />
|
||||
|
||||
{/* Agent Strategy */}
|
||||
{/* Strategy */}
|
||||
<Field title="Agent Strategy">
|
||||
<Select
|
||||
items={strategyOptions}
|
||||
defaultValue={inputs.agent_strategy || 'auto'}
|
||||
onSelect={(item) => updateData({ agent_strategy: item.value as any })}
|
||||
/>
|
||||
<select
|
||||
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.agent_strategy || 'auto'}
|
||||
onChange={e => updateData({ agent_strategy: e.target.value as any })}
|
||||
>
|
||||
{strategyOptions.map(opt => (
|
||||
<option key={opt.value} value={opt.value}>{opt.label}</option>
|
||||
))}
|
||||
</select>
|
||||
</Field>
|
||||
|
||||
{/* Max Iterations */}
|
||||
@ -81,9 +55,9 @@ const Panel: FC<NodePanelProps<AgentV2NodeType>> = ({ 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 })}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
@ -95,14 +69,15 @@ const Panel: FC<NodePanelProps<AgentV2NodeType>> = ({ id, data }) => {
|
||||
{(inputs.tools || []).map((tool, idx) => (
|
||||
<div key={idx} className="flex items-center justify-between rounded-lg border border-divider-subtle px-3 py-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Switch
|
||||
size="sm"
|
||||
defaultValue={tool.enabled}
|
||||
onChange={(v) => {
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={tool.enabled}
|
||||
onChange={e => {
|
||||
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"
|
||||
/>
|
||||
<span className="text-[13px] text-text-secondary">{tool.tool_name}</span>
|
||||
</div>
|
||||
@ -111,7 +86,7 @@ const Panel: FC<NodePanelProps<AgentV2NodeType>> = ({ id, data }) => {
|
||||
))}
|
||||
{(inputs.tools || []).length === 0 && (
|
||||
<div className="py-3 text-center text-[13px] text-text-quaternary">
|
||||
No tools configured. Add tools from the workflow toolbar.
|
||||
No tools configured
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -121,21 +96,40 @@ const Panel: FC<NodePanelProps<AgentV2NodeType>> = ({ id, data }) => {
|
||||
|
||||
{/* Memory */}
|
||||
<Field title="Memory">
|
||||
<MemoryConfig
|
||||
readonly={false}
|
||||
config={inputs.memory || { window: { enabled: true, size: 50 } }}
|
||||
onChange={(memory) => updateData({ memory })}
|
||||
/>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-[13px] text-text-secondary">Window Size</span>
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
max={200}
|
||||
className="w-20 rounded-lg border border-components-input-border-active bg-transparent px-2 py-1 text-center text-[13px] text-text-secondary"
|
||||
value={inputs.memory?.window?.size || 50}
|
||||
onChange={e => 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 },
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
</Field>
|
||||
|
||||
<Split />
|
||||
|
||||
{/* Vision */}
|
||||
<Field title="Vision">
|
||||
<ConfigVision
|
||||
payload={inputs.vision}
|
||||
onChange={(vision) => updateData({ vision })}
|
||||
/>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-[13px] text-text-secondary">Enable image understanding</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={inputs.vision?.enabled || false}
|
||||
onChange={e => updateData({
|
||||
vision: { ...inputs.vision, enabled: e.target.checked },
|
||||
})}
|
||||
className="h-4 w-4"
|
||||
/>
|
||||
</div>
|
||||
</Field>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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 代码实现自定义逻辑",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user