package squad import "context" // ProgressSink 是小队过程事件的输出端口(KTD1:SSE 映射、task_runs 持久事件、 // 权限与重放由产品侧实现;小队只产出有类型的进度/步骤/完成事件)。 // // 实现方约定:方法不得阻塞(消费方自行异步入队);nil 安全由调用侧判断, // ProgressFromContext 未注入时返回 nil,小队内部全部 no-op。 type ProgressSink interface { // EmitPhase 报告阶段进展(装配、门禁、失败等里程碑)。 EmitPhase(phaseID, message, role string, stepIndex, totalSteps, progress int) // EmitDetail 报告过程细节帧(思考增量、工具调用、步骤输出)。 EmitDetail(p DetailEvent) // EmitDeliverable 报告正式交付物完成。 EmitDeliverable(taskKey, title, filePath string, wordCount int, score float64) // EmitSummary 报告任务摘要(含成熟度)。 EmitSummary(title, content string, maturityScore int, maturityLevel string) // EmitBriefing 报告参谋简报载荷(结构由产品侧定义)。 EmitBriefing(brief any) } // DetailEvent 是小队过程细节事件的唯一载荷形态;与产品 SSE detail 帧的字段 // 对应关系由产品侧适配器维护(squad 不 import stream 包)。 type DetailEvent struct { Category string // agent_thought | step_output | tool_call | log StepID string Role string ItemID string // 聚合项:一个思考块/一次工具调用 Title string Content string // 完整快照(对账帧) Collapsible bool Delta string // 增量追加到 ItemID 项 Done bool // 定稿标记 Tool *ToolEvent } // ToolEvent 是工具调用状态帧(Category == tool_call 时)。 type ToolEvent struct { Name string // write_file / read_file / ... Status string // calling | succeeded | failed Input string // 入参摘要(截断) Output string // 结果摘要(截断) DurationMs int64 } type progressCtxKey struct{} // WithProgress 向 ctx 注入小队过程端口(产品装配点调用)。 func WithProgress(ctx context.Context, sink ProgressSink) context.Context { if sink == nil { return ctx } return context.WithValue(ctx, progressCtxKey{}, sink) } // ProgressFromContext 提取小队过程端口;未注入返回 nil(调用侧 no-op)。 func ProgressFromContext(ctx context.Context) ProgressSink { if ctx == nil { return nil } if sink, ok := ctx.Value(progressCtxKey{}).(ProgressSink); ok { return sink } return nil }