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
116 lines
4.6 KiB
Go
116 lines
4.6 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
agentactivitybiz "github.com/tutti-os/tutti/packages/agent/store-sqlite"
|
|
"github.com/tutti-os/tutti/packages/agent/store-sqlite/canonical"
|
|
agentservice "github.com/tutti-os/tutti/services/tuttid/service/agent"
|
|
)
|
|
|
|
func TestGeneratedAgentSessionIncludesIndependentLatestTurnProjection(t *testing.T) {
|
|
latest := agentactivitybiz.Turn{
|
|
WorkspaceID: "workspace-1",
|
|
AgentSessionID: "session-1",
|
|
TurnID: "turn-settled",
|
|
Phase: agentactivitybiz.TurnPhaseSettled,
|
|
Outcome: agentactivitybiz.TurnOutcomeCompleted,
|
|
StartedAtUnixMS: 10,
|
|
UpdatedAtUnixMS: 20,
|
|
}
|
|
latestInteractions := []agentactivitybiz.Interaction{
|
|
{
|
|
WorkspaceID: "workspace-1", AgentSessionID: "session-1", TurnID: "turn-settled",
|
|
RequestID: "request-answered", Kind: agentactivitybiz.InteractionKindQuestion,
|
|
Status: agentactivitybiz.InteractionStatusAnswered,
|
|
},
|
|
{
|
|
WorkspaceID: "workspace-1", AgentSessionID: "session-1", TurnID: "turn-settled",
|
|
RequestID: "request-superseded", Kind: agentactivitybiz.InteractionKindApproval,
|
|
Status: agentactivitybiz.InteractionStatusSuperseded,
|
|
},
|
|
}
|
|
generated, err := generatedAgentSession(agentservice.Session{
|
|
ID: "session-1",
|
|
Kind: agentactivitybiz.SessionKindRoot,
|
|
Provider: "codex",
|
|
RailSectionKey: "project:repo-1",
|
|
CreatedAt: time.UnixMilli(10),
|
|
MessageVersion: 11,
|
|
LatestTurn: &latest,
|
|
LatestTurnInteractions: latestInteractions,
|
|
GoalSyncState: &agentservice.SessionGoalSyncState{
|
|
PendingOperationID: "goal-operation-1",
|
|
Revision: 3,
|
|
SyncStatus: agentactivitybiz.GoalSyncStatusApplying,
|
|
ExecutionPending: true,
|
|
},
|
|
Capabilities: canonical.NewCapabilitySnapshot([]string{"planMode", "planImplementation"}),
|
|
Metadata: agentactivitybiz.SessionMetadata{
|
|
Usage: &agentactivitybiz.SessionUsage{
|
|
ContextWindow: &agentactivitybiz.SessionUsageContextWindow{UsedTokens: 7_460, TotalTokens: 200_000},
|
|
Quotas: []agentactivitybiz.SessionUsageQuota{},
|
|
},
|
|
Goal: &agentactivitybiz.SessionGoal{Objective: "ship", Status: "active"},
|
|
Imported: true,
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("generatedAgentSession() error = %v", err)
|
|
}
|
|
if generated.MessageVersion != 11 {
|
|
t.Fatalf("messageVersion = %#v, want 11", generated.MessageVersion)
|
|
}
|
|
if generated.ActiveTurn != nil || generated.ActiveTurnId != nil {
|
|
t.Fatalf("active turn = %#v id=%#v, want none", generated.ActiveTurn, generated.ActiveTurnId)
|
|
}
|
|
if generated.LatestTurn == nil || generated.LatestTurn.TurnId != "turn-settled" || generated.LatestTurn.Outcome == nil {
|
|
t.Fatalf("latest turn = %#v", generated.LatestTurn)
|
|
}
|
|
if len(generated.LatestTurnInteractions) != 2 ||
|
|
generated.LatestTurnInteractions[0].Status != "answered" ||
|
|
generated.LatestTurnInteractions[1].Status != "superseded" {
|
|
t.Fatalf("latest turn interactions = %#v", generated.LatestTurnInteractions)
|
|
}
|
|
if generated.PendingInteractions == nil || generated.Capabilities == nil || !generated.Capabilities.PlanMode ||
|
|
generated.Usage == nil || generated.Usage.ContextWindow == nil || generated.Usage.ContextWindow.UsedTokens != 7_460 ||
|
|
generated.Goal == nil || !generated.Imported {
|
|
t.Fatalf("v2 session fields = %#v", generated)
|
|
}
|
|
if generated.RailSectionKey != "project:repo-1" {
|
|
t.Fatalf("rail section key = %q, want project:repo-1", generated.RailSectionKey)
|
|
}
|
|
if generated.GoalSyncState == nil ||
|
|
generated.GoalSyncState.Revision != 3 ||
|
|
generated.GoalSyncState.SyncStatus != "applying" ||
|
|
generated.GoalSyncState.PendingOperationId == nil ||
|
|
*generated.GoalSyncState.PendingOperationId != "goal-operation-1" ||
|
|
!generated.GoalSyncState.ExecutionPending {
|
|
t.Fatalf("goal sync state = %#v", generated.GoalSyncState)
|
|
}
|
|
encoded, err := json.Marshal(generated)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var payload map[string]any
|
|
if err := json.Unmarshal(encoded, &payload); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, ok := payload["activeTurnId"]; !ok || payload["activeTurnId"] != nil {
|
|
t.Fatalf("activeTurnId payload=%#v", payload)
|
|
}
|
|
if interactions, ok := payload["pendingInteractions"].([]any); !ok || len(interactions) != 0 {
|
|
t.Fatalf("pendingInteractions payload=%#v", payload)
|
|
}
|
|
if payload["railSectionKey"] != "project:repo-1" {
|
|
t.Fatalf("railSectionKey payload=%#v", payload)
|
|
}
|
|
for _, removed := range []string{"status", "turnLifecycle", "submitAvailability", "runtimeContext", "createdAt", "updatedAt", "endedAt", "lastError"} {
|
|
if _, ok := payload[removed]; ok {
|
|
t.Fatalf("removed field %q leaked in payload=%#v", removed, payload)
|
|
}
|
|
}
|
|
}
|