Why: Contract foundation for the inbox/command-bus/workspaces phase (proposal D28/D30): ActivityCard as the first-class state object behind the right-rail inbox, card.* stream events, inline-confirm anchoring (anchorMessageId + blocked/blockReason) on HITL, seven new UI schema vocabularies, plugin provides.commands/workspaces, workflow card step and workspace declarations. Evidence: go vet clean; conformance goldens regenerated and verified — new activity_card / hitl_card_blocked / event_card_created / event_card_resolved / ui_vocabularies samples plus extended plugin_manifest; CardStatus.Terminal helper unit-covered via build; ts/types.ts mirrors all additions. Impact: Additive only (omitempty fields, new types, new event types) — existing consumers ignore unknown values per forward-compat rule; vocabulary spec types carry a Spec suffix to avoid const-name collisions. Refs: modules/documents docs/proposals/2026-09-30-ui-inbox-command-workspace.md
160 lines
5.4 KiB
Go
160 lines
5.4 KiB
Go
package core
|
||
|
||
import "encoding/json"
|
||
|
||
// 事件信封:后端 → 前端的唯一增量通道(SSE),持久化后转发,Seq 在会话内单调。
|
||
// 消费方对未知 Type 静默忽略(原则 6 前向兼容)。
|
||
type StreamEvent struct {
|
||
Seq int64 `json:"seq"`
|
||
RunID ID `json:"runId,omitempty"`
|
||
ConversationID ID `json:"conversationId"`
|
||
TS string `json:"ts"` // RFC3339
|
||
V int `json:"v"`
|
||
Type StreamEventType `json:"type"`
|
||
Payload json.RawMessage `json:"payload,omitempty"`
|
||
}
|
||
|
||
type StreamEventType string
|
||
|
||
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"`
|
||
}
|