Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

482 lines
15 KiB
Go

package liveprotocol
import (
"bytes"
"encoding/json"
"fmt"
"strings"
"google.golang.org/protobuf/encoding/protowire"
)
// EncodeFrame uses a deliberately small protobuf wire schema. The containing
// gRPC contract transports these bytes opaquely, so every Go consumer shares
// this codec and no generated transport DTO can drift from it. Field numbers
// and delivery-kind values are generated from the revisioned wire contract.
func EncodeFrame(frame Frame) ([]byte, error) {
if err := validateFrame(frame); err != nil {
return nil, err
}
var out []byte
out = protowire.AppendTag(out, frameRevisionField, protowire.BytesType)
out = protowire.AppendString(out, frame.ProtocolRevision)
out = protowire.AppendTag(out, frameStreamIDField, protowire.BytesType)
out = protowire.AppendString(out, frame.StreamID)
out = protowire.AppendTag(out, frameBindingIDField, protowire.BytesType)
out = protowire.AppendString(out, frame.BindingID)
out = protowire.AppendTag(out, frameEpochField, protowire.VarintType)
out = protowire.AppendVarint(out, frame.Epoch)
for _, delivery := range frame.Deliveries {
raw, err := encodeDelivery(delivery)
if err != nil {
return nil, err
}
out = protowire.AppendTag(out, frameDeliveriesField, protowire.BytesType)
out = protowire.AppendBytes(out, raw)
}
if len(out) > DefaultFrameMaxBytes {
return nil, ErrFrameTooLarge
}
return out, nil
}
func frameEnvelopeWireSize(frame Frame) int {
return protowire.SizeTag(frameRevisionField) +
protowire.SizeBytes(len(frame.ProtocolRevision)) +
protowire.SizeTag(frameStreamIDField) +
protowire.SizeBytes(len(frame.StreamID)) +
protowire.SizeTag(frameBindingIDField) +
protowire.SizeBytes(len(frame.BindingID)) +
protowire.SizeTag(frameEpochField) +
protowire.SizeVarint(frame.Epoch)
}
func framedDeliveryWireSize(encodedDeliveryBytes int) int {
return protowire.SizeTag(frameDeliveriesField) +
protowire.SizeBytes(encodedDeliveryBytes)
}
func DecodeFrame(raw []byte) (Frame, error) {
if len(raw) == 0 || len(raw) > DefaultFrameMaxBytes {
return Frame{}, ErrInvalidFrame
}
var frame Frame
seen := map[protowire.Number]bool{}
for len(raw) > 0 {
number, wireType, consumed := protowire.ConsumeTag(raw)
if consumed < 0 {
return Frame{}, wireParseError(consumed)
}
raw = raw[consumed:]
if number != frameDeliveriesField && seen[number] {
return Frame{}, fmt.Errorf("%w: duplicate field %d", ErrInvalidFrame, number)
}
seen[number] = true
switch number {
case frameRevisionField, frameStreamIDField, frameBindingIDField:
if wireType != protowire.BytesType {
return Frame{}, ErrInvalidFrame
}
value, n := protowire.ConsumeString(raw)
if n < 0 {
return Frame{}, wireParseError(n)
}
raw = raw[n:]
switch number {
case frameRevisionField:
frame.ProtocolRevision = value
case frameStreamIDField:
frame.StreamID = value
case frameBindingIDField:
frame.BindingID = value
}
case frameEpochField:
if wireType != protowire.VarintType {
return Frame{}, ErrInvalidFrame
}
value, n := protowire.ConsumeVarint(raw)
if n < 0 {
return Frame{}, wireParseError(n)
}
raw = raw[n:]
frame.Epoch = value
case frameDeliveriesField:
if wireType != protowire.BytesType {
return Frame{}, ErrInvalidFrame
}
value, n := protowire.ConsumeBytes(raw)
if n < 0 {
return Frame{}, wireParseError(n)
}
raw = raw[n:]
delivery, err := decodeDelivery(value)
if err != nil {
return Frame{}, err
}
frame.Deliveries = append(frame.Deliveries, delivery)
default:
return Frame{}, fmt.Errorf("%w: unknown field %d", ErrInvalidFrame, number)
}
}
if err := validateFrame(frame); err != nil {
return Frame{}, err
}
return frame, nil
}
func encodeDelivery(delivery Delivery) ([]byte, error) {
if err := validateDelivery(delivery); err != nil {
return nil, err
}
var out []byte
out = protowire.AppendTag(out, deliverySeqField, protowire.VarintType)
out = protowire.AppendVarint(out, delivery.Seq)
out = protowire.AppendTag(out, deliveryKindField, protowire.VarintType)
out = protowire.AppendVarint(out, uint64(delivery.Kind))
var payload []byte
var field protowire.Number
var err error
switch delivery.Kind {
case DeliveryKindEvent:
field, payload = deliveryEventField, delivery.Event
case DeliveryKindDiscontinuity:
field, payload = deliveryDiscontinuityField, mustMarshalControl(delivery.Discontinuity)
case DeliveryKindAttachmentChanged:
field, payload = deliveryAttachmentField, mustMarshalControl(delivery.AttachmentChanged)
case DeliveryKindAttachmentCaughtUp:
field, payload = deliveryAttachmentCaughtUpField, mustMarshalControl(delivery.AttachmentCaughtUp)
case DeliveryKindGoalChanged:
field, payload = deliveryGoalField, mustMarshalControl(delivery.GoalChanged)
case DeliveryKindStreamReady:
field, payload = deliveryReadyField, mustMarshalControl(delivery.StreamReady)
case DeliveryKindRejected:
field, payload = deliveryRejectedField, mustMarshalControl(delivery.Rejected)
default:
err = ErrInvalidFrame
}
if err != nil {
return nil, err
}
out = protowire.AppendTag(out, field, protowire.BytesType)
out = protowire.AppendBytes(out, payload)
if len(out) > DefaultDeliveryMaxBytes {
return nil, ErrDeliveryTooLarge
}
return out, nil
}
func decodeDelivery(raw []byte) (Delivery, error) {
if len(raw) == 0 || len(raw) > DefaultDeliveryMaxBytes {
return Delivery{}, ErrDeliveryTooLarge
}
var delivery Delivery
var payload []byte
var payloadField protowire.Number
seen := map[protowire.Number]bool{}
for len(raw) > 0 {
number, wireType, consumed := protowire.ConsumeTag(raw)
if consumed < 0 || seen[number] {
return Delivery{}, ErrInvalidFrame
}
seen[number] = true
raw = raw[consumed:]
switch number {
case deliverySeqField, deliveryKindField:
if wireType != protowire.VarintType {
return Delivery{}, ErrInvalidFrame
}
value, n := protowire.ConsumeVarint(raw)
if n < 0 {
return Delivery{}, wireParseError(n)
}
raw = raw[n:]
if number == deliverySeqField {
delivery.Seq = value
} else {
delivery.Kind = DeliveryKind(value)
}
case deliveryEventField, deliveryDiscontinuityField, deliveryAttachmentField, deliveryGoalField, deliveryReadyField, deliveryRejectedField, deliveryAttachmentCaughtUpField:
if wireType != protowire.BytesType || payloadField != 0 {
return Delivery{}, ErrInvalidFrame
}
value, n := protowire.ConsumeBytes(raw)
if n < 0 {
return Delivery{}, wireParseError(n)
}
raw = raw[n:]
payloadField = number
payload = append([]byte(nil), value...)
default:
return Delivery{}, fmt.Errorf("%w: unknown delivery field %d", ErrInvalidFrame, number)
}
}
expectedPayload := map[DeliveryKind]protowire.Number{
DeliveryKindEvent: deliveryEventField,
DeliveryKindDiscontinuity: deliveryDiscontinuityField,
DeliveryKindAttachmentChanged: deliveryAttachmentField,
DeliveryKindAttachmentCaughtUp: deliveryAttachmentCaughtUpField,
DeliveryKindGoalChanged: deliveryGoalField,
DeliveryKindStreamReady: deliveryReadyField,
DeliveryKindRejected: deliveryRejectedField,
}[delivery.Kind]
if expectedPayload == 0 || payloadField != expectedPayload {
return Delivery{}, ErrInvalidFrame
}
switch delivery.Kind {
case DeliveryKindEvent:
if _, err := DecodeEvent(payload); err != nil {
delivery.Kind = DeliveryKindDiscontinuity
delivery.Discontinuity = &Discontinuity{Reason: "invalid_delivery"}
} else {
delivery.Event = payload
}
case DeliveryKindDiscontinuity:
delivery.Discontinuity = &Discontinuity{}
if err := strictControlDecode(payload, delivery.Discontinuity); err != nil {
return Delivery{}, err
}
case DeliveryKindAttachmentChanged:
delivery.AttachmentChanged = &AttachmentChanged{}
if err := strictControlDecode(payload, delivery.AttachmentChanged); err != nil {
return Delivery{}, err
}
case DeliveryKindAttachmentCaughtUp:
delivery.AttachmentCaughtUp = &AttachmentCaughtUp{}
if err := strictControlDecode(payload, delivery.AttachmentCaughtUp); err != nil {
return Delivery{}, err
}
case DeliveryKindGoalChanged:
delivery.GoalChanged = &GoalChanged{}
if err := strictControlDecode(payload, delivery.GoalChanged); err != nil {
return Delivery{}, err
}
case DeliveryKindStreamReady:
delivery.StreamReady = &StreamReady{}
if err := strictControlDecode(payload, delivery.StreamReady); err != nil {
return Delivery{}, err
}
case DeliveryKindRejected:
delivery.Rejected = &Rejected{}
if err := strictControlDecode(payload, delivery.Rejected); err != nil {
return Delivery{}, err
}
}
if err := validateDelivery(delivery); err != nil {
return Delivery{}, err
}
return delivery, nil
}
func validateFrame(frame Frame) error {
if strings.TrimSpace(frame.StreamID) == "" || strings.TrimSpace(frame.BindingID) == "" || frame.Epoch == 0 ||
len(frame.Deliveries) == 0 {
return ErrInvalidFrame
}
var previous uint64
for _, delivery := range frame.Deliveries {
if err := validateDelivery(delivery); err != nil {
return err
}
if previous != 0 && delivery.Seq != previous+1 {
return ErrSequenceGap
}
previous = delivery.Seq
}
if frame.ProtocolRevision != ProtocolRevision && !isTypedRejectionFrame(frame) {
return fmt.Errorf("%w: got %q want %q", ErrProtocolMismatch, frame.ProtocolRevision, ProtocolRevision)
}
return nil
}
func isTypedRejectionFrame(frame Frame) bool {
return len(frame.Deliveries) == 1 &&
frame.Deliveries[0].Kind == DeliveryKindRejected &&
frame.Deliveries[0].Rejected != nil
}
func validateDelivery(delivery Delivery) error {
if delivery.Seq == 0 {
return ErrInvalidFrame
}
count := 0
switch delivery.Kind {
case DeliveryKindEvent:
count = boolCount(len(delivery.Event) > 0)
if count == 1 {
if _, err := DecodeEvent(delivery.Event); err != nil {
return err
}
}
case DeliveryKindDiscontinuity:
count = boolCount(delivery.Discontinuity != nil)
if delivery.Discontinuity != nil && strings.TrimSpace(delivery.Discontinuity.Reason) == "" {
return ErrInvalidFrame
}
case DeliveryKindAttachmentChanged:
count = boolCount(delivery.AttachmentChanged != nil)
if delivery.AttachmentChanged != nil && !validAttachmentControl(
delivery.AttachmentChanged.BindingID,
delivery.AttachmentChanged.WorkspaceID,
delivery.AttachmentChanged.AgentSessionID,
delivery.AttachmentChanged.CanonicalTurnID,
delivery.AttachmentChanged.CanonicalTurnIDs,
delivery.AttachmentChanged.CallerTurnID,
delivery.AttachmentChanged.CurrentInteractionRootTurnID,
delivery.AttachmentChanged.AttachmentRevision,
) {
return ErrInvalidFrame
}
case DeliveryKindAttachmentCaughtUp:
count = boolCount(delivery.AttachmentCaughtUp != nil)
if delivery.AttachmentCaughtUp != nil && !validAttachmentControl(
delivery.AttachmentCaughtUp.BindingID,
delivery.AttachmentCaughtUp.WorkspaceID,
delivery.AttachmentCaughtUp.AgentSessionID,
delivery.AttachmentCaughtUp.CanonicalTurnID,
delivery.AttachmentCaughtUp.CanonicalTurnIDs,
delivery.AttachmentCaughtUp.CallerTurnID,
delivery.AttachmentCaughtUp.CurrentInteractionRootTurnID,
delivery.AttachmentCaughtUp.AttachmentRevision,
) {
return ErrInvalidFrame
}
case DeliveryKindGoalChanged:
count = boolCount(delivery.GoalChanged != nil)
if delivery.GoalChanged != nil &&
(strings.TrimSpace(delivery.GoalChanged.WorkspaceID) == "" ||
strings.TrimSpace(delivery.GoalChanged.AgentSessionID) == "" ||
delivery.GoalChanged.Revision < 0) {
return ErrInvalidFrame
}
case DeliveryKindStreamReady:
count = boolCount(delivery.StreamReady != nil)
if delivery.StreamReady != nil &&
(delivery.StreamReady.ProtocolRevision != ProtocolRevision ||
strings.TrimSpace(delivery.StreamReady.StreamID) == "" ||
strings.TrimSpace(delivery.StreamReady.BindingID) == "") {
return ErrInvalidFrame
}
case DeliveryKindRejected:
count = boolCount(delivery.Rejected != nil)
if delivery.Rejected != nil {
switch delivery.Rejected.Reason {
case RejectionProtocolRevisionMismatch, RejectionPermission, RejectionBinding:
default:
return ErrInvalidFrame
}
}
default:
return ErrInvalidFrame
}
if count != 1 {
return ErrInvalidFrame
}
return nil
}
func validAttachmentControl(
bindingID, workspaceID, agentSessionID, canonicalTurnID string, canonicalTurnIDs []string, callerTurnID,
currentInteractionRootTurnID string,
revision uint64,
) bool {
if strings.TrimSpace(bindingID) == "" ||
strings.TrimSpace(workspaceID) == "" ||
strings.TrimSpace(agentSessionID) == "" ||
revision == 0 {
return false
}
// Goal-only attachments are turnless; invocation attachments always carry
// both sides of the Turn identity mapping. A half-populated pair cannot be
// projected safely by a recipient. The optional canonical set may still be
// populated for a turnless attachment after Host proves each Goal Turn.
canonicalTurnID = strings.TrimSpace(canonicalTurnID)
callerTurnID = strings.TrimSpace(callerTurnID)
currentInteractionRootTurnID = strings.TrimSpace(currentInteractionRootTurnID)
if (canonicalTurnID == "") != (callerTurnID == "") {
return false
}
if len(canonicalTurnIDs) == 0 {
// A singular anchor is the complete identity set. A turnless attachment
// with no set has not yet observed a Host-proven Goal Turn.
if canonicalTurnID == "" {
return currentInteractionRootTurnID == ""
}
return currentInteractionRootTurnID == canonicalTurnID
}
seen := make(map[string]struct{}, len(canonicalTurnIDs))
for _, candidate := range canonicalTurnIDs {
candidate = strings.TrimSpace(candidate)
if candidate == "" {
return false
}
if _, ok := seen[candidate]; ok {
return false
}
seen[candidate] = struct{}{}
}
if canonicalTurnID != "" {
_, anchored := seen[canonicalTurnID]
return anchored && currentInteractionRootTurnID == canonicalTurnID
}
_, current := seen[currentInteractionRootTurnID]
return currentInteractionRootTurnID != "" && current
}
func strictControlDecode(raw []byte, target any) error {
if err := validateRequiredControlFields(raw, target); err != nil {
return err
}
decoder := json.NewDecoder(bytes.NewReader(raw))
decoder.DisallowUnknownFields()
if err := decoder.Decode(target); err != nil {
return fmt.Errorf("%w: %v", ErrInvalidFrame, err)
}
if err := ensureJSONEOF(decoder); err != nil {
return fmt.Errorf("%w: trailing control data", ErrInvalidFrame)
}
return nil
}
func validateRequiredControlFields(raw []byte, target any) error {
var required []string
switch target.(type) {
case *AttachmentChanged, *AttachmentCaughtUp:
required = []string{"currentInteractionRootTurnId"}
default:
return nil
}
var fields map[string]json.RawMessage
if err := json.Unmarshal(raw, &fields); err != nil {
return fmt.Errorf("%w: %v", ErrInvalidFrame, err)
}
for _, field := range required {
value, present := fields[field]
if !present {
return fmt.Errorf("%w: missing required control field %q", ErrInvalidFrame, field)
}
if bytes.Equal(bytes.TrimSpace(value), []byte("null")) {
return fmt.Errorf("%w: required control field %q cannot be null", ErrInvalidFrame, field)
}
}
return nil
}
func mustMarshalControl(value any) []byte {
raw, err := json.Marshal(value)
if err != nil {
panic(err)
}
return raw
}
func wireParseError(code int) error {
return fmt.Errorf("%w: protobuf parse code %d", ErrInvalidFrame, code)
}
func boolCount(value bool) int {
if value {
return 1
}
return 0
}