Skip to content

Commit d5a7102

Browse files
Merge remote-tracking branch 'upstream/v2' into variable-assign-support-type-convert
2 parents 42f6c9b + d186bac commit d5a7102

File tree

76 files changed

+1169
-566
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1169
-566
lines changed

.github/workflows/build-and-push-python-pg.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
run: |
2626
DOCKER_IMAGE=ghcr.io/1panel-dev/maxkb-base
2727
DOCKER_PLATFORMS=${{ github.event.inputs.architecture }}
28-
TAG_NAME=python3.11-pg17.7-20260212
28+
TAG_NAME=python3.11-pg17.7-20260323
2929
DOCKER_IMAGE_TAGS="--tag ${DOCKER_IMAGE}:${TAG_NAME}"
3030
echo ::set-output name=docker_image::${DOCKER_IMAGE}
3131
echo ::set-output name=version::${TAG_NAME}

.github/workflows/build-and-push.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
inputs:
88
dockerImageTag:
99
description: 'Image Tag'
10-
default: 'v2.6.0-dev'
10+
default: 'v2.8.0-dev'
1111
required: true
1212
dockerImageTagWithLatest:
1313
description: '是否发布latest tag(正式发版时选择,测试版本切勿选择)'

apps/application/chat_pipeline/step/chat_step/impl/base_chat_step.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,8 @@ def _handle_mcp_request(self, mcp_source, mcp_servers, mcp_tool_ids, tool_ids,
242242
# 兼容老数据
243243
if not mcp_tool_ids:
244244
mcp_tool_ids = []
245-
if mcp_source == 'custom' and mcp_servers and '"stdio"' not in mcp_servers:
245+
if mcp_source == 'custom' and mcp_servers:
246+
ToolExecutor().validate_mcp_transport(mcp_servers)
246247
mcp_servers_config = json.loads(mcp_servers)
247248
elif mcp_tool_ids:
248249
mcp_tools = QuerySet(Tool).filter(id__in=mcp_tool_ids).values()

apps/application/flow/backend/sandbox_shell.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def execute(
6262
if _enable_sandbox:
6363
# 用 runuser 在子进程里切换用户,父进程凭据保持不变,
6464
# 避免父进程 ruid/euid 不一致导致 execve 报 Permission denied
65-
command = f"runuser -u {_run_user} -- env -i LD_PRELOAD=/opt/maxkb-app/sandbox/lib/sandbox.so PATH=${{PATH}} {command}"
65+
command = f"env -i LD_PRELOAD=/opt/maxkb-app/sandbox/lib/sandbox.so PATH=${{PATH}} gosu {_run_user} {command}"
6666
# command = f"runuser -u {_run_user} -- env -i PATH=${{PATH}} {command}"
6767

6868
# print(f"Executing command in sandbox: {command}")

apps/application/flow/step_node/ai_chat_step_node/impl/base_chat_node.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,8 @@ def _handle_mcp_request(self, mcp_source, mcp_servers, mcp_tool_id, mcp_tool_ids
248248
mcp_tool_ids = []
249249
if mcp_tool_id:
250250
mcp_tool_ids = list(set(mcp_tool_ids + [mcp_tool_id]))
251-
if mcp_source == 'custom' and mcp_servers and '"stdio"' not in mcp_servers:
251+
if mcp_source == 'custom' and mcp_servers:
252+
ToolExecutor().validate_mcp_transport(mcp_servers)
252253
mcp_servers_config = json.loads(mcp_servers)
253254
mcp_servers_config = self.handle_variables(mcp_servers_config)
254255
elif mcp_tool_ids:
Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,29 @@
11

22

3-
4-
5-
PROMPT_TEMPLATE = """
6-
# Role
7-
You are an intention classification expert, good at being able to judge which classification the user's input belongs to.
8-
9-
## Skills
10-
Skill 1: Clearly determine which of the following intention classifications the user's input belongs to.
11-
Intention classification list:
12-
{classification_list}
13-
14-
Note:
15-
- Please determine the match only between the user's input content and the Intention classification list content, without judging or categorizing the match with the classification ID.
16-
- **When classifying, you must give higher weight to the context and intent continuity shown in the historical conversation. Do not rely solely on the literal meaning of the current input; instead, prioritize the most consistent classification with the previous dialogue flow.**
17-
18-
## User Input
19-
{user_input}
20-
21-
## Reply requirements
22-
- The answer must be returned in JSON format.
23-
- Strictly ensure that the output is in a valid JSON format.
24-
- Do not add prefix ```json or suffix ```
25-
- The answer needs to include the following fields such as:
26-
{{
27-
"classificationId": 0,
28-
"reason": ""
29-
}}
30-
31-
## Limit
32-
- Please do not reply in text."""
3+
PROMPT_TEMPLATE = """# Role
4+
You are an intention classification expert, good at being able to judge which classification the user's input belongs to.
5+
6+
## Skills
7+
Skill 1: Clearly determine which of the following intention classifications the user's input belongs to.
8+
Intention classification list:
9+
{classification_list}
10+
11+
Note:
12+
- Please determine the match between the user's input content and the Intention classification list content, without judging or categorizing the match with the classification ID.
13+
- **When classifying, you must give higher weight to the context and intent continuity shown in the historical conversation. Do not rely solely on the literal meaning of the current input; instead, prioritize the most consistent classification with the previous dialogue flow.**
14+
15+
## User Input
16+
{user_input}
17+
18+
## Reply requirements
19+
- The answer must be returned in JSON format.
20+
- Strictly ensure that the output is in a valid JSON format.
21+
- Do not add prefix ```json or suffix ```
22+
- The answer needs to include the following fields such as:
23+
{{
24+
"classificationId": 0,
25+
"reason": ""
26+
}}
27+
28+
## Limit
29+
- Please do not reply in text."""

apps/application/flow/step_node/mcp_node/impl/base_mcp_node.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from application.flow.i_step_node import NodeResult
1010
from application.flow.step_node.mcp_node.i_mcp_node import IMcpNode
1111
from tools.models import Tool
12+
from common.utils.tool_code import ToolExecutor
1213

1314

1415
class BaseMcpNode(IMcpNode):
@@ -34,6 +35,7 @@ def execute(self, mcp_servers, mcp_server, mcp_tool, mcp_tool_id, mcp_source, to
3435
else:
3536
servers = json.loads(mcp_servers)
3637
servers = self.handle_variables(servers) # 处理servers中的变量
38+
ToolExecutor().validate_mcp_transport(json.dumps(servers))
3739
params = json.loads(json.dumps(tool_params))
3840
params = self.handle_variables(params)
3941

apps/application/flow/step_node/variable_aggregation_node/i_variable_aggregation_node.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
class VariableListSerializer(serializers.Serializer):
1313
v_id = serializers.CharField(required=True, label=_("Variable id"))
14+
key = serializers.CharField(required=False, label=_("Key"), allow_null=True, allow_blank=True, )
1415
variable = serializers.ListField(required=True, label=_("Variable"))
1516

1617

apps/application/flow/step_node/variable_aggregation_node/impl/base_variable_aggregation_node.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ def save_context(self, details, workflow_manage):
3131
self.context['exception_message'] = details.get('err_message')
3232

3333
def get_first_non_null(self, variable_list):
34-
3534
for variable in variable_list:
3635
v = self.workflow_manage.get_reference_field(
3736
variable.get('variable')[0],
@@ -40,12 +39,16 @@ def get_first_non_null(self, variable_list):
4039
return v
4140
return None
4241

43-
def set_variable_to_json(self, variable_list):
44-
42+
def set_variable_to_array(self, variable_list):
4543
return [self.workflow_manage.get_reference_field(
4644
variable.get('variable')[0],
4745
variable.get('variable')[1:]) for variable in variable_list]
4846

47+
def set_variable_to_dict(self, variable_list):
48+
return {(variable.get('key') or variable.get('variable')[-1]): self.workflow_manage.get_reference_field(
49+
variable.get('variable')[0],
50+
variable.get('variable')[1:]) for variable in variable_list}
51+
4952
def reset_variable(self, variable):
5053
value = self.workflow_manage.get_reference_field(
5154
variable.get('variable')[0],
@@ -65,9 +68,14 @@ def reset_group_list(self, group_list):
6568

6669
def execute(self, strategy, group_list, **kwargs) -> NodeResult:
6770
strategy_map = {'first_non_null': self.get_first_non_null,
68-
'variable_to_json': self.set_variable_to_json,
71+
'variable_to_array': self.set_variable_to_array,
72+
'variable_to_dict': self.set_variable_to_dict,
6973
}
7074

75+
# 向下兼容
76+
if strategy == 'variable_to_json':
77+
strategy = 'variable_to_array'
78+
7179
result = {item.get('field'): strategy_map[strategy](item.get('variable_list')) for item in group_list}
7280

7381
return NodeResult(

apps/application/flow/step_node/variable_splitting_node/impl/base_variable_splitting_node.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def save_context(self, details, workflow_manage):
4141
self.context['exception_message'] = details.get('err_message')
4242

4343
def execute(self, input_variable, variable_list, **kwargs) -> NodeResult:
44-
if type(input_variable).__name__ == "str":
44+
if isinstance(input_variable, str):
4545
try:
4646
input_variable = json.loads(input_variable)
4747
except Exception:

0 commit comments

Comments
 (0)