package orchestration import ( "fmt" "time" "git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/loop" ) // SubAgentResult is a point-in-time snapshot of a SubAgent. It is used both as // the per-sub-agent entry in MergedResult and as the return value of // (*SubAgent).Snapshot for monitoring. type SubAgentResult struct { // ID is the sub-agent id. ID string // Goal is the sub-agent's objective. Goal string // RoleID is the bound role/persona. RoleID string // Mode is the bound behavior mode. Mode string // AttachInfo is the supplied attachment text. AttachInfo string // Status is the terminal (or current) status. Status Status // Summary is the execution summary written on finalization. Summary string // Text is the loop result text on a successful run. Text string // Steps is the number of loop steps executed on a successful run. Steps int // Err is the error that ended a failed/aborted run (nil on success). Err error // StartedAt is when the sub-agent began running. StartedAt time.Time // FinishedAt is when the sub-agent finalized. FinishedAt time.Time } // MergedResult aggregates the outcomes of every spawned sub-agent, produced by // (*Scheduler).Join. type MergedResult struct { // Agents holds one entry per spawned sub-agent, in spawn order. Agents []SubAgentResult // Total is the number of spawned sub-agents. Total int // Succeeded is how many sub-agents finished with StatusDone. Succeeded int // Failed is how many sub-agents finished with StatusFailed. Failed int // Aborted is how many sub-agents finished with StatusAborted. Aborted int // Summary is a one-line aggregate summary of all sub-agents. Summary string } // summaryTextMax caps how many runes of the result text appear in a summary. const summaryTextMax = 80 // doneSummary builds the execution summary written when a sub-agent succeeds. func doneSummary(res *loop.Result) string { if res == nil { return "完成" } text := compactText(res.Text, summaryTextMax) if res.StopReason != "" { return fmt.Sprintf("完成 (%s, 步骤=%d): %s", res.StopReason, res.Steps, text) } return fmt.Sprintf("完成 (步骤=%d): %s", res.Steps, text) } // failedSummary builds the summary written when a sub-agent fails. func failedSummary(err error) string { if err == nil { return "失败" } return "失败: " + err.Error() } // canceledSummary builds the summary written when a sub-agent is aborted. func canceledSummary() string { return "中止: 已取消" } // timeoutSummary builds the summary written when a sub-agent times out. func timeoutSummary(d time.Duration) string { return fmt.Sprintf("中止: 超时 (%s)", d) } // summarizeMerged produces the one-line aggregate summary of a merged result. func summarizeMerged(r *MergedResult) string { return fmt.Sprintf("子代理汇总: 共 %d 个, %d 成功, %d 失败, %d 中止", r.Total, r.Succeeded, r.Failed, r.Aborted) }