Add the app/intentflow skeleton so HITL state, error codes, REST shapes, and BatchActionPolicy live outside intent and default to the legacy tier. Co-authored-by: Cursor <cursoragent@cursor.com>
90 lines
1.6 KiB
Go
90 lines
1.6 KiB
Go
package intentflow
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
// PlanTier is the intentflow rollout switch. It must not be stored on
|
|
// intent.ActionSpec or intent.FeatureFlags.
|
|
type PlanTier string
|
|
|
|
const (
|
|
TierLegacy PlanTier = "legacy"
|
|
TierShadow PlanTier = "shadow"
|
|
TierAutoRead PlanTier = "auto_read"
|
|
TierConfirm PlanTier = "confirm"
|
|
TierFull PlanTier = "full"
|
|
)
|
|
|
|
type FeatureFlags struct {
|
|
PlanTier PlanTier
|
|
}
|
|
|
|
var (
|
|
flagsMu sync.RWMutex
|
|
activeFlags = defaultFeatureFlags()
|
|
)
|
|
|
|
func defaultFeatureFlags() FeatureFlags {
|
|
return FeatureFlags{PlanTier: parsePlanTier(os.Getenv("MULTI_INTENT_PLAN_TIER"))}
|
|
}
|
|
|
|
func parsePlanTier(raw string) PlanTier {
|
|
switch strings.ToLower(strings.TrimSpace(raw)) {
|
|
case "", "legacy":
|
|
return TierLegacy
|
|
case "shadow":
|
|
return TierShadow
|
|
case "auto_read", "autoread":
|
|
return TierAutoRead
|
|
case "confirm":
|
|
return TierConfirm
|
|
case "full":
|
|
return TierFull
|
|
default:
|
|
return TierLegacy
|
|
}
|
|
}
|
|
|
|
func CurrentFeatureFlags() FeatureFlags {
|
|
flagsMu.RLock()
|
|
defer flagsMu.RUnlock()
|
|
return activeFlags
|
|
}
|
|
|
|
func SetFeatureFlagsForTest(f FeatureFlags) {
|
|
flagsMu.Lock()
|
|
activeFlags = f
|
|
flagsMu.Unlock()
|
|
}
|
|
|
|
func ResetFeatureFlagsForTest() {
|
|
flagsMu.Lock()
|
|
activeFlags = defaultFeatureFlags()
|
|
flagsMu.Unlock()
|
|
}
|
|
|
|
// Allows reports whether the current (or supplied) tier may activate a policy row.
|
|
func (t PlanTier) Allows(min PlanTier) bool {
|
|
return tierRank(t) >= tierRank(min)
|
|
}
|
|
|
|
func tierRank(t PlanTier) int {
|
|
switch t {
|
|
case TierLegacy:
|
|
return 0
|
|
case TierShadow:
|
|
return 1
|
|
case TierAutoRead:
|
|
return 2
|
|
case TierConfirm:
|
|
return 3
|
|
case TierFull:
|
|
return 4
|
|
default:
|
|
return 0
|
|
}
|
|
}
|