Files
Agent-System-Core/events.go
T
weichen ed579bf29c Extract project channel key helpers (CF3 review fix)
Why: project channel convention (pseudo-key project:<projectId>) was
duplicated across runmgr/server/store; centralize so replay envelopes
match live stamping.
Evidence: go test green.
Impact: no behavior change; enables store replay stamping.
2026-09-30 19:07:06 +00:00

179 lines
6.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package core
import (
"encoding/json"
"strings"
)
// 事件信封:后端 → 前端的唯一增量通道(SSE),持久化后转发,Seq 在会话内单调。
// 消费方对未知 Type 静默忽略(原则 6 前向兼容)。
// 项目流(D50):项目频道事件以伪会话键 "project:<projectId>" 复用同一机制
//(独立 seq、持久化、断线重放),信封以 ProjectID 标识归属(会话流事件为空)。
type StreamEvent struct {
Seq int64 `json:"seq"`
RunID ID `json:"runId,omitempty"`
ConversationID ID `json:"conversationId"`
ProjectID ID `json:"projectID,omitempty"` // 项目流事件的项目归属(D50;只增不删)
TS string `json:"ts"` // RFC3339
V int `json:"v"`
Type StreamEventType `json:"type"`
Payload json.RawMessage `json:"payload,omitempty"`
}
type StreamEventType string
// 项目流频道约定(D50):项目频道以伪会话键 "project:<projectId>" 复用会话
// 事件的持久化/seq/重放机制;信封 ProjectID 由该键派生(发布与重放同源)。
const projectChannelPrefix = "project:"
// ProjectChannelKey 返回项目流的事件频道键。
func ProjectChannelKey(projectID ID) ID { return ID(projectChannelPrefix + string(projectID)) }
// ProjectFromChannel 反解项目流频道键;非项目流频道返回 false。
func ProjectFromChannel(key ID) (ID, bool) {
pid, ok := strings.CutPrefix(string(key), projectChannelPrefix)
return ID(pid), ok && pid != ""
}
const (
EvMessageDelta StreamEventType = "message.delta"
EvThinkingDelta StreamEventType = "thinking.delta"
EvToolCall StreamEventType = "tool.call"
EvToolResult StreamEventType = "tool.result"
EvRunPhase StreamEventType = "run.phase"
EvHITLRequest StreamEventType = "hitl.request"
EvHITLResolved StreamEventType = "hitl.resolved"
EvPlanUpdate StreamEventType = "plan.update"
EvTodoUpdate StreamEventType = "todo.update"
EvAgentSpawn StreamEventType = "agent.spawn"
EvAgentProgress StreamEventType = "agent.progress"
EvAgentResult StreamEventType = "agent.result"
EvArtifactCreated StreamEventType = "artifact.created"
EvArtifactUpdated StreamEventType = "artifact.updated"
EvRunCompleted StreamEventType = "run.completed"
EvRunFailed StreamEventType = "run.failed"
EvError StreamEventType = "error"
// 收件箱卡片(activity.go):前端右栏收件箱的唯一数据源(投影语义,服务端权威)。
EvCardCreated StreamEventType = "card.created"
EvCardUpdated StreamEventType = "card.updated"
EvCardStatus StreamEventType = "card.status"
EvCardResolved StreamEventType = "card.resolved"
)
// ProtocolVersion 是事件信封与 payload 词汇的当前版本。
const ProtocolVersion = 1
// ---- 各事件 payload(新增字段只增不删;消费方忽略未知字段)----
// MessageDeltaPayload:正文增量。Index 标识目标 Part 序号(流式聚合用)。
type MessageDeltaPayload struct {
Index int `json:"index"`
Text string `json:"text"`
}
type ThinkingDeltaPayload struct {
Index int `json:"index"`
Text string `json:"text"`
}
type ToolCallPayload struct {
CallID string `json:"callId"`
Name string `json:"name"`
Arguments string `json:"arguments,omitempty"`
}
type ToolResultPayload struct {
CallID string `json:"callId"`
Status string `json:"status"`
Summary string `json:"summary,omitempty"`
Truncated bool `json:"truncated,omitempty"`
}
type RunPhasePayload struct {
Phase RunPhase `json:"phase"`
}
type HITLResolvedPayload struct {
CardID ID `json:"cardId"`
Answer string `json:"answer,omitempty"`
Kind string `json:"kind"` // choice | free | timeout | cancelled
}
type PlanUpdatePayload struct {
Plan PlanSnapshot `json:"plan"`
}
type TodoUpdatePayload struct {
List TodoList `json:"list"`
}
// AgentSpawnPayload:子代理派生;AgentRun 即子 Run(父子关系即任务树)。
type AgentSpawnPayload struct {
AgentRun ID `json:"agentRun"`
Name string `json:"name"`
Task string `json:"task"`
}
type AgentProgressPayload struct {
AgentRun ID `json:"agentRun"`
Note string `json:"note,omitempty"`
Phase RunPhase `json:"phase,omitempty"`
}
type AgentResultPayload struct {
AgentRun ID `json:"agentRun"`
Status RunStatus `json:"status"`
Summary string `json:"summary,omitempty"`
// Text 为子代理完整文本产出(squad 步骤交付物用;截断摘要见 Summary)。
Text string `json:"text,omitempty"`
}
type ArtifactPayload struct {
Artifact Artifact `json:"artifact"`
}
type RunCompletedPayload struct {
Usage Usage `json:"usage"`
// Context 为该次运行的上下文组装观测(4.10/4.17:构成 + 裁剪记录;可解释性)。
Context *ContextObservation `json:"context,omitempty"`
}
// ContextObservation 记录一次模型输入的实际构成与预算裁剪(ctxasm 产出)。
type ContextObservation struct {
Items []string `json:"items"` // 如 system(画像) / history(12) / attachments(1) / knowledge(3)
Truncations []string `json:"truncations,omitempty"` // 裁剪记录(历史超窗/工具结果超限/附件截断)
EstChars int `json:"estChars"` // 估算输入字符量
}
type RunFailedPayload struct {
Code string `json:"code"`
Message string `json:"message"`
}
type ErrorPayload struct {
Code string `json:"code"`
Message string `json:"message"`
RunID ID `json:"runId,omitempty"`
}
// CardPayload:card.created / card.updated 携带整卡投影(服务端权威,前端整体替换)。
type CardPayload struct {
Card ActivityCard `json:"card"`
}
// CardStatusPayload:card.status 携带状态迁移(含 Tone,便于轻量更新状态灯)。
type CardStatusPayload struct {
CardID ID `json:"cardId"`
Status CardStatus `json:"status"`
Tone string `json:"tone,omitempty"`
Note string `json:"note,omitempty"`
}
// CardResolvedPayload:card.resolved 携带所点动作语义——确认结论回写对话时间线
// (AI 回执)并写入审计;Answer 为自由输入文本(如有)。
type CardResolvedPayload struct {
CardID ID `json:"cardId"`
ActionID string `json:"actionId,omitempty"`
Answer string `json:"answer,omitempty"`
}