myagent-ai 1.14.1 → 1.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/main_agent.py +47 -18
- package/core/output_parser.py +422 -393
- package/memory/manager.py +8 -4
- package/package.json +1 -1
- package/web/api_server.py +9 -4
- package/web/ui/chat/chat.css +2 -21
- package/web/ui/chat/chat_main.js +100 -25
package/agents/main_agent.py
CHANGED
|
@@ -6,6 +6,7 @@ agents/main_agent.py - 主 Agent
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
import asyncio
|
|
9
|
+
import re
|
|
9
10
|
from typing import Any, Callable, Dict, List, Optional
|
|
10
11
|
|
|
11
12
|
from core.logger import get_logger
|
|
@@ -442,6 +443,8 @@ class MainAgent(BaseAgent):
|
|
|
442
443
|
get_knowledge_content = ""
|
|
443
444
|
# 追踪流式推送的 reasoning 文本(用于构建有意义的最终回复)
|
|
444
445
|
_v2_reasoning_collected: List[str] = []
|
|
446
|
+
# XML 解析失败时的 LLM 修正重试计数
|
|
447
|
+
_xml_correction_retries: int = 0
|
|
445
448
|
|
|
446
449
|
conversation_history = list(context.conversation_history or [])
|
|
447
450
|
|
|
@@ -587,31 +590,54 @@ class MainAgent(BaseAgent):
|
|
|
587
590
|
"finish": parsed.finish,
|
|
588
591
|
"finish_reason": truncate_str(parsed.finish_reason, 200),
|
|
589
592
|
"next_step": truncate_str(parsed.next_step, 200),
|
|
593
|
+
"response": truncate_str(parsed.response, 500),
|
|
590
594
|
"parse_success": parsed.parse_success,
|
|
595
|
+
"needs_correction": parsed.needs_correction,
|
|
591
596
|
}},
|
|
592
597
|
stream_callback,
|
|
593
598
|
)
|
|
594
599
|
|
|
600
|
+
# Step 4.5: 解析失败处理 — 回退给 LLM 修正或提取周边文本
|
|
595
601
|
if not parsed.parse_success:
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
602
|
+
if parsed.needs_correction and _xml_correction_retries < 1:
|
|
603
|
+
# XML 完全无法解析,让 LLM 重新格式化输出
|
|
604
|
+
_xml_correction_retries += 1
|
|
605
|
+
logger.warning(
|
|
606
|
+
f"[{task_id}] XML 解析完全失败,回退给 LLM 修正 "
|
|
607
|
+
f"(重试 {_xml_correction_retries}/1)"
|
|
608
|
+
)
|
|
609
|
+
correction_prompt = (
|
|
610
|
+
"你上一次的输出格式有误,XML解析器无法识别。"
|
|
611
|
+
"请严格按照 <output>...</output> 格式重新输出你的回答。"
|
|
612
|
+
"注意:不要在 <output> 标签前后输出任何其他文字。\n\n"
|
|
613
|
+
f"你上一次的原始输出如下:\n{llm_raw}"
|
|
614
|
+
)
|
|
615
|
+
conversation_history.append(
|
|
616
|
+
Message(role="assistant", content=llm_raw)
|
|
617
|
+
)
|
|
618
|
+
conversation_history.append(
|
|
619
|
+
Message(role="user", content=correction_prompt)
|
|
620
|
+
)
|
|
621
|
+
await self._emit_v2_event(
|
|
622
|
+
"v2_reasoning",
|
|
623
|
+
{"content": "⚠️ 模型输出格式异常,正在自动修正..."},
|
|
624
|
+
stream_callback,
|
|
625
|
+
)
|
|
626
|
+
continue # 重新进入循环,让 LLM 重新生成
|
|
609
627
|
else:
|
|
610
|
-
#
|
|
611
|
-
logger.warning(f"[{task_id}]
|
|
612
|
-
|
|
628
|
+
# 已重试过或不需要修正,提取周边文本作为备选
|
|
629
|
+
logger.warning(f"[{task_id}] XML 解析失败,提取周边文本作为备选")
|
|
630
|
+
before, after = extract_surrounding_text(llm_raw)
|
|
631
|
+
if before.strip() or after.strip():
|
|
632
|
+
final_text = (before + "\n" + after).strip()
|
|
633
|
+
else:
|
|
634
|
+
# 清除残余 XML 标签后作为纯文本
|
|
635
|
+
final_text = re.sub(r"<[^>]+>", "", llm_raw).strip()
|
|
636
|
+
final_text = final_text if final_text else "处理完毕。"
|
|
613
637
|
context.working_memory["final_response"] = final_text
|
|
614
|
-
await self._emit_v2_event(
|
|
638
|
+
await self._emit_v2_event(
|
|
639
|
+
"v2_reasoning", {"content": final_text}, stream_callback
|
|
640
|
+
)
|
|
615
641
|
if self.memory:
|
|
616
642
|
self.memory.add_session(
|
|
617
643
|
session_id=context.session_id,
|
|
@@ -809,6 +835,7 @@ class MainAgent(BaseAgent):
|
|
|
809
835
|
"v2_tool_start",
|
|
810
836
|
{"tool": {
|
|
811
837
|
"toolname": tool_name,
|
|
838
|
+
"beforecalltext": before_call,
|
|
812
839
|
"parms": truncate_str(parms, 500),
|
|
813
840
|
"timeout": timeout,
|
|
814
841
|
"callback": should_callback,
|
|
@@ -1002,10 +1029,12 @@ class MainAgent(BaseAgent):
|
|
|
1002
1029
|
|
|
1003
1030
|
# 保存工具调用到会话记忆
|
|
1004
1031
|
if self.memory:
|
|
1032
|
+
# 构建工具调用记录,包含 beforecalltext 作为标题
|
|
1033
|
+
tool_call_title = before_call if before_call else f"调用工具: {tool_name}"
|
|
1005
1034
|
self.memory.add_session(
|
|
1006
1035
|
session_id=context.session_id,
|
|
1007
1036
|
role="assistant",
|
|
1008
|
-
content=f"调用工具: {tool_name}\n参数: {truncate_str(parms, 1000)}",
|
|
1037
|
+
content=f"{tool_call_title}\n调用工具: {tool_name}\n参数: {truncate_str(parms, 1000)}",
|
|
1009
1038
|
key="tool_call",
|
|
1010
1039
|
importance=0.4,
|
|
1011
1040
|
)
|