diff --git a/api/core/tools/entities/tool_entities.py b/api/core/tools/entities/tool_entities.py
index b8eae600d1..83e69d063d 100644
--- a/api/core/tools/entities/tool_entities.py
+++ b/api/core/tools/entities/tool_entities.py
@@ -185,7 +185,7 @@ class ToolInvokeMessage(BaseModel):
"""
plain text, image url or link url
"""
- message: JsonMessage | TextMessage | BlobMessage | VariableMessage | FileMessage | LogMessage | None
+ message: JsonMessage | TextMessage | BlobMessage | LogMessage | FileMessage | None | VariableMessage
meta: dict[str, Any] | None = None
@field_validator("message", mode="before")
diff --git a/api/core/workflow/nodes/agent/agent_node.py b/api/core/workflow/nodes/agent/agent_node.py
index db84624961..d50c858fff 100644
--- a/api/core/workflow/nodes/agent/agent_node.py
+++ b/api/core/workflow/nodes/agent/agent_node.py
@@ -8,12 +8,12 @@ from core.model_manager import ModelManager
from core.model_runtime.entities.model_entities import ModelType
from core.plugin.manager.exc import PluginDaemonClientSideError
from core.plugin.manager.plugin import PluginInstallationManager
-from core.tools.entities.tool_entities import ToolProviderType
+from core.tools.entities.tool_entities import ToolParameter, ToolProviderType
from core.tools.tool_manager import ToolManager
from core.workflow.entities.node_entities import NodeRunResult
from core.workflow.entities.variable_pool import VariablePool
from core.workflow.enums import SystemVariableKey
-from core.workflow.nodes.agent.entities import AgentNodeData
+from core.workflow.nodes.agent.entities import AgentNodeData, ParamsAutoGenerated
from core.workflow.nodes.base.entities import BaseNodeData
from core.workflow.nodes.enums import NodeType
from core.workflow.nodes.event.event import RunCompletedEvent
@@ -156,16 +156,38 @@ class AgentNode(ToolNode):
value = cast(list[dict[str, Any]], value)
value = [tool for tool in value if tool.get("enabled", False)]
+ for tool in value:
+ if "schemas" in tool:
+ tool.pop("schemas")
+ parameters = tool.get("parameters", {})
+ if all(isinstance(v, dict) for _, v in parameters.items()):
+ params = {}
+ for key, param in parameters.items():
+ if param.get("auto", ParamsAutoGenerated.OPEN.value) == ParamsAutoGenerated.CLOSE.value:
+ value_param = param.get("value", {})
+ params[key] = value_param.get("value", "") if value_param is not None else None
+ else:
+ params[key] = None
+ parameters = params
+ tool["settings"] = {k: v.get("value", None) for k, v in tool.get("settings", {}).items()}
+ tool["parameters"] = parameters
+
if not for_log:
if parameter.type == "array[tools]":
value = cast(list[dict[str, Any]], value)
tool_value = []
for tool in value:
+ provider_type = ToolProviderType(tool.get("type", ToolProviderType.BUILT_IN.value))
+ setting_params = tool.get("settings", {})
+ parameters = tool.get("parameters", {})
+ manual_input_params = [key for key, value in parameters.items() if value is not None]
+
+ parameters = {**parameters, **setting_params}
entity = AgentToolEntity(
provider_id=tool.get("provider_name", ""),
- provider_type=ToolProviderType.BUILT_IN,
+ provider_type=provider_type,
tool_name=tool.get("tool_name", ""),
- tool_parameters=tool.get("parameters", {}),
+ tool_parameters=parameters,
plugin_unique_identifier=tool.get("plugin_unique_identifier", None),
)
@@ -178,11 +200,26 @@ class AgentNode(ToolNode):
tool_runtime.entity.description.llm = (
extra.get("descrption", "") or tool_runtime.entity.description.llm
)
-
+ for tool_runtime_params in tool_runtime.entity.parameters:
+ tool_runtime_params.form = (
+ ToolParameter.ToolParameterForm.FORM
+ if tool_runtime_params.name in manual_input_params
+ else tool_runtime_params.form
+ )
+ manual_input_value = {}
+ if tool_runtime.entity.parameters:
+ manual_input_value = {
+ key: value for key, value in parameters.items() if key in manual_input_params
+ }
+ runtime_parameters = {
+ **tool_runtime.runtime.runtime_parameters,
+ **manual_input_value,
+ }
tool_value.append(
{
**tool_runtime.entity.model_dump(mode="json"),
- "runtime_parameters": tool_runtime.runtime.runtime_parameters,
+ "runtime_parameters": runtime_parameters,
+ "provider_type": provider_type.value,
}
)
value = tool_value
diff --git a/api/core/workflow/nodes/agent/entities.py b/api/core/workflow/nodes/agent/entities.py
index 066dcd5666..a10cee69bd 100644
--- a/api/core/workflow/nodes/agent/entities.py
+++ b/api/core/workflow/nodes/agent/entities.py
@@ -1,3 +1,4 @@
+from enum import Enum
from typing import Any, Literal, Union
from pydantic import BaseModel
@@ -16,3 +17,8 @@ class AgentNodeData(BaseNodeData):
type: Literal["mixed", "variable", "constant"]
agent_parameters: dict[str, AgentInput]
+
+
+class ParamsAutoGenerated(Enum):
+ CLOSE = 0
+ OPEN = 1
diff --git a/docker/nginx/conf.d/default.conf.template b/docker/nginx/conf.d/default.conf.template
index a24219ed40..a458412d1e 100644
--- a/docker/nginx/conf.d/default.conf.template
+++ b/docker/nginx/conf.d/default.conf.template
@@ -29,7 +29,7 @@ server {
include proxy.conf;
}
- location /e {
+ location /e/ {
proxy_pass http://plugin_daemon:5002;
proxy_set_header Dify-Hook-Url $scheme://$host$request_uri;
include proxy.conf;
diff --git a/web/app/components/base/markdown.tsx b/web/app/components/base/markdown.tsx
index 1a4358c8bc..2b58b932a4 100644
--- a/web/app/components/base/markdown.tsx
+++ b/web/app/components/base/markdown.tsx
@@ -211,7 +211,9 @@ const Paragraph = (paragraph: any) => {
return (
<>
{paragraph.children.slice(1)}
+ { + Array.isArray(paragraph.children) ?{paragraph.children.slice(1)}
: null + } > ) } diff --git a/web/service/_tools_util.spec.ts b/web/service/_tools_util.spec.ts new file mode 100644 index 0000000000..f06e5a1e34 --- /dev/null +++ b/web/service/_tools_util.spec.ts @@ -0,0 +1,16 @@ +import { buildProviderQuery } from './_tools_util' + +describe('makeProviderQuery', () => { + test('collectionName without special chars', () => { + expect(buildProviderQuery('ABC')).toBe('provider=ABC') + }) + test('should escape &', () => { + expect(buildProviderQuery('ABC&DEF')).toBe('provider=ABC%26DEF') + }) + test('should escape /', () => { + expect(buildProviderQuery('ABC/DEF')).toBe('provider=ABC%2FDEF') + }) + test('should escape ?', () => { + expect(buildProviderQuery('ABC?DEF')).toBe('provider=ABC%3FDEF') + }) +}) diff --git a/web/service/_tools_util.ts b/web/service/_tools_util.ts new file mode 100644 index 0000000000..89dede8163 --- /dev/null +++ b/web/service/_tools_util.ts @@ -0,0 +1,5 @@ +export const buildProviderQuery = (collectionName: string): string => { + const query = new URLSearchParams() + query.set('provider', collectionName) + return query.toString() +} diff --git a/web/service/tools.ts b/web/service/tools.ts index d6b2f2034b..38dcf382e6 100644 --- a/web/service/tools.ts +++ b/web/service/tools.ts @@ -10,6 +10,7 @@ import type { } from '@/app/components/tools/types' import type { ToolWithProvider } from '@/app/components/workflow/types' import type { Label } from '@/app/components/tools/labels/constant' +import { buildProviderQuery } from './_tools_util' export const fetchCollectionList = () => { return get