From 9c062f769d9b44ef74deb7bc5d85c48b09ba0fad Mon Sep 17 00:00:00 2001 From: taking-lying-flat <1615405@qq.com> Date: Thu, 17 Sep 2026 07:07:27 +0800 Subject: [PATCH] fix: align OpenAI tool results before message normalization Signed-off-by: taking-lying-flat <1615405@qq.com> --- swift/template/template_inputs.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/swift/template/template_inputs.py b/swift/template/template_inputs.py index 50d9f1e890..3f12642ac2 100644 --- a/swift/template/template_inputs.py +++ b/swift/template/template_inputs.py @@ -14,12 +14,25 @@ def normalize_openai_tool_calls(messages: Messages) -> Messages: """Convert OpenAI assistant ``tool_calls`` into SWIFT canonical messages.""" normalized = [] - for message in messages: + messages = list(messages) + for index, message in enumerate(messages): tool_calls = message.get('tool_calls') if message.get('role') == 'assistant' else None if not tool_calls: normalized.append(message) continue + # Canonical tool responses are positional, so align a complete result batch + # before the call IDs are discarded. Keep legacy messages without IDs as-is. + call_order = {call.get('id'): i for i, call in enumerate(tool_calls)} + end = index + 1 + while end < len(messages) and messages[end].get('role') in {'tool', 'tool_response'}: + end += 1 + responses = messages[index + 1:end] + if (None not in call_order and len(call_order) == len(tool_calls) == len(responses) + and set(call_order) == {response.get('tool_call_id') + for response in responses}): + messages[index + 1:end] = sorted(responses, key=lambda response: call_order[response['tool_call_id']]) + content = message.get('content') if content: normalized.append({