MCPcopy Create free account
hub / github.com/astercloud/aster / validateMessageHistory

Method validateMessageHistory

pkg/agent/agent.go:1623–1667  ·  view source on GitHub ↗

validateMessageHistory 验证消息历史格式是否正确 DeepSeek 等 API 要求:每个包含 tool_calls 的 assistant 消息后必须紧跟对应的 tool_result 消息 注意:__parse_error__ 标记的消息不在这里处理,而是在 convertMessages 中替换为有效 JSON

(messages []types.Message)

Source from the content-addressed store, hash-verified

1621// DeepSeek 等 API 要求:每个包含 tool_calls 的 assistant 消息后必须紧跟对应的 tool_result 消息
1622// 注意:__parse_error__ 标记的消息不在这里处理,而是在 convertMessages 中替换为有效 JSON
1623func (a *Agent) validateMessageHistory(messages []types.Message) bool {
1624 for i, msg := range messages {
1625 // 检查是否有 tool_calls,并收集所有 tool_call IDs
1626 var toolCallIDs []string
1627 hasToolCalls := false
1628 for _, block := range msg.ContentBlocks {
1629 if toolUse, ok := block.(*types.ToolUseBlock); ok {
1630 hasToolCalls = true
1631 toolCallIDs = append(toolCallIDs, toolUse.ID)
1632 // 注意:不再检查 __parse_error__,让 convertMessages 处理
1633 }
1634 }
1635
1636 if hasToolCalls {
1637 // 如果是最后一条消息,无效(tool_calls 必须有 response)
1638 if i+1 >= len(messages) {
1639 return false
1640 }
1641
1642 // 检查紧接着的下一条消息是否包含 tool_result
1643 nextMsg := messages[i+1]
1644 var toolResultIDs []string
1645 hasToolResult := false
1646 for _, block := range nextMsg.ContentBlocks {
1647 if toolResult, ok := block.(*types.ToolResultBlock); ok {
1648 hasToolResult = true
1649 toolResultIDs = append(toolResultIDs, toolResult.ToolUseID)
1650 }
1651 }
1652
1653 if !hasToolResult {
1654 return false
1655 }
1656
1657 // 验证每个 tool_call ID 都有对应的 tool_result
1658 for _, toolCallID := range toolCallIDs {
1659 found := slices.Contains(toolResultIDs, toolCallID)
1660 if !found {
1661 return false
1662 }
1663 }
1664 }
1665 }
1666 return true
1667}
1668
1669// removeIncompleteToolCalls 移除所有不完整的 tool_call 序列
1670// 策略:找到第一个不完整的 tool_call,截断到该位置之前

Callers 1

initializeMethod · 0.95

Calls

no outgoing calls

Tested by

no test coverage detected