Files
tutti/packages/agent/daemon/activity/events/turn_capability_references.go
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

92 lines
3.1 KiB
Go

package events
import "strings"
// CapabilityReference records structured provenance for a capability that
// influenced one canonical turn, whether introduced by its initial submission
// or later native guidance. It is activity metadata, never provider prompt
// text.
type CapabilityReference struct {
Capability string `json:"capability"`
Source string `json:"source"`
}
// TurnCapabilityReferencesMetadataKey is the stable activity-event metadata
// key used to carry provenance from controller-owned submission events into
// the durable turn projection. Native guidance uses a lifecycle-neutral turn
// state patch instead of this event metadata carrier.
const TurnCapabilityReferencesMetadataKey = "turnCapabilityRefs"
// StampTurnCapabilityReferences attaches normalized, de-duplicated references
// to a turn event. Empty references intentionally leave the event unchanged.
func StampTurnCapabilityReferences(event *Event, references []CapabilityReference) {
if event == nil {
return
}
normalized := NormalizeCapabilityReferences(references)
if len(normalized) == 0 {
return
}
if event.Payload.Metadata == nil {
event.Payload.Metadata = map[string]any{}
}
encoded := make([]map[string]any, 0, len(normalized))
for _, reference := range normalized {
encoded = append(encoded, map[string]any{
"capability": reference.Capability,
"source": reference.Source,
})
}
event.Payload.Metadata[TurnCapabilityReferencesMetadataKey] = encoded
}
// TurnCapabilityReferencesFromEvent extracts references after either an
// in-process handoff or a JSON round trip through the report worker.
func TurnCapabilityReferencesFromEvent(event Event) []CapabilityReference {
raw, ok := event.Payload.Metadata[TurnCapabilityReferencesMetadataKey]
if !ok {
return nil
}
decoded := make([]CapabilityReference, 0)
switch values := raw.(type) {
case []map[string]any:
for _, value := range values {
decoded = append(decoded, capabilityReferenceFromMap(value))
}
case []any:
for _, value := range values {
if mapped, ok := value.(map[string]any); ok {
decoded = append(decoded, capabilityReferenceFromMap(mapped))
}
}
case []CapabilityReference:
decoded = append(decoded, values...)
}
return NormalizeCapabilityReferences(decoded)
}
func NormalizeCapabilityReferences(references []CapabilityReference) []CapabilityReference {
seen := make(map[string]struct{}, len(references))
normalized := make([]CapabilityReference, 0, len(references))
for _, reference := range references {
reference.Capability = strings.TrimSpace(reference.Capability)
reference.Source = strings.TrimSpace(reference.Source)
if reference.Capability == "" || reference.Source == "" {
continue
}
key := reference.Source + "\x00" + reference.Capability
if _, ok := seen[key]; ok {
continue
}
seen[key] = struct{}{}
normalized = append(normalized, reference)
}
return normalized
}
func capabilityReferenceFromMap(value map[string]any) CapabilityReference {
capability, _ := value["capability"].(string)
source, _ := value["source"].(string)
return CapabilityReference{Capability: capability, Source: source}
}