Skip to content

Commit 5e95b97

Browse files
temp
1 parent 63e05b9 commit 5e95b97

File tree

3 files changed

+51
-8
lines changed

3 files changed

+51
-8
lines changed

backend/service/mcp_client.py

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Author: ai-business-hql [email protected]
33
Date: 2025-06-16 16:50:17
44
LastEditors: ai-business-hql [email protected]
5-
LastEditTime: 2025-11-17 15:09:44
5+
LastEditTime: 2025-11-18 19:18:30
66
FilePath: /comfyui_copilot/backend/service/mcp-client.py
77
Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
88
'''
@@ -63,6 +63,51 @@ async def comfyui_agent_invoke(messages: List[Dict[str, Any]], images: List[Imag
6363
tuple: (text, ext) where text is accumulated text and ext is structured data
6464
"""
6565
try:
66+
# ------------------------------------------------------------------
67+
# Sanitize messages to avoid provider validation errors
68+
# Some backends (e.g. Bedrock via ConverseStream) reject requests if
69+
# the final assistant message content ends with trailing whitespace.
70+
# We defensively strip only *trailing* whitespace from assistant text
71+
# segments, preserving internal spaces and formatting.
72+
# ------------------------------------------------------------------
73+
def _strip_trailing_whitespace_from_messages(
74+
msgs: List[Dict[str, Any]]
75+
) -> List[Dict[str, Any]]:
76+
cleaned: List[Dict[str, Any]] = []
77+
for msg in msgs:
78+
role = msg.get("role")
79+
# Only touch assistant messages to minimize impact
80+
if role != "assistant":
81+
cleaned.append(msg)
82+
continue
83+
84+
msg_copy = dict(msg)
85+
content = msg_copy.get("content")
86+
87+
# Simple string content
88+
if isinstance(content, str):
89+
msg_copy["content"] = content.rstrip()
90+
# OpenAI / Agents style list content blocks
91+
elif isinstance(content, list):
92+
new_content = []
93+
for part in content:
94+
if isinstance(part, dict):
95+
part_copy = dict(part)
96+
# Common text block key is "text"
97+
text_val = part_copy.get("text")
98+
if isinstance(text_val, str):
99+
part_copy["text"] = text_val.rstrip()
100+
new_content.append(part_copy)
101+
else:
102+
new_content.append(part)
103+
msg_copy["content"] = new_content
104+
105+
cleaned.append(msg_copy)
106+
107+
return cleaned
108+
109+
messages = _strip_trailing_whitespace_from_messages(messages)
110+
66111
# Get session_id and config from request context
67112
session_id = get_session_id()
68113
config = get_config()
@@ -141,9 +186,7 @@ async def on_handoff(ctx: RunContextWrapper[None], input_data: HandoffRewriteDat
141186
- If you cannot find the information needed to answer a query, consider using bing_search to obtain relevant information. For example, if search_node tool cannot find the node, you can use bing_search to obtain relevant information about those nodes or components.
142187
- If search_node tool cannot find the node, you MUST use bing_search to obtain relevant information about those nodes or components.
143188
144-
- **DEBUG Intent** - When the user's intent is to debug workflow execution problems, runtime errors, or troubleshoot failed workflows (keywords: "debug", "调试", "工作流报错", "执行失败", "workflow failed", "node error", "runtime error", "不能运行", "出错了"), respond with: "Please click the 🪲 button in the bottom right corner to trigger debug"
145-
146-
- **WORKFLOW REWRITE Intent** - [Critical!] When the user's intent is to functionally modify, enhance, or add NEW features to the current workflow OR modify the current canvas (keywords: "修改当前工作流", "更新工作流", "在当前工作流中添加", "添加功能", "enhance current workflow", "modify workflow", "add to current workflow", "update current workflow", "添加LoRA", "加个upscale", "add upscaling", "修改当前画布", "更新画布", "在画布中", "modify current canvas", "update canvas", "change canvas"), you MUST handoff to the Workflow Rewrite Agent immediately. This is for feature enhancements, not error fixes.
189+
- [Critical!] **WORKFLOW REWRITE Intent** - When the user's intent is to functionally modify, enhance, or add NEW features to the current workflow OR modify the current canvas (keywords: "修改当前工作流", "更新工作流", "在当前工作流中添加", "添加功能", "enhance current workflow", "modify workflow", "add to current workflow", "update current workflow", "添加LoRA", "加个upscale", "add upscaling", "修改当前画布", "更新画布", "在画布中", "modify current canvas", "update canvas", "change canvas"), you MUST always handoff to the Workflow Rewrite Agent immediately.
147190
148191
- **ERROR MESSAGE ANALYSIS** - When a user pastes specific error text/logs (containing terms like "Failed", "Error", "Traceback", or stack traces), prioritize providing troubleshooting help rather than invoking search tools. Follow these steps:
149192
1. Analyze the error to identify the root cause (error type, affected component, missing dependencies, etc.)

backend/service/workflow_rewrite_agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def create_workflow_rewrite_agent():
8787
8888
**Tool Usage Guidelines:**
8989
- get_current_workflow(): Get current workflow from checkpoint or session
90-
- search_node(node_class, keywords, limit): 优先使用的节点检索工具
90+
- search_node_local(node_class, keywords, limit): 优先使用的本地已经安装好的节点的检索工具
9191
* 当你已经有候选节点类名(例如从其它工具返回的 class_name,如 "LayerColor: BrightnessContrastV2")时,将该类名作为 node_class 传入,keywords 传入与功能相关的少量关键词(如 ["brightness", "contrast"]),工具会先通过 /api/object_info/{node_class} 精确获取该节点的完整定义,如果命中则直接返回该节点信息。
9292
* 当你只有功能/参数描述而没有明确类名时,可以将 node_class 置为空字符串 "",仅在 keywords 中传入 1~3 个尽量具体的英文或中文关键词(例如 "brightness"、"contrast"、"saturation"、"锐化" 等),工具会在所有节点中按名称、显示名、分类及输入参数名进行模糊搜索,返回带有 class_name、hit_params 和 score 的候选列表。
9393
* 避免在 keywords 中使用过于宽泛的词(例如 "image"、"图像" 等),否则会导致搜索结果过多且不精确。
@@ -110,7 +110,7 @@ def create_workflow_rewrite_agent():
110110
111111
始终以用户的实际需求为导向,提供专业、准确、高效的工作流改写服务。
112112
""",
113-
tools=[get_rewrite_expert_by_name, get_current_workflow, search_node, get_node_infos, update_workflow, remove_node],
113+
tools=[get_rewrite_expert_by_name, get_current_workflow, search_node_local, get_node_infos, update_workflow, remove_node],
114114
config={
115115
"max_tokens": 8192,
116116
** config

backend/service/workflow_rewrite_tools.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ async def get_node_infos(node_class_list: list[str]) -> str:
110110
return json.dumps({"error": f"Failed to get node infos of {','.join(node_class_list)}: {str(e)}"})
111111

112112
@function_tool
113-
async def search_node(node_class: str = "", keywords: list[str] = None, limit: int = 10) -> str:
113+
async def search_node_local(node_class: str = "", keywords: list[str] = None, limit: int = 10) -> str:
114114
"""
115-
综合节点搜索工具(node_class + keywords 联合检索):
115+
节点的搜索工具(node_class + keywords 联合检索):
116116
1. 优先使用 node_class 按节点类名精确查询。
117117
2. 如果没有命中,则在全部节点中使用 node_class 和 keywords 做联合模糊搜索:
118118
- 关键词会在节点类名、名称、显示名、分类、描述以及输入参数名中匹配。

0 commit comments

Comments
 (0)