Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 60 additions & 22 deletions coderd/aibridge/budget/budget.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,55 +20,93 @@ import (
type Store interface {
GetUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAIBudgetOverride, error)
GetHighestGroupAIBudgetByUser(ctx context.Context, userID uuid.UUID) (database.GetHighestGroupAIBudgetByUserRow, error)
GetUserEveryoneFallbackGroup(ctx context.Context, userID uuid.UUID) (uuid.UUID, error)
}

// EffectiveBudget is the AI budget that applies to a user after override and
// policy resolution.
type EffectiveBudget struct {
// EffectiveGroup is a user's resolved effective group and, when a budget
// applies, its limit. Limit is nil for the Everyone fallback (unlimited).
type EffectiveGroup struct {
// GroupID is the group the spend is attributed to.
GroupID uuid.UUID
// SpendLimitMicros is the effective spend limit in micro-units
// (1 unit = 1,000,000).
// Limit is the resolved spend limit, or nil for the unlimited Everyone
// fallback.
Limit *Limit
}

Comment thread
ssncferreira marked this conversation as resolved.
// Limit is an AI spend limit and the source that produced it.
type Limit struct {
// SpendLimitMicros is the spend limit in micro-units (1 unit = 1,000,000).
SpendLimitMicros int64
Source codersdk.AIBudgetLimitSource
}

// ResolveUserAIBudget returns the effective AI budget for userID. The second
// return value is false when no budget is configured for the user. A per-user
// override wins unconditionally; otherwise the budget is selected from the
// user's groups according to policy.
// ResolveUserAIBudget returns the effective AI budget group for userID,
// resolved in order:
// 1. A per-user override, if configured.
// 2. Otherwise, a group budget selected by the deployment policy.
//
// The second return value is false when no budget is configured for the user.
// TODO(AIGOV-527): unify effective group resolution in a single place.
func ResolveUserAIBudget(ctx context.Context, db Store, userID uuid.UUID, policy codersdk.AIBudgetPolicy) (EffectiveBudget, bool, error) {
func ResolveUserAIBudget(ctx context.Context, db Store, userID uuid.UUID, policy codersdk.AIBudgetPolicy) (EffectiveGroup, bool, error) {
// A per-user override always wins.
override, err := db.GetUserAIBudgetOverride(ctx, userID)
if err == nil {
return EffectiveBudget{
GroupID: override.GroupID,
SpendLimitMicros: override.SpendLimitMicros,
Source: codersdk.AIBudgetLimitSourceUserOverride,
return EffectiveGroup{
GroupID: override.GroupID,
Limit: &Limit{
SpendLimitMicros: override.SpendLimitMicros,
Source: codersdk.AIBudgetLimitSourceUserOverride,
},
}, true, nil
}
if !errors.Is(err, sql.ErrNoRows) {
return EffectiveBudget{}, false, xerrors.Errorf("get user AI budget override: %w", err)
return EffectiveGroup{}, false, xerrors.Errorf("get user AI budget override: %w", err)
}

// No override: select a group budget according to the deployment policy.
switch policy {
case codersdk.AIBudgetPolicyHighest:
row, err := db.GetHighestGroupAIBudgetByUser(ctx, userID)
if errors.Is(err, sql.ErrNoRows) {
return EffectiveBudget{}, false, nil
return EffectiveGroup{}, false, nil
}
if err != nil {
return EffectiveBudget{}, false, xerrors.Errorf("get highest group AI budget: %w", err)
return EffectiveGroup{}, false, xerrors.Errorf("get highest group AI budget: %w", err)
}
return EffectiveBudget{
GroupID: row.GroupID,
SpendLimitMicros: row.SpendLimitMicros,
Source: codersdk.AIBudgetLimitSourceGroup,
return EffectiveGroup{
GroupID: row.GroupID,
Limit: &Limit{
SpendLimitMicros: row.SpendLimitMicros,
Source: codersdk.AIBudgetLimitSourceGroup,
},
}, true, nil
default:
return EffectiveBudget{}, false, xerrors.Errorf("unsupported AI budget policy: %q", policy)
return EffectiveGroup{}, false, xerrors.Errorf("unsupported AI budget policy: %q", policy)
}
}

// ResolveUserEffectiveGroup resolves the user's effective group, falling back to
// the organization's Everyone group when no override or group budget applies.
// The second return value is false when no effective group was found for the
// user.
func ResolveUserEffectiveGroup(ctx context.Context, db Store, userID uuid.UUID, policy codersdk.AIBudgetPolicy) (EffectiveGroup, bool, error) {
group, ok, err := ResolveUserAIBudget(ctx, db, userID, policy)
if err != nil {
Comment thread
ssncferreira marked this conversation as resolved.
return EffectiveGroup{}, false, err
}
if ok {
return group, true, nil
}

// No override or group budget: fall back to the Everyone group (unlimited).
groupID, err := db.GetUserEveryoneFallbackGroup(ctx, userID)
if errors.Is(err, sql.ErrNoRows) {
Comment thread
ssncferreira marked this conversation as resolved.
// This should not happen, as a user should always be a member of an
// organization and its associated Everyone group.
return EffectiveGroup{}, false, nil

@ssncferreira ssncferreira Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, a user should always belong to an org. However, it seems the codebase allows a user to end up orgless in a few cases, e.g. an admin removing a user from their last org (only self-removal is blocked), or the user's only org being deleted. This shouldn't happen in normal circumstances, but the code handles it defensively nevertheless.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call 👍
For the record, it looks like in most cases a 'dis-organized' user can't really do anything of much substance unless they have a site-wide admin role.

}
if err != nil {
return EffectiveGroup{}, false, xerrors.Errorf("get everyone fallback group: %w", err)
}
return EffectiveGroup{GroupID: groupID}, true, nil
}
Loading
Loading