package loop import ( "git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/agent" "git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model" ) // appendToolCallHistory 按调用顺序渲染 assistant 工具调用轮,其后是每个 // 工具结果。当每个调用都带 provider id(原生 // Anthropic tool_use / OpenAI tool_calls)时,该轮以原生 // tool_use + tool_result 块发出,使 provider 能把每个结果关联到其 // 调用;不带 id 的批次(旧式 JSON 信封约定)保持 // 纯 RoleTool 文本回灌形态。 func appendToolCallHistory(messages []model.Message, calls []agent.ToolCall, outcomes []ToolOutcome) []model.Message { native := nativeModelToolCalls(calls) if len(native) == 0 { for i := range calls { messages = append(messages, toolResultMessage(calls[i], outcomes[i])) } return messages } messages = append(messages, model.AssistantToolCallMessage(native)) for i := range calls { isError := outcomes[i].Err != nil || outcomes[i].Skipped messages = append(messages, model.ToolResultMessage(calls[i].ID, toolResultText(calls[i], outcomes[i]), isError)) } return messages } // nativeModelToolCalls 仅在每个调用都带 provider id 时把批次转换为 // model.ToolCall;不带 id 的批次(旧式 JSON 信封 // 约定)返回 nil,使调用方保持纯文本回灌形态。 func nativeModelToolCalls(calls []agent.ToolCall) []model.ToolCall { if len(calls) == 0 { return nil } out := make([]model.ToolCall, 0, len(calls)) for _, c := range calls { if c.ID == "" { return nil } args := c.Args if args == nil { args = map[string]any{} } out = append(out, model.ToolCall{ID: c.ID, Name: c.Name, Args: args}) } return out }