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
75 lines
2.1 KiB
Go
75 lines
2.1 KiB
Go
package storesqlite
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
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 mergeTurnCapabilityReferencesTx(
|
|
ctx context.Context,
|
|
tx *sql.Tx,
|
|
existing Turn,
|
|
incoming []CapabilityReference,
|
|
) (Turn, bool, error) {
|
|
merged := normalizeCapabilityReferences(append(
|
|
append([]CapabilityReference(nil), existing.CapabilityRefs...),
|
|
incoming...,
|
|
))
|
|
if capabilityReferencesEqual(existing.CapabilityRefs, merged) {
|
|
return existing, false, nil
|
|
}
|
|
payload, err := json.Marshal(merged)
|
|
if err != nil {
|
|
return Turn{}, false, fmt.Errorf("encode workspace agent turn capability refs: %w", err)
|
|
}
|
|
if _, err := tx.ExecContext(ctx, `
|
|
UPDATE workspace_agent_turns
|
|
SET capability_refs_json = ?
|
|
WHERE workspace_id = ? AND agent_session_id = ? AND turn_id = ?
|
|
`, string(payload), existing.WorkspaceID, existing.AgentSessionID, existing.TurnID); err != nil {
|
|
return Turn{}, false, fmt.Errorf("merge workspace agent turn capability refs: %w", err)
|
|
}
|
|
stored, ok, err := getAgentTurnTx(ctx, tx, existing.WorkspaceID, existing.AgentSessionID, existing.TurnID)
|
|
if err != nil {
|
|
return Turn{}, false, err
|
|
}
|
|
if !ok {
|
|
return Turn{}, false, fmt.Errorf("read merged workspace agent turn capability refs: %w", sql.ErrNoRows)
|
|
}
|
|
return stored, true, nil
|
|
}
|
|
|
|
func capabilityReferencesEqual(left, right []CapabilityReference) bool {
|
|
if len(left) != len(right) {
|
|
return false
|
|
}
|
|
for index := range left {
|
|
if left[index] != right[index] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|