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

151 lines
6.0 KiB
Go

package activityreplication_test
import (
"encoding/json"
"testing"
activityreplication "github.com/tutti-os/tutti/packages/agent/activity-replication"
"github.com/tutti-os/tutti/packages/agent/store-sqlite/canonical"
)
func TestValidateMutationAcceptsEveryProjectionSnapshot(t *testing.T) {
t.Parallel()
sessionScope := &activityreplication.SessionScope{
ExecutorOwnerUserID: "owner-1", SourceDeviceID: "device-1",
SharedAgentBindingID: "binding-1", Visibility: activityreplication.VisibilityMembers,
}
base := func(entityType activityreplication.EntityType, key activityreplication.EntityKey) activityreplication.Mutation {
return activityreplication.Mutation{
SchemaVersion: activityreplication.SchemaVersion, MutationID: "mutation-1", TransactionID: "transaction-1",
SourceDeviceID: "device-1", WorkspaceID: "workspace-1", EntityType: entityType,
Operation: activityreplication.OperationUpsert, Key: key,
}
}
turnID := "turn-1"
identityAnchorTurnID := "plan-turn-1"
tests := []struct {
name string
mutation activityreplication.Mutation
}{
{
name: "target",
mutation: func() activityreplication.Mutation {
mutation := base(activityreplication.EntityTarget, activityreplication.EntityKey{AgentTargetID: "target-1"})
mutation.Target = &activityreplication.Target{ID: "target-1", LaunchRef: json.RawMessage(`{}`)}
mutation.TargetScope = &activityreplication.TargetScope{OwnerUserID: "owner-1", OwnerDeviceID: "device-1"}
return mutation
}(),
},
{
name: "session",
mutation: func() activityreplication.Mutation {
mutation := base(activityreplication.EntitySession, activityreplication.EntityKey{AgentSessionID: "session-1"})
mutation.Session = &activityreplication.Session{
WorkspaceID: "workspace-1", AgentSessionID: "session-1", Kind: canonical.SessionKindRoot,
Origin: "runtime",
Settings: json.RawMessage(`{}`), SessionMetadata: json.RawMessage(`{}`),
InternalRuntimeContext: json.RawMessage(`{}`), RailSectionKey: "conversations",
}
mutation.SessionScope = sessionScope
return mutation
}(),
},
{
name: "turn",
mutation: func() activityreplication.Mutation {
mutation := base(activityreplication.EntityTurn, activityreplication.EntityKey{AgentSessionID: "session-1", TurnID: turnID})
mutation.Turn = &activityreplication.Turn{
WorkspaceID: "workspace-1", AgentSessionID: "session-1", TurnID: turnID,
IdentityAnchorTurnID: &identityAnchorTurnID,
Phase: canonical.TurnPhaseRunning, Origin: canonical.TurnOriginUserPrompt,
ProviderTurnBindingJSON: json.RawMessage(`{}`),
}
mutation.SessionScope = sessionScope
return mutation
}(),
},
{
name: "interaction",
mutation: func() activityreplication.Mutation {
mutation := base(activityreplication.EntityInteraction, activityreplication.EntityKey{
AgentSessionID: "session-1", TurnID: turnID, RequestID: "request-1",
})
mutation.Interaction = &activityreplication.Interaction{
WorkspaceID: "workspace-1", AgentSessionID: "session-1", TurnID: turnID, RequestID: "request-1",
Kind: canonical.InteractionKindQuestion, Status: canonical.InteractionStatusPending,
Input: json.RawMessage(`{}`), Output: json.RawMessage(`{}`), Metadata: json.RawMessage(`{}`),
}
mutation.SessionScope = sessionScope
return mutation
}(),
},
{
name: "message",
mutation: func() activityreplication.Mutation {
mutation := base(activityreplication.EntityMessage, activityreplication.EntityKey{
AgentSessionID: "session-1", MessageID: "message-1",
})
mutation.Message = &activityreplication.Message{
WorkspaceID: "workspace-1", AgentSessionID: "session-1", MessageID: "message-1", Version: 1,
TurnID: &turnID, Role: "assistant", Kind: "text", Payload: json.RawMessage(`{}`),
}
mutation.SessionScope = sessionScope
return mutation
}(),
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
if err := activityreplication.ValidateMutation(test.mutation); err != nil {
t.Fatalf("ValidateMutation() error = %v", err)
}
})
}
}
func TestValidateMutationRejectsInvalidTurnIdentityAnchor(t *testing.T) {
t.Parallel()
for _, anchor := range []string{" ", "turn-1"} {
anchor := anchor
t.Run(anchor, func(t *testing.T) {
t.Parallel()
mutation := activityreplication.Mutation{
SchemaVersion: activityreplication.SchemaVersion, MutationID: "mutation-1", TransactionID: "transaction-1",
SourceDeviceID: "device-1", WorkspaceID: "workspace-1", EntityType: activityreplication.EntityTurn,
Operation: activityreplication.OperationUpsert,
Key: activityreplication.EntityKey{AgentSessionID: "session-1", TurnID: "turn-1"},
Turn: &activityreplication.Turn{
WorkspaceID: "workspace-1", AgentSessionID: "session-1", TurnID: "turn-1",
IdentityAnchorTurnID: &anchor, Phase: canonical.TurnPhaseRunning,
Origin: canonical.TurnOriginUserPrompt, ProviderTurnBindingJSON: json.RawMessage(`{}`),
},
SessionScope: &activityreplication.SessionScope{
ExecutorOwnerUserID: "owner-1", SourceDeviceID: "device-1", Visibility: activityreplication.VisibilityMembers,
},
}
if err := activityreplication.ValidateMutation(mutation); err == nil {
t.Fatal("ValidateMutation() error = nil")
}
})
}
}
func TestValidateMutationRejectsTrailingJSON(t *testing.T) {
t.Parallel()
mutation := activityreplication.Mutation{
SchemaVersion: activityreplication.SchemaVersion, MutationID: "mutation-1", TransactionID: "transaction-1",
SourceDeviceID: "device-1", WorkspaceID: "workspace-1", EntityType: activityreplication.EntityTarget,
Operation: activityreplication.OperationUpsert, Key: activityreplication.EntityKey{AgentTargetID: "target-1"},
Target: &activityreplication.Target{ID: "target-1", LaunchRef: json.RawMessage(`{} {}`)},
TargetScope: &activityreplication.TargetScope{OwnerUserID: "owner-1", OwnerDeviceID: "device-1"},
}
if err := activityreplication.ValidateMutation(mutation); err == nil {
t.Fatal("ValidateMutation() error = nil")
}
}