Skip to content

Commit a7754c0

Browse files
committed
refactor: simplify fix_messages to single-pass state machine
1 parent 33d93ae commit a7754c0

1 file changed

Lines changed: 31 additions & 36 deletions

File tree

astrbot/core/agent/context/truncator.py

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -24,44 +24,39 @@ def fix_messages(self, messages: list[Message]) -> list[Message]:
2424
if not messages:
2525
return messages
2626

27-
# First pass: identify which assistant(tool_calls) have valid tool responses
28-
# Build a set of indices for assistant messages that have valid tool responses
29-
valid_tool_call_indices: set[int] = set()
30-
i = 0
31-
while i < len(messages):
32-
msg = messages[i]
33-
if self._has_tool_calls(msg):
34-
# Check if next message(s) are tool responses
35-
j = i + 1
36-
has_tool_response = False
37-
while j < len(messages) and messages[j].role == "tool":
38-
has_tool_response = True
39-
j += 1
40-
if has_tool_response:
41-
valid_tool_call_indices.add(i)
42-
i += 1
43-
44-
# Second pass: build fixed message list
4527
fixed_messages: list[Message] = []
46-
in_valid_tool_chain = False # 是否处于有效的 tool call 链中
47-
48-
for i, msg in enumerate(messages):
28+
pending_assistant: Message | None = None
29+
pending_tools: list[Message] = []
30+
31+
def flush_pending_if_valid() -> None:
32+
nonlocal pending_assistant, pending_tools
33+
if pending_assistant is not None and pending_tools:
34+
fixed_messages.append(pending_assistant)
35+
fixed_messages.extend(pending_tools)
36+
pending_assistant = None
37+
pending_tools = []
38+
39+
for msg in messages:
4940
if msg.role == "tool":
50-
# tool 消息:只有在有效的 tool call 链中才保留
51-
if in_valid_tool_chain:
52-
fixed_messages.append(msg)
53-
# else: 孤立的 tool 消息,跳过
54-
elif self._has_tool_calls(msg):
55-
# assistant(tool_calls):只保留有效的(后面有 tool response 的)
56-
if i in valid_tool_call_indices:
57-
fixed_messages.append(msg)
58-
in_valid_tool_chain = True # 进入有效的 tool call 链
59-
else:
60-
in_valid_tool_chain = False # 孤立的 tool_calls,跳过并重置状态
61-
else:
62-
# system, user, 或不含 tool_calls 的 assistant
63-
fixed_messages.append(msg)
64-
in_valid_tool_chain = False # 退出 tool call 链
41+
# 只有在有挂起的 assistant(tool_calls) 时才记录 tool 响应
42+
if pending_assistant is not None:
43+
pending_tools.append(msg)
44+
# else: 孤立的 tool 消息,直接忽略
45+
continue
46+
47+
if self._has_tool_calls(msg):
48+
# 遇到新的 assistant(tool_calls) 前,先处理旧的 pending 链
49+
flush_pending_if_valid()
50+
pending_assistant = msg
51+
continue
52+
53+
# 非 tool,且不含 tool_calls 的消息
54+
# 先结束任何 pending 链,再正常追加
55+
flush_pending_if_valid()
56+
fixed_messages.append(msg)
57+
58+
# 结束时处理最后一个 pending 链
59+
flush_pending_if_valid()
6560

6661
return fixed_messages
6762

0 commit comments

Comments
 (0)